From 1437badf4c1ed4bd551bdf0f8fee1b9f61bb4abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iwo=20Strzebo=C5=84ski?= Date: Sun, 11 Oct 2026 17:38:42 +0000 Subject: [PATCH] Add control_print to the edge command set Pause, resume and stop, as one variant carrying a verb rather than three near-identical ones - matching the gateway's `PrintControl`, which exists so there is one method across four vendor implementations instead of three. Confirmed live on a P1P (2026-10-11), which is also where the two warnings in the description come from. A stop is a cancel and is not undoable: the printer reports the cancelled print as FAILED. And `result: "success"` from the printer means the command was accepted, not that anything changed - all three verbs answered success while it sat IDLE with nothing to pause - so a caller that needs to know the state changed has to read telemetry back. The enum is `pause|resume|stop` and deliberately not `cancel`, even though `cancel` is Moonraker's word and the Klipper implementation behind this does send a cancel. A verb only one vendor recognises must not validate on the wire. The "no start a print variant" note stays, with its reason corrected: starting an uploaded file has now been confirmed by hand, so what is missing is the path around it - nothing uploads a sliced file to a gateway and nothing decides which printer runs which job. Co-Authored-By: Claude Opus 5 --- packages/ts-types/src/schemas/edge.ts | 17 +++++++++++++++++ .../v1/edge/printer_command.schema.json | 15 ++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/ts-types/src/schemas/edge.ts b/packages/ts-types/src/schemas/edge.ts index e0c8b85..cddca06 100644 --- a/packages/ts-types/src/schemas/edge.ts +++ b/packages/ts-types/src/schemas/edge.ts @@ -72,6 +72,23 @@ export const PrinterCommandSchema = Type.Union([ */ percent: Type.Integer({ minimum: 0, maximum: 100 }), }), + Type.Object({ + action: Type.Literal("control_print"), + /** + * Confirmed live on a P1P (2026-10-11). Beware what the printer's + * acceptance means: all three answered `success` while it was IDLE with + * nothing to pause, so confirmation that the state actually changed has + * to come from telemetry, not from the command result. + * + * `stop` is a cancel and cannot be undone - a Bambu reports the + * cancelled print as `FAILED`. + */ + control: Type.Union([ + Type.Literal("pause"), + Type.Literal("resume"), + Type.Literal("stop"), + ]), + }), Type.Object({ action: Type.Literal("send_gcode_line"), /** The most powerful variant by far; be careful about exposing it to a UI. */ diff --git a/schemas/continuum/v1/edge/printer_command.schema.json b/schemas/continuum/v1/edge/printer_command.schema.json index 621587b..d056d68 100644 --- a/schemas/continuum/v1/edge/printer_command.schema.json +++ b/schemas/continuum/v1/edge/printer_command.schema.json @@ -2,7 +2,7 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://git.octoturge.com/Continuum/continuum-schemas/raw/branch/main/schemas/continuum/v1/edge/printer_command.schema.json", "title": "PrinterCommand", - "description": "The closed set of things the cloud may ask a printer to do. Deliberately small, and deliberately missing the obvious one: there is no 'start a print' variant. The gateway can start an uploaded file, but that code path has never been run against real hardware, and the first thing to exercise it should be a human watching the machine rather than a message arriving from the internet. Add the variant here once it has been confirmed by hand.", + "description": "The closed set of things the cloud may ask a printer to do. Deliberately small, and deliberately missing the obvious one: there is no 'start a print' variant. Starting an uploaded file has now been confirmed by hand on a real P1P (2026-10-11), so the earlier reason for leaving it out is spent; what is still missing is the rest of the path around it - nothing uploads a sliced file to a gateway, and no job-dispatch route decides which printer should run which job. A start variant belongs here once there is something to start, not before.", "oneOf": [ { "type": "object", @@ -18,6 +18,19 @@ }, "required": ["action", "percent"] }, + { + "type": "object", + "title": "ControlPrint", + "description": "Pause, resume or stop the print the printer is currently running. Confirmed live on a P1P (2026-10-11): all three are accepted and a stop during PREPARE/RUNNING moved the printer to FAILED, which is how Bambu reports an operator-cancelled print. Note what the printer's acceptance does not mean - all three answered success while it was IDLE with nothing to pause, so a caller that needs to know the state actually changed must read telemetry back rather than trust the command result.", + "properties": { + "action": { "const": "control_print" }, + "control": { + "enum": ["pause", "resume", "stop"], + "description": "Stop is a cancel, not a pause: it ends the print and it cannot be undone. A UI should treat it accordingly." + } + }, + "required": ["action", "control"] + }, { "type": "object", "title": "SendGcodeLine",