Files
bambuddy/static
Thomas Scott Williams f86f5a7c34 feat(queue): keep the chamber warm between prints and skip redundant soak
Back-to-back prints in chamber-heated materials (ASA, ABS, PA, PC) each paid
a full heat-soak from cold, even when the print that just finished had left
the chamber at temperature. Two changes remove that cost.

Keep bed warm between prints
  While a printer sits in FINISH awaiting plate-clear and the next queued item
  needs chamber heat, hold the bed hot so the chamber does not cool during the
  bed-clearing window. The bed is the chamber's heating element here, not a
  print surface, so the hold runs at the new `queue_keep_warm_bed_temp`
  (default 90C, which also satisfies bed-threshold-linked aftermarket chamber
  heaters), raised to the item's own bed temperature when that is higher.

  Gated on `queue_keep_bed_warm` AND `require_plate_clear` AND
  `preheat_enabled`, all re-checked in the backend so a stale UI cannot leave
  the feature running. `queue_keep_warm_max_minutes` (default 120) bounds the
  hold: when it elapses the bed is switched off and the hold latches until the
  printer is next a candidate, so a plate nobody clears cannot leave the bed
  hot indefinitely. The hold is also released when the item is deleted, the
  queue empties, or a gate is toggled off mid-hold, and never when firmware
  reports a target other than the one it set — a temperature the user or a
  print changed is left alone. Publishing is idempotent.

Smart soak reduction from chamber history
  The scheduler samples each connected printer's chamber temperature every tick
  into a 2h rolling history. Preheat credits time the chamber has already spent
  at temperature against the configured soak, shortening or skipping it.

  Credit starts no earlier than the newest sample, the most recent unbroken run
  of samples, or the end of the last real dip below target. A dip only counts
  once it outlasts a grace period: an enclosed chamber cannot lose and regain
  several degrees quickly (measured on an X1C, cooling from 55C to below 48C
  takes 23-73 minutes, ~0.2 C/min), so a brief low reading is a door opening or
  sensor noise rather than lost soak — and a plate swap, which is exactly when
  keep-warm runs, produces one. A stale history credits nothing: at that
  cooling rate the chamber can cross the threshold unobserved, so the full soak
  runs instead.

Three supporting changes to preheat itself:

  * Cancelling or deleting a queued item now stops a preheat already running
    for it. Those routes only write `status` to the database, which a dispatch
    coroutine parked in `asyncio.sleep` cannot observe, so the heaters ran for
    the rest of max_wait + soak — 45 minutes at the default settings — and the
    printer stayed in `busy_printers`, blocking every other queued item behind
    a print that was not happening. The routes now signal the scheduler
    directly, and the stage sleeps in slices so it notices promptly and
    abandons the dispatch, letting the existing rollback shut the heaters off.

  * A chamber-heated print whose slicer metadata carries no bed temperature
    (common for Orca-exported 3MFs) used to skip preheat entirely and start
    with a cold chamber. It now heats the bed to `queue_keep_warm_bed_temp`.
    A parsed bed temperature still wins, and a print with no chamber
    requirement still skips — no bed temperature is invented for the print
    itself. Preheat's bed target is transient regardless: the print's own
    gcode issues its M140/M190 at start.

  * Preheat records which commands it sent (bed, chamber, airduct) and unwinds
    them if the dispatch aborts before the print starts — a failed upload, a
    cancelled item, an exception — instead of leaving the printer heating for
    a job that is not happening.
2026-08-09 17:07:34 -04:00
..
2026-08-08 10:20:57 +02:00
2026-08-08 10:20:57 +02:00
2026-08-08 10:20:57 +02:00
2026-08-08 10:20:57 +02:00
2026-08-08 10:20:57 +02:00
2026-08-08 10:20:57 +02:00
2026-08-08 10:20:57 +02:00
2026-08-08 10:20:57 +02:00