From 1006bcb85ea9dcc35bf4ee3ef131d75b32f53cf3 Mon Sep 17 00:00:00 2001 From: Rainboooom <1035388373@qq.com> Date: Thu, 15 Jun 2023 12:58:13 +0800 Subject: [PATCH] QIDI moonraker --- .editorconfig | 13 + .gitattributes | 2 + .gitignore | 7 + .readthedocs.yaml | 10 + docs/api_changes.md | 376 ++ docs/components.md | 365 ++ docs/configuration.md | 2067 ++++++ docs/contributing.md | 128 + docs/dev_changelog.md | 350 + docs/developer-certificate-of-origin | 37 + docs/doc-requirements.txt | 2 + docs/example-home-assistant-extended.yaml | 106 + docs/example-home-assistant.yaml | 111 + docs/index.md | 21 + docs/installation.md | 342 + docs/moonraker.conf | 30 + docs/printer_objects.md | 385 ++ docs/user_changes.md | 136 + docs/web_api.md | 5768 +++++++++++++++++ mkdocs.yml | 25 + moonraker/app.py | 1022 +++ moonraker/assets/welcome.html | 235 + moonraker/components/__init__.py | 6 + moonraker/components/announcements.py | 541 ++ moonraker/components/authorization.py | 816 +++ moonraker/components/button.py | 132 + moonraker/components/data_store.py | 171 + moonraker/components/database.py | 900 +++ moonraker/components/dbus_manager.py | 130 + moonraker/components/extensions.py | 107 + moonraker/components/file_manager/__init__.py | 15 + .../components/file_manager/file_manager.py | 1804 ++++++ moonraker/components/file_manager/metadata.py | 1168 ++++ .../update_manager/update_manager.py | 1312 ++++ moonraker/components/gpio.py | 280 + moonraker/components/history.py | 401 ++ moonraker/components/http_client.py | 488 ++ moonraker/components/job_queue.py | 317 + moonraker/components/job_state.py | 88 + moonraker/components/klippy_apis.py | 236 + moonraker/components/ldap.py | 118 + moonraker/components/machine.py | 798 +++ moonraker/components/mqtt.py | 757 +++ moonraker/components/notifier.py | 185 + moonraker/components/octoprint_compat.py | 400 ++ moonraker/components/paneldue.py | 840 +++ moonraker/components/power.py | 1322 ++++ moonraker/components/proc_stats.py | 336 + moonraker/components/secrets.py | 84 + moonraker/components/shell_command.py | 375 ++ moonraker/components/template.py | 87 + .../components/update_manager/__init__.py | 15 + .../components/update_manager/app_deploy.py | 301 + .../components/update_manager/base_config.py | 62 + .../components/update_manager/base_deploy.py | 94 + .../components/update_manager/git_deploy.py | 991 +++ .../update_manager/update_manager.py | 1312 ++++ .../components/update_manager/zip_deploy.py | 431 ++ moonraker/components/webcam.py | 359 + moonraker/components/wled.py | 590 ++ moonraker/components/zeroconf.py | 102 + moonraker/confighelper.py | 557 ++ moonraker/eventloop.py | 193 + moonraker/klippy_connection.py | 605 ++ moonraker/moonraker.py | 517 ++ moonraker/thirdparty/__init__.py | 1 + moonraker/thirdparty/packagekit/__init__.py | 1 + moonraker/thirdparty/packagekit/enums.py | 768 +++ moonraker/utils.py | 232 + moonraker/websockets.py | 660 ++ pytest.ini | 13 + scripts/build-zip-release.sh | 64 + scripts/build_release.py | 338 + scripts/dbtool.py | 233 + scripts/fetch-apikey.sh | 42 + scripts/install-moonraker.sh | 174 + scripts/moonraker-requirements.txt | 18 + scripts/pk-enum-convertor.py | 209 + scripts/set-policykit-rules.sh | 151 + scripts/sudo_fix.sh | 189 + scripts/tag-release.sh | 71 + scripts/uninstall-moonraker.sh | 71 + tests/assets/klipper/base_printer.cfg | 403 ++ tests/assets/klipper/error_printer.cfg | 403 ++ tests/assets/klipper/klipper.dict | 1 + tests/assets/klipper/missing_reqs.cfg | 347 + tests/assets/moonraker/bare_db.cdb | 16 + tests/assets/moonraker/base_server.conf | 18 + tests/assets/moonraker/base_server_ssl.conf | 20 + tests/assets/moonraker/invalid_config.conf | 18 + tests/assets/moonraker/secrets.ini | 3 + tests/assets/moonraker/secrets.json | 6 + tests/assets/moonraker/supplemental.conf | 39 + tests/assets/moonraker/unparsed_server.conf | 22 + tests/conftest.py | 244 + tests/fixtures/__init__.py | 5 + tests/fixtures/http_client.py | 78 + tests/fixtures/klippy_process.py | 81 + tests/fixtures/websocket_client.py | 136 + tests/mocks/__init__.py | 70 + tests/mocks/mock_gpio.py | 193 + tests/test_config.py | 496 ++ tests/test_database.py | 1461 +++++ tests/test_klippy_connection.py | 260 + tests/test_server.py | 518 ++ 105 files changed, 39954 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .readthedocs.yaml create mode 100644 docs/api_changes.md create mode 100644 docs/components.md create mode 100644 docs/configuration.md create mode 100644 docs/contributing.md create mode 100644 docs/dev_changelog.md create mode 100644 docs/developer-certificate-of-origin create mode 100644 docs/doc-requirements.txt create mode 100644 docs/example-home-assistant-extended.yaml create mode 100644 docs/example-home-assistant.yaml create mode 100644 docs/index.md create mode 100644 docs/installation.md create mode 100644 docs/moonraker.conf create mode 100644 docs/printer_objects.md create mode 100644 docs/user_changes.md create mode 100644 docs/web_api.md create mode 100644 mkdocs.yml create mode 100644 moonraker/app.py create mode 100644 moonraker/assets/welcome.html create mode 100644 moonraker/components/__init__.py create mode 100644 moonraker/components/announcements.py create mode 100644 moonraker/components/authorization.py create mode 100644 moonraker/components/button.py create mode 100644 moonraker/components/data_store.py create mode 100644 moonraker/components/database.py create mode 100644 moonraker/components/dbus_manager.py create mode 100644 moonraker/components/extensions.py create mode 100644 moonraker/components/file_manager/__init__.py create mode 100644 moonraker/components/file_manager/file_manager.py create mode 100644 moonraker/components/file_manager/metadata.py create mode 100644 moonraker/components/file_manager/update_manager/update_manager.py create mode 100644 moonraker/components/gpio.py create mode 100644 moonraker/components/history.py create mode 100644 moonraker/components/http_client.py create mode 100644 moonraker/components/job_queue.py create mode 100644 moonraker/components/job_state.py create mode 100644 moonraker/components/klippy_apis.py create mode 100644 moonraker/components/ldap.py create mode 100644 moonraker/components/machine.py create mode 100644 moonraker/components/mqtt.py create mode 100644 moonraker/components/notifier.py create mode 100644 moonraker/components/octoprint_compat.py create mode 100644 moonraker/components/paneldue.py create mode 100644 moonraker/components/power.py create mode 100644 moonraker/components/proc_stats.py create mode 100644 moonraker/components/secrets.py create mode 100644 moonraker/components/shell_command.py create mode 100644 moonraker/components/template.py create mode 100644 moonraker/components/update_manager/__init__.py create mode 100644 moonraker/components/update_manager/app_deploy.py create mode 100644 moonraker/components/update_manager/base_config.py create mode 100644 moonraker/components/update_manager/base_deploy.py create mode 100644 moonraker/components/update_manager/git_deploy.py create mode 100644 moonraker/components/update_manager/update_manager.py create mode 100644 moonraker/components/update_manager/zip_deploy.py create mode 100644 moonraker/components/webcam.py create mode 100644 moonraker/components/wled.py create mode 100644 moonraker/components/zeroconf.py create mode 100644 moonraker/confighelper.py create mode 100644 moonraker/eventloop.py create mode 100644 moonraker/klippy_connection.py create mode 100644 moonraker/moonraker.py create mode 100644 moonraker/thirdparty/__init__.py create mode 100644 moonraker/thirdparty/packagekit/__init__.py create mode 100644 moonraker/thirdparty/packagekit/enums.py create mode 100644 moonraker/utils.py create mode 100644 moonraker/websockets.py create mode 100644 pytest.ini create mode 100644 scripts/build-zip-release.sh create mode 100644 scripts/build_release.py create mode 100644 scripts/dbtool.py create mode 100644 scripts/fetch-apikey.sh create mode 100644 scripts/install-moonraker.sh create mode 100644 scripts/moonraker-requirements.txt create mode 100644 scripts/pk-enum-convertor.py create mode 100644 scripts/set-policykit-rules.sh create mode 100644 scripts/sudo_fix.sh create mode 100644 scripts/tag-release.sh create mode 100644 scripts/uninstall-moonraker.sh create mode 100644 tests/assets/klipper/base_printer.cfg create mode 100644 tests/assets/klipper/error_printer.cfg create mode 100644 tests/assets/klipper/klipper.dict create mode 100644 tests/assets/klipper/missing_reqs.cfg create mode 100644 tests/assets/moonraker/bare_db.cdb create mode 100644 tests/assets/moonraker/base_server.conf create mode 100644 tests/assets/moonraker/base_server_ssl.conf create mode 100644 tests/assets/moonraker/invalid_config.conf create mode 100644 tests/assets/moonraker/secrets.ini create mode 100644 tests/assets/moonraker/secrets.json create mode 100644 tests/assets/moonraker/supplemental.conf create mode 100644 tests/assets/moonraker/unparsed_server.conf create mode 100644 tests/conftest.py create mode 100644 tests/fixtures/__init__.py create mode 100644 tests/fixtures/http_client.py create mode 100644 tests/fixtures/klippy_process.py create mode 100644 tests/fixtures/websocket_client.py create mode 100644 tests/mocks/__init__.py create mode 100644 tests/mocks/mock_gpio.py create mode 100644 tests/test_config.py create mode 100644 tests/test_database.py create mode 100644 tests/test_klippy_connection.py create mode 100644 tests/test_server.py diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f76d6a5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# Editorconfig file for moonraker repo, courtesy of @trevjonez + +root = true + +[*] +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true +charset = utf-8 + +[*.py] +max_line_length = 80 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e72ad8f --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +.devel +.venv + diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..7e23dd5 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,10 @@ +version: 2 + +mkdocs: + configuration: mkdocs.yml + fail_on_warning: false + +python: + version: 3.8 + install: + - requirements: docs/doc-requirements.txt diff --git a/docs/api_changes.md b/docs/api_changes.md new file mode 100644 index 0000000..c16e2b7 --- /dev/null +++ b/docs/api_changes.md @@ -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/`. + +### 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: "/"}, id: } + ``` + Where is either "gcodes" or "config", and 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: , + modified: "last modified date", + slicer: "Slicer Name", + first_layer_height: , + layer_height: , + object_height: , + estimated_time: