فهرست منبع

Correct the drying settings path and the print-drying comment (issue #2518)

The changelog named Settings -> Print Queue -> Auto-Drying; the toggle
lives in the Queue Auto-Drying card under Settings -> Workflow. The
scheduler comment and a test docstring called print_drying a permission
overlay rather than a trigger, but since #1816 it starts mid-print
cycles on its own regardless of queue state.
maziggy 1 روز پیش
والد
کامیت
61e2841d16
3فایلهای تغییر یافته به همراه12 افزوده شده و 13 حذف شده
  1. 1 1
      CHANGELOG.md
  2. 7 7
      backend/app/services/print_scheduler.py
  3. 4 5
      backend/tests/unit/test_scheduler_auto_drying.py

+ 1 - 1
CHANGELOG.md

@@ -5,7 +5,7 @@ All notable changes to Bambuddy will be documented in this file.
 ## [1.2.6b1] - Unreleased
 
 ### Added
-- **Ambient drying can wait until the humidity stays high, so opening the AMS lid no longer buys a drying cycle (#2518, requested by @ryansouza, contributed by @M2ABRAMSTANK in #2895)** — Ambient auto-drying started on the first humidity reading above the threshold. Opening the AMS lid to swap a spool lets room air reach the sensor for a few minutes, and that brief spike was enough to start a cycle of up to 12 hours. A new **Require sustained humidity** switch under Settings → Print Queue → Auto-Drying, shown while ambient drying is on, sets how long the humidity has to stay above the threshold before a cycle starts: 5 to 240 minutes, 15 when first switched on. It is off by default, so nothing changes until it is turned on. The 15 minutes come from a measured trace on an H2D: after the lid had been open for one to five minutes, every unit was back at or below 25% within about 12 minutes of opening, and the wait only starts counting at the first high reading. One reading at or below the threshold starts the wait over, and so does a gap of more than two minutes without a reading (a disconnect, or a print that pauses checking), which is logged with the measured gap. A missing reading changes nothing. A printer with a scheduled print pending still starts at once, for every AMS unit on it, because that drying has a deadline. The wait also applies to a printer that is printing with **Continue drying while printing** on, but not while ambient drying itself is off. It runs alongside the cooldown after a cycle instead of being added to it, never interrupts a running or manual cycle, and does not log a wait for a unit the printer refuses to dry. Translated in all locales.
+- **Ambient drying can wait until the humidity stays high, so opening the AMS lid no longer buys a drying cycle (#2518, requested by @ryansouza, contributed by @M2ABRAMSTANK in #2895)** — Ambient auto-drying started on the first humidity reading above the threshold. Opening the AMS lid to swap a spool lets room air reach the sensor for a few minutes, and that brief spike was enough to start a cycle of up to 12 hours. A new **Require sustained humidity** switch in the **Queue Auto-Drying** card under Settings → Workflow, shown while **Ambient drying** is on, sets how long the humidity has to stay above the threshold before a cycle starts: 5 to 240 minutes, 15 when first switched on. It is off by default, so nothing changes until it is turned on. The 15 minutes come from a measured trace on an H2D: after the lid had been open for one to five minutes, every unit was back at or below 25% within about 12 minutes of opening, and the wait only starts counting at the first high reading. One reading at or below the threshold starts the wait over, and so does a gap of more than two minutes without a reading (a disconnect, or a print on a printer that isn't drying while printing), which is logged with the measured gap. A missing reading changes nothing. A printer with a scheduled print pending still starts at once, for every AMS unit on it, because that drying has a deadline. The wait also applies to a printer that is printing with **Continue drying while printing** on, but not while ambient drying itself is off. It runs alongside the cooldown after a cycle instead of being added to it, never interrupts a running or manual cycle, and does not log a wait for a unit the printer refuses to dry. Translated in all locales.
 - **Other applications can send messages through your notification channels** — A new switch per notification provider, **Messages from connected apps** (off by default), lets an application such as Bambuddy Orders send its own messages ("3 orders need you") to Telegram, ntfy, email and the other channels. The app calls `POST /api/v1/notifications/app-message` with an API key that has the new **Send Notifications** permission (off by default; the key's owner also needs `notifications:update`). Messages go through quiet hours, the daily digest and the notification log like Bambuddy's own. Text is plain, links must be http(s), and each key is limited to 20 messages a minute. `GET /api/v1/notifications/app-message/channels` tells the app which channels take its messages. The check behind the electricity-price door and this one is now one shared helper.
 - **A link can open one batch order** — `/queue?batch=<id>` opens the Batches tab with that order highlighted and scrolled into view, whatever its status.
 - **The streaming overlay can show the printer model (#3080, requested and contributed by @adamspicedev in #3099)** — Settings → API Keys → Streaming Overlay has a new **Printer model** checkbox, which adds `model` to the overlay URL's `show=` list. It can be picked together with the printer name or on its own. With both, the overlay shows `Big Mumma · H2D`; with only the model, `H2D`. A printer with no model stored shows the name alone, without a stray separator. The model is off by default, so every overlay URL already set up in OBS looks the same after upgrading. The token-authenticated feed that OBS reads (`/printers/{id}/overlay-status`) now returns `model` for connected and disconnected printers; it exposes nothing else new. A long name plus model in a narrow OBS source is now cut off with an ellipsis instead of running past the edge of the panel.

+ 7 - 7
backend/app/services/print_scheduler.py

@@ -4555,13 +4555,13 @@ class PrintScheduler:
                 # Sustained-humidity wait (#2518): ambient-triggered starts
                 # wait; only a printer with a scheduled queue item pending
                 # keeps the instant behavior, because that drying has a real
-                # deadline. Mid-print is deliberately NOT exempt: print_drying
-                # is a permission overlay, not a trigger -- an ambient start on
-                # a printer that happens to be printing is the same
-                # transient-vulnerable humidity trigger as on an idle one
-                # (proven live: a 2-point threshold crossing mid-print bought a
-                # parked 12h command). Inactive when ambient drying is off, so a
-                # mid-print start under print_drying alone stays instant.
+                # deadline. Mid-print is deliberately NOT exempt while ambient
+                # drying is on: a humidity start on a printer that happens to be
+                # printing is as vulnerable to a lid-open spike as one on an idle
+                # printer (proven live: a 2-point threshold crossing mid-print
+                # bought a parked 12h command). Inactive when ambient drying is
+                # off: print_drying then still starts mid-print cycles on its own
+                # (#1816, "regardless of queue state"), and those stay instant.
                 if sustained_wait_active and pid not in printers_with_scheduled:
                     _above = self._auto_dry_above.get(unit_key)
                     _waited = time.monotonic() - _above["since"] if _above else 0.0

+ 4 - 5
backend/tests/unit/test_scheduler_auto_drying.py

@@ -2211,11 +2211,10 @@ class TestAmbientDryingSustainedDelay(_DryingTestBase):
     @pytest.mark.asyncio
     @patch("backend.app.services.print_scheduler.printer_manager")
     async def test_mid_print_ambient_start_waits_like_any_ambient_start(self, mock_pm, scheduler):
-        """print_drying is a permission overlay, not a trigger: an ambient
-        start on a printer that happens to be printing is still an ambient
-        start and must serve the sustained wait. (The original exemption here
-        was disproven live — a 2-point threshold crossing mid-print bought a
-        parked 12h command instantly.)"""
+        """With ambient drying on, a humidity start on a printer that happens to
+        be printing must serve the sustained wait like one on an idle printer.
+        (The original exemption here was disproven live — a 2-point threshold
+        crossing mid-print bought a parked 12h command instantly.)"""
         state = self._state()
         state.state = "RUNNING"
         mock_pm.get_status.return_value = state