fix(logs): demote benign "not connected" + "may linger" warnings

Two warnings polluting every A1 support bundle on healthy prints, both
  unrelated to the timelapse-default behaviour the issue actually reports.

  1. mqtt_bridge.py's post-bind nudge calls request_status_update on the
     real printer's MQTT client to populate the bridge cache without
     waiting for the next periodic pushall. The bind frequently races the
     TLS handshake, especially on A1 firmware. Skip the nudge when
     state.connected is False — the periodic pushall fills the cache
     anyway. The WARNING in bambu_mqtt.py stays for the genuinely-
     actionable callers (refresh-status API, bug reporter).

  2. Post-finish SD-card cleanup (and the symmetric forced-timelapse dir
     walk) used delete_file_async's bool return to drive a WARNING when
     all candidates failed. A1 firmware self-cleans the SD card before
     our cleanup runs — every candidate FTP-DELE returns 550, we burn
     the retry budget, then WARN on a successful print. Introduce
     DeleteResult.{DELETED,NOT_FOUND,FAILED} so the helpers only WARN
     on real network/auth/transient failures. NOT_FOUND advances to the
     next candidate without consuming the 2s backoff. User-facing delete
     endpoint returns 404 on NOT_FOUND.
This commit is contained in:
maziggy
2026-06-12 15:13:40 +02:00
parent 1bcd5c8ba5
commit 7190fc2d13
8 changed files with 286 additions and 53 deletions
@@ -371,18 +371,38 @@ class MQTTBridge:
# but that fires before the bridge attaches as a raw-message consumer,
# so without this nudge the cache stays empty until the next periodic
# query (which can be minutes away).
request_fn = getattr(current, "_request_version", None)
if callable(request_fn):
try:
request_fn()
except Exception:
logger.exception("[%s] MQTT bridge: _request_version failed", self.vp_name)
request_status_fn = getattr(current, "request_status_update", None)
if callable(request_status_fn):
try:
request_status_fn()
except Exception:
logger.exception("[%s] MQTT bridge: request_status_update failed", self.vp_name)
#
# The bind frequently races the real printer's MQTT TLS handshake — a
# slicer-side reconnect re-resolves the client before the underlying
# session has reconnected, especially on A1 firmware where the bridge
# cycles more aggressively (#1721). When that happens, the nudge is a
# no-op — the next periodic pushall populates the cache anyway — but
# `request_status_update` logs WARNING on the not-connected return path
# and pollutes every support bundle with a benign line.
#
# Gate both nudges on the client being actually connected. The fall-
# through path is unchanged: when the client comes up, the next
# `_resolve_client` tick re-enters this branch on identity change OR
# the periodic pushall in `bambu_mqtt.py` fills the cache.
client_connected = bool(getattr(getattr(current, "state", None), "connected", False))
if not client_connected:
logger.debug(
"[%s] MQTT bridge: post-bind nudge skipped (printer client not connected yet)",
self.vp_name,
)
else:
request_fn = getattr(current, "_request_version", None)
if callable(request_fn):
try:
request_fn()
except Exception:
logger.exception("[%s] MQTT bridge: _request_version failed", self.vp_name)
request_status_fn = getattr(current, "request_status_update", None)
if callable(request_status_fn):
try:
request_status_fn()
except Exception:
logger.exception("[%s] MQTT bridge: request_status_update failed", self.vp_name)
def _unbind_client(self) -> None:
if self._target_client is None: