12 KiB
This document describes Klipper's Application Programmer Interface (API). This interface enables external applications to query and control the Klipper host software.
Enabling the API socket
In order to use the API server, the klippy.py host software must be
started with the -a
parameter. For example:
~/klippy-env/bin/python ~/klipper/klippy/klippy.py ~/printer.cfg -a /tmp/klippy_uds -l /tmp/klippy.log
This causes the host software to create a Unix Domain Socket. A client can then open a connection on that socket and send commands to Klipper.
Request format
Messages sent and received on the socket are JSON encoded strings terminated by an ASCII 0x03 character:
<json_object_1><0x03><json_object_2><0x03>...
Klipper contains a scripts/whconsole.py
tool that can perform the
above message framing. For example:
~/klipper/scripts/whconsole.py /tmp/klippy_uds
This tool can read a series of JSON commands from stdin, send them to Klipper, and report the results. The tool expects each JSON command to be on a single line, and it will automatically append the 0x03 terminator when transmitting a request. (The Klipper API server does not have a newline requirement.)
API Protocol
The command protocol used on the communication socket is inspired by json-rpc.
A request might look like:
{"id": 123, "method": "info", "params": {}}
and a response might look like:
{"id": 123, "result": {"state_message": "Printer is ready", "klipper_path": "/home/pi/klipper", "config_file": "/home/pi/printer.cfg", "software_version": "v0.8.0-823-g883b1cb6", "hostname": "octopi", "cpu_info": "4 core ARMv7 Processor rev 4 (v7l)", "state": "ready", "python_path": "/home/pi/klippy-env/bin/python", "log_file": "/tmp/klippy.log"}}
Each request must be a JSON dictionary. (This document uses the Python
term "dictionary" to describe a "JSON object" - a mapping of key/value
pairs contained within {}
.)
The request dictionary must contain a "method" parameter that is the string name of an available Klipper "endpoint".
The request dictionary may contain a "params" parameter which must be of a dictionary type. The "params" provide additional parameter information to the Klipper "endpoint" handling the request. Its content is specific to the "endpoint".
The request dictionary may contain an "id" parameter which may be of any JSON type. If "id" is present then Klipper will respond to the request with a response message containing that "id". If "id" is omitted (or set to a JSON "null" value) then Klipper will not provide any response to the request. A response message is a JSON dictionary containing "id" and "result". The "result" is always a dictionary - its contents are specific to the "endpoint" handling the request.
If the processing of a request results in an error, then the response
message will contain an "error" field instead of a "result" field. For
example, the request:
{"id": 123, "method": "gcode/script", "params": {"script": "G1 X200"}}
might result in an error response such as:
{"id": 123, "error": {"message": "Must home axis first: 200.000 0.000 0.000 [0.000]", "error": "WebRequestError"}}
Klipper will always start processing requests in the order that they are received. However, some request may not complete immediately, which could cause the associated response to be sent out of order with respect to responses from other requests. A JSON request will never pause the processing of future JSON requests.
Subscriptions
Some Klipper "endpoint" requests allow one to "subscribe" to future asynchronous update messages.
For example:
{"id": 123, "method": "gcode/subscribe_output", "params": {"response_template":{"key": 345}}}
may initially respond with:
{"id": 123, "result": {}}
and cause Klipper to send future messages similar to:
{"params": {"response": "ok B:22.8 /0.0 T0:22.4 /0.0"}, "key": 345}
A subscription request accepts a "response_template" dictionary in the
"params" field of the request. That "response_template" dictionary is
used as a template for future asynchronous messages - it may contain
arbitrary key/value pairs. When sending these future asynchronous
messages, Klipper will add a "params" field containing a dictionary
with "endpoint" specific contents to the response template and then
send that template. If a "response_template" field is not provided
then it defaults to an empty dictionary ({}
).
Available "endpoints"
By convention, Klipper "endpoints" are of the form
<module_name>/<some_name>
. When making a request to an "endpoint",
the full name must be set in the "method" parameter of the request
dictionary (eg, {"method"="gcode/restart"}
).
info
The "info" endpoint is used to obtain system and version information
from Klipper. It is also used to provide the client's version
information to Klipper. For example:
{"id": 123, "method": "info", "params": { "client_info": { "version": "v1"}}}
If present, the "client_info" parameter must be a dictionary, but that dictionary may have arbitrary contents. Clients are encouraged to provide the name of the client and its software version when first connecting to the Klipper API server.
emergency_stop
The "emergency_stop" endpoint is used to instruct Klipper to
transition to a "shutdown" state. It behaves similarly to the G-Code
M112
command. For example:
{"id": 123, "method": "emergency_stop"}
register_remote_method
This endpoint allows clients to register methods that can be called from klipper. It will return an empty object upon success.
For example:
{"id": 123, "method": "register_remote_method", "params": {"response_template": {"action": "run_paneldue_beep"}, "remote_method": "paneldue_beep"}}
will return:
{"id": 123, "result": {}}
The remote method paneldue_beep
may now be called from Klipper. Note
that if the method takes parameters they should be provided as keyword
arguments. Below is an example of how it may called from a gcode_macro:
[gcode_macro PANELDUE_BEEP]
default_parameter_FREQUENCY: 300
default_parameter_DURATION: 1.
gcode:
{action_call_remote_method("paneldue_beep",
frequency=FREQUENCY|int,
duration=DURATION|float)}
When the PANELDUE_BEEP gcode macro is executed, Klipper would send something like the following over the socket: `{"action": "run_paneldue_beep", "params": {"frequency": 300, "duration": 1.0}}
objects/list
This endpoint queries the list of available printer "objects" that one
may query (via the "objects/query" endpoint). For example:
{"id": 123, "method": "objects/list"}
might return:
{"id": 123, "result": {"objects": ["webhooks", "configfile", "heaters", "gcode_move", "query_endstops", "idle_timeout", "toolhead", "extruder"]}}
objects/query
This endpoint allows one to query information from printer objects.
For example:
{"id": 123, "method": "objects/query", "params": {"objects": {"toolhead": ["position"], "webhooks": null}}}
might return:
{"id": 123, "result": {"status": {"webhooks": {"state": "ready", "state_message": "Printer is ready"}, "toolhead": {"position": [0.0, 0.0, 0.0, 0.0]}}, "eventtime": 3051555.377933684}}
The "objects" parameter in the request must be a dictionary containing the printer objects that are to be queried - the key contains the printer object name and the value is either "null" (to query all fields) or a list of field names.
The response message will contain a "status" field containing a dictionary with the queried information - the key contains the printer object name and the value is a dictionary containing its fields. The response message will also contain an "eventtime" field containing the timestamp from when the query was taken.
Available fields are documented in the Command Template document.
objects/subscribe
This endpoint allows one to query and then subscribe to information
from printer objects. The endpoint request and response is identical
to the "objects/query" endpoint. For example:
{"id": 123, "method": "objects/subscribe", "params": {"objects":{"toolhead": ["position"], "webhooks": ["state"]}, "response_template":{}}}
might return:
{"id": 123, "result": {"status": {"webhooks": {"state": "ready"}, "toolhead": {"position": [0.0, 0.0, 0.0, 0.0]}}, "eventtime": 3052153.382083195}}
and result in subsequent asynchronous messages such as:
{"params": {"status": {"webhooks": {"state": "shutdown"}}, "eventtime": 3052165.418815847}}
gcode/help
This endpoint allows one to query available G-Code commands that have
a help string defined. For example:
{"id": 123, "method": "gcode/help"}
might return:
{"id": 123, "result": {"RESTORE_GCODE_STATE": "Restore a previously saved G-Code state", "PID_CALIBRATE": "Run PID calibration test", "QUERY_ADC": "Report the last value of an analog pin", ...}}
gcode/script
This endpoint allows one to run a series of G-Code commands. For example:
{"id": 123, "method": "gcode/script", "params": {"script": "G90"}}
If the provided G-Code script raises an error, then an error response is generated. However, if the G-Code command produces terminal output, that terminal output is not provided in the response. (Use the "gcode/subscribe_output" endpoint to obtain G-Code terminal output.)
If there is a G-Code command being processed when this request is received, then the provided script will be queued. This delay could be significant (eg, if a G-Code wait for temperature command is running). The JSON response message is sent when the processing of the script fully completes.
gcode/restart
This endpoint allows one to request a restart - it is similar to
running the G-Code "RESTART" command. For example:
{"id": 123, "method": "gcode/restart"}
As with the "gcode/script" endpoint, this endpoint only completes after any pending G-Code commands complete.
gcode/firmware_restart
This is similar to the "gcode/restart" endpoint - it implements the
G-Code "FIRMWARE_RESTART" command. For example:
{"id": 123, "method": "gcode/firmware_restart"}
As with the "gcode/script" endpoint, this endpoint only completes after any pending G-Code commands complete.
gcode/subscribe_output
This endpoint is used to subscribe to G-Code terminal messages that
are generated by Klipper. For example:
{"id": 123, "method": "gcode/subscribe_output", "params": {"response_template":{}}}
might later produce asynchronous messages such as:
{"params": {"response": "// Klipper state: Shutdown"}}
This endpoint is intended to support human interaction via a "terminal window" interface. Parsing content from the G-Code terminal output is discouraged. Use the "objects/subscribe" endpoint to obtain updates on Klipper's state.
pause_resume/cancel
This endpoint is similar to running the "PRINT_CANCEL" G-Code command.
For example:
{"id": 123, "method": "pause_resume/cancel"}
As with the "gcode/script" endpoint, this endpoint only completes after any pending G-Code commands complete.
pause_resume/pause
This endpoint is similar to running the "PAUSE" G-Code command. For
example:
{"id": 123, "method": "pause_resume/pause"}
As with the "gcode/script" endpoint, this endpoint only completes after any pending G-Code commands complete.
pause_resume/resume
This endpoint is similar to running the "RESUME" G-Code command. For
example:
{"id": 123, "method": "pause_resume/resume"}
As with the "gcode/script" endpoint, this endpoint only completes after any pending G-Code commands complete.
query_endstops/status
This endpoint will query the active endpoints and return their status.
For example:
{"id": 123, "method": "query_endstops/status"}
might return:
{"id": 123, "result": {"y": "open", "x": "open", "z": "TRIGGERED"}}
As with the "gcode/script" endpoint, this endpoint only completes after any pending G-Code commands complete.