@riddix/hamh 2.1.0-alpha.640 β†’ 2.1.0-alpha.642

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,9 +56,9 @@ of port forwarding etc.
56
56
 
57
57
  **New in v2.0.42 (hotfix release):**
58
58
 
59
- - πŸ‡―πŸ‡΅ Aqara bridge registration no longer stalls β€” root `softwareVersionString` now matches the numeric `softwareVersion` ([#316](https://github.com/RiDDiX/home-assistant-matter-hub/issues/316))
59
+ - πŸ‡―πŸ‡΅ Aqara bridge registration no longer stalls, root `softwareVersionString` now matches the numeric `softwareVersion` ([#316](https://github.com/RiDDiX/home-assistant-matter-hub/issues/316))
60
60
  - ❄️ Climate `auto` mode is clamped to `heat`/`cool` on devices without an `AutoMode` base ([#319](https://github.com/RiDDiX/home-assistant-matter-hub/issues/319))
61
- - πŸŒ€ Per-entity `disableClimateFanControl` mapping flag β€” falls back to `ThermostatDevice` when controllers like Aqara don't recognise `RoomAirConditioner` (`0x0072`) ([#318](https://github.com/RiDDiX/home-assistant-matter-hub/issues/318))
61
+ - πŸŒ€ Per-entity `disableClimateFanControl` mapping flag, falls back to `ThermostatDevice` when controllers like Aqara don't recognise `RoomAirConditioner` (`0x0072`) ([#318](https://github.com/RiDDiX/home-assistant-matter-hub/issues/318))
62
62
  - πŸ—ΊοΈ Vacuum service area `selectedAreas` is kept after dispatch instead of being cleared
63
63
 
64
64
  **Previously in v2.0.41:**
@@ -68,13 +68,13 @@ of port forwarding etc.
68
68
  | 🌑️ Google Home AC offline fix | `DeadFrontBehavior` on climate OnOff cluster so RoomAirConditioner stops showing offline on Google Home ([#302](https://github.com/RiDDiX/home-assistant-matter-hub/issues/302)) |
69
69
  | πŸͺŸ Cover device_class mapping | Map HA `garage`/`gate`/`window`/`awning`/etc. to the matching Matter WindowCovering type so voice commands hit the right device type ([#304](https://github.com/RiDDiX/home-assistant-matter-hub/issues/304)) |
70
70
  | πŸ“Ί LG TV commissioning patch | Local patch on matter.js 0.16.11 to accept long NOC operational cert serials ([#305](https://github.com/RiDDiX/home-assistant-matter-hub/issues/305)) |
71
- | πŸ’‘ Alexa brightness-reset behind flag | Old Alexa brightness-reset heuristic moved behind `alexaPreserveBrightnessOnTurnOn`, default off β€” Apple Home "set room to 100%" works again ([#306](https://github.com/RiDDiX/home-assistant-matter-hub/issues/306)) |
71
+ | πŸ’‘ Alexa brightness-reset behind flag | Old Alexa brightness-reset heuristic moved behind `alexaPreserveBrightnessOnTurnOn`, default off, Apple Home "set room to 100%" works again ([#306](https://github.com/RiDDiX/home-assistant-matter-hub/issues/306)) |
72
72
  | πŸŒ€ Google Home fan speed | Uses `fan.set_percentage` so already-on fans pick up speed changes from Google Home ([#308](https://github.com/RiDDiX/home-assistant-matter-hub/issues/308)) |
73
73
  | ❄️ Climate auto mode | Expose Matter Auto mode when HA reports `auto` in `hvac_modes` ([#309](https://github.com/RiDDiX/home-assistant-matter-hub/issues/309)) |
74
74
  | πŸ†” Server-mode root identity | Root identity now applies as a single transaction, so controllers don't drop devices mid-swap ([#311](https://github.com/RiDDiX/home-assistant-matter-hub/issues/311)) |
75
- | πŸͺŸ Lift-only blinds | No more `TiltBlindTiltOnly` on covers without tilt β€” fixes Alexa routines for roller blinds ([#312](https://github.com/RiDDiX/home-assistant-matter-hub/issues/312)) |
75
+ | πŸͺŸ Lift-only blinds | No more `TiltBlindTiltOnly` on covers without tilt, fixes Alexa routines for roller blinds ([#312](https://github.com/RiDDiX/home-assistant-matter-hub/issues/312)) |
76
76
  | 🏷️ Per-entity `disableClimateOnOff` | Turn off the OnOff cluster on climate endpoints per entity for controllers that prefer mode-only control |
77
- | πŸ”’ `serialNumberSuffix` per bridge | Append a suffix to every entity serial β€” useful if controllers like Aqara cache stale device data |
77
+ | πŸ”’ `serialNumberSuffix` per bridge | Append a suffix to every entity serial, useful if controllers like Aqara cache stale device data |
78
78
  | πŸ“ `protocolLogLevel` option | Quiet matter.js logs independently from the app log level |
79
79
  | πŸ–₯️ Bridge HW/SW version strings | HA device-registry `hw_version`/`sw_version` now show up in Matter BasicInformation on server-mode endpoints |
80
80
  | 🎨 Extended color light: XY + enhancedColorMode | XY feature added as mandatory, `enhancedColorMode` mirrors `colorMode` |
@@ -87,7 +87,7 @@ of port forwarding etc.
87
87
  **Reliability & resilience:** parallel bridge stop in `stopAll`/`restartAll`, parallel HA registry fetches, serialized bridge start/stop lifecycle, serialized `updateStates` with plugin listener detach, HA reconnect retry on transient network errors, 30s timeout on `sendMessagePromise`, port-conflict reject on web-api start, graceful shutdown on `/api/backup/restart`, `AppEnvironment` disposal on SIGINT, stale optimistic state sweep, pending debouncer clear, healthcheck 401 fix under basic auth, deep-equal entity attribute comparison, overlap guard for auto-refresh, safer mireds conversion, aligned `colorMode` publishing, surfaced bridge import errors, corrected thermostat running state for unknown modes + drying, unified Node version across Dockerfiles, sourcemaps excluded from npm tarball, unused deps dropped (rxjs, strip-color, lodash), unused `config-validator` utility removed.
88
88
 
89
89
  **Previously in v2.0.39 & v2.0.40 (hotfix releases):**
90
- - Fixed crash loop on startup caused by Node 22 native WebSocket dropping connections ([#297](https://github.com/RiDDiX/home-assistant-matter-hub/issues/297), [#299](https://github.com/RiDDiX/home-assistant-matter-hub/issues/299)) β€” affects both aarch64 (RPi) and amd64
90
+ - Fixed crash loop on startup caused by Node 22 native WebSocket dropping connections ([#297](https://github.com/RiDDiX/home-assistant-matter-hub/issues/297), [#299](https://github.com/RiDDiX/home-assistant-matter-hub/issues/299)), affects both aarch64 (RPi) and amd64
91
91
  - Fixed service initialization errors being silently swallowed, causing the process to hang instead of exiting
92
92
  - Registry fetch now waits for WebSocket reconnect between retries and has increased retry tolerance
93
93
  - Fixed `select`, `input_select`, `siren` domains showing as unsupported in filter preview ([#298](https://github.com/RiDDiX/home-assistant-matter-hub/issues/298))
@@ -161,7 +161,7 @@ of port forwarding etc.
161
161
  <summary><strong>πŸ“œ Previous Stable Versions</strong> - Click to expand</summary>
162
162
 
163
163
  ### v2.0.40
164
- Filter preview domain fix β€” `select`, `input_select`, `siren` now show as supported ([#298](https://github.com/RiDDiX/home-assistant-matter-hub/issues/298))
164
+ Filter preview domain fix, `select`, `input_select`, `siren` now show as supported ([#298](https://github.com/RiDDiX/home-assistant-matter-hub/issues/298))
165
165
 
166
166
  ### v2.0.39
167
167
  Node 22 WebSocket crash loop fix ([#297](https://github.com/RiDDiX/home-assistant-matter-hub/issues/297), [#299](https://github.com/RiDDiX/home-assistant-matter-hub/issues/299)), service init error surfacing, registry retry hardening, support link added
@@ -205,7 +205,7 @@ Vacuum mop intensity, vacuum auto-detection, Roborock room auto-detect, live ent
205
205
  ### v2.0.24
206
206
  Dashboard landing page, composed devices, bridge wizard feature flags, entity autocomplete, light transitions, live diagnostics, vacuum suction level, thermostat auto-resume, vacuum docked state, memory leak fix
207
207
 
208
- ### v2.0.19–v2.0.23
208
+ ### v2.0.19-v2.0.23
209
209
  Bridge templates, live filter preview, entity diagnostics, multi-bridge bulk operations, entity health indicators, diagnostic export, EntityLabel/DeviceLabel filters, Power & Energy Measurement, Event domain (GenericSwitch)
210
210
 
211
211
  ### v2.0.17 / v2.0.18
@@ -347,26 +347,26 @@ configuration options, known issues, limitations and guides.
347
347
  ## πŸ”§ Network Troubleshooting
348
348
 
349
349
  <details>
350
- <summary><strong>⚠️ "No Response" / Connection Drops β€” Common Network Causes</strong> (click to expand)</summary>
350
+ <summary><strong>⚠️ "No Response" / Connection Drops, Common Network Causes</strong> (click to expand)</summary>
351
351
 
352
352
  ### The Problem
353
353
 
354
- Your Matter devices suddenly show **"No Response"** (Apple Home), **"Unavailable"** (Google Home), or become **unresponsive** after some time β€” even though the bridge is still running and other controllers (e.g., Alexa) continue to work fine.
354
+ Your Matter devices suddenly show **"No Response"** (Apple Home), **"Unavailable"** (Google Home), or become **unresponsive** after some time, even though the bridge is still running and other controllers (e.g., Alexa) continue to work fine.
355
355
 
356
356
  ### Root Cause: Network Equipment Blocking mDNS/Multicast
357
357
 
358
- Matter relies heavily on **mDNS (multicast DNS)** for device discovery and reachability. Many routers, access points, and managed switches have features that **filter, throttle, or block multicast traffic** β€” which breaks Matter communication silently.
358
+ Matter relies heavily on **mDNS (multicast DNS)** for device discovery and reachability. Many routers, access points, and managed switches have features that **filter, throttle, or block multicast traffic**, which breaks Matter communication silently.
359
359
 
360
- > **πŸ’‘ This was confirmed and documented thanks to the excellent systematic testing by [@omerfaruk-aran](https://github.com/omerfaruk-aran) in [#129](https://github.com/RiDDiX/home-assistant-matter-hub/issues/129).** The issue was traced to a TP-Link Archer AX50 (in AP mode) sitting between the Apple TV and the network β€” its default settings were blocking/limiting mDNS/Bonjour traffic over time.
360
+ > **πŸ’‘ This was confirmed and documented thanks to the excellent systematic testing by [@omerfaruk-aran](https://github.com/omerfaruk-aran) in [#129](https://github.com/RiDDiX/home-assistant-matter-hub/issues/129).** The issue was traced to a TP-Link Archer AX50 (in AP mode) sitting between the Apple TV and the network, its default settings were blocking/limiting mDNS/Bonjour traffic over time.
361
361
 
362
362
  ### What to Check on Your Network Equipment
363
363
 
364
- 1. **IGMP Snooping** β€” Disable or configure it to allow mDNS (`224.0.0.251` / `ff02::fb`)
365
- 2. **Multicast Optimization / Multicast Enhancement** β€” Disable (often called "Airtime Fairness" or "Multicast to Unicast")
366
- 3. **AP Isolation / Client Isolation** β€” Must be **disabled** so devices on the same network can communicate
367
- 4. **mDNS / Bonjour Forwarding** β€” Enable if available (some enterprise APs have this)
368
- 5. **DHCP Server on secondary devices** β€” Disable DHCP on access points / switches that are NOT your main router (multiple DHCP servers cause IP conflicts)
369
- 6. **Firmware Updates** β€” Update your router/AP firmware, as multicast handling is frequently improved
364
+ 1. **IGMP Snooping**, Disable or configure it to allow mDNS (`224.0.0.251` / `ff02::fb`)
365
+ 2. **Multicast Optimization / Multicast Enhancement**, Disable (often called "Airtime Fairness" or "Multicast to Unicast")
366
+ 3. **AP Isolation / Client Isolation**, Must be **disabled** so devices on the same network can communicate
367
+ 4. **mDNS / Bonjour Forwarding**, Enable if available (some enterprise APs have this)
368
+ 5. **DHCP Server on secondary devices**, Disable DHCP on access points / switches that are NOT your main router (multiple DHCP servers cause IP conflicts)
369
+ 6. **Firmware Updates**, Update your router/AP firmware, as multicast handling is frequently improved
370
370
 
371
371
  ### Affected Equipment (Known Cases)
372
372
 
@@ -390,14 +390,14 @@ Matter relies heavily on **mDNS (multicast DNS)** for device discovery and reach
390
390
  ```
391
391
  --mdns-network-interface eth0
392
392
  ```
393
- (or `end0`, `enp0s18`, etc. β€” check your system)
393
+ (or `end0`, `enp0s18`, etc., check your system)
394
394
 
395
395
  ### Network Topology Tips
396
396
 
397
397
  - **Keep the path simple**: Avoid placing access points or managed switches between your Matter bridge (Home Assistant) and your Home Hub (HomePod/Apple TV)
398
398
  - **Use wired connections** where possible for Home Hubs and the Home Assistant host
399
399
  - **Same subnet**: All Matter devices, controllers, and the bridge must be on the same Layer 2 network / subnet
400
- - **IPv6**: Matter requires IPv6 β€” do not disable it. For VLAN setups, configure **ULA addresses** (`fd00::/8`), not just link-local (`fe80::`). See [Troubleshooting](https://home-assistant-matter-hub.riddix.dev/guides/connectivity-issues#ipv6) and [Discussion #39](https://github.com/RiDDiX/home-assistant-matter-hub/discussions/39)
400
+ - **IPv6**: Matter requires IPv6, do not disable it. For VLAN setups, configure **ULA addresses** (`fd00::/8`), not just link-local (`fe80::`). See [Troubleshooting](https://home-assistant-matter-hub.riddix.dev/guides/connectivity-issues#ipv6) and [Discussion #39](https://github.com/RiDDiX/home-assistant-matter-hub/discussions/39)
401
401
 
402
402
  </details>
403
403
 
@@ -405,7 +405,7 @@ Matter relies heavily on **mDNS (multicast DNS)** for device discovery and reach
405
405
 
406
406
  ## Migration from t0bst4r
407
407
 
408
- Migrating from the original `t0bst4r/home-assistant-matter-hub` is straightforward. **Your Matter fabric connections and paired devices will be preserved!**
408
+ Migrating from the original `t0bst4r/home-assistant-matter-hub` is easy. **Your Matter fabric connections and paired devices will be preserved!**
409
409
 
410
410
  ### Home Assistant Add-on
411
411
 
@@ -457,22 +457,29 @@ Your volume mounts stay the same - no data migration needed.
457
457
 
458
458
  This project thrives thanks to the amazing community! Special thanks to everyone who contributes by reporting bugs, suggesting features, and helping others.
459
459
 
460
+ > Note: GitHub doesn't surface contributors on this repo because it's still a fork of the original. The list below is maintained by hand.
461
+
460
462
  ### πŸ† Top Contributors
461
463
 
464
+ Newest first.
465
+
462
466
  | Contributor | Contributions |
463
467
  |-------------|---------------|
464
- | [@codyc1515](https://github.com/codyc1515) | πŸ₯‡ **Top Reporter** - Climate/thermostat bugs (#52, #24, #21, #20), extensive testing feedback |
468
+ | [@Yllelder](https://github.com/Yllelder) | 🌐 **Translator** - Spanish translation ([#314](https://github.com/RiDDiX/home-assistant-matter-hub/pull/314)) |
469
+ | [@MStankiewiczOfficial](https://github.com/MStankiewiczOfficial) | 🌐 **Translator** - Polish translation ([#288](https://github.com/RiDDiX/home-assistant-matter-hub/pull/288)) |
470
+ | [@aetasoul](https://github.com/aetasoul) | πŸ€– **Code Contributor** - Immediate force sync on startup to beat stale Alexa queues ([#282](https://github.com/RiDDiX/home-assistant-matter-hub/pull/282)) |
471
+ | [@omerfaruk-aran](https://github.com/omerfaruk-aran) | 🌐 Turkish translation ([#260](https://github.com/RiDDiX/home-assistant-matter-hub/pull/260)) + πŸ”§ Network debugging for "No Response" issues ([#129](https://github.com/RiDDiX/home-assistant-matter-hub/issues/129)) |
472
+ | [@gustavakerstrom](https://github.com/gustavakerstrom) | πŸ€– **Code Contributor** - Custom fan speed mapping ([#226](https://github.com/RiDDiX/home-assistant-matter-hub/pull/226)), template description fix ([#215](https://github.com/RiDDiX/home-assistant-matter-hub/pull/215)) |
473
+ | [@AmineDjeghri](https://github.com/AmineDjeghri) | πŸ“ Migration instructions for the addon data folder ([#171](https://github.com/RiDDiX/home-assistant-matter-hub/pull/171)) |
474
+ | [@markgaze](https://github.com/markgaze) | πŸ€– **Code Contributor** - Ecovacs Deebot room support ([#118](https://github.com/RiDDiX/home-assistant-matter-hub/pull/118)) |
475
+ | [@codyc1515](https://github.com/codyc1515) | πŸ₯‡ **Top Reporter** - Climate/thermostat bugs (#52, #24, #21, #20), README badge & install steps ([#285](https://github.com/RiDDiX/home-assistant-matter-hub/pull/285)), binary sensor classes ([#66](https://github.com/RiDDiX/home-assistant-matter-hub/pull/66)), fan control init ([#10](https://github.com/RiDDiX/home-assistant-matter-hub/pull/10)) |
476
+ | [@AymericLeFeyer](https://github.com/AymericLeFeyer) | πŸ“ README YouTube video link |
477
+ | [@depahk](https://github.com/depahk) | πŸ“ Migration docs ([#32](https://github.com/RiDDiX/home-assistant-matter-hub/pull/32)) |
465
478
  | [@Hatton920](https://github.com/Hatton920) | πŸ€– **Vacuum Expert** - Intensive testing of Robot Vacuum Server Mode, Apple Home & Siri validation |
466
- | [@Chrulf](https://github.com/Chrulf) | πŸ” Google Home brightness debugging (#41), detailed logs & testing |
479
+ | [@razzietheman](https://github.com/razzietheman) | πŸ₯ˆ **Active Tester** - Bridge icons (#101), sorting (#80), feature requests (#31, #30), extensive UI/UX feedback |
467
480
  | [@SH1FT-W](https://github.com/SH1FT-W) | πŸ’Ž **Sponsor** + Vacuum room selection feature request (#49) |
468
- | [@depahk](https://github.com/depahk) | πŸ“ Migration documentation fix ([#32](https://github.com/RiDDiX/home-assistant-matter-hub/pull/32)) |
481
+ | [@Chrulf](https://github.com/Chrulf) | πŸ” Google Home brightness debugging (#41), detailed logs & testing |
469
482
  | [@Fettkeewl](https://github.com/Fettkeewl) | πŸ› Script import bug (#26), Alias feature request (#25) |
470
- | [@razzietheman](https://github.com/razzietheman) | πŸ₯ˆ **Active Tester** - Bridge icons (#101), sorting (#80), feature requests (#31, #30), extensive UI/UX feedback |
471
- | [@markgaze](https://github.com/markgaze) | πŸ€– **Code Contributor** - Ecovacs Deebot room support ([#118](https://github.com/RiDDiX/home-assistant-matter-hub/pull/118)) |
472
- | [@omerfaruk-aran](https://github.com/omerfaruk-aran) | πŸ”§ **Network Debugging Expert** - Systematic mDNS/multicast root cause analysis for "No Response" issues ([#129](https://github.com/RiDDiX/home-assistant-matter-hub/issues/129)) |
473
- | [@gustavakerstrom](https://github.com/gustavakerstrom) | πŸ€– **Code Contributor** - Template description display fix ([#215](https://github.com/RiDDiX/home-assistant-matter-hub/pull/215)) |
474
- | [@aetasoul](https://github.com/aetasoul) | πŸ€– **Code Contributor** - Immediate force sync on startup to beat stale Alexa queues ([#282](https://github.com/RiDDiX/home-assistant-matter-hub/pull/282)) |
475
- | [@Yllelder](https://github.com/Yllelder) | 🌐 **Translator** - Spanish translation ([#314](https://github.com/RiDDiX/home-assistant-matter-hub/pull/314)) |
476
483
 
477
484
  <details>
478
485
  <summary><strong>πŸ“‹ Issue Tracker - All Contributors</strong> (click to expand)</summary>
@@ -516,7 +523,7 @@ Thank you to everyone who helps improve this project by reporting issues!
516
523
 
517
524
  ### πŸ’– Sponsors
518
525
 
519
- > **Donations are completely voluntary!** This project exists because of passion for open source, not money. Thank you to everyone who has supported it β€” it truly means a lot! ❀️
526
+ > **Donations are completely voluntary!** This project exists because of passion for open source, not money. Thank you to everyone who has supported it, it truly means a lot! ❀️
520
527
 
521
528
  πŸ₯‡ **First Sponsor:** [@thorsten-gehrig](https://github.com/thorsten-gehrig)
522
529
 
@@ -568,3 +575,4 @@ Your support helps cover hosting costs and motivates continued development. Than
568
575
  </div>
569
576
 
570
577
  ---
578
+
@@ -146781,7 +146781,7 @@ var init_bridge_config_schema = __esm({
146781
146781
  },
146782
146782
  autoComposedDevices: {
146783
146783
  title: "Auto Composed Devices",
146784
- description: "Master toggle: combine related entities from the same Home Assistant device into a single Matter endpoint. Turns on battery, humidity, pressure, power, and energy auto-mapping at once \u2014 a Shelly Plug shows up as one device with power monitoring instead of several siblings.",
146784
+ description: "Master toggle: combine related entities from the same Home Assistant device into a single Matter endpoint. Turns on battery, humidity, pressure, power, and energy auto-mapping at once, a Shelly Plug shows up as one device with power monitoring instead of several siblings.",
146785
146785
  type: "boolean",
146786
146786
  default: false
146787
146787
  },
@@ -146799,13 +146799,13 @@ var init_bridge_config_schema = __esm({
146799
146799
  },
146800
146800
  preferEntityRegistryName: {
146801
146801
  title: "Prefer Entity Registry Name (HA 2026.4 workaround)",
146802
- description: "Use the entity registry name (or original_name) as nodeLabel instead of the composed friendly_name. Since Home Assistant 2026.4, friendly_name is prefixed with the device name, which breaks voice commands that relied on the short entity name. Resolution order: customName \u2192 registry name \u2192 registry original_name \u2192 friendly_name \u2192 entity_id. Matter has no alias concept \u2014 this only changes which single name is reported.",
146802
+ description: "Use the entity registry name (or original_name) as nodeLabel instead of the composed friendly_name. Since Home Assistant 2026.4, friendly_name is prefixed with the device name, which breaks voice commands that relied on the short entity name. Resolution order: customName \u2192 registry name \u2192 registry original_name \u2192 friendly_name \u2192 entity_id. Matter has no alias concept, this only changes which single name is reported.",
146803
146803
  type: "boolean",
146804
146804
  default: false
146805
146805
  },
146806
146806
  vacuumOnOff: {
146807
146807
  title: "Vacuum: Include OnOff Cluster (Alexa)",
146808
- description: "Add an OnOff cluster to robot vacuum endpoints. Alexa REQUIRES this (PowerController) to show robotic vacuums in the app. Without it, Alexa commissions the device but never displays it. In Server Mode this is enabled automatically \u2014 only check this for bridge mode. WARNING: OnOff is NOT part of the Matter RVC device type specification. Enabling this may break Apple Home (shows 'Updating') and Google Home.",
146808
+ description: "Add an OnOff cluster to robot vacuum endpoints. Alexa REQUIRES this (PowerController) to show robotic vacuums in the app. Without it, Alexa commissions the device but never displays it. In Server Mode this is enabled automatically, only check this for bridge mode. WARNING: OnOff is NOT part of the Matter RVC device type specification. Enabling this may break Apple Home (shows 'Updating') and Google Home.",
146809
146809
  type: "boolean"
146810
146810
  },
146811
146811
  alexaPreserveBrightnessOnTurnOn: {
@@ -152748,7 +152748,7 @@ var HomeAssistantRegistry = class extends Service {
152748
152748
  let refreshing = false;
152749
152749
  this.autoRefresh = setInterval(async () => {
152750
152750
  if (refreshing) {
152751
- logger146.debug("Skipping registry refresh \u2014 previous tick still running");
152751
+ logger146.debug("Skipping registry refresh, previous tick still running");
152752
152752
  return;
152753
152753
  }
152754
152754
  refreshing = true;
@@ -165337,7 +165337,7 @@ var ServerModeServerNode = class extends ServerNode {
165337
165337
  /**
165338
165338
  * Update root-level BasicInformation with entity-specific data.
165339
165339
  * In server mode, controllers (Apple Home, Alexa) read the root node's
165340
- * BasicInformation β€” not the device endpoint's BridgedDeviceBasicInformation.
165340
+ * BasicInformation, not the device endpoint's BridgedDeviceBasicInformation.
165341
165341
  * Without this, server-mode devices show bridge defaults (e.g. "riddix" / "MatterHub").
165342
165342
  */
165343
165343
  async updateDeviceIdentity(entityId, device, mapping, friendlyName) {
@@ -167848,7 +167848,7 @@ ${e?.toString()}`);
167848
167848
  );
167849
167849
  if (totalSubs === 0 && sessions.length > 0) {
167850
167850
  this.log.warn(
167851
- `All subscriptions lost \u2014 ${sessions.length} session(s) still active, waiting for controller to re-subscribe`
167851
+ `All subscriptions lost, ${sessions.length} session(s) still active, waiting for controller to re-subscribe`
167852
167852
  );
167853
167853
  if (!this.deadSessionTimer) {
167854
167854
  this.deadSessionTimer = setTimeout(() => {
@@ -167896,7 +167896,7 @@ ${e?.toString()}`);
167896
167896
  for (const s of [...sessionManager.sessions]) {
167897
167897
  if (s !== newSession && !s.isClosing && s.peerNodeId === newSession.peerNodeId && s.fabric?.fabricIndex === newSession.fabric?.fabricIndex && s.subscriptions.size === 0) {
167898
167898
  this.log.info(
167899
- `Closing stale session ${s.id} (peer ${s.peerNodeId}, 0 subs) \u2014 replaced by session ${newSession.id}`
167899
+ `Closing stale session ${s.id} (peer ${s.peerNodeId}, 0 subs), replaced by session ${newSession.id}`
167900
167900
  );
167901
167901
  s.initiateForceClose().catch(() => {
167902
167902
  });
@@ -169200,7 +169200,7 @@ var FeaturedBase5 = FanControlServer.with(
169200
169200
  "Rocking",
169201
169201
  "Wind"
169202
169202
  ).set({
169203
- // rockSupport / windSupport are Fixed quality attributes β€” they MUST be set
169203
+ // rockSupport / windSupport are Fixed quality attributes, they MUST be set
169204
169204
  // via .set() at behavior creation time, NOT in initialize().
169205
169205
  // Without these, controllers reject attempts to enable rocking/wind.
169206
169206
  rockSupport: { rockUpDown: true },
@@ -171304,7 +171304,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171304
171304
  // Heat/Cool/Off but SKIPS Auto (see #handleSystemModeChange in Matter.js).
171305
171305
  // Without this, switching Heatβ†’Auto leaves runningMode stale at Heat.
171306
171306
  // 889010b set for ALL modes (conflicted with reactor), 0678d35 set for NONE
171307
- // (stale in Auto). da04b2e's Auto-only approach is correct β€” the issues
171307
+ // (stale in Auto). da04b2e's Auto-only approach is correct, the issues
171308
171308
  // reported after it were caused by localTemperature fallback, not runningMode.
171309
171309
  ...this.features.heating && this.features.cooling && systemMode === Thermostat3.SystemMode.Auto ? { thermostatRunningMode: runningMode } : {}
171310
171310
  });
@@ -171589,7 +171589,7 @@ var CoolingOnlyThermostatServerBase = class extends CoolingOnlyFeaturedBase {
171589
171589
  static State = class extends CoolingOnlyFeaturedBase.State {
171590
171590
  config;
171591
171591
  };
171592
- // Each variant MUST define its own initialize() β€” see HeatingOnly comment above.
171592
+ // Each variant MUST define its own initialize(), see HeatingOnly comment above.
171593
171593
  async initialize() {
171594
171594
  thermostatPreInitialize(this);
171595
171595
  await super.initialize();
@@ -171611,7 +171611,7 @@ var HeatingAndCoolingThermostatServerBase = class extends HeatingAndCoolingFeatu
171611
171611
  static State = class extends HeatingAndCoolingFeaturedBase.State {
171612
171612
  config;
171613
171613
  };
171614
- // Each variant MUST define its own initialize() β€” see HeatingOnly comment above.
171614
+ // Each variant MUST define its own initialize(), see HeatingOnly comment above.
171615
171615
  async initialize() {
171616
171616
  thermostatPreInitialize(this);
171617
171617
  await super.initialize();
@@ -172239,7 +172239,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
172239
172239
  } else if (type === MovementType.Tilt) {
172240
172240
  if (targetPercent100ths == null && this.lastLiftMovementDirection === direction && Date.now() - this.lastLiftMovementMs < 50) {
172241
172241
  logger179.info(
172242
- `Skipping tilt ${MovementDirection[direction]} \u2014 lift already moving in same direction`
172242
+ `Skipping tilt ${MovementDirection[direction]}, lift already moving in same direction`
172243
172243
  );
172244
172244
  return;
172245
172245
  }
@@ -174674,7 +174674,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase8 {
174674
174674
  *
174675
174675
  * The base class registers a reactor on onOff$Changed that sets
174676
174676
  * currentLevel = onLevel. This is designed for lights (restore brightness
174677
- * on power-on) but is wrong for speakers β€” it overwrites the correct
174677
+ * on power-on) but is wrong for speakers, it overwrites the correct
174678
174678
  * volume (e.g. 191 for 75%) with a stale onLevel value, causing Google
174679
174679
  * Home to display the wrong percentage (Issue #79).
174680
174680
  */
@@ -176679,7 +176679,7 @@ function SensorDevice(homeAssistantEntity) {
176679
176679
  if (deviceClass) {
176680
176680
  diagnosticEventBus.emit(
176681
176681
  "entity_warning",
176682
- `Sensor "${homeAssistantEntity.entity.entity_id}" has unsupported device_class "${deviceClass}" \u2014 skipped`,
176682
+ `Sensor "${homeAssistantEntity.entity.entity_id}" has unsupported device_class "${deviceClass}", skipped`,
176683
176683
  {
176684
176684
  entityId: homeAssistantEntity.entity.entity_id,
176685
176685
  details: { device_class: deviceClass }
@@ -176795,7 +176795,7 @@ var VacuumIdentifyServer = class extends IdentifyServer2 {
176795
176795
  return;
176796
176796
  }
176797
176797
  logger190.warn(
176798
- `${source} for ${homeAssistant.entityId} \u2014 LOCATE not in supported_features (${features2}), trying vacuum.locate anyway`
176798
+ `${source} for ${homeAssistant.entityId}, LOCATE not in supported_features (${features2}), trying vacuum.locate anyway`
176799
176799
  );
176800
176800
  homeAssistant.callAction({ action: "vacuum.locate" });
176801
176801
  }
@@ -176925,7 +176925,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
176925
176925
  if (!currentRoomEntityId) {
176926
176926
  this.logShortCircuitOnce(
176927
176927
  "no-mapping",
176928
- "currentRoom sensor: no currentRoomEntity in mapping \u2014 auto-detect did not run or sensor not on same HA device"
176928
+ "currentRoom sensor: no currentRoomEntity in mapping, auto-detect did not run or sensor not on same HA device"
176929
176929
  );
176930
176930
  return;
176931
176931
  }
@@ -176941,7 +176941,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
176941
176941
  if (s.activeAreas.length === 0) {
176942
176942
  this.logShortCircuitOnce(
176943
176943
  "no-active-areas",
176944
- `currentRoom sensor: activeAreas empty while cleaning \u2014 sensor=${currentRoomEntityId} state="${roomState.state}"`
176944
+ `currentRoom sensor: activeAreas empty while cleaning, sensor=${currentRoomEntityId} state="${roomState.state}"`
176945
176945
  );
176946
176946
  return;
176947
176947
  }
@@ -178308,11 +178308,11 @@ function buildSupportedModes3(fanSpeedList, mopIntensityList, cleaningModeOption
178308
178308
  }
178309
178309
  var CLEAN_TOKENS = {
178310
178310
  vacuum: /\b(vacuum|vacuuming|sweep|sweeping|suction)\b/i,
178311
- mop: /\b(mop|mopping|wipe|wet)\b/i,
178312
- sequential: /\b(then|after|before|followed|following)\b/i
178311
+ mop: /\b(mop|mopping|wipe|wet|wash|scrub)\b/i,
178312
+ sequential: /\b(then|after|before|followed|following|first|secondly|sequentially)\b/i
178313
178313
  };
178314
178314
  function normalizeCleanLabel(s) {
178315
- return s.toLowerCase().replace(/[_\-+&/]+/g, " ").replace(/\band\b/g, " ").trim();
178315
+ return s.toLowerCase().replace(/[_\-+&/. ]+/g, " ").replace(/\band\b/g, " ").trim();
178316
178316
  }
178317
178317
  function classifyCleanOption(option) {
178318
178318
  const s = normalizeCleanLabel(option);
@@ -178645,7 +178645,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178645
178645
  const vacuumEntityId = homeAssistant.entityId;
178646
178646
  const mapping = homeAssistant.state.mapping;
178647
178647
  logger196.info(
178648
- `setCleanMode(${mode}) for ${vacuumEntityId} \u2014 suctionEntity=${mapping?.suctionLevelEntity ?? "none"}, mopEntity=${mapping?.mopIntensityEntity ?? "none"}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})}`
178648
+ `setCleanMode(${mode}) for ${vacuumEntityId}, suctionEntity=${mapping?.suctionLevelEntity ?? "none"}, mopEntity=${mapping?.mopIntensityEntity ?? "none"}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})}`
178649
178649
  );
178650
178650
  if (mopIntensityList && mopIntensityList.length > 0 && isMopIntensityMode(mode)) {
178651
178651
  const mopIndex = mode - MOP_INTENSITY_MODE_BASE;
@@ -180612,7 +180612,7 @@ var BridgeEndpointManager = class extends Service {
180612
180612
  this.mappingFingerprints.delete(endpoint.entityId);
180613
180613
  } else if (this.registry.isAutoComposedDevicesEnabled() && this.registry.isComposedSubEntityUsed(endpoint.entityId)) {
180614
180614
  this.log.info(
180615
- `Deleting standalone endpoint ${endpoint.entityId} \u2014 consumed by composed device`
180615
+ `Deleting standalone endpoint ${endpoint.entityId}, consumed by composed device`
180616
180616
  );
180617
180617
  try {
180618
180618
  await endpoint.delete();
@@ -180650,14 +180650,14 @@ var BridgeEndpointManager = class extends Service {
180650
180650
  if (!memoryLimitReached && isHeapUnderPressure()) {
180651
180651
  memoryLimitReached = true;
180652
180652
  this.log.error(
180653
- "Memory pressure detected \u2014 skipping remaining entities to prevent OOM crash. Reduce the number of entities in this bridge or increase the Node.js heap size (NODE_OPTIONS=--max-old-space-size=1024)."
180653
+ "Memory pressure detected, skipping remaining entities to prevent OOM crash. Reduce the number of entities in this bridge or increase the Node.js heap size (NODE_OPTIONS=--max-old-space-size=1024)."
180654
180654
  );
180655
180655
  }
180656
180656
  if (memoryLimitReached) {
180657
180657
  if (!existingEndpoints.some((e) => e.entityId === entityId)) {
180658
180658
  this._failedEntities.push({
180659
180659
  entityId,
180660
- reason: "Skipped due to memory pressure \u2014 reduce entities or increase heap size"
180660
+ reason: "Skipped due to memory pressure, reduce entities or increase heap size"
180661
180661
  });
180662
180662
  }
180663
180663
  continue;
@@ -180669,7 +180669,7 @@ var BridgeEndpointManager = class extends Service {
180669
180669
  }
180670
180670
  if (this.registry.isAutoComposedDevicesEnabled() && this.registry.isComposedSubEntityUsed(entityId)) {
180671
180671
  this.log.debug(
180672
- `Skipping ${entityId} \u2014 already part of a composed device`
180672
+ `Skipping ${entityId}, already part of a composed device`
180673
180673
  );
180674
180674
  continue;
180675
180675
  }
@@ -180769,7 +180769,7 @@ var BridgeEndpointManager = class extends Service {
180769
180769
  }
180770
180770
  /**
180771
180771
  * Log detailed behavior error information for debugging "Behaviors have errors".
180772
- * Matter.js EndpointBehaviorsError extends AggregateError β€” the `errors` array
180772
+ * Matter.js EndpointBehaviorsError extends AggregateError, the `errors` array
180773
180773
  * contains individual behavior crash errors (one per failed behavior).
180774
180774
  */
180775
180775
  logDetailedError(entityId, error) {
@@ -180918,7 +180918,7 @@ var BridgeRegistry = class _BridgeRegistry {
180918
180918
  * Check if auto composed devices mode is enabled.
180919
180919
  * When enabled, temperature sensors with auto-mapped humidity/pressure/battery
180920
180920
  * build real Matter Composed Devices (BridgedNodeEndpoint with sub-endpoints)
180921
- * rather than stacking extra clusters onto a flat TemperatureSensor β€”
180921
+ * rather than stacking extra clusters onto a flat TemperatureSensor.
180922
180922
  * Apple Home, Google Home, and Alexa render each sub-endpoint using its
180923
180923
  * own device type.
180924
180924
  */
@@ -181223,14 +181223,14 @@ var BridgeRegistry = class _BridgeRegistry {
181223
181223
  const segments = areaMapping[haAreaId];
181224
181224
  if (!segments || segments.length === 0) {
181225
181225
  _BridgeRegistry.cleanAreaLogger.debug(
181226
- `${entityId}: Skipping HA area ${haAreaId} \u2014 no segments mapped`
181226
+ `${entityId}: Skipping HA area ${haAreaId}, no segments mapped`
181227
181227
  );
181228
181228
  continue;
181229
181229
  }
181230
181230
  if (validSegmentIds && !segments.some((sid) => validSegmentIds.has(sid))) {
181231
181231
  const areaName2 = this.registry.areas.get(haAreaId) ?? haAreaId;
181232
181232
  _BridgeRegistry.cleanAreaLogger.info(
181233
- `${entityId}: Skipping stale HA area "${areaName2}" (${haAreaId}) \u2014 segments [${segments.join(", ")}] no longer exist on vacuum`
181233
+ `${entityId}: Skipping stale HA area "${areaName2}" (${haAreaId}), segments [${segments.join(", ")}] no longer exist on vacuum`
181234
181234
  );
181235
181235
  continue;
181236
181236
  }
@@ -181706,7 +181706,7 @@ ${e?.toString()}`);
181706
181706
  );
181707
181707
  if (totalSubs === 0 && sessions.length > 0) {
181708
181708
  this.log.warn(
181709
- `All subscriptions lost \u2014 ${sessions.length} session(s) still active, waiting for controller to re-subscribe`
181709
+ `All subscriptions lost, ${sessions.length} session(s) still active, waiting for controller to re-subscribe`
181710
181710
  );
181711
181711
  if (!this.deadSessionTimer) {
181712
181712
  this.deadSessionTimer = setTimeout(() => {
@@ -181745,7 +181745,7 @@ ${e?.toString()}`);
181745
181745
  for (const s of [...sessionManager.sessions]) {
181746
181746
  if (s !== newSession && !s.isClosing && s.peerNodeId === newSession.peerNodeId && s.fabric?.fabricIndex === newSession.fabric?.fabricIndex && s.subscriptions.size === 0) {
181747
181747
  this.log.info(
181748
- `Closing stale session ${s.id} (peer ${s.peerNodeId}, 0 subs) \u2014 replaced by session ${newSession.id}`
181748
+ `Closing stale session ${s.id} (peer ${s.peerNodeId}, 0 subs), replaced by session ${newSession.id}`
181749
181749
  );
181750
181750
  s.initiateForceClose().catch(() => {
181751
181751
  });
@@ -182166,7 +182166,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
182166
182166
  }
182167
182167
  }
182168
182168
  } else {
182169
- logger205.warn(`${entityId}: No device_id \u2014 cannot auto-assign battery`);
182169
+ logger205.warn(`${entityId}: No device_id, cannot auto-assign battery`);
182170
182170
  }
182171
182171
  const payload = {
182172
182172
  entity_id: entityId,
@@ -182222,7 +182222,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
182222
182222
  * Previous approaches that pushed state through
182223
182223
  * HomeAssistantEntityBehavior failed because the reactor writes
182224
182224
  * (RvcOperationalStateServer.update()) run inside the postCommit
182225
- * phase of the HAEntityBehavior transaction β€” those writes are
182225
+ * phase of the HAEntityBehavior transaction, those writes are
182226
182226
  * buffered but never committed, so no attrsChanged event reaches
182227
182227
  * the ServerSubscription.
182228
182228
  *
@@ -182468,11 +182468,11 @@ var ServerModeEndpointManager = class extends Service {
182468
182468
  }
182469
182469
  if (isHeapUnderPressure()) {
182470
182470
  this.log.error(
182471
- "Memory pressure detected \u2014 cannot create device endpoint. Reduce entities on other bridges or increase the Node.js heap size (NODE_OPTIONS=--max-old-space-size=1024)."
182471
+ "Memory pressure detected, cannot create device endpoint. Reduce entities on other bridges or increase the Node.js heap size (NODE_OPTIONS=--max-old-space-size=1024)."
182472
182472
  );
182473
182473
  this._failedEntities.push({
182474
182474
  entityId,
182475
- reason: "Skipped due to memory pressure \u2014 reduce entities or increase heap size"
182475
+ reason: "Skipped due to memory pressure, reduce entities or increase heap size"
182476
182476
  });
182477
182477
  return;
182478
182478
  }
@@ -182862,7 +182862,7 @@ function patchLevelControlTlv() {
182862
182862
  );
182863
182863
  } else {
182864
182864
  logger206.warn(
182865
- "Failed to patch LevelControl TLV schemas \u2014 field definitions not found. Google Home brightness adjustment may not work."
182865
+ "Failed to patch LevelControl TLV schemas, field definitions not found. Google Home brightness adjustment may not work."
182866
182866
  );
182867
182867
  }
182868
182868
  }