Log home_flag changes on printers without cfg to check AMS Filament Backup in update frames (#3259)

This commit is contained in:
maziggy
2026-10-08 11:08:18 +02:00
parent 7d46baea65
commit 170335e8dc
2 changed files with 42 additions and 0 deletions
+21
View File
@@ -1494,6 +1494,8 @@ class BambuMQTTClient:
# True once the printer has sent `cfg`; from then on AMS Filament Backup
# is read from cfg only, never from home_flag (#3259).
self._backup_cfg_seen: bool = False
# Last home_flag written by the #3259 probe log below.
self._backup_home_flag_logged: int | None = None
# Track last requested tray ID for H2D dual-nozzle printers
# H2D only reports slot number (0-3) in tray_now, not global tray ID
@@ -2339,6 +2341,25 @@ class BambuMQTTClient:
new_backup = parse_ams_filament_backup_from_cfg(print_data["cfg"])
elif not self._backup_cfg_seen and len(print_data) > 30:
new_backup = parse_ams_filament_backup_from_home_flag(print_data.get("home_flag"))
# Probe for #3259: does bit 10 stay right in the small update
# frames these printers send between full reports? Logged on
# every change, so a heartbeat that clears bit 10 shows up as
# a flip. Remove once a P1S capture answers it.
home_flag = print_data.get("home_flag")
if (
not self._backup_cfg_seen
and isinstance(home_flag, int)
and not isinstance(home_flag, bool)
and home_flag != self._backup_home_flag_logged
):
self._backup_home_flag_logged = home_flag
logger.debug(
"[%s] home_flag probe: 0x%08X bit10=%d keys=%d",
self.serial_number,
home_flag & 0xFFFFFFFF,
(home_flag >> 10) & 1,
len(print_data),
)
if new_backup is not None and new_backup != self.state.ams_filament_backup:
hold_start = self._xcam_hold_start.get("print_option_auto_switch_filament")
if hold_start is not None and (time.time() - hold_start) <= self._xcam_hold_time:
@@ -7269,6 +7269,27 @@ class TestCommandAckIsNotTelemetry:
assert mqtt_client.state.ams_filament_backup is True
def test_home_flag_probe_logs_each_change_with_frame_size(self, mqtt_client, caplog):
"""#3259 probe: small frames are logged too, but only when home_flag changes."""
caplog.set_level(logging.DEBUG, logger="backend.app.services.bambu_mqtt")
mqtt_client._process_message(self._full_status(home_flag=7554719)) # bit10=1
mqtt_client._process_message({"print": {"command": "push_status", "home_flag": 7554719}})
mqtt_client._process_message({"print": {"command": "push_status", "home_flag": -1024}})
probes = [r.getMessage() for r in caplog.records if "home_flag probe" in r.getMessage()]
assert len(probes) == 2
assert "0x0073469F bit10=1 keys=32" in probes[0]
assert "0xFFFFFC00 bit10=1 keys=2" in probes[1]
def test_home_flag_probe_silent_once_printer_sent_cfg(self, mqtt_client, caplog):
caplog.set_level(logging.DEBUG, logger="backend.app.services.bambu_mqtt")
mqtt_client._process_message(self._full_status(cfg="C0340FC219"))
mqtt_client._process_message({"print": {"command": "push_status", "home_flag": 0}})
assert not [r for r in caplog.records if "home_flag probe" in r.getMessage()]
def test_project_file_ack_does_not_clear_timelapse_state(self, mqtt_client):
"""The ack echoes the per-job timelapse request, not the recorder."""
mqtt_client.state.timelapse = True