mirror of
https://github.com/QIDITECH/moonraker.git
synced 2026-01-30 16:18:44 +03:00
QIDI moonraker
This commit is contained in:
376
docs/api_changes.md
Normal file
376
docs/api_changes.md
Normal file
@@ -0,0 +1,376 @@
|
||||
##
|
||||
This document keeps a record of all changes to Moonraker's web APIs.
|
||||
|
||||
### March 4th 2022
|
||||
- Moonraker API Version 1.0.1
|
||||
- The `server.websocket.id` endpoint has been deprecated. It is
|
||||
recommended to use `server.connection.idenitfy` 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.
|
||||
|
||||
### 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
|
||||
these roots are also monitored, however hidden folders are not.
|
||||
The following changes API changes have been made to acccommodate
|
||||
this functionality:
|
||||
- The `notify_filelist_changed` actions have changed. The new
|
||||
actions are as follows:
|
||||
- `create_file`: sent when a new file has been created. This
|
||||
includes file uploads and copied files.
|
||||
- `create_dir`: sent when a new directory has been created.
|
||||
- `delete_file`: sent when a file has been deleted.
|
||||
- `delete_dir`: sent when a directory has been deleted.
|
||||
- `move_file`: sent when a file has moved.
|
||||
- `move_dir`: sent when a directory has moved.
|
||||
- `modify_file`: sent when an existing file has been modified
|
||||
- `root_update`: sent when a root directory location has been set.
|
||||
For example, if a user changes the gcode path in Klipper, this
|
||||
action is sent with a `notify_filelist_changed` notification.
|
||||
- File list notifications for gcode files are now only sent after
|
||||
all metadata has been processed. Likewise, requests to copy,
|
||||
move, or upload a file will only return after metadata has been
|
||||
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
|
||||
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`
|
||||
directory and filelist notifications will be sent for changes to
|
||||
these thumbnails.
|
||||
- The `notify_metadata_update` notification has been removed Clients
|
||||
- can reliably expect metadata to be available for new or moved gcode
|
||||
files when a request returns.
|
||||
- The return values for several endpoints have been updated. They
|
||||
now contain information similar to that which is pushed by the
|
||||
`notify_filelist_changed` notification.
|
||||
- The deprecated `data` field in gcode metadata has been removed.
|
||||
The `size` field now returns the size of the `.png` file.
|
||||
|
||||
|
||||
### March 15th 2021
|
||||
- The `data` field for gcode thumbnails is now deprecated and will
|
||||
be removed in the near future. Thumbnails are now saved to png
|
||||
files in a `thumbs` directory relative to a gcode file's location.
|
||||
This path is available in the `relative_path` field for each
|
||||
thumbnail entry in the metadata.
|
||||
|
||||
### January 31st 2021
|
||||
- The `GET /server/temperature_store` endpoint now only returns fields
|
||||
that each sensor reports. For example, if a particuarly 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.
|
||||
|
||||
### January 22nd 2021
|
||||
- The `POST /machine/update/client` endpoint now requires a `name`
|
||||
argument. This change added multiple client support
|
||||
- The response to `GET /machine/update/status` no longer returns a
|
||||
`client` field. Instead it will add fields matching the `name` of
|
||||
each configured client. Keep in mind that the client object could
|
||||
have a different set of fields depending on the type of a client. The
|
||||
easy way to check for this is to see if a `branch` field is present.
|
||||
If so, this client is a `git repo`. Otherwise it is a `web` client.
|
||||
|
||||
### January 4th 2021
|
||||
- A `notify_update_refreshed` notification has been added. Moonraker now
|
||||
auto-refreshes the update status at roughly a 2 hour interval. When
|
||||
an auto-refresh is complete this notification is broadcast. Included
|
||||
is an object that matches the response from `/machine/update/status`.
|
||||
- The behavior of some of the `update_manager` APIs has changed:
|
||||
- The `refresh` argument for `/machine/update/status` is now more
|
||||
of a suggestion than a rule. If an update or a print is in
|
||||
progress then the request will ignore the refresh argument
|
||||
and immediately return the current status. Generally speaking requesting
|
||||
a refresh should not be necessary with addition of auto refresh.
|
||||
- The update requests (ie `/machine/update/klipper`) will now return
|
||||
an error if a print is in progress. If the requested update is in
|
||||
progress then the request will return valid with a message stating
|
||||
that the update is in progress. If another object is being updated
|
||||
then the request will be queued and block until it its complete.
|
||||
### January 1st 2021
|
||||
- A `notify_klippy_shutdown` websocket notification has been added
|
||||
|
||||
### December 30th 2020
|
||||
- Some additional fields are now reported in the response to
|
||||
`GET /machine/update/status`.
|
||||
|
||||
### November 28th 2020
|
||||
- The following new endpoints are available when the `[update_manager]`
|
||||
section has been configured:
|
||||
- `GET /machine/update/status`
|
||||
- `POST /machine/update/moonraker`
|
||||
- `POST /machine/update/klipper`
|
||||
- `POST /machine/update/client`
|
||||
- `POST /machine/update/system`
|
||||
- The following endpoint has been added and is available as part of the
|
||||
core API:
|
||||
- `POST /machine/services/restart`
|
||||
|
||||
See [web_api.md](web_api.md) for details on these new endpoints.
|
||||
|
||||
### November 23rd 2020
|
||||
- Moonraker now serves Klipper's "docs" directory. This can be access
|
||||
at `GET /server/files/docs/<filename>`.
|
||||
|
||||
### November 19th 2020
|
||||
- The path for the power APIs has changed from `gpio_power` to `device_power`:
|
||||
- `GET /machine/device_power/devices`\
|
||||
`{"jsonrpc":"2.0","method":"machine.device_power.devices","id":"1"}`\
|
||||
Returns an array of objects listing all detected devices.
|
||||
Each object in the array is guaranteed to have the following
|
||||
fields:
|
||||
- `device`: The device name
|
||||
- `status`: May be "init", "on", "off", or "error"
|
||||
- `type`: May be "gpio" or "tplink_smartplug"
|
||||
- `GET /machine/device_power/status?dev_name`\
|
||||
`{"jsonrpc":"2.0","method":"machine.device_power.status","id":"1",
|
||||
"params":{"dev_name":null}}`\
|
||||
It is no longer possible to call this method with no arguments.
|
||||
Status will only be returned for the requested device, to get
|
||||
status of all devices use `/machine/device_power/devices`. As
|
||||
before, this returns an object in the format of
|
||||
`{device_name: status}`, where device_name is the name of the device
|
||||
and `status` is the devices current status.
|
||||
- `POST /machine/device_power/on?dev_name`\
|
||||
`{"jsonrpc":"2.0","method":"machine.device_power.on","id":"1",
|
||||
"params":{"dev_name":null}}`\
|
||||
Toggles device on. Returns the current status of the device.
|
||||
- `POST /machine/device_power/off?dev_name`\
|
||||
`{"jsonrpc":"2.0","method":"machine.device_power.off","id":"1",
|
||||
"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
|
||||
from a single item in `/machine/power/devices`.
|
||||
|
||||
### November 12th 2020
|
||||
- Two new fields have been added to the gcode metadata:
|
||||
- `gcode_start_byte`: Indicates the byte position in the
|
||||
file where the first "Gxx" or "Mxx" command is detected.
|
||||
- `gcode_end_byte`: Indicates the byte position in the
|
||||
file where the last "Gxx" or "Mxx" command is detected.
|
||||
These fields may be used to more accurately predict print
|
||||
progress based on the file size.
|
||||
|
||||
### November 11th 2020
|
||||
- The `server.websocket.id` API has been added. This returns a
|
||||
unique ID that Moonraker uses to track each client connection.
|
||||
As such, this API is only available over the websocket, there
|
||||
is no complementary HTTP request.
|
||||
- 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
|
||||
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
|
||||
websocket connection, one may use the id received from
|
||||
`server.websocket.id`.
|
||||
- The `notify_klippy_ready` websocket notification has been
|
||||
added.
|
||||
|
||||
### November 2nd 2020
|
||||
- The `GET /server/files/directory` endpoint now accepts a new
|
||||
optional argument, `extended`. If `extended=true`, then
|
||||
the data returned for gcode files will also include extracted
|
||||
metadata if it exists.
|
||||
|
||||
### October 25th 2020
|
||||
- The `modified` field reported for files and directories is no
|
||||
longer represented as a string. It is now a floating point
|
||||
value representing unix time (in seconds). This can be used
|
||||
to display the "last modified date" based on the client's
|
||||
timezone.
|
||||
|
||||
### October 21st 2020
|
||||
- The `/server/gcode_store` endpoint no longer returns a string
|
||||
in the result's `gcode_store` field. It now returns an
|
||||
Array of objects, each object containing `message` and `time`
|
||||
fields. The time refers to a timestamp in unix time (seconds),
|
||||
and may be used to determine when the gcode store received the
|
||||
accompanying `message`.
|
||||
|
||||
### September 30th 2020
|
||||
- Two new endpoints have been added:
|
||||
- `GET /server/info` (`server.info`)
|
||||
- `GET /server/gcode_store` (`server.gcode_store`)
|
||||
See web_api.md for details on their usage.
|
||||
|
||||
### September 7th 2020
|
||||
- A new websocket API has been added, `server.files.delete_file`:
|
||||
```
|
||||
{jsonrpc: "2.0", method: "server.files.delete_file", params:
|
||||
{path: "<root>/<file_name>"}, id: <request id>}
|
||||
```
|
||||
Where <root> is either "gcodes" or "config", and <file_name> is
|
||||
the relative path to the file for deletion. For example:
|
||||
`path: "gcodes/my_sub_dir/my_gcode_file.gcode"`
|
||||
|
||||
|
||||
### September 3rd 2020
|
||||
- The Websocket APIs have changed for clarity. The APIs methods now
|
||||
use namespaces similar to those found in common programming languages.
|
||||
This change affects all websocket APIs, however websocket events have
|
||||
not changed. Below is a chart mapping the Previous API to the New API:
|
||||
| Previous Websocket Method | New Websocket Method |
|
||||
|---------------------------|----------------------|
|
||||
| get_printer_info | printer.info |
|
||||
| post_printer_emergency_stop | printer.emergency_stop |
|
||||
| post_printer_restart | printer.restart |
|
||||
| post_printer_firmware_restart | printer.firmware_restart |
|
||||
| get_printer_objects_list | printer.objects.list |
|
||||
| get_printer_objects_query | printer.objects.query |
|
||||
| post_printer_objects_subscribe | printer.objects.subscribe |
|
||||
| get_printer_query_endstops_status | printer.query_endstops.status |
|
||||
| post_printer_gcode_script | printer.gcode.script |
|
||||
| get_printer_gcode_help | printer.gcode.help |
|
||||
| post_printer_print_start | printer.print.start |
|
||||
| post_printer_print_pause | printer.print.pause |
|
||||
| post_printer_print_resume | printer.print.resume |
|
||||
| post_printer_print_cancel | printer.print.cancel |
|
||||
| post_machine_reboot | machine.reboot |
|
||||
| post_machine_shutdown | machine.shutdown |
|
||||
| get_server_temperature_store | server.temperature_store |
|
||||
| get_file_list | server.files.list |
|
||||
| get_file_metadata | server.files.metadata |
|
||||
| get_directory | server.files.get_directory |
|
||||
| post_directory | server.files.post_directory |
|
||||
| delete_directory | server.files.delete_directory |
|
||||
| post_file_move | server.files.move |
|
||||
| post_file_copy | server.files.copy |
|
||||
- The "power" plugin APIs have changed. This affects both HTTP and
|
||||
Websocket APIs. They were originally added to the "/printer" path,
|
||||
however this adds the possibility of a naming conflict. The new
|
||||
APIs are as follows:
|
||||
- `GET /machine/gpio_power/devices` : `machine.gpio_power.devices`
|
||||
- `GET /machine/gpio_power/status` : `machine.gpio_power.status`
|
||||
- `POST /machine/gpio_power/on` : `machine.gpio_power.on`
|
||||
- `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.
|
||||
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:
|
||||
```
|
||||
{jsonrpc: "2.0", method: "notify_metadata_update", params: [metadata]}
|
||||
```
|
||||
Where `metadata` is an object in the following format:
|
||||
|
||||
```json
|
||||
{
|
||||
filename: "file name",
|
||||
size: <file size>,
|
||||
modified: "last modified date",
|
||||
slicer: "Slicer Name",
|
||||
first_layer_height: <in mm>,
|
||||
layer_height: <in mm>,
|
||||
object_height: <in mm>,
|
||||
estimated_time: <time in seconds>,
|
||||
filament_total: <in mm>,
|
||||
thumbnails: [
|
||||
{
|
||||
width: <in pixels>,
|
||||
height: <in pixels>,
|
||||
size: <length of string>,
|
||||
data: <base64 string>
|
||||
}, ...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### August 16th 2020
|
||||
- The structure of data returned from `/printer/info` (`get_printer_info`)
|
||||
has changed to the following format:
|
||||
```json
|
||||
{
|
||||
state: "<klippy state>",
|
||||
state_message: "<current state message>",
|
||||
hostname: "<hostname>",
|
||||
software_version: "<version>",
|
||||
cpu_info: "<cpu_info>",
|
||||
klipper_path: "<moonraker use only>",
|
||||
python_path: "<moonraker use only>",
|
||||
log_file: "<moonraker use only>",
|
||||
config_file: "<moonraker use only>",
|
||||
}
|
||||
```
|
||||
The "state" item can be one of the following:
|
||||
- "startup" - Klippy is in the process of starting up
|
||||
- "ready" - Klippy is ready
|
||||
- "shutdown" - Klippy has shutdown
|
||||
- "error" - Klippy has experienced an error during startup
|
||||
|
||||
The message from each state can be found in the `state_message`.
|
||||
- A `webhooks` printer object has been added, available for subscription or
|
||||
query. It includes the following items:
|
||||
- `state` - Printer state identical to that returned from `/printer/info`
|
||||
- `state_message` - identical to that returned from `/printer/info`
|
||||
- `/printer/objects/status` (`get_printer_objects_status`) has been renamed to
|
||||
`/printer/objects/query` (`get_printer_objects_query`). The format of the
|
||||
websocket request has changed, it should now look like the following:
|
||||
```json
|
||||
{
|
||||
jsonrpc: "2.0",
|
||||
method: "get_printer_objects_query",
|
||||
params: {
|
||||
objects: {
|
||||
gcode: null,
|
||||
toolhead: ["position", "status"]
|
||||
}
|
||||
},
|
||||
id: <request id>
|
||||
}
|
||||
```
|
||||
As shown above, printer objects are now wrapped in an "objects" parameter.
|
||||
When a client wishes to subscribe to all items of a printer object, they
|
||||
should now be set to `null` rather than an empty array.
|
||||
The return value has also changed:
|
||||
```json
|
||||
{
|
||||
eventtime: <klippy time of update>,
|
||||
status: {
|
||||
gcode: {
|
||||
busy: true,
|
||||
gcode_position: [0, 0, 0 ,0],
|
||||
...},
|
||||
toolhead: {
|
||||
position: [0, 0, 0, 0],
|
||||
status: "Ready",
|
||||
...},
|
||||
...}
|
||||
}
|
||||
```
|
||||
The `status` item now contains the requested status.
|
||||
- `/printer/objects/subscription` (`post_printer_objects_subscription`) is now
|
||||
`printer/objects/subscribe` (`post_printer_objects_subscribe`). This
|
||||
request takes parameters in the same format as the `query`. It now returns
|
||||
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
|
||||
for subscribed items when that data changes. This requires that clients
|
||||
initialize their local state with the data returned from the subscription
|
||||
request.
|
||||
- The structure of data returned from `/printer/objects/list` has changed. It
|
||||
now returns an array of available printer objects:
|
||||
```json
|
||||
{ objects: ["gcode", "toolhead", "bed_mesh", "configfile",....]}
|
||||
```
|
||||
- The `notify_klippy_state_changed` notification has been removed. Clients
|
||||
can subscribe to `webhooks` and use `webhooks.state` to be notified of
|
||||
transitions to the "ready" and "shutdown" states
|
||||
- A `notify_klippy_disconnected` event has been added to notify clients
|
||||
when the connection between Klippy and Moonraker has been terminated.
|
||||
This event is sent with no parameters:
|
||||
```json
|
||||
{jsonrpc: "2.0", method: "notify_klippy_disconnected"}
|
||||
```
|
||||
365
docs/components.md
Normal file
365
docs/components.md
Normal file
@@ -0,0 +1,365 @@
|
||||
## Components
|
||||
|
||||
Components in Moonraker are used to extend Moonraker's functionality,
|
||||
similar to "extras" in Klipper. Moonraker divides components into
|
||||
two categories, "core" components and "optional" components. A core
|
||||
component gets its configuration from the `[server]` section and is
|
||||
loaded when Moonraker starts. For example, the `file_manager` is a
|
||||
core component. If a core component fails to load Moonraker will
|
||||
exit with an error.
|
||||
|
||||
Optional components must be configured in `moonraker.conf`. If they
|
||||
have no specific configuration, a bare section, such as `[octoprint_compat]`
|
||||
must be present in `moonraker.conf`. Unlike with core components,
|
||||
Moonraker will still start if an optional component fails to load.
|
||||
Its failed status will be available for clients to query and present
|
||||
to the user.
|
||||
|
||||
### Basic Example
|
||||
|
||||
Components exist in the `components` directory. The below example
|
||||
shows how an `example.py` component might look:
|
||||
```python
|
||||
# Example Component
|
||||
#
|
||||
# Copyright (C) 2021 Eric Callahan <arksine.code@gmail.com>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license.
|
||||
|
||||
class Example:
|
||||
def __init__(self, config):
|
||||
self.server = config.get_server()
|
||||
self.name = config.get_name()
|
||||
|
||||
# Raises an error if "example_int_option" is not configured in
|
||||
# the [example] section
|
||||
self.example_int_opt = config.getint("example_int_option")
|
||||
|
||||
# Returns a NoneType if "example_float_option is not configured
|
||||
# in the config
|
||||
self.example_float_opt = config.getfloat("example_float_option", None)
|
||||
|
||||
self.server.register_endpoint("/server/example", ['GET'],
|
||||
self._handle_example_request)
|
||||
|
||||
async def request_some_klippy_state(self):
|
||||
klippy_apis = self.server.lookup_component('klippy_apis')
|
||||
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_float("optional_request_param", None)
|
||||
state = await self.request_some_klippy_state()
|
||||
return {"example_return_value": state}
|
||||
|
||||
def load_component(config):
|
||||
return Example(config)
|
||||
|
||||
```
|
||||
If you have created a "Klippy extras" module then the above should look
|
||||
look familiar. Moonraker attempts to use similar method for adding
|
||||
extensions, making easier Klipper contributors to add new functionality
|
||||
to Moonraker. Be aware that there is no "Reactor" object in Moonraker,
|
||||
it uses `asyncio` for coroutines. Like Klippy, you should not write
|
||||
code that blocks the main thread.
|
||||
|
||||
### The ConfigHelper Object
|
||||
|
||||
As shown above, each component is passed a config object. This object
|
||||
will be a `ConfigHelper` type, which is an object that wraps a
|
||||
configuration section to simply access to the native `ConfigParser`.
|
||||
A `ConfigHelper` should never be directly instantiated.
|
||||
|
||||
#### *ConfigHelper.get_server()*
|
||||
|
||||
Returns the primary [server](#the-server-object) instance.
|
||||
|
||||
#### *ConfigHelper.get_name()*
|
||||
|
||||
Returns the configuration section name associated with this `ConfigHelper`.
|
||||
|
||||
#### *ConfigHelper.get(option_name, default=Sentinel)*
|
||||
|
||||
Returns the value of the option`option_name` as a string. If
|
||||
the option does not exist, returns `default`. If `default` is
|
||||
not provided raises a `ConfigError`.
|
||||
|
||||
#### *ConfigHelper.getint(option_name, default=Sentinel)*
|
||||
|
||||
Returns the value of the option`option_name` as an integer. If
|
||||
the option does not exist, returns `default`. If `default` is
|
||||
not provided raises a `ConfigError`.
|
||||
|
||||
#### *ConfigHelper.getfloat(option_name, default=Sentinel)*
|
||||
|
||||
Returns the value of the option`option_name` as a float. If
|
||||
the option does not exist, returns `default`. If `default` is
|
||||
not provided raises a `ConfigError`.
|
||||
|
||||
#### *ConfigHelper.getboolean(option_name, default=Sentinel)*
|
||||
|
||||
Returns the value of the option`option_name` as a boolean. If
|
||||
the option does not exist, returns `default`. If `default` is
|
||||
not provided raises a `ConfigError`.
|
||||
|
||||
#### *ConfigHelper.has_section(section_name)*
|
||||
|
||||
Returns True if a section matching `section_name` is in the configuration,
|
||||
otherwise False.
|
||||
|
||||
Note that a ConfigHelper object also implements `__contains__`,
|
||||
which is an alias for `has_section`, ie: `section_name in config_instance`
|
||||
|
||||
#### *ConfigHelper.getsection(section_name)*
|
||||
|
||||
Returns a Config object for the section matching `section_name`. If the
|
||||
section does not exist in the configuration raises a `ConfigError`.
|
||||
|
||||
Note that a ConfigHelper object also implements `__getitem__`,
|
||||
which is an alias for `get_section`, ie: `config_instance[section_name]`
|
||||
|
||||
#### *ConfigHelper.get_options()*
|
||||
|
||||
Returns a dict mapping options to values for all options in the Config
|
||||
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
|
||||
[get_section()](#confighelpergetsectionsection_name).
|
||||
|
||||
### The Server Object
|
||||
|
||||
The server instance represents the central management object in Moonraker.
|
||||
It can be used to register endpoints, register notifications, look up other
|
||||
components, send events, and more.
|
||||
|
||||
#### *Server.lookup_component(component_name, default=Sentinel)*
|
||||
|
||||
Attempts to look up a loaded component, returning the result. If
|
||||
the component has not been loaded, `default` will be returned.
|
||||
If `default` is not provided a `ServerError` will be raised.
|
||||
|
||||
#### *Server.load_component(config, component_name, default=Sentinel)*
|
||||
|
||||
Attempts to load an uninitialized component and returns the result. It is
|
||||
only valid to call this within a a component's `__init__()` method, and
|
||||
should only be necessary if one optional component relies on another. Core components will always be loaded before optional components, thus an optional
|
||||
component may always call
|
||||
[lookup_component()](#serverlookup_componentcomponent_name-defaultsentinel)
|
||||
when it needs a reference to core component.
|
||||
|
||||
If the component fails to load `default` will be returned. If `default`
|
||||
is not provided a `ServerError` will be raised.
|
||||
|
||||
#### *Server.register_endpoint(uri, request_methods, callback, transports=["http", "websocket", "mqtt"], wrap_result=True)*
|
||||
|
||||
Registers the supplied `uri` with the server.
|
||||
|
||||
The `request_methods` argument should be a list of strings containing any
|
||||
combination of `GET`, `POST`, and `DELETE`.
|
||||
|
||||
The `callback` is executed when a request matching the `uri` and a
|
||||
`request_method` is received. The callback function will be passed a
|
||||
`WebRequest` object with details about the request. This function
|
||||
should be able of handling each registered `request_method`. The
|
||||
provided callback must be a coroutine.
|
||||
|
||||
The `transports` argument is a list containing any combination of
|
||||
`http`, `websocket` and `mqtt`. JSON-RPC methods for `websocket` and `mqtt`
|
||||
will be generated based on what is supplied by the `uri` and
|
||||
request_methods` argument. A unique JSON_RPC method is generated for each
|
||||
request method. For example:
|
||||
```python
|
||||
self.server.register_endpoint("/server/example", ["POST"], self._handle_request)
|
||||
```
|
||||
would register a JSON-RPC method like:
|
||||
```
|
||||
server.example
|
||||
```
|
||||
|
||||
However, if multiple requests methods are supplied, the generated JSON-RPC
|
||||
methods will differ:
|
||||
```python
|
||||
self.server.register_endpoint("/server/example", ["GET", "POST", "DELETE"],
|
||||
self._handle_request)
|
||||
```
|
||||
would register:
|
||||
```
|
||||
server.get_example
|
||||
server.post_example
|
||||
server.delete_example
|
||||
```
|
||||
|
||||
The `wrap_result` argument applies only to the `http` protocol. In Moonraker
|
||||
all http requests return a result with a JSON body. By default, the value returned
|
||||
by a `callback` is wrapped in a dict:
|
||||
```python
|
||||
{"result": return_value}
|
||||
```
|
||||
It is only necessary to set this to false if you need to return a body that
|
||||
does not match this result. For example, the `[octoprint_compat]` component
|
||||
uses this functionality to return results in a format that match what
|
||||
OctoPrint itself would return.
|
||||
|
||||
#### *Server.register_event_handler(event, callback)*
|
||||
|
||||
Registers the provided `callback` method to be executed when the
|
||||
provided `event` is sent. The callback may be a coroutine, however it
|
||||
is not required.
|
||||
|
||||
#### *Server.send_event(event, \*args)*
|
||||
|
||||
Emits the event named `event`, calling all callbacks registered to the
|
||||
event. All positional arguments in `*args` will be passed to each
|
||||
callback. Event names should be in the form of
|
||||
`"module_name:event_description"`.
|
||||
|
||||
#### *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
|
||||
`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.
|
||||
|
||||
#### *Server.get_host_info()*
|
||||
|
||||
Returns a tuple of the current host name of the PC and the port Moonraker
|
||||
is serving on.
|
||||
|
||||
#### *Server.get_klippy_info()*
|
||||
|
||||
Returns a dict containing the values from the most recent `info` request to
|
||||
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)
|
||||
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.
|
||||
|
||||
#### *WebRequest.get_endpoint()*
|
||||
|
||||
Returns the URI registered with this request, ie: `/server/example`.
|
||||
|
||||
#### *WebRequest.get_action()*
|
||||
|
||||
Returns the request action, which is synonomous 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.
|
||||
|
||||
#### *WebRequest.get_connection()*
|
||||
|
||||
Returns the associated Websocket connection ID. This will be `None`
|
||||
for HTTP requests when no associated websocket is connected to
|
||||
the client.
|
||||
|
||||
#### *WebRequest.get_args()*
|
||||
|
||||
Returns a reference to the entire argument dictionary. Useful if
|
||||
one request handler needs to preprocess the arguments before
|
||||
passing the WebRequest on to another request handler.
|
||||
|
||||
#### *WebRequest.get(key, default=Sentinel)*
|
||||
|
||||
Returns the request argument at the provided `key`. If the key is not
|
||||
present `default` will be returned. If `default` is not provided a
|
||||
`ServerError` will be raised.
|
||||
|
||||
#### *WebRequest.get_str(key, default=Sentinel)*
|
||||
|
||||
Retrieves the request argument at the provided `key` and converts it
|
||||
to a string, returning the result. If the key is not present the `default`
|
||||
value will be returned. If `default` is not provided or if the attempt at
|
||||
type conversion fails a `ServerError` will be raised.
|
||||
|
||||
#### *WebRequest.get_int(key, default=Sentinel)*
|
||||
|
||||
Retrieves the request argument at the provided `key` and converts it
|
||||
to an integer, returning the result. If the key is not present the `default`
|
||||
value will be returned. If `default` is not provided or if the attempt at
|
||||
type conversion fails a `ServerError` will be raised.
|
||||
|
||||
#### *WebRequest.get_float(key, default=Sentinel)*
|
||||
|
||||
Retrieves the request argument at the provided `key` and converts it
|
||||
to a float, returning the result. If the key is not present the `default`
|
||||
value will be returned. If `default` is not provided or if the attempt at
|
||||
type conversion fails a `ServerError` will be raised.
|
||||
|
||||
#### *WebRequest.get_boolean(key, default=Sentinel)*
|
||||
|
||||
Retrieves the request argument at the provided `key` and converts it
|
||||
to a boolean, returning the result. If the key is not present the `default`
|
||||
value will be returned. If `default` is not provided or if the attempt at
|
||||
type conversion fails a `ServerError` will be raised.
|
||||
|
||||
### MQTT
|
||||
|
||||
If configured by the user the MQTT component is available for lookup.
|
||||
Developers may use this to subscribe and publish topics.
|
||||
|
||||
#### *MQTTClient.is_connected()*
|
||||
|
||||
Returns true if Moonraker is currently connected to the Broker, false
|
||||
otherwise.
|
||||
|
||||
#### *MQTTClient.wait_connection(timeout=None)*
|
||||
|
||||
Blocks until a connection with the broker has been successfully established
|
||||
or until the specified timeout has exceeded. Returns true if the connection
|
||||
was successful established, or False on timeout. If no timeout is specified
|
||||
then this method will block indefinitely until a connection has been
|
||||
established.
|
||||
|
||||
#### *MQTTClient.publish_topic(topic, payload=None, qos=None, retain=False)*
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
Returns a Future that will block until topic is confirmed as published.
|
||||
For QOS level 0 an exception will be raised if the broker is not connected.
|
||||
|
||||
|
||||
#### *MQTTClient.publish_topic_with_response(topic, response_topic, payload=None, qos=None, retain=False, timeout=None)*
|
||||
|
||||
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.
|
||||
The `timeout` is applied to both the attempt to publish and the pending
|
||||
response, so the maximum waiting time would be approximately 2*timeout.
|
||||
|
||||
!!! warning
|
||||
This should only be used when it is guaranteed that the `response_topic`
|
||||
does not have a retained value. Otherwise the returned response will
|
||||
be the retained value.
|
||||
|
||||
#### *MQTTClient.subscribe_topic(topic, callback, qos=None)*
|
||||
|
||||
Subscibes 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
|
||||
is published by another client.
|
||||
|
||||
Returns a `SubscriptionHandle` that may be used to unsubscribe the topic.
|
||||
|
||||
#### *MQTTClinet.unsubscribe(hdl)*
|
||||
|
||||
Unsubscribes the callback associated with `hdl`. If no outstanding callbacks
|
||||
exist for the topic then the topic is unsubscribed from the broker.
|
||||
2067
docs/configuration.md
Normal file
2067
docs/configuration.md
Normal file
File diff suppressed because it is too large
Load Diff
128
docs/contributing.md
Normal file
128
docs/contributing.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Contributing to Moonraker
|
||||
|
||||
While Moonraker exists as a service independently from Klipper, it relies
|
||||
on Klipper to be useful. Thus, the tentative plan is to eventually merge
|
||||
the Moonraker application into the Klipper repo after Moonraker matures,
|
||||
at which point this repo will be archived. As such, contibuting guidelines
|
||||
are near those of Klipper:
|
||||
|
||||
#### New Module Contributions
|
||||
|
||||
All source files should begin with a copyright notice in the following format:
|
||||
|
||||
```python
|
||||
# Module name and brief description of module
|
||||
#
|
||||
# Copyright (C) 2021 YOUR NAME <YOUR EMAIL ADDRESS>
|
||||
#
|
||||
# This file may be distributed under the terms of the GNU GPLv3 license
|
||||
```
|
||||
|
||||
#### Git Commit Format
|
||||
|
||||
Commits should be contain one functional change. Changes that are unrelated
|
||||
or independent should be broken up into multiple commits. It is acceptable
|
||||
for a commit to contain multiple files if a change to one module depends on a
|
||||
change to another (ie: changing the name of a method).
|
||||
|
||||
Avoid merge commits. If it is necessary to update a Pull Request from the
|
||||
master branch use git's interactive rebase and force push.
|
||||
|
||||
Each Commit message should be in the following format:
|
||||
|
||||
```text
|
||||
module: brief description of commit
|
||||
|
||||
More detailed explanation of the change if required
|
||||
|
||||
Signed-off-by: Your Name <your email address>
|
||||
```
|
||||
|
||||
Where:
|
||||
|
||||
- `module`: is the name of the Python module you are changing or parent
|
||||
folder if not applicable
|
||||
- `Your Name`: Your real first and last name
|
||||
- `<your email address>`: A real, reachable email address
|
||||
|
||||
For example, the git log of a new `power.py` device implementation might look
|
||||
like the following:
|
||||
|
||||
```git
|
||||
power: add support for mqtt devices
|
||||
|
||||
Signed-off-by: Eric Callahan <arksine.code@gmail.com>
|
||||
```
|
||||
```git
|
||||
docs: add mqtt power device documentation
|
||||
|
||||
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)
|
||||
shown below. As mentioned above, your signature must contain your
|
||||
real name and a current email address.
|
||||
|
||||
```text
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
1 Letterman Drive
|
||||
Suite D4700
|
||||
San Francisco, CA, 94129
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
||||
#### Code Style
|
||||
Python methods should be fully annotated. Variables should be annotated where
|
||||
the type cannot be inferred. Moonraker uses the `mypy` static type checker for
|
||||
code validation with the following options:
|
||||
|
||||
- `--ignore-missing-imports`
|
||||
- `--follow-imports=silent`
|
||||
|
||||
No line in the source code should exceed 80 characters. Be sure there is no
|
||||
trailing whitespace. To validate code before submission one may use
|
||||
`pycodestyle` with the following options:
|
||||
|
||||
- `--ignore=E226,E301,E302,E303,W503,W504`
|
||||
- `--max-line-length=80`
|
||||
- `--max-doc-length=80`
|
||||
|
||||
Generally speaking, each line in submitted documentation should also be no
|
||||
longer than 80 characters, however there are situations where this isn't
|
||||
possible, such as long hyperlinks or example return values. Documentation
|
||||
isn't linted, so it
|
||||
|
||||
Don't peek into the member variables of another class. Use getters or
|
||||
properties to access object state.
|
||||
350
docs/dev_changelog.md
Normal file
350
docs/dev_changelog.md
Normal file
@@ -0,0 +1,350 @@
|
||||
### Moonraker Version 0.1 - August 11 2020
|
||||
- It is no longer possible to configure the subscription timer. All subscribed
|
||||
objects will update at an interval of 250ms.
|
||||
- Request timeout configuration has been removed. The server will no longer
|
||||
apply a timeout to requests. Any requests pending when Klippy disconnects
|
||||
will be aborted with an error. All pending requests are logged each minute.
|
||||
- The RESET_SD gcode is now SDCARD_RESET_FILE
|
||||
- The "virtual_sdcard" object has removed the following items:
|
||||
- "filename"
|
||||
- "total_duration"
|
||||
- "print_duration"
|
||||
- "filament_used"
|
||||
- A new object, "print_stats", has been added. It reports the following items:
|
||||
- "filename"
|
||||
- "total_duration"
|
||||
- "print_duration"
|
||||
- "filament_used"
|
||||
- "state" - can be one of the following:
|
||||
- "standby" - sd print not in progress
|
||||
- "printing" - print in progress
|
||||
- "paused" - print paused
|
||||
- "error" - print experienced an error
|
||||
- "complete" - print complete
|
||||
- "message" - contains error message when state is "error"
|
||||
- The behavior of print_stats is slightly different. When a print is finished the stats are
|
||||
not cleared. They will remain populated with the final data until the user issues a
|
||||
SDCARD_RESET_FILE gcode.
|
||||
- Moonraker Configuration has moved to moonraker.conf
|
||||
- Klippy now hosts the Unix Domain Socket. As a result, the order in which the
|
||||
Klipper and Moonraker services are started no longer matters.
|
||||
- The `notify_filelist_changed` event has been refactored for clarity. It now
|
||||
returns a result in the following format:
|
||||
```json
|
||||
{
|
||||
action: "<action>",
|
||||
item: {
|
||||
path: "<file or directory path>",
|
||||
root: "<root_name>",
|
||||
size: <file size>,
|
||||
modified: "<date modified>"
|
||||
},
|
||||
source_item: {
|
||||
path: "<file or directory path>",
|
||||
root: "<root_name>"
|
||||
}
|
||||
}
|
||||
```
|
||||
Note that the `source_item` is only present for `move_item` and `copy_item`
|
||||
actions. Below is a list of all available actions:
|
||||
- `upload_file`
|
||||
- `delete_file`
|
||||
- `create_dir`
|
||||
- `delete_dir`
|
||||
- `move_item`
|
||||
- `copy_item`
|
||||
|
||||
### Moonraker Version .08-alpha - 7/2/2020
|
||||
- Moonraker has moved to its own repo.
|
||||
- Python 3 support has been added.
|
||||
- API Key management has moved from Klippy to Moonraker
|
||||
- File Management has moved from Klippy to Moonraker. All static files are now
|
||||
located in the the `/server/files` root path:
|
||||
- klippy.log - `/server/files/klippy.log`
|
||||
- moonraker.log - `/server/files/moonraker.log`
|
||||
- gcode files - `/server/files/gcodes/(.*)`
|
||||
Note that the new file manager will be capable of serving and listing files
|
||||
in directories aside from "gcodes".
|
||||
- Added basic plugin support
|
||||
- Added metadata support for SuperSlicer
|
||||
- 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.
|
||||
They should instead use the new API which exposes this functionality.
|
||||
- New APIs:
|
||||
- `POST /printer/emergency_stop` - `post_printer_emergency_stop`
|
||||
- `GET /server/files/metadata` - `get_file_metadata`
|
||||
- `GET /server/files/directory`
|
||||
- `POST /server/files/directory`
|
||||
- `DELETE /server/files/directory`
|
||||
- The following API changes have been made:
|
||||
| Previous URI | New URI | Previous JSON_RPC method | New JSON_RPC method |
|
||||
|--------------|---------|--------------------------| --------------------|
|
||||
| GET /printer/objects | GET /printer/objects/list | get_printer_objects | get_printer_objects_list |
|
||||
| GET /printer/subscriptions | GET /printer/objects/subscription | get_printer_subscriptions | get_printer_objects_subscription |
|
||||
| POST /printer/subscriptions | POST /printer/objects/subscription | post_printer_subscriptions | post_printer_objects_subscription |
|
||||
| GET /printer/status | GET /printer/objects/status | get_printer_status | get_printer_objects_status |
|
||||
| POST /printer/gcode | POST /printer/gcode/script | post_printer_gcode | post_printer_gcode_script |
|
||||
| GET /printer/klippy.log | GET /server/files/klippy.log | | |
|
||||
| GET /server/moonraker.log | GET /server/files/moonraker.log | | |
|
||||
| GET /printer/files | GET /server/files/list | get_printer_files | get_file_list |
|
||||
| POST /printer/files/upload | POST /server/files/upload | | |
|
||||
| GET /printer/files/<filename> | GET /server/files/gcodes/<filename> | | |
|
||||
| DELETE /printer/files/<filename> | DELETE /server/files/<filename> | | |
|
||||
| GET /printer/endstops | GET /printer/query_endstops/status | get_printer_endstops | get_printer_query_endstops_status |
|
||||
|
||||
### Moonraker Version .07-alpha - 5/7/2020
|
||||
- The server process is no longer managed directly by Klippy. It has moved
|
||||
into its own process dubbed Moonraker. Please see README.md for
|
||||
installation instructions.
|
||||
- API Changes:
|
||||
- `/printer/temperature_store` is now `/server/temperature_store`, or
|
||||
`get_server_temperature_store` via the websocket
|
||||
- `/printer/log` is now `/printer/klippy.log`
|
||||
- `/server/moonraker.log` has been added to fetch the server's log file
|
||||
- Klippy Changes:
|
||||
- The remote_api directory has been removed. There is now a single
|
||||
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
|
||||
when an error is generated attempting to upload or delete a file
|
||||
- The nginx configuration will need the following additional section:
|
||||
```
|
||||
location /server {
|
||||
proxy_pass http://apiserver/server;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
}
|
||||
```
|
||||
|
||||
### Version .06-alpha - 5/4/2020
|
||||
- Add `/machine/reboot` and `/machine/shutdown` endpoints. These may be used
|
||||
to reboot or shutdown the host machine
|
||||
- Fix issue where websocket was blocked on long transactions, resulting in the
|
||||
connection being closed
|
||||
- Log all client requests over the websocket
|
||||
- Add `/printer/temperature_store` endpoint. Clients may use this to fetch
|
||||
stored temperature data. By default the store for each temperature sensor
|
||||
is updated every 1s, with the store holding 20 minutes of data.
|
||||
|
||||
### Version .05-alpha - 04/23/2020
|
||||
- The `[web_server]` module has been renamed to `[remote_api]`. Please update
|
||||
printer.cfg accordingly
|
||||
- Static files no longer served by the API server. As a result, there is
|
||||
no `web_path` option in `[remote_api]`.
|
||||
- The server process now now forwards logging requests back to the Klippy
|
||||
Host, thus all logging is done in klippy.log. The temporary endpoint serving
|
||||
klippy_server.log has been removed.
|
||||
- `/printer/info` now includes two additional keys:
|
||||
- `error_detected` - Boolean value set to true if a host error has been
|
||||
detected
|
||||
- `message` - The current Klippy State message. If an error is detected this
|
||||
message may be presented to the user. This is the same message returned
|
||||
when by the STATUS gcode.
|
||||
- The server process is now launched immediately after the config file is read.
|
||||
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:
|
||||
- `/websocket`
|
||||
- `/printer/info`
|
||||
- `/printer/restart`
|
||||
- `/printer/firmware_restart`
|
||||
- `/printer/log`
|
||||
- `/printer/gcode`
|
||||
- `/access/api_key`
|
||||
- `/access/oneshot_token`
|
||||
The following startup sequence is recommened 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
|
||||
check `error_detected`. If not ready and no error, continue querying on
|
||||
a timer until the printer is either ready or an error is detected.
|
||||
- After the printer has identified itself as ready make subscription requests,
|
||||
get the current file list, etc
|
||||
- If the websocket disconnects the client can assume that the server is shutdown.
|
||||
It should consider the printer's state to be NOT ready and try reconnecting to
|
||||
the websocket until successful.
|
||||
|
||||
### Version .04-alpha - 04/20/2020
|
||||
- Add `/printer/gcode/help` endpoint to gcode.py
|
||||
- Allow the clients to fetch .json files in the root web directory
|
||||
- Add support for detailed print tracking to virtual_sdcard.py. This
|
||||
includes filament usage and print time tracking
|
||||
- Add new file_manager.py module for advanced gcode file management. Gcode
|
||||
files may exist in subdirectories. This module also supports extracting
|
||||
metadata from gcode files.
|
||||
- Clean up API registration. All endpoints are now registered by Klippy
|
||||
host modules outside of static files and `/api/version`, which is used for
|
||||
compatibility with OctoPrint's file upload API.
|
||||
- The server now runs in its own process. Communication between the Host and
|
||||
the server is done over a duplex pipe. Currently this results in a second
|
||||
log file being generated specifically for the server at
|
||||
`/tmp/klippy_server.log`. This is likely a temporary solution, and as such
|
||||
a temporary endpoint has been added at `/printer/klippy_server.log`. Users
|
||||
can use the browser to download the log by navigating to
|
||||
`http://<host>/printer/klippy_server.log`.
|
||||
|
||||
### Version .03-alpha - 03/09/2020
|
||||
- Require that the configured port be above 1024.
|
||||
- Fix hard crash if the webserver fails to start.
|
||||
- Fix file uploads with names containing whitespace
|
||||
- Serve static files based on their relative directory, ie a request
|
||||
for "/js/main.js" will now look for the files in "<web_path>/js/main.js".
|
||||
- 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
|
||||
changes:
|
||||
- The `cancel_gcode`, `pause_gcode`, and `resume_gcode` options have
|
||||
been removed from the [web_server] section.
|
||||
- The `/printer/pause` and `/printer/resume` endpoints will run the "PAUSE"
|
||||
and "RESUME" gcodes respectively. These gcodes can be overridden by a
|
||||
gcode_macro to run custom PAUSE and RESUME commands. For example:
|
||||
```
|
||||
[gcode_macro PAUSE]
|
||||
rename_existing: BASE_PAUSE
|
||||
gcode:
|
||||
{% if not printer.pause_resume.is_paused %}
|
||||
M600
|
||||
{% endif %}
|
||||
|
||||
[gcode_macro M600]
|
||||
default_parameter_X: 50
|
||||
default_parameter_Y: 0
|
||||
default_parameter_Z: 10
|
||||
gcode:
|
||||
SET_IDLE_TIMEOUT TIMEOUT=18000
|
||||
{% if not printer.pause_resume.is_paused %}
|
||||
BASE_PAUSE
|
||||
{% endif %}
|
||||
G1 E-.8 F2700
|
||||
G91
|
||||
G1 Z{Z}
|
||||
G90
|
||||
G1 X{X} Y{Y} F3000
|
||||
```
|
||||
If you are calling "PAUSE" in any other macro of config section, please
|
||||
remember that it will execute the macro. If that is not your intention,
|
||||
change "PAUSE" in those sections to the renamed version, in the example
|
||||
above it is BASE_PAUSE.
|
||||
- The cancel endpoint runs a "CANCEL_PRINT" gcode. Users will need to
|
||||
define their own gcode macro for this
|
||||
- Remove "notify_paused_state_changed" and "notify_printer_state_changed"
|
||||
events. The data from these events can be fetched via status
|
||||
subscriptions.
|
||||
- "idle_timeout" and "pause_resume" now default to tier 1 status updates,
|
||||
which sets their default refresh time is 250ms.
|
||||
- Some additional status attributes have been added to virtual_sdcard.py. At
|
||||
the moment they are experimental and subject to change:
|
||||
- 'is_active' - returns true when the virtual_sdcard is processing. Note
|
||||
that this will return false when the printer is paused
|
||||
- 'current_file' - The name of the currently loaded file. If no file is
|
||||
loaded returns an empty string.
|
||||
- 'print_duration' - The approximate duration (in seconds) of the current
|
||||
print. This value does not include time spent paused. Returns 0 when
|
||||
no file is loaded.
|
||||
- 'total_duration' - The total duration of the current print, including time
|
||||
spent paused. This can be useful for approximating the local time the
|
||||
print started Returns 0 when no file is loaded.
|
||||
- 'filament_used' - The approximate amount of filament used. This does not
|
||||
include changes to flow rate. Returns 0 when no file is loaded.
|
||||
- 'file_position' - The current position (in bytes) of the loaded file
|
||||
Returns 0 when no file is loaded.
|
||||
- 'progress' - This attribute already exists, however it has been changed
|
||||
to retain its value while the print is paused. Previously it would reset
|
||||
to 0 when paused. Returns 0 when no file is loaded.
|
||||
|
||||
### Version .02-alpha - 02/27/2020
|
||||
- Migrated Framework and Server from Bottle/Eventlet to Tornado. This
|
||||
resolves an issue where the server hangs for a period of time if the
|
||||
network connection abruptly drops.
|
||||
- A `webhooks` host module has been created. Other modules can use this
|
||||
the webhooks to register endpoints, even if the web_server is not
|
||||
configured.
|
||||
- Two modules have been renamed, subscription_handler.py is now
|
||||
status_handler.py and ws_handler.py is now ws_manager.py. These names
|
||||
more accurately reflect their current functionality.
|
||||
- Tornado Websockets support string encoded frames. Thus it is no longer
|
||||
necessary for clients to use a FileReader object to convert incoming
|
||||
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:
|
||||
- `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
|
||||
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
|
||||
- `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
|
||||
add the specified objects and attributes to the list of subscribed objects
|
||||
- Requests that query the Klippy host with additional parameters can no
|
||||
longer use variable paths. For example, `POST /printer/gcode/<gcode>` is no
|
||||
longer valid. Parameters must be added to the query string. This currently
|
||||
affects two endpoints:
|
||||
- `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
|
||||
endpoints. Each method name is now generated from its comparable HTTP
|
||||
request. The new method names are listed below:
|
||||
| new method | old method |
|
||||
|------------|------------|
|
||||
| get_printer_files | get_file_list |
|
||||
| get_printer_info | get_klippy_info |
|
||||
| get_printer_objects | get_object_info |
|
||||
| get_printer_subscriptions | get_subscribed |
|
||||
| get_printer_status | get_status |
|
||||
| post_printer_subscriptions | add_subscription |
|
||||
| post_printer_gcode | run_gcode |
|
||||
| post_printer_print_start | start_print |
|
||||
| post_printer_print_pause | pause_print |
|
||||
| post_printer_print_resume | resume_print |
|
||||
| post_printer_print_cancel | cancel_print |
|
||||
| post_printer_restart | restart |
|
||||
| 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
|
||||
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
|
||||
means that it is no longer necessary to wrap the Object in an Array. The
|
||||
gcode and start print requests now look for named parameters, ie:
|
||||
- gcode requests - `{jsonrpc: "2.0", method: "post_printer_gcode",
|
||||
params: {script: "M117 FooBar"}, id: <request id>}`
|
||||
- start print - `{jsonrpc: "2.0", method: "post_printer_print_start",
|
||||
params: {filename: "my_file.gcode"}, id:<request id>}`
|
||||
|
||||
|
||||
### Version .01-alpha - 02/14/2020
|
||||
- The api.py module has been refactored to contain the bottle application and
|
||||
all routes within a class. Bottle is now imported and patched dynamically
|
||||
within this class's constructor. This resolves an issue where the "request"
|
||||
context was lost when the Klippy host restarts.
|
||||
- Change the Websocket API to use the JSON-RPC 2.0 protocol. See the test
|
||||
client (main.js and json-rpc.js) for an example client side implementation.
|
||||
- Remove file transfer support from the websocket. Use the HTTP for all file
|
||||
transfer requests.
|
||||
- Add support for Klippy Host modules to register their own urls.
|
||||
Query_endstops.py has been updated with an example. As a result of this
|
||||
change, the endpoint for endstop query has been changed to
|
||||
`/printer/extras/endstops`.
|
||||
- Add support for "paused", "resumed", and "cleared" pause events.
|
||||
- Add routes for downloading klippy.log, restart, and firmware_restart.
|
||||
- Remove support for trailing slashes in HTTP API routes.
|
||||
- Support "start print after upload" requests
|
||||
- Add support for user configured request timeouts
|
||||
- The test client has been updated to work with the new changes
|
||||
37
docs/developer-certificate-of-origin
Normal file
37
docs/developer-certificate-of-origin
Normal file
@@ -0,0 +1,37 @@
|
||||
Developer Certificate of Origin
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
1 Letterman Drive
|
||||
Suite D4700
|
||||
San Francisco, CA, 94129
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
|
||||
Developer's Certificate of Origin 1.1
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
2
docs/doc-requirements.txt
Normal file
2
docs/doc-requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
mkdocs==1.3.0
|
||||
pymdown-extensions==9.1
|
||||
106
docs/example-home-assistant-extended.yaml
Normal file
106
docs/example-home-assistant-extended.yaml
Normal file
@@ -0,0 +1,106 @@
|
||||
# Example Home Assistant configuration file for a Artillery Sidewinder X1
|
||||
# Credit to GitHub users @Kruppes and @pedrolamas
|
||||
# extended by @tispokes
|
||||
camera:
|
||||
- platform: generic
|
||||
still_image_url: http://192.168.178.66/webcam/?action=snapshot
|
||||
stream_source: http://192.168.178.66/webcam/?action=stream
|
||||
framerate: 10
|
||||
|
||||
sensor:
|
||||
- platform: rest
|
||||
name: SWX1_sensor
|
||||
resource: "http://192.168.178.66:7125/printer/objects/query?heater_bed&extruder&print_stats&toolhead&display_status&virtual_sdcard"
|
||||
json_attributes_path: "$.result.status"
|
||||
json_attributes:
|
||||
- heater_bed
|
||||
- extruder
|
||||
- print_stats
|
||||
- toolhead
|
||||
- display_status
|
||||
- virtual_sdcard
|
||||
value_template: >-
|
||||
{{ "OK" if ("result" in value_json) else "offline" }}
|
||||
# Adding an API key is only necessary while using the [authorization] component
|
||||
# and if Home Assistant is not a trusted client
|
||||
headers:
|
||||
x-api-key: 123456789abcdefghijklmno
|
||||
|
||||
- platform: template
|
||||
sensors:
|
||||
swx1_state:
|
||||
unique_id: sensor.swx1_state
|
||||
friendly_name: "Status"
|
||||
icon_template: mdi:printer-3d
|
||||
value_template: >-
|
||||
{{ states.sensor.swx1_sensor.attributes['print_stats']['state'] if is_state('sensor.swx1_sensor', 'OK') else None }}
|
||||
|
||||
swx1_current_print:
|
||||
unique_id: sensor.swx1_current_print
|
||||
friendly_name: >-
|
||||
{{ "Printed" if states.sensor.swx1_sensor.attributes['display_status']['progress'] == 1 else "Printing..." }}
|
||||
icon_template: mdi:video-3d
|
||||
value_template: >-
|
||||
{{ states.sensor.swx1_sensor.attributes['print_stats']['filename'].split(".")[0] if is_state('sensor.swx1_sensor', 'OK') else None }}
|
||||
|
||||
swx1_current_progress:
|
||||
unique_id: sensor.swx1_current_progress
|
||||
friendly_name: "Progress"
|
||||
unit_of_measurement: '%'
|
||||
icon_template: mdi:file-percent
|
||||
value_template: >-
|
||||
{{ (states.sensor.swx1_sensor.attributes['display_status']['progress'] * 100) | round(1) if is_state('sensor.swx1_sensor', 'OK') else None }}
|
||||
|
||||
swx1_print_time:
|
||||
unique_id: sensor.swx1_print_time
|
||||
friendly_name: "T-elapsed"
|
||||
icon_template: mdi:clock-start
|
||||
value_template: >-
|
||||
{{ states.sensor.swx1_sensor.attributes['print_stats']['print_duration'] | timestamp_custom("%H:%M:%S", 0) if is_state('sensor.swx1_sensor', 'OK') else None }}
|
||||
|
||||
swx1_time_remaining:
|
||||
unique_id: sensor.swx1_time_remaining
|
||||
friendly_name: "T-remaining"
|
||||
icon_template: mdi:clock-end
|
||||
value_template: >-
|
||||
{{ (((states.sensor.swx1_sensor.attributes['print_stats']['print_duration'] / states.sensor.swx1_sensor.attributes['display_status']['progress'] - states.sensor.swx1_sensor.attributes['print_stats']['print_duration']) if states.sensor.swx1_sensor.attributes['display_status']['progress'] > 0 else 0) | timestamp_custom('%H:%M:%S', 0)) if is_state('sensor.swx1_sensor', 'OK') else None }}
|
||||
|
||||
swx1_eta:
|
||||
unique_id: sensor.swx1_eta
|
||||
friendly_name: "T-ETA"
|
||||
icon_template: mdi:clock-outline
|
||||
value_template: >-
|
||||
{{ (as_timestamp(now()) + 2 * 60 * 60 + ((states.sensor.swx1_sensor.attributes['print_stats']['print_duration'] / states.sensor.swx1_sensor.attributes['display_status']['progress'] - states.sensor.swx1_sensor.attributes['print_stats']['print_duration']) if states.sensor.swx1_sensor.attributes['display_status']['progress'] > 0 else 0)) | timestamp_custom("%H:%M:%S", 0) if is_state('sensor.swx1_sensor', 'OK') else None }}
|
||||
|
||||
swx1_nozzletemp:
|
||||
unique_id: sensor.swx1_nozzletemp
|
||||
friendly_name: >-
|
||||
Nozzle
|
||||
{{ ["(shall ", (states.sensor.swx1_sensor.attributes['extruder']['target'] | float | round(1)), "°C)"] | join if states.sensor.swx1_sensor.attributes['display_status']['progress'] < 1 }}
|
||||
icon_template: >-
|
||||
{{ "mdi:printer-3d-nozzle-heat" if states.sensor.swx1_sensor.attributes['extruder']['target'] > 0 else "mdi:printer-3d-nozzle-heat-outline" }}
|
||||
value_template: >-
|
||||
{{ states.sensor.swx1_sensor.attributes['extruder']['temperature'] | float | round(1) if is_state('sensor.swx1_sensor', 'OK') else None }}
|
||||
|
||||
swx1_bedtemp:
|
||||
unique_id: sensor.swx1_bedtemp
|
||||
friendly_name: >-
|
||||
Bed
|
||||
{{ ["(shall ", (states.sensor.swx1_sensor.attributes['heater_bed']['target'] | float | round(1)), "°C)"] | join if states.sensor.swx1_sensor.attributes['display_status']['progress'] < 1 }}
|
||||
icon_template: >-
|
||||
{{ "mdi:radiator" if states.sensor.swx1_sensor.attributes['extruder']['target'] > 0 else "mdi:radiator-off" }}
|
||||
value_template: >-
|
||||
{{ states.sensor.swx1_sensor.attributes['heater_bed']['temperature'] | float | round(1) if is_state('sensor.swx1_sensor', 'OK') else None }}
|
||||
# The following will allow you to control the power of devices configured in the "[power]" sections of moonraker
|
||||
# Make sure to change the `Printer` name below to the device name on your configuration
|
||||
#
|
||||
switch:
|
||||
- platform: rest
|
||||
name: SWX1_power
|
||||
resource: "http://192.168.178.66:7125/machine/device_power/device?device=SWX1"
|
||||
body_on: '{"action": "on"}'
|
||||
body_off: '{"action": "off"}'
|
||||
headers:
|
||||
Content-Type: 'application/json'
|
||||
is_on_template: >-
|
||||
{{ 'result' in value_json and (value_json.result.values() | list | first == "on") }}
|
||||
111
docs/example-home-assistant.yaml
Normal file
111
docs/example-home-assistant.yaml
Normal file
@@ -0,0 +1,111 @@
|
||||
# Example Home Assistant configuration file for a Voron V0.
|
||||
# Credit to GitHub users @Kruppes and @pedrolamas
|
||||
#
|
||||
sensor:
|
||||
- platform: rest
|
||||
name: Voron_V0_sensor
|
||||
resource: "http://192.168.178.56:7125/printer/objects/query?heater_bed&extruder&print_stats&toolhead&display_status&virtual_sdcard"
|
||||
json_attributes_path: "$.result.status"
|
||||
json_attributes:
|
||||
- heater_bed
|
||||
- extruder
|
||||
- print_stats
|
||||
- toolhead
|
||||
- display_status
|
||||
- virtual_sdcard
|
||||
value_template: >-
|
||||
{{ 'OK' if ('result' in value_json) else None }}
|
||||
# Adding an API key is only necessary while using the [authorization] component
|
||||
# and if Home Assistant is not a trusted client
|
||||
headers:
|
||||
x-api-key: 123456789abcdefghijklmno
|
||||
|
||||
- platform: template
|
||||
sensors:
|
||||
|
||||
vzero_hotend_target:
|
||||
friendly_name: 'V0.126 Hotend Target'
|
||||
device_class: temperature
|
||||
unit_of_measurement: '°C'
|
||||
value_template: >-
|
||||
{{ states.sensor.voron_v0_sensor.attributes['extruder']['target'] | float | round(1) if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_hotend_actual:
|
||||
device_class: temperature
|
||||
unit_of_measurement: '°C'
|
||||
value_template: >-
|
||||
{{ states.sensor.voron_v0_sensor.attributes['extruder']['temperature'] | float | round(1) if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_bed_target:
|
||||
device_class: temperature
|
||||
unit_of_measurement: '°C'
|
||||
value_template: >-
|
||||
{{ states.sensor.voron_v0_sensor.attributes['heater_bed']['target'] | float | round(1) if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_bed_actual:
|
||||
device_class: temperature
|
||||
unit_of_measurement: '°C'
|
||||
value_template: >-
|
||||
{{ states.sensor.voron_v0_sensor.attributes['heater_bed']['temperature'] | float | round(1) if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_state:
|
||||
icon_template: mdi:printer-3d
|
||||
value_template: >-
|
||||
{{ states.sensor.voron_v0_sensor.attributes['print_stats']['state'] if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_current_print:
|
||||
value_template: >-
|
||||
{{ states.sensor.voron_v0_sensor.attributes['print_stats']['filename'] if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_current_progress:
|
||||
unit_of_measurement: '%'
|
||||
icon_template: mdi:file-percent
|
||||
value_template: >-
|
||||
{{ (states.sensor.voron_v0_sensor.attributes['display_status']['progress'] * 100) | round(1) if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_print_time:
|
||||
icon_template: mdi:clock-start
|
||||
value_template: >-
|
||||
{{ states.sensor.voron_v0_sensor.attributes['print_stats']['print_duration'] | timestamp_custom("%H:%M:%S", 0) if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_time_remaining:
|
||||
icon_template: mdi:clock-end
|
||||
value_template: >-
|
||||
{{ (((states.sensor.voron_v0_sensor.attributes['print_stats']['print_duration'] / states.sensor.voron_v0_sensor.attributes['display_status']['progress'] - states.sensor.voron_v0_sensor.attributes['print_stats']['print_duration']) if states.sensor.voron_v0_sensor.attributes['display_status']['progress'] > 0 else 0) | timestamp_custom('%H:%M:%S', 0)) if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_eta:
|
||||
icon_template: mdi:clock-outline
|
||||
value_template: >-
|
||||
{{ (as_timestamp(now()) + 2 * 60 * 60 + ((states.sensor.voron_v0_sensor.attributes['print_stats']['print_duration'] / states.sensor.voron_v0_sensor.attributes['display_status']['progress'] - states.sensor.voron_v0_sensor.attributes['print_stats']['print_duration']) if states.sensor.voron_v0_sensor.attributes['display_status']['progress'] > 0 else 0)) | timestamp_custom("%H:%M:%S", 0) if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_nozzletemp:
|
||||
icon_template: mdi:thermometer
|
||||
value_template: >-
|
||||
{{ [(states.sensor.voron_v0_sensor.attributes['extruder']['temperature'] | float | round(1) | string), " / ", (states.sensor.voron_v0_sensor.attributes['extruder']['target'] | float | round(1) | string)] | join if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
vzero_bedtemp:
|
||||
icon_template: mdi:thermometer
|
||||
value_template: >-
|
||||
{{ [(states.sensor.voron_v0_sensor.attributes['heater_bed']['temperature'] | float | round(1) | string), " / ", (states.sensor.voron_v0_sensor.attributes['heater_bed']['target'] | float | round(1) | string)] | join if is_state('sensor.voron_v0_sensor', 'OK') else None }}
|
||||
|
||||
# The following will allow you to control the power of devices configured in the "[power]" sections of moonraker
|
||||
# Make sure to change the `Printer` name below to the device name on your configuration
|
||||
#
|
||||
switch:
|
||||
- platform: rest
|
||||
name: Voron_V0_power
|
||||
resource: "http://192.168.178.56:7125/machine/device_power/device?device=Printer"
|
||||
body_on: '{"action": "on"}'
|
||||
body_off: '{"action": "off"}'
|
||||
headers:
|
||||
Content-Type: 'application/json'
|
||||
is_on_template: >-
|
||||
{{ 'result' in value_json and (value_json.result.values() | list | first == "on") }}
|
||||
|
||||
# MJPEG camera can be exposed to HA
|
||||
#
|
||||
camera:
|
||||
- platform: mjpeg
|
||||
name: Voron_V0_camera
|
||||
still_image_url: http://192.168.178.56/webcam/?action=snapshot
|
||||
mjpeg_url: http://192.168.178.56/webcam/?action=stream
|
||||
21
docs/index.md
Normal file
21
docs/index.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Welcome to Moonraker Documentation
|
||||
|
||||
Moonraker is a Python 3 based web server that exposes APIs with which
|
||||
client applications may use to interact with the 3D printing firmware
|
||||
[Klipper](https://github.com/KevinOConnor/klipper). Communcation between
|
||||
the Klippy host and Moonraker is done over a Unix Domain Socket. Tornado
|
||||
is used to provide Moonraker's server functionality.
|
||||
|
||||
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)
|
||||
documentation.
|
||||
|
||||
Backend developers should refer to the
|
||||
[contibuting](contributing.md) section for basic contribution
|
||||
guidelines prior to creating a pull request. The
|
||||
[components](components.md) document provides a brief overview
|
||||
of how to create a component and interact with Moonraker's
|
||||
primary internal APIs.
|
||||
342
docs/installation.md
Normal file
342
docs/installation.md
Normal file
@@ -0,0 +1,342 @@
|
||||
## Installation
|
||||
|
||||
This document provides a guide on how to install Moonraker on a Raspberry
|
||||
Pi running Raspian/Rasperry Pi OS. Other SBCs and/or linux distributions
|
||||
may work, however 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
|
||||
|
||||
Klipper should be installed prior to installing Moonraker. Please see
|
||||
[Klipper's Documention](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
|
||||
|
||||
Moonraker depends on the following Klippy extras for full functionality:
|
||||
|
||||
- `[virtual_sdcard]`
|
||||
- `[pause_resume]`
|
||||
- `[display_status]`
|
||||
|
||||
If you have a `[filament_switch_sensor]` configured then `[pause_resume]` will
|
||||
automatically be loaded. Likewise, if you have a `[display]` configured then
|
||||
`[display_status]` will be automatically loaded. If your configuration is
|
||||
missing one or both, you can simply add the bare sections to `printer.cfg`:
|
||||
```ini
|
||||
[pause_resume]
|
||||
|
||||
[display_status]
|
||||
|
||||
[virtual_sdcard]
|
||||
path: ~/gcode_files
|
||||
```
|
||||
|
||||
### Enabling the Unix Socket
|
||||
|
||||
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
|
||||
editor of choice, for example:
|
||||
```
|
||||
sudo nano /etc/default/klipper
|
||||
```
|
||||
You should see a file that looks something like the following:
|
||||
```
|
||||
# Configuration for /etc/init.d/klipper
|
||||
|
||||
KLIPPY_USER=pi
|
||||
|
||||
KLIPPY_EXEC=/home/pi/klippy-env/bin/python
|
||||
|
||||
KLIPPY_ARGS="/home/pi/klipper/klippy/klippy.py /home/pi/printer.cfg -l /tmp/klippy.log"
|
||||
```
|
||||
|
||||
Add `-a /tmp/klippy_uds` to KLIPPY_ARGS:
|
||||
```
|
||||
# Configuration for /etc/init.d/klipper
|
||||
|
||||
KLIPPY_USER=pi
|
||||
|
||||
KLIPPY_EXEC=/home/pi/klippy-env/bin/python
|
||||
|
||||
KLIPPY_ARGS="/home/pi/klipper/klippy/klippy.py /home/pi/printer.cfg -l /tmp/klippy.log -a /tmp/klippy_uds"
|
||||
```
|
||||
|
||||
!!! note
|
||||
Your installation of Klipper may use systemd instead of
|
||||
the default LSB script. In this case, you need to modify the
|
||||
klipper.service file.
|
||||
|
||||
You may also want to take this opportunity to change the location of
|
||||
printer.cfg to match Moonraker's `config_path` option (see the
|
||||
[configuration document](configuration.md#primary-configuration)
|
||||
for more information on the config_path). For example, if the `config_path`
|
||||
is set to `~/printer_config`, your klipper defaults file might look
|
||||
like the following:
|
||||
```
|
||||
# Configuration for /etc/init.d/klipper
|
||||
|
||||
KLIPPY_USER=pi
|
||||
|
||||
KLIPPY_EXEC=/home/pi/klippy-env/bin/python
|
||||
|
||||
KLIPPY_ARGS="/home/pi/klipper/klippy/klippy.py /home/pi/printer_config/printer.cfg -l /tmp/klippy.log -a /tmp/klippy_uds"
|
||||
```
|
||||
|
||||
If necessary, create the config directory and move printer.cfg to it:
|
||||
```
|
||||
cd ~
|
||||
mkdir printer_config
|
||||
mv printer.cfg printer_config
|
||||
```
|
||||
|
||||
### Installing Moonraker
|
||||
|
||||
Begin by cloning the git respository:
|
||||
|
||||
```
|
||||
cd ~
|
||||
git clone https://github.com/Arksine/moonraker.git
|
||||
```
|
||||
|
||||
Now is a good time to create [moonraker.conf](configuration.md). If you are
|
||||
using the `config_path`, create it in the specified directory otherwise create
|
||||
it in the HOME directory. The [sample moonraker.conf](./moonraker.conf) in
|
||||
the `docs` directory may be used as a starting point.
|
||||
|
||||
For a default installation run the following commands:
|
||||
```
|
||||
cd ~/moonraker/scripts
|
||||
./install-moonraker.sh
|
||||
```
|
||||
|
||||
Or to install with `moonraker.conf` in the `config_path`:
|
||||
```
|
||||
cd ~/moonraker/scripts
|
||||
./install-moonraker.sh -f -c /home/pi/printer_config/moonraker.conf
|
||||
```
|
||||
|
||||
The install script has a few command line options that may be useful,
|
||||
particularly for those upgrading:
|
||||
|
||||
- `-r`:
|
||||
Rebuilds the virtual environment for existing installations.
|
||||
Sometimes this is necessary when a dependency has been added.
|
||||
- `-f`:
|
||||
Force an overwrite of Moonraker's systemd script. By default the
|
||||
the systemd script will not be modified if it exists.
|
||||
- `-c /home/pi/moonraker.conf`:
|
||||
Specifies the path to Moonraker's config file. The default location
|
||||
is `/home/<user>/moonraker.conf`. When using this option to modify
|
||||
an existing installation it is necessary to add `-f` as well.
|
||||
- `-z`:
|
||||
Disables `systemctl` commands during install (ie: daemon-reload, restart).
|
||||
This is useful for installations that occur outside of a standard environment
|
||||
where systemd is not running.
|
||||
|
||||
Additionally, installation may be customized with the following environment
|
||||
variables:
|
||||
|
||||
- `MOONRAKER_VENV`
|
||||
- `MOONRAKER_REBUILD_ENV`
|
||||
- `MOONRAKER_FORCE_DEFAULTS`
|
||||
- `MOONRAKER_DISABLE_SYSTEMCTL`
|
||||
- `MOONRAKER_CONFIG_PATH`
|
||||
- `MOONRAKER_LOG_PATH`
|
||||
|
||||
When the script completes it should start both Moonraker and Klipper. In
|
||||
`/tmp/klippy.log` you should find the following entry:
|
||||
|
||||
`webhooks client <uid>: Client info {'program': 'Moonraker', 'version': '<version>'}`
|
||||
|
||||
Now you may install a client, such as
|
||||
[Mainsail](https://github.com/mainsail-crew/mainsail) or
|
||||
[Fluidd](https://github.com/cadriel/fluidd).
|
||||
|
||||
!!! Note
|
||||
Moonraker's install script no longer includes the nginx dependency.
|
||||
If you want to install one of the above clients on the local machine,
|
||||
you may want to first install nginx (`sudo apt install nginx` on
|
||||
debian/ubuntu distros).
|
||||
|
||||
|
||||
### Command line usage
|
||||
|
||||
This section is intended for users that need to write their own
|
||||
installation script. Detailed are the command line arguments
|
||||
available to Moonraker:
|
||||
```
|
||||
usage: moonraker.py [-h] [-c <configfile>] [-l <logfile>] [-n]
|
||||
|
||||
Moonraker - Klipper API Server
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-c <configfile>, --configfile <configfile>
|
||||
Location of moonraker configuration file
|
||||
-l <logfile>, --logfile <logfile>
|
||||
log file name and location
|
||||
-n, --nologfile disable logging to a file
|
||||
```
|
||||
|
||||
The default configuration is:
|
||||
- config file path- `~/moonraker.conf`
|
||||
- log file path - `/tmp/moonraker.log`
|
||||
- logging to a file is enabled
|
||||
|
||||
If one needs to start moonraker without generating a log file, the
|
||||
`-n` option may be used, for example:
|
||||
```
|
||||
~/moonraker-env/bin/python ~/moonraker/moonraker/moonraker.py -n -c /path/to/moonraker.conf
|
||||
```
|
||||
In general it is not recommended to install moonraker with this option.
|
||||
While moonraker will still log to stdout, all requests for support must
|
||||
be accompanied by moonraker.log.
|
||||
|
||||
These options may be changed by editing
|
||||
`/etc/systemd/system/moonraker.service`. The `install-moonraker.sh` script
|
||||
may also be used to modify the config file location.
|
||||
|
||||
### PolicyKit Permissions
|
||||
|
||||
Some of Moonraker's components require elevated privileges to perform actions.
|
||||
Previously these actions could only be run via commandline programs launched
|
||||
with the `sudo` prefix. This has significant downsides:
|
||||
|
||||
- The user must be granted `NOPASSWD` sudo access. Raspberry Pi OS
|
||||
grants the Pi user this access by default, however most other distros
|
||||
require that this be enabled through editing `visudo` or adding files
|
||||
in `/etc/sudoers.d/`.
|
||||
- Some linux distributions require additional steps such as those taken
|
||||
in `sudo_fix.sh`.
|
||||
- Running CLI programs is relatively expensive. This isn't an issue for
|
||||
programs that are run once at startup, but is undesirable if Moonraker
|
||||
wants to poll information about the system.
|
||||
|
||||
Moonraker now supports communicating with system services via D-Bus.
|
||||
Operations that require elevated privileges are authrorized through
|
||||
PolicyKit. On startup Moonraker will check for the necessary privileges
|
||||
and warn users if they are not available. Warnings are presented in
|
||||
`moonraker.log` and directly to the user through some clients.
|
||||
|
||||
To resolve these warnings users have two options:
|
||||
|
||||
1) Install the PolicyKit permissions with the `set-policykit-rules.sh` script,
|
||||
for example:
|
||||
|
||||
```shell
|
||||
cd ~/moonraker/scripts
|
||||
./set-policykit-rules.sh
|
||||
sudo service moonraker restart
|
||||
```
|
||||
|
||||
!!! tip
|
||||
If you still get warnings after installing the PolKit rules, run the
|
||||
install script with no options to make sure that all new dependencies
|
||||
are installed.
|
||||
|
||||
```shell
|
||||
cd ~/moonraker/scripts
|
||||
./install-moonraker.sh
|
||||
```
|
||||
|
||||
2) Configure Moonraker to use the legacy backend implementations for
|
||||
the `machine` and/or `update_manager` components, ie:
|
||||
|
||||
```ini
|
||||
# Use the systemd CLI provider rather than the DBus Provider
|
||||
[machine]
|
||||
provider: systemd_cli
|
||||
|
||||
# Edit your existing [update_manager] section to disable
|
||||
# PackageKit. This will fallback to the APT CLI Package Update
|
||||
# implementation.
|
||||
[update_manager]
|
||||
#..other update manager options
|
||||
enable_packagekit: False
|
||||
|
||||
# Alternatively system updates can be disabled
|
||||
[update_manager]
|
||||
#..other update manager options
|
||||
enable_system_updates: False
|
||||
```
|
||||
|
||||
!!! Note
|
||||
Previously installed PolicyKit rules can be removed by running
|
||||
`set-policykit-rules.sh -c`
|
||||
|
||||
### 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
|
||||
generate an API Key. There are two ways in which the key may be retrieved
|
||||
by the user:
|
||||
|
||||
Retrieve the API Key via the command line (SSH):
|
||||
```
|
||||
cd ~/moonraker/scripts
|
||||
./fetch-apikey.sh
|
||||
```
|
||||
|
||||
Retrieve the API Key via the browser from a trusted client:
|
||||
|
||||
- Navigate to `http://{moonraker-host}/access/api_key`, where
|
||||
`{moonraker-host}` is the host name or ip address of the desired
|
||||
moonraker instance.
|
||||
- The result will appear in the browser window in JSON format. Copy
|
||||
The API Key without the quotes.
|
||||
|
||||
{"result": "8ce6ae5d354a4365812b83140ed62e4b"}
|
||||
|
||||
### 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
|
||||
file system corruption in the event of a loss of power, bad sdcard, etc.
|
||||
If this occurs, updates using the `[update_manager]` may fail. In most
|
||||
cases Moonraker provides an automated method to recover, however in some
|
||||
edge cases this is not possible and the user will need to do so manually.
|
||||
This requires that you `ssh` into your machine. The example below assumes
|
||||
the following:
|
||||
|
||||
- You are using a Raspberry Pi
|
||||
- Moonraker and Klipper are installed at the default locations in the `home`
|
||||
directory
|
||||
- Both Moonraker and Klipper have been corrupted and need to be restored
|
||||
|
||||
The following commands may be used to restore Moonraker:
|
||||
|
||||
```shell
|
||||
cd ~
|
||||
rm -rf moonraker
|
||||
git clone https://github.com/Arksine/moonraker.git
|
||||
cd moonraker/scripts
|
||||
./install-moonraker.sh
|
||||
./set-policykit-rules.sh
|
||||
sudo systemctl restart moonraker
|
||||
```
|
||||
|
||||
And for Klipper:
|
||||
|
||||
```shell
|
||||
cd ~
|
||||
rm -rf klipper
|
||||
git clone https://github.com/Klipper3d/klipper.git
|
||||
sudo systemctl restart klipper
|
||||
```
|
||||
|
||||
### Additional Notes
|
||||
|
||||
- Make sure that Moonraker and Klipper both have read and write access to the
|
||||
directory set in the `path` option for the `[virtual_sdcard]` in
|
||||
`printer.cfg`.
|
||||
- Upon first starting Moonraker is not aware of the gcode file path, thus
|
||||
it cannot serve gcode files, add directories, etc. After Klippy enters
|
||||
the "ready" state it sends Moonraker the gcode file path.
|
||||
Once Moonraker receives the path it will retain it regardless of Klippy's
|
||||
state, and update it if the path is changed in printer.cfg.
|
||||
|
||||
Please see [configuration.md](configuration.md) for details on how to
|
||||
configure moonraker.conf.
|
||||
30
docs/moonraker.conf
Normal file
30
docs/moonraker.conf
Normal file
@@ -0,0 +1,30 @@
|
||||
# Sample Moonraker Configuration File
|
||||
#
|
||||
# !!! Moonraker does not load this file. See configuration.md !!!
|
||||
# !!! for details on path to Moonraker's configuration. !!!
|
||||
#
|
||||
|
||||
[server]
|
||||
# Bind server defaults of 0.0.0.0, port 7125
|
||||
enable_debug_logging: True
|
||||
config_path: ~/printer_config
|
||||
|
||||
[authorization]
|
||||
enabled: True
|
||||
trusted_clients:
|
||||
# Enter your client IP here or range here
|
||||
192.168.1.0/24
|
||||
cors_domains:
|
||||
# Allow CORS requests for Fluidd
|
||||
http://app.fluidd.xyz
|
||||
|
||||
# Enable OctoPrint compatibility for Slicer uploads
|
||||
# Supports Cura, Slic3r, and Slic3r dervivatives
|
||||
# (PrusaSlicer, SuperSlicer)
|
||||
[octoprint_compat]
|
||||
# Default webcam config values:
|
||||
# flip_h = false
|
||||
# flip_v = false
|
||||
# rotate_90 = false
|
||||
# stream_url = /webcam/?action=stream
|
||||
# webcam_enabled = true
|
||||
385
docs/printer_objects.md
Normal file
385
docs/printer_objects.md
Normal file
@@ -0,0 +1,385 @@
|
||||
#
|
||||
As mentioned in the API documentation, it is possible to
|
||||
[query](web_api.md#query-printer-object-status) or
|
||||
[subscribe](web_api.md#subscribe-to-printer-object-status)
|
||||
to "Klipper Printer Objects." There are numerous printer objects in
|
||||
Klipper, many of which are optional and only report status if they are
|
||||
enabled by Klipper's configuration. Client's may retrieve a list of
|
||||
available printer objects via the
|
||||
[list objects endpoint](web_api.md#list-available-printer-objects). This
|
||||
should be done after Klipper reports its state as "ready".
|
||||
|
||||
This section will provide an overview of the most useful printer objects.
|
||||
If a developer is interested in retrieving state for an object not listed here,
|
||||
look in Klipper's source code for module you wish to query. If the module
|
||||
contains a "get_status()" method, its return value will contain a dictionary
|
||||
that reports state which can be queried.
|
||||
|
||||
## webhooks
|
||||
```json
|
||||
{
|
||||
"state": "startup",
|
||||
"state_message": "message"
|
||||
}
|
||||
```
|
||||
The `webhooks` object contains the current printer state and the current
|
||||
state message. These fields match those returned via the `/printer/info`
|
||||
endpoint. This is provided as a convience, clients may subscribe to `webhooks`
|
||||
so they are asynchonously notified of a change to printer state. The `state`
|
||||
may be `startup`, `ready`, `shutdown`, or `error`. The `state_message`
|
||||
contains a message specific to the current printers state.
|
||||
|
||||
## gcode_move
|
||||
```json
|
||||
{
|
||||
"speed_factor": 1.0,
|
||||
"speed": 100.0,
|
||||
"extrude_factor": 1.0,
|
||||
"absolute_coordinates": true,
|
||||
"absolute_extrude": false,
|
||||
"homing_origin": [0.0, 0.0, 0.0, 0.0],
|
||||
"position": [0.0, 0.0, 0.0, 0.0],
|
||||
"gcode_position": [0.0, 0.0, 0.0, 0.0]
|
||||
}
|
||||
```
|
||||
The `gcode_move` object reports the current gcode state:
|
||||
|
||||
- `speed_factor`: AKA "feedrate", this is the current speed multiplier
|
||||
- `speed`: The current gcode speed in mm/s.
|
||||
- `extrude_factor`: AKA "extrusion multiplier".
|
||||
- `absolute_coorinates`: true if the machine axes are moved using
|
||||
absolute coordinates, false if using relative coordinates.
|
||||
- `absolute_extrude`: true if the extruder is moved using absolute
|
||||
coordinates, false if using relative coordinates.
|
||||
- `homing_origin`: [X, Y, Z, E] - returns the "gcode offset" applied to
|
||||
each axis. For example, the "Z" axis can be checked to determine how
|
||||
much offset has been applied via "babystepping".
|
||||
- `position`: [X, Y, Z, E] - The internal gcode position, including
|
||||
any offsets (gcode_offset, G92, etc) added to an axis.
|
||||
- `gcode_position`: [X, Y, Z, E] - The current gcode position
|
||||
sans any offsets applied. For X, Y, and Z, this should match
|
||||
the most recent "G1" or "G0" processed assuming the machine is
|
||||
using absolute coordinates.
|
||||
|
||||
!!! Note
|
||||
The printer's actual movement will lag behind the reported positional
|
||||
coordinates due to lookahead.
|
||||
|
||||
## toolhead
|
||||
```json
|
||||
{
|
||||
"homed_axes": "xyz",
|
||||
"print_time": 0.0,
|
||||
"estimated_print_time": 0.0,
|
||||
"extruder": "extruder",
|
||||
"position": [0.0, 0.0, 0.0, 0.0],
|
||||
"max_velocity": 500.0,
|
||||
"max_accel": 3000.0,
|
||||
"max_accel_to_decel": 1500.0,
|
||||
"square_corner_velocity": 5.0
|
||||
}
|
||||
```
|
||||
The `toolhead` object reports state of the current tool:
|
||||
|
||||
- `homed_axes`: a string containing the axes that are homed. If no axes
|
||||
are homed, returns a null string.
|
||||
- `print_time`: internal value, not generally useful for clients
|
||||
- `estimated_print_time`: internal value, not generally useful for clients.
|
||||
- `extruder`: the name of the currently selected extruder, ie "extruder"
|
||||
or "extruder1".
|
||||
- `position`: [X, Y, Z, E] - This the the last position toward which the tool
|
||||
was commanded to move. It includes any offsets applied via gcode as well
|
||||
as any transforms made by modules such as "bed_mesh", "bed_tilt", or
|
||||
"skew_correction".
|
||||
- `max_velocity`: The currently set maximum velocity of the tool (mm/s^2).
|
||||
- `max_accel`: The currently set maximum acceleration of the tool (mm/s^2).
|
||||
- `max_accel_to_decel`: The currently set maximum accel to decel of the tool.
|
||||
This value is the maximum rate at which the tool can transition from
|
||||
acceleration to deceleration (mm/s^2).
|
||||
- `square_corner_velocity`: The currently set square corner velocity. This
|
||||
is the maximum velocity at which the tool may travel a 90 degree corner.
|
||||
|
||||
!!! tip
|
||||
`max_velocity`, `max_accel`, `max_accel_to_decel`, and
|
||||
`square_corner_velocity` can be changed by the `SET_VELOCITY_LIMIT` gcode.
|
||||
`M204` can also change `max_accel`.
|
||||
|
||||
## configfile
|
||||
```json
|
||||
{
|
||||
"config": {},
|
||||
"settings": {},
|
||||
"save_config_pending": false
|
||||
}
|
||||
```
|
||||
The `configfile` object reports printer configuration state:
|
||||
|
||||
- `config`: This is an object containing the configuration as read from
|
||||
printer.cfg. Each config section will be an object containing the
|
||||
configured options. Values will ALWAYS be reported as
|
||||
strings. Note that default values are not reported, only options
|
||||
configured in printer.cfg are present.
|
||||
- `settings`: Similar to `config`, however this object includes default
|
||||
values that may not have been included in `printer.cfg`. It is possible
|
||||
for a value to be a string, integer, boolean, or float.
|
||||
- `save_config_pending`: True if the printer has taken an action which
|
||||
has updated the internal configuration (ie: PID calibration, probe
|
||||
calibration, bed mesh calibration). This allows clients to present
|
||||
the user with the option to execute a SAVE_CONFIG gcode which will
|
||||
save the configuration to printer.cfg and restart the Klippy Host.
|
||||
|
||||
## extruder
|
||||
*Enabled when `[extruder]` is included in printer.cfg*
|
||||
!!! note
|
||||
If multiple extruders are configured, extruder 0 is available as
|
||||
`extruder`, extruder 1 as `extruder1` and so on.
|
||||
```json
|
||||
{
|
||||
"temperature": 0.0,
|
||||
"target": 0.0,
|
||||
"power": 0.0,
|
||||
"pressure_advance": 0.0,
|
||||
"smooth_time": 0.0
|
||||
}
|
||||
```
|
||||
The `extruder` object reports state of an extruder:
|
||||
|
||||
- `temperature`: The extruder's current temperature (in C).
|
||||
- `target`: The extruder's target temperature (in C).
|
||||
- `power`: The current pwm value applied to the heater. This value is
|
||||
expressed as a percentage from 0.0 to 1.0.
|
||||
- `pressure_advance`: The extruder's current pressure advance value.
|
||||
- `smooth_time`: The currently set time range to use when calculating the
|
||||
average extruder velocity for pressure advance.
|
||||
|
||||
## heater_bed
|
||||
*Enabled when `[heater_bed]` is included in printer.cfg*
|
||||
```json
|
||||
{
|
||||
"temperature": 0.0,
|
||||
"target": 0.0,
|
||||
"power": 0.0,
|
||||
}
|
||||
```
|
||||
The `heater_bed` object reports state of the heated bed:
|
||||
|
||||
- `temperature`: The bed's current temperature
|
||||
- `target`: The bed's target temperature
|
||||
- `power`: The current pwm value applied to the heater. This value is
|
||||
expressed as a percentage from 0.0 to 1.0.
|
||||
|
||||
## fan
|
||||
*Enabled when `[fan]` is included in printer.cfg*
|
||||
```json
|
||||
{
|
||||
"speed": 0.0,
|
||||
"rpm": 4000
|
||||
}
|
||||
```
|
||||
The `fan` object returns state of the part cooling fan:
|
||||
|
||||
- `speed`: The current fan speed. This is reported as a
|
||||
percentage of maximum speed in the range of 0.0 - 1.0.
|
||||
- `rpm`: The fan's revolutions per minute if the tachometer
|
||||
pin has been configured. Will report `null` if no tach
|
||||
has been configured.
|
||||
|
||||
## idle_timeout
|
||||
```json
|
||||
{
|
||||
"state": "Idle",
|
||||
"printing_time": 0.0
|
||||
}
|
||||
```
|
||||
|
||||
The `idle_timeout` object reports the idle state of the printer:
|
||||
|
||||
- `state`: Can be `Idle`, `Ready`, or `Printing`. The printer will
|
||||
transition to the `Printing` state whenever a gcode is issued that
|
||||
commands the tool, this includes manual commands. Thus this should
|
||||
not be used to determine if a gcode file print is in progress. It can
|
||||
however be used to determine if the printer is busy.
|
||||
- `printing_time`: The amount of time the printer has been in the
|
||||
`Printing` state. This is reset to 0 whenever the printer transitions
|
||||
from `Printing` to `Ready`.
|
||||
|
||||
## virtual_sdcard
|
||||
*Enabled when `[virtual_sdcard]` is included in printer.cfg*
|
||||
```json
|
||||
{
|
||||
"progress": 0.0,
|
||||
"is_active": false,
|
||||
"file_position": 0
|
||||
}
|
||||
```
|
||||
The `virtual_sdcard` object reports the state of the virtual sdcard:
|
||||
|
||||
- `progress`: The print progress reported as a percentage of the file
|
||||
read, in the range of 0.0 - 1.0.
|
||||
- `is_active`: Returns true if the virtual sdcard is currently processing
|
||||
a file. Note that this will return false if a virtual sdcard print is
|
||||
paused.
|
||||
- `file_position`: The current file position in bytes. This will always
|
||||
be an integer value
|
||||
|
||||
!!! Note
|
||||
`progress` and `file_position` will persist after a print has
|
||||
paused, completed, or errored. They are cleared when the user issues
|
||||
a SDCARD_RESET_FILE gcode or when a new print has started.
|
||||
|
||||
## print_stats
|
||||
*Enabled when `[virtual_sdcard]` is included in printer.cfg*
|
||||
```json
|
||||
{
|
||||
"filename": "",
|
||||
"total_duration": 0.0,
|
||||
"print_duration": 0.0,
|
||||
"filament_used": 0.0,
|
||||
"state": "standby",
|
||||
"message": ""
|
||||
}
|
||||
```
|
||||
The `print_stats` object reports `virtual_sdcard` print state:
|
||||
|
||||
- `filename`: The name of the current file loaded. This will be a null
|
||||
string if no file is loaded. Note that name is a path relative to the
|
||||
gcode folder, thus if the file is located in a subdirectory it would
|
||||
be reported as "my_sub_dir/myprint.gcode".
|
||||
- `total_duration`: The total time (in seconds) elapsed since a print
|
||||
has started. This includes time spent paused.
|
||||
- `print_duration`: The total time spent printing (in seconds). This is
|
||||
equivalent to `total_duration` - time paused.
|
||||
- `filament_used`: The amount of filament used during the current print
|
||||
(in mm). Any extrusion during a pause is excluded.
|
||||
- `state`: Current print state. Can be one of the following values:
|
||||
- `"standby"`
|
||||
- `"printing"`
|
||||
- `"paused"`
|
||||
- `"complete"`
|
||||
- `"cancelled"`
|
||||
- `"error"` - Note that if an error is detected the print will abort
|
||||
- `message`: If an error is detected, this field contains the error
|
||||
message generated. Otherwise it will be a null string.
|
||||
|
||||
!!! Note
|
||||
After a print has started all of the values above will persist until
|
||||
the user issues a SDCARD_RESET_FILE gcode or when a new print has started.
|
||||
|
||||
## display_status
|
||||
*Enabled when `[display]` or `[display_status]` is included in printer.cfg*
|
||||
```json
|
||||
{
|
||||
"message": "",
|
||||
"progress": 0.0
|
||||
}
|
||||
```
|
||||
The `display_status` object contains state typically used to update displays:
|
||||
|
||||
- `message`: The message set by a M117 gcode. If no message is set this will
|
||||
be a null string.
|
||||
- `progress`: The percentage of print progress, as reported by M73. This
|
||||
will be in the range of 0.0 - 1.0. If no M73 has been issued this value
|
||||
will fallback to the eqivalent of `virtual_sdcard.progress`. Note that
|
||||
progress updated via M73 has a timeout. If no M73 is received after 5
|
||||
seconds, `progress` will be set to the fallback value.
|
||||
|
||||
## temperature_sensor sensor_name
|
||||
*Enabled when `[temperature_sensor sensor_name]` is included in printer.cfg.
|
||||
It is possible for multiple temperature sensors to be configured.*
|
||||
```json
|
||||
{
|
||||
"temperature": 0.0,
|
||||
"measured_min_temp": 0.0,
|
||||
"measured_max_temp": 0.0
|
||||
}
|
||||
```
|
||||
A `temperature_sensor` reports the following state:
|
||||
|
||||
- `temperature`: Sensor's current reported temperature
|
||||
- `measured_min_temp`: The mimimum temperature read from the sensor
|
||||
- `measured_max_temp`: The maximum temperature read from the sensor
|
||||
|
||||
## temperature_fan fan_name
|
||||
*Enabled when `[temperature_fan fan_name]` is included in printer.cfg. It is
|
||||
possible for multiple temperature fans to be configured.*
|
||||
```json
|
||||
{
|
||||
"speed": 0.0,
|
||||
"temperature": 0.0,
|
||||
"target": 0.0
|
||||
}
|
||||
```
|
||||
A `temperature_fan` reports the following state:
|
||||
|
||||
- `speed`: Current fan speed as a percentage of maximum speed, reported
|
||||
in the range of 0.0 - 1.0
|
||||
- `temperature`: Currently reported temperature of the sensor associated
|
||||
with the fan
|
||||
- `target`: The current target temperature for the `temperature_fan`.
|
||||
|
||||
## filament_switch_sensor sensor_name
|
||||
*Enabled when `[filament_switch_sensor sensor_name]` is included in
|
||||
printer.cfg. It is possible for multiple filament sensors to be configured.*
|
||||
```json
|
||||
{
|
||||
"filament_detected": false,
|
||||
"enabled": true
|
||||
}
|
||||
```
|
||||
A `filament_switch_sensor` reports the following state:
|
||||
|
||||
- `filament_detected`: Set to true if the switch detects filament, otherwise
|
||||
false
|
||||
- `enabled`: Set to true if the sensor is currently enabled, otherwise false
|
||||
|
||||
## output_pin pin_name
|
||||
*Enabled when `[output_pin pin_name]` is included in printer.cfg.
|
||||
It is possible for multiple output pins to be configured.*
|
||||
```json
|
||||
{
|
||||
"value": 0.0
|
||||
}
|
||||
```
|
||||
An `output_pin` reports the following state:
|
||||
|
||||
- `value`: The currently set value of the pin, in the range of 0.0 - 1.0.
|
||||
A digital pin will always be 0 or 1, whereas a pwm pin may report a value
|
||||
across the entire range.
|
||||
|
||||
## bed_mesh
|
||||
*Enabled when `[bed_mesh]` is included in printer.cfg.*
|
||||
```json
|
||||
{
|
||||
"profile_name": "",
|
||||
"mesh_min": [0.0, 0.0],
|
||||
"mesh_max": [0.0, 0.0],
|
||||
"probed_matrix": [[]],
|
||||
"mesh_matrix": [[]]
|
||||
}
|
||||
```
|
||||
The `bed_mesh` printer object reports the following state:
|
||||
|
||||
- `profile_name`: The name of the currently loaded profile. If no profile is
|
||||
loaded then this will report a null string. If the user is not using
|
||||
bed_mesh profile management then this will report `default` after mesh
|
||||
calibration completes.
|
||||
- `mesh_min`: [X, Y] - The minimum x and y coordinates of the mesh.
|
||||
- `mesh_max`: [X, Y] - The maximum x and y coordinates of the mesh.
|
||||
- `probed_matrix`: A 2 dimensional array representing the matrix of probed
|
||||
values. If the matrix has not been probed the the result is `[[]]`.
|
||||
- `mesh_matrix`: A 2 dimension array representing the interpolated mesh. If
|
||||
no matrix has been generated the result is `[[]]`.
|
||||
|
||||
!!! tip
|
||||
See [web_api.md](web_api.md##bed-mesh-coordinates) for an example
|
||||
of how to use this information to generate (X,Y,Z) coordinates.
|
||||
|
||||
## gcode_macro macro_name
|
||||
*Enabled when `[gcode_macro macro_name]` is included in printer.cfg.
|
||||
It is possible for multiple gcode macros to be configured.*
|
||||
|
||||
Gcode macros will report the state of configured `variables`.
|
||||
While user defined macros likely won't report state that is useful
|
||||
for a client, it is possible for client developers to recommend or
|
||||
request a specific gcode_macro configuration, then have the client
|
||||
take action based on the variables reported by the macro.
|
||||
136
docs/user_changes.md
Normal file
136
docs/user_changes.md
Normal file
@@ -0,0 +1,136 @@
|
||||
##
|
||||
This file will track changes that require user intervention,
|
||||
such as a configuration change or a reinstallation.
|
||||
|
||||
### April 6th 2022
|
||||
- The ability to configure core components in the `[server]`section
|
||||
is now deprecated. When legacy items are detected in `[server]` a
|
||||
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
|
||||
- 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
|
||||
job is queued, not only when its sourced from an upload. The
|
||||
`on_when_upload_queued` option will be treated as an alias to
|
||||
`on_when_job_queued` until its removal.
|
||||
|
||||
### February 16th 2022
|
||||
- Webcam settings can now be defined in the `moonraker.conf` file, under
|
||||
the `[octoprint_compat]` section. The default values are being used as
|
||||
default values.
|
||||
|
||||
Default values:
|
||||
| Setting | Default value |
|
||||
|---------|---------------|
|
||||
| flip_h | False |
|
||||
| flip_v | False |
|
||||
| rotate_90 | False |
|
||||
| stream_url | /webcam/?action=stream |
|
||||
| webcam_enabled | True |
|
||||
|
||||
### January 22th 2022
|
||||
- The `color_order` option in the `[wled]` section has been deprecated.
|
||||
This is configured in wled directly. This is not a breaking change,
|
||||
the setting will simply be ignored not affecting functionality.
|
||||
|
||||
### December 24th 2021
|
||||
- The `password_file` option in the `[mqtt]` section has been deprecated.
|
||||
Use the `password` option instead. This option may be a template, thus
|
||||
can resolve secrets stored in the `[secrets]` module.
|
||||
|
||||
### November 7th 2021
|
||||
- Previously all core components received configuration through
|
||||
the `[server]` config section. As Moonraker's core functionality
|
||||
has expanded this is becoming unsustainable, thus core components
|
||||
should now be configured in their own section. For example, the
|
||||
`config_path` and `log_path` should now be configured in the
|
||||
`[file_manager]` section of `moonraker.conf`. See the
|
||||
[configuration documentation](https://moonraker.readthedocs.io/en/latest/configuration/)
|
||||
for details. This is not a breaking change, core components
|
||||
will still fall back to checking the `[server]` section for
|
||||
configuration.
|
||||
|
||||
### April 19th 2021
|
||||
- The `[authorization]` module is now a component, thus is only
|
||||
loaded if the user has it configured in `moonraker.conf`. This
|
||||
deprecates the previous `enable` option, as it is enabled
|
||||
if configured and disabled otherwise.
|
||||
- The API Key is now stored in the database. This deprecates the
|
||||
`api_key_file` option in the `[authorization]` module. Users can
|
||||
no longer read the contents of the API Key file to retrieve the
|
||||
API Key. Instead, users can run `scripts/fetch-apikey.sh` to
|
||||
print the API Key. Alternative a user can navigate to
|
||||
`http://{moonraker-host}/access/api_key` from a trusted client
|
||||
to retrieve the API Key.
|
||||
|
||||
### March 10th 2021
|
||||
- The `cors_domain` option in the `[authoriztion]` 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
|
||||
this match.
|
||||
|
||||
### March 6th 2021
|
||||
- The `enable_debug_logging` in the `[server]` section now defaults
|
||||
to `False`. This dramatically reduces the amount of logging produced
|
||||
by Moonraker for the typical user.
|
||||
|
||||
### March 4th 2021
|
||||
- To enable OctoPrint compatibility with slicer uploads it is now
|
||||
required to add `[octoprint_compat]` to `moonraker.conf`. After
|
||||
making this change it is necessary to restart the Moonraker service
|
||||
so the module is loaded.
|
||||
|
||||
### December 31st 2020
|
||||
- The file manager no longer restricts the `config_path` to a folder
|
||||
within the HOME directory. The path may not be the system root,
|
||||
however it can reside anywhere else on the file system as long as
|
||||
Moonraker has read and write access to the directory. This applies
|
||||
to gcode path received from Klipper via the `virtual_sdcard` section
|
||||
as well.
|
||||
|
||||
### December 6th 2020
|
||||
- Moonraker is now installed as a systemd service. This allows logging
|
||||
to stdout which can be viewed with the `journalctl -u moonraker` command.
|
||||
This changes requires the user to rerun the install script. If
|
||||
`moonraker.conf` is not located in the home directory, the command
|
||||
will looks something like the following:
|
||||
|
||||
cd ~/moonraker
|
||||
./scripts/install-moonraker.sh -f -c /home/pi/klipper_config/moonraker.conf
|
||||
|
||||
Otherwise you can run the install script with no arguments.
|
||||
|
||||
### November 19th 2020
|
||||
- The install script (`install-moonraker.sh`) now has command-line
|
||||
options:\
|
||||
`-r` Rebuild the python virtual env\
|
||||
`-f` Force an overwrite of `/etc/default/moonraker` during installation\
|
||||
`-c /path/to/moonraker.conf` Allows user to specify the path to
|
||||
moonraker.conf during configuration. Using this in conjunction with `-f`
|
||||
will update the defaults file wih the new path.
|
||||
- New dependencies have been added to Moonraker which require reinstallation.
|
||||
Run the following command to reinstall and rebuild the virtualenv:
|
||||
|
||||
~/moonraker/scripts/install-moonraker.sh -r
|
||||
|
||||
- The power plugin configuration has changed. See the
|
||||
[install guide](installation.md#power-control-plugin) 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
|
||||
may be used to unexport pin 19:
|
||||
|
||||
echo 19 > /sys/class/gpio/unexport
|
||||
|
||||
Alternatively one may reboot the machine after upgrading:
|
||||
|
||||
cd ~/moonraker/
|
||||
git pull
|
||||
~/moonraker/scripts/install-moonraker.sh -r
|
||||
sudo reboot
|
||||
|
||||
Make sure that the power plugin configuration has been updated prior
|
||||
to rebooting the machine.
|
||||
5768
docs/web_api.md
Normal file
5768
docs/web_api.md
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user