Add AMS humidity/temperature indicators with configurable thresholds

- Add dynamic humidity indicator with Bambu Lab style water drop icons
    - Empty drop for good (dry), half-filled for fair, full for bad (wet)
    - Configurable thresholds via Settings page

  - Add dynamic temperature indicator with thermometer icons
    - Empty for good, half-filled for fair, full for hot
    - Colors match humidity: green/gold/red

  - Add AMS Display Thresholds settings card
    - Humidity thresholds (good/fair) configurable
    - Temperature thresholds (good/fair) configurable
    - Persisted in backend settings

  - Fix AMS card stability issues
    - Add ams_extruder_map to WebSocket broadcasts
    - Cache AMS data and extruder map to prevent bouncing
    - Fix L/R nozzle indicator for dual-nozzle H2 printers

  - Fix status summary bar counting
    - Don't count printers with unknown status as offline

  - Theme-aware L/R nozzle badges (light/dark theme support)
This commit is contained in:
maziggy
2025-12-07 14:56:52 +00:00
parent e688c35719
commit 71e15b0ed7
9 changed files with 679 additions and 435 deletions
+10
View File
@@ -23,6 +23,12 @@ class AppSettings(BaseModel):
# Language
notification_language: str = Field(default="en", description="Language for push notifications (en, de)")
# AMS threshold settings for humidity and temperature coloring
ams_humidity_good: int = Field(default=40, description="Humidity threshold for good (green): <= this value")
ams_humidity_fair: int = Field(default=60, description="Humidity threshold for fair (orange): <= this value, > is red")
ams_temp_good: float = Field(default=28.0, description="Temperature threshold for good (blue): <= this value")
ams_temp_fair: float = Field(default=35.0, description="Temperature threshold for fair (orange): <= this value, > is red")
class AppSettingsUpdate(BaseModel):
"""Schema for updating settings (all fields optional)."""
@@ -39,3 +45,7 @@ class AppSettingsUpdate(BaseModel):
spoolman_sync_mode: str | None = None
check_updates: bool | None = None
notification_language: str | None = None
ams_humidity_good: int | None = None
ams_humidity_fair: int | None = None
ams_temp_good: float | None = None
ams_temp_fair: float | None = None
+5
View File
@@ -336,6 +336,9 @@ def printer_state_to_dict(state: PrinterState, printer_id: int | None = None) ->
"tag_uid": vt_tag_uid,
}
# Get ams_extruder_map from raw_data (populated by MQTT handler from AMS info field)
ams_extruder_map = raw_data.get("ams_extruder_map", {})
result = {
"connected": state.connected,
"state": state.state,
@@ -358,6 +361,8 @@ def printer_state_to_dict(state: PrinterState, printer_id: int | None = None) ->
"ams_status_main": state.ams_status_main,
"ams_status_sub": state.ams_status_sub,
"tray_now": state.tray_now,
# Per-AMS extruder map: {ams_id: extruder_id} where 0=right, 1=left
"ams_extruder_map": ams_extruder_map,
# WiFi signal strength
"wifi_signal": state.wifi_signal,
}