nozzleFlow.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. /**
  2. * Nozzle flow type: High Flow vs Standard.
  3. *
  4. * A printer files each calibration profile under a nozzle id of the form
  5. * `HH00-0.4` (high flow) or `HS00-0.4` (standard), so on a machine that sells
  6. * both, the flow is part of a K profile's identity — the same filament reads a
  7. * different K value through each.
  8. *
  9. * Two spellings have to reduce to the same answer, which is why this compares
  10. * two characters rather than four:
  11. *
  12. * - a calibration entry says `HH00-0.4`
  13. * - the fitted nozzle reports its type as `HH01`
  14. *
  15. * Both measured on an H2D; the trailing digits are a hardware variant that the
  16. * calibration table normalises to `00`.
  17. *
  18. * And it can legitimately be absent. An X1C answers `extrusion_cali_get` with
  19. * `nozzle_id: ''` on every profile — measured, all eight — even though the
  20. * machine really does take either nozzle. So "no flow" means *unknown*, never
  21. * Standard: inventing a value here and then filtering on it would drop every
  22. * X1C profile the moment a high-flow nozzle was fitted. (BambuStudio's own
  23. * parser defaults a missing id to Standard for *display*, which is fine for a
  24. * label and wrong for a lookup key.)
  25. */
  26. export type NozzleFlow = 'HH' | 'HS';
  27. /** The flow code in a nozzle id (`HH00-0.4`) or a nozzle type (`HH01`). */
  28. export function normaliseFlow(raw: string | null | undefined): NozzleFlow | null {
  29. const code = (raw ?? '').trim().toUpperCase().slice(0, 2);
  30. return code === 'HH' || code === 'HS' ? code : null;
  31. }
  32. /** Short label for a flow code, or null when there is nothing to say. */
  33. export function flowLabel(flow: NozzleFlow | null): string | null {
  34. if (!flow) return null;
  35. return flow === 'HH' ? 'HF' : 'S';
  36. }
  37. /**
  38. * Whether a stored K profile's flow applies to the nozzle now fitted.
  39. *
  40. * Unknown on either side matches: every profile stored before flow was
  41. * recorded has none, as does every profile from a printer whose table omits it.
  42. * Mirrors `SlotNozzle.flow_matches` on the backend, which is what actually
  43. * decides at assign time — this is the same rule for the picker's benefit.
  44. */
  45. export function flowApplies(
  46. storedFlow: string | null | undefined,
  47. fittedFlow: string | null | undefined,
  48. ): boolean {
  49. const stored = normaliseFlow(storedFlow);
  50. const fitted = normaliseFlow(fittedFlow);
  51. if (!stored || !fitted) return true;
  52. return stored === fitted;
  53. }