From d5810a530f72be93678c27f2c3007ce728f871bf Mon Sep 17 00:00:00 2001 From: Reid 'arrdem' McKenzie <me@arrdem.com> Date: Mon, 19 Jun 2023 23:24:10 -0600 Subject: [PATCH 1/3] Cache API clients to reduce 500 risk(s) --- projects/tentacles/src/python/tentacles/workers.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/projects/tentacles/src/python/tentacles/workers.py b/projects/tentacles/src/python/tentacles/workers.py index 03cd5e9..ec0024d 100644 --- a/projects/tentacles/src/python/tentacles/workers.py +++ b/projects/tentacles/src/python/tentacles/workers.py @@ -8,6 +8,7 @@ Mostly related to monitoring and managing Printer state. """ from contextlib import closing +from functools import cache import logging from pathlib import Path from pprint import pformat @@ -49,6 +50,11 @@ class OctoRest(_OR): raise e +@cache +def get_client(url, key): + return OctoRest(url=url, apikey=key) + + log = logging.getLogger(__name__) @@ -65,7 +71,7 @@ def poll_printers(app: App, db: Db) -> None: printer_job = {} try: - client = OctoRest(url=printer.url, apikey=printer.api_key) + client = get_client(printer.url, printer.api_key) printer_job: dict = client.job_info() try: printer_state: dict = client.printer().get("state").get("flags", {}) @@ -136,7 +142,7 @@ def push_jobs(app: App, db: Db) -> None: db.delete_job(job.user_id, job.id) try: - client = OctoRest(url=printer.url, apikey=printer.api_key) + client = get_client(printer.url, printer.api_key) printer_job = client.job_info() try: printer_state = client.printer().get("state").get("flags", {}) @@ -182,7 +188,7 @@ def revoke_jobs(app: App, db: Db) -> None: try: log.info(f"Cancelling running job {job.id}") - client = OctoRest(url=printer.url, apikey=printer.api_key) + client = get_client(printer.url, printer.api_key) try: client.cancel() except HTTPError as e: @@ -211,7 +217,7 @@ def pull_jobs(app: App, db: Db) -> None: for job in db.list_running_jobs(): printer = db.fetch_printer(pid=job.printer_id) try: - client = OctoRest(url=printer.url, apikey=printer.api_key) + client = get_client(printer.url, printer.api_key) job_state = client.job_info() try: printer_state = client.printer().get("state").get("flags", {}) From ae1d00b13f3551dfb70f429271f55c971f4859cd Mon Sep 17 00:00:00 2001 From: Reid 'arrdem' McKenzie <me@arrdem.com> Date: Mon, 19 Jun 2023 23:25:03 -0600 Subject: [PATCH 2/3] Create an 'occupied' state for unready beds --- projects/tentacles/src/python/tentacles/schema.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/projects/tentacles/src/python/tentacles/schema.sql b/projects/tentacles/src/python/tentacles/schema.sql index 1e36258..4c1f3d8 100644 --- a/projects/tentacles/src/python/tentacles/schema.sql +++ b/projects/tentacles/src/python/tentacles/schema.sql @@ -157,6 +157,10 @@ CREATE TABLE IF NOT EXISTS email_spool ( , FOREIGN KEY(user_id) REFERENCES users(id) ); +-- name: migration-0002-create-occupied-state +-- Create a state representing that the printer needs to be unloaded after a print +INSERT OR IGNORE INTO printer_statuses (id, name) VALUES (5, 'occupied'); + ---------------------------------------------------------------------------------------------------- -- Users ---------------------------------------------------------------------------------------------------- From 730a6a3950b751cb9177c6cabce0e5541de0fa91 Mon Sep 17 00:00:00 2001 From: Reid 'arrdem' McKenzie <me@arrdem.com> Date: Mon, 19 Jun 2023 23:24:39 -0600 Subject: [PATCH 3/3] Use the bedready plugin to check if the bed is clear or occupied --- .../tentacles/src/python/tentacles/workers.py | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/projects/tentacles/src/python/tentacles/workers.py b/projects/tentacles/src/python/tentacles/workers.py index ec0024d..90f599f 100644 --- a/projects/tentacles/src/python/tentacles/workers.py +++ b/projects/tentacles/src/python/tentacles/workers.py @@ -69,6 +69,24 @@ def poll_printers(app: App, db: Db) -> None: log.info(f"Printer {printer.id} {printer.status} -> {status}") db.update_printer_status(pid=printer.id, status=status) + def _bed_clear(): + if not ( + snapshots := client._post( + "/api/plugin/bedready", json={"command": "list_snapshots"} + ) + ): + return True # Assume the bed is ready + + status = client._post( + "/api/plugin/bedready", + json={ + "command": "check_bed", + "similarity": 0.97, + "reference": snapshots[0], + }, + ) + return status.get("bed_clear", True) + printer_job = {} try: client = get_client(printer.url, printer.api_key) @@ -98,7 +116,10 @@ def poll_printers(app: App, db: Db) -> None: _set_status("connecting") elif printer_state.get("ready"): - _set_status("idle") + if _bed_clear(): + _set_status("idle") + else: + _set_status("occupied") else: raise Exception(