You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Creator 5 performs material matching at print-start (POST /printGcode),
unlike the AD5X which maps materials at upload time. Add a Creator 5-native
start method that sends only the fields the firmware reads.
- startCreator5Job(Creator5JobParams): POSTs /printGcode with fileName,
levelingBeforePrint, optional flowCalibration/timeLapseVideo, and 3-field
Creator5MaterialMapping[] (toolId 0-based, slotId 1-based, materialName).
Omits materialMappings for single-tool prints; no AD5X-only fields.
- Add Creator5JobParams / Creator5MaterialMapping types + exports.
- Replace the AD5X-bodied start aliases (released minutes ago, no consumers)
with the native method; keep uploadFileWithMaterialMappings since C5 upload
genuinely reuses the AD5X path.
- Document Creator 5 support and the library's by-concern organization
(do-not-refactor-into-per-printer-clients) in CLAUDE.md.
Bump to 1.3.4.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CLAUDE.md
+22Lines changed: 22 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -42,6 +42,18 @@ The API uses two communication layers that work together:
42
42
43
43
Raw API responses (`FFPrinterDetail` in `src/models/ff-models.ts`) are transformed into the structured `FFMachineInfo` model by `MachineInfo.fromDetail()` (`src/models/MachineInfo.ts`). This handles status string-to-enum mapping, time formatting, temperature pairing, and boolean conversion from the printer's "open"/"close" string convention.
44
44
45
+
### Model Detection (Pid-First)
46
+
47
+
`MachineInfo.fromDetail()` derives `IsPro` / `IsAD5X` from the firmware-set integer `pid` field on `/detail` (35 = Adventurer 5M, 36 = 5M Pro, 38 = AD5X — see `KNOWN_HTTP_PIDS` in `MachineInfo.ts`). The raw value is also surfaced as `FFMachineInfo.Pid` for consumers that need to do their own model-class gating. When `pid` is absent (older firmware) the parser falls back to a name+capability heuristic, but new code should NOT substring-match `detail.name` — that field is user-mutable via the LCD or cloud account and changing it broke detection in pre-1.3.1 builds (see CHANGELOG entry for 1.3.1, ref `ff-5mp-hass#13`).
48
+
49
+
### Why TCP Bootstrap Is Still Required for Modern Printers
50
+
51
+
The HTTP `/detail` endpoint requires authentication (`serialNumber` + `checkCode` via `FNetCode`). During discovery and the first connection attempt — before a check code has been entered — there are no credentials, so `pid` cannot be read from `/detail`. The library bridges this with TCP:
52
+
53
+
1.`PrinterDiscovery` (UDP) returns the USB-style PID in the broadcast packet and maps it to a `PrinterModel`. Consumers can pre-select a model class before pairing.
54
+
2. After a check code is provided, `FiveMClient.initialize()` runs an authenticated `/detail` call alongside an unauthenticated TCP `M115` via `tcpClient.getPrinterInfo()`. M115 returns `TypeName` (firmware-controlled, e.g. `"FlashForge Adventurer 5M Pro"`) which is safe to substring-match; do NOT use M115's `Name` field for capability inference — like `detail.name` it is user-set.
55
+
3. Once `verifyConnection()` finishes, `FFMachineInfo.Pid` / `IsPro` / `IsAD5X` are authoritative. All later capability gating should read those, not re-parse strings.
56
+
45
57
### Network Layer
46
58
47
59
-`NetworkUtils` (`src/api/network/NetworkUtils.ts`) — Response validation helpers; checks `GenericResponse.code` for success.
@@ -56,6 +68,16 @@ Located in `src/tcpapi/replays/`, each parser has a `fromReplay(response)` metho
56
68
57
69
The AD5X (Adventurer 5X) extends the 5M API with Intelligent Filament Station (IFS) support. Key types: `AD5XMaterialMapping`, `AD5XLocalJobParams`, `AD5XSingleColorJobParams`, `AD5XUploadParams`, `MatlStationInfo`, `SlotInfo` — all in `src/models/ff-models.ts`.
58
70
71
+
### Creator 5 / Creator 5 Pro Support
72
+
73
+
The Creator 5 series is "AD5X + per-tool temps". It shares the 4-slot material station and reuses the AD5X upload path, but **material matching happens at print-start** (`POST /printGcode`) rather than at upload time. Use `startCreator5Job(Creator5JobParams)` — its `materialMappings` are the 3-field `Creator5MaterialMapping` (`toolId` 0-based, `slotId` 1-based, `materialName`; no colors). Per-tool temps are in `FFMachineInfo.ToolTemps[]` (single-nozzle models report a 1-element array). Capability flags: `IsCreator5Pro`, `HasCamera`, `HasLidar`, `HasDoorSensor` (Pro only — plain C5 `doorStatus` is cosmetic). Filtration is force-enabled by model for the C5 Pro in `FiveMClient.sendProductCommand` because its `/product` under-reports the fan states.
74
+
75
+
## Architecture Note — Organization Axis (future cleanup, NOT urgent)
76
+
77
+
This library is intentionally organized **by concern** (`Control` / `JobControl` / `Info` / `Files` / `TempControl` / discovery / TCP), exposing a **single `FiveMClient` facade** — not by printer model the way FFUI splits into per-model backends (`AD5XBackend`, `Creator5Backend`, …). That asymmetry is **correct on purpose**: a transport library wins with one capability-based entry point; per-printer *client subclasses* would force a breaking API change and a migration across every consumer (FFUI, FFWebUI) to make the library *worse* to use. **Do not refactor this into per-printer clients.**
78
+
79
+
The one real smell is that model-specific job logic is accumulating inline in `JobControl.ts` (AD5X + Creator 5). If/when it gets unwieldy, the **non-breaking** fix is to extract per-model job modules *behind the same facade* (e.g. `api/controls/jobs/ad5x.ts`, `api/controls/jobs/creator5.ts`, composed by `JobControl`) — same for `MachineInfo.fromDetail` if model branching grows there. This is optional polish with zero consumer breakage; defer it until it actually hurts, and never bundle it with feature work.
0 commit comments