Update HMS error handling with comprehensive database and unknown filtering

- Replace manual error database with 853 codes from ha-bambulab
    (Source: https://github.com/greghesp/ha-bambulab)
  - Filter out unknown HMS error codes from display
    (Printers sometimes send duplicate/undocumented codes for same error)
  - Update HMS badge count to only show known errors
  - Export filterKnownHMSErrors helper for reuse across components
This commit is contained in:
maziggy
2025-12-15 13:50:13 +01:00
parent 3a8cdba1e3
commit f22acedc7d
5 changed files with 1363 additions and 618 deletions
+41 -1
View File
@@ -1258,6 +1258,7 @@ class BambuMQTTClient:
# Parse HMS (Health Management System) errors
if "hms" in data:
hms_list = data["hms"]
logger.info(f"[{self.serial_number}] HMS data received: {hms_list}")
self.state.hms_errors = []
if isinstance(hms_list, list):
for hms in hms_list:
@@ -1284,6 +1285,45 @@ class BambuMQTTClient:
)
)
# Parse print_error - this is a different error format than HMS
# print_error is a 32-bit integer where:
# - High 16 bits contain module info (e.g., 0x0500)
# - Low 16 bits contain error code (e.g., 0x8061)
# Format on printer screen: [0500-8061] -> short code: 0500_8061
if "print_error" in data:
print_error = data["print_error"]
if print_error and print_error != 0:
# Extract components: MMMMEEEE -> MMMM_EEEE
module = (print_error >> 16) & 0xFFFF # High 16 bits (e.g., 0x0500)
error = print_error & 0xFFFF # Low 16 bits (e.g., 0x8061)
# Store in a format that matches the community error database
# attr stores the full 32-bit value for reconstruction
# code stores the short format string for lookup
short_code = f"{module:04X}_{error:04X}"
logger.info(
f"[{self.serial_number}] print_error: {print_error} (0x{print_error:08x}) -> short_code={short_code}"
)
# Only add if not already in HMS errors (avoid duplicates)
existing_short_codes = set()
for e in self.state.hms_errors:
# Extract short code from existing errors
e_module = (e.attr >> 16) & 0xFFFF
e_error = int(e.code.replace("0x", ""), 16) if e.code else 0
existing_short_codes.add(f"{e_module:04X}_{e_error:04X}")
if short_code not in existing_short_codes:
self.state.hms_errors.append(
HMSError(
code=f"0x{error:x}",
attr=print_error, # Store full value for display
module=module >> 8, # High byte of module (e.g., 0x05)
severity=3, # Warning level for print_error
)
)
# Parse SD card status
if "sdcard" in data:
self.state.sdcard = data["sdcard"] is True
@@ -2152,7 +2192,7 @@ class BambuMQTTClient:
command_json = json.dumps(command)
logger.info(
f"[{self.serial_number}] Setting K-profile: {name} = {k_value} (cali_idx={effective_cali_idx}, new={slot_id==0})"
f"[{self.serial_number}] Setting K-profile: {name} = {k_value} (cali_idx={effective_cali_idx}, new={slot_id == 0})"
)
logger.info(f"[{self.serial_number}] K-profile SET command: {command_json}")
self._client.publish(self.topic_publish, command_json, qos=1)
File diff suppressed because it is too large Load Diff
+20 -19
View File
@@ -36,7 +36,7 @@ import { Button } from '../components/Button';
import { ConfirmModal } from '../components/ConfirmModal';
import { FileManagerModal } from '../components/FileManagerModal';
import { MQTTDebugModal } from '../components/MQTTDebugModal';
import { HMSErrorModal } from '../components/HMSErrorModal';
import { HMSErrorModal, filterKnownHMSErrors } from '../components/HMSErrorModal';
import { PrinterQueueWidget } from '../components/PrinterQueueWidget';
import { AMSHistoryModal } from '../components/AMSHistoryModal';
@@ -781,24 +781,25 @@ function PrinterCard({
</span>
)}
{/* HMS Status Indicator */}
{status?.connected && (
<button
onClick={() => setShowHMSModal(true)}
className={`flex items-center gap-1 px-2 py-1 rounded-full text-xs cursor-pointer hover:opacity-80 transition-opacity ${
status.hms_errors && status.hms_errors.length > 0
? status.hms_errors.some(e => e.severity <= 2)
? 'bg-red-500/20 text-red-400'
: 'bg-orange-500/20 text-orange-400'
: 'bg-bambu-green/20 text-bambu-green'
}`}
title="Click to view HMS errors"
>
<AlertTriangle className="w-3 h-3" />
{status.hms_errors && status.hms_errors.length > 0
? status.hms_errors.length
: 'OK'}
</button>
)}
{status?.connected && (() => {
const knownErrors = status.hms_errors ? filterKnownHMSErrors(status.hms_errors) : [];
return (
<button
onClick={() => setShowHMSModal(true)}
className={`flex items-center gap-1 px-2 py-1 rounded-full text-xs cursor-pointer hover:opacity-80 transition-opacity ${
knownErrors.length > 0
? knownErrors.some(e => e.severity <= 2)
? 'bg-red-500/20 text-red-400'
: 'bg-orange-500/20 text-orange-400'
: 'bg-bambu-green/20 text-bambu-green'
}`}
title="Click to view HMS errors"
>
<AlertTriangle className="w-3 h-3" />
{knownErrors.length > 0 ? knownErrors.length : 'OK'}
</button>
);
})()}
{/* Maintenance Status Indicator */}
{maintenanceInfo && (
<button
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -23,7 +23,7 @@
<!-- Splash screens for iOS -->
<link rel="apple-touch-startup-image" href="/img/android-chrome-512x512.png" />
<script type="module" crossorigin src="/assets/index-CZTNgITa.js"></script>
<script type="module" crossorigin src="/assets/index-B6uuyApI.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CbCN6LSA.css">
</head>
<body>