-
Notifications
You must be signed in to change notification settings - Fork 0
Hardware Reference
Facts about the Inova MK1 + SLS4All Compact firmware that were verified empirically (firmware audit, decompilation, build-40 telemetry) and are load-bearing for tooling decisions.
The printer exposes two parallel HTTP surfaces, both unauthenticated on this unit:
-
Port 5001 — our Inova API Plugin: live numeric telemetry (
/state/streamWS), positions, runtime overrides. - Port 80 — the firmware's own API: images and rich status the plugin deliberately doesn't proxy.
| Endpoint | Returns | Notes |
|---|---|---|
GET /api/status |
small JSON heartbeat | online, isPrinting flags (~225 B) |
GET /api/printingservice/status |
rich JSON heartbeat | Phase, Progress, Remaining, JobName, CpuTemp, SurfaceTarget (~566 B). The plugin can't serve this — IPrintingService lives in AppCore. |
GET /api/videocamera/image/{uuid} |
JPEG | chamber camera; {uuid} is an opaque cache-buster. Native ~20–22 fps. |
GET /api/videocamera/workingarea/{uuid} |
PNG | print-bed projection overlay (calibration views) |
GET /api/bedmatrix/image/{uuid} |
GIF | IR thermal heatmap, ~6 Hz native, ~51 KB/frame |
GET /api/plottedimage/{uuid} |
PNG | live galvo plot of the laser path on the current layer |
GET /api/plottedimage/{uuid}/{layerIndex} |
PNG | historical per-layer plot |
GET /api/slicingimage/{version}/{layerIndex} |
PNG | pre-print sliced layer preview |
Rule of thumb: images and rich status from :80; numeric telemetry from :5001.
Not exposed on either port: raw 1 kHz galvo positions (only the rasterized PNG + 10–100 Hz snapshots), raw thermal float matrix (only the rendered GIF), per-laser/heater PWM duty.
Decompiled from the deployed (obfuscated) firmware: with PowderBedDivision = "Thickness", RecoatPasses = N means fractional powder staging, not N full recoats:
- The powder piston feeds 1/N of the dose per pass (
GetZ1Pos(pass) = (pass+1) · z1Thickness / N). - Mid passes run with the print bed dropped extra (
MidRecoatThicknessFactorOverride = 2.0); only the final pass sweeps at true layer height and planes the surface. - Observed: pass i stops ~i/N across the bed, pauses ~1 s (recoater shake), continues.
This is why the MCP surface has two distinct mechanisms: recoater_passes_* (staged, firmware-native) and recoater_full_passes_* (plugin's FullRecoatLayerClient — genuine repeated full recoats). Never treat them as interchangeable.
- Z1/Z2 positions are in micrometers (z1 ≈ 33928, z2 = 29600 mid-print).
- Z1 decreases as powder feeds — piston rising = negative delta; z1 fell 42.5 mm → 33.8 mm over a print.
- Per-layer feed dose ≈ LayerThickness × (PrintChamberArea 31109 / PowderChamberArea 39074) × VolumeFactor ≈ 105.6 µm observed; the per-layer Z1 dance is −(dose+700)/+700 pairs (700 µm = ZMoveDefault clearance).
- Manual feed primitive:
IMovementClient.MoveAux(Z1, MoveAuxItem(-dose, Relative: true))— what the full-recoat powder feed uses. The firmware's powder-depth planner doesn't know about manual feeds, so the chamber runs down faster than it predicts.
- Profile names can lie — a "20mJ/mm" profile has been observed to contain 15. Always read the JSON field, never the name.
-
Profile thickness fields are micrometers, not mm:
layerThickness100,bedPreparationThickness13000,printCapThickness5000 (live-data confirmed 2026-07-18; the GUI mislabeled them mm for weeks and could never edit them). - One firmware PrintSession can span multiple recorder builds (restarts/false starts) — the registry maps them via
builds.inova_session_id. - Overrides land on the next layer — verify there, not on the current one. Layer time ≫ agent latency, which is exactly why agentic control fits AM's timescale.