mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-08 15:11:21 +02:00
A printer files each calibration under a nozzle id of the form HH00-0.4 (high flow) or HS00-0.4 (standard) and can hold both for one diameter -- a maintainer's H2D carries 102 high-flow entries against 6 standard -- because the same filament reads a different K through each. Nothing read that, so a standard-flow profile could be selected for a high-flow nozzle and vice versa. The flow is now stored with the profile, shown against each option in the picker, and checked before a stored profile is applied. Two spellings have to agree for that: a calibration entry says HH00-0.4 while the fitted nozzle reports HH01, so the comparison is two characters rather than four -- the trailing digits are a hardware variant the calibration table normalises to 00. Unknown flow on either side matches anything, which is what it has to do. Every profile stored before this has none. And an X1C declares none on any profile at all -- probed live, all eight come back with an empty nozzle id, against a four-digit cali_idx and a populated setting_id -- even though the machine really does take either nozzle. supports_nozzle_flow_type is therefore the wrong thing to gate on: it returns True for an X1C, and treating that silence as Standard would have dropped every X1C profile the moment a high-flow nozzle was fitted. What the printer's own table declares per profile is the test. NozzleInfo.nozzle_type carries two vocabularies by printer generation -- the nozzle material on legacy printers, the flow code on H2 -- and the comment claiming only the former is corrected. Anything that is not HH or HS reads as unknown, which is what makes the material spelling harmless. Storing both flows for one hotend and diameter is deliberately not done: spoolman_k_profile is UNIQUE on (spool, printer, extruder, diameter) with no flow column, and allowing a second row in internal mode alone would break inventory-mode parity. The picker marks a profile whose flow does not match what is fitted instead of letting it look configured while doing nothing.
58 lines
2.3 KiB
TypeScript
58 lines
2.3 KiB
TypeScript
/**
|
|
* Nozzle flow type: High Flow vs Standard.
|
|
*
|
|
* A printer files each calibration profile under a nozzle id of the form
|
|
* `HH00-0.4` (high flow) or `HS00-0.4` (standard), so on a machine that sells
|
|
* both, the flow is part of a K profile's identity — the same filament reads a
|
|
* different K value through each.
|
|
*
|
|
* Two spellings have to reduce to the same answer, which is why this compares
|
|
* two characters rather than four:
|
|
*
|
|
* - a calibration entry says `HH00-0.4`
|
|
* - the fitted nozzle reports its type as `HH01`
|
|
*
|
|
* Both measured on an H2D; the trailing digits are a hardware variant that the
|
|
* calibration table normalises to `00`.
|
|
*
|
|
* And it can legitimately be absent. An X1C answers `extrusion_cali_get` with
|
|
* `nozzle_id: ''` on every profile — measured, all eight — even though the
|
|
* machine really does take either nozzle. So "no flow" means *unknown*, never
|
|
* Standard: inventing a value here and then filtering on it would drop every
|
|
* X1C profile the moment a high-flow nozzle was fitted. (BambuStudio's own
|
|
* parser defaults a missing id to Standard for *display*, which is fine for a
|
|
* label and wrong for a lookup key.)
|
|
*/
|
|
|
|
export type NozzleFlow = 'HH' | 'HS';
|
|
|
|
/** The flow code in a nozzle id (`HH00-0.4`) or a nozzle type (`HH01`). */
|
|
export function normaliseFlow(raw: string | null | undefined): NozzleFlow | null {
|
|
const code = (raw ?? '').trim().toUpperCase().slice(0, 2);
|
|
return code === 'HH' || code === 'HS' ? code : null;
|
|
}
|
|
|
|
/** Short label for a flow code, or null when there is nothing to say. */
|
|
export function flowLabel(flow: NozzleFlow | null): string | null {
|
|
if (!flow) return null;
|
|
return flow === 'HH' ? 'HF' : 'S';
|
|
}
|
|
|
|
/**
|
|
* Whether a stored K profile's flow applies to the nozzle now fitted.
|
|
*
|
|
* Unknown on either side matches: every profile stored before flow was
|
|
* recorded has none, as does every profile from a printer whose table omits it.
|
|
* Mirrors `SlotNozzle.flow_matches` on the backend, which is what actually
|
|
* decides at assign time — this is the same rule for the picker's benefit.
|
|
*/
|
|
export function flowApplies(
|
|
storedFlow: string | null | undefined,
|
|
fittedFlow: string | null | undefined,
|
|
): boolean {
|
|
const stored = normaliseFlow(storedFlow);
|
|
const fitted = normaliseFlow(fittedFlow);
|
|
if (!stored || !fitted) return true;
|
|
return stored === fitted;
|
|
}
|