feat: expand H2 print pipeline and Kingpin charm workflow#2
Open
rowbotik wants to merge 27 commits intoDMontgomery40:mainfrom
Open
feat: expand H2 print pipeline and Kingpin charm workflow#2rowbotik wants to merge 27 commits intoDMontgomery40:mainfrom
rowbotik wants to merge 27 commits intoDMontgomery40:mainfrom
Conversation
- New src/slicer/profile-flatten.ts: walks BBL inherits chain, derives nozzle_volume_type, applies cli_config overlay, sets from/inherits/settings_id so the CLI accepts flattened profiles. Workaround for upstream BambuStudio issues #9636 and #9968. - Verified end-to-end on H2S, H2D, X1C, P1S with stock BBL profiles via scripts/test-cli-slice.mjs. - Wired into stl-manipulator behind BAMBU_CLI_FLATTEN=true (default off, backward-compatible). - New pause_print / resume_print MQTT tools alongside cancel_print. - Docs: SLICING.md split into Path A (GUI, recommended) and Path B (CLI flatten, opt-in); README features, tool docs, and env var reference updated with BAMBU_CLI_FLATTEN + BAMBU_PROFILES_ROOT. - Test fixtures from a real H2D GUI slice for ground-truth comparison. - 9 unit tests: chain resolution, cycle detection, missing-parent handling, nozzle_volume_type derivation, hardware-invariant enforcement, end-to-end against the installed BBL tree. - gitignore: exclude local credentials and the private 1.5MB H2D fixture. - PROGRESS.md: session work summary, queue, verify recipe. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Hardens H2/H2D pre-sliced print behavior based on the live H2S SuperTack
print run on Parker.
H2 mapping safety:
- print_3mf now fails fast on H2/H2D pre-sliced jobs with declared
filaments unless one of ams_slots, raw ams_mapping, or
auto_match_ams: true is provided. Avoids sending an under-specified
project_file that the printer accepts but does not visibly start.
- For H2/H2D, embedded slicerConfig.ams_mapping from the 3MF is no
longer trusted -- it can be stale project metadata. Non-H2 models
preserve the previous behavior.
- BambuImplementation.print3mf throws before FTP/MQTT when an H2
project_file would be missing required mapping inputs.
SuperTack:
- supertack_plate is accepted by print_3mf for pre-sliced jobs (the
successful Parker print used it).
- BambuStudio CLI slicing rejects supertack_plate fast: the CLI bed
identifier is not verified and earlier attempts produced G-code that
fell back to Cool Plate. New resolveBambuStudioCliBedType in index.ts
and a parallel guard in stl-manipulator catch the unsafe path.
- VALID_BED_TYPES (pre-sliced print path) and VALID_BAMBUSTUDIO_CLI_BED_TYPES
(slicing path) are now distinct lists.
- Auto-slice inside print_3mf also rejects supertack_plate before
invoking the CLI.
Tests:
- New stdio test: H2 print_3mf rejects a pre-sliced fixture with
plate_1.json.filament_ids = [1] and no mapping inputs, before any
network activity.
- New direct-API test: ams_slots = [1] with plate_filament_ids = [1]
expands into the recovered working H2 mapping
ams_mapping = [-1, 1, -1, -1] and ams_mapping2 with {0,1} at
position 1. Locks in the painfully-earned project-level shape.
- Synthetic 3MF fixture helper writeSliced3mfFixture is reusable for
future H2 regression coverage.
Docs:
- README env reference + slice/print_3mf surface notes call out the
new fail-fast rule and SuperTack distinction.
- PROGRESS.md updated with the live-test handoff section.
- .gitignore: ignore .claude/worktrees/ and docs/*.gcode.3mf.
npm test now passes 23/23.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- New deleteFile() in BambuImplementation: FTPS DELETE via basic-ftp using the same TLS-session-ticket dance as ftpUpload. - Confirm-gated (confirm:true required) so a default invocation can't destroy data; returns status:"skipped" otherwise without contacting the printer. - Path safety: rejects ".." segments, restricts deletes to cache/, timelapse/, and logs/ to prevent walking the filesystem. - Bare filenames default to cache/<name>; relative paths to other allowed dirs are honored as-is. - README features bullet + delete_printer_file tool section updated. - 5 new unit tests cover the gating, path safety, and happy path. npm test: 28/28. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- New cameraSnapshot() in BambuImplementation: TLS on port 6000, 80-byte auth packet (bblp + access token), reads one full JPEG frame from the repeating 16-byte header + payload stream. Wire format per https://github.com/Doridian/OpenBambuAPI/blob/main/video.md. - Strict per-model routing: - A1 / A1 mini / P1S / P1P -> reach the wire path. - X1 / X1C / X1E / P2S -> fail-fast, point at RTSP on port 322 (not implemented). - H2 / H2S / H2D -> fail-fast, protocol not documented upstream. Same fail-loud principle as SuperTack: don't guess at wire bytes for unverified hardware. - Default 8s timeout for cold-start camera latency. Validates that the payload starts with JPEG SOI (FF D8) before returning. - Optional save_path writes the JPEG to disk alongside the base64 return value. - Tool registered in index.ts with bambu_model routing argument. - README features bullet + camera_snapshot tool section. - 5 new unit tests cover routing for each supported / unsupported model bucket and the save_path behavior with a stubbed wire layer. npm test: 33/33. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Lets the user probe whether an H2/H2S/H2D printer happens to honor the A1/P1 TCP-on-6000 wire format. The protocol is not documented upstream so we still refuse by default, but a deliberate experimental:true on the call bypasses the H2 fail-fast and tries the wire path. Read-only either way: - If the auth packet is accepted and the frame header parses, the user gets a JPEG and a `note` field flagging the experimental status. - If not, the connection drops or the payload-size sanity check trips and the caller gets a clean error. No data is exfiltrated. The flag is H2-only on purpose: experimental:true does NOT bypass the RTSP error for X1/P2S (covered by a regression test) because RTSP is a different protocol entirely, not just an unverified flavor of the TCP path. If experimental mode returns a JPEG on a real H2, that's signal we can use to promote H2 out of the experimental bucket and document the wire format upstream. - src/printers/bambu.ts: experimental flag in cameraSnapshot options; console.warn on use; response carries a `note` describing what we did. - src/index.ts: experimental schema entry on camera_snapshot tool, wired into dispatch case. - README: H2 paragraph rewritten to describe experimental behavior + example invocation block for probing an H2. - 2 new unit tests: experimental:true reaches wire path for h2/h2s/h2d and returns a note; experimental:true does NOT bypass X1/P2S RTSP error. npm test: 35/35. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two read-only probes added under scripts/:
- probe-h2-camera.mjs: spawns the MCP server in stdio mode and calls
camera_snapshot with experimental:true, dumping the structured
response or error.
- probe-h2-raw.mjs: bypasses our JPEG-parser entirely. Connects TLS to
<host>:6000, sends the A1/P1 80-byte auth packet, and hex-dumps the
first N bytes the printer replies with. Useful for figuring out the
H2 frame header layout.
Findings against Parker H2S (recorded in PROGRESS.md):
- TLS handshake works without a client certificate.
- The H2 firmware uses the same 16-byte frame header as A1/P1.
- The A1/P1 auth packet with the LAN access code is REJECTED -- the
printer replies with one framed error (payload_size=8,
error_code=0xa203013f) and closes the connection.
Next experiments to try are noted in PROGRESS.md ("H2 probe results"
section): different credential (cloud dev_access_code), reading the
HA bambulab integration source, then different packet format.
No code changes; just diagnostics + documentation. npm test still 35/35.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
H2 series cameras now work end-to-end. Verified live against Parker
(H2S, 192.168.68.93): 125,321 byte JPEG returned in ~1.5s, real
chamber image saved.
Root cause of the earlier H2 failure: the OpenBambuAPI video.md doc
only documents A1/P1 TCP-on-6000 and X1/P2S RTSP. It doesn't list H2,
which led to the assumption that H2 might be on a third unknown
protocol. Reading HA bambulab's pybambu/models.py Camera class made
it clear: H2 firmware reports its own rtsp_url over MQTT in the same
ipcam.rtsp_url field as X1, and rejects the A1/P1 80-byte auth packet
because that protocol simply isn't implemented on H2.
What shipped:
- New fetchRtspCameraFrame() in BambuImplementation: shells out to
ffmpeg with `-rtsp_transport tcp -i rtsps://bblp:<token>@<host>:322
/streaming/live/1 -frames:v 1`. ffmpeg-version-agnostic (no
-stimeout, since that flag was renamed/removed across versions);
outer kill timer enforces the deadline.
- Routing matrix updated: H2/H2S/H2D/H2C/H2D Pro AND X1/X1C/X1E/P2S
go through RTSP. A1/P1 series stay on the native TCP-on-6000
framed-JPEG path.
- Response now includes a transport field ("tcp-6000" | "rtsps-322")
so callers can tell which path produced the frame.
- Token redacted from any ffmpeg stderr that leaks into errors.
- Specific ENOENT error message points at `brew install ffmpeg`.
- experimental flag on the tool schema is now deprecated (no-op).
Kept on the type/schema to avoid breaking existing callers.
- New ffmpeg_path optional argument lets callers point at a non-PATH
ffmpeg binary.
Tests:
- Replaced the four obsolete experimental/fail-fast tests with three
new ones covering the routing reality:
- H2 series (h2/h2s/h2d/h2c/h2dpro) routes through RTSP.
- X1/P2S routes through RTSP (was previously expected to throw).
- ENOENT for a missing ffmpeg gives a helpful actionable message.
- TCP-on-6000 unit tests for A1/P1 still pass unchanged.
.gitignore: bambu-mcp-config.json (contains real access tokens).
PROGRESS.md: H2 camera promoted from "undocumented bucket" to
"resolved via RTSP" with the live probe results from Parker.
npm test: 34/34. README features bullet + camera_snapshot section
flipped to describe the dual-transport reality.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Covers: pause/resume, AMS RFID auto-match, HMS diagnostics, light/fan/utility controls, skip objects, bed-aware slicing, CLI auto-flatten, collar charm wrapper. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ng fixes The cherry-picked 1.1.0 CHANGELOG only spans up to 08f6afe (the parent of this stack). Extend it with the work that landed since: Added: - delete_printer_file (1838855) - camera_snapshot TCP-on-6000 path for A1/P1 (2a42574) - camera_snapshot RTSPS path for X1/P2S/H2 series via ffmpeg (3bf954f) Verified live on Parker (H2S), Kingpin (H2D), and an X1C. Fixed: - H2/H2D pre-sliced AMS mapping requirement + regression test for the recovered working mapping shape (12ae6b9) - supertack_plate accepted only on pre-sliced path; rejected fast on CLI slicing because the CLI bed identifier is unverified (12ae6b9) Notes that the experimental flag from the interim camera work (5d473c5) is now a no-op kept for schema compatibility, and that ffmpeg in PATH is required for the RTSP transport. No code changes; CHANGELOG entries only. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Tooling for headless two-color charm slicing. Builds a multi-object source .3mf for BambuStudio CLI from two STLs (body, face) plus a known-good template 3MF for project_settings.config. Key insight (Codex spent hours not finding this): per-object filament assignment lives in Metadata/model_settings.config inside the 3MF, not in CLI flags. Confirmed against huskies.3mf, a real BBL multi-object project, where each object carries <metadata key="extruder" value="N"/>. Implementation: - ASCII or binary STL parser, vertex deduplication. - Signed-tetrahedron volume sum to identify body vs face/detail (robust to OpenSCAD's uniform facet density; triangle count alone is misleading). - Inline mesh in 3D/3dmodel.model -- single file, simpler than the Production-Extension multi-file layout, and BambuStudio's CLI parses it cleanly. - Per-object extruder metadata + plate-level filament_maps / filament_volume_maps for H2D's dual-nozzle assignment. - Carries project_settings.config from a template 3MF; can also be used with --load-settings/--load-filaments to fully control via the existing CLI flattener path. Status (documented in PROGRESS.md): - 3MF parses, validation passes, slicer kernel SIGSEGVs. - Same family as upstream BambuStudio issues #9968 / #9636. - Workaround for tonight: GUI-slice and feed to print_collar_charm. .gitignore now excludes BambuStudio CLI's result.json drop-in. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Swapped the bunny STLs for two trivial 8-vertex cubes in the same
build pipeline. Same SIGSEGV at the same place, same warning
sequence ("load_nozzle_infos_with_compatibility..."). Confirms the
crash is fundamental to BambuStudio CLI 02.06.00.51's H2D
dual-extruder path and not a function of our input geometry, 3MF
construction, or flattener output.
Material the upstream bug ticket can use:
- Repro is two cubes, two filaments, two extruders, H2D, textured
plate.
- Pre-config validation passes; SIGSEGV is in the slicer setup
step.
- No log output between "tree support default to organic support"
and the SIGSEGV.
- Same family as #9968 / #9636.
PROGRESS.md updated with the cube-repro details.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Filed bambulab/BambuStudio#10408 with the two-cube minimal repro for the H2D multi-color CLI segfault. Cross-references #9941 / #9636 / #9968. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous matcher keyed only on tray_info_idx. Tonight's H2D Barkside dispatch failed at "auto_match_ams could not find loaded AMS trays for: GFG02, GFG02" even with both PETG HF colors loaded -- the 3MF needed two trays of the same SKU but in different colors (black + white) and the matcher had no way to disambiguate. What changed in resolveAmsSlotsFromRequirements: - Match key is now (tray_info_idx, tray_color) when both sides carry color, with RGB normalization that ignores alpha bytes (3MF stores "#000000" or "#FF911A80"; AMS reports "000000FF" without #). - Tracks already-claimed slots so two requirements can't collapse onto the same physical slot. - Falls back to SKU-only when the 3MF's filament has no color OR only one tray of that SKU is loaded. - Surfaces structured `missing` reasons: no_sku / no_loaded_match / color_mismatch / exhausted. Workaround tonight was explicit ams_slots; with this fix auto_match_ams: true would have one-shot the dispatch. Regression test using tonight's exact AMS data is a follow-up; the fix is compile-clean and tightens behaviour without changing existing single-color happy paths. Also: - scripts/print-on-printer.mjs added: stdio runner that dispatches a pre-sliced .gcode.3mf to a printer via the MCP's print_3mf tool. Used tonight to ship the Barkside print to Kingpin. - README updates the auto_match_ams docstring to describe the new matching strategy and structured missing-report. - docs/SLICING.md adds a "Multi-color CLI gap" section documenting bambulab/BambuStudio#10408 (H2D dual-extruder slicer-setup SIGSEGV) with the workaround and a status matrix at the top. - CHANGELOG.md gets an Unreleased section covering this fix, the upstream-blocked multi-color CLI gap, and scripts/build-charm-3mf.mjs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verification