[PR #1202] [MERGED] feat(vp): mirror live target printer state to slicer in non-proxy modes #1172

Closed
opened 2026-05-06 12:35:29 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/maziggy/bambuddy/pull/1202
Author: @maziggy
Created: 5/3/2026
Status: Merged
Merged: 5/3/2026
Merged by: @maziggy

Base: devHead: feature/vp_non_proxy_refactor


📝 Commits (1)

  • 7dea33d feat(vp): mirror live target printer state to slicer in non-proxy modes

📊 Changes

9 files changed (+1175 additions, -16 deletions)

View changed files

📝 CHANGELOG.md (+1 -0)
📝 README.md (+2 -1)
📝 backend/app/main.py (+1 -0)
📝 backend/app/services/bambu_mqtt.py (+46 -0)
📝 backend/app/services/virtual_printer/manager.py (+68 -1)
backend/app/services/virtual_printer/mqtt_bridge.py (+334 -0)
📝 backend/app/services/virtual_printer/mqtt_server.py (+126 -11)
backend/tests/unit/test_vp_mqtt_bridge.py (+592 -0)
📝 docker-compose.yml (+5 -3)

📄 Description

feat(vp): mirror live target printer state to slicer in non-proxy modes

In non-proxy VP modes (Immediate / Review / Print Queue), the slicer now
sees real AMS / FTS / nozzle / k-profile state from the target printer
and streams the live camera — full slicer-as-remote functionality without
giving up Bambuddy's queue / archive / dispatch features.

Architecture (cached-as-base, single source of truth). The bridge caches
the latest real push_status and info.get_version response from Bambuddy's
existing per-printer MQTT subscription — no second session on the printer,
firmware in-flight budget unaffected (#1164). _send_status_report serves
a near-byte-identical copy of the cached push with only the upload-state-
machine fields overridden. Command responses (extrusion_cali_get, AMS
write acks, xcam) fan out raw — they carry sequence_ids the slicer is
waiting on. Slicer-issued commands forward to the printer except
project_file / gcode_file, which still terminate locally because the file
lives on Bambuddy. Camera is a raw TCPProxy on bind_ip:322 → printer:322,
same approach proxy mode uses.

Field-shape gotchas pinned in the bridge module's docstring and the
new test file:

  • Real Bambu pushes use json.dumps(indent=4) wire format. Compact JSON
    fails BambuStudio's Send pre-flight silently.
  • net.info[*].ip is the FTP destination IP (little-endian uint32).
    Without rewriting to the VP bind IP, the slicer FTPs straight to
    the real printer.
  • upgrade_state.sn rewritten to VP serial; AMS-hardware sn fields
    (n3f/0.sn etc.) left alone.
  • ipcam.rtsp_url passes through unchanged; BambuStudio overrides the
    URL host with the device IP it bound on, so :322 lands on the VP's
    TCPProxy.
  • extrusion_cali_get must forward; answering it locally hides the
    user's stored per-filament k-profiles.

Setup nuance for camera: the VP's access code must match the target
printer's because the slicer authenticates RTSPS with whatever access
code is in its profile. MQTT and FTP work either way.

Tested e2e with BambuStudio and OrcaSlicer against H2D (dual-nozzle,
AMS 2 Pro + AMS HT) and X1C across all three non-proxy modes — sync,
send, k-profile lookup, AMS configuration from slicer, and live camera
all work. Proxy mode is untouched: SlicerProxyManager owns its own
proxies and never instantiates SimpleMQTTServer or MQTTBridge.

25 new tests in backend/tests/unit/test_vp_mqtt_bridge.py cover lifecycle,
caching, identity / IP rewriting, wire format, slicer→printer routing,
and the LE-uint32 IP encoder against the real H2D capture value.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/maziggy/bambuddy/pull/1202 **Author:** [@maziggy](https://github.com/maziggy) **Created:** 5/3/2026 **Status:** ✅ Merged **Merged:** 5/3/2026 **Merged by:** [@maziggy](https://github.com/maziggy) **Base:** `dev` ← **Head:** `feature/vp_non_proxy_refactor` --- ### 📝 Commits (1) - [`7dea33d`](https://github.com/maziggy/bambuddy/commit/7dea33d0d81cac5c6cef85d77e91935eab401d2e) feat(vp): mirror live target printer state to slicer in non-proxy modes ### 📊 Changes **9 files changed** (+1175 additions, -16 deletions) <details> <summary>View changed files</summary> 📝 `CHANGELOG.md` (+1 -0) 📝 `README.md` (+2 -1) 📝 `backend/app/main.py` (+1 -0) 📝 `backend/app/services/bambu_mqtt.py` (+46 -0) 📝 `backend/app/services/virtual_printer/manager.py` (+68 -1) ➕ `backend/app/services/virtual_printer/mqtt_bridge.py` (+334 -0) 📝 `backend/app/services/virtual_printer/mqtt_server.py` (+126 -11) ➕ `backend/tests/unit/test_vp_mqtt_bridge.py` (+592 -0) 📝 `docker-compose.yml` (+5 -3) </details> ### 📄 Description feat(vp): mirror live target printer state to slicer in non-proxy modes In non-proxy VP modes (Immediate / Review / Print Queue), the slicer now sees real AMS / FTS / nozzle / k-profile state from the target printer and streams the live camera — full slicer-as-remote functionality without giving up Bambuddy's queue / archive / dispatch features. Architecture (cached-as-base, single source of truth). The bridge caches the latest real push_status and info.get_version response from Bambuddy's existing per-printer MQTT subscription — no second session on the printer, firmware in-flight budget unaffected (#1164). _send_status_report serves a near-byte-identical copy of the cached push with only the upload-state- machine fields overridden. Command responses (extrusion_cali_get, AMS write acks, xcam) fan out raw — they carry sequence_ids the slicer is waiting on. Slicer-issued commands forward to the printer except project_file / gcode_file, which still terminate locally because the file lives on Bambuddy. Camera is a raw TCPProxy on bind_ip:322 → printer:322, same approach proxy mode uses. Field-shape gotchas pinned in the bridge module's docstring and the new test file: - Real Bambu pushes use json.dumps(indent=4) wire format. Compact JSON fails BambuStudio's Send pre-flight silently. - net.info[*].ip is the FTP destination IP (little-endian uint32). Without rewriting to the VP bind IP, the slicer FTPs straight to the real printer. - upgrade_state.sn rewritten to VP serial; AMS-hardware sn fields (n3f/0.sn etc.) left alone. - ipcam.rtsp_url passes through unchanged; BambuStudio overrides the URL host with the device IP it bound on, so :322 lands on the VP's TCPProxy. - extrusion_cali_get must forward; answering it locally hides the user's stored per-filament k-profiles. Setup nuance for camera: the VP's access code must match the target printer's because the slicer authenticates RTSPS with whatever access code is in its profile. MQTT and FTP work either way. Tested e2e with BambuStudio and OrcaSlicer against H2D (dual-nozzle, AMS 2 Pro + AMS HT) and X1C across all three non-proxy modes — sync, send, k-profile lookup, AMS configuration from slicer, and live camera all work. Proxy mode is untouched: SlicerProxyManager owns its own proxies and never instantiates SimpleMQTTServer or MQTTBridge. 25 new tests in backend/tests/unit/test_vp_mqtt_bridge.py cover lifecycle, caching, identity / IP rewriting, wire format, slicer→printer routing, and the LE-uint32 IP encoder against the real H2D capture value. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 12:35:29 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/bambuddy#1172
No description provided.