Browse Source

Fix spurious 0300_0002 error notification via HMS array path (#583)

  The previous fix only filtered status codes (< 0x4000) from the
  print_error field. Firmware can also send the same false positive
  through the hms array in MQTT, which had no such filter. Apply the
  same < 0x4000 check to the HMS parser so status/phase indicators
  are skipped regardless of which MQTT field carries them.
maziggy 2 months ago
parent
commit
acae51b938

+ 1 - 1
CHANGELOG.md

@@ -23,7 +23,7 @@ All notable changes to Bambuddy will be documented in this file.
 ### Fixed
 - **Archive Card Shows "Source" Badge for Sliced .3mf Files** — Archive cards created from prints showed a "SOURCE" badge instead of "GCODE" when the filename was a plain `.3mf` (without `.gcode` in the name). The `isSlicedFile()` check only matched `.gcode` or `.gcode.3mf` extensions, but `.3mf` files can be either sliced (contains gcode) or raw source models. Now checks the archive's `total_layers` and `print_time_seconds` metadata — if either is present, the file is sliced. Also passes the original human-readable filename when creating archives from the file manager print flow (previously stored the UUID library filename).
 - **AMS Slot Shows Wrong Material for "Support for" Profiles** — Configuring an AMS slot with a filament profile like "PLA Support for PETG PETG Basic @Bambu Lab H2D 0.4 nozzle" set the slot material to PLA instead of PETG. The name parser iterated material types in order and returned the first match ("PLA"), ignoring that "PLA Support for PETG" means the filament type is PETG. Both the frontend `parsePresetName()` and backend `_parse_material_from_name()` now detect the "X Support for Y" naming pattern and extract the material after "Support for". The frontend also prefers the corrected parsed material over the stored `filament_type` (which may have been saved with the old parser during import).
-- **Spurious Error Notifications During Normal Printing (0300_0002)** — Some firmware versions send non-zero `print_error` values in MQTT during normal printing (e.g., `0x03000002` → short code `0300_0002`). The `print_error` parser treated any non-zero value as a real error, appending it to `hms_errors` and triggering notifications — even though the printer was printing fine. All known real HMS error codes have their low 16 bits >= `0x4000` (`0x4xxx` = fatal, `0x8xxx` = warning/pause, `0xCxxx` = prompt). Values below `0x4000` are status/phase indicators, not faults. Now skips `print_error` values where the error portion is below `0x4000`.
+- **Spurious Error Notifications During Normal Printing (0300_0002)** — Some firmware versions send non-zero `print_error` values in MQTT during normal printing (e.g., `0x03000002` → short code `0300_0002`). The `print_error` parser treated any non-zero value as a real error, appending it to `hms_errors` and triggering notifications — even though the printer was printing fine. All known real HMS error codes have their low 16 bits >= `0x4000` (`0x4xxx` = fatal, `0x8xxx` = warning/pause, `0xCxxx` = prompt). Values below `0x4000` are status/phase indicators, not faults. Now skips values where the error portion is below `0x4000` in both the `print_error` and `hms` array parsers.
 - **K-Profile Apply Fails With Greenlet Error on Auto-Created Spools** — When a Bambu Lab spool was detected via RFID for the first time (auto-creating a new inventory entry), the K-profile application step logged `WARNING greenlet_spawn has not been called; can't call await_only() here`. The `create_spool_from_tray()` function flushed the new spool to the database but didn't eagerly load the `k_profiles` relationship. When `auto_assign_spool()` then iterated `spool.k_profiles` to find a matching K-profile, SQLAlchemy attempted a lazy load — which requires a synchronous DB call that's illegal inside an async context. The K-profile step was silently skipped (caught by `except Exception`), so spool assignment still worked but without K-profile selection. Now eagerly sets `k_profiles = []` on newly created spools since they can never have K-profiles yet.
 - **SpoolBuddy Link Tag Missing tag_type** — Linking an NFC tag to a spool via the SpoolBuddy dashboard's "Link to Spool" action only set `tag_uid` but left `tag_type` and `data_origin` empty, because it called the generic `updateSpool` API instead of the dedicated `linkTagToSpool` endpoint. The printer card's `LinkSpoolModal` already used `linkTagToSpool` correctly. Now uses `linkTagToSpool` with `tag_type: 'generic'` and `data_origin: 'nfc_link'`, which also handles conflict checks and archived tag recycling.
 - **SpoolBuddy AMS Page Missing Fill Levels for Non-BL Spools** — AMS slots with non-Bambu Lab spools assigned to inventory didn't show fill level bars on the SpoolBuddy AMS page, even though the main printer card displayed them correctly. The SpoolBuddy AMS page only used the MQTT `remain` field (which is -1/unknown for non-BL spools), while the printer card had a fallback chain: Spoolman → inventory → AMS remain. Now fetches inventory spool assignments and computes fill levels from `(label_weight - weight_used) / label_weight`, falling back to AMS remain when no inventory assignment exists.

+ 5 - 0
backend/app/services/bambu_mqtt.py

@@ -1854,6 +1854,11 @@ class BambuMQTTClient:
                         severity = (attr >> 8) & 0xF
                         # Module is in attr byte 3 (bits 24-31)
                         module = (attr >> 24) & 0xFF
+                        # Skip non-error status codes — all real HMS errors
+                        # have code >= 0x4000. Lower values are status/phase
+                        # indicators that some firmware sends during normal printing.
+                        if code < 0x4000:
+                            continue
                         self.state.hms_errors.append(
                             HMSError(
                                 code=f"0x{code:x}" if code else "0x0",

+ 1 - 1
backend/tests/integration/test_print_lifecycle.py

@@ -236,7 +236,7 @@ class TestTimelapseTracking:
             {
                 "print": {
                     "gcode_state": "RUNNING",
-                    "hms": [{"attr": 0x07000002, "code": 0x1234}],  # Filament module error
+                    "hms": [{"attr": 0x07000002, "code": 0x8001}],  # Filament module error (code must be >= 0x4000)
                 }
             }
         )