feat(print-options): add "Auto" state to bed levelling, flow & nozzle-offset calibration

Bed levelling, flow calibration, and nozzle-offset calibration were on/off
only, so the sole way to run bed levelling was to force a full level before
every print. Bambu Studio has always offered a third "Auto" state that lets
the printer skip the calibration when it was done recently -- the state most
users actually want. Make these three options tri-state (off/on/auto),
defaulting to auto, and leave vibration/layer-inspect/timelapse as on/off
(Bambu Studio exposes no auto for those).

Wire encoding follows Bambu Studio's source exactly: each option sends a JSON
bool (true only for "on") plus a companion int -- off=0, on=1, auto=2. The
bool fields stay booleans (the #1478 H2S regression); only the companion int
widened from {0,1} to {0,1,2}. #1721's observation that stage 8/39 stays
queued when sending 2 is the auto contract (queued, skipped at runtime if
recent), not a broken "off".

- schemas: TriState = Literal[off/on/auto] with a BeforeValidator coercing
  legacy bool / 0-1 / true-false so old clients and un-migrated rows validate
- model + migration: boolean columns -> String; SQLite via column affinity +
  data backfill, PostgreSQL via ALTER COLUMN TYPE guarded on information_schema
  (verified on both dialects); settings rows normalised true/false -> on/off
- MQTT: start_print takes the tri-state strings and emits the paired bool+int
- Virtual Printer: reconstructs the slicer's auto/on/off from the int companion
  (auto_bed_leveling / extrude_cali_flag) in both capture paths
- frontend: CalibrationMode type; off/auto/on segmented controls in the print
  dialog, queue bulk-edit, and Settings -> Workflow; calibrationMode_* strings
  in all 11 locales
This commit is contained in:
maziggy
2026-07-20 17:55:56 +02:00
parent 454ce3ceec
commit 2e45893dd5
41 changed files with 817 additions and 343 deletions
+19
View File
@@ -0,0 +1,19 @@
import type { CalibrationMode } from '../api/client';
/** Display order for the off/auto/on segmented controls. */
export const CALIBRATION_MODES: CalibrationMode[] = ['off', 'auto', 'on'];
/**
* Active-button classes per calibration mode. Each state gets its own colour so
* the selected value is legible at a glance rather than every choice reading as
* the same "on" green: Off = red (never), Auto = blue (printer decides),
* On = green (force every print).
*/
export const CALIBRATION_MODE_ACTIVE: Record<CalibrationMode, string> = {
off: 'bg-red-500 text-white',
auto: 'bg-blue-500 text-white',
on: 'bg-bambu-green text-white',
};
/** Inactive-button classes shared by every mode. */
export const CALIBRATION_MODE_INACTIVE = 'bg-bambu-dark-tertiary text-bambu-gray hover:text-white';