1. Timelapse detection fixed - bambu_mqtt.py:1320-1329

- H2D sends timelapse status in ipcam.timelapse field, not xcam.timelapse
  - Added parsing for timelapse from ipcam data
  - Added test to prevent regression

  2. Systemd service updated - /etc/systemd/system/bambuddy.service
  - Now runs as claude user instead of root
  - Added ExecStartPre commands with + prefix (runs as root) to:
    - Create logs and archive directories if missing
    - Fix ownership to claude:claude before service starts

  The service restarted successfully with the permission fixes running at startup. On the next print with timelapse enabled, both the snapshot and timelapse should be captured automatically.
This commit is contained in:
maziggy
2025-12-13 10:59:58 +01:00
parent e85e5fa33e
commit 4b8e6ca797
2 changed files with 64 additions and 0 deletions
+12
View File
@@ -1317,6 +1317,18 @@ class BambuMQTTClient:
if isinstance(ipcam_data, dict):
# Check ipcam_record field for live view status
self.state.ipcam = ipcam_data.get("ipcam_record") == "enable"
# Check timelapse field (H2D sends it here, not in xcam)
if "timelapse" in ipcam_data:
timelapse_enabled = ipcam_data.get("timelapse") == "enable"
if timelapse_enabled != self.state.timelapse:
logger.info(
f"[{self.serial_number}] timelapse changed (from ipcam): {self.state.timelapse} -> {timelapse_enabled}"
)
self.state.timelapse = timelapse_enabled
# Track if timelapse was ever active during this print
if self.state.timelapse and self._was_running:
self._timelapse_during_print = True
logger.info(f"[{self.serial_number}] Timelapse detected during print (from ipcam)")
else:
self.state.ipcam = ipcam_data is True
@@ -282,6 +282,58 @@ class TestTimelapseTracking:
assert completion_data["status"] == "aborted"
assert "hms_errors" in completion_data
@pytest.mark.asyncio
async def test_timelapse_detected_from_ipcam_data(self):
"""Verify timelapse is detected from ipcam data (H2D sends it there, not xcam)."""
from backend.app.services.bambu_mqtt import BambuMQTTClient
client = BambuMQTTClient(
ip_address="192.168.1.100",
serial_number="TEST123",
access_code="12345678",
)
completion_data = {}
def on_complete(data):
completion_data.update(data)
client.on_print_start = lambda data: None
client.on_print_complete = on_complete
# Start print with timelapse in ipcam data (H2D format)
client._process_message(
{
"print": {
"gcode_state": "RUNNING",
"gcode_file": "/data/Metadata/test.gcode",
"subtask_name": "Test",
"ipcam": {
"ipcam_record": "enable",
"timelapse": "enable",
"resolution": "1080p",
},
}
}
)
assert client._timelapse_during_print is True, "Timelapse should be detected from ipcam data"
# Complete print
client._process_message(
{
"print": {
"gcode_state": "FINISH",
"gcode_file": "/data/Metadata/test.gcode",
"subtask_name": "Test",
}
}
)
assert (
completion_data["timelapse_was_active"] is True
), "timelapse_was_active should be True when timelapse was in ipcam"
class TestCallbackErrorHandling:
"""Test that callback errors are properly logged."""