@riddix/hamh 2.1.0-alpha.710 → 2.1.0-alpha.712

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,22 +56,22 @@ of port forwarding etc.
56
56
 
57
57
  **New in v2.0.46:**
58
58
 
59
- - ❄️ Opt-in **companion fan** for climate ACs a per-entity toggle exposes the AC's fan as its own Matter fan endpoint, the setting is persisted, and fan-speed presets are now ordered low→high ([#309](https://github.com/RiDDiX/home-assistant-matter-hub/issues/309))
60
- - 🌦️ **Weather domain support** `weather.*` entities are exposed as a composed Temperature + Humidity + Pressure sensor read from the entity's attributes (pressure converted to hPa, shown on Google Home)
61
- - 🤖 **Vacuum service-area editing** edit area data inline in Entity Mapping and dispatch room cleaning in batches, plus a batch-room-data fix ([#291](https://github.com/RiDDiX/home-assistant-matter-hub/issues/291))
62
- - 🔒 **Door Lock credential hardening** safer access-code handling and fabric-index casting on the lock cluster ([#313](https://github.com/RiDDiX/home-assistant-matter-hub/issues/313))
63
- - ⚡ **Skip unchanged endpoints on HA updates** only endpoints whose entity or a mapped sub-entity actually changed are refreshed, so CPU no longer scales with entity count × event rate ([#351](https://github.com/RiDDiX/home-assistant-matter-hub/issues/351))
64
- - 🔌 **Registry stays resilient when HA drops** an initial reload failure no longer puts the add-on in a restart loop on a flaky HA boot, and a mid-flight "Connection lost" retries once ([#352](https://github.com/RiDDiX/home-assistant-matter-hub/issues/352))
59
+ - ❄️ Opt-in **companion fan** for climate ACs: a per-entity toggle exposes the AC's fan as its own Matter fan endpoint, the setting is persisted, and fan-speed presets are now ordered low→high ([#309](https://github.com/RiDDiX/home-assistant-matter-hub/issues/309))
60
+ - 🌦️ **Weather domain support**: `weather.*` entities are exposed as a composed Temperature + Humidity + Pressure sensor read from the entity's attributes (pressure converted to hPa, shown on Google Home)
61
+ - 🤖 **Vacuum service-area editing**: edit area data inline in Entity Mapping and dispatch room cleaning in batches, plus a batch-room-data fix ([#291](https://github.com/RiDDiX/home-assistant-matter-hub/issues/291))
62
+ - 🔒 **Door Lock credential hardening**: safer access-code handling and fabric-index casting on the lock cluster ([#313](https://github.com/RiDDiX/home-assistant-matter-hub/issues/313))
63
+ - ⚡ **Skip unchanged endpoints on HA updates**: only endpoints whose entity or a mapped sub-entity actually changed are refreshed, so CPU no longer scales with entity count × event rate ([#351](https://github.com/RiDDiX/home-assistant-matter-hub/issues/351))
64
+ - 🔌 **Registry stays resilient when HA drops**: an initial reload failure no longer puts the add-on in a restart loop on a flaky HA boot, and a mid-flight "Connection lost" retries once ([#352](https://github.com/RiDDiX/home-assistant-matter-hub/issues/352))
65
65
  - 🔁 **RVC sessions refreshed safely** so vacuum reactors don't go stale ([#287](https://github.com/RiDDiX/home-assistant-matter-hub/issues/287))
66
66
  - 🪟 **Tilt-only covers** use the tilt channel for lift commands ([#350](https://github.com/RiDDiX/home-assistant-matter-hub/issues/350))
67
67
  - 🔋 **Battery auto-mapping narrowed** to avoid false matches, plus support for enum battery states ([#359](https://github.com/RiDDiX/home-assistant-matter-hub/issues/359))
68
- - 🔘 **`automation` entities are momentary** turning one on triggers it and snaps back to off ([#364](https://github.com/RiDDiX/home-assistant-matter-hub/issues/364))
68
+ - 🔘 **`automation` entities are momentary**: turning one on triggers it and snaps back to off ([#364](https://github.com/RiDDiX/home-assistant-matter-hub/issues/364))
69
69
  - 🌀 **Climate swing-mode handling fix**
70
- - 🚨 **Non-5540 Alexa bridge warning** a bridge on any other port now warns, since Alexa only pairs on port 5540
71
- - 🧵 **matter.js 0.17.0** upgraded from 0.16.11; the local LG-TV NOC-serial patch is dropped because upstream now tolerates 21-octet operational cert serials ([#305](https://github.com/RiDDiX/home-assistant-matter-hub/issues/305))
72
- - 🧰 Build/runtime fixes `bun:sqlite` `constants` export stubbed so the esbuild bundle builds against matter.js 0.17.0, add-on heap flag preserved ([#358](https://github.com/RiDDiX/home-assistant-matter-hub/issues/358))
70
+ - 🚨 **Non-5540 Alexa bridge warning**: a bridge on any other port now warns, since Alexa only pairs on port 5540
71
+ - 🧵 **matter.js 0.17.0**: upgraded from 0.16.11; the local LG-TV NOC-serial patch is dropped because upstream now tolerates 21-octet operational cert serials ([#305](https://github.com/RiDDiX/home-assistant-matter-hub/issues/305))
72
+ - 🧰 Build/runtime fixes: `bun:sqlite` `constants` export stubbed so the esbuild bundle builds against matter.js 0.17.0, add-on heap flag preserved ([#358](https://github.com/RiDDiX/home-assistant-matter-hub/issues/358))
73
73
  - ⬆️ Dependency vulnerabilities resolved
74
- - 📝 Docs `hvac_action` requirement for the Auto running-state display ([#309](https://github.com/RiDDiX/home-assistant-matter-hub/issues/309)), Google Home ModeSelect label gap ([#356](https://github.com/RiDDiX/home-assistant-matter-hub/issues/356)), Alexa cover-routine limitation ([#312](https://github.com/RiDDiX/home-assistant-matter-hub/issues/312)), and the new weather domain
74
+ - 📝 Docs: `hvac_action` requirement for the Auto running-state display ([#309](https://github.com/RiDDiX/home-assistant-matter-hub/issues/309)), Google Home ModeSelect label gap ([#356](https://github.com/RiDDiX/home-assistant-matter-hub/issues/356)), Alexa cover-routine limitation ([#312](https://github.com/RiDDiX/home-assistant-matter-hub/issues/312)), and the new weather domain
75
75
 
76
76
  **Previously in v2.0.45 (hotfix release):**
77
77
 
@@ -79,12 +79,12 @@ of port forwarding etc.
79
79
 
80
80
  **Previously in v2.0.44:**
81
81
 
82
- - 🪟 Cover reliability overhaul Matter state/target/current reports split and correctly ordered, deferred target writes de-duplicated, legacy position attributes dropped from updates, cluster profile aligned with the certified Eve blind, current position held during external motion ([#328](https://github.com/RiDDiX/home-assistant-matter-hub/issues/328))
82
+ - 🪟 Cover reliability overhaul: Matter state/target/current reports split and correctly ordered, deferred target writes de-duplicated, legacy position attributes dropped from updates, cluster profile aligned with the certified Eve blind, current position held during external motion ([#328](https://github.com/RiDDiX/home-assistant-matter-hub/issues/328))
83
83
  - 🎚️ Per-bridge and per-entity cover slider debounce, window widened to 300 ms for smoother slider control ([#331](https://github.com/RiDDiX/home-assistant-matter-hub/issues/331))
84
84
  - 🤖 Vacuum service-area handling: `customServiceAreas` preserved in dynamic `RvcRunMode` supported modes, custom areas dispatched sequentially, `currentArea` cleared on dock return and no longer inherited stale across restarts, `observedCleaning` set on every cleaning event ([#335](https://github.com/RiDDiX/home-assistant-matter-hub/issues/335))
85
85
  - 🔋 Docked vacuum stops reporting charging once the battery is full ([#334](https://github.com/RiDDiX/home-assistant-matter-hub/issues/334))
86
86
  - ❄️ Per-entity `climateKeepModeOnIdle` for off+idle ACs; mode kept through a cool→off transition, freeze applied immediately on off and cleared on `action=off` ([#340](https://github.com/RiDDiX/home-assistant-matter-hub/issues/340))
87
- - 🔁 Matter session rotation opt-in per-bridge setting, aged sessions rotated, RVC clean-mode reactor goes offline correctly, `pushKeepalive` guarded on construction ([#287](https://github.com/RiDDiX/home-assistant-matter-hub/issues/287))
87
+ - 🔁 Matter session rotation: opt-in per-bridge setting, aged sessions rotated, RVC clean-mode reactor goes offline correctly, `pushKeepalive` guarded on construction ([#287](https://github.com/RiDDiX/home-assistant-matter-hub/issues/287))
88
88
  - 🧠 Heap-headroom and force-sync pressure guard to reduce memory pressure ([#347](https://github.com/RiDDiX/home-assistant-matter-hub/issues/347))
89
89
  - 🏷️ Per-entity `customVendorId` with Home Assistant device-registry serial fallback ([#290](https://github.com/RiDDiX/home-assistant-matter-hub/issues/290))
90
90
  - 🔢 `serialNumberSuffix` now loads when editing a bridge and is preserved when the serial is trimmed to 32 characters ([#330](https://github.com/RiDDiX/home-assistant-matter-hub/issues/330))
@@ -97,7 +97,7 @@ of port forwarding etc.
97
97
  - 🧩 JSON editor de-duplicates `@codemirror/state` ([#345](https://github.com/RiDDiX/home-assistant-matter-hub/issues/345))
98
98
  - 🌍 Polish translation update, credited to [@MStankiewiczOfficial](https://github.com/MStankiewiczOfficial) ([#329](https://github.com/RiDDiX/home-assistant-matter-hub/pull/329))
99
99
  - ✅ Added regression test coverage for the session-max-age parser ([#287](https://github.com/RiDDiX/home-assistant-matter-hub/issues/287))
100
- - ⬆️ Dependency hygiene transitive deps flagged by Dependabot patched, `serialize-javascript` bumped to 7.0.5 in docs-site
100
+ - ⬆️ Dependency hygiene: transitive deps flagged by Dependabot patched, `serialize-javascript` bumped to 7.0.5 in docs-site
101
101
 
102
102
  **Previously in v2.0.43:**
103
103
 
@@ -124137,7 +124137,7 @@ var init_bridge_config_schema = __esm({
124137
124137
  },
124138
124138
  coverSliderDebounceMs: {
124139
124139
  title: "Cover Slider Debounce (ms)",
124140
- description: "Override the cover position-update debounce window for this bridge. Some controllers (Apple Home) stream slider updates while the user is still dragging, causing covers to start moving toward an intermediate target. Set to the time the bridge should wait after the last update before sending the final value to Home Assistant. 0 keeps the built-in two-phase debounce (400 ms initial / 150 ms subsequent), which fits most controllers. Try 800\u20131500 ms for slow blinds. A per-entity override on a single cover wins over this flag.",
124140
+ description: "Override the cover position-update debounce window for this bridge. Some controllers (Apple Home) stream slider updates while the user is still dragging, causing covers to start moving toward an intermediate target. Set to the time the bridge should wait after the last update before sending the final value to Home Assistant. 0 keeps the built-in two-phase debounce (400 ms initial / 150 ms subsequent), which fits most controllers. Try 800-1500 ms for slow blinds. A per-entity override on a single cover wins over this flag.",
124141
124141
  type: "number",
124142
124142
  minimum: 0,
124143
124143
  maximum: 5e3,
@@ -145361,6 +145361,15 @@ var ServerModeServerNode = class extends ServerNode {
145361
145361
  );
145362
145362
  }
145363
145363
  }
145364
+ // align the pairing device-type hint with the real device (default is vacuum)
145365
+ async updateAdvertisedDeviceType(deviceType) {
145366
+ try {
145367
+ await this.set({ productDescription: { deviceType } });
145368
+ } catch (e) {
145369
+ const msg = e instanceof Error ? e.message : String(e);
145370
+ logger180.warn(`Failed to set server-mode device type: ${msg}`);
145371
+ }
145372
+ }
145364
145373
  async factoryReset() {
145365
145374
  await this.cancel();
145366
145375
  await this.erase();
@@ -160218,10 +160227,29 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
160218
160227
  }
160219
160228
  };
160220
160229
 
160230
+ // src/matter/endpoints/standalone-endpoint-type.ts
160231
+ init_esm7();
160232
+ var BRIDGED_INFO_ID = "bridgedDeviceBasicInformation";
160233
+ function asStandaloneEndpointType(type) {
160234
+ const behaviors = type.behaviors;
160235
+ if (!(BRIDGED_INFO_ID in behaviors)) {
160236
+ return type;
160237
+ }
160238
+ const kept = Object.entries(behaviors).filter(([id]) => id !== BRIDGED_INFO_ID).map(([, behavior]) => behavior);
160239
+ return MutableEndpoint({
160240
+ name: type.name,
160241
+ deviceType: type.deviceType,
160242
+ deviceRevision: type.deviceRevision,
160243
+ deviceClass: type.deviceClass,
160244
+ requirements: type.requirements,
160245
+ behaviors: SupportedBehaviors(...kept)
160246
+ });
160247
+ }
160248
+
160221
160249
  // src/matter/endpoints/legacy/legacy-endpoint.ts
160222
160250
  var logger225 = Logger.get("LegacyEndpoint");
160223
160251
  var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
160224
- static async create(registry2, entityId, mapping, pluginDomainMappings) {
160252
+ static async create(registry2, entityId, mapping, pluginDomainMappings, standalone = false) {
160225
160253
  const deviceRegistry = registry2.deviceOf(entityId);
160226
160254
  let state = registry2.initialState(entityId);
160227
160255
  const entity = registry2.entity(entityId);
@@ -160547,7 +160575,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
160547
160575
  }
160548
160576
  }
160549
160577
  const areaName = registry2.getAreaName(entityId);
160550
- const type = createLegacyEndpointType(payload, effectiveMapping, areaName, {
160578
+ let type = createLegacyEndpointType(payload, effectiveMapping, areaName, {
160551
160579
  vacuumOnOff: registry2.isVacuumOnOffEnabled(),
160552
160580
  cleaningModeOptions,
160553
160581
  pluginDomainMappings
@@ -160555,6 +160583,9 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
160555
160583
  if (!type) {
160556
160584
  return;
160557
160585
  }
160586
+ if (standalone) {
160587
+ type = asStandaloneEndpointType(type);
160588
+ }
160558
160589
  const customName = effectiveMapping?.customName;
160559
160590
  const mappedIds = getMappedEntityIds(effectiveMapping);
160560
160591
  return new _LegacyEndpoint(type, entityId, customName, mappedIds);
@@ -162982,14 +163013,22 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
162982
163013
  }
162983
163014
  }, 55e3);
162984
163015
  }
162985
- async delete() {
163016
+ clearTimers() {
162986
163017
  if (this.keepaliveTimer) {
162987
163018
  clearInterval(this.keepaliveTimer);
162988
163019
  this.keepaliveTimer = void 0;
162989
163020
  }
162990
163021
  this.flushUpdate.clear();
163022
+ }
163023
+ // dispose calls close(), not delete(), so clean up in both
163024
+ async delete() {
163025
+ this.clearTimers();
162991
163026
  await super.delete();
162992
163027
  }
163028
+ async close() {
163029
+ this.clearTimers();
163030
+ await super.close();
163031
+ }
162993
163032
  /**
162994
163033
  * Re-push the latest operational state through setStateOf.
162995
163034
  * NoError stays detail-free so controllers do not display a false issue.
@@ -163235,7 +163274,9 @@ var ServerModeEndpointManager = class extends Service {
163235
163274
  const endpoint = await LegacyEndpoint.create(
163236
163275
  this.registry,
163237
163276
  entityId,
163238
- mapping
163277
+ mapping,
163278
+ void 0,
163279
+ true
163239
163280
  );
163240
163281
  if (!endpoint) {
163241
163282
  this._failedEntities.push({
@@ -163278,6 +163319,10 @@ var ServerModeEndpointManager = class extends Service {
163278
163319
  mapping,
163279
163320
  friendlyName
163280
163321
  );
163322
+ const deviceType = this.deviceEndpoint?.type?.deviceType;
163323
+ if (deviceType != null) {
163324
+ await this.serverNode.updateAdvertisedDeviceType(deviceType);
163325
+ }
163281
163326
  }
163282
163327
  /**
163283
163328
  * Creates a Server Mode Vacuum endpoint without BridgedDeviceBasicInformation.