Skip to content

Happy Hare and AFC slot reading for the Moonraker send dialog - #612

Draft
aceRage wants to merge 8 commits into
mainfrom
cursor/klipper-mmu-slots-f5f8
Draft

aceRage wants to merge 8 commits into
mainfrom
cursor/klipper-mmu-slots-f5f8

Conversation

@aceRage

@aceRage aceRage commented Oct 18, 2026 •

Copy link
Copy Markdown
Owner

Description

Depends on #625 (merge #625 first).

#625 adoption: the shared map panel is used only for Happy Hare, AFC/BoxTurtle, and QIDI Box hosts — not Snapmaker/U1. Gates/lanes/Box slots group as 1A–1D with colour and type. Sent data is unchanged (Slot::index, QIDI SAVE_VARIABLE value_tN / filament_mapping()).

Klipper printers with Happy Hare or AFC/BoxTurtle can now populate the existing print-host send-dialog mapping table. Port of the parsing only from upstream OrcaSlicer src/slic3r/Utils/MoonrakerPrinterAgent.cpp into this fork's PrintHostDeviceStatus probe. The IPrinterAgent / printer_agent framework is not ported (research X1: keep EdgeSlicer's probe + send dialog; #610/#611 already extend that for QIDI).

This is S2 from the vendor-send-gaps research. Independent of the native Moonraker host PR — Sovol profiles stay on octoprint, which already probes as Moonraker. Based on main, not stacked.

Review follow-ups (Russ 1/3)

  • F1 Add-on mmu / lane_data GETs use a 1 s timeout. probe() is called from the send dialog on the UI thread; the first query still uses the caller's timeout (3 s).
  • F2 Extras are skipped when multi_color_controller.box_count > 0 (asked on the first query, same object QIDI Box: send the filament-to-slot mapping before starting a print #610 adds). Comment at the merge point for Status::qidi_box. Happy Hare/AFC indices cannot go out as QIDI SAVE_VARIABLE value_tN.
  • F3 AFC lanes: index range [0, 32), de-duplication (first wins), cap 32.
  • F4 num_gates > 32 is clamped, not dropped. CSS colour names map to hex (red → #FF0000).
  • F5 Header no longer claims probe is off the GUI thread.
  • Catch2: wrong-type fields, huge gate_status arrays, num_gates>32, QIDI Box vs HH, AFC dupes/out-of-range/40 lanes.

Re-review follow-up (Russ re-review 1/3)

  • F6 Unparsable CSS names no longer go into Slot.color. That field stays #RRGGBB or empty so auto-match cannot treat chartreuse as a colour. Known names still map to hex; unknown ones are kept in Slot.color_name and appended to the dropdown label. print_host_slot_colour() is the GUI-free mapper used by Catch2.

Upstream source

  • MoonrakerPrinterAgent::fetch_hh_filament_info — GET /printer/objects/query?mmu (num_gates, gate_status, gate_material, gate_color).
  • MoonrakerPrinterAgent::fetch_moonraker_filament_data — GET /server/database/item?namespace=lane_data (per-lane lane / material / color).
  • scripts/test_moonraker_lane_data.py for the AFC JSON shape.

What was adapted

  • Parsers live next to slots_from_print_task_config / slots_from_extruders and fill the same Slot list the send dialog already draws.
  • Priority: Snapmaker print_task_config first, then Happy Hare mmu (not if a QIDI Box is present), then AFC lane_data, then bare extruderN tools. Empty gates/lanes stay in the list so the unit is visible; only a loaded gate/lane with a type or colour (or a readable unmapped name) sets slots_have_filaments.
  • Probe networking: first query is print_stats&print_task_config&multi_color_controller&extruder… (the QIDI object QIDI Box: send the filament-to-slot mapping before starting a print #610 also asks for). Happy Hare and AFC are extra 1 s GETs, only when that first answer named no filaments and is not a QIDI Box. A 404/timeout on the extras does not fail a probe that already got print_stats. X-Api-Key is sent when the device has an API key.
  • Network-free entry points for Catch2: parse_happy_hare_mmu and parse_afc_lane_data (full HTTP body or the inner object). parse_moonraker_status also accepts mmu inside a status snapshot.
  • Catch2 v2 tests appended to tests/slic3rutils/printhost_devices_tests.cpp. No CMake test edits. No G-code changes. No new enum values. No filament_is_mixed.

Mapping at start — not sent

Upstream MoonrakerPrinterAgent::start_print is a stub (return BAMBU_NETWORK_SUCCESS) and start_local_print only uploads. There is no Happy Hare T / MMU_CHANGE_TOOL or AFC lane mapping in the start path. This PR is read-only display + the dialog's existing auto-match.

Material-first auto-match (research X3) is the change in #610, not duplicated here, so the two PRs do not edit the same send-dialog loop. On main today the table still auto-matches by colour among loaded slots that have a colour; once #610 lands, material-first applies to these HH/AFC slots too.

Tests

Inline JSON fixtures:

  • Happy Hare: four gates (loaded / loaded / empty / unknown), 0x colour prefix, named colours, unparsable names (chartreuse → empty colour + color_name), status-object form, empty mmu, Snapmaker print_task_config winning over mmu, clamp num_gates>32, wrong-type fields, huge arrays, QIDI Box suppressing HH. Tile grouping 1A–1D from index/4 and index%4; Slot::label() stays T1 PLA.
  • AFC: lane_data value object sorted by tool number, empty lane with #None, lanes array form, garbage JSON, duplicate/out-of-range indices, 40-lane cap, unmapped colour name, 1A/1B grouping.
  • QIDI Box: 1A–1D grouping; label() stays Box 1 slot 2 ASA.
  • print_host_slot_colour("red") == "#FF0000", print_host_slot_colour("chartreuse").empty().

This VM has no EdgeSlicer deps prefix, so slic3rutils_tests was not compiled here. Wx-free ThirdPartyFilamentMap.cpp compiled.

Untested (no hardware)

Live probe against Happy Hare or AFC, and the send-dialog table on a real printer.

Smoke checklist

  1. Stock Klipper, no MMU — still a tool list (or Snapmaker filaments) as today; extra mmu / lane_data GETs 404/empty and are ignored (1 s each).
  2. Happy Hare: Fluidd/Mainsail mmu object with loaded gates → send dialog mapping table shows Bambu-style 1A–1D tiles with colour/type. Empty gates show as empty. Named colours (red) show as a swatch. An unknown name does not auto-match by colour. Auto-match picks a loaded gate with a #RRGGBB colour (material-first once QIDI Box: send the filament-to-slot mapping before starting a print #610 is in).
  3. AFC / BoxTurtle: lane_data with lane / material / color → table shows those tools. Empty material → unloaded.
  4. Snapmaker with print_task_config — still that list, not the shared panel.
  5. QIDI Box (multi_color_controller, box_count>0) — HH/AFC extras are not asked; Box uses the shared panel.
  6. API key set — extras send X-Api-Key.
  7. Confirm Upload and Print does not send any MMU_* / AFC mapping commands (no upstream precedent). Switching devices in the send dialog should not stall ~9 s.

Screenshots/Recordings/Graphs

None — uses the existing mapping table; no new chrome.

Open in Web Open in Cursor 

cursoragent and others added 3 commits October 18, 2026 22:26
Port the parsing from upstream MoonrakerPrinterAgent (mmu gates/materials/colors
and lane_data lanes) into PrintHostDeviceStatus so the send-dialog mapping table
can show those slots. Extra GETs run only when print_task_config named nothing,
and the first objects/query string is left unchanged for PRs #610/#611.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
Add-on mmu/lane_data GETs use a 1 s timeout because probe() runs on the UI
thread. Skip them when multi_color_controller reports a QIDI Box so those
indices cannot become SAVE_VARIABLE value_tN once #610 lands. Clamp
num_gates above 32, cap/dedupe AFC lanes, map CSS colour names, and cover
wrong-type fields and huge arrays in Catch2.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
Slot.color stays '#RRGGBB' or empty so auto-match cannot treat a raw
name as a colour. Known names still map to hex; unknown ones are kept
in Slot.color_name and the dropdown label.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
Elegoo CC upload now uses MaterialItem colour cards and a MappingItem
slot popup instead of a text combo, while the start-print slot_map is
unchanged. Other hosts keep the existing rows; Bambu and Snapmaker
are not switched over.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
cursoragent and others added 3 commits October 19, 2026 13:26
Call the panel's DPI/theme handlers from the send dialog, use dark-mode colours only on the new badge and panel paths, add the panel to gettext, label Elegoo warnings with the same 1A-1D tiles, shrink the badge so long types still fit, number unit-less slots 1..N, and keep read-only auto-match visual while encoding an empty mapping.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
update_mapping_note combines mapping_warning() and third_party_mismatch_warning(). Read-only mismatch compares T-number identity, not the visual auto-match. The nozzle badge pill follows Body_10 extent so labels like 10 fit.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
…er-mmu-slots-f5f8

Adopt the shared Bambu-style filament map panel for Happy Hare, AFC, and
QIDI Box hosts only (not Snapmaker/U1). Gates/lanes/Box slots group as
1A-1D with colour and type; Slot::index and the sent mapping stay the
same.

Conflicts in PrintHostDeviceStatus kept both the Happy Hare/AFC parsers
and the QIDI Box helpers from #625.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
cursor Bot pushed a commit that referenced this pull request Oct 19, 2026
Russ #622 B1: skip M106/M107 (including P-indexed) between '; custom gcode end'
and T so real tool changes still count after CoolingBuffer replaces
;_FORCE_RESUME_FAN_SPEED. Start G-code T, M104 T3, and T0 reset stay excluded.
F1: apply the Slot.name tile label only on direct_rack so #612's 1A-1D grouping
is not overridden.

Co-authored-by: aceRage <aceRage@users.noreply.github.com>
The truncation case built gate_status as [1] plus two hundred zeros, so
gate 1 was empty and leftover names stayed off the slot. Pad after two
loaded gates so extra statuses cannot drop gate_material at the same index.

Deft

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants