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
+22 -15
View File
@@ -1154,6 +1154,13 @@ export interface APIKeyUpdate {
expires_at?: string | null;
}
/**
* Tri-state calibration option (BambuStudio parity): "off" never runs it,
* "on" forces it every print, "auto" lets the printer skip it if it was done
* recently. Used by bed_levelling, flow_cali, and nozzle_offset_cali.
*/
export type CalibrationMode = 'off' | 'on' | 'auto';
// Settings types
export interface AppSettings {
auto_archive: boolean;
@@ -1263,12 +1270,12 @@ export interface AppSettings {
// User email notifications toggle
user_notifications_enabled: boolean;
// Default print options
default_bed_levelling: boolean;
default_flow_cali: boolean;
default_bed_levelling: CalibrationMode;
default_flow_cali: CalibrationMode;
default_vibration_cali: boolean;
default_layer_inspect: boolean;
default_timelapse: boolean;
default_nozzle_offset_cali: boolean;
default_nozzle_offset_cali: CalibrationMode;
// Staggered batch start defaults
stagger_group_size: number;
stagger_interval_minutes: number;
@@ -2181,13 +2188,13 @@ export interface PrintQueueItem {
filament_overrides: Array<{ slot_id: number; type: string; color: string; color_name?: string; force_color_match?: boolean }> | null; // Filament overrides for model-based assignment
plate_id: number | null; // Plate ID for multi-plate 3MF files
// Print options
bed_levelling: boolean;
flow_cali: boolean;
bed_levelling: CalibrationMode;
flow_cali: CalibrationMode;
vibration_cali: boolean;
layer_inspect: boolean;
timelapse: boolean;
use_ams: boolean;
nozzle_offset_cali: boolean;
nozzle_offset_cali: CalibrationMode;
preheat_override: 'inherit' | 'on' | 'off';
preheat_chamber_target_override: number | null;
status: 'pending' | 'printing' | 'completed' | 'failed' | 'skipped' | 'cancelled';
@@ -2258,13 +2265,13 @@ export interface PrintQueueItemCreate {
ams_mapping?: number[] | null; // AMS slot mapping for multi-color prints
plate_id?: number | null; // Plate ID for multi-plate 3MF files
// Print options
bed_levelling?: boolean;
flow_cali?: boolean;
bed_levelling?: CalibrationMode;
flow_cali?: CalibrationMode;
vibration_cali?: boolean;
layer_inspect?: boolean;
timelapse?: boolean;
use_ams?: boolean;
nozzle_offset_cali?: boolean;
nozzle_offset_cali?: CalibrationMode;
preheat_override?: 'inherit' | 'on' | 'off';
preheat_chamber_target_override?: number | null;
// Auto-print G-code injection
@@ -2302,13 +2309,13 @@ export interface PrintQueueItemUpdate {
ams_mapping?: number[];
plate_id?: number | null; // Plate ID for multi-plate 3MF files
// Print options
bed_levelling?: boolean;
flow_cali?: boolean;
bed_levelling?: CalibrationMode;
flow_cali?: CalibrationMode;
vibration_cali?: boolean;
layer_inspect?: boolean;
timelapse?: boolean;
use_ams?: boolean;
nozzle_offset_cali?: boolean;
nozzle_offset_cali?: CalibrationMode;
preheat_override?: 'inherit' | 'on' | 'off';
preheat_chamber_target_override?: number | null;
// Auto-print G-code injection
@@ -2323,13 +2330,13 @@ export interface PrintQueueBulkUpdate {
auto_off_after?: boolean;
manual_start?: boolean;
// Print options
bed_levelling?: boolean;
flow_cali?: boolean;
bed_levelling?: CalibrationMode;
flow_cali?: CalibrationMode;
vibration_cali?: boolean;
layer_inspect?: boolean;
timelapse?: boolean;
use_ams?: boolean;
nozzle_offset_cali?: boolean;
nozzle_offset_cali?: CalibrationMode;
preheat_override?: 'inherit' | 'on' | 'off';
preheat_chamber_target_override?: number | null;
// Auto-print G-code injection