docs: complete API documentation rework

Moonraker's external API documentation has been significantly
overhauled in an effort to improve clarity and readability.
All parameters and responses are documented with specifications.
Tables and other elements are used to make documentation more
visible and less verbose.

Spelling and other corrections have also been added.

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan
2024-01-24 14:24:31 -05:00
parent 5a3b35f5ac
commit 9c550a8f9a
38 changed files with 15200 additions and 9082 deletions

View File

@@ -3,9 +3,9 @@ This document keeps a record of notable changes to Moonraker's Web API.
### July 18th 2023
- Moonraker API Version 1.3.0
- Added [Spoolman](web_api.md#spoolman-apis) APIs.
- Added [Rollback](web_api.md#rollback-to-the-previous-version) API to
the `update_manager`
- Added [Spoolman](./external_api/integrations.md#spoolman) APIs.
- Added [Rollback](./external_api/update_manager.md#rollback-to-the-previous-version)
API to the `update_manager`
- The `update_manager` status response has new fields for items of the
`git_repo` and `web` types:
- `recovery_url`: Url of the repo a "hard" recovery will fetch from
@@ -25,12 +25,13 @@ This document keeps a record of notable changes to Moonraker's Web API.
- `GET /server/sensors/sensor`
- `GET /server/sensors/measurements`
See [web_api.md](web_api.md) for details on these new endpoints.
See [the documentation](./external_api/devices.md#sensor-endpoints)
for details on these new endpoints.
- A `sensors:sensor_update` notification has been added. When at least one
monitored sensor is reporting a changed value Moonraker will broadcast this
notification.
See [web_api.md](web_api.md) for details on this new notification.
See [the documentation](./external_api/jsonrpc_notifications.md#sensor-events)
for details on this new notification.
### February 17 2023
- Moonraker API Version 1.2.1
@@ -50,14 +51,14 @@ This document keeps a record of notable changes to Moonraker's Web API.
recommended to use `server.connection.identify` method to identify
your client. This method returns a `connection_id` which is
the websocket's unique id. See
[the documentation](web_api.md#identify-connection) for details.
[the documentation](./external_api/server.md#identify-connection) for details.
### May 8th 2021
- The `file_manager` has been refactored to support system file
file events through `inotify`. Only mutable `roots` are monitored,
(currently `gcodes` and `config`). Subfolders within these
(currently `gcodes` and `config`). Sub-folders within these
these roots are also monitored, however hidden folders are not.
The following changes API changes have been made to acccommodate
The following changes API changes have been made to accommodate
this functionality:
- The `notify_filelist_changed` actions have changed. The new
actions are as follows:
@@ -78,7 +79,7 @@ This document keeps a record of notable changes to Moonraker's Web API.
processed. Notifications are synced with requests so that the
request should always return before the notification is sent.
- Thumbnails are now stored in the `.thumbs` directory to prevent
changes to thumbnails from emitting filelist notications. This
changes to thumbnails from emitting filelist notifications. This
change will be reflected in the metadata's `relative_path` field,
so clients that use this field should not need to take additional
action. Note that existing thumbnails will remain in the `thumbs`
@@ -103,7 +104,7 @@ This document keeps a record of notable changes to Moonraker's Web API.
### January 31st 2021
- The `GET /server/temperature_store` endpoint now only returns fields
that each sensor reports. For example, if a particuarly temperature
that each sensor reports. For example, if a particularly temperature
sensor does not report "target" or "power", then the corresponding
fields will not be reported for that sensor in response to the
`temperature_store` request.
@@ -153,7 +154,8 @@ This document keeps a record of notable changes to Moonraker's Web API.
core API:
- `POST /machine/services/restart`
See [web_api.md](web_api.md) for details on these new endpoints.
See [the documentation](./external_api/update_manager.md) for details
on these new endpoints.
### November 23rd 2020
- Moonraker now serves Klipper's "docs" directory. This can be access
@@ -187,7 +189,7 @@ See [web_api.md](web_api.md) for details on these new endpoints.
"params":{"dev_name":null}}`\
Toggles device off. Returns the current status of the device.
- The `notify_power_changed` notification now includes an object
containing device info, matching that which would be recieved
containing device info, matching that which would be received
from a single item in `/machine/power/devices`.
### November 12th 2020
@@ -207,13 +209,13 @@ See [web_api.md](web_api.md) for details on these new endpoints.
- All HTTP API request may now include arguments in either the
query string or in the request's body.
- Subscriptions are now managed on a per connection basis. Each
connection will only recieve updates for objects in which they
connection will only receive updates for objects in which they
are currently subscribed. If an "empty" request is sent, the
subscription will be cancelled.
- The `POST /printer/object/subscribe` now requires a
`connection_id` argument. This is used to identify which
connection's associated subscription should be updated.
Currenlty subscriptions are only supported over the a
Currently subscriptions are only supported over the a
websocket connection, one may use the id received from
`server.websocket.id`.
- The `notify_klippy_ready` websocket notification has been
@@ -298,8 +300,8 @@ See [web_api.md](web_api.md) for details on these new endpoints.
- `POST /machine/gpio_power/off` : `machine.gpio_power.off`
### September 1st 2020
- A new notification has been added: `notify_metdata_update`. This
notification is sent when Moonraker parses metdata from a new upload.
- A new notification has been added: `notify_metadata_update`. This
notification is sent when Moonraker parses metadata from a new upload.
Note that the upload must be made via the API, files manually (using
SAMBA, SCP, etc) do not trigger a notification. The notification is
sent in the following format:
@@ -399,7 +401,7 @@ See [web_api.md](web_api.md) for details on these new endpoints.
state for all currently subscribed objects (in the same format as a `query`).
This data can be used to initialize all local state after the request
completes.
- Subscriptions are now pushed as "diffs". Clients will only recieve updates
- Subscriptions are now pushed as "diffs". Clients will only receive updates
for subscribed items when that data changes. This requires that clients
initialize their local state with the data returned from the subscription
request.

View File

@@ -174,7 +174,8 @@ The format is based on [Keep a Changelog].
- **update_manager**: The `install_script` option for the `git_repo` has been
deprecated, new configurations should use the `system_dependencies` option.
- **update_manager**: APIs that return status report additional fields.
See the [API Documentation](./web_api.md#get-update-status) for details.
See the [API Documentation](./external_api/update_manager.md#get-update-status)
for details.
- **proc_stats**: Improved performance of Raspberry Pi CPU throttle detection.
- **power**: Bound services are now processed during initialization when
`initial_state` is configured.
@@ -193,7 +194,7 @@ The format is based on [Keep a Changelog].
!!! Note
This is the first tagged release since a changelog was introduced. The list
below contains notable changes introduced beginning in Feburary 2023. Prior
below contains notable changes introduced beginning in February 2023. Prior
notable changes were kept in [user_changes.md] and [api_changes.md].
### Added
@@ -202,10 +203,10 @@ The format is based on [Keep a Changelog].
- Added pyproject.toml with support for builds through [pdm](https://pdm.fming.dev/latest/).
- **sensor**: New component for generic sensor configuration.
- [Configuration Docs](configuration.md#sensor)
- [API Docs](web_api.md#sensor-apis)
- [Websocket Notification Docs](web_api.md#sensor-events)
- **file_manager**: Added new [scan metadata](web_api.md#scan-gcode-metadata) endpoint.
- **file_manager**: Added new [thumbnails](web_api.md#get-gcode-thumbnails) endpoint.
- [API Docs](./external_api/devices.md#sensor-endpoints)
- [Websocket Notification Docs](./external_api/jsonrpc_notifications.md#sensor-events)
- **file_manager**: Added new [scan metadata](./external_api/file_manager.md#scan-gcode-metadata) endpoint.
- **file_manager**: Added new [thumbnails](./external_api/file_manager.md#get-gcode-thumbnail-details) endpoint.
- **file_manager**: Added [file_system_observer](configuration.md#file_manager)
configuration option.
- **file_manager**: Added [enable_observer_warnings](configuration.md#file_manager)
@@ -217,9 +218,9 @@ The format is based on [Keep a Changelog].
- **machine**: Added service detection to the `supervisord_cli` provider.
- **machine**: Added `octoeverywhere` to the list of default allowed service.
- **power**: Added support for "Hue" device groups.
- **websockets**: Added support for [direct bridge](web_api.md#bridge-websocket)
- **websockets**: Added support for [direct bridge](./external_api/introduction.md#bridge-websocket)
connections.
- **update_manager**: Added new [refresh](web_api.md#refresh-update-status) endpoint.
- **update_manager**: Added new [refresh](./external_api/update_manager.md#refresh-update-status) endpoint.
- **update_manager**: Added support for pinned pip upgrades.
- **websockets**: Added support for post connection authentication over the websocket.
- **scripts**: Added database backup and restore scripts.

View File

@@ -47,7 +47,7 @@ class Example:
return await klippy_apis.query_objects({'print_stats': None})
async def _handle_example_request(self, web_request):
web_request.get_int("required_reqest_param")
web_request.get_int("required_request_param")
web_request.get_float("optional_request_param", None)
state = await self.request_some_klippy_state()
return {"example_return_value": state}
@@ -126,7 +126,7 @@ object.
#### *ConfigHelper.get_prefix_sections(prefix)*
Returns a list section names in the configuration that start with `prefix`.
These strings can be used to retreve ConfigHelpers via
These strings can be used to retrieve ConfigHelpers via
[get_section()](#confighelpergetsectionsection_name).
### The Server Object
@@ -219,15 +219,15 @@ callback. Event names should be in the form of
#### *Server.register_notification(event_name, notify_name=None)*
Registers a websocket notification to be pushed when `event_name`
is emitted. By default JSON-RPC notifcation sent will be in the form of
is emitted. By default JSON-RPC notification sent will be in the form of
`notify_{event_description}`. For example, when the server sends the
`server:klippy_connected` event, the JSON_RPC notification will be
`notify_klippy_connected`.
If a `notify_name` is provided it will override the `{event_description}`
extracted from the `event_name`. For example, if the `notify_name="kconnect`
were specfied when registering the `server:klippy_connected` event, the
websocket would emit a `notify_kconnect` notification.
extracted from the `event_name`. For example, if the `notify_name="k_connected"`
were specified when registering the `server:klippy_connected` event, the
websocket would emit a `notify_k_connected` notification.
#### *Server.get_host_info()*
@@ -242,7 +242,7 @@ Klippy. If Klippy has never connected this will be an empty dict.
### The WebRequest Object
All callbacks registered with the
[register_endpoint()](#serverregister_endpointuri-request_methods-callback-protocolhttp-websocket-wrap_resulttrue)
[register_endpoint()](#serverregister_endpointuri-request_methods-callback-transportshttp-websocket-mqtt-wrap_resulttrue)
method are passed a WebRequest object when they are executed. This object
contains information about the request including its endpoint name and arguments
parsed from the request.
@@ -253,7 +253,7 @@ Returns the URI registered with this request, ie: `/server/example`.
#### *WebRequest.get_action()*
Returns the request action, which is synonomous with its HTTP request
Returns the request action, which is synonymous with its HTTP request
method. Will be either `GET`, `POST`, or `DELETE`. This is useful
if your endpoint was registered with multiple request methods and
needs to handle each differently.
@@ -326,7 +326,7 @@ established.
Attempts to publish a topic to the Broker. The `payload` may be a bool, int,
float, string, or json encodable (Dict or List). If omitted then an empty
payload is sent. The `qos` may be an integer from 0 to 2. If not specifed
payload is sent. The `qos` may be an integer from 0 to 2. If not specified
then the QOS level will use the configured default. If `retain` is set to
`True` then the retain flag for the payload will be set.
@@ -340,7 +340,7 @@ Publishes the supplied `topic` with the arguments specified by `payload`,
`qos`, and `retain`, then subscribes to the `response_topic`. The payload
delivered by the response topic is returned. Note that this method is
a coroutine, it must always be awaited. The call will block until the
entire process has completed unless a `timeout` (in seconds) is specifed.
entire process has completed unless a `timeout` (in seconds) is specified.
The `timeout` is applied to both the attempt to publish and the pending
response, so the maximum waiting time would be approximately 2*timeout.
@@ -351,7 +351,7 @@ response, so the maximum waiting time would be approximately 2*timeout.
#### *MQTTClient.subscribe_topic(topic, callback, qos=None)*
Subscibes to the supplied `topic` with the specified `qos`. If `qos` is not
Subscribes to the supplied `topic` with the specified `qos`. If `qos` is not
supplied the configured default will be used. The `callback` should be a
callable that accepts a `payload` argument of a `bytes` type. The callable
may be a coroutine. The callback will be run each time the subscribed topic
@@ -359,7 +359,7 @@ is published by another client.
Returns a `SubscriptionHandle` that may be used to unsubscribe the topic.
#### *MQTTClinet.unsubscribe(hdl)*
#### *MQTTClient.unsubscribe(hdl)*
Unsubscribes the callback associated with `hdl`. If no outstanding callbacks
exist for the topic then the topic is unsubscribed from the broker.

View File

@@ -271,7 +271,7 @@ gcode:
!!! Note
This section no long has configuration options. Previously the
`database_path` option was used to determine the locatation of
`database_path` option was used to determine the location of
the database folder, it is now determined by the `data path`
configured on the command line.
@@ -559,7 +559,7 @@ user_filter: (&(objectClass=user)(cn=USERNAME))
### `[octoprint_compat]`
Enables partial support of OctoPrint API is implemented with the purpose of
allowing uploading of sliced prints to a moonraker instance.
Currently we support Slic3r derivatives and Cura with Cura-OctoPrint.
Currently PrusaSlicer derivatives and Cura with Cura-OctoPrint.
```ini
# moonraker.conf
@@ -718,7 +718,7 @@ bound_services:
# the Moonraker service can not be bound to a power device. Note that
# service names are case sensitive.
#
# When the "initial_state" option is explcitly configured bound services
# When the "initial_state" option is explicitly configured bound services
# will be synced with the current state. For example, if the initial_state
# is "off", all bound services will be stopped after device initialization.
#
@@ -1386,7 +1386,7 @@ port:
##### Example
```ini
# moonraker.confg
# moonraker.config
# Example for controlling a device connected to a Raspberry Pi 3B+.
# Location 1-1 Port 2 controls power for all 4 exposed ports.
@@ -1432,7 +1432,7 @@ a Jinja2 context with the following fields:
- `async_sleep`: An alias for the `asyncio.sleep` method. This may be used
to add delays if necessary.
- `log_debug`: An alias for `logging.debug`. This can be used to log messages
and data to `moonraker.log` to aid in debugging an implmentation. Note that
and data to `moonraker.log` to aid in debugging an implementation. Note that
verbose logging must be
[enabled](installation.md#debug-options-for-developers) for these messages
to appear in the log.
@@ -1531,7 +1531,7 @@ __`http_response.final_url`__
> A property that returns "effective" url of the request after all redirects.
__`http_reponse.headers`__
__`http_response.headers`__
> A property that returns the response headers as a python `Dict`.
@@ -1688,7 +1688,7 @@ gcode:
# Override SDCARD_PRINT_FILE
[gcode_macro SDCARD_PRINT_FILE]
rename_existing: SDCPF
rename_existing: DO_PRINT
gcode:
# Step 1: Call the remote method to turn on the power device
POWER_ON_HEATERS
@@ -1696,7 +1696,7 @@ gcode:
# pauses for 4 seconds. It may be necessary to tweak this value.
G4 P4000
# Step 3: Call the renamed command to start the print
SDCPF {rawparams}
DO_PRINT {rawparams}
```
@@ -1712,7 +1712,7 @@ gcode:
Another exotic use case is the addition of a "conditional" peripheral,
such as an MMU device. The user may not wish to power on this device
for every print, and instead power it on from within the "Start G-GCode"
conditionally. Additionaly we do not want this device to be turned on/off
conditionally. Additionally we do not want this device to be turned on/off
unintentionally during a print. The `set_device_power` remote method takes
an optional `force` argument that can be used to accommodate this scenario.
@@ -2064,7 +2064,7 @@ info_tags:
pinned_commit:
# A git commit hash to "pin" updates to. When specified Moonraker will not
# update the repo beyond the pinned commit. If the repo is already beyond
# the specified commit, or if the commit is not in the repo, futher updates
# the specified commit, or if the commit is not in the repo, further updates
# are disabled until the pinned_commit is changed. It is recommended to
# specify the complete hash, however abbreviated hashes with a minimum of
# 8 characters are accepted. The "pinned_commit" overrides the update
@@ -2078,7 +2078,7 @@ pinned_commit:
services Moonraker is allowed to manage and how to add additional services.
Also not that systemd services are case sensitive. The `extension_name`
in the section header and the value provided in the `managed_servies`
in the section header and the value provided in the `managed_services`
option must match the case of the systemd unit file.
#### Zip Application Configuration
@@ -2147,12 +2147,12 @@ refresh_interval:
# This overrides the refresh_interval set in the primary [update_manager]
# section.
virtualenv:
# Path to the virtual enviromnent containing the python application.
# Path to the virtual environment containing the python application.
project_name:
# Name of the python project as listed in the python package index. If
# the packaged is sourced from GitHub, this will be the name of the project
# specified in the build. Optional "extras" may be added, see the tip
# follwing this example for details. The default is the name specified by the
# following this example for details. The default is the name specified by the
# configuration section.
primary_branch:
# For packages sourced from GitHub, this option may be used to specify the
@@ -2242,7 +2242,7 @@ When a `zip` or `git_repo` application depends on OS packages it is possible
to specify them in a file that Moonraker can refer to. During an update
Moonraker will use this file to install new dependencies if they are detected.
Below is an example of Moonraker's system dependcies file, located at
Below is an example of Moonraker's system dependencies file, located at
in the repository at
[scripts/system-dependencies.json](https://github.com/Arksine/moonraker/blob/master/scripts/system-dependencies.json):
@@ -2278,8 +2278,8 @@ Pi OS, Ubuntu, and likely other Debian derived distributions.
Enables an MQTT Client. When configured most of Moonraker's APIs are available
by publishing JSON-RPC requests to `{instance_name}/moonraker/api/request`.
Responses will be published to `{instance_name}/moonraker/api/response`. See
the [API Documentation](web_api.md#json-rpc-api-overview) for details on
on JSON-RPC.
the [API Documentation](./external_api/introduction.md#json-rpc-api-overview)
for details on on JSON-RPC.
It is also possible for other components within Moonraker to use MQTT to
publish and subscribe to topics.
@@ -2294,7 +2294,7 @@ address:
port:
# Port the Broker is listening on. Default is 1883.
client_id:
# A string client identifer sent by the client to the broker after
# A string client identifier sent by the client to the broker after
# connecting. The default is a randomly assigned client id.
enable_tls: False
# Enables SSL/TLS connections when set to true. Note that if a user intends
@@ -2450,7 +2450,7 @@ serial:
# 0.13 Build 2108250 or later.
# Required when type: serial
initial_preset:
# Initial preset ID (favourite) to use. If not specified initial_colors
# Initial preset ID (favorite) to use. If not specified initial_colors
# will be used instead.
initial_red:
initial_green:
@@ -2555,7 +2555,7 @@ detect and use Moonraker instances.
[zeroconf]
mdns_hostname:
# The hostname used when registering the multicast DNS serivce.
# The hostname used when registering the multicast DNS service.
# The instance will be available at:
# http://{mdns_hostname}.local:{port}/
# The default is the operating system's configured hostname.
@@ -2598,7 +2598,7 @@ debounce_period: .05
minimum_event_time: 0
# The minimum event duration (in seconds) required to trigger a response.
# This can be used as a secondary debounce procedure. The default is 0
# seconds (no minumum duration).
# seconds (no minimum duration).
on_press:
on_release:
# Jinja2 templates to be executed when a button event is detected. At least one
@@ -2613,7 +2613,8 @@ with two methods that may be called in addition to Jinja2's default filters
adn methods:
- `call_method`: Calls an internal API method. See the
[API documentation](web_api.md#jinja2-template-api-calls) for details.
[API documentation](./external_api/introduction.md#jinja2-template-api-calls)
for details.
- `send_notification`: Emits a websocket notification. This is useful if you
wish to use buttons to notify attached clients of some action. This
method takes an optional argument that may contain any JSON object.
@@ -2826,7 +2827,7 @@ body: "Your printer status has changed to {event_name}"
# event_message: An additional message passed to the notification when
# triggered. This is commonly used when the notification
# is received from Klippy using a gcode_macro.
# The default is a body containining the "name" of the notification as entered
# The default is a body containing the "name" of the notification as entered
# in the section header.
body_format:
# The formatting to use for the body, can be `text`, `html` and `markdown`.
@@ -2838,8 +2839,8 @@ title:
attach:
# One or more items to attach to the notification. This may be a path to a
# local file or a url (such as a webcam snapshot). Multiple attachments must be
# separated by a newline. This option accepts Jinja2 templates, the tempalte
# will recieve the same context as the "body" and "title" options. The default
# separated by a newline. This option accepts Jinja2 templates, the template
# will receive the same context as the "body" and "title" options. The default
# is no attachment will be sent with the notification.
#
# Note: Attachments are not available for all notification services, you can
@@ -2948,7 +2949,7 @@ ambient_sensor:
- Klipper's version, connection state, and date pulled
- Moonraker's version
- Currenly connected front-end and version
- Currently connected front-end and version
- Current python version
- Linux distribution and version
- Network connection type (wifi or ethernet)
@@ -3003,7 +3004,7 @@ parameter_{parameter_name}:
# be a valid measurement reported by the sensor. The value should be
# a newline separated list of key-value pairs describing the
# the measurement. Currently the only key used is "units". For
# example, the configuration for a parameter may look like the follwing:
# example, the configuration for a parameter may look like the following:
#
# parameter_energy:
# units=kWh
@@ -3061,7 +3062,7 @@ history_field_{field_name}:
- `basic`: This strategy should be used if the value should be stored
in history directly as it is received. Simply put, the last value
received before a job completes wiill the the value stored in the job
received before a job completes will be the value stored in the job
history.
- `accumulate`: When a job starts, the tracked value initialized to 0 or
the last received measurement. New measurements will be added to the
@@ -3181,7 +3182,7 @@ Tasmota Example:
!!! Note
It may be necessary to set Tasmota's Telemetry Period to a low value
to acheive a decent response. This can be done in the with the
to achieve a decent response. This can be done in the with the
`TelePeriod` command via the console. For example, the command
to set the telemetry period to 10 seconds is:
@@ -3223,7 +3224,7 @@ history_field_average_current:
units=A
report_total=false
report_maximum=true
# Mulitple history fields may track the same sensor parameter:
# Multiple history fields may track the same sensor parameter:
history_field_max_current:
parameter=current
desc=Maximum current draw

View File

@@ -78,7 +78,7 @@ Signed-off-by: Eric Callahan <arksine.code@gmail.com>
```
By signing off on commits, you acknowledge that you agree to the
[developer certificate of origin](../developer-certificate-of-origin)
[developer certificate of origin](https://developercertificate.org/)
shown below. As mentioned above, your signature must contain your
real name and a current email address.

View File

@@ -70,7 +70,7 @@
- Added thumbnail extraction from SuperSlicer and PrusaSlicer gcode files
- For status requests, `virtual_sdcard.current_file` has been renamed to
`virtual_sdcard.filename`
- Clients should not send `M112` via gcode to execute an emegency shutdown.
- Clients should not send `M112` via gcode to execute an emergency shutdown.
They should instead use the new API which exposes this functionality.
- New APIs:
- `POST /printer/emergency_stop` - `post_printer_emergency_stop`
@@ -108,7 +108,7 @@
remote_api.py module that handles server configuration.
- webhooks.py has been changed to handle communications with the server
- klippy.py has been changed to pass itself to webhooks
- file_manager.py has been changed to specifiy the correct status code
- file_manager.py has been changed to specify the correct status code
when an error is generated attempting to upload or delete a file
- The nginx configuration will need the following additional section:
```
@@ -149,8 +149,8 @@
This allows the client limited access to Klippy in the event of a startup
error, assuming the config file was successfully parsed and the
`remote_api` configuration section is valid. Note that when the server is
initally launched not all endpoints will be available. The following
endponts are guaranteed when the server is launched:
initially launched not all endpoints will be available. The following
endpoints are guaranteed when the server is launched:
- `/websocket`
- `/printer/info`
- `/printer/restart`
@@ -159,7 +159,7 @@
- `/printer/gcode`
- `/access/api_key`
- `/access/oneshot_token`
The following startup sequence is recommened for clients which make use of
The following startup sequence is recommended for clients which make use of
the websocket:
- Attempt to connect to `/websocket` until successful
- Once connected, query `/printer/info` for the ready status. If not ready
@@ -199,7 +199,7 @@
- Fix bug in CORS where DELETE requests raised an exception
- Disable the server when running Klippy in batch mode
- The the `/printer/cancel`, `/printer/pause` and `/printer/resume` gcodes
are now registed by the pause_resume module. This results in the following
are now registered by the pause_resume module. This results in the following
changes:
- The `cancel_gcode`, `pause_gcode`, and `resume_gcode` options have
been removed from the [web_server] section.
@@ -275,17 +275,17 @@
websocket data from a Blob into a String.
- The endpoint for querying endstops has changed from `GET
/printer/extras/endstops` to `GET /printer/endstops`
- Serveral API changes have been made to accomodate the addition of webhooks:
- Several API changes have been made to accommodate the addition of webhooks:
- `GET /printer/klippy_info` is now `GET /printer/info`. This endpoint no
longer returns host information, as that can be retrieved direct via the
`location` object in javascript. Instead it returns CPU information.
- `GET /printer/objects` is no longer used to accomodate multiple request
- `GET /printer/objects` is no longer used to accommodate multiple request
types by modifying the "Accept" headers. Each request has been broken
down in their their own endpoints:
- `GET /printer/objects` returns all available printer objects that may
be queried
- `GET /printer/status?gcode=gcode_position,speed&toolhead` returns the
status of the printer objects and attribtues
status of the printer objects and attributes
- `GET /printer/subscriptions` returns all printer objects that are current
being subscribed to along with their poll times
- `POST /printer/subscriptions?gcode&toolhead` requests that the printer
@@ -297,7 +297,7 @@
- `POST /printer/gcode/<gcode>` is now `POST /printer/gcode?script=<gcode>`
- `POST printer/print/start/<filename>` is now
`POST /printer/print/start?filename=<filename>`
- The websocket API also required changes to accomodate dynamically registered
- The websocket API also required changes to accommodate dynamically registered
endpoints. Each method name is now generated from its comparable HTTP
request. The new method names are listed below:
| new method | old method |
@@ -317,7 +317,7 @@
| post_printer_firmware_restart | firmware_restart |
| get_printer_endstops | get_endstops |
- As with the http API, a change was necessary to the way arguments are send
along with the request. Webocket requests should now send "keyword
along with the request. Websocket requests should now send "keyword
arguments" rather than "variable arguments". The test client has been
updated to reflect these changes, see main.js and json-rpc.js, specifically
the new method `call_method_with_kwargs`. For status requests this simply

View File

@@ -0,0 +1,168 @@
adxl
apikey
apirequest
apiresponse
argone
argtwo
arksine
armv
asvc
asyncio
atmega
Benchy
bigtreetech
binutils
calicat
camerastreamer
canbus
cansocket
cmnd
comms
compat
configfile
configheler
confighelper
configurator
Connor
crowsnest
Cura
datapath
datasheet
dbus
devel
distro
distros
Domoticz
Donkie
eeprom
endstop
endstops
EPCOS
eventtime
extr
feedrate
filelist
fileobj
firemon
Fluidd
fourcc
fromjson
frontends
ftdi
gcode
gcodes
getboolean
getfloat
getfqdn
getint
getitem
getsection
gpio
gpiochip
hexeditor
highspeed
hlsstream
homeassistant
homeseer
httpx
inotify
ipstream
jmuxer
journalctl
Kasa
katapult
klipper
klippy
klippysocket
kwargs
libcamera
libgpiod
libnacl
lmdb
logind
Loxone
loxonev
mediamtx
metascan
microsteps
mjpeg
mjpegstreamer
MJPG
Mobileraker
moko
moonagent
moontest
msgspec
Muxer
mypassword
mypy
neopixel
neopixels
Obico
octoeverywhere
octoprint
oneshot
packagekit
packagename
paneldue
piezo
PKGLIST
poweroff
Prusa
pstats
pullup
pyapp
Pycurl
pyproject
pyserial
raspberrypi
ratos
rawparams
readwrite
sdcard
sdcardinfo
sdist
Semitec
setitem
sgbrg
simplyprint
smartplug
smartthings
spoolman
SSDP
stallguard
subdir
supervisord
sysfs
sysinfo
tasmota
telegam
testcam
testdir
testuser
TESTZ
tojson
tplink
trapq
uart
ububctl
uhubctl
unicam
unixsocket
userpass
uvcvideo
uvloop
vcgencmd
venv
virt
virtualenv
volted
webcamd
webrtc
websockets
wlan
WLED
worktrees
yuyv
zeroconf
Zigbee

View File

@@ -1,3 +1,4 @@
mkdocs-material==9.5.4
compact_tables@git+https://github.com/Arksine/markdown-compact-tables@v1.0.0
./pymdown-extras
mkdocs-material==9.5.50
pymdown-extensions~=10.14.1
compact_tables@git+https://github.com/Arksine/markdown-compact-tables@v1.1.0
./docs/pymdown-extras

View File

@@ -0,0 +1,692 @@
# Announcements
The following endpoints are available to manage announcements.
Moonraker announcements are effectively push notifications that
can be used to notify users of important information related the
development and status of software in the Klipper ecosystem.
See [the appendix](#appendix) for details on how announcements
work and recommendations for your implementation.
## List announcements
Retrieves a list of current announcements.
```{.http .apirequest title="HTTP Request"}
GET /server/announcements/list?include_dismissed=false
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.announcements.list",
"params": {
"include_dismissed": false
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------------------- | :--: | ------- | ----------------------------------- |
| `include_dismissed` | bool | true | When set to false dismissed entries |
| | | | will be excluded from the returned |^
| | | | list of current announcements. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"entries": [
{
"entry_id": "arksine/moonlight/issue/3",
"url": "https://github.com/Arksine/moonlight/issues/3",
"title": "Test announcement 3",
"description": "Test Description [with a link](https://moonraker.readthedocs.io).",
"priority": "normal",
"date": 1647459219,
"dismissed": false,
"date_dismissed": null,
"dismiss_wake": null,
"source": "moonlight",
"feed": "moonlight"
},
{
"entry_id": "arksine/moonlight/issue/2",
"url": "https://github.com/Arksine/moonlight/issues/2",
"title": "Announcement Test Two",
"description": "This is a high priority announcement. This line is included in the description.",
"priority": "high",
"date": 1646855579,
"dismissed": false,
"date_dismissed": null,
"dismiss_wake": null,
"source": "moonlight",
"feed": "moonlight"
},
{
"entry_id": "arksine/moonlight/issue/1",
"url": "https://github.com/Arksine/moonlight/issues/1",
"title": "Announcement Test One",
"description": "This is the description. Anything here should appear in the announcement, up to 512 characters.",
"priority": "normal",
"date": 1646854678,
"dismissed": false,
"date_dismissed": null,
"dismiss_wake": null,
"source": "moonlight",
"feed": "moonlight"
},
{
"entry_id": "arksine/moonraker/issue/349",
"url": "https://github.com/Arksine/moonraker/issues/349",
"title": "PolicyKit warnings; unable to manage services, restart system, or update packages",
"description": "This announcement is an effort to get ahead of a coming change that will certainly result in issues. PR #346 has been merged, and with it are some changes to Moonraker's default behavior.",
"priority": "normal",
"date": 1643392406,
"dismissed": false,
"dismiss_wake": null,
"source": "moonlight",
"feed": "Moonraker"
}
],
"feeds": [
"moonraker",
"klipper",
"moonlight"
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| --------- | :------: | ---------------------------------------------------------- |
| `entries` | [object] | An array of [announcement entry](#announcement-entry-spec) |
| | | objects. The array is sorted by date in descending order |^
| | | (newest to oldest). |^
| `feeds` | [string] | An array of RSS announcement feeds Moonraker is |
| | | currently subscribed to. |^
{ #list-announcements-spec }
| Field | Type | Description |
| ---------------- | :-----------: | ------------------------------------------------------------ |
| `entry_id` | string | A unique identifier for the announcement entry. |
| `url` | string | A url associated with the announcement. This will link to |
| | | a GitHub issue for announcements sourced from `moonlight`. |^
| `title` | string | The title of the announcement. |
| `description` | string | A brief description of the announcement. For announcement's |
| | | sourced from `moonlight` this will be the first paragraph |^
| | | of the associated GitHub issue. Moonlight will truncate |^
| | | truncate descriptions over 512 characters. |^
| `priority` | string | The [priority](#announcement-priority-desc) of the |
| | | announcement. |^
| `date` | int \| float | The announcement creation date in unix time. |
| `dismissed` | bool | Set to `true` if the announcement has been dismissed. |
| `date_dismissed` | float \| null | The date, in unix time, the announcement was last dismissed. |
| | | Will be `null` if the announcement has not been dismissed. |^
| `dismiss_wake` | float \| null | The amount of time remaining, in seconds, before the entry's |
| | | `dismissed` flag reverts to `true`. Will be `null` if the |^
| | | announcement has not been dismissed or if the announcement |^
| | | was dismissed indefinitely. |^
| `source` | string | The [source](#announcement-source-desc) of the announcement. |
| `feed` | string | The registered RSS feed the announcement belongs to. For |
| | | announcements sourced internally this will typically be |^
| | | the name of the component that generated the announcement. |^
{ #announcement-entry-spec } Announcement Entry
| Priority | Description |
| -------- | ----------------------------------------------------------------- |
| `normal` | Standard priority. Front-end devs should use their own discretion |
| | on how to present announcements with normal priority to users. |^
| `high` | High priority. It is recommended that front-ends alert the user |
| | when a high priority announcement is received. |^
{ #announcement-priority-desc } Announcement Priority
| Source | Description |
| ----------- | -------------------------------------------------------------------- |
| `moonlight` | The announcement was received from the |
| | [moonlight](https://github.com/Arksine/moonlight) GitHub repo. |^
| | Announcements received from local XML files when the `announcements` |^
| | module is configured in `dev_mode` will also report the source as |^
| | `moonlight`. |^
| `internal` | The announcement was generated by Moonraker itself. This could |
| | be a component, such as `simplyprint`. |^
{ #announcement-source-desc } Announcement Source
///
## Update announcements
Requests that Moonraker check for announcement updates. This is generally
not required in production, as Moonraker will automatically check for
updates every 30 minutes. However, during development this endpoint is
useful to force an update when it is necessary to perform integration
tests.
```{.http .apirequest title="HTTP Request"}
POST /server/announcements/update
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.announcements.update",
"id": 4654
}
```
Returns:
The current list of announcements, in descending order (newest to oldest)
sorted by `date`, and a `modified` field that contains a boolean value
indicating if the update resulted in a change:
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"entries": [
{
"entry_id": "arksine/moonraker/issue/349",
"url": "https://github.com/Arksine/moonraker/issues/349",
"title": "PolicyKit warnings; unable to manage services, restart system, or update packages",
"description": "This announcement is an effort to get ahead of a coming change that will certainly result in issues. PR #346 has been merged, and with it are some changes to Moonraker's default behavior.",
"priority": "normal",
"date": 1643392406,
"dismissed": false,
"source": "moonlight",
"feed": "Moonraker"
},
{
"entry_id": "arksine/moonlight/issue/1",
"url": "https://github.com/Arksine/moonlight/issues/1",
"title": "Announcement Test One",
"description": "This is the description. Anything here should appear in the announcement, up to 512 characters.",
"priority": "normal",
"date": 1646854678,
"dismissed": true,
"source": "moonlight",
"feed": "Moonlight"
},
{
"entry_id": "arksine/moonlight/issue/2",
"url": "https://github.com/Arksine/moonlight/issues/2",
"title": "Announcement Test Two",
"description": "This is a high priority announcement. This line is included in the description.",
"priority": "high",
"date": 1646855579,
"dismissed": false,
"source": "moonlight",
"feed": "Moonlight"
},
{
"entry_id": "arksine/moonlight/issue/3",
"url": "https://github.com/Arksine/moonlight/issues/3",
"title": "Test announcement 3",
"description": "Test Description [with a link](https://moonraker.readthedocs.io).",
"priority": "normal",
"date": 1647459219,
"dismissed": false,
"source": "moonlight",
"feed": "Moonlight"
}
],
"modified": false
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :------: | ---------------------------------------------------------- |
| `entries` | [object] | An array of [Announcement Entry](#announcement-entry-spec) |
| | | objects. |^
| `modified` | bool | A value of `true` indicates that announcement entries |
| | | were changed after the update operation. |^
///
## Dismiss an announcement
Sets the dismiss flag of an announcement to `true`.
```{.http .apirequest title="HTTP Request"}
POST /server/announcements/dismiss
Content-Type: application/json
{
"entry_id": "arksine/moonlight/issue/1",
"wake_time": 600
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.announcements.dismiss",
"params": {
"entry_id": "arksine/moonlight/issue/1",
"wake_time": 600
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ----------- | :-----------: | ------------ | -------------------------------------------- |
| `entry_id` | string | **REQUIRED** | The entry ID of the announcement to dismiss. |
| `wake_time` | float \| null | null | A time, in seconds, after which the entry's |
| | | | `dismiss` flag will revert to `true`. When |^
| | | | set to `null` the flag will remain `false` |^
| | | | indefinitely. |^
//// tip
The `entry_id` typically contains forward slashes. Remember to escape this value
if including it in the query string of an HTTP request.
////
///
```{.json .apiresponse title="Example Response"}
{
"entry_id": "arksine/moonlight/issue/1"
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :----: | ------------------------------------------------- |
| `entry_id` | string | The entry ID of the dismissed announcement entry. |
///
## List announcement feeds
```{.http .apirequest title="HTTP Request"}
GET /server/announcements/feeds
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.announcements.feeds",
"id": 4654
}
```
```{.json .apiresponse title="Example Response"}
{
"feeds": [
"moonraker",
"klipper"
]
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| ------- | :------: | ----------------------------------------------------- |
| `feeds` | [string] | An array of announcement feeds Moonraker is currently |
| | | subscribed to. |^
///
## Subscribe to an announcement feed
Subscribes Moonraker to the announcement feed specified in the request.
```{.http .apirequest title="HTTP Request"}
POST /server/announcements/feed
Content-Type: application/json
{
"name": "my_feed"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.announcements.post_feed",
"params": {
"name": "my_feed"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------ | :----: | ------------ | -------------------------------------------------- |
| `name` | string | **REQUIRED** | The name of the announcement feed to subscribe to. |
///
```{.json .apiresponse title="Example Response"}
{
"feed": "my_feed",
"action": "added"
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| -------- | :----: | -------------------------------------------------------- |
| `feed` | string | The name of the announcement feed subscribed to. |
| `action` | string | The [subscription action](#feed-subscribed-action-desc ) |
| | | taken by Moonraker after the request has been processed. |^
| Action | Description |
| --------- | ------------------------------------------------------- |
| `added` | The requested announcement feed has been subscribed to. |
| `skipped` | Moonraker was already subscribed to the requested feed. |
{ #feed-subscribed-action-desc } Subscription Action
///
## Remove an announcement feed
Removes a subscribed feed. Only feeds previously subscribed to using
the [subscribe feed](#subscribe-to-an-announcement-feed) endpoint may be
removed. Feeds configured in `moonraker.conf` may not be removed.
```{.http .apirequest title="HTTP Request"}
DELETE /server/announcements/feed?name=my_feed
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.announcements.delete_feed",
"params": {
"name": "my_feed"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------ | :----: | ------------ | -------------------------------------------- |
| `name` | string | **REQUIRED** | The name of the announcement feed to remove. |
///
Parameters:
- `name`: The name of the new feed to remove. This parameter is required.
Returns:
The name of the new feed and the action taken. The `action` will be
`removed` if the operation was successful.
```{.json .apiresponse title="Example Response"}
{
"feed": "my_feed",
"action": "removed"
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| -------- | :----: | ------------------------------------------------------ |
| `feed` | string | The name of the announcement feed removed. |
| `action` | string | The action taken after the request. Will be `removed` |
| | | upon successful removal. |^
//// tip
Unlike the [feed subscription request](#subscribe-to-an-announcement-feed) an
error will be returned if either the feed does not exist or the feed is
configured in `moonraker.conf`.
////
///
## Appendix
This section will provide an overview of how the announcement system
in Moonraker works, how to set up a dev environment, and provide
recommendations on front-end implementation.
### How announcements work
Moonraker announcements are GitHub issues tagged with the `announcement`
label. GitHub repos may registered with
[moonlight](https://github.com/arksine/moonlight), which is responsible
for generating RSS feeds from GitHub issues using GitHub's REST API. These
RSS feeds are hosted on GitHub Pages, for example Moonraker's feed may be found
[here](https://arksine.github.io/moonlight/assets/moonraker.xml). By
centralizing GitHub API queries in `moonlight` we are able to poll multiple
repos without running into API rate limit issues. Moonlight has has a workflow
that checks all registered repos for new announcements every 30 minutes. In
theory it would be able to check for announcements in up to 500 repos before
exceeding GitHub's API rate limit.
Moonraker's `[announcements]` component will always check the `klipper` and
`moonraker` RSS feeds. It is possible to configure additional RSS feeds by
adding them to the `subscriptions` option. The component will poll configured
feeds every 30 minutes, resulting in maximum of 1 hour for new announcements
to reach all users.
When new issues are tagged with `announcement` these entries will be parsed
and added to the RSS feeds. When the issue is closed they will be removed from
the corresponding feed. Moonlight will fetch up to 20 announcements for each
feed, if a repo goes over this limit older announcements will be removed.
/// Note
It is also possible for Moonraker to generate announcements itself. For
example, if a Moonraker component needs user feedback it may generate an
announcement and notify all connected clients. From a front-end's
perspective there is no need to treat these announcements differently than
any other announcement.
///
### Setting up the dev environment
Moonraker provides configuration to parse announcements from a local folder
so that it is possible to manually add and remove entries, allowing front-end
developers to perform integration tests:
```ini
# moonraker.conf
[announcements]
dev_mode: True
```
With `dev_mode` enabled, Moonraker will look for`moonraker.xml` and
`klipper.xml` in the following folder:
```shell
~/moonraker/.devel/announcement_xml
```
If moonraker is not installed in the home folder then substitute `~`
for the parent folder location. This folder is in a hardcoded location
to so as not to expose users to vulnerabilities associated with parsing XML.
It is possible to configure Moonraker to search for your own feeds:
```ini
# moonraker.conf
[announcements]
subscription:
my_project
dev_mode: True
```
The above configuration would look for `my_project.xml` in addition to
`klipper.xml` and `moonraker.xml`. The developer may manually create
the xml feeds or they may clone `moonlight` and leverage its script
to generate a feed from issues created on their test repo. When local
feeds have been modified one may call the [update announcements API](#update-announcements)
to have Moonraker fetch the updates and add/remove entries.
### RSS file structure
Moonlight generates RSS feeds in XML format. Below is an example generated
from moonlight's own issue tracker:
```xml
<?xml version='1.0' encoding='utf-8'?>
<rss version="2.0" xmlns:moonlight="https://arksine.github.io/moonlight">
<channel>
<title>arksine/moonlight</title>
<link>https://github.com/Arksine/moonlight</link>
<description>RSS Announcements for Moonraker</description>
<pubDate>Tue, 22 Mar 2022 23:19:04 GMT</pubDate>
<moonlight:configHash>f2912192bf0d09cf18d8b8af22b2d3501627043e5afa3ebff0e45e4794937901</moonlight:configHash>
<item>
<title>Test announcement 3</title>
<link>https://github.com/Arksine/moonlight/issues/3</link>
<description>Test Description [with a link](https://moonraker.readthedocs.io).</description>
<pubDate>Wed, 16 Mar 2022 19:33:39 GMT</pubDate>
<category>normal</category>
<guid>arksine/moonlight/issue/3</guid>
</item>
<item>
<title>Announcement Test Two</title>
<link>https://github.com/Arksine/moonlight/issues/2</link>
<description>This is a high priority announcement. This line is included in the description.</description>
<pubDate>Wed, 09 Mar 2022 19:52:59 GMT</pubDate>
<category>high</category>
<guid>arksine/moonlight/issue/2</guid>
</item>
<item>
<title>Announcement Test One</title>
<link>https://github.com/Arksine/moonlight/issues/1</link>
<description>This is the description. Anything here should appear in the announcement, up to 512 characters.</description>
<pubDate>Wed, 09 Mar 2022 19:37:58 GMT</pubDate>
<category>normal</category>
<guid>arksine/moonlight/issue/1</guid>
</item>
</channel>
</rss>
```
Each xml file may contain only one `<rss>` element, and each `<rss>` element
may contain only one channel. All items must be present aside from
`moonlight:configHash`, which is used by the workflow to detect changes to
moonlight's configuration. Most elements are self explanatory, developers will
be most interested in adding and removing `<item>` elements, as these are
the basis for entries in Moonraker's announcement database.
### Generating announcements from your own repo
As mentioned previously, its possible to clone moonlight and use its rss
script to generate announcements from issues in your repo:
```shell
cd ~
git clone https://github.com/arksine/moonlight
cd moonlight
virtualenv -p /usr/bin/python3 .venv
source .venv/bin/activate
pip install httpx[http2]
deactivate
```
To add your repo edit `~/moonlight/src/config.json`:
```json
{
"moonraker": {
"repo_owner": "Arksine",
"repo_name": "moonraker",
"description": "API Host For Klipper",
"authorized_creators": ["Arksine"]
},
"klipper": {
"repo_owner": "Klipper3d",
"repo_name": "klipper",
"description": "A 3D Printer Firmware",
"authorized_creators": ["KevinOConnor"]
},
// Add your test repo info here. It should contain
// fields matching those in "moonraker" and "klipper"
// shown above.
}
```
Once your repo is added, create one or more issues on your GitHub
repo tagged with the `announcement` label. Add the `critical` label to
one if you wish to test high priority announcements. You may need to
create these labels in your repo before they can be added.
Now we can use moonlight to generate the xml files:
```shell
cd ~/moonlight
source .venv/bin/activate
src/update_rss.py
deactivate
```
After the script has run it will generate the configured RSS feeds
and store them in `~/moonlight/assets`. If using this method it may
be useful to create a symbolic link to it in Moonraker's devel folder:
```shell
cd ~/moonraker
mkdir .devel
cd .devel
ln -s ~/moonlight/assets announcement_xml
```
If you haven't done so, configure Moonraker to subscribe to your feed
and restart the Moonraker service. Otherwise you may call the
[announcement update](#update-announcements) API to have Moonraker
parse the announcements from your test feed.
### Implementation details and recommendations
When a front-end first connects to Moonraker it is recommended that the
[list announcements](#list-announcements) API is called to retrieve
the current list of [announcement entries](#announcement-entry-spec).
If the front-end is connected via websocket it may watch for the
[announcement update](./jsonrpc_notifications.md#announcement-update-event) and
[announcement dismissed](./jsonrpc_notifications.md#announcement-dismissed-event)
JSON-RPC notifications and update its UI accordingly.
Front-end devs should decide how they want to present announcements to users.
They could be treated as any other notification, for example a front-end
may have a notification icon that shows the current number of unread
announcements. Front-ends can mark an announcement as `read` by calling
the [dismiss announcement](#dismiss-an-announcement) endpoint. Any
announcement entry with `dismissed == true` should be considered read.
When a `high priority` announcement is detected it is recommended that
clients present the announcement in a format that is immediately visible
to the user. That said, it may be wise to allow users to opt out of
this behavior via configuration.
/// note
If an announcement is dismissed, closed on GitHub, then reopened,
the `dismissed` flag will reset to false. This is expected behavior
as announcements are pruned from the database when they are no
longer present in feeds. It isn't valid for repo maintainers
to re-open a closed announcement. That said, its fine to close
and re-open issues during development and testing using repos
that are not yet registered with moonlight.
///

View File

@@ -0,0 +1,635 @@
# Authorization and Authentication
The Authorization endpoints provide access to the various methods
used to authorize connections to Moonraker. This includes user
authentication, API Key authentication, Temporary access via
"oneshot tokens", and IP and/or domain based authentication
("ie: trusted clients).
Untrusted clients must use either a JSON Web Token or an API key to access
Moonraker's HTTP APIs. JWTs should be included in the `Authorization`
header as a `Bearer` type for each HTTP request. If using an API Key it
should be included in the `X-Api-Key` header for each HTTP Request.
Websocket authentication can be achieved via the request itself or
post connection. Unlike HTTP requests it is not necessary to pass a
token and/or API Key to each request. The
[identify connection](./server.md#identify-connection) endpoint takes optional
`access_token` and `api_key` parameters that may be used to authenticate
a user already logged in, otherwise the `login` API may be used for
authentication. Websocket connections will stay authenticated until
the connection is closed or the user logs out.
User authentication can be performed using a choice sources. Moonraker
currently supports the following authentication sources:
| Source Name | Description |
| ----------- | -------------------------------------------------------------- |
| `moonraker` | Authentication is performed using credentials stored in |
| | Moonraker's database. |^
| `ldap` | Authentication is performed through a connected LDAP provider. |
| | Requires a valid `[LDAP]` configuration. |^
{ #auth-source-desc } Authentication Source
/// note
ECMAScript imposes limitations on certain requests that prohibit the
developer from modifying the HTTP headers (ie: Requests to open a
websocket, "download" requests that open a user dialog). In these cases
it is recommended for the developer to request a `oneshot_token`, then
send the result via the `token` query string argument in the desired
request.
///
/// warning
It is strongly recommended that arguments for the below APIs are
passed in the request's body.
///
## Login User
```{.http .apirequest title="HTTP Request"}
POST /access/login
Content-Type: application/json
{
"username": "my_user",
"password": "my_password",
"source": "moonraker"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.login",
"params": {
"username": "my_user",
"password": "my_password",
"source": "moonraker"
},
"id": 1323
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ---------- | :----: | -------------------- | --------------------------------------------------- |
| `username` | string | **REQUIRED** | The user login name. |
| `password` | string | **REQUIRED** | The user password. |
| `source` | string | Set by configuration | A valid [authentication source](#auth-source-desc). |
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"username": "my_user",
"token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAiTW9vbnJha2VyIiwgImlhdCI6IDE2MTg4NzY4MDAuNDgxNjU1LCAiZXhwIjogMTYxODg4MDQwMC40ODE2NTUsICJ1c2VybmFtZSI6ICJteV91c2VyIiwgInRva2VuX3R5cGUiOiAiYXV0aCJ9.QdieeEskrU0FrH7rXKuPDSZxscM54kV_vH60uJqdU9g",
"refresh_token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAiTW9vbnJha2VyIiwgImlhdCI6IDE2MTg4NzY4MDAuNDgxNzUxNCwgImV4cCI6IDE2MjY2NTI4MDAuNDgxNzUxNCwgInVzZXJuYW1lIjogIm15X3VzZXIiLCAidG9rZW5fdHlwZSI6ICJyZWZyZXNoIn0.btJF0LJfymInhGJQ2xvPwkp2dFUqwgcw4OA_wE-EcCM",
"action": "user_logged_in",
"source": "moonraker"
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| --------------- | :----: | -------------------------------------------------------------------- |
| `username` | string | The name of the logged in user. |
| `token` | string | A JSON Web Token (JWT) used to authenticate requests, also commonly |
| | | referred to as an `access token`. HTTP requests should include this |^
| | | token in the `Authorization` header as a `Bearer` type. This token |^
| | | expires after 1 hour. |^
| `refresh_token` | string | A JWT that should be used to generate new access tokens after they |
| | | expire. See the [refresh token section](#refresh-json-web-token) |^
| | | for details. |^
| `action` | string | The action taken by the auth manager. Will always be |
| | | "user_logged_in". |^
| `source` | string | The [authentication source](#auth-source-desc) used. |
///
/// note
This endpoint may be accessed without prior authentication. A 401 will
only be returned if the authentication fails.
///
## Logout Current User
```{.http .apirequest title="HTTP Request"}
POST /access/logout
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.logout",
"id": 1323
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"username": "my_user",
"action": "user_logged_out"
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :----: | ----------------------------------------------------- |
| `username` | string | The name of the logged out user. |
| `action` | string | The action taken by the auth manager. Will always be |
| | | "user_logged_out". |^
///
## Get Current User
```{.http .apirequest title="HTTP Request"}
GET /access/user
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.get_user",
"id": 1323
}
```
Returns: An object containing the currently logged in user name, the source and
the date on which the user was created (in unix time).
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"username": "my_user",
"source": "moonraker",
"created_on": 1618876783.8896716
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ------------ | :----: | ---------------------------------------------------- |
| `username` | string | The name of the logged in user. |
| `source` | string | The [source](#auth-source-desc) used to authenticate |
| | | the user. |^
| `created_on` | float | The date, in unix time, the user entry was created. |
///
## Create User
Creates a new local user and logs them in.
```{.http .apirequest title="HTTP Request"}
POST /access/user
Content-Type: application/json
{
"username": "my_user",
"password": "my_password"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.post_user",
"params": {
"username": "my_user",
"password": "my_password"
},
"id": 1323
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ---------- | :----: | ------------ | -------------------- |
| `username` | string | **REQUIRED** | The user login name. |
| `password` | string | **REQUIRED** | The user password. |
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"username": "my_user",
"token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAiTW9vbnJha2VyIiwgImlhdCI6IDE2MTg4NzY3ODMuODkxNjE5LCAiZXhwIjogMTYxODg4MDM4My44OTE2MTksICJ1c2VybmFtZSI6ICJteV91c2VyIiwgInRva2VuX3R5cGUiOiAiYXV0aCJ9.oH0IShTL7mdlVs4kcx3BIs_-1j0Oe-qXezJKjo-9Xgo",
"refresh_token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAiTW9vbnJha2VyIiwgImlhdCI6IDE2MTg4NzY3ODMuODkxNzAyNCwgImV4cCI6IDE2MjY2NTI3ODMuODkxNzAyNCwgInVzZXJuYW1lIjogIm15X3VzZXIiLCAidG9rZW5fdHlwZSI6ICJyZWZyZXNoIn0.a6ZeRjk8RQQJDDH0JV-qGY_d_HIgfI3XpsqUlUaFT7c",
"source": "moonraker",
"action": "user_created"
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| --------------- | :----: | --------------------------------------------------------------------- |
| `username` | string | The name of the created user. |
| `token` | string | A JSON Web Token (JWT) used to authenticate requests, also commonly |
| | | referred to as an `access token`. HTTP requests should include this |^
| | | token in the `Authorization` header as a `Bearer` type. This token |^
| | | expires after 1 hour. |^
| `refresh_token` | string | A JWT that should be used to generate new access tokens after they |
| | | expire. See the [refresh token section](#refresh-json-web-token) |^
| | | for details. |^
| `action` | string | The action taken by the auth manager. Will always be "user_created". |
| `source` | string | The [authentication source](#auth-source-desc) used. |
///
/// note
Unlike `/access/login`, `/access/user` is a protected endpoint. To
create a new user a client must either be trusted, use the API Key,
or be logged in as another user.
///
## Delete User
/// note
A request to delete a user MUST come from an authorized login
other than the account to be deleted. This can be a "trusted user",
the "api key user", or any other user account.
///
```{.http .apirequest title="HTTP Request"}
DELETE /access/user
Content-Type: application/json
{
"username": "my_username"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.delete_user",
"params": {
"username": "my_username"
},
"id": 1323
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ---------- | :--: | ------------ | ------------------------------------ |
| `username` | str | **REQUIRED** | The username of the entry to delete. |
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"username": "my_user",
"action": "user_deleted"
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :----: | ------------------------------------------------- |
| `username` | string | The username of the deleted entry. |
| `action` | string | The action taken by the auth manager. Will always |
| | | be "user_deleted". |^
///
## List Available Users
```{.http .apirequest title="HTTP Request"}
GET /access/users/list
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.users.list",
"id": 1323
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"users": [
{
"username": "testuser",
"source": "moonraker",
"created_on": 1618771331.1685035
},
{
"username": "testuser2",
"source": "ldap",
"created_on": 1620943153.0191233
}
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ------- | :------: | -------------------------------- |
| `users` | [object] | An array of `User Info` objects. |
| | | #user-info-spec |+
| Field | Type | Description |
| ------------ | :----: | ---------------------------------------------------- |
| `username` | string | The username of the entry. |
| `source` | string | The [source](#auth-source-desc) that must be used to |
| | | authenticate the user. |^
| `created_on` | float | The date, in unix time, the user entry was created. |
{ #user-info-spec } User Info
///
## Reset User Password
```{.http .apirequest title="HTTP Request"}
POST /access/user/password
Content-Type: application/json
{
"password": "my_current_password",
"new_password": "my_new_pass"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.user.password",
"params": {
"password": "my_current_password",
"new_password": "my_new_pass"
},
"id": 1323
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| -------------- | :----: | ------------ | ---------------------------- |
| `password` | string | **REQUIRED** | The user's current password. |
| `new_password` | string | **REQUIRED** | The user's new password. |
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"username": "my_user",
"action": "user_password_reset"
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :----: | --------------------------------------------------- |
| `username` | string | The username of the entry whose password was reset. |
| `action` | string | Action taken by the Auth manager. Will always be |
| | | "user_password_reset". |^
///
## Refresh JSON Web Token
This endpoint can be used to refresh an expired access token. If this
request returns an error then the refresh token is no longer valid and
the user must login with their credentials.
```{.http .apirequest title="HTTP Request"}
POST /access/refresh_jwt
Content-Type: application/json
{
"refresh_token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAiTW9vbnJha2VyIiwgImlhdCI6IDE2MTg4Nzc0ODUuNzcyMjg5OCwgImV4cCI6IDE2MjY2NTM0ODUuNzcyMjg5OCwgInVzZXJuYW1lIjogInRlc3R1c2VyIiwgInRva2VuX3R5cGUiOiAicmVmcmVzaCJ9.Y5YxGuYSzwJN2WlunxlR7XNa2Y3GWK-2kt-MzHvLbP8"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.refresh_jwt",
"params": {
"refresh_token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAiTW9vbnJha2VyIiwgImlhdCI6IDE2MTg4Nzc0ODUuNzcyMjg5OCwgImV4cCI6IDE2MjY2NTM0ODUuNzcyMjg5OCwgInVzZXJuYW1lIjogInRlc3R1c2VyIiwgInRva2VuX3R5cGUiOiAicmVmcmVzaCJ9.Y5YxGuYSzwJN2WlunxlR7XNa2Y3GWK-2kt-MzHvLbP8"
},
"id": 1323
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| --------------- | :----: | ------------ | ------------------------------------- |
| `refresh_token` | string | **REQUIRED** | A valid `refresh_token` for the user. |
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"username": "my_user",
"token": "eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAiTW9vbnJha2VyIiwgImlhdCI6IDE2MTg4NzgyNDMuNTE2Nzc5MiwgImV4cCI6IDE2MTg4ODE4NDMuNTE2Nzc5MiwgInVzZXJuYW1lIjogInRlc3R1c2VyIiwgInRva2VuX3R5cGUiOiAiYXV0aCJ9.Ia_X_pf20RR4RAEXcxalZIOzOBOs2OwearWHfRnTSGU",
"source": "moonraker",
"action": "user_jwt_refresh"
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :----: | -------------------------------------------------------------------- |
| `username` | string | The username of the entry whose access token ws refreshed. |
| `token` | string | A JSON Web Token (JWT) used to authenticate requests, also commonly |
| | | referred to as an `access token`. HTTP requests should include this |^
| | | token in the `Authorization` header as a `Bearer` type. This token |^
| | | expires after 1 hour. |^
| `source` | string | The [authentication source](#auth-source-desc) of the user entry. |
| `action` | string | The action taken by the Auth Manager. Will always be |
| | | "user_jwt_refresh". |^
///
/// note
This endpoint may be accessed by unauthorized clients. A 401 will
only be returned if the refresh token is invalid.
///
## Generate a Oneshot Token
Javascript is not capable of modifying the headers for some HTTP requests
(for example, the `websocket`), which is a requirement to apply JWT or API Key
authorization. To work around this clients may request a Oneshot Token and
pass it via the query string for these requests. Tokens expire in 5 seconds
and may only be used once, making them relatively safe for inclusion in the
query string.
```{.http .apirequest title="HTTP Request"}
GET /access/oneshot_token
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.oneshot_token",
"id": 1323
}
```
```{.json .apiresponse title="Example Response"}
"APDBEGHUTBUD6SOAYBPF3KE5BRMO7YSL"
```
/// api-response-spec
open: True
The response is a string value containing the oneshot token. It may
added to a request's query string for access to any API endpoint. The query
string should be added in the form of:
```
?token={base32_random_token}
```
///
## Get authorization module info
```{.http .apirequest title="HTTP Request"}
GET /access/info
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.info",
"id": 1323
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"default_source": "moonraker",
"available_sources": [
"moonraker",
"ldap"
],
"login_required": false,
"trusted": true
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ------------------- | :------: | ---------------------------------------------------- |
| `default_source` | string | The configured default |
| | | [authentication source](#auth-source-desc). |^
| `available_sources` | [string] | An array of available authentication sources. |
| `login_required` | bool | Set to `true` when `force_logins` is enabled via the |
| | | configuration at least one user has been created. |^
| `trusted` | bool | Set to `true` when the connection making the info |
| | | request is a trusted connection. |^
///
/// note
This endpoint may be accessed by unauthorized clients.
///
## Get the Current API Key
```{.http .apirequest title="HTTP Request"}
GET /access/api_key
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.get_api_key",
"id": 1323
}
```
```{.json .apiresponse title="Example Response"}
e514851f37b94c779d955212b6906f95
```
/// api-response-spec
open: True
The response string value containing the current API key.
///
## Generate a New API Key
```{.http .apirequest title="HTTP Request"}
POST /access/api_key
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "access.post_api_key",
"id": 1323
}
```
```{.json .apiresponse title="Example Response"}
e514851f37b94c779d955212b6906f95
```
/// api-response-spec
open: True
The response string value containing the new API key.
///
/// note
After this request executes the API key change is applied immediately.
All subsequent HTTP requests from untrusted clients must use the new key.
Changing the API Key will not affect open websockets authenticated using
the previous API Key.
///

View File

@@ -0,0 +1,773 @@
# Database Management
The following endpoints provide access to Moonraker's internal sqlite database.
The primary table exposed to clients is divided into `namespaces`. Each client
may define its own namespace to store information. From the client's point of
view, a namespace is an `object`. Items in the database are accessed by providing
a namespace and a key. A key may be specified as string, where a "." is a
delimiter to access nested fields. Alternatively the key may be specified
as an array of strings, where each string references a nested field.
This is useful for scenarios where a namespace contains fields that include
a "." character, such as a file name.
/// note
Moonraker reserves several namespaces for internal use. Clients may read from
these namespaces but they may not modify them.
///
For example, assume the following object is stored in the "superclient"
namespace:
```json
{
"settings": {
"console": {
"enable_autocomplete": true
}
},
"theme": {
"background_color": "black"
}
}
```
One may access the `enable_autocomplete` field by supplying `superclient` as
the `namespace` argument and `settings.console.enable_autocomplete` or
`["settings", "console", "enable_autocomplete"]` as the `key` argument for
the request. The entire settings object could be accessed by providing
`settings` or `["settings"]` as the `key` argument. The entire namespace
may be read by omitting the `key` argument, however as explained below it
is not possible to modify a namespace without specifying a key.
## List Database Info
Lists all namespaces with read and/or write access. Also lists database
backup files.
```{.http .apirequest title="HTTP Request"}
GET /server/database/list
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.database.list",
"id": 8694
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"namespaces": [
"gcode_metadata",
"webcams",
"update_manager",
"announcements",
"database",
"moonraker"
],
"backups": [
"sqldb-backup-20240513-134542.db",
"testbackup.db",
"testbackup2.db"
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ------------ | :------: | ---------------------------------------------------- |
| `namespaces` | [string] | An array of namespaces registered with the database |
| | | that may be read by clients. |^
| `backups` | [string] | An array of database backup filenames that have been |
| | | created. |^
///
## Get Database Item
Retrieves an item from a specified namespace. The `key` argument may be
omitted, in which case an object representing the entire namespace will
be returned in the `value` field. If the `key` is provided and does not
exist in the database an error will be returned.
```{.http .apirequest title="HTTP Request"}
GET /server/database/item?namespace={namespace}&key={key}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.database.get_item",
"params": {
"namespace": "{namespace}",
"key": "{key}"
},
"id": 5644
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ----------- | :----------------: | ------------ | ------------------------------------------ |
| `namespace` | string | **REQUIRED** | The namespace of the item to retrieve. |
| `key` | string \| [string] | null | The key indicating the field or fields |
| | \| null | | within the namespace to retrieve. May |^
| | | | be a string, where nested fields are |^
| | | | separated by a ".", or a list of strings. |^
| | | | If the key is omitted the entire namespace |^
| | | | will be returned. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"namespace": "moonraker",
"key": "file_manager.metadata_version",
"value": 2
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ----------- | :----------------: | ------------------------------------------------- |
| `namespace` | string | The namespace of the returned item. |
| `key` | string \| [string] | The key indicating the requested field(s). |
| | \| null | |^
| `value` | any | The value of the requested item. This can be any |
| | | valid JSON type. |^
///
## Add Database Item
Inserts an item into the database. If the `namespace` does not exist
it will be created. If the `key` specifies a nested field, all parents
will be created if they do not exist. If the key exists it will be
overwritten with the provided `value`. The `key` parameter must be provided,
as it is not possible to assign a value directly to a namespace.
/// note
If the request parameters are placed in the query string and the `value`
is not a string type, then `value` argument must provide a
[type hint](./introduction.md#query-string-type-hints). It is strongly
recommended to put parameters in the body of the request wrapped in a
JSON object.
///
```{.http .apirequest title="HTTP Request"}
POST /server/database/item
Content-Type: application/json
{
"namespace": "my_client",
"key": "settings.some_count",
"value": 100
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ----------- | :----------------: | ------------ | ----------------------------------------- |
| `namespace` | string | **REQUIRED** | The namespace where the value |
| | | | should be inserted. |^
| `key` | string \| [string] | **REQUIRED** | The key indicating the field or fields |
| | | | where the value should be inserted. |^
| `value` | any | **REQUIRED** | The value to insert in the database. May |
| | | | be any valid JSON type. |^
///
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.database.post_item",
"params": {
"namespace": "{namespace}",
"key": "{key}",
"value": 100
},
"id": 4654
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"namespace": "test",
"key": "settings.some_count",
"value": 9001
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ----------- | :----------------: | ------------------------------------------- |
| `namespace` | string | The namespace where the value was inserted. |
| `key` | string \| [string] | The key indicating the field or fields |
| | | where the value was inserted. |^
| `value` | any | The value inserted into the database. May |
| | | be any valid JSON type. |^
///
## Delete Database Item
Deletes an item from a `namespace` at the specified `key`. If the key does not
exist in the namespace an error will be returned. If the deleted item results
in an empty namespace, the namespace will be removed from the database.
```{.http .apirequest title="HTTP Request"}
DELETE /server/database/item?namespace={namespace}&key={key}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.database.delete_item",
"params": {
"namespace": "{namespace}",
"key": "{key}"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ----------- | :----------------: | ------------ | -------------------------------------- |
| `namespace` | string | **REQUIRED** | The namespace where the item should be |
| | | | should be removed. |^
| `key` | string \| [string] | **REQUIRED** | The key indicating the field or fields |
| | | | where the item should be removed. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"namespace": "test",
"key": "settings.some_count",
"value": 9001
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ----------- | :----------------: | ------------------------------------------ |
| `namespace` | string | The namespace containing the item removed. |
| `key` | string \| [string] | The key indicating the field or fields |
| | | where the item was removed. |^
| `value` | any | The of the item at the removed field. May |
| | | be any valid JSON type. |^
///
## Compact Database
Compacts and defragments the the sqlite database using the `VACUUM` command.
This endpoint cannot be requested when Klipper is printing.
```{.http .apirequest title="HTTP Request"}
POST /server/database/compact
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.database.compact",
"id": 4654
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"previous_size": 139264,
"new_size": 122880
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| --------------- | :--: | -------------------------------------------------- |
| `previous_size` | int | Size in bytes of the database prior to compaction. |
| `new_size` | int | Size in bytes of the database after compaction. |
///
## Backup Database
Creates a backup of the current database. The backup will be
created in the `<data_path>/backup/database/<filename>`.
This API cannot be requested when Klipper is printing.
```{.http .apirequest title="HTTP Request"}
POST /server/database/backup
Content-Type: application/json
{
"filename": "sql-db-backup.db"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.database.post_backup",
"params": {
"filename": "sql-db-backup.db"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ---------- | :----: | -------------------------- | -------------------------- |
| `filename` | string | sqldb-backup-{timespec}.db | The file name of the saved |
| | | | backup file. |^
//// note
The `{timespec}` of the default `filename` is in the following format:
`<year><month><day>-<hour><minute><second>`
////
///
```{.json .apiresponse title="Example Response"}
{
"backup_path": "/home/test/printer_data/backup/database/sql-db-backup.db"
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| ------------- | :----: | ------------------------------------------------------ |
| `backup_path` | string | The complete absolute path where the backup was saved. |
///
## Delete a backup
Deletes a previously backed up database.
```{.http .apirequest title="HTTP Request"}
DELETE /server/database/backup?filename=sql-db-backup.db
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.database.delete_backup",
"params": {
"filename": "sql-db-backup.db"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ---------- | :----: | ------------ | ---------------------------------------------- |
| `filename` | string | **REQUIRED** | The name of the backup file to delete. Must be |
| | | | a valid filename reported by the |^
| | | | [database list endpoint](#list-database-info). |^
///
```{.json .apiresponse title="Example Response"}
{
"backup_path": "/home/test/printer_data/backup/database/sql-db-backup.db"
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| ------------- | :----: | -------------------------------------------------------- |
| `backup_path` | string | The complete absolute path where the backup was removed. |
///
## Restore Database
Restores a previously backed up sqlite database file. The backup
must be located at `<data_path>/backup/database/<filename>`. The
`<filename>` must be a valid filename reported in by the
[database list](#list-database-info) API.
This API cannot be requested when Klipper is printing.
/// Note
Moonraker will restart immediately after this request is processed.
///
```{.http .apirequest title="HTTP Request"}
POST /server/database/restore
Content-Type: application/json
{
"filename": "sql-db-backup.db"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.database.restore",
"params": {
"filename": "sql-db-backup.db"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ---------- | :----: | ------------ | ----------------------------------------------- |
| `filename` | string | **REQUIRED** | The name of the backup file to restore. Must be |
| | | | a valid filename reported by the |^
| | | | [database list endpoint](#list-database-info). |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"restored_tables": [
"table_registry",
"namespace_store",
"authorized_users",
"job_history",
"job_totals"
],
"restored_namespaces": [
"database",
"fluidd",
"gcode_metadata",
"mainsail",
"moonraker",
"update_manager",
"webcams"
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| --------------------- | :------: | ------------------------------------------- |
| `restored_tables` | [string] | An array of table names that were recovered |
| | | after the restore operation. |^
| `restored_namespaces` | [string] | An array of namespaces that were recovered |
| | | after the restore operation. |^
///
## Debug endpoints
Below are a number of debug endpoints available when Moonraker has been
launched with [debug features enabled](../installation.md#command-line-usage).
Front ends should not rely on these endpoints in production releases, however
they may be useful during development. Developers writing extensions and/or
additions to Moonraker may also find these endpoints useful.
/// Warning
Debug endpoints may expose security vulnerabilities. They should only be
enabled by developers on secured machines.
///
### List Database Info (debug)
Debug version of the [List Database Info](#list-database-info) endpoint.
Returns all namespaces, including those exclusively reserved for Moonraker.
In addition all registered SQL tables are reported.
```{.http .apirequest title="HTTP Request"}
GET /debug/database/list
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "debug.database.list",
"id": 8694
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"namespaces": [
"gcode_metadata",
"webcams",
"update_manager",
"announcements",
"database",
"moonraker"
],
"backups": [
"sqldb-backup-20240513-134542.db",
"testbackup.db",
"testbackup2.db"
],
"tables": [
"job_history",
"job_totals",
"namespace_store",
"table_registry",
"authorized_users"
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ------------ | :------: | -------------------------------------------------------- |
| `namespaces` | [string] | An array of all namespaces registered with the database. |
| `backups` | [string] | An array of database backup filenames that have been |
| | | created. |^
| `tables` | [string] | An array of tables created within the database. |
///
### Get Database Item (debug)
Debug version of the [Get Database Item](#get-database-item) endpoint.
Keys within protected and forbidden namespaces may be read.
```http title="HTTP Request"
GET /debug/database/item?namespace={namespace}&key={key}
```
```json title="JSON-RPC Request"
{
"jsonrpc": "2.0",
"method": "debug.database.get_item",
"params": {
"namespace": "{namespace}",
"key": "{key}"
},
"id": 5644
}
```
See the [Get Database Item](#get-database-item) endpoint for the
`Parameter Specification`, `Example Response`, and `Response Specification`.
### Add Database Item (debug)
Debug version of the [Add Database Item](#add-database-item) endpoint.
Keys within protected and forbidden namespaces may be inserted.
/// Warning
Modifying protected namespaces outside of Moonraker can result in
broken functionality and is not supported for production environments.
Issues opened with reports/queries related to this endpoint will be
redirected to this documentation and closed.
///
```{.http .apirequest title="HTTP Request"}
POST /debug/database/item
Content-Type: application/json
{
"namespace": "my_client",
"key": "settings.some_count",
"value": 100
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "debug.database.post_item",
"params": {
"namespace": "{namespace}",
"key": "{key}",
"value": 100
},
"id": 4654
}
```
See the [Add Database Item](#add-database-item) endpoint for the
`Parameter Specification`, `Example Response`, and `Response Specification`.
### Delete Database Item (debug)
Debug version of [Delete Database Item](#delete-database-item). Keys within
protected and forbidden namespaces may be removed.
/// Warning
Modifying protected namespaces outside of Moonraker can result in
broken functionality and is not supported for production environments.
Issues opened with reports/queries related to this endpoint will be
redirected to this documentation and closed.
///
```{.http .apirequest title="HTTP Request"}
DELETE /debug/database/item?namespace={namespace}&key={key}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "debug.database.delete_item",
"params": {
"namespace": "{namespace}",
"key": "{key}"
},
"id": 4654
}
```
See the [Delete Database Item](#delete-database-item) endpoint for the
`Parameter Specification`, `Example Response`, and `Response Specification`.
### Get Database Table
Requests all the contents of a specified table.
```{.http .apirequest title="HTTP Request"}
GET /debug/database/table?table=job_history
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "debug.database.table",
"params": {
"table": "job_history"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------- | :----: | ------------ | --------------------------------- |
| `table` | string | **REQUIRED** | The name of the table to request. |
///
Returns:
An object with the table's name and a list of all rows contained
within the table. The `rowid` will always be included for each
row, however it may be represented by an alias. In the example
below the alias for `rowid` is `job_id`.
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"table_name": "job_history",
"rows": [
{
"job_id": 1,
"user": "No User",
"filename": "active_test.gcode",
"status": "completed",
"start_time": 1690749153.2661753,
"end_time": 1690749173.076986,
"print_duration": 0.0,
"total_duration": 19.975574419135228,
"filament_used": 0.0,
"metadata": {
"size": 211,
"modified": 1635771217.0,
"uuid": "627371e0-faa5-4ced-8bb4-7017d29226fa",
"slicer": "Unknown",
"gcode_start_byte": 8,
"gcode_end_byte": 211
},
"auxiliary_data": [],
"instance_id": "default"
},
{
"job_id": 2,
"user": "No User",
"filename": "active_test.gcode",
"status": "completed",
"start_time": 1701262034.9242446,
"end_time": 1701262054.7332363,
"print_duration": 0.0,
"total_duration": 19.990913168992847,
"filament_used": 0.0,
"metadata": {
"size": 211,
"modified": 1635771217.0,
"uuid": "627371e0-faa5-4ced-8bb4-7017d29226fa",
"slicer": "Unknown",
"gcode_start_byte": 8,
"gcode_end_byte": 211
},
"auxiliary_data": {
"spool_ids": [
2
]
},
"instance_id": "default"
}
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ------------ | :------: | -------------------------------------------------- |
| `table_name` | string | The name of the table requested. |
| `rows` | [object] | An array of row objects. The fields for each |
| | | object are columns defined by the table schema. |^
| | | The `rowid` will always be included for each row, |^
| | | however it may be represented by an alias. In the |^
| | | example above, `job_id` is an alias for `rowid`. |^
///

1442
docs/external_api/devices.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,277 @@
# Extensions
Moonraker has limited support for 3rd party extensions through the
use of its API. Extensions must establish a Websocket or Unix Socket
connection and [identify](./server.md#identify-connection) themselves
as an `agent`.
The endpoints in this section can be broken down into two categories:
- Endpoints used by Front Ends and other clients to manage and manipulate
extensions.
- Endpoints specific to agents that provide functional enhancements not
available to other client types.
## Extension Management
### List Extensions
Returns a list of all available extensions. Currently Moonraker can only
be officially extended through connected `agents`.
```{.http .apirequest title="HTTP Request"}
GET /server/extensions/list
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.extensions.list",
"id": 4564
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"agents": [
{
"name": "moonagent",
"version": "0.0.1",
"type": "agent",
"url": "https://github.com/arksine/moontest"
}
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| -------- | :------: | --------------------------------------------------- |
| `agents` | [object] | An array of [Agent Info](#agent-info-spec) objects. |
| Field | Type | Description |
| --------- | :----: | -------------------------------------------------- |
| `name` | string | The name provided by the registered agent. |
| `version` | string | The version of the software reported by the agent. |
| `type` | string | The client type. Will always be `agent`. |
| `url` | string | A url to the agent software's webpage. |
{ #agent-info-spec } Agent Info
///
### Call an extension method
This endpoint may be used to call a method on a connected agent.
The request effectively relays a JSON-RPC request from a front end
or other client to the agent. Agents should document their
available methods so Moonraker client developers can interact
with them.
```{.http .apirequest title="HTTP Request"}
POST /server/extensions/request
Content-Type: application/json
{
"agent": "moonagent",
"method": "moontest.hello_world",
"arguments": {"argone": true, "argtwo": 9000}
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.extensions.request",
"params":{
"agent": "moonagent",
"method": "moontest.hello_world",
"arguments": {"argone": true, "argtwo": 9000}
},
"id": 4564
}
```
Parameters:
/// api-parameters
open: True
| Name | Type | Default | Description |
| ----------- | :-------------: | ------------ | -------------------------------- |
| `agent` | string | **REQUIRED** | The name of the registered agent |
| | | | hosting the requested method. |^
| `method` | string | **REQUIRED** | The name of the method to call. |
| `arguments` | array \| object | null | The arguments to send with the |
| | | | method. This may be an array |^
| | | | containing positional arguments |^
| | | | or an object containing keyword |^
| | | | arguments. A value of `null` |^
| | | | will omit arguments from the |^
| | | | request. |^
///
/// api-response-spec
open: True
The result received from the agent will be returned directly. See
the agent's documentation for response specifications
///
## Agent specific endpoints
/// Note
These endpoints are only available to connections that have
identified themselves as an `agent` type.
///
### Send an agent event
Sends a [JSON-RPC notification](./jsonrpc_notifications.md#agent-events)
containing the supplied event info to all of Moonraker's persistent
connections.
```{.http .apirequest title="HTTP Request"}
Not Available
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "connection.send_event",
"params":{
"event": "my_event",
"data": {"my_arg": "optional data"}
}
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------- | :----: | ------------ | -------------------------------------------- |
| `event` | string | **REQUIRED** | The name of the event. This may be any |
| | | | name other than those reserved by Moonraker. |^
| `data` | any | undefined | The data to send with the event. This can be |
| | | | any valid JSON decodable value. If omitted |^
| | | | no data is sent with the event. |^
//// Note
The `connected` and `disconnected` events are reserved for use
by Moonraker and may not be sent from agents.
////
///
```{.apiresponse title="Response when JSON-RPC 'id' present"}
ok
```
/// note
An agent may send an event without specifying the JSON-RPC `id` field.
In this case Moonraker will not return a response.
///
### Register a method with Klipper
Registers a "remote method" with Klipper that can be called
from GCode Macros.
```{.http .apirequest title="HTTP Request"}
Not Available
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "connection.register_remote_method",
"params": {
"method_name": "firemon_alert_heated"
}
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------------- | :----: | ------------ | --------------------------------------------- |
| `method_name` | string | **REQUIRED** | The name of the remote method to register |
| | | | with Klipper. It is recommended for agents |^
| | | | to use a unique identifier, such as a prefix, |^
| | | | to prevent collisions with other remote |^
| | | | methods registered with Klipper. |^
///
```{.apiresponse title= Response"}
ok
```
/// Note
Methods registered by agents will persist until the agent disconnects.
Upon connection it is only necessary that they register their desired
methods once.
///
#### Remote Method Example
Presume an application named `firemon` has connected to Moonraker's websocket
and identified itself as an `agent`. After identification it registers a
remote method named `firemon_alert_heated` using the JSON-RPC request
example above.
In addition, the user has following `gcode_macro` configured in `printer.cfg`:
```ini
# printer.cfg
[gcode_macro ALERT_HEATED]
gcode:
{% if not params %}
{action_call_remote_method("firemon_alert_heated")}
{% else %}
{% set htr = params.HEATER|default("unknown") %}
{% set tmp = params.TEMP|default(0)|float %}
{action_call_remote_method(
"firemon_alert_heated", heater=htr, temp=tmp)}
{% endif %}
```
When the `ALERT_HEATED HEATER=extruder TEMP=200` gcode is executed by Klipper,
the agent will receive the following JSON-RPC request from Moonraker:
```{.json .apiresponse title="Remote Method Call"}
{
"jsonrpc": "2.0",
"method": "firemon_alert_heated",
"params": {
"heater": "extruder",
"temp": 200
}
}
```
When the `ALERT_HEATED` gcode is executed with no parameters, the agent will
receive the following JSON-RPC request from Moonraker:
```{.json .apiresponse title="Remote Method Call"}
{
"jsonrpc": "2.0",
"method": "monitor_alert_heated"
}
```
/// Note
Remote methods called from Klipper never contain the JSON-RPC "id" field,
as Klipper does not accept return values to remote methods.
///

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,452 @@
# Job History
Moonraker's `history` component tracks print job completion data.
The following endpoints are available to manage Moonraker's job
history data.
## Get job list
```{.http .apirequest title="HTTP Request"}
GET /server/history/list?limit=50&start=50&since=1&before=5&order=asc
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.history.list",
"params":{
"limit": 50,
"start": 10,
"since": 464.54,
"before": 1322.54,
"order": "asc"
},
"id": 5656
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| -------- | :----: | --------- | ----------------------------------------------- |
| `limit` | int | 50 | Maximum number of job entries to return. |
| `start` | int | 0 | The record number indicating the first entry |
| | | | of the returned list. |^
| `before` | float | undefined | A timestamp in unix time. When specified, the |
| | | | returned list will only contain entries created |^
| | | | before this date. |^
| `since` | float | undefined | A timestamp in unix time. When specified, the |
| | | | returned list will only contain entries created |^
| | | | after this date. |^
| `order` | string | "desc" | The order of the list returned. May be `asc` |
| | | | (ascending) or `desc` (descending). |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"count": 1,
"jobs": [
{
"job_id": "000001",
"exists": true,
"end_time": 1615764265.6493807,
"filament_used": 7.83,
"filename": "test/history_test.gcode",
"metadata": {
// Object containing metadata at time of job
},
"print_duration": 18.37201827496756,
"status": "completed",
"start_time": 1615764496.622146,
"total_duration": 18.37201827496756,
"user": "testuser",
"auxiliary_data": [
{
"provider": "sensor hist_test",
"name": "power_consumption",
"value": 4.119977,
"description": "Printer Power Consumption",
"units": "kWh"
},
{
"provider": "sensor hist_test",
"name": "max_current",
"value": 2.768851,
"description": "Maximum current draw",
"units": "A"
},
{
"provider": "sensor hist_test",
"name": "min_current",
"value": 0.426725,
"description": "Minimum current draw",
"units": "A"
},
{
"provider": "sensor hist_test",
"name": "avg_current",
"value": 1.706872,
"description": "Average current draw",
"units": "A"
},
{
"provider": "sensor hist_test",
"name": "status",
"value": 2,
"description": "Power Switch Status",
"units": null
},
{
"provider": "sensor hist_test",
"name": "filament",
"value": 19.08058495194607,
"description": "filament usage tracker",
"units": "mm"
},
{
"provider": "spoolman",
"name": "spool_ids",
"value": [
1
],
"description": "Spool IDs used",
"units": null
}
]
}
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ------- | :------: | -------------------------------------------------- |
| `count` | int | The number of entries returned by the query. |
| `jobs` | [object] | An array of [Job History](#job-history-entry-spec) |
| | | objects. |^
| Field | Type | Description |
| ---------------- | :------------: | ----------------------------------------------------------- |
| `job_id` | string | A unique ID for the entry. |
| `user` | string \| null | The user that started the job. Will be `null` |
| | | if Moonraker cannot identify a user (ie: job) |^
| | | was started via Klipper's display. |^
| `filename` | string | The path, relative to `gcodes` root, of the file |
| | | associated with the job. |^
| `exists` | bool | A value of `true` indicates that the file |
| | | associated with the job exists on disk and has |^
| | | not been modified. |^
| `status` | string | The [job status](#job-history-status-desc) |
| | | at the time of query. |^
| `start_time` | float | A timestamp, in unix time, indicating when |
| | | the job started. |^
| `end_time` | float \| null | A timestamp, in unix time, indicating when |
| | | the job finished. Will be `null` if the |^
| | | job is in progress or if Moonraker is |^
| | | interrupted prior to the job completion. |^
| `print_duration` | float | The amount of time, in seconds, the job |
| | | spent printing (ie: printer not idle). |^
| `total_duration` | float | The total amount of time, in seconds, the |
| | | job took to print. This includes time paused. |^
| `filament_used` | float | The amount of filament (in mm) used during the job. |
| `metadata` | object | The [gcode metadata](./file_manager.md#gcode-metadata-spec) |
| | | object associated with the job. The `job_id` and |^
| | | `print_start_time` fields are removed from the metadata as |^
| | | they are redundant. |^
| `auxiliary_data` | [object] | An array of [auxiliary field](#job-history-aux-field-spec) |
| | | objects containing supplemental history data related to |^
| | | the job. |^
{ #job-history-entry-spec } Job History
| Field | Type | Description |
| ------------- | :------------: | ------------------------------------------------- |
| `provider` | string | The component or extension that generated the |
| | | auxiliary field. |^
| `name` | string | A name identifying the field. |
| `description` | string | A brief description of the data in this entry. |
| `value` | any | The value associated with the field. Can be any |
| | | valid JSON type. |^
| `units` | string \| null | The unit type associated with the value. For |
| | | example this would be `mm` for millimeters. Can |^
| | | be `null` if no unit abbreviation is appropriate. |^
{ #job-history-aux-field-spec } Auxiliary Field
| Status | Description |
| ------------------- | ----------------------------------------------------- |
| `in_progress` | The job is currently active. |
| `completed` | The job successfully completed. |
| `cancelled` | The job was cancelled by the user. |
| `error` | The job was aborted due to an error during execution. |
| `klippy_shutdown` | The job was aborted due to Klippy Shutdown. |
| `klippy_disconnect` | Moonraker's connection to Klippy was lost while the |
| | job was in progress. |^
| `interrupted` | Moonraker was abruptly terminated while the job was |
| | in progress. |^
{ #job-history-status-desc } Job Status
///
## Get job totals
```{.http .apirequest title="HTTP Request"}
GET /server/history/totals
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.history.totals",
"id": 5656
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"job_totals": {
"total_jobs": 3,
"total_time": 11748.077333278954,
"total_print_time": 11348.794790096988,
"total_filament_used": 11615.718840001999,
"longest_job": 11665.191012736992,
"longest_print": 11348.794790096988
},
"auxiliary_totals": [
{
"provider": "sensor hist_test",
"field": "power_consumption",
"maximum": 4.119977,
"total": 4.119977
},
{
"provider": "sensor hist_test",
"field": "avg_current",
"maximum": 1.706872,
"total": null
},
{
"provider": "sensor hist_test",
"field": "filament",
"maximum": 19.08058495194607,
"total": 19.08058495194607
}
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ------------------ | :------: | ----------------------------------------------- |
| `job_totals` | object | A [Job Totals](#job-history-totals-spec) object |
| | | reporting all current totals. |^
| `auxiliary_totals` | [object] | An array of |
| | | [Auxiliary Total](#job-auxiliary-totals-spec) |^
| | | objects. |^
| Field | Type | Description |
| --------------------- | :------: | ------------------------------------------------------ |
| `total_jobs` | int | The total number of jobs tracked. |
| `total_time` | float | The total amount of job work time (in seconds) |
| | | across all jobs, including time paused. |^
| `total_print_time` | float | The total amount of time printing (in seconds) |
| | | across all jobs. |^
| `total_filament_used` | float | The total amount of filament used (in mm) across |
| | | all jobs. |^
| `longest_job` | float | The maximum time spent working on a single job, |
| | | including time paused. |^
| `longest_print` | float | The maximum time spent printing a single job. |
| `auxiliary_totals` | [object] | An array of |
| | | [Auxiliary Total](#job-auxiliary-totals-spec) objects. |^
{ #job-history-totals-spec } Job Totals
| Field | Type | Description |
| ---------- | :-----------: | ----------------------------------------------- |
| `provider` | string | The component or extension that generated the |
| | | auxiliary totals. |^
| `field` | string | The corresponding `name` of the auxiliary field |
| | | used to generate totals. |^
| `maximum` | float \| null | The maximum value observed across all prints. |
| | | Will be `null` if the maximum is not available. |^
| `total` | float \| null | The accumulated total value across all prints. |
| | | Will be `null` if the total is not available. |^
{ #job-auxiliary-totals-spec } Auxiliary Total
///
## Reset totals
Resets the persistent "job totals" to zero.
```{.http .apirequest title="HTTP Request"}
POST /server/history/reset_totals
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.history.reset_totals",
"id": 5534
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"last_totals": {
"total_jobs": 3,
"total_time": 11748.077333278954,
"total_print_time": 11348.794790096988,
"total_filament_used": 11615.718840001999,
"longest_job": 11665.191012736992,
"longest_print": 11348.794790096988
},
"last_auxiliary_totals": [
{
"provider": "sensor hist_test",
"field": "power_consumption",
"maximum": 4.119977,
"total": 4.119977
},
{
"provider": "sensor hist_test",
"field": "avg_current",
"maximum": 1.706872,
"total": null
},
{
"provider": "sensor hist_test",
"field": "filament",
"maximum": 19.08058495194607,
"total": 19.08058495194607
}
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ----------------------- | :------: | ----------------------------------------------- |
| `last_totals` | object | A [Job Totals](#job-history-totals-spec) object |
| | | reporting all totals prior to the reset. |^
| `last_auxiliary_totals` | [object] | An array of |
| | | [Auxiliary Total](#job-auxiliary-totals-spec) |^
| | | objects reporting totals prior to the reset. |^
///
## Get a single job
```{.http .apirequest title="HTTP Request"}
GET /server/history/job?uid=<id>
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.history.get_job",
"params":{"uid": "{uid}"},
"id": 4564
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ----- | :----: | ------------ | --------------------------------------- |
| `uid` | string | **REQUIRED** | The unique identifier for the requested |
| | | | job history. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"job": {
"job_id": "000001",
"exists": true,
"end_time": 1615764265.6493807,
"filament_used": 7.83,
"filename": "test/history_test.gcode",
"metadata": {
// Object containing metadata at time of job
},
"print_duration": 18.37201827496756,
"status": "completed",
"start_time": 1615764496.622146,
"total_duration": 18.37201827496756
}
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ----- | :----: | ------------------------------------------------------------- |
| `job` | object | The requested [Job History](#job-history-entry-spec ) object. |
///
## Delete a job
```{.http .apirequest title="HTTP Request"}
DELETE /server/history/job?uid=<id>
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.history.delete_job",
"params":{
"uid": "{uid}"
},
"id": 5534
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ----- | :----: | --------------- | ------------------------------------------ |
| `uid` | string | **REQUIRED** | The unique identifier for the job entry |
| | | if `all==false` | to delete. |^
| `all` | bool | false | When set to `true` all job history entries |
| | | | will be removed. |^
//// tip
If `all = true` is specified the `uid` parameter should be omitted.
////
///
```{.json .apiresponse title="Example Response"}
{
"deleted_jobs": [
"000000",
"000001"
]
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| -------------- | :------: | ------------------------------------- |
| `deleted_jobs` | [string] | An array of unique IDs indicating the |
| | | job entries that were deleted. |^
///

View File

@@ -0,0 +1,782 @@
# Third Party Integrations
## Apprise Notifier
Moonraker supports configurable push notifications using the
[apprise](https://github.com/caronc/apprise) library. The
endpoints in this section may be used to manage/view registered
notifiers.
The following endpoints are available when at least one
`[notifier <name>]` section has been configured in `moonraker.conf`.
### List Notifiers
```{.http .apirequest title="HTTP Request"}
GET /server/notifiers/list
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.notifiers.list",
"id": 4654
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"notifiers": [
{
"name": "print_start",
"url": "tgram://{bottoken}/{ChatID}",
"events": [
"started"
],
"body": "Your printer started printing '{event_args[1].filename}'",
"title": null,
"attach": null
},
{
"name": "print_complete",
"url": "tgram://{bottoken}/{ChatID}",
"events": [
"complete"
],
"body": "Your printer completed printing '{event_args[1].filename}",
"title": null,
"attach": "http://192.168.1.100/webcam/?action=snapshot"
},
{
"name": "print_error",
"url": "tgram://{bottoken}/{ChatID}",
"events": [
"error"
],
"body": "{event_args[1].message}",
"title": null,
"attach": "http://192.168.1.100/webcam/?action=snapshot"
}
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ----------- | :------: | ---------------------------------------------------- |
| `notifiers` | [object] | An array of [Notifier Status](#notifier-status-spec) |
| | | objects. |^
| Field | Type | Description |
| -------- | :------------: | ---------------------------------------------------- |
| `name` | string | The configured name of the notifier. |
| `url` | string | The notifier's destination url. |
| `events` | [string] | An array that contains one or more |
| | | [events](#notifier-event-desc) which will trigger |^
| | | the push notification. |^
| `body` | string \| null | The content to send in the body of the notification. |
| | | Will be `null` if no body is configured. |^
| `title` | string \| null | The title of the notification. Will be `null` if no |
| | | title is configured |^
| `attach` | string \| null | One or more attachments added to the notification. |
| | | Multiple attachments are separated by newlines. Will |^
| | | be `null` if no attachment is configured. |^
{ #notifier-status-spec } Notifier Status
| Event | Description |
| ----------- | ------------------------------------------ |
| `standby` | The printer has entered its standby state. |
| `started` | A print job has started. |
| `paused` | A print job has paused. |
| `resumed` | A print job has resumed. |
| `complete` | A print job has successfully finished. |
| `error` | A print job exited with an error. |
| `cancelled` | A print job was cancelled by the user. |
{ #notifier-event-desc } Available Notifier Events
//// note
The `url`, `body`, `title`, and `attach` parameters may contain Jinja 2
templates. All templates are evaluated before the notification is
pushed.
////
///
### Test a notifier (debug)
Forces a registered notifier to push a notification.
/// note
This endpoint is only available when Moonraker's debug
features are enabled and should not be implemented
in production code
///
```{.http .apirequest title="HTTP Request"}
POST /debug/notifiers/test
Content-Type: application/json
{
"name": "notifier_name"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "debug.notifiers.test",
"params": {
"name": "notifier_name"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------ | :----: | ------------ | --------------------------------- |
| `name` | string | **REQUIRED** | The name of the notifier to test. |
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"status": "success",
"stats": {
"print_duration": 0.0,
"total_duration": 0.0,
"filament_used": 0.0,
"filename": "notifier_test.gcode",
"state": "standby",
"message": "",
"info": {
"total_layer": null,
"current_layer": null
}
}
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| -------- | :----: | ----------------------------------------- |
| `status` | string | The status of the test result. Currently |
| | | will always be `success`. |^
| `stats` | object | A [Print Stats](#print-stats-spec) object.| |
| Field | Type | Description |
| ---------------- | :----: | -------------------------------------------------- |
| `print_duration` | float | Time spent printing the current job in seconds. |
| | | Does not include time paused. |^
| `total_duration` | float | Total job duration in seconds. |
| `filament_used` | float | Amount of filament used for the current job in mm. |
| `filename` | string | File path of the current job, relative to the |
| | | `gcodes` root. |^
| `state` | string | The current job [state](#print-stats-state-desc). |
| `message` | string | A status message set by Klipper. Will be an empty |
| | | string if no message is set. |^
| `info` | object | A `Print Stats Supplemental Info` object. |
| | | #print-stats-supplemental-info-spec |+
{#print-stats-spec} Print Stats
| Field | Type | Description |
| --------------- | :---------: | -------------------------------------------- |
| `total_layer` | int \| null | The total layer count of the current |
| | | job. Will be null if the total layer |^
| | | count is not set. |^
| `current_layer` | int \| null | The index of the layer the job is currently |
| | | printing. Will be null of the current layer |^
| | | is not set. |^
{#print-stats-supplemental-info-spec} Print Stats Supplemental Info
| State | Description |
| ----------- | ---------------------------------------------- |
| `standby` | The printer is standing by for a job to begin. |
| `printing` | A job is currently printing. |
| `paused` | A print job has paused. |
| `complete` | A print job has successfully finished. |
| `error` | A print job exited with an error. |
| `cancelled` | A print job was cancelled by the user. |
{ #print-stats-state-desc } Print Stats State
///
## Spoolman
[Spoolman](https://github.com/Donkie/Spoolman) is a spool
tracking web service that can manage spool data across
multiple printers. Moonraker has support for updating and retrieving
spool data through its `[spoolman]` integration.
The following endpoints are available when the `[spoolman]` component
has been configured.
### Get Spoolman Status
Returns the current status of the spoolman module.
```{.http .apirequest title="HTTP Request"}
GET /server/spoolman/status
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.spoolman.status",
"id": 4654
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"spoolman_connected": false,
"pending_reports": [
{
"spool_id": 1,
"filament_used": 10
}
],
"spool_id": 2
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| -------------------- | :---------: | ---------------------------------------------- |
| `spoolman_connected` | bool | Indicates that Moonraker has an established |
| | | websocket connection to Spoolman. |^
| `pending_reports` | [object] | An array of `Pending Spoolman Report` objects. |
| | | A pending report is a report that has not yet |^
| | | been sent to Spoolman. This may be because |^
| | | Spoolman is not available or because the |^
| | | current batch of reports are waiting for the |^
| | | internal report timer to schedule them. |^
| | | #spoolman-report-spec |+
| `spool_id` | int \| null | The ID of the currently tracked spool. A value |
| | | of `null` indicates that no spool ID is set |^
| | | and tracking is disabled. |^
| Field | Type | Description |
| --------------- | :---: | --------------------------------------------- |
| `spool_id` | int | The ID of the spool with pending report data. |
| `filament_used` | float | The amount of used filament to report in mm. |
{ #spoolman-report-spec } Pending Reports
///
### Set active spool
Set the active ID of the spool to track filament usage and report
to Spoolman.
```{.http .apirequest title="HTTP Request"}
POST /server/spoolman/spool_id
Content-Type: application/json
{
"spool_id": 1
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.spoolman.post_spool_id",
"params": {
"spool_id": 1
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ---------- | :---------: | ------- | ---------------------------------- |
| `spool_id` | int \| null | null | The new active spool ID. A `null` |
| | | | value will unset the previous |^
| | | | active spool and disable tracking. |^
///
```{.json .apiresponse title="Example Response"}
{
"spool_id": 1
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :---------: | ---------------------------------------------- |
| `spool_id` | int \| null | The ID of the currently tracked spool. A value |
| | | of `null` indicates that no spool ID is set |^
| | | and tracking is disabled. |^
///
### Get active spool
Retrieve the ID of the spool to which Moonraker reports usage for Spoolman.
```{.http .apirequest title="HTTP Request"}
GET /server/spoolman/spool_id
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.spoolman.get_spool_id",
"id": 4654
}
```
```{.json .apiresponse title="Example Response"}
{
"spool_id": 1
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :---------: | ---------------------------------------------- |
| `spool_id` | int \| null | The ID of the currently tracked spool. A value |
| | | of `null` indicates that no spool ID is set |^
| | | and tracking is disabled. |^
///
### Proxy
Proxy an API request to the Spoolman Server.
See Spoolman's [OpenAPI Description](https://donkie.github.io/Spoolman/) for
detailed information about it's API.
/// Note
The version 2 response has been added to eliminate ambiguity between
Spoolman errors and Moonraker errors. With version 1 a frontend
is not able to reliably to determine if the error is sourced from
Spoolman or Moonraker. Version 2 responses will return success
unless Moonraker is the source of the error.
The version 2 response is currently opt-in to avoid breaking
existing implementations, however in the future it will be
required, at which point the version 1 response will be removed.
The version 1 response is now deprecated.
///
```{.http .apirequest title="HTTP Request"}
POST /server/spoolman/proxy
Content-Type: application/json
{
"request_method": "POST",
"path": "/v1/spool",
"query": "a=1&b=4",
"body": {
"filament_id": 1
}
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.spoolman.proxy",
"params": {
"use_v2_response": true,
"request_method": "POST",
"path": "/v1/spool",
"query": "a=1&b=4",
"body": {
"filament_id": 1
}
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ----------------- | :----: | ------------ | ---------------------------------------- |
| `use_v2_response` | bool | false | When set to `true` the request will |
| | | | return a version 2 response. |^
| `request_method` | string | **REQUIRED** | The HTTP request method of the API |
| | | | call to proxy. |^
| `path` | string | **REQUIRED** | The path section of the API endpoint to |
| | | | proxy. It must include the version, ie: |^
| | | | `/v1/filament` |^
| `query` | string | null | An optional query string component of |
| | | | the URL to proxy. A `null` value |^
| | | | will omit the query string. |^
| `body` | object | null | An optional body containing request |
| | | | parameters for the API call. This |^
| | | | should be a JSON encodable object. |^
| | | | A `null` value will send an empty body. |^
///
/// collapse-code
```{.json .apiresponse title="Example Success Response (Version 2)"}
{
"response": {
"id": 2,
"registered": "2023-11-23T12:18:31Z",
"first_used": "2023-11-22T12:17:56.123000Z",
"last_used": "2023-11-23T10:17:59.900000Z",
"filament": {
"id": 2,
"registered": "2023-11-23T12:17:44Z",
"name": "Reactor Red",
"vendor": {
"id": 2,
"registered": "2023-06-26T21:00:42Z",
"name": "Fusion"
},
"material": "PLA",
"price": 25,
"density": 1.24,
"diameter": 1.75,
"weight": 1000,
"color_hex": "BD0B0B"
},
"remaining_weight": 950,
"used_weight": 50,
"remaining_length": 318519.4384459262,
"used_length": 16764.18097083822,
"archived": false
},
"error": null
}
```
///
/// collapse-code
```{.json .apiresponse title="Example Error Response (Version 2)"}
{
"response": null,
"error": {
"status_code": 404,
"message": "No spool with ID 3 found."
}
}
```
///
/// api-response-spec
open: True
//// Note
Version 1 responses are proxied directly. See Spoolman's API
documentation for response specifications. Errors are also
proxied directly.
////
| Field | Type | Description |
| ---------- | :------------: | ------------------------------------------- |
| `response` | object \| null | On success will be an object containing the |
| | | response received from Spoolman. Will be |^
| | | `null` if an error is received. |^
| `error` | object \| null | On error will be a `Spoolman Error` object. |
| | | Will be `null` on successful requests. |^
| | | #spoolman-error-spec |+
{ #version2-success-spec} Version 2 response
| Field | Type | Description |
| ------------- | :----: | --------------------------------------------- |
| `status_code` | int | The HTTP status code of the response. |
| `message` | string | The error message received with the response. |
{ #spoolman-error-spec} Spoolman Error
///
## OctoPrint API emulation
Supports the minimal API requirements necessary to add compatibility
with the `upload G-Code to OctoPrint` feature present on 3rd party
applications, such as slicers. Developers of Moonraker applications
*should not* implement these APIs.
These endpoints are available when the `[octoprint_compat]` feature
has been configured in `moonraker.conf`
/// tip
Most slicers now support Moonraker's native upload interface,
reducing the need for these endpoints.
///
/// note
Unlike all other Moonraker responses, OctoPrint responses are
not wrapped in an object with a `result` field. This section
will not include parameter and response specifications, they
can be found in OctoPrint's API documentation.
In addition, many values in the responses returned by Moonraker
are simply placeholders and have no real meaning with regard
to Moonraker's internal state.
///
### Version information
```{.http .apirequest title="HTTP Request"}
GET /api/version
```
```{.json .apirequest title="JSON-RPC Request"}
Not Available
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"server": "1.5.0",
"api": "0.1",
"text": "OctoPrint (Moonraker v0.3.1-12)"
}
```
///
### Server status
```{.http .apirequest title="HTTP Request"}
GET /api/server
```
```{.json .apirequest title="JSON-RPC Request"}
Not Available
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"server": "1.5.0",
"safemode": "settings"
}
```
///
### Login verification & User information
```{.http .apirequest title="HTTP Request"}
GET /api/login
```
```{.json .apirequest title="JSON-RPC Request"}
Not Available
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"_is_external_client": false,
"_login_mechanism": "apikey",
"name": "_api",
"active": true,
"user": true,
"admin": true,
"apikey": null,
"permissions": [],
"groups": ["admins", "users"]
}
```
///
### Get settings
```{.http .apirequest title="HTTP Request"}
GET /api/settings
```
```{.json .apirequest title="JSON-RPC Request"}
Not Available
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"plugins": {
"UltimakerFormatPackage": {
"align_inline_thumbnail": false,
"inline_thumbnail": false,
"inline_thumbnail_align_value": "left",
"inline_thumbnail_scale_value": "50",
"installed": true,
"installed_version": "0.2.2",
"scale_inline_thumbnail": false,
"state_panel_thumbnail": true
}
},
"feature": {
"sdSupport": false,
"temperatureGraph": false
},
"webcam": {
"flipH": false,
"flipV": false,
"rotate90": false,
"streamUrl": "/webcam/?action=stream",
"webcamEnabled": true
}
}
```
///
/// note
The webcam route in the response is hardcoded to Fluidd/Mainsail
default path. The UFP plugin reports that it is installed so the
Cura-OctoPrint plugin will upload in the preferred UFP format.
///
### OctoPrint File Upload
```{.http .apirequest title="HTTP Request"}
POST /api/files/local
```
```{.json .apirequest title="JSON-RPC Request"}
Not Available
```
Alias for Moonraker's [file upload API](./file_manager.md#file-upload).
### Get Job status
```{.http .apirequest title="HTTP Request"}
GET /api/job
```
```{.json .apirequest title="JSON-RPC Request"}
Not Available
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"job": {
"file": {"name": null},
"estimatedPrintTime": null,
"filament": {"length": null},
"user": null
},
"progress": {
"completion": null,
"filepos": null,
"printTime": null,
"printTimeLeft": null,
"printTimeOrigin": null
},
"state": "Offline"
}
```
///
### Get Printer status
```{.http .apirequest title="HTTP Request"}
GET /api/printer
```
```{.json .apirequest title="JSON-RPC Request"}
Not Available
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"temperature": {
"tool0": {
"actual": 22.25,
"offset": 0,
"target": 0
},
"bed": {
"actual": 22.25,
"offset": 0,
"target": 0
}, ...<additional heaters>
},
"state": {
"text": "state",
"flags": {
"operational": true,
"paused": false,
"printing": false,
"cancelling": false,
"pausing": false,
"error": false,
"ready": false,
"closedOrError": false
}
}
}
```
///
### Send GCode command
```{.http .apirequest title="HTTP Request"}
POST /api/printer/command
Content-Type: application/json
{
"commands": ["G28"]
}
```
```{.json .apirequest title="JSON-RPC Request"}
Not Available
```
```{.json .apiresponse title="Example Response"}
{}
```
### List Printer profiles
```{.http .apirequest title="HTTP Request"}
GET /api/printerprofiles
```
```{.json .apirequest title="JSON-RPC Request"}
Not Available
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"profiles": {
"_default": {
"id": "_default",
"name": "Default",
"color": "default",
"model": "Default",
"default": true,
"current": true,
"heatedBed": true,
"heatedChamber": false
}
}
}
```
///

View File

@@ -0,0 +1,510 @@
# Introduction
Moonraker provides APIs over two protocols, HTTP and JSON-RPC. Most
endpoints have corresponding APIs over both protocols. When requests
are exclusive to a protocol or depend on some other condition it will
be noted in the documentation for that specific API.
At a high level, file transfer requests (upload and download) are exclusive
to the HTTP API. The Websocket is required to receive events such as status
updates and gcode responses. For information on how to set up the Websocket,
please see the [Miscellaneous Tutorials](#websocket-setup).
## HTTP API Overview
Moonraker's HTTP API could be described as "REST-ish". Attempts are made to
conform to REST standards, however the dynamic nature of Moonraker's endpoint
registration along with the need to keep consistency between two API protocols
results in an HTTP API that deviates
Moonraker is capable of parsing request arguments from the both the body
(either JSON or form-data depending on the `Content-Type` header) and from
the query string. All arguments are grouped together in one data structure,
with body arguments taking precedence over query arguments. Thus
if the same argument is supplied both in the body and in the
query string the body argument would be used. It is left up to the front end
developer to decide exactly how they want to provide arguments.
Nearly all successful HTTP requests will return a json encoded object in
the form of:
```text
{
"result": <response data>
}
```
The response data may be any valid JSON type. In most cases it will be
a JSON object itself, but some requests may return a simple string.
If the response is not wrapped in an object with a `result` field it will
be noted in the documentation for that API (or API set). Generally this
only applies to endpoints that attempt to emulate other backends.
Should a request result in an error, a standard error code along with
an error specific message is returned, wrapped in a JSON object.
### Query string type hints
By default all arguments passed via the query string are represented as
strings. Most endpoint handlers know the data type for each of their
arguments, thus they can perform conversion from a string type if necessary.
However some endpoints accept arguments of a "generic" type, thus the
client is responsible for specifying the type if "string" is not desirable.
This is not a problem for websocket requests as the JSON parser can extract
the appropriate type. HTTP requests must provide "type hints" in these
scenarios. Moonraker supplies support for the following query string type hints:
- int
- bool
- float
- json
The `json` type hint can be specified to pass an array or an object via
the query string. Remember to percent encode the json string so that
the query string is correctly parsed.
Type hints may be specified by post-fixing them to a key, with a ":"
separating the key and the hint. For example, lets assume that we
have a request that takes `seconds` (integer) and `enabled` (boolean)
arguments. The query string with type hints might look like:
```
?seconds:int=120&enabled:bool=true
```
A query string that takes a `value` argument with which we want to
pass an object, `{foo: 21.5, bar: "hello"}` might look like:
```
?value:json=%7B%22foo%22%3A21.5%2C%22bar%22%3A%22hello%22%7D
```
As you can see, a percent encoded json string is not human readable,
thus using this functionality should be seen as a "last resort." If at
all possible clients should attempt to put these arguments in the body
of a request.
## JSON-RPC API Overview
Websocket, Unix Socket, and MQTT connections exclusively use the API
available over [JSON-RPC 2.0](https://jsonrpc.org). In addition, Moonraker
provides an [JSON-RPC HTTP endpoint](#json-rpc-over-http-endpoint) giving
developers who want to avoid persistent connections a choice to use JSON-RPC.
The Websocket transmits and receives JSON-RPC objects in text frames. MQTT
transmits them in the payload of a topic defined when MQTT is configured. By
default, Moonraker receives JSON-RPC requests from the
`{instance_name}/moonraker/api/request` topic, and publishes responses to the
`{instance_name}/moonraker/api/response` topic. The `{instance_name}` must be
a unique identifier for each instance of Moonraker connected to the broker.
It defaults to the machine's host name.
An encoded request should look something like:
```json
{
"jsonrpc": "2.0",
"method": "API method",
"params": {"arg_one": 1, "arg_two": true},
"id": 354
}
```
The `params` field may be left out if the API request takes no arguments.
The `id` should be a unique value that has no chance of colliding
with other JSON-RPC requests. The `method` is the API method, as defined
for each API in this document.
/// details | Optional MQTT timestamp
type: tip
MQTT requests may provide an optional `mqtt_timestamp` keyword
argument in the `params` field of the JSON-RPC request. To avoid
potential collisions from time drift it is recommended to specify
the timestamp in microseconds since the Unix Epoch. If provided
Moonraker will use the timestamp to discard duplicate requests.
It is recommended to either provide a timestamp or publish API
requests at a QoS level of 0 or 2.
///
A successful request will return a response like the following:
```json
{
"jsonrpc": "2.0",
"result": {"res_data": "success"},
"id": 354
}
```
The `result` will generally contain an object, but as with the HTTP API in some
cases it may simply return a string. The `id` field will return an id that
matches the one provided by the request.
Requests that result in an error will receive a properly formatted
JSON-RPC response:
```json
{
"jsonrpc": "2.0",
"error": {"code": 36000, "message": "Error Message"},
"id": 354
}
```
Some errors may not return a request ID, such as an improperly formatted request.
The [moontest](https://www.github.com/arksine/moontest) repo includes a basic
test interface with example usage for most of the requests below. It also
includes a basic JSON-RPC implementation that uses promises to return responses
and errors (see json-rpc.js).
## Websocket Connections
### Primary websocket
The primary websocket supports Moonraker's JSON-RPC API. Most applications that
desire a websocket connection will make use of the primary websocket.
The primary websocket is available at:
```
ws://host_or_ip:port/websocket`
```
The primary websocket will remain connected until the application disconnects
or Moonraker is shutdown.
### Bridge websocket
The "bridge" websocket provides a near direct passthrough to Klipper's API
Server. Klipper uses its own RPC protocol, which is effectively a simplified
version of the JSON-RPC specification. Developers should refer to
[Klipper's API documentation](https://www.klipper3d.org/API_Server.html)
for details on the protocol and available APIs.
!!! Note
The bridge websocket is described as "near direct passthrough" because
Moonraker handles the ETX (`0x03`) terminator internally. Applications
can expect to receive complete JSON encoded messages in a text frame
without the ETX terminator. Likewise applications should send JSON encoded
messages without the ETX terminator. Messages may be sent using either
text frames or binary frames.
The bridge websocket provides access to diagnostic APIs that are not generally
suitable for Moonraker's primary connection. These requests stream a
substantial amount of data; bridge connections allow Moonraker to avoid
decoding and re-encoding this data, reducing CPU load on the host. The "dump"
requests, such as `motion_report/dump_stepper` and `adxl345/dump_adxl345`, are
examples of APIs that should make use of the bridge websocket.
The bridge websocket is available at:
```
ws://host_or_ip:port/klippysocket
```
The availability of bridge connections depends on Klippy's availability.
If Klippy is not running or its API server is not enabled then a bridge
websocket connection cannot be established. Established bridge connections
will close when Klippy is shutdown or restarted. Such connections will also
be closed if Moonraker is restarted or shutdown.
!!! Note
If JWT or API Key authentication is required the application must use a
[oneshot token](./authorization.md#generate-a-oneshot-token) when connecting
to a bridge socket. Since Moonraker does not decode bridge requests it is
not possible to perform JWT authentication post connection.
## Unix Socket Connection
All JSON-RPC APIs available over the Websocket transport are also available
over the Unix Domain Socket connection. Moonraker creates the socket file at
`<datapath>/comms/moonraker.sock` (ie: `~/printer_data/comms/moonraker.sock`).
The Unix Socket expects UTF-8 encoded JSON-RPC byte strings. Each JSON-RPC
request must be terminated with an ETX character (`0x03`).
The Unix Socket is desirable for front ends and extensions running on the
local machine as authentication is not necessary. There should be a small
performance improvement due to the simplified transport protocol, however
the impact of this is likely negligible.
The `moontest` repo contains a
[python script](https://github.com/Arksine/moontest/blob/master/scripts/unix_socket_test.py)
to test comms over the unix socket.
## JSON-RPC over HTTP Endpoint
Exposes the JSON-RPC interface over HTTP. Most JSON-RPC methods with
corresponding HTTP APIs are available. Methods exclusive to other
transports, such as [Identify Connection](./server.md#identify-connection), are
not available.
/// note
If authentication is required it must be part of the HTTP request,
either using the API Key Header (`X-Api-Key`) or JWT Bearer Token.
///
```{.http .apirequest title="HTTP Request"}
POST /server/jsonrpc
Content-Type: application/json
{
"jsonrpc": "2.0",
"method": "printer.info",
"id": 5153
}
```
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"jsonrpc": "2.0",
"id": 5153,
"result": {
"state": "ready",
"state_message": "Printer is ready",
"hostname": "my-pi-hostname",
"software_version": "v0.9.1-302-g900c7396",
"cpu_info": "4 core ARMv7 Processor rev 4 (v7l)",
"klipper_path": "/home/pi/klipper",
"python_path": "/home/pi/klippy-env/bin/python",
"log_file": "/tmp/klippy.log",
"config_file": "/home/pi/printer.cfg"
}
}
```
////
/// note
If an error is encountered while processing a JSON-RPC request
over HTTP the request itself will still return success. The
error will be returned in the response as a JSON-RPC encoded
object.
///
## Jinja2 Template API Calls
Some template options in Moonraker's configuration, such as those in the
[button](../configuration.md#button) component, may call Moonraker APIs through
the `call_method(method_name, kwargs)` context function. The `call_method`
function takes the API's JSON-RPC method name as its first parameter, followed
by a set of keyword arguments as per the method's requirements.
```ini
# moonraker.conf
# Query Printer Objects example
[button check_status]
pin: gpio26
on_press:
{% set query = {"toolhead": ["position"], "print_stats": None} %}
# JSON-RPC method is "printer.objects.query", which takes a single "objects"
# argument
{% set status = call_method("printer.objects.query", objects=query) %}
# do something with the value returned from the object query, perhaps
# send a websocket notification or publish a mqtt topic
# Publish button event to MQTT Topic
[button check_status]
pin: gpio26
on_release:
# JSON-RPC method is "server.mqtt.publish"
{% do call_method("server.mqtt.publish",
topic="moonraker/my-button",
payload="Button Released") %}
```
## Miscellaneous Tutorials
### Websocket setup
The websocket is located at `ws://host:port/websocket`, for example:
```javascript
var s = new WebSocket("ws://" + location.host + "/websocket");
```
/// Note
It may be necessary to authenticate the connection first. This
tutorial assumes that the client is running on a trusted connection.
///
The following is a basic startup sequence that may be used to establish
a full connection to Moonraker and ensure that Klipper is running and
available:
1. Attempt to connect to `/websocket` until successful using a timer-like
mechanism.
2. Once connected, query the [server info](./server.md#query-server-info)
endpoint to check Klippy's state.
- If the response returns an error then either the client
is not authorized or Moonraker is not running. Direct the user to
SSH into the machine and check `<data_folder/logs/moonraker.log`.
- If the response returns success, check the result's `klippy_state`
field:
- `klippy_state == "ready"`: you may proceed to request status of
printer objects make subscriptions, get the file list, etc.
- `klippy_state == "error"`: Klippy has experienced an error
starting up
- `klippy_state == "shutdown"`: Klippy is in a shutdown state.
- `klippy_state == "startup"`: re-request the `server info` endpoint in 2 seconds.
- `klippy_state == "disconnected"`: The Klippy host either isn't running,
has experienced a critical error during startup, or does not have its
API Server enabled.
3. Repeat step 2 until Klipper reports ready.
4. Clients should watch for the `notify_klippy_disconnected` event. If
received then Klippy has either been stopped or restarted. In this
state the client should repeat the steps above to determine when
klippy is ready.
/// note
If Klippy reports an `error` or `shutdown` state it is advisable prompt
the user. You can get a description from the `state_message`
field of a [printer info](./printer.md#get-klippy-host-information) request.
///
### Basic Print Status
An advanced client will likely use subscriptions and notifications
to interact with Moonraker, however simple clients such as home automation
software and embedded devices (ie: ESP32) may only wish to monitor the
status of a print. Below is a high level walkthrough for receiving print state
via polling.
- Set up a timer to poll at the desired interval. Depending on your use
case, 1 to 2 seconds is recommended.
- On each cycle, issue the following request:
```
GET http://host/printer/objects/query?webhooks&virtual_sdcard&print_stats
```
Or via JSON-RPC 2.0:
```json
{
"jsonrpc": "2.0",
"method": "printer.objects.query",
"params": {
"objects": {
"webhooks": null,
"virtual_sdcard": null,
"print_stats": null
}
},
"id": 5664
}
```
- If the request returns an error or the returned `result.status` is an empty
object, then this is an indication that Klippy either experienced an error or
it is not properly configured. Each queried object should be available in
`result.status`. The client should check to make sure that all objects are
received before proceeding.
- Inspect `webhooks.state`. If the value is not `ready` the printer
is not available. `webhooks.message` contains a message pertaining
to the current state.
- If the printer is ready, inspect `print_stats.state`. It may be one
of the following values:
- `standby`: No print in progress
- `printing`: The printer is currently printing
- `paused`: A print in progress has been paused
- `error`: The print exited with an error. `print_stats.message`
contains a related error message
- `complete`: The last print has completed
- If `print_stats.state` is not `standby` then `print_stats.filename`
will report the name of the currently loaded file.
- `print_stats.filename` can be used to fetch file metadata. It
is only necessary to fetch metadata once per print.
```
GET http://host/server/files/metadata?filename=<filename>
```
Or via JSON-RPC 2.0:
```json
{
"jsonrpc": "2.0",
"method": "server.files.metadata",
"params": {
"filename": "{filename}"
},
"id": 5643
}
```
If metadata extraction failed then this request will return an error.
Some metadata fields are only populated for specific slicers, and
unsupported slicers will only return the size and modified date.
- There are multiple ways to calculate the ETA, this example will use
file progress, as it is possible calculate the ETA with or without
metadata.
- If `metadata.estimated_time` is available, the eta calculation can
be done as:
```javascript
// assume "result" is the response from the status query
let vsd = result.status.virtual_sdcard;
let prog_time = vsd.progress * metadata.estimated_time;
let eta = metadata.estimated_time - prog_time
```
Alternatively, one can simply subtract the print duration from
the estimated time:
```javascript
// assume "result" is the response from the status query
let pstats = result.status.print_status;
let eta = metadata.estimated_time - pstats.print_duration;
if (eta < 0) eta = 0;
```
- If no metadata is available, print duration and progress can be used to
calculate the ETA:
```javascript
// assume "result" is the response from the status query
let vsd = result.status.virtual_sdcard;
let pstats = result.status.print_stats;
let total_time = pstats.print_duration / vsd.progress;
let eta = total_time - pstats.print_duration;
```
- It is possible to query additional objects if a client wishes to display
more information (ie: temperatures). See Klipper's
[Status Reference](https://www.klipper3d.org/Status_Reference.html)
documentation for details on objects available for query.
### Bed Mesh Coordinates
The [Bed Mesh](../printer_objects.md#bed_mesh) printer object may be used
to generate three dimensional coordinates of a probed area (or mesh).
Below is an example (in javascript) of how to transform the data received
from a bed_mesh object query into an array of 3D coordinates.
```javascript
// assume that we have executed an object query for bed_mesh and have the
// result. This example generates 3D coordinates for the probed matrix,
// however it would work with the mesh matrix as well
function process_mesh(result) {
let bed_mesh = result.status.bed_mesh;
let matrix = bed_mesh.probed_matrix;
if (!(matrix instanceof Array) || matrix.length < 3 ||
!(matrix[0] instanceof Array) || matrix[0].length < 3)
// make sure that the matrix is valid
return;
let coordinates = [];
// calculate the distance between each sample on both the X an Y
// axes
let x_distance = (bed_mesh.mesh_max[0] - bed_mesh.mesh_min[0]) /
(matrix[0].length - 1);
let y_distance = (bed_mesh.mesh_max[1] - bed_mesh.mesh_min[1]) /
(matrix.length - 1);
let x_idx = 0;
let y_idx = 0;
// transform the matrix of z values into (x, y, z) coordinates
for (const x_axis of matrix) {
x_idx = 0;
// mesh_min is the (x, y) coordinate of the first z sample
let y_coord = bed_mesh.mesh_min[1] + (y_idx * y_distance);
for (const z_coord of x_axis) {
let x_coord = bed_mesh.mesh_min[0] + (x_idx * x_distance);
x_idx++;
coordinates.push([x_coord, y_coord, z_coord]);
}
y_idx++;
}
}
// Use the array of coordinates to visualize the "probed area"
// or mesh..
```
### Converting to Unix Time
Some of Moonraker's APIs return a date represented in Unix time.
Most languages have functionality built in to convert Unix
time to a workable object or string. For example, in JavaScript
one might do something like the following:
```javascript
for (let resp of result.gcode_store) {
let date = new Date(resp.time * 1000);
// Do something with date and resp.message ...
}
```

View File

@@ -0,0 +1,440 @@
# Job Queue Management
The following endpoints may be used to manage Moonraker's job queue.
Note that Moonraker's Job Queue is implemented as a FIFO queue and it may
contain multiple references to the same job.
The queue maintains an internal state attribute, which will always be one
of the following:
| State | Description |
| ---------- | ---------------------------------------------------------------- |
| `ready` | The queue is active and will load the next queued job upon |
| | completion of the current job. |^
| `loading` | The queue is currently loading the next job. If the |
| | `job_queue` configuration specifies a `job_transition_delay` |^
| | and/or a `job_transition_gcode` the queue will remain in the |^
| | `loading` state until both are completed. |^
| `starting` | The state reported while the Job Queue is requesting Klipper |
| | to start the print. |^
| `paused` | When the queue is `paused` it will not load the next queued |
| | job after a working job has completed. The queue will enter |^
| | this state if a pause is requested through the "pause" endpoint, |^
| | an error is encountered during the startup or loading phases, or |^
| | after completion of a job when the `job_queue` configuration |^
| | specifies that `automatic_transition` is set to false. |^
{ #queue-state-desc } Queue State
/// note
All filenames provided to and returned by these endpoints are relative to
the `gcodes` root.
///
## Get job queue status
Retrieves the current state of the job queue.
```{.http .apirequest title="HTTP Request"}
GET /server/job_queue/status
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.job_queue.status",
"id": 4654
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"queued_jobs": [
{
"filename": "job1.gcode",
"job_id": "0000000066D99C90",
"time_added": 1636151050.7666452,
"time_in_queue": 21.89680004119873
},
{
"filename": "job2.gcode",
"job_id": "0000000066D991F0",
"time_added": 1636151050.7766452,
"time_in_queue": 21.88680004119873
},
{
"filename": "subdir/job3.gcode",
"job_id": "0000000066D99D80",
"time_added": 1636151050.7866452,
"time_in_queue": 21.90680004119873
}
],
"queue_state": "ready"
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ------------- | :------: | -------------------------------------------------------- |
| `queued_jobs` | [object] | An array of `Queued Job` objects. |
| | | #queued-job-spec |+
| `queue_state` | string | The current [state](#queue-state-desc) of the job queue. |
{ #job-queue-status-response-spec }
| Field | Type | Description |
| --------------- | :----: | ------------------------------------------------------- |
| `filename` | string | The name of the gcode file queued. |
| `job_id` | string | A unique ID assigned to the queued job. |
| `time_added` | float | The time (in Unix Time) the job was added to the queue. |
| `time_in_queue` | float | The cumulative amount of time, in seconds, the job has |
| | | been pending in the queue. |^
{ #queued-job-spec } Queued Job
///
## Enqueue a job
Adds a job, or an array of jobs, to the end of the job queue. The same
filename may be specified multiple times to queue a job that repeats.
When multiple jobs are specified they will be enqueued in the order they
are received.
/// note
The request will be aborted and return an error if any of the supplied
files do not exist.
///
```{.http .apirequest title="HTTP Request"}
POST /server/job_queue/job
Content-Type: application/json
{
"filenames": [
"job1.gcode",
"job2.gcode",
"subdir/job3.gcode"
],
"reset": false
}
```
/// tip
If it isn't possible for your client to pass parameters in the body
of the request as a json object, they can be added to the query string
as shown below:
```{.http .apirequest title="HTTP Request"}
POST /server/job_queue/job?filenames=job1.gcode,job2.gcode,subdir/job3.gcode
```
Multiple jobs should be comma separated as shown above.
///
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.job_queue.post_job",
"params": {
"filenames": [
"job1.gcode",
"job2.gcode",
"subdir/job3.gcode"
],
"reset": false
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ----------- | :------: | ------------ | ------------------------------------------------------- |
| `filenames` | [string] | **REQUIRED** | An array of filenames of jobs to add to the queue. |
| | | | The file names should be paths relative to the `gcodes` |^
| | | | root. All of the specified files must exist, otherwise |^
| | | | the request will return with an error. |^
| `reset` | bool | false | When set to `true` the job queue will be |
| | | | cleared prior to adding the requested jobs. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"queued_jobs": [
{
"filename": "job1.gcode",
"job_id": "0000000066D99C90",
"time_added": 1636151050.7666452,
"time_in_queue": 0.01680004119873
},
{
"filename": "job2.gcode",
"job_id": "0000000066D991F0",
"time_added": 1636151050.7766452,
"time_in_queue": 0.01480004119873
},
{
"filename": "subdir/job3.gcode",
"job_id": "0000000066D99D80",
"time_added": 1636151050.7866452,
"time_in_queue": 0.010680004119873
}
],
"queue_state": "ready"
}
```
///
/// api-response-spec
open: True
See the [Job Queue Status](#job-queue-status-response-spec)
Response Specification.
///
## Remove a Job
Removes one or more jobs from the queue.
/// Note
Unlike the POST version of this method, it is not necessary that
all job ids exist. If any supplied job id does not exist in the
queue it will be silently ignored. Clients can verify the contents
of the queue via the return value.
///
```{.http .apirequest title="HTTP Request"}
DELETE /server/job_queue/job?job_ids=0000000066D991F0,0000000066D99D80
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.job_queue.delete_job",
"params": {
"job_ids": [
"0000000066D991F0",
"0000000066D99D80"
]
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| --------- | :------: | --------------- | ------------------------------------------------ |
| `job_ids` | [string] | **REQUIRED** | An array of `job_ids` to remove from the queue. |
| | | if `all==false` | Any job ids that do not exist will be ignored. |^
| `all` | bool | false | When set to `true` all jobs will be removed |
| | | | from the queue. In this case it is not necessary |^
| | | | to set the `job_ids` parameter. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"queued_jobs": [
{
"filename": "job1.gcode",
"job_id": "0000000066D99C90",
"time_added": 1636151050.7666452,
"time_in_queue": 21.89680004119873
}
],
"queue_state": "ready"
}
```
///
/// api-response-spec
open: True
See the [Job Queue Status](#job-queue-status-response-spec)
Response Specification.
///
## Pause the job queue
Sets the job queue state to "pause", which prevents the next job
in the queue from loading after an job in progress is complete.
If the queue is paused while the queue is in the `loading` state
the load will be aborted.
```{.http .apirequest title="HTTP Request"}
POST /server/job_queue/pause
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.job_queue.pause",
"id": 4654
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"queued_jobs": [
{
"filename": "job1.gcode",
"job_id": "0000000066D99C90",
"time_added": 1636151050.7666452,
"time_in_queue": 21.89680004119873
},
{
"filename": "job2.gcode",
"job_id": "0000000066D991F0",
"time_added": 1636151050.7766452,
"time_in_queue": 21.88680004119873
},
{
"filename": "subdir/job3.gcode",
"job_id": "0000000066D99D80",
"time_added": 1636151050.7866452,
"time_in_queue": 21.90680004119873
}
],
"queue_state": "paused"
}
```
///
/// api-response-spec
open: True
See the [Job Queue Status](#job-queue-status-response-spec)
Response Specification.
///
## Start the job queue
Starts the job queue. If Klipper is ready to start a print the next
job in the queue will be loaded. Otherwise the queue will be put
into the "ready" state, where the job will be loaded after the current
job completes.
```{.http .apirequest title="HTTP Request"}
POST /server/job_queue/start
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.job_queue.start",
"id": 4654
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"queued_jobs": [
{
"filename": "job1.gcode",
"job_id": "0000000066D99C90",
"time_added": 1636151050.7666452,
"time_in_queue": 21.89680004119873
},
{
"filename": "job2.gcode",
"job_id": "0000000066D991F0",
"time_added": 1636151050.7766452,
"time_in_queue": 21.88680004119873
},
{
"filename": "subdir/job3.gcode",
"job_id": "0000000066D99D80",
"time_added": 1636151050.7866452,
"time_in_queue": 21.90680004119873
}
],
"queue_state": "loading"
}
```
///
/// api-response-spec
open: True
See the [Job Queue Status](#job-queue-status-response-spec)
Response Specification.
///
## Perform a Queue Jump
Jumps a job to the front of the queue.
```{.http .apirequest title="HTTP Request"}
POST /server/job_queue/jump?job_id=0000000066D991F0
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.job_queue.jump",
"params": {
"job_id": "0000000066D991F0"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| -------- | :----: | ------------ | --------------------------------------- |
| `job_id` | string | **REQUIRED** | The `job_id` of the job to jump to the. |
| | | | front of the queue. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"queued_jobs": [
{
"filename": "job2.gcode",
"job_id": "0000000066D991F0",
"time_added": 1636151050.7766452,
"time_in_queue": 21.88680004119873
},
{
"filename": "job1.gcode",
"job_id": "0000000066D99C90",
"time_added": 1636151050.7666452,
"time_in_queue": 21.89680004119873
},
{
"filename": "subdir/job3.gcode",
"job_id": "0000000066D99D80",
"time_added": 1636151050.7866452,
"time_in_queue": 21.90680004119873
}
],
"queue_state": "loading"
}
```
///
/// api-response-spec
open: True
See the [Job Queue Status](#job-queue-status-response-spec)
Response Specification.
///

File diff suppressed because it is too large Load Diff

1473
docs/external_api/machine.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,667 @@
# Printer Administration
These endpoints provide access to printer state and printer control.
Klippy must be connected to Moonraker to receive a successful response,
and in many cases Klippy must be in the `ready` state.
Most of these endpoints are registered with Moonraker by Klipper.
Requests pass from the frontend through Moonraker directly to Klipper.
Moonraker does not intervene.
## Get Klippy host information
```{.http .apirequest title="HTTP Request"}
GET /printer/info
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.info",
"id": 5445
}
```
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"state": "ready",
"state_message": "Printer is ready",
"hostname": "pi-debugger",
"klipper_path": "/home/pi/klipper",
"python_path": "/home/pi/klipper/venv/bin/python",
"process_id": 275124,
"user_id": 1000,
"group_id": 1000,
"log_file": "/home/pi/printer_data/logs/klippy.log",
"config_file": "/home/pi/printer_data/config/printer.cfg",
"software_version": "v0.12.0-85-gd785b396",
"cpu_info": "4 core ?"
}
```
////
/// api-response-spec
open: True
| Field | Type | Description |
| ------------------ | :----: | ----------------------------------------------------- |
| `state` | string | Klippy's current [state](#klippy-state-desc). |
| `state_message` | string | A message describing Klippy's current state. |
| `hostname` | string | Hostname of the machine running Klippy. |
| `klipper_path` | string | Path on disk to the Klipper application. |
| `python_path` | string | Path on disk to the Python executable running Klippy. |
| `process_id` | int | The PID of the current Klippy process. |
| `user_id` | int | The UID of the user the Klippy process belongs to. |
| `group_id` | int | The GID of the group the Klippy process belongs to. |
| `log_file` | string | Path on disk to Klipper's log file. |
| `configfile` | string | Path on disk to Klipper's configuration file. |
| `software_version` | string | Version of the currently running instance of Klipper. |
| `cpu_info` | string | A brief description of the host machine's CPU. |
| State | Description |
| ---------- | ------------------------------------------------------- |
| `ready` | Klippy has initialized and is ready for commands. |
| `startup` | Klippy is currently in its startup phase. |
| `error` | Klippy encountered an error during startup. |
| `shutdown` | Klippy is in the shutdown state. This can be initiated |
| | by the user via an emergency stop, or by the software |^
| | if it encounters a critical error during operation. |^
{ #klippy-state-desc } Klippy State
///
## Emergency Stop
```{.http .apirequest title="HTTP Request"}
POST /printer/emergency_stop
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.emergency_stop",
"id": 4564
}
```
/// Note
This endpoint will immediately halt the printer and put it in a "shutdown"
state. It should be used to implement an "emergency stop" button and
also used if a user enters `M112`(emergency stop) via a console.
///
```{.text .apiresponse title="Response"}
"ok"
```
## Host Restart
Requests a Klipper "soft" restart. This will reload the Klippy application
and configuration. Connected MCUs will not be reset.
```{.http .apirequest title="HTTP Request"}
POST /printer/restart
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.restart",
"id": 4894
}
```
```{.text .apiresponse title="Response"}
"ok"
```
## Firmware Restart
Requests a complete Klipper restart. Both the Klippy Application and connected
MCUs will be reset.
```{.http .apirequest title="HTTP Request"}
POST /printer/firmware_restart
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.firmware_restart",
"id": 8463
}
```
```{.text .apiresponse title="Response"}
"ok"
```
## Printer Status Requests
### List loaded printer objects
Returns a list of Klipper `printer objects` that are currently loaded.
This can be used to determine if a specific object is available for query
and/or subscription.
```{.http .apirequest title="HTTP Request"}
GET /printer/objects/list
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.objects.list",
"id": 1454
}
```
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"objects": [
"gcode",
"webhooks",
"configfile",
"mcu",
"mcu linux",
"heaters",
"bme280 chamber",
"temperature_sensor chamber",
"filament_switch_sensor extruder_sensor",
"output_pin sensor_toggle",
"gcode_move",
"bed_mesh",
"exclude_object",
"temperature_host RPi",
"temperature_sensor RPi",
"gcode_macro TURN_OFF_MOTORS",
"gcode_macro SET_HOMING_CURRENT",
"temperature_sensor ambient",
"gcode_macro query_bme280",
"pause_resume",
"print_stats",
"virtual_sdcard",
"probe",
"stepper_enable",
"tmc2130 stepper_x",
"tmc2130 stepper_y",
"tmc2130 stepper_z",
"tmc2130 extruder",
"heater_bed",
"heater_fan nozzle_cooling_fan",
"fan",
"menu",
"display_status",
"output_pin BEEPER_pin",
"idle_timeout",
"motion_report",
"query_endstops",
"system_stats",
"manual_probe",
"toolhead",
"extruder"
]
}
```
////
/// api-response-spec
open: True
| Field | Type | Description |
| --------- | :------: | ------------------------------------------------ |
| `objects` | [string] | A list Klipper printer objects currently loaded. |
///
### Query printer object status
Requests the status of a provided set of printer objects.
/// Tip
See the [Printer Objects](../printer_objects.md) document
for details on the objects available for query.
///
```{.http .apirequest title="HTTP Request"}
POST /printer/objects/query
Content-Type: application/json
{
"objects": {
"gcode_move": null,
"toolhead": ["position", "status"]
}
}
```
/// details | Using the Query String
The HTTP Request may also be performed using the query string. It is
recommended to send the request in the body unless otherwise not possible.
```{.http .apirequest title="HTTP Request"}
GET /printer/objects/query?gcode_move&toolhead&extruder=target,temperature
```
The above will request a status update for all `gcode_move` and `toolhead`
attributes. Only the `temperature` and `target` attributes are requested
for the `extruder`.
///
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.objects.query",
"params": {
"objects": {
"gcode_move": null,
"toolhead": ["position", "status"]
}
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| --------- | :----: | ------------ | ------------------------------------------------------ |
| `objects` | object | **REQUIRED** | An object whose key, value pairs represent one or |
| | | | more [Printer Object Requests](#printer-obj-req-desc). |^
| Key Description | Value Description |
| ------------------------------- | ----------------------------------------------------------- |
| The `key`should be an available | The `value` specifies the attributes of the object that |
| Klipper printer object. | should be returned. If the value is `null` all attributes |^
| { width=40% } | will be returned. Alternatively a list of strings |^
| | specifying the desired attributes can be provided. |^
{ #printer-obj-req-desc } Printer Object Request
//// Note
If a requested printer object or attribute does not exist then the result
will be omitted from the response. No error is returned.
////
///
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"eventtime": 578243.57824499,
"status": {
"gcode_move": {
"absolute_coordinates": true,
"absolute_extrude": true,
"extrude_factor": 1,
"gcode_position": [0, 0, 0, 0],
"homing_origin": [0, 0, 0, 0],
"position": [0, 0, 0, 0],
"speed": 1500,
"speed_factor": 1
},
"toolhead": {
"position": [0, 0, 0, 0],
"status": "Ready"
}
}
}
```
////
/// api-response-spec
open: True
| Field | Type | Description |
| ----------- | :----: | -------------------------------------------------------------- |
| `eventtime` | float | The time at which the status was received, according Klipper's |
| | | monotonic clock. |^
| `status` | object | An object containing the current state of the requested |
| | | printer objects. |^
{ #object-query-response-spec }
///
### Subscribe to printer object status updates
Requests status updates for a set of printer objects. A persistent
connection (Websocket or Unix Socket) is required to fulfill this
request.
Status updates for subscribed objects are sent asynchronously over the
connection. See the
[notify_status_update](./jsonrpc_notifications.md#subscription-updates)
notification for details.
/// Tip
See the [Printer Objects](../printer_objects.md) document
for details on the objects available for subscription.
///
```{.text .apirequest title="HTTP Request"}
Not available
```
```{.json .apirequest title="JSON-RPC Request (Websocket and Unix Socket Only)"}
{
"jsonrpc": "2.0",
"method": "printer.objects.subscribe",
"params": {
"objects": {
"gcode_move": null,
"toolhead": ["position", "status"]
}
},
"id": 5434
}
```
/// api-parameters
open: True
Parameters are identical to the [query](#query-printer-object-status)
status parameters. A new request will override a previous request.
If `objects` is set to an empty object then the subscription will be
cancelled.
///
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"eventtime": 578243.57824499,
"status": {
"gcode_move": {
"absolute_coordinates": true,
"absolute_extrude": true,
"extrude_factor": 1,
"gcode_position": [0, 0, 0, 0],
"homing_origin": [0, 0, 0, 0],
"position": [0, 0, 0, 0],
"speed": 1500,
"speed_factor": 1,
},
"toolhead": {
"position": [0, 0, 0, 0],
"status": "Ready"
}
}
}
```
////
/// api-response-spec
open: True
The response spec is identical to the [query response specification](#object-query-response-spec)
The response may be used to initialize local state without performing a
separate query.
///
### Query Endstops
```{.http .apirequest title="HTTP Request"}
GET /printer/query_endstops/status
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.query_endstops.status",
"id": 3456
}
```
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"x": "TRIGGERED",
"y": "open",
"z": "open"
}
```
////
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :----: | ----------------------------------------------------------- |
| *variable* | string | The field is the name of the registered endstop. The value |
| | | will be `open` or `TRIGGERED`. |^
///
## GCode APIs
### Run a gcode command
Executes a gcode command. Multiple commands may be executed by separating
them with a newline (`\n`). The request returns when the command or series
of commands have completed, or when the command results in an error.
/// warning
When `M112`(emergency stop) is requested via this endpoint it will not
immediately stop the printer. `M112` will be placed on the gcode queue and
executed after all previous gcodes are complete. If a frontend detects
`M112` via user input (such as a console) it should request the
`/printer/emergency_stop` endpoint to immediately halt the printer. This
may be done in addition to sending the `M112` gcode if desired.
///
```{.http .apirequest title="HTTP Request"}
POST /printer/gcode/script
Content-Type: application/json
{
"script": "G28"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.gcode.script",
"params": {
"script": "G28"
},
"id": 7466}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| -------- | :----: | ------------ | ------------------------------------------------- |
| `script` | string | **REQUIRED** | A GCode Command to run. Multiple commands may be |
| | | | specified, separated by a newline (`\n`). |^
///
```{.text .apiresponse title="Response"}
"ok"
```
### Get GCode Help
Retrieves a list of registered GCode Command Descriptions. Not all registered
GCode commands have a description, so this list should not be treated as an
exhaustive list of all supported commands.
```{.http .apirequest title="HTTP Request"}
GET /printer/gcode/help
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.gcode.help",
"id": 4645
}
```
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"RESTART": "Reload config file and restart host software",
"FIRMWARE_RESTART": "Restart firmware, host, and reload config",
"STATUS": "Report the printer status",
"HELP": "Report the list of available extended G-Code commands",
"SAVE_CONFIG": "Overwrite config file and restart",
"SHUTDOWN_MACHINE": "G-Code macro",
"SET_GCODE_VARIABLE": "Set the value of a G-Code macro variable",
"REBOOT_MACHINE": "G-Code macro",
"UPDATE_DELAYED_GCODE": "Update the duration of a delayed_gcode",
"TURN_OFF_HEATERS": "Turn off all heaters",
"TEMPERATURE_WAIT": "Wait for a temperature on a sensor",
"QUERY_ADC": "Report the last value of an analog pin",
"QUERY_FILAMENT_SENSOR": "Query the status of the Filament Sensor",
"SET_FILAMENT_SENSOR": "Sets the filament sensor on/off",
"SET_PIN": "Set the value of an output pin",
"BED_MESH_CALIBRATE": "Perform Mesh Bed Leveling",
"BED_MESH_PROFILE": "Bed Mesh Persistent Storage management",
"BED_MESH_OUTPUT": "Retrieve interpolated grid of probed z-points",
"BED_MESH_MAP": "Serialize mesh and output to terminal",
"BED_MESH_CLEAR": "Clear the Mesh so no z-adjustment is made",
"BED_MESH_OFFSET": "Add X/Y offsets to the mesh lookup",
"SET_GCODE_OFFSET": "Set a virtual offset to g-code positions",
"SAVE_GCODE_STATE": "Save G-Code coordinate state",
"RESTORE_GCODE_STATE": "Restore a previously saved G-Code state",
"GET_POSITION": "Return information on the current location of the toolhead",
"EXCLUDE_OBJECT_START": "Marks the beginning the current object as labeled",
"EXCLUDE_OBJECT_END": "Marks the end the current object",
"EXCLUDE_OBJECT": "Cancel moves inside a specified objects",
"EXCLUDE_OBJECT_DEFINE": "Provides a summary of an object",
"TURN_OFF_MOTORS": "G-Code macro",
"CLEAR_PAUSE": "Clears the current paused state without resuming the print",
"SET_PRINT_STATS_INFO": "Pass slicer info like layer act and total to klipper",
"SDCARD_RESET_FILE": "Clears a loaded SD File. Stops the print if necessary",
"SDCARD_PRINT_FILE": "Loads a SD file and starts the print. May include files in subdirectories.",
"RESPOND": "Echo the message prepended with a prefix",
"PROBE": "Probe Z-height at current XY position",
"QUERY_PROBE": "Return the status of the z-probe",
"PROBE_CALIBRATE": "Calibrate the probe's z_offset",
"PROBE_ACCURACY": "Probe Z-height accuracy at current XY position",
"Z_OFFSET_APPLY_PROBE": "Adjust the probe's z_offset",
"GET_CURRENT_SKEW": "Report current printer skew",
"CALC_MEASURED_SKEW": "Calculate skew from measured print",
"SET_SKEW": "Set skew based on lengths of measured object",
"SKEW_PROFILE": "Profile management for skew_correction",
"SET_STEPPER_ENABLE": "Enable/disable individual stepper by name",
"SET_TMC_FIELD": "Set a register field of a TMC driver",
"INIT_TMC": "Initialize TMC stepper driver registers",
"SET_TMC_CURRENT": "Set the current of a TMC driver",
"DUMP_TMC": "Read and display TMC stepper driver registers",
"PID_CALIBRATE": "Run PID calibration test",
"SET_HEATER_TEMPERATURE": "Sets a heater temperature",
"SET_DISPLAY_TEXT": "Set or clear the display message",
"SET_DISPLAY_GROUP": "Set the active display group",
"STEPPER_BUZZ": "Oscillate a given stepper to help id it",
"FORCE_MOVE": "Manually move a stepper; invalidates kinematics",
"SET_KINEMATIC_POSITION": "Force a low-level kinematic position",
"SET_IDLE_TIMEOUT": "Set the idle timeout in seconds",
"QUERY_ENDSTOPS": "Report on the status of each endstop",
"SET_VELOCITY_LIMIT": "Set printer velocity limits",
"MANUAL_PROBE": "Start manual probe helper script",
"TUNING_TOWER": "Tool to adjust a parameter at each Z height",
"SET_PRESSURE_ADVANCE": "Set pressure advance parameters",
"SET_EXTRUDER_ROTATION_DISTANCE": "Set extruder rotation distance",
"SYNC_EXTRUDER_MOTION": "Set extruder stepper motion queue",
"SET_EXTRUDER_STEP_DISTANCE": "Set extruder step distance",
"SYNC_STEPPER_TO_EXTRUDER": "Set extruder stepper",
"ACTIVATE_EXTRUDER": "Change the active extruder",
"BASE_PAUSE": "Renamed builtin of 'PAUSE'",
"BASE_RESUME": "Renamed builtin of 'RESUME'",
"BASE_CANCEL_PRINT": "Renamed builtin of 'CANCEL_PRINT'",
"ACCEPT": "Accept the current Z position",
"ABORT": "Abort manual Z probing tool",
"TESTZ": "Move to new Z height"
}
```
////
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :----: | ----------------------------------------------------------------- |
| *variable* | string | The field is the name of the registered gcode command. The value |
| | | is a string containing the associated help descriptions. |^
//// Note
As mentioned previously, this list is not exhaustive. Help strings are not
available for default gcode handlers such as G1, G28, etc, nor are they
available for extended handlers that failed to register a description in
Klipper's python source.
////
///
## Print Job Management
### Start a print job
```{.http .apirequest title="HTTP Request"}
POST /printer/print/start?filename=test_print.gcode
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.print.start",
"params": {
"filename": "test_print.gcode"
},
"id": 4654
}
```
/// api-parameters
open: true
| Name | Type | Default | Description |
| ---------- | :----: | ------------ | --------------------------------------------------- |
| `filename` | string | **REQUIRED** | The name of the gcode file to print. May be a path |
| | | | relative to the gcode folder. |^
///
```{.text .apiresponse title="Response"}
"ok"
```
### Pause a print job
```{.http .apirequest title="HTTP Request"}
POST /printer/print/pause
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.print.pause",
"id": 4564
}
```
```{.text .apiresponse title="Response"}
"ok"
```
### Resume a print job
```{.http .apirequest title="HTTP Request"}
POST /printer/print/resume
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.print.resume",
"id": 1465
}
```
```{.text .apiresponse title="Response"}
"ok"
```
### Cancel a print job
```{.http .apirequest title="HTTP Request"}
POST /printer/print/cancel
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "printer.print.cancel",
"id": 2578
}
```
```{.text .apiresponse title="Response"}
"ok"
```

648
docs/external_api/server.md Normal file
View File

@@ -0,0 +1,648 @@
# Server Administration
These endpoints provide access to server status, data tracking, and
administrative requests.
## Query Server Info
```{.http .apirequest title="HTTP Request"}
GET /server/info
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.info",
"id": 9546
}
```
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"klippy_connected": true,
"klippy_state": "ready",
"components": [
"database",
"file_manager",
"klippy_apis",
"machine",
"data_store",
"shell_command",
"proc_stats",
"history",
"octoprint_compat",
"update_manager",
"power"
],
"failed_components": [],
"registered_directories": ["config", "gcodes", "config_examples", "docs"],
"warnings": [
"Invalid config option 'api_key_path' detected in section [authorization]. Remove the option to resolve this issue. In the future this will result in a startup error.",
"Unparsed config section [fake_section] detected. This may be the result of a component that failed to load. In the future this will result in a startup error."
],
"websocket_count": 2,
"moonraker_version": "v0.7.1-105-ge4f103c",
"api_version": [1, 4, 0],
"api_version_string": "1.4.0"
}
```
////
/// api-response-spec
open: True
| Field | Type | Description |
| ------------------------ | :------: | -------------------------------------------------------- |
| `klippy_connected` | bool | Moonraker's connection status to the Klippy Host. |
| `klippy_state` | string | Klippy's current state. Expand for available values. |
| #klippy-state-desc | | |+
| `components` | [string] | A list of Moonraker components that are currently |
| | | loaded. |^
| `failed_components` | [string] | A list of Moonraker components that failed to load. |
| `registered_directories` | [string] | A list "roots" registered with Moonraker's file manager. |
| `warnings` | [string] | A list of warning messages describing errors encountered |
| | | during initialization or regular operation. |^
| `websocket_count` | int | The number of currently active websocket connections. |
| `moonraker_version` | string | The version of the Moonraker Application. |
| `api_version` | [int] | The version of the API in tuple format. |
| `api_version_string` | string | The version of the API in string format. |
| State | Description |
| -------------- | ------------------------------------------------------------------ |
| `disconnected` | Moonraker is currently disconnect from Klippy. |
| `startup` | Klippy is currently initializing. |
| `ready` | Klippy is active and ready to receive commands. |
| `error` | Klippy experienced an error during startup. |
| `shutdown` | Klippy has been emergency stopped. This can occur at user request |
| | or if a critical error is encountered while running. |^
{ #klippy-state-desc }
///
## Get Server Configuration
```{.http .apirequest title="HTTP Request"}
GET /server/config
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.config",
"id": 5616
}
```
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"config": {
"server": {
"host": "0.0.0.0",
"port": 7125,
"ssl_port": 7130,
"enable_debug_logging": true,
"enable_asyncio_debug": false,
"klippy_uds_address": "/tmp/klippy_uds",
"max_upload_size": 210,
"ssl_certificate_path": null,
"ssl_key_path": null
},
"dbus_manager": {},
"database": {
"database_path": "~/.moonraker_database",
"enable_database_debug": false
},
"file_manager": {
"enable_object_processing": true,
"queue_gcode_uploads": true,
"config_path": "~/printer_config",
"log_path": "~/logs"
},
"klippy_apis": {},
"machine": {
"provider": "systemd_dbus"
},
"shell_command": {},
"data_store": {
"temperature_store_size": 1200,
"gcode_store_size": 1000
},
"proc_stats": {},
"job_state": {},
"job_queue": {
"load_on_startup": true,
"automatic_transition": false,
"job_transition_delay": 2,
"job_transition_gcode": "\nM118 Transitioning to next job..."
},
"http_client": {},
"announcements": {
"dev_mode": false,
"subscriptions": []
},
"authorization": {
"login_timeout": 90,
"force_logins": false,
"cors_domains": [
"*.home",
"http://my.mainsail.xyz",
"http://app.fluidd.xyz",
"*://localhost:*"
],
"trusted_clients": [
"192.168.1.0/24"
]
},
"zeroconf": {},
"octoprint_compat": {
"enable_ufp": true,
"flip_h": false,
"flip_v": false,
"rotate_90": false,
"stream_url": "/webcam/?action=stream",
"webcam_enabled": true
},
"history": {},
"secrets": {
"secrets_path": "~/moonraker_secrets.ini"
},
"mqtt": {
"address": "eric-work.home",
"port": 1883,
"username": "{secrets.mqtt_credentials.username}",
"password_file": null,
"password": "{secrets.mqtt_credentials.password}",
"mqtt_protocol": "v3.1.1",
"instance_name": "pi-debugger",
"default_qos": 0,
"status_objects": {
"webhooks": null,
"toolhead": "position,print_time",
"idle_timeout": "state",
"gcode_macro M118": null
},
"api_qos": 0,
"enable_moonraker_api": true
},
"template": {}
},
"orig": {
"DEFAULT": {},
"server": {
"enable_debug_logging": "True",
"max_upload_size": "210"
},
"file_manager": {
"config_path": "~/printer_config",
"log_path": "~/logs",
"queue_gcode_uploads": "True",
"enable_object_processing": "True"
},
"machine": {
"provider": "systemd_dbus"
},
"announcements": {},
"job_queue": {
"job_transition_delay": "2.",
"job_transition_gcode": "\nM118 Transitioning to next job...",
"load_on_startup": "True"
},
"authorization": {
"trusted_clients": "\n192.168.1.0/24",
"cors_domains": "\n*.home\nhttp://my.mainsail.xyz\nhttp://app.fluidd.xyz\n*://localhost:*"
},
"zeroconf": {},
"octoprint_compat": {},
"history": {},
"secrets": {
"secrets_path": "~/moonraker_secrets.ini"
},
"mqtt": {
"address": "eric-work.home",
"port": "1883",
"username": "{secrets.mqtt_credentials.username}",
"password": "{secrets.mqtt_credentials.password}",
"enable_moonraker_api": "True",
"status_objects": "\nwebhooks\ntoolhead=position,print_time\nidle_timeout=state\ngcode_macro M118"
}
},
"files": [
{
"filename": "moonraker.conf",
"sections": [
"server",
"file_manager",
"machine",
"announcements",
"job_queue",
"authorization",
"zeroconf",
"octoprint_compat",
"history",
"secrets"
]
},
{
"filename": "include/extras.conf",
"sections": [
"mqtt"
]
}
]
}
```
////
/// api-response-spec
open: True
| Field | Type | Description |
| -------- | :------: | ---------------------------------------------------------------------- |
| `config` | object | An object containing the full Moonraker configuration. Each field of |
| | | this object is a section name. The value for each section is an |^
| | | object mapping option names to values. Values are cast to their |^
| | | internal type. Default values not specified in the configuration |^
| | | files are included. |^
| `orig` | object | An object containing the original configuration as read from the |
| | | configuration file(s). Like `config`, each field is a section name |^
| | | and each value is a mapping of options to values. Only values present |^
| | | in the configuration files are reported, and all values are strings. |^
| `files` | [object] | An array of [File Objects](#file-object-spec) describing the config |
| | | files parsed. |^
| Field | Type | Description |
| ---------- | :------: | ----------------------------------------------------------------- |
| `filename` | string | The name of the configuration file. This name is a path relative |
| | | to the main configuration file's parent folder. |^
| `sections` | [string] | The config sections parsed from this file. |
{ #file-object-spec } File Object
///
## Request Cached Temperature Data
```{.http .apirequest title="HTTP Request"}
GET /server/temperature_store?include_monitors=false
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.temperature_store",
"params": {
"include_monitors": false
},
"id": 2313
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------------------ | :--: | ------- | -------------------------------------------- |
| `include_monitors` | bool | `false` | When set to `true` the response will include |
| | | | sensors reported as `temperature monitors.` |^
| | | | A temperature monitor is a specific type of |^
| | | | sensor that may include `null` values in |^
| | | | the `temperatures` field of the response. |^
///
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"extruder": {
"temperatures": [21.05, 21.12, 21.1, 21.1, 21.1],
"targets": [0, 0, 0, 0, 0],
"powers": [0, 0, 0, 0, 0]
},
"temperature_fan my_fan": {
"temperatures": [21.05, 21.12, 21.1, 21.1, 21.1],
"targets": [0, 0, 0, 0, 0],
"speeds": [0, 0, 0, 0, 0]
},
"temperature_sensor my_sensor": {
"temperatures": [21.05, 21.12, 21.1, 21.1, 21.1]
}
}
```
////
/// api-response-spec
open: True
| Field | Type | Description |
| ---------- | :----: | ----------------------------------------------------------------------------- |
| *variable* | object | A primary object including zero or more [Sensor Objects](#sensor-obj-spec). |
| | | The `fields` in this object will be sensor names as reported by Klippy. |^
| | | If Klippy has not been initialized or reports no sensors this object will |^
| | | be empty. |^
| Field | Type | Description |
| -------------- | :------: | ------------------------------------------------------------------ |
| `temperatures` | [float?] | Contains the history of temperature measurements of this sensor. |
| | | If the sensor is a `temperature monitor` values may be `null`. A |^
| | | `null` value indicates that the sensor recorded no measurement at |^
| | | that time. |^
| `targets` | [float] | Contains the history of temperature targets for heaters. |
| `speeds` | [float] | Contains a history of `speeds` for fans. This value should be |
| | | between 0 and 1 indicating the pwm duty cycle. |^
| `powers` | [float] | Contains a history fof `powers` for heaters. This value should be |
| | | between 0 and 1 indicating the pwm duty cycle. |^
{ #sensor-obj-spec } Sensor Object
//// Note
Fields not reported by a sensor will be omitted in the `Sensor Object`.
Each array in the `Sensor Object` is a FIFO queue, where the measurement at index 0
is the oldest value. The time period between each measurement is 1 second. The
maximum length of the array is set in Moonraker's configuration, where the default is
1200 values.
////
///
## Request Cached GCode Responses
```{.http .apirequest title="HTTP Request"}
GET /server/gcode_store?count=100
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.gcode_store",
"params": {
"count": 100
},
"id": 7643
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------- | :--: | ------------ | --------------------------------------------------- |
| `count` | int | *Store Size* | The number of cached gcode responses to return. The |
| | | | default is to return all cached items. |^
///
//// collapse-code
```{.json .apiresponse title="Example Response"}
{
"gcode_store": [
{
"message": "FIRMWARE_RESTART",
"time": 1615832299.1167388,
"type": "command"
},
{
"message": "// Klipper state: Ready",
"time": 1615832309.9977088,
"type": "response"
},
{
"message": "M117 This is a test",
"time": 1615834094.8662775,
"type": "command"
},
{
"message": "G4 P1000",
"time": 1615834098.761729,
"type": "command"
},
{
"message": "STATUS",
"time": 1615834104.2860553,
"type": "command"
},
{
"message": "// Klipper state: Ready",
"time": 1615834104.3299904,
"type": "response"
}
]
}
```
////
/// api-response-spec
open: True
| Field | Type | Description |
| ------------- | :------: | ---------------------------------------------------------------- |
| `gcode_store` | [object] | An array of [GCode Tracking Objects](#gc-tracking-obj-spec). |
| | | The array is a FIFO queue with the oldest item being at index 0. |^
| Field | Type | Description |
| --------- | :----: | ------------------------------------------------------------------ |
| `message` | string | The GCode Message associated with ths object. |
| `time` | float | The time at which the message was received reported in Unix Time. |
| `type` | string | The message type. Can be `command` or `response`. Commands are |
| | | only tracked when received through Moonraker's gcode API endpoint. |^
{ #gc-tracking-obj-spec } GCode Tracking Object
///
## Rollover Logs
Requests a manual rollover for log files registered with Moonraker's
log management facility. Currently these are limited to `moonraker.log`
and `klippy.log`.
/// Warning
Moonraker must be able to manage Klipper's systemd service to
perform a manual rollover. The rollover will fail under the following
conditions:
- Moonraker cannot detect Klipper's systemd unit
- Moonraker cannot detect the location of Klipper's files
- A print is in progress
///
```{.http .apirequest title="HTTP Request"}
POST /server/logs/rollover
Content-Type: application/json
{
"application": "moonraker"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.logs.rollover",
"params": {
"application": "moonraker"
},
"id": 4656
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------------- | :----: | ------- | ------------------------------------------------------- |
| `application` | string | *all* | The name of the application for which the log should be |
| | | | rolled over. Can be `moonraker` or `klipper`. When no |^
| | | | value is specified all logs are rolled over. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"rolled_over": [
"moonraker",
"klipper"
],
"failed": {}
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| ------------- | :------: | -------------------------------------------------------- |
| `rolled_over` | [string] | A list of application names successfully rolled over. |
| `failed` | object | An object where the fields consist of applications names |
| | | that failed the rollover procedure. The value assigned |^
| | | to each field is an error message. |^
///
## Restart Server
```{.http .apirequest title="HTTP Request"}
POST /server/restart
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.restart",
"id": 4656
}
```
```{.text .apiresponse title="Response"}
"ok"
```
## Identify Connection
This method provides a way for applications with persistent connections
to identify themselves to Moonraker. This information may be used by
Moonraker perform an action or present information based on if a specific
type of frontend is connected. Currently this method is only available
to websocket and unix socket connections. Once this endpoint returns
success it cannot be called again, repeated calls will result in an error.
```{.text .apirequest title="HTTP request"}
Not Available
```
```{.json .apirequest title="JSON-RPC request (Websocket/Unix Socket Only)"}
{
"jsonrpc": "2.0",
"method": "server.connection.identify",
"params": {
"client_name": "moontest",
"version": "0.0.1",
"type": "web",
"url": "http://github.com/arksine/moontest",
"access_token": "<base64 encoded token>",
"api_key": "<system API key>"
},
"id": 4656
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| -------------- | :----: | ------------ | -------------------------------------------------- |
| `client_name` | string | **REQUIRED** | The name of the application identifying itself, |
| | | | ie: `Mainsail`, `Fluidd`, `KlipperScreen`, etc. |^
| `version` | string | **REQUIRED** | The version of the application identifying itself. |
| `type` | string | **REQUIRED** | The type of the application. Expand for available |
| | | | values. |^
| | | | #valid-id-type-desc |+
| `url` | string | **REQUIRED** | The project URL or homepage for the application. |
| `access_token` | string | `null` | An optional JSON Web Token used to authenticate |
| | | | the websocket connection. Only needed when the |^
| | | | app uses JWT authentication and did not |^
| | | | authenticate through the original Websocket |^
| | | | Request. |^
| `api_key` | string | `null` | An optional API Key used to authenticate the |
| | | | connection. Only needed when the APP uses API |^
| | | | Key authentication and did not authenticate |^
| | | | through the original Websocket Request. |^
| Name | Description |
| --------- | --------------------------------------------------------------- |
| `web` | A web application like `Mainsail` and `Fluidd`. |
| `mobile` | A mobile application like `Mobileraker`. |
| `desktop` | A desktop application like `OrcaSlicer`. |
| `display` | An application intended to drive displays like `KlipperScreen`. |
| `bot` | An interactive bot like `MoonCord`. |
| `agent` | An external extension like `Obico`. |
| `other` | Anything that doesn't fit in to the above categories. |
{: #valid-id-type-desc }
//// Note
When identifying as an `agent`, only one instance should be connected
to Moonraker at a time. If multiple agents of the same `client_name`
attempt to identify themselves this endpoint will return an error.
See the [extensions](./extensions.md) document for more information about
`agents`.
////
//// Tip
See the authorization API documentation for details on JWT and API Key authentication.
////
///
```{.json .apiresponse title="Example Response"}
{
"connection_id": 1730367696
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| --------------- | :--: | ---------------------------------------- |
| `connection_id` | int | A unique identifier for this connection. |
///
## Get Websocket ID
!!! Warning
This method is deprecated. Please use the
[identify endpoint](#identify-connection) to retrieve the
Websocket's UID
```{.text .apirequest title="HTTP request"}
Not Available
```
```{json .apirequest title="JSON-RPC request (Websocket/Unix Socket Only)"}
{
"jsonrpc": "2.0",
"method": "server.websocket.id",
"id": 4656
}
```
```{.json .apiresponse title="Example Response"}
{
"websocket_id": 1730367696
}
```
/// api-response-spec
open: True
| Field | Type | Description |
| -------------- | :--: | ---------------------------------------- |
| `websocket_id` | int | A unique identifier for this connection. |
///

View File

@@ -0,0 +1,770 @@
# Update Management
The endpoints in the section are available when the `[update_manager]`
component has been configured in `moonraker.conf`. They may be used
to manage updates for Moonraker, Klipper, OS Packages, and additional
software added through the configuration.
## Get update status
```{.http .apirequest title="HTTP Request"}
GET /machine/update/status
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "machine.update.status",
"id": 4644
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| --------- | :--: | ------- | ----------------------------------------------- |
| `refresh` | bool | false | *DEPRECATED*. When `true` an attempt will |
| | | | be made to refresh all updaters. The refresh |^
| | | | will abort under the following conditions:<BR/> |^
| | | | - an update is in progress<BR/> |^
| | | | - a print is in progress<BR/> |^
| | | | - the update manager hasn't completed |^
| | | | initialization<BR/> |^
| | | | - a refresh has been performed within the last |^
| | | | 60 seconds<BR/> |^
//// Note
The `refresh` parameter is deprecated. Front end developers should use the
[refresh endpoint](#refresh-update-status) to request a refresh.
////
///
/// collapse-code
```{.json #status-example-response .apiresponse title="Example Response"}
{
"busy": false,
"github_rate_limit": 60,
"github_requests_remaining": 57,
"github_limit_reset_time": 1615836932,
"version_info": {
"system": {
"name": "system",
"configured_type": "system",
"package_count": 4,
"package_list": [
"libtiff5",
"raspberrypi-sys-mods",
"rpi-eeprom-images",
"rpi-eeprom"
]
},
"moonraker": {
"channel": "dev",
"debug_enabled": true,
"is_valid": true,
"configured_type": "git_repo",
"corrupt": false,
"info_tags": [],
"detected_type": "git_repo",
"name": "moonraker",
"remote_alias": "arksine",
"branch": "master",
"owner": "arksine",
"repo_name": "moonraker",
"version": "v0.7.1-364",
"remote_version": "v0.7.1-364",
"rollback_version": "v0.7.1-360",
"current_hash": "ecfad5cff15fff1d82cb9bdc64d6b548ed53dfaf",
"remote_hash": "ecfad5cff15fff1d82cb9bdc64d6b548ed53dfaf",
"is_dirty": false,
"detached": true,
"commits_behind": [],
"git_messages": [],
"full_version_string": "v0.7.1-364-gecfad5c",
"pristine": true,
"recovery_url": "https://github.com/Arksine/moonraker.git",
"remote_url": "https://github.com/Arksine/moonraker.git",
"warnings": [],
"anomalies": [
"Unofficial remote url: https://github.com/Arksine/moonraker-fork.git",
"Repo not on official remote/branch, expected: origin/master, detected: altremote/altbranch",
"Detached HEAD detected"
]
},
"mainsail": {
"name": "mainsail",
"owner": "mainsail-crew",
"version": "v2.1.1",
"remote_version": "v2.1.1",
"rollback_version": "v2.0.0",
"configured_type": "web",
"channel": "stable",
"info_tags": [
"desc=Mainsail Web Client",
"action=some_action"
],
"warnings": [],
"anomalies": [],
"is_valid": true
},
"fluidd": {
"name": "fluidd",
"owner": "fluidd-core",
"version": "v1.16.2",
"remote_version": "v1.16.2",
"rollback_version": "v1.15.0",
"configured_type": "web",
"channel": "beta",
"info_tags": [],
"warnings": [],
"anomalies": [],
"is_valid": true
},
"klipper": {
"channel": "dev",
"debug_enabled": true,
"is_valid": true,
"configured_type": "git_repo",
"corrupt": false,
"info_tags": [],
"detected_type": "git_repo",
"name": "klipper",
"remote_alias": "origin",
"branch": "master",
"owner": "Klipper3d",
"repo_name": "klipper",
"version": "v0.10.0-1",
"remote_version": "v0.10.0-41",
"rollback_version": "v0.9.1-340",
"current_hash": "4c8d24ae03eadf3fc5a28efb1209ce810251d02d",
"remote_hash": "e3cbe7ea3663a8cd10207a9aecc4e5458aeb1f1f",
"is_dirty": false,
"detached": false,
"commits_behind": [
{
"sha": "e3cbe7ea3663a8cd10207a9aecc4e5458aeb1f1f",
"author": "Kevin O'Connor",
"date": "1644534721",
"subject": "stm32: Clear SPE flag on a change to SPI CR1 register",
"message": "The stm32 specs indicate that the SPE bit must be cleared before\nchanging the CPHA or CPOL bits.\n\nReported by @cbc02009 and @bigtreetech.\n\nSigned-off-by: Kevin O'Connor <kevin@koconnor.net>",
"tag": null
},
{
"sha": "99d55185a21703611b862f6ce4b80bba70a9c4b5",
"author": "Kevin O'Connor",
"date": "1644532075",
"subject": "stm32: Wait for transmission to complete before returning from spi_transfer()",
"message": "It's possible for the SCLK pin to still be updating even after the\nlast byte of data has been read from the receive pin. (In particular\nin spi mode 0 and 1.) Exiting early from spi_transfer() in this case\ncould result in the CS pin being raised before the final updates to\nSCLK pin.\n\nAdd an additional wait at the end of spi_transfer() to avoid this\nissue.\n\nSigned-off-by: Kevin O'Connor <kevin@koconnor.net>",
"tag": null
}
],
"git_messages": [],
"full_version_string": "v0.10.0-1-g4c8d24ae-shallow",
"pristine": true,
"recovery_url": "https://github.com/Klipper3d/klipper.git",
"remote_url": "https://github.com/Klipper3d/klipper.git",
"warnings": [],
"anomalies": []
}
}
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| --------------------------- | :----: | ----------------------------------------------------- |
| `busy` | bool | Set to `true` if an update is currently in progress. |
| `github_rate_limit` | int | The maximum number of GitHub API requests allowed. |
| | | An unauthenticated user is typically allowed 60 |^
| | | requests per hour. |^
| `github_requests_remaining` | int | The number of GitHub API requests remaining until the |
| | | reset time is reached. |^
| `github_limit_reset_time` | int | The time when the rate limit will reset, reported in |
| | | unix time. |^
| `version_info` | object | A `Version Info` object containing the update status |
| | | for each configured software updater. |^
| | | #version-info-desc |+
{ #update-status-spec }
| Field | Type | Description |
| --------- | :----: | ---------------------------------------------------------- |
| `system` | object | A [System Status](#system-status-spec) object. |
| | | This field is only available when the `update_manager` is |^
| | | configured to update system packages. |^
| _updater_ | object | A `Status Update` object. There are multiple sub-types of |
| | | status objects, the specific type can be determined by the |^
| | | object's [configured_type](#configured-type-desc) field. |^
| | | The `version_info` object may have multiple _updater_ |^
| | | items. The field name for each updater will match the |^
| | | object's `name`. |^
{ #version-info-desc } Version Info
| Type | Description |
| ---------- | ---------------------------------------------------------- |
| `git_repo` | A [Git Repo Status](#git-repo-status-spec) object. |
| | The software is distributed through a git repo on GitHub. |^
| `web` | A [Net Hosted Status](#net-app-status-spec ) object. |
| | The software is a web application. |^
| | Updates are GitHub hosted releases packaged in a zip file. |^
| `zip` | A [Net Hosted Status](#net-app-status-spec ) object. |
| | The software is a local application, optionally installed |^
| | as a system service. Updates are GitHub hosted releases |^
| | packaged in a zip file. |^
| `python` | A [Python Package Status](#python-status-spec) object. |
| | The software is a Python Application installed in its own |^
| | virtualenv. Updates may be hosted on PyPI or GitHub. |^
| | Pip is used to deploy updates. |^
| `system` | A [System Status](#system-status-spec) object. This type |
| | is internally managed and only applicable to the system |^
| | package manager. |^
{ #configured-type-desc } Configured Types
| Field | Type | Description |
| ---------------------- | :------: | -------------------------------------------------------- |
| `name` | string | The name of the software to manage updates for. |
| `configured_type` | string | The [type](#configured-type-desc) of updater configured. |
| `detected_type` | string | **DEPRECATED.** Will always report `git_repo`. |
| `channel` | string | The configured update `channel`. |
| | | #git-repo-channel-desc |+
| `channel_invalid` | bool | A value of `true` indicates that the current `channel` |
| | | configuration is not supported by the type. Will |^
| | | always be `false` for `git_repo` types as all channels |^
| | | are supported. |^
| `debug_enabled` | bool | Set to `true` when Moonraker's debug features are |
| | | enabled. In this condition updates may proceed when the |^
| | | repo's HEAD is detached. |^
| `is_valid` | bool | Set to `true` when repo detection completes and passes |
| | | all validity checks. |^
| `version` | string | The current detected version. |
| `remote_version` | string | The latest version available on the remote. |
| `rollback_version` | string | The version prior to the last update. This version is |
| | | used during a `rollback` request. |^
| `full_version_string` | string | The complete version string reported by `git describe`. |
| | | Generally includes an abbreviated hash of the current |^
| | | commit and tags such as "dirty" when appropriate. |^
| `remote_hash` | string | The latest available commit hash on the remote. |
| `current_hash` | string | The commit hash the local repo is currently on. |
| `remote_alias` | string | The git alias of the remote. The git default for the |
| | | primary alias is `origin`. |^
| `remote_url` | string | Full URL of the git remote matching the current |
| | | `remote_alias`. |^
| `recovery_url` | string | The `origin` git remote URL for this repo. This URL is |
| | | used to perform a `hard recovery` when requested. |^
| `owner` | string | The owner of the remote repo as detected from the remote |
| | | URL. |^
| `branch` | string | The name of the current git branch. |
| `repo_name` | string | The name of the remote repo as detected from the remote |
| | | URL. |^
| `is_dirty` | bool | Set to `true` if the repo is "dirty", ie: if one or |
| | | more files in the repo have been modified. |^
| `corrupt` | bool | Set to `true` if the repo is corrupt. This indicates |
| | | that the local repo is broken and needs to be recovered. |^
| `pristine` | bool | Set to `true` when the repo is clean and no untracked |
| | | files exist in the repo. |^
| `detached` | bool | Set to `true` when the git repo's HEAD is detached. |
| `git_messages` | [string] | An array of strings containing the output from a failed |
| | | `git` command during initialization or an update. This |^
| | | array will be empty if all `git` commands succeed. |^
| `anomalies` | [string] | An array of strings that describe anomalies found during |
| | | initialization. An anomaly can be defined as an |^
| | | unexpected condition that does not result in an |^
| | | `invalid` repo state. Updates may proceed when |^
| | | anomalies are detected. An example of an anomaly is the |^
| | | presence of "untracked files" in the repo. |^
| `warnings` | [string] | An array of strings that describe warnings detected |
| | | during repo initialization. When a warning is present |^
| | | the repo is marked invalid and updates are disabled. |^
| `commits_behind` | [object] | An array of `Commit Info` objects providing commit data |
| | | on upstream commits available for update. This array is |^
| | | limited to a size of 30 untagged commits. Any tagged |^
| | | commits within 100 commits behind are included. |^
| | | #git-commit-info-spec |+
| `commits_behind_count` | int | The total number of commits the current repo is behind |
| | | the next update. This number may be greater than the |^
| | | length of the `commits_behind` array. |^
| `info_tags` | object | An object containing custom tags added to the updater's |
| | | configuration in `moonraker.conf`. The values will |^
| | | always be strings. Client developers may define what |^
| | | tags, if any, users will configure. The software can |^
| | | then choose to display information or perform a |^
| | | specific action pre/post update if necessary. |^
{ #git-repo-status-spec } Git Repo Status
| Channel | Description |
| -------- | --------------------------------------------------------- |
| `stable` | The repo will update to the latest tagged stable release. |
| `beta` | The repo will update to the latest tag. This may include |
| | tags with `beta` and `release candidate` identifiers. |^
| `dev` | The repo will update to the latest available commit. |
{ #git-repo-channel-desc }
| Field | Type | Description |
| --------- | :------------: | ----------------------------------------------------- |
| `author` | string | The author of the commit. |
| `date` | string | The date of the commit in unix time. Note that the |
| | | date is extracted from the git log as a string value. |^
| | | It should be converted to an integer prior to |^
| | | processing from unix time. |^
| `sha` | string | The commit hash. |
| `subject` | string | The title of the commit. |
| `message` | string | The content in the body of the commit. |
| `tag` | string \| null | The name of the associated tag if present. Will be |
| | | null if the commit has no tag. |^
{ #git-commit-info-spec } Commit Info
| Field | Type | Description |
| ------------------ | :------: | -------------------------------------------------------- |
| `name` | string | The name of the software to manage updates for. |
| `configured_type` | string | The [type](#configured-type-desc) of updater configured. |
| `channel` | string | The configured update `channel`. |
| | | #net-hosted-channel-desc |+
| `channel_invalid` | bool | A value of `true` indicates that the current `channel` |
| | | configuration is not supported by the type. |^
| | | are supported. |^
| `debug_enabled` | bool | Set to `true` when Moonraker's debug features are |
| | | enabled. |^
| `owner` | string | The owner of the GitHub repo hosting the software. |
| `repo_name` | string | The name of the GitHub repo hosting the software. |
| `last_error` | string | A message associated with the last error encountered |
| | | after initialization or an update. Will be an empty |^
| | | string if no errors were detected. |^
| `version` | string | The current detected version. |
| `remote_version` | string | The version of the latest available release on GitHub. |
| `rollback_version` | string | The version prior to the last update. This version is |
| | | used during a `rollback` request. |^
| `is_valid` | bool | Set to `true` when the updater has completed |
| | | initialization and all validity checks passed. |^
| `anomalies` | [string] | An array of strings that describe anomalies found during |
| | | initialization. An anomaly can be defined as an |^
| | | unexpected condition that does not result in an |^
| | | `invalid` updater state. Updates may proceed when |^
| | | anomalies are detected. |^
| `warnings` | [string] | An array of strings that describe warnings detected |
| | | during initialization. When a warning is present |^
| | | the updater is marked invalid and updates are disabled. |^
| `info_tags` | object | An object containing custom tags added to the updater's |
| | | configuration in `moonraker.conf`. The values will |^
| | | always be strings. Client developers may define what |^
| | | tags, if any, users will configure. The software can |^
| | | then choose to display information or perform a |^
| | | specific action pre/post update if necessary. |^
{ #net-app-status-spec } Net Hosted Status
| Channel | Description |
| -------- | --------------------------------------------------------- |
| `stable` | The software will update to the stable release on GitHub. |
| `beta` | The software will update to the latest release on GitHub, |
| | including those marked as "pre-release". |^
{ #net-hosted-channel-desc }
| Field | Type | Description |
| --------------------- | :------------: | --------------------------------------------------------- |
| `name` | string | The name of the software to manage updates for. |
| `configured_type` | string | The [type](#configured-type-desc) of updater configured. |
| `channel` | string | The configured update `channel`. |
| | | #python-channel-desc |+
| `channel_invalid` | bool | A value of `true` indicates that the current `channel` |
| | | configuration is not supported by the type. |^
| | | are supported. |^
| `debug_enabled` | bool | Set to `true` when Moonraker's debug features are |
| | | enabled. |^
| `owner` | string | The owner of the GitHub repo hosting the software. |
| | | Will be a `?` when no repo owner is detected. |^
| `repo_name` | string | The name of the GitHub repo hosting the software. |
| | | Will be a `?` when no repo name is detected. |^
| `branch` | string \| null | The name of the branch on the GitHub remote to build |
| | | `dev` updates from. Will be `null` if no primary branch |^
| | | is configured. |^
| `version` | string | The current detected version. |
| `remote_version` | string | The version of the latest available release on GitHub. |
| `rollback_version` | string | The version prior to the last update. This version is |
| | | used during a `rollback` request. |^
| `full_version_string` | string | The complete version string extracted from the python |
| | | package's metadata. |^
| `current_hash` | string | The hash of the commit used to build the current version |
| | | of the package. A placeholder of `not-specified` is used |^
| | | when the the current hash is not provided in the package |^
| | | metadata. |^
| `remote_hash` | string | The hash of the latest update available. A placeholder of |
| | | `update-available` is used when the remote hash is not |^
| | | provided by the remote host and updates are available. |^
| `is_valid` | bool | Set to `true` when the updater has completed |
| | | initialization and all validity checks passed. |^
| `is_dirty` | bool | Set to `true` if the repo was modified at the time the |
| | | package was built. |^
| `changelog_url` | string | A URL to the software's changelog. Will be an empty |
| | | string if no changelog URL is detected. |^
| `anomalies` | [string] | An array of strings that describe anomalies found during |
| | | initialization. An anomaly can be defined as an |^
| | | unexpected condition that does not result in an |^
| | | `invalid` updater state. Updates may proceed when |^
| | | anomalies are detected. |^
| `warnings` | [string] | An array of strings that describe warnings detected |
| | | during initialization. When a warning is present |^
| | | the updater is marked invalid and updates are disabled. |^
| `info_tags` | object | An object containing custom tags added to the updater's |
| | | configuration in `moonraker.conf`. The values will |^
| | | always be strings. Client developers may define what |^
| | | tags, if any, users will configure. The software can |^
| | | then choose to display information or perform a |^
| | | specific action pre/post update if necessary. |^
{ #python-status-spec } Python Package Status
| Channel | Description |
| -------- | -------------------------------------------------------- |
| `stable` | The software will update to the stable release on GitHub |
| | or PyPI. |^
| `beta` | Only applies to packages installed via GitHub. The |
| | software will update to the latest release, including |^
| | hose marked as "pre-release". |^
| `dev` | Only applies to packages installed via GitHub. The |
| | software will update to the latest commit available. |^
{ #python-channel-desc }
| Field | Type | Description |
| ----------------- | :------: | -------------------------------------------------------- |
| `name` | string | The name of the software to manage updates for. Will |
| | | always be `system`. |^
| `configured_type` | string | The [type](#configured-type-desc) of updater configured. |
| | | Will always be `system`. |^
| `package_count` | int | The number of system packages that require updating. |
| `package_list` | [string] | An array of package names that require updating. |
{ #system-status-spec } System Update Status
///
## Refresh update status
Refreshes the internal update state for the requested software.
```{.http .apirequest title="HTTP Request"}
POST /machine/update/refresh
Content-Type: application/json
{
"name": "klipper"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "machine.update.refresh",
"params": {
"name": "klipper"
},
"id": 4644
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------ | :----: | ------- | ----------------------------------------------------- |
| `name` | string | `null` | The name of the software to refresh. |
| | | | If omitted all registered software will be refreshed. |^
///
/// Note
This endpoint will raise 503 error under the following conditions:
- An update is in progress
- A print is in progress
- The update manager hasn't completed initialization
///
For an example response refer to the
[Status Example Response](#status-example-response).
/// api-response-spec
open: True
The response spec is identical to the
[Status Request Specification](#update-status-spec)
///
/// Tip
Applications should use care when calling this method as a refresh
is CPU intensive and may be time consuming. Moonraker can be
configured to refresh state periodically, thus it is recommended
that applications avoid their own procedural implementations.
Instead it is best to call this API only when a user requests a
refresh.
///
## Perform an Upgrade
*Added in API Version 1.5.0*
Upgrade to the most recent release of the requested software.
If an update is requested while a print is in progress then this
request will return an error.
```{.http .apirequest title="HTTP Request"}
POST /machine/update/upgrade
Content-Type: application/json
{
"name": "app_name"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "machine.update.upgrade",
"params": {
"name": "app_name"
},
"id": 8546
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------ | :----: | ------- | ------------------------------------ |
| `name` | string | null | The name of the software to upgrade. |
| | | | If omitted all registered |^
| | | | software updates will be upgraded. |^
///
```{.text .apiresponse title="Response"}
"ok"
```
## Recover a corrupt repo
On occasion a git command may fail resulting in a repo in a
dirty or invalid state. This endpoint may be used to attempt
to recover a git repo that is dirty, broken, or corrupt.
```{.http .apirequest title="HTTP Request"}
POST /machine/update/recover
Content-Type: application/json
{
"name": "moonraker",
"hard": false
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "machine.update.recover",
"params": {
"name": "moonraker",
"hard": false
},
"id": 4564
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------ | :----: | ------------ | --------------------------------------------------- |
| `name` | string | **REQUIRED** | The name of the software to recover. |
| `hard` | bool | false | Determines the [mode](#git-repo-recovery-mode-desc) |
| | | | used to perform the recovery. |^
| Name | Description |
| --------------- | ------------------------------------------------------- |
| `hard == false` | Moonraker will attempt to recover the repo by running |
| | `git reset`. This will generally work for repos that |^
| | are dirty, but will not correct repos that are corrupt. |^
| `hard == true` | Moonraker will remove the current repo and re-clone it. |
{ #git-repo-recovery-mode-desc } Recovery Modes
///
```{.text .apiresponse title="Response"}
"ok"
```
## Rollback to the previous version
```{.http .apirequest title="HTTP Request"}
POST /machine/update/rollback
Content-Type: application/json
{
"name": "moonraker"
}
```
JSON-RPC request:
```json
{
"jsonrpc": "2.0",
"method": "machine.update.rollback",
"params": {
"name": "moonraker"
},
"id": 4564
}
```
```{.text .apiresponse title="Response"}
"ok"
```
## Perform a full update
*Deprecated in API Version 1.5.0, superseded by the*
*[Upgrade](#perform-an-upgrade) endpoint.*
Attempts to update all registered software. Updates are performed in the
following order:
- `system` if enabled
- All optional software configured in `moonraker.conf`.
- Klipper
- Moonraker
```{.http .apirequest title="HTTP Request"}
POST /machine/update/full
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "machine.update.full",
"id": 4645
}
```
```{.text .apiresponse title="Response"}
"ok"
```
## Update Moonraker
*Deprecated in API Version 1.5.0, superseded by the*
*[Upgrade](#perform-an-upgrade) endpoint.*
Upgrades to the latest version of Moonraker and restarts
the service. If an update is requested while a print is in progress then
this request will return an error.
```{.http .apirequest title="HTTP Request"}
POST /machine/update/moonraker
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "machine.update.moonraker",
"id": 4645
}
```
```{.text .apiresponse title="Response"}
"ok"
```
## Update Klipper
*Deprecated in API Version 1.5.0, superseded by the*
*[Upgrade](#perform-an-upgrade) endpoint.*
Upgrades to the latest version of Klipper and restarts
the service. If an update is requested while a print is in progress
then this request will return an error.
```{.http .apirequest title="HTTP Request"}
POST /machine/update/klipper
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "machine.update.klipper",
"id": 5745
}
```
```{.text .apiresponse title="Response"}
"ok"
```
## Update Client
*Deprecated in API Version 1.5.0, superseded by the*
*[Upgrade](#perform-an-upgrade) endpoint.*
Update to the most recent release of the requested software.
If an update is requested while a print is in progress then this
request will return an error.
```{.http .apirequest title="HTTP Request"}
POST /machine/update/client
Content-Type: application/json
{
"name": "app_name"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "machine.update.client",
"params": {
"name": "app_name"
},
"id": 8546
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------ | :----: | ------- | ------------------------------------ |
| `name` | string | null | The name of the software to upgrade. |
| | | | If omitted all registered |^
| | | | software updates will be upgraded. |^
///
```{.text .apiresponse title="Response"}
"ok"
```
## Update System Packages
*Deprecated in API Version 1.5.0, superseded by the*
*[Upgrade](#perform-an-upgrade) endpoint.*
Upgrades system packages. If an update is requested while a print is
in progress then this request will return an error.
```{.http .apirequest title="HTTP Request"}
POST /machine/update/system
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "machine.update.system",
"id": 4564
}
```
```{.text .apiresponse title="Response"}
"ok"
```

View File

@@ -0,0 +1,471 @@
# Webcam Management
Moonraker maintains webcam configuration in its database so
various applications and front-ends can share this configuration
through a consistent interface. The endpoints in this section
may be used to manage various webcam configurations.
/// note
Moonraker does not directly manipulate webcams.
External applications, such as
[crowsnest](https://github.com/mainsail-crew/crowsnest),
handle direct webcam functionality.
///
## List Webcams
```{.http .apirequest title="HTTP Request"}
GET /server/webcams/list
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.webcams.list",
"id": 4654
}
```
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"webcams": [
{
"name": "testcam3",
"location": "door",
"service": "mjpegstreamer",
"enabled": true,
"icon": "mdiWebcam",
"target_fps": 20,
"target_fps_idle": 5,
"stream_url": "http://camera.lan/webcam?action=stream",
"snapshot_url": "http://camera.lan/webcam?action=snapshot",
"flip_horizontal": false,
"flip_vertical": true,
"rotation": 90,
"aspect_ratio": "4:3",
"extra_data": {},
"source": "config",
"uid": "55d3801e-fdc1-438d-8728-2fff8b83b909"
},
{
"name": "tc2",
"location": "printer",
"service": "mjpegstreamer",
"enabled": true,
"icon": "mdiWebcam",
"target_fps": 15,
"target_fps_idle": 5,
"stream_url": "http://printer.lan/webcam?action=stream",
"snapshot_url": "http://printer.lan/webcam?action=snapshot",
"flip_horizontal": false,
"flip_vertical": false,
"rotation": 0,
"aspect_ratio": "4:3",
"extra_data": {},
"source": "database",
"uid": "65e51c8a-6763-41d4-8e76-345bb6e8e7c3"
},
{
"name": "TestCam",
"location": "printer",
"service": "mjpegstreamer",
"enabled": true,
"icon": "mdiWebcam",
"target_fps": 15,
"target_fps_idle": 5,
"stream_url": "/webcam/?action=stream",
"snapshot_url": "/webcam/?action=snapshot",
"flip_horizontal": false,
"flip_vertical": false,
"rotation": 0,
"aspect_ratio": "4:3",
"extra_data": {},
"source": "database",
"uid": "341778f9-387f-455b-8b69-ff68442d41d9"
}
]
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| --------- | :------: | ------------------------------------------------------- |
| `webcams` | [object] | An array of [Webcam Entry](#webcam-entry-spec) objects. |
| Field | Type | Description |
| ----------------- | :----: | ------------------------------------------------------------- |
| `name` | string | Friendly name of the webcam. |
| `location` | string | A single word description of where the webcam |
| | | is located or what it is viewing. |^
| `service` | string | The name of the webcam streaming service used to |
| | | operate the webcam. |^
| `enabled` | bool | Set to `true` when the webcam is available, `false` |
| | | otherwise. |^
| `icon` | string | Name of the icon associated with the webcam. |
| `target_fps` | int | Target frames per second when the printer is active. |
| `target_fps_idle` | int | Target frames per second when the printer is idle. |
| `stream_url` | string | The url for the webcam's stream request. This may |
| | | be a complete url, or a url path relative to |^
| | | Moonraker's host. |^
| `snapshot_url` | string | The url for the webcam's snapshot request. This may |
| | | be a complete url, or a url path relative to |^
| | | Moonraker's host. If the webcam does not support |^
| | | a snapshot url this will be an empty string. |^
| `flip_horizontal` | bool | A value of `true` indicates that the stream should |
| | | be flipped horizontally. |^
| `flip_vertical` | bool | A value of `true` indicates that the stream should |
| | | be flipped vertically. |^
| `rotation` | int | Indicates the amount of clockwise rotation, in |
| | | degrees, that should be applied to the stream. May |^
| | | be 0, 90, 180, or 270. |^
| `aspect_ratio` | string | Indicates the aspect ratio of the stream. The format |
| | | should be `W:H`, for example `4:3` or `16:9`. |^
| `extra_data` | object | An object containing custom configuration added by |
| | | frontends. |^
| `source` | string | The [configuration source](#webcam-configuration-source-desc) |
| | | of the webcam entry. |^
| `uid` | string | A unique identifier assigned to the webcam entry. |
{ #webcam-entry-spec } Webcam Entry
| Source | Description |
| ---------- | -------------------------------------------------------------- |
| `database` | The webcam's configuration is stored in Moonraker's database. |
| | These entries are generally added by front-ends via the webcam |^
| | API. Front-ends may modify and remove these entries. |^
| `config` | The webcam's configuration is sourced from `moonraker.conf`. |
| | The webcam endpoints can not modify or remove these entries. |^
{ #webcam-configuration-source-desc } Configuration Source
//// note
Moonraker does not provide a specification for the `location`, `service`,
and `icon` fields. These fields can contain any string value, generally
front-ends set these values based on their needs. Developers should
consider using the same values that existing front-ends (such as Mainsail
and Fluidd) currently use to maintain compatibility.
////
///
## Get Webcam Information
```{.http .apirequest title="HTTP Request"}
GET /server/webcams/item?uid=341778f9-387f-455b-8b69-ff68442d41d9
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.webcams.get_item",
"params": {
"uid": "341778f9-387f-455b-8b69-ff68442d41d9"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------ | :----: | -------------- | ----------------------------------------------- |
| `uid` | string | **REQUIRED** | The requested webcam's unique ID. While |
| | | | this parameter is considered required, if |^
| | | | omitted the request will fall back on looking |^
| | | | up the camera by `name`. |^
| `name` | string | **DEPRECATED** | The requested webcam's friendly name. This |
| | | | parameter is deprecated, all future |^
| | | | implementations should use the `uid` parameter. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"webcam": {
"name": "TestCam",
"location": "printer",
"service": "mjpegstreamer",
"enabled": true,
"icon": "mdiWebcam",
"target_fps": 15,
"target_fps_idle": 5,
"stream_url": "/webcam/?action=stream",
"snapshot_url": "/webcam/?action=snapshot",
"flip_horizontal": false,
"flip_vertical": false,
"rotation": 0,
"aspect_ratio": "4:3",
"extra_data": {},
"source": "database",
"uid": "341778f9-387f-455b-8b69-ff68442d41d9"
}
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| -------- | :----: | ----------------------------------------------- |
| `webcam` | object | A [Webcam Entry](#webcam-entry-spec) object for |
| | | the requested webcam. |^
///
## Add or update a webcam
Adds a new webcam entry or updates an existing entry. When updating
an entry only the fields provided will be modified.
/// Note
A webcam configured in `moonraker.conf` cannot be updated or
overwritten using this API.
///
```{.http .apirequest title="HTTP Request"}
POST /server/webcams/item
Content-Type: application/json
{
"name": "cam_name",
"snapshot_url": "http://printer.lan:8080/webcam?action=snapshot",
"stream_url": "http://printer.lan:8080/webcam?action=stream"
}
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.webcams.post_item",
"params": {
"name": "cam_name",
"snapshot_url": "/webcam?action=snapshot",
"stream_url": "/webcam?action=stream"
},
"id": 4654
}
```
/// api-parameters
open: True
//// note
The default values in the parameter specification below apply to *new* webcam
entries. Existing entries to be updated only require the `uid` parameter,
all other parameters default to their existing value.
////
| Name | Type | Default | Description |
| ----------------- | :----: | --------------- | ---------------------------------------------------- |
| `uid` | string | null | The unique ID of an existing Webcam Entry to |
| | | | modify. If omitted the request will attempt |^
| | | | to create a new Webcam Entry, otherwise the |^
| | | | existing entry will be updated. |^
| `name` | string | **REQUIRED** | The friendly name of the webcam. Each webcam |
| | | | entry must have a *unique* name. |^
| `location` | string | "printer" | A single word description of where the webcam |
| | | | is located or what it is viewing. |^
| `icon` | string | "mdiWebcam" | Name of the icon associated with the webcam. |
| `enabled` | bool | true | Set to `true` when the webcam is available, `false` |
| | | | otherwise. |^
| `service` | string | "mjpegstreamer" | The name of the webcam streaming service used to |
| | | | operate the webcam. |^
| `target_fps` | int | 15 | Target frames per second when the printer is active. |
| `target_fps_idle` | int | 5 | Target frames per second when the printer is idle. |
| `stream_url` | string | **REQUIRED** | The url for the webcam's stream request. This may |
| | | | be a complete url or a url path relative to |^
| | | | Moonraker's host. |^
| `snapshot_url` | string | "" | The url for the webcam's snapshot request. This may |
| | | | be a complete url or a url path relative to |^
| | | | Moonraker's host. |^
| `flip_horizontal` | bool | false | A value of `true` indicates that the stream should |
| | | | be flipped horizontally. |^
| `flip_vertical` | bool | false | A value of `true` indicates that the stream should |
| | | | be flipped vertically. |^
| `rotation` | int | 0 | Indicates the amount of clockwise rotation, in |
| | | | degrees, that should be applied to the stream. May |^
| | | | be 0, 90, 180, or 270. |^
| `aspect_ratio` | string | "4:3" | Indicates the aspect ratio of the stream. The format |
| | | | should be `W:H`, for example `4:3` or `16:9`. |^
| `extra_data` | object | {} | An object containing custom configuration added by |
| | | | frontends. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"webcam": {
"name": "TestCam",
"location": "printer",
"service": "mjpegstreamer",
"enabled": true,
"icon": "mdiWebcam",
"target_fps": 15,
"target_fps_idle": 5,
"stream_url": "/webcam/?action=stream",
"snapshot_url": "/webcam/?action=snapshot",
"flip_horizontal": false,
"flip_vertical": false,
"rotation": 0,
"aspect_ratio": "4:3",
"extra_data": {},
"source": "database",
"uid": "341778f9-387f-455b-8b69-ff68442d41d9"
}
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| -------- | :----: | ----------------------------------------------- |
| `webcam` | object | A [Webcam Entry](#webcam-entry-spec) object for |
| | | the new or updated webcam. |^
///
## Delete a webcam
/// Note
A webcam configured via `moonraker.conf` cannot be deleted
using this API.
///
```{.http .apirequest title="HTTP Request"}
DELETE /server/webcams/item?uid=341778f9-387f-455b-8b69-ff68442d41d9
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.webcams.delete_item",
"params": {
"uid": "341778f9-387f-455b-8b69-ff68442d41d9"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------ | :----: | -------------- | ----------------------------------------------- |
| `uid` | string | **REQUIRED** | The requested webcam's unique ID. While |
| | | | this parameter is considered required, if |^
| | | | omitted the request will fall back on looking |^
| | | | up the camera by `name`. |^
| `name` | string | **DEPRECATED** | The requested webcam's friendly name. This |
| | | | parameter is deprecated, all future |^
| | | | implementations should use the `uid` parameter. |^
///
Parameters:
- `uid`: The webcam's assigned unique ID. This parameter is optional, when
not specified the request will fallback to the `name` parameter.
- `name`: The name of the webcam to delete. If the named webcam is not
available the request will return with an error. This parameter must
be provided when the `uid` is omitted.
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"webcam": {
"name": "TestCam",
"location": "printer",
"service": "mjpegstreamer",
"target_fps": 15,
"stream_url": "/webcam/?action=stream",
"snapshot_url": "/webcam/?action=snapshot",
"flip_horizontal": false,
"flip_vertical": false,
"rotation": 0,
"source": "database",
"uid": "341778f9-387f-455b-8b69-ff68442d41d9"
}
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| -------- | :----: | ----------------------------------------------- |
| `webcam` | object | A [Webcam Entry](#webcam-entry-spec) object for |
| | | the deleted webcam. |^
///
## Test a webcam
Resolves a webcam's stream and snapshot urls. If the snapshot
is served over http, a test is performed to see if the url is
reachable.
```{.http .apirequest title="HTTP Request"}
POST /server/webcams/test?uid=341778f9-387f-455b-8b69-ff68442d41d9
```
```{.json .apirequest title="JSON-RPC Request"}
{
"jsonrpc": "2.0",
"method": "server.webcams.test",
"params": {
"uid": "341778f9-387f-455b-8b69-ff68442d41d9"
},
"id": 4654
}
```
/// api-parameters
open: True
| Name | Type | Default | Description |
| ------ | :----: | -------------- | ----------------------------------------------- |
| `uid` | string | **REQUIRED** | The requested webcam's unique ID. While |
| | | | this parameter is considered required, if |^
| | | | omitted the request will fall back on looking |^
| | | | up the camera by `name`. |^
| `name` | string | **DEPRECATED** | The requested webcam's friendly name. This |
| | | | parameter is deprecated, all future |^
| | | | implementations should use the `uid` parameter. |^
///
/// collapse-code
```{.json .apiresponse title="Example Response"}
{
"name": "TestCam",
"snapshot_reachable": true,
"snapshot_url": "http://127.0.0.1:80/webcam/?action=snapshot",
"stream_url": "http://127.0.0.1:80/webcam/?action=stream"
}
```
///
/// api-response-spec
open: True
| Field | Type | Description |
| -------------------- | :----: | ------------------------------------------ |
| `name` | string | The friendly name of the webcam tested. |
| `snapshot_reachable` | bool | Value will be `true` if Moonraker is able |
| | | to successfully resolve and connect to the |^
| | | snapshot url. |^
| `snapshot_url` | string | The resolved snapshot url. |
| `stream_url` | string | The resolved stream url. |
///

View File

@@ -10,7 +10,8 @@ Users should refer to the [Installation](installation.md) and
[Configuration](configuration.md) sections for documentation on how
to install and configure Moonraker.
Client developers may refer to the [Client API](web_api.md)
Front end and other client developers may refer to the
[External API](./external_api/introduction.md)
documentation.
Backend developers should refer to the

View File

@@ -1,4 +1,4 @@
## Installation
#
This document provides a guide on how to install Moonraker on a Debian
based Linux Distributions. Other linux distributions may work, however
@@ -6,14 +6,14 @@ they may need a custom install script. Moonraker requires Python 3.7 or
greater, verify that your distribution's Python 3 packages meet this
requirement.
### Installing Klipper
## Installing Klipper
Klipper should be installed prior to installing Moonraker. Please see
[Klipper's Documentation](https://klipper3d.com/Overview.html) for details.
After installing Klipper you should make sure to add Moonraker's
[configuration requirements](#klipper-configuration-requirements).
#### Klipper Configuration Requirements
### Klipper Configuration Requirements
Moonraker depends on the following Klippy extras for full functionality:
@@ -34,7 +34,7 @@ missing one or both, you can simply add the bare sections to `printer.cfg`:
path: ~/printer_data/gcodes
```
#### Enabling Klipper's Unix Domain Socket Server
### Enabling Klipper's Unix Domain Socket Server
After Klipper is installed it may be necessary to modify its `defaults` file in
order to enable the Unix Domain Socket. Begin by opening the file in your
@@ -92,7 +92,7 @@ mkdir ~/printer_data/config
mv printer.cfg ~/printer_data/config
```
### Installing Moonraker
## Installing Moonraker
Moonraker provides an install script that can be used to facilitate
installation. The type of installation depends on where the install
@@ -105,7 +105,7 @@ Prior to installation it is necessary to open a terminal on the host
machine, or SSH into it. It is recommended to read this entire
section before proceeding with the installation.
#### Installing the Moonraker Python package
### Installing the Moonraker Python package
The Python Package version of Moonraker will receive fewer updates, and
should generally be more stable. This is intended for users that do
@@ -123,7 +123,7 @@ wget https://raw.githubusercontent.com/Arksine/moonraker/master/scripts/install-
./install-moonraker.sh
```
#### Installing Moonraker from source
### Installing Moonraker from source
Moonraker can be run directly from source. This method of installation will
clone Moonraker's git repository, and may receive frequent bleeding edge
@@ -138,7 +138,7 @@ git clone https://github.com/Arksine/moonraker.git
~/moonraker/scripts/install-moonraker.sh
```
#### Customizing the installation
### Customizing the installation
The install script will attempt to create a basic configuration if
`moonraker.conf` does not exist at the expected location, however if you
@@ -218,7 +218,7 @@ Now you may wish to install a frontend, such as
debian/ubuntu distros).
### Data Folder Structure
## Data Folder Structure
As mentioned previously, files and folders used by Moonraker are organized
in a primary data folder. The example below illustrates the folder
@@ -299,7 +299,7 @@ systemd service unit, ie:
when a file change is detected. The action taken depends on the
"root" folder, thus it is important that they be distinct.
### The systemd service file
## The systemd service file
The default installation will create `/etc/systemd/system/moonraker.service`.
Below is a common example of service file, installed on a Raspberry Pi:
@@ -340,7 +340,7 @@ Following are some items to take note of:
the environment file.
### Command line usage
## Command line usage
This section is intended for users that need to write their own
installation script. Detailed are the command line arguments
@@ -418,7 +418,7 @@ be used to specify options in place of the command line.
[The environment file](#the-environment-file) may be used to set Moonraker's
command line arguments and/or environment variables.
### The environment file
## The environment file
The environment file, `moonraker.env`. is created in the data path during
installation. A default installation's environment file will contain the path
@@ -454,7 +454,7 @@ MOONRAKER_ARGS="-m moonraker"
PYTHONPATH="/home/pi/moonraker"
```
# Optional Speedups
## Optional Speedups
Moonraker supports two optional Python packages that can be used to reduce
its CPU load:
@@ -480,7 +480,7 @@ environment variables in [moonraker.env](#the-environment-file):
- `MOONRAKER_ENABLE_UVLOOP="n"`
### PolicyKit Permissions
## PolicyKit Permissions
Some of Moonraker's components require elevated privileges to perform actions.
Previously these actions could only be run via commandline programs launched
@@ -548,7 +548,7 @@ enable_system_updates: False
Previously installed PolicyKit rules can be removed by running
`set-policykit-rules.sh -c`
### Completing Privileged Upgrades
## Completing Privileged Upgrades
At times an update to Moonraker may require a change to the systemd service
file, which requires sudo permission to complete. Moonraker will present
@@ -579,7 +579,7 @@ bound to another port the user may specify a custom address and port.
The API Key (`-k`) option is only necessary if the localhost is not authorized
to access Moonraker's API.
### Retrieving the API Key
## Retrieving the API Key
Some clients may require an API Key to connect to Moonraker. After the
`[authorization]` component is first configured Moonraker will automatically
@@ -617,7 +617,7 @@ sudo systemctl restart moonraker
{"result": "8ce6ae5d354a4365812b83140ed62e4b"}
### Database Backup and Restore
## Database Backup and Restore
Moonraker stores persistent data using an Sqlite database. By default
the database file is located at `<data_folder>/database/moonraker-sql.db`.
@@ -632,7 +632,7 @@ existing database file when the Moonraker service has been stopped.
Restoration can be performed by stopping the Moonraker service and
overwriting the existing database with the backup.
#### LDMB Database (deprecated)
### LDMB Database (deprecated)
Previous versions of Moonraker used a [LMDB Database](http://www.lmdb.tech/doc/)
for persistent storage of procedurally generated data. LMDB database files are
@@ -697,7 +697,7 @@ contain credentials and other sensitive information, so users should treat
this file accordingly. It is not recommended to keep backups in any folder
served by Moonraker.
### Recovering a broken repo
## Recovering a broken repo
Currently Moonraker is deployed using `git`. Without going into the gritty
details,`git` is effectively a file system, and as such is subject to
@@ -734,7 +734,7 @@ git clone https://github.com/Klipper3d/klipper.git
sudo systemctl restart klipper
```
### Debug options for developers
## Debug options for developers
Moonraker accepts several command line arguments that can be used to
assist both front end developers and developers interested in extending

View File

@@ -18,7 +18,7 @@ cors_domains:
http://app.fluidd.xyz
# Enable OctoPrint compatibility for Slicer uploads
# Supports Cura, Slic3r, and Slic3r dervivatives
# Supports Cura, Slic3r, and Slic3r derivatives
# (PrusaSlicer, SuperSlicer)
[octoprint_compat]
# Default webcam config values:

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +0,0 @@
[data-md-color-scheme="slate"] {
--md-table-color: rgb(20, 20, 20);
}
thead th {
background-color: var(--md-table-color)
}

View File

@@ -0,0 +1,2 @@
!function(){"use strict";var t;t=function(){for(var t=document.querySelectorAll("tbody"),e=0;e<t.length;e++)for(var n=t[e].children,o=function(){var t=n[r];if(t.hasAttribute("compact-container")){var e=n[r-1];t.classList.add("table-container"),e.classList.add("table-container-ctrl"),e.addEventListener("click",(function(n){e.hasAttribute("open")?(t.removeAttribute("open"),e.removeAttribute("open")):(t.setAttribute("open",""),e.setAttribute("open",""))}))}},r=1;r<n.length;r++)o()},window.document$?window.document$.subscribe(t):document.addEventListener("DOMContentLoaded",t)}();
//# sourceMappingURL=compact-tables-qqTQvuZ9.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"compact-tables-qqTQvuZ9.js","sources":["compact-tables.js"],"sourcesContent":["(() => {\n const main = () => {\n // Iterate through all tables looking for containers. This\n // works without assigning IDs to everything.\n const tbody_list = document.querySelectorAll(\"tbody\")\n for (let i = 0; i < tbody_list.length; i++) {\n const tbody = tbody_list[i]\n const row_list = tbody.children\n for (let j = 1; j < row_list.length; j++) {\n const cur_row = row_list[j]\n if (cur_row.hasAttribute(\"compact-container\")) {\n const control_row = row_list[j-1]\n cur_row.classList.add(\"table-container\")\n control_row.classList.add(\"table-container-ctrl\")\n control_row.addEventListener(\"click\", (event) => {\n if (control_row.hasAttribute(\"open\")) {\n cur_row.removeAttribute(\"open\")\n control_row.removeAttribute(\"open\")\n } else {\n cur_row.setAttribute(\"open\", \"\")\n control_row.setAttribute(\"open\", \"\")\n }\n })\n }\n }\n }\n }\n\n if (window.document$) {\n // Material specific hook\n window.document$.subscribe(main)\n } else {\n // Normal non-Material specific hook\n document.addEventListener(\"DOMContentLoaded\", main)\n }\n\n})()"],"names":["main","tbody_list","document","querySelectorAll","i","length","row_list","children","_loop","cur_row","j","hasAttribute","control_row","classList","add","addEventListener","event","removeAttribute","setAttribute","window","document$","subscribe"],"mappings":"yBAAA,IACUA,IAAO,WAIT,IADA,IAAMC,EAAaC,SAASC,iBAAiB,SACpCC,EAAI,EAAGA,EAAIH,EAAWI,OAAQD,IAGnC,IAFA,IACME,EADQL,EAAWG,GACFG,SAAQC,EAAAA,WAE3B,IAAMC,EAAUH,EAASI,GACzB,GAAID,EAAQE,aAAa,qBAAsB,CAC3C,IAAMC,EAAcN,EAASI,EAAE,GAC/BD,EAAQI,UAAUC,IAAI,mBACtBF,EAAYC,UAAUC,IAAI,wBAC1BF,EAAYG,iBAAiB,SAAS,SAACC,GAC/BJ,EAAYD,aAAa,SACzBF,EAAQQ,gBAAgB,QACxBL,EAAYK,gBAAgB,UAE5BR,EAAQS,aAAa,OAAQ,IAC7BN,EAAYM,aAAa,OAAQ,IAEzC,GACJ,GAfKR,EAAI,EAAGA,EAAIJ,EAASD,OAAQK,IAAGF,KAoB5CW,OAAOC,UAEPD,OAAOC,UAAUC,UAAUrB,GAG3BE,SAASa,iBAAiB,mBAAoBf"}

View File

@@ -1,6 +1,6 @@
##
This file tracks configuration changes and deprecations. Additionally
changest to Moonraker that require user intervention will be tracked
changes to Moonraker that require user intervention will be tracked
here.
### December 24th 2023
@@ -36,7 +36,7 @@ here.
- Configuration options for `[spoolman]` have been added
- Configuration options for `[sensor]` have been added
### Februrary 8th 2023
### February 8th 2023
- The `provider` option in the `[machine]` section no longer accepts
`supervisord` as an option. It has been renamed to `supervisord_cli`.
@@ -72,7 +72,7 @@ here.
### July 27th 2022
- The behavior of `[include]` directives has changed. Included files
are now parsed as they are encountered. If sections are duplicated
options in the last section parsed take precendence. If you are
options in the last section parsed take precedence. If you are
using include directives to override configuration in `moonraker.conf`
the directives should be moved to the bottom of the file.
- Configuration files now support inline comments.
@@ -83,7 +83,7 @@ here.
warning will be generated. It is crucially important to move configuration
to the correct section as in the future it will be a hard requirement.
### Feburary 22nd 2022
### February 22nd 2022
- The `on_when_upload_queued` option for [power] devices has been
deprecated in favor of `on_when_job_queued`. As the new option
name implies, this option will power on the device when any new
@@ -141,7 +141,7 @@ here.
to retrieve the API Key.
### March 10th 2021
- The `cors_domain` option in the `[authoriztion]` section is now
- The `cors_domain` option in the `[authorization]` section is now
checked for dangerous entries. If a domain entry contains a
wildcard in the top level domain (ie: `http://www.*`) then it
will be rejected, as malicious website can easily reproduce
@@ -192,10 +192,10 @@ here.
~/moonraker/scripts/install-moonraker.sh -r
- The power plugin configuration has changed. See the
[install guide](installation.md#power-control-plugin) for
[the configuration documentation](./configuration.md#power) for
details on the new configuration.
- Users transitioning from the previous version of the power plugin will need
to unexport any curently used pins. For example, the following command
to unexport any currently used pins. For example, the following command
may be used to unexport pin 19:
echo 19 > /sys/class/gpio/unexport

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,28 @@
site_name: Moonraker
site_url: https://moonraker.readthedocs.io
repo_url: https://github.com/Arksine/moonraker
edit_uri: blob/master/docs/
nav:
- Installation: installation.md
- Configuration : configuration.md
- 'Developer Documentation':
- Remote API: web_api.md
- Developer Documentation:
- External API:
- Introduction: external_api/introduction.md
- Server Administration: external_api/server.md
- Printer Administration: external_api/printer.md
- System Administration: external_api/machine.md
- File Management: external_api/file_manager.md
- Authorization and Authentication: external_api/authorization.md
- Database Management: external_api/database.md
- Job Queue Management: external_api/job_queue.md
- Job History Management: external_api/history.md
- Announcements: external_api/announcements.md
- Webcam Management: external_api/webcams.md
- Update Management: external_api/update_manager.md
- Switches, Sensors, and Devices: external_api/devices.md
- Third Party Integrations: external_api/integrations.md
- Extensions: external_api/extensions.md
- JSON-RPC Notifications: external_api/jsonrpc_notifications.md
- Printer Objects: printer_objects.md
- Components: components.md
- Contribution Guidelines: contributing.md
@@ -58,8 +75,8 @@ markdown_extensions:
- pymdownx.caret
- pymdownx.details
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
- pymdownx.highlight
- pymdownx.inlinehilite
- pymdownx.keys
@@ -71,6 +88,8 @@ markdown_extensions:
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde
- pymdownx.saneheaders
- pymdownx.blocks.admonition
- pymdownx.blocks.details:
types:
- name: details-new
@@ -103,13 +122,16 @@ markdown_extensions:
class: quote
- name: api-example-response
class: example
title: "Example Response"
- name: api-response-schema
title: "Response Example"
- name: api-response-spec
class: info
title: "Response Schema"
title: "Response Specification"
- name: api-parameters
class: info
title: "Parameters"
- name: api-notification-spec
class: info
title: "Notification Parameter Specification"
- tables
- compact_tables:
auto_insert_break: false
@@ -117,4 +139,6 @@ markdown_extensions:
expand_text: ''
collapse_text: ''
extra_css:
- src/css/extras.css
- src/css/extra-950ac449d4.css
extra_javascript:
- src/js/compact-tables-qqTQvuZ9.js