diff --git a/README.md b/README.md index ea6fd4f..f7f972d 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,4 @@ Users:\ [user_changes.md](/docs/user_changes.md) - November 19th 2020 Developers:\ -[api_changes.md](/docs/api_changes.md) - November 23rd 2020 +[api_changes.md](/docs/api_changes.md) - November 28th 2020 diff --git a/docs/api_changes.md b/docs/api_changes.md index 4ece73f..1b33344 100644 --- a/docs/api_changes.md +++ b/docs/api_changes.md @@ -1,5 +1,18 @@ -This document keeps a record of all changes to Moonraker's remote -facing APIs. +This document keeps a record of all changes to Moonraker's web APIs. + +### 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 diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..83ef4f0 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,225 @@ +This document describes Moonraker's full configuration. + +# Primary Configuration +The sections outlined here are required for Moonraker to function. A +minimal functional configuration might look like the following: +``` +[server] +host: 0.0.0.0 +port: 7125 +enable_debug_logging: True +config_path: ~/.klippy_config + +[authorization] +enabled: True +trusted_clients: + 192.168.1.0/24 +``` + +## server + +``` +[server] +host: 0.0.0.0 +# The host address in which to bind the HTTP server. Default is to bind +# to all interfaces +port: 7125 +# The port the HTTP server will listen on. Default is 7125 +klippy_uds_address: /tmp/klippy_uds +# The address of Unix Domain Socket used to communicate with Klippy. Default +# is /tmp/klippy_uds +max_upload_size: 200 +# The maximum size allowed for a file upload. Default is 200 MiB. +enable_debug_logging: True +# When set to True Moonraker will log in verbose mode. During this stage +# of development the default is True. In the future this will change. +config_path: +# An optional path where configuration files are located. If specified, +# Moonraker will serve this path allowing file and directory manipulation +# within it. This path must be located within the user's HOME directory, +# by may not be the home directory itself. The default is no path, which +# results in no configuration files being served. +``` +## authorization + +``` +[authorization] +enabled: True +# Enables authorization. When set to true, requests must either contain +# a valid API key or originate from a trusted client. Default is True. +api_key_file: ~/.moonraker_api_key +# Path of the file that stores Moonraker's API key. The default is +# ~/.moonraker_api_key +trusted_clients: + 192.168.1.30 + 192.168.1.0/24 +# A list of newline separated ip addresses and/or ip ranges that are +# trusted. Trusted clients are given full access to the API. Both IPv4 +# and IPv6 addresses and ranges are supported. Ranges must be expressed +# in CIDR notation (see http://ip.sb/cidr for more info). For example, an +# entry of 192.168.1.0/24 will authorize IPs in the range of 192.168.1.1 - +# 192.168.1.254. Note that when specifying IPv4 ranges the last segment +# of the ip address must be 0. The default is no clients or ranges are +# trusted. +cors_domains: + http://klipper-printer.local + http://second-printer.local:7125 +# Enables CORS for the specified domains. One may specify * if they wish +# to allow all domains. +``` + +# Plugin Configuration +The sections outlined here are optional and enable additional +functionality in moonraker. + +## paneldue +Enables PanelDue display support. The PanelDue should be connected to the +host machine, either via the machine's UART GPIOs or through a USB-TTL +converter. + +``` +[paneldue] +serial: +# The serial port in which the PanelDue is connected. This parameter +# must be provided. +baud: 57600 +# The baud rate to connect at. The default is 57600 baud. +machine_name: Klipper +# An optional unique machine name which displays on the PanelDue's +# Header. The default is "Klipper". +macros: + LOAD_FILAMENT + UNLOAD_FILAMENT + PANELDUE_BEEP FREQUENCY=500 DURATION=1 +# A list of newline separated "macros" that are displayed in the +# PanelDue's "macros" tab. These can be gcode macros or simple +# gcodes. A macro may contain parameters. The default is no +# macros will be displayed by the PanelDue. +confirmed_macros: + RESTART + FIRMWARE_RESTART +# Like the "macros" option, this list is added to the macros tab. +# When one of these macros is excuted the PanelDue will prompt +# the user with a confirmation dialog. The default is to include +# RESTART and FIRMWARE_RESTART. +``` + +Most options above are self explanatory. The "macros" option can be used +to specify commands (either built in or gcode_macros) that will show up +in the PanelDue's "macro" menu. + +Note that buzzing the piezo requires the following gcode_macro in `printer.cfg`: +``` +[gcode_macro PANELDUE_BEEP] +# Beep frequency +default_parameter_FREQUENCY: 300 +# Beep duration in seconds +default_parameter_DURATION: 1. +gcode: + {action_call_remote_method("paneldue_beep", + frequency=FREQUENCY|int, + duration=DURATION|float)} +``` + +## power +Enables device power control. Currently GPIO (relays), TPLink Smartplug, +and Tasmota (via http) devices are supported. + +``` +[power device_name] +type: gpio +# The type of device. Can be either gpio, tplink_smartplug or tasmota. +# This parameter must be provided. +pin: gpiochip0/gpio26 +# The pin to use for GPIO devices. The chip is optional, if left out +# then the module will default to gpiochip0. If one wishes to invert +# the signal, a "!" may be prefixed to the pin. Valid examples: +# gpiochip0/gpio26 +# gpio26 +# !gpiochip0/gpio26 +# !gpio26 +# This parameter must be provided for "gpio" type devices +address: +port: +# The above options are used for "tplink_smartplug" devices. The +# address should be a valid ip or hostname for the tplink device. +# The port should be the port the device is configured to use. The +# address must be provided. The port defaults to 9999. +address: +password: +output_id: +# The above options are used for "tasmota" devices. The +# address should be a valid ip or hostname for the tasmota device. +# Provide a password if configured in Tasmota (default is empty). +# Provided an output_id (relay id) if the Tasmota device supports +# more than one (default is 1). +# If your single-relay Tasmota device switches on/off successfully, +# but fails to report its state, ensure that 'SetOption26' is set in +# Tasmota. + +``` +Below are some potential examples: +``` +[power printer] +type: gpio +pin: gpio26 + +[power printer_led] +type: gpio +pin: !gpiochip0/gpio16 + +[power wifi_switch] +type: tplink_smartplug +address: 192.168.1.123 + +[power tasmota_plug] +type: tasmota +address: 192.168.1.124 +password: password1 +``` + +It is possible to toggle device power from the Klippy host, this can be done +with a gcode_macro, such as: +``` +[gcode_macro POWER_OFF_PRINTER] +gcode: + {action_call_remote_method("set_device_power", + device="printer", + state="off")} +``` +The `POWER_OFF_PRINTER` gcode can be run to turn off the "printer" device. +This could be used in conjunction with Klipper's idle timeout to turn the +printer off when idle with a configuration similar to that of below: +``` +[delayed_gcode delayed_printer_off] +initial_duration: 0. +gcode: + {% if printer.idle_timeout.state == "Idle" %} + POWER_OFF_PRINTER + {% endif %} + +[idle_timeout] +gcode: + TURN_OFF_MOTORS + TURN_OFF_HEATERS + UPDATE_DELAYED_GCODE ID=delayed_printer_off DURATION=60 +``` + +## update_manager +This enables moonraker's update manager. Note that updates can only be +performed on pristine git repos. Repos that have been modified on +disk or cloned from unofficial sources are not supported. + +``` +[update_manager] +client_repo: +# This is the GitHub repo of the client, in the format of user/client. +# For example, this could be set to cadriel/fluidd to update Fluidd or +# meteyou/mainsail to update Mainsail. If this option is not set then +# the update manager will not attempt to update a client. +client_path: +# The path to the client's files on disk. This cannot be a symbolic link, +# it must be the real directory in which the client's files are located. +# If `client_repo` is set, this parameter must be provided + +``` diff --git a/docs/installation.md b/docs/installation.md index 093353e..6b0320b 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -77,9 +77,7 @@ https://github.com/meteyou/mainsail). developer some time to bring up Mainsail in line with the latest release of Moonraker. -# Configuration - -## Command line +## Command line Usage The configuration and log file paths may be specified via the command line. ``` @@ -102,7 +100,7 @@ The default configuration is: It is recommended to use the defaults, however one may change these arguments by editing `/etc/default/moonraker`. -## Klipper configuration (printer.cfg) +## Prerequisites (Klipper Configuration) Moonraker depends on the following Klippy extras for full functionality: - [virtual_sdcard] @@ -132,214 +130,5 @@ NOTES: 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. -## Moonraker configuration (moonraker.conf) - -All other configuration is done via `moonraker.conf`. If you are -familiar with Klipper, the configuration is similar. A basic -configuration might look like the following: -``` -[server] -host: 0.0.0.0 -port: 7125 -enable_debug_logging: True -config_path: ~/.klippy_config - -[authorization] -enabled: True -trusted_clients: - 192.168.1.0/24 -``` - -Note that while all items in the `[server]` and `[authorization]` -sections have default values, the sections must be present for -moonraker to start. Aside from the `config_path` and `trusted_clients` -options it is recommended to use default values. - -Below is a detailed explanation of all options currently available: -``` -[server] -host: 0.0.0.0 -# The host address in which to bind the HTTP server. Default is to bind -# to all interfaces -port: 7125 -# The port the HTTP server will listen on. Default is 7125 -klippy_uds_address: /tmp/klippy_uds -# The address of Unix Domain Socket used to communicate with Klippy. Default -# is /tmp/klippy_uds -max_upload_size: 200 -# The maximum size allowed for a file upload. Default is 200 MiB. -enable_debug_logging: True -# When set to True Moonraker will log in verbose mode. During this stage -# of development the default is True. In the future this will change. -config_path: -# An optional path where configuration files are located. If specified, -# Moonraker will serve this path allowing file and directory manipulation -# within it. This path must be located within the user's HOME directory, -# by may not be the home directory itself. The default is no path, which -# results in no configuration files being served. - -[authorization] -enabled: True -# Enables authorization. When set to true, requests must either contain -# a valid API key or originate from a trusted client. Default is True. -api_key_file: ~/.moonraker_api_key -# Path of the file that stores Moonraker's API key. The default is -# ~/.moonraker_api_key -trusted_clients: - 192.168.1.30 - 192.168.1.0/24 -# A list of newline separated ip addresses and/or ip ranges that are -# trusted. Trusted clients are given full access to the API. Both IPv4 -# and IPv6 addresses and ranges are supported. Ranges must be expressed -# in CIDR notation (see http://ip.sb/cidr for more info). For example, an -# entry of 192.168.1.0/24 will authorize IPs in the range of 192.168.1.1 - -# 192.168.1.254. Note that when specifying IPv4 ranges the last segment -# of the ip address must be 0. The default is no clients or ranges are -# trusted. -cors_domains: - http://klipper-printer.local - http://second-printer.local:7125 -# Enables CORS for the specified domains. One may specify * if they wish -# to allow all domains. -``` - -For the moment, you need to restart the moonraker service to load a new -configuration: -``` -sudo service moonraker restart -``` - -### Plugin Configuration -The core plugins are configured via the primary configuration above. Optional -plugins each need their own configuration as outlined below. - -#### PanelDue Plugin -``` -[paneldue] -serial: -# The serial port in which the PanelDue is connected. This parameter -# must be provided. -baud: 57600 -# The baud rate to connect at. The default is 57600 baud. -machine_name: Klipper -# An optional unique machine name which displays on the PanelDue's -# Header. The default is "Klipper". -macros: - LOAD_FILAMENT - UNLOAD_FILAMENT - PANELDUE_BEEP FREQUENCY=500 DURATION=1 -# A list of newline separated "macros" that are displayed in the -# PanelDue's "macros" tab. These can be gcode macros or simple -# gcodes. A macro may contain parameters. The default is no -# macros will be displayed by the PanelDue. -confirmed_macros: - RESTART - FIRMWARE_RESTART -# Like the "macros" option, this list is added to the macros tab. -# When one of these macros is excuted the PanelDue will prompt -# the user with a confirmation dialog. The default is to include -# RESTART and FIRMWARE_RESTART. -``` - -Most options above are self explanatory. The "macros" option can be used -to specify commands (either built in or gcode_macros) that will show up -in the PanelDue's "macro" menu. - -Note that buzzing the piezo requires the following gcode_macro in `printer.cfg`: -``` -[gcode_macro PANELDUE_BEEP] -# Beep frequency -default_parameter_FREQUENCY: 300 -# Beep duration in seconds -default_parameter_DURATION: 1. -gcode: - {action_call_remote_method("paneldue_beep", - frequency=FREQUENCY|int, - duration=DURATION|float)} -``` - -#### Power Control Plugin -Power Plugin Configuration. One may use this module to toggle the -state of a relay using a linux GPIO, enabling the ability to power -a printer on/off regardless of Klippy's state. GPIOs are toggled -using libgpiod. A configuration section should be added for each -device as shown below: -``` -[power device_name] -type: gpio -# The type of device. Can be either gpio, tplink_smartplug or tasmota. -# This parameter must be provided. -pin: gpiochip0/gpio26 -# The pin to use for GPIO devices. The chip is optional, if left out -# then the module will default to gpiochip0. If one wishes to invert -# the signal, a "!" may be prefixed to the pin. Valid examples: -# gpiochip0/gpio26 -# gpio26 -# !gpiochip0/gpio26 -# !gpio26 -# This parameter must be provided for "gpio" type devices -address: -port: -# The above options are used for "tplink_smartplug" devices. The -# address should be a valid ip or hostname for the tplink device. -# The port should be the port the device is configured to use. The -# address must be provided. The port defaults to 9999. -address: -password: -output_id: -# The above options are used for "tasmota" devices. The -# address should be a valid ip or hostname for the tasmota device. -# Provide a password if configured in Tasmota (default is empty). -# Provided an output_id (relay id) if the Tasmota device supports -# more than one (default is 1). -# If your single-relay Tasmota device switches on/off successfully, -# but fails to report its state, ensure that 'SetOption26' is set in -# Tasmota. - -``` -Below are some potential examples: -``` -[power printer] -type: gpio -pin: gpio26 - -[power printer_led] -type: gpio -pin: !gpiochip0/gpio16 - -[power wifi_switch] -type: tplink_smartplug -address: 192.168.1.123 - -[power tasmota_plug] -type: tasmota -address: 192.168.1.124 -password: password1 -``` - -It is possible to toggle device power from the Klippy host, this can be done -with a gcode_macro, such as: -``` -[gcode_macro POWER_OFF_PRINTER] -gcode: - {action_call_remote_method("set_device_power", - device="printer", - state="off")} -``` -The `POWER_OFF_PRINTER` gcode can be run to turn off the "printer" device. -This could be used in conjunction with Klipper's idle timeout to turn the -printer off when idle with a configuration similar to that of below: -``` -[delayed_gcode delayed_printer_off] -initial_duration: 0. -gcode: - {% if printer.idle_timeout.state == "Idle" %} - POWER_OFF_PRINTER - {% endif %} - -[idle_timeout] -gcode: - TURN_OFF_MOTORS - TURN_OFF_HEATERS - UPDATE_DELAYED_GCODE ID=delayed_printer_off DURATION=60 -``` +Please see [configuration.md](configuration.md) for details on how to +configure moonraker.conf. diff --git a/docs/web_api.md b/docs/web_api.md index 0440ca7..677e99d 100644 --- a/docs/web_api.md +++ b/docs/web_api.md @@ -410,6 +410,20 @@ for (let resp of result.gcode_store) { - Returns:\ No return value as the server will shut down upon execution +### Restart a system service +Restarts a system service via `sudo systemctl restart `. Currently +only `moonraker` and `klipper` are allowed. + +- HTTP command:\ + `POST /machine/services/restart?service=` + +- Websocket command:\ + `{jsonrpc: "2.0", method: "machine.services.restart", + params: {service: "service name"}, id: }` + +- Returns:\ + `ok` when complete. Note that if `moonraker` is chosen, the return + value will be sent prior to the restart. ## File Operations @@ -799,8 +813,149 @@ only be used once, making them relatively for inclusion in the query string. to any API endpoint. The query string should be added in the form of: `?token=randomly_generated_token` +## Update Manager APIs +The following endpoints are availabe when the `[update_manager]` plugin has +been configured: + +### Get update status +Retreives the current state of each "package" available for update. Typically +this will consist of information regarding `moonraker`, `klipper`, and +a `client`. If moonraker has not yet received information from Klipper then +its status will be omitted. If a client has not been configured then its +status will also be omitted. If the parameter "refresh" is passed and set +to true then Moonraker will query Github for the most recent release +information. + +- HTTP command:\ + `GET /machine/update/status?refresh=false` + + If the query string is omitted then "refresh" will default + to false. + +- Websocket command:\ + `{jsonrpc: "2.0", method: "machine.update.status", + params: {refresh: false} , id: }` + + If the "params" are omitted then "refresh" will default to false. + +- Returns:\ + Status information in the following format: + ```json + { + 'version_info': { + 'moonraker': { + version: , + current_hash: , + remote_hash: , + is_valid: , + is_dirty: + }, + 'klipper': { + version: , + current_hash: , + remote_hash: , + is_valid: , + is_dirty: + } + 'client': { + name: , + version: , + remote_version: + } + }, + busy: false + } + ``` + - The `busy` field is set to true if an update is in progress. Moonraker + will not allow concurrent updates. + - The `moonraker` and `klipper` objects have the following fields: + - `version`: version of the current repo on disk + - `current_hash`: hash of the most recent commit on disk + - `remote_hash`: hash of the most recent commit pushed to the remote + - `is_valid`: True if installation is a valid git repo on the master branch + and an "origin" set to the official remote + - `is_dirty`: True if the repo has been modified + - The `client` object has the following fields: + `name`: Name of the configured client + `version`: version of the installed client. + `remote_version`: version of the latest release published to GitHub + +### Update Moonraker +Pulls the most recent version of Moonraker from GitHub and restarts +the service. If "include_deps" is set to `true` an attempt will be made +to install new packages (via apt-get) and python dependencies (via pip). +Note that Moonraker uses semantic versioning to check for dependency changes +automatically, so it is generally not necessary to set `include_deps` +to `true`. + +- HTTP command:\ + `POST /machine/update/moonraker?include_deps=false` + + If the query string is omitted then "include_deps" will default + to false. + +- Websocket command:\ + `{jsonrpc: "2.0", method: "machine.update.moonraker", + params: {include_deps: false}, id: }` + + If the "params" are omitted then "include_deps" will default to false. + +- Returns:\ + `ok` when complete + +### Update Klipper +Pulls the most recent version of Klipper from GitHub and restarts +the service. If "include_deps" is set to `true` an attempt will be made +to install new packages (via apt-get) and python dependencies (via pip). +At the moment there is no method for automatically checking for updated +Klipper dependencies, so clients might wish to make this option available +to users via the UI. + +- HTTP command:\ + `POST /machine/update/klipper?include_deps=false` + + If the query string is omitted then "include_deps" will default + to false. + +- Websocket command:\ + `{jsonrpc: "2.0", method: "machine.update.klipper", + params: {include_deps: false}, id: }` + + If the "params" are omitted then "include_deps" will default to false. + +- Returns:\ + `ok` when complete + +### Update Client +If `client_repo` and `client_path` have been configured in `[update_manager]` +this endpoint can be used to install the most recently publish release +of the client. + +- HTTP command:\ + `POST /machine/update/client` + +- Websocket command:\ + `{jsonrpc: "2.0", method: "machine.update.client", + id: }` + +- Returns:\ + `ok` when complete + +### Update System Packages +Upgrades the system packages. Currently only `apt-get` is supported. + +- HTTP command:\ + `POST /machine/update/system` + +- Websocket command:\ + `{jsonrpc: "2.0", method: "machine.update.system", + id: }` + +- Returns:\ + `ok` when complete + ## Power APIs -The APIs below are available when the "power" plugin has been enabled. +The APIs below are available when the `[power]` plugin has been configured. ### Get Devices - HTTP command:\ @@ -993,6 +1148,28 @@ Where `metadata` is an object in the following format: } ``` +### Update Manager Responses +The update manager will send asyncronous messages to the client during an +update: + +`{jsonrpc: "2.0", method: "notify_update_response", params: [response]}` + +Where `response` is an object int he following format: +```json +{ + application: , + proc_id: , + message: +} +``` +- The `application` field contains the name of application currently being + updated. Generally this will be either "moonraker", "klipper", "system", + or "client". +- The `proc_id` field contains a unique id associated with the current update + process. This id is generated for each update request. +- The `message` field contains an asyncronous message sent during the update + process. + # Appendix ## Websocket setup