Files
bambuddy/frontend/src/utils/temperatureFanPresets.ts
T
maziggy b04664c64a Raise the chamber-temperature ceiling from 60 to 65 C
Every field that takes a chamber target stopped at 60: the per-filament
chamber map and per-print override in Preheat & Heat Soak, the chamber
quick-select presets, and the printer-card chamber control. 60 is the
X1E's ceiling and the X1E was the only heated-chamber model when that
limit was written; the H2 series and X2D heat to 65, so the top of their
range was unreachable.

The ceiling now lives in one constant per side (MAX_CHAMBER_TEMP_C in
backend/app/utils/printer_models.py and frontend/src/utils/printer.ts)
rather than as a literal at each call site. X1E firmware clamps a higher
request to its own maximum, so a shared ceiling is safe.

Also fixes a live bug at PrintersPage.tsx:7985: parsePresetTriple was
bounded to 60 there, and it rejects the whole triple on any out-of-range
entry, so a saved 65 preset would have silently reverted the printer
card to the defaults while Settings still showed 65.
2026-08-03 08:52:23 +02:00

74 lines
2.5 KiB
TypeScript

/**
* Helpers for the user-configurable temperature / fan-speed presets shown in
* the printer-card popovers and edited under Settings -> Workflow.
*
* Storage shape: JSON string of exactly 3 integers per category. Empty string
* means "use built-in defaults". Validators on the backend (AppSettingsUpdate)
* enforce the same shape on writes; helpers here are defensive parsers.
*
* The "Off" (value 0) button is rendered separately by buildPresetOptions and
* is not part of the configurable triple.
*/
import { MAX_CHAMBER_TEMP_C } from './printer';
export type PresetTriple = readonly [number, number, number];
export const NOZZLE_TEMP_DEFAULTS: PresetTriple = [120, 220, 260];
export const BED_TEMP_DEFAULTS: PresetTriple = [55, 75, 90];
export const CHAMBER_TEMP_DEFAULTS: PresetTriple = [35, 45, 60];
export const FAN_SPEED_DEFAULTS: PresetTriple = [50, 75, 100];
export interface PresetCategory {
key: 'nozzle_temp_presets' | 'bed_temp_presets' | 'chamber_temp_presets' | 'fan_speed_presets';
defaults: PresetTriple;
lo: number;
hi: number;
unit: 'C' | '%';
}
export const PRESET_CATEGORIES: readonly PresetCategory[] = [
{ key: 'nozzle_temp_presets', defaults: NOZZLE_TEMP_DEFAULTS, lo: 0, hi: 320, unit: 'C' },
{ key: 'bed_temp_presets', defaults: BED_TEMP_DEFAULTS, lo: 0, hi: 140, unit: 'C' },
{ key: 'chamber_temp_presets', defaults: CHAMBER_TEMP_DEFAULTS, lo: 0, hi: MAX_CHAMBER_TEMP_C, unit: 'C' },
{ key: 'fan_speed_presets', defaults: FAN_SPEED_DEFAULTS, lo: 0, hi: 100, unit: '%' },
];
/**
* Parse a JSON triple from settings, falling back to defaults if empty / malformed
* / wrong shape. Forward-compat for any storage drift; backend validators are
* the source of truth.
*/
export function parsePresetTriple(
raw: string | undefined | null,
fallback: PresetTriple,
lo: number,
hi: number,
): [number, number, number] {
if (!raw) return [...fallback];
try {
const parsed = JSON.parse(raw);
if (
Array.isArray(parsed) &&
parsed.length === 3 &&
parsed.every((n) => Number.isInteger(n) && n >= lo && n <= hi)
) {
return parsed as [number, number, number];
}
} catch {
// fall through to defaults
}
return [...fallback];
}
/** Build the popover options: fixed "Off" button + 3 user-configured presets. */
export function buildPresetOptions(
values: PresetTriple,
unit: 'C' | '%',
): Array<{ label: string; value: number }> {
return [
{ label: 'Off', value: 0 },
...values.map((v) => ({ label: `${v} ${unit}`, value: v })),
];
}