@riddix/hamh 2.1.0-alpha.709 → 2.1.0-alpha.711
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
|
|
60
|
-
- 🌦️ **Weather domain support
|
|
61
|
-
- 🤖 **Vacuum service-area editing
|
|
62
|
-
- 🔒 **Door Lock credential hardening
|
|
63
|
-
- ⚡ **Skip unchanged endpoints on HA updates
|
|
64
|
-
- 🔌 **Registry stays resilient when HA drops
|
|
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
|
|
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
|
|
71
|
-
- 🧵 **matter.js 0.17.0
|
|
72
|
-
- 🧰 Build/runtime fixes
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
package/dist/backend/cli.js
CHANGED
|
@@ -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
|
|
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,
|
|
@@ -125176,7 +125176,8 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
|
|
|
125176
125176
|
req.file.buffer
|
|
125177
125177
|
);
|
|
125178
125178
|
const existingIds = new Set(bridgeStorage.bridges.map((b) => b.id));
|
|
125179
|
-
const
|
|
125179
|
+
const bridgeIds = options.bridgeIds;
|
|
125180
|
+
const bridgesToRestore = bridgeIds ? backupData.bridges.filter((b) => bridgeIds.includes(b.id)) : backupData.bridges;
|
|
125180
125181
|
let bridgesRestored = 0;
|
|
125181
125182
|
let bridgesSkipped = 0;
|
|
125182
125183
|
let mappingsRestored = 0;
|
|
@@ -125220,6 +125221,7 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
|
|
|
125220
125221
|
coverSliderDebounceMs: config11.coverSliderDebounceMs,
|
|
125221
125222
|
disableClimateOnOff: config11.disableClimateOnOff,
|
|
125222
125223
|
disableClimateFanControl: config11.disableClimateFanControl,
|
|
125224
|
+
climateAutoMode: config11.climateAutoMode,
|
|
125223
125225
|
customServiceAreas: config11.customServiceAreas,
|
|
125224
125226
|
customFanSpeedTags: config11.customFanSpeedTags,
|
|
125225
125227
|
composedEntities: config11.composedEntities
|
|
@@ -125324,7 +125326,8 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
|
|
|
125324
125326
|
const options = req.body || {};
|
|
125325
125327
|
const { backupData, zipDirectory } = await extractBackupData(buffer);
|
|
125326
125328
|
const existingIds = new Set(bridgeStorage.bridges.map((b) => b.id));
|
|
125327
|
-
const
|
|
125329
|
+
const bridgeIds = options.bridgeIds;
|
|
125330
|
+
const bridgesToRestore = bridgeIds ? backupData.bridges.filter((b) => bridgeIds.includes(b.id)) : backupData.bridges;
|
|
125328
125331
|
let bridgesRestored = 0;
|
|
125329
125332
|
let bridgesSkipped = 0;
|
|
125330
125333
|
let mappingsRestored = 0;
|
|
@@ -125368,6 +125371,7 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
|
|
|
125368
125371
|
coverSliderDebounceMs: config11.coverSliderDebounceMs,
|
|
125369
125372
|
disableClimateOnOff: config11.disableClimateOnOff,
|
|
125370
125373
|
disableClimateFanControl: config11.disableClimateFanControl,
|
|
125374
|
+
climateAutoMode: config11.climateAutoMode,
|
|
125371
125375
|
customServiceAreas: config11.customServiceAreas,
|
|
125372
125376
|
customFanSpeedTags: config11.customFanSpeedTags,
|
|
125373
125377
|
composedEntities: config11.composedEntities
|
|
@@ -126211,6 +126215,7 @@ function entityMappingApi(mappingStorage) {
|
|
|
126211
126215
|
disableClimateFanControl: body.disableClimateFanControl,
|
|
126212
126216
|
climateKeepModeOnIdle: body.climateKeepModeOnIdle,
|
|
126213
126217
|
climateExposeFan: body.climateExposeFan,
|
|
126218
|
+
climateAutoMode: body.climateAutoMode,
|
|
126214
126219
|
composedEntities: body.composedEntities
|
|
126215
126220
|
};
|
|
126216
126221
|
const config11 = await mappingStorage.setMapping(request);
|
|
@@ -126678,7 +126683,8 @@ function configToProfileEntry(config11) {
|
|
|
126678
126683
|
disableClimateOnOff: config11.disableClimateOnOff,
|
|
126679
126684
|
disableClimateFanControl: config11.disableClimateFanControl,
|
|
126680
126685
|
climateKeepModeOnIdle: config11.climateKeepModeOnIdle,
|
|
126681
|
-
climateExposeFan: config11.climateExposeFan
|
|
126686
|
+
climateExposeFan: config11.climateExposeFan,
|
|
126687
|
+
climateAutoMode: config11.climateAutoMode
|
|
126682
126688
|
};
|
|
126683
126689
|
}
|
|
126684
126690
|
function mappingProfileApi(mappingStorage) {
|
|
@@ -126804,7 +126810,8 @@ function mappingProfileApi(mappingStorage) {
|
|
|
126804
126810
|
disableClimateOnOff: entry.disableClimateOnOff,
|
|
126805
126811
|
disableClimateFanControl: entry.disableClimateFanControl,
|
|
126806
126812
|
climateKeepModeOnIdle: entry.climateKeepModeOnIdle,
|
|
126807
|
-
climateExposeFan: entry.climateExposeFan
|
|
126813
|
+
climateExposeFan: entry.climateExposeFan,
|
|
126814
|
+
climateAutoMode: entry.climateAutoMode
|
|
126808
126815
|
});
|
|
126809
126816
|
applied++;
|
|
126810
126817
|
} catch (e) {
|
|
@@ -130741,9 +130748,10 @@ var EntityMappingStorage = class extends Service {
|
|
|
130741
130748
|
disableClimateFanControl: request.disableClimateFanControl || void 0,
|
|
130742
130749
|
climateKeepModeOnIdle: request.climateKeepModeOnIdle || void 0,
|
|
130743
130750
|
climateExposeFan: request.climateExposeFan || void 0,
|
|
130751
|
+
climateAutoMode: request.climateAutoMode || void 0,
|
|
130744
130752
|
composedEntities: request.composedEntities?.filter((e) => e.entityId?.trim()) ?? void 0
|
|
130745
130753
|
};
|
|
130746
|
-
if (!config11.matterDeviceType && !config11.customName && !config11.customProductName && !config11.customVendorName && !config11.customSerialNumber && config11.customVendorId === void 0 && config11.disabled !== true && !config11.filterLifeEntity && !config11.cleaningModeEntity && !config11.temperatureEntity && !config11.humidityEntity && !config11.batteryEntity && !config11.roomEntities && !config11.disableLockPin && !config11.powerEntity && !config11.energyEntity && !config11.pressureEntity && !config11.suctionLevelEntity && !config11.mopIntensityEntity && (!config11.customServiceAreas || config11.customServiceAreas.length === 0) && (!config11.customFanSpeedTags || Object.keys(config11.customFanSpeedTags).length === 0) && !config11.currentRoomEntity && !config11.valetudoIdentifier && !config11.coverSwapOpenClose && !config11.coverSliderDebounceMs && !config11.disableClimateOnOff && !config11.disableClimateFanControl && !config11.climateKeepModeOnIdle && !config11.climateExposeFan && (!config11.composedEntities || config11.composedEntities.length === 0)) {
|
|
130754
|
+
if (!config11.matterDeviceType && !config11.customName && !config11.customProductName && !config11.customVendorName && !config11.customSerialNumber && config11.customVendorId === void 0 && config11.disabled !== true && !config11.filterLifeEntity && !config11.cleaningModeEntity && !config11.temperatureEntity && !config11.humidityEntity && !config11.batteryEntity && !config11.roomEntities && !config11.disableLockPin && !config11.powerEntity && !config11.energyEntity && !config11.pressureEntity && !config11.suctionLevelEntity && !config11.mopIntensityEntity && (!config11.customServiceAreas || config11.customServiceAreas.length === 0) && (!config11.customFanSpeedTags || Object.keys(config11.customFanSpeedTags).length === 0) && !config11.currentRoomEntity && !config11.valetudoIdentifier && !config11.coverSwapOpenClose && !config11.coverSliderDebounceMs && !config11.disableClimateOnOff && !config11.disableClimateFanControl && !config11.climateKeepModeOnIdle && !config11.climateExposeFan && !config11.climateAutoMode && (!config11.composedEntities || config11.composedEntities.length === 0)) {
|
|
130747
130755
|
bridgeMap.delete(request.entityId);
|
|
130748
130756
|
} else {
|
|
130749
130757
|
bridgeMap.set(request.entityId, config11);
|
|
@@ -150795,6 +150803,15 @@ function getRunningModeFromHvacAction(entity) {
|
|
|
150795
150803
|
}
|
|
150796
150804
|
return hvacActionToRunningMode[action] ?? Thermostat3.ThermostatRunningMode.Off;
|
|
150797
150805
|
}
|
|
150806
|
+
function pinnedAutoSystemMode(override) {
|
|
150807
|
+
if (override === "cool") {
|
|
150808
|
+
return Thermostat3.SystemMode.Cool;
|
|
150809
|
+
}
|
|
150810
|
+
if (override === "heat") {
|
|
150811
|
+
return Thermostat3.SystemMode.Heat;
|
|
150812
|
+
}
|
|
150813
|
+
return void 0;
|
|
150814
|
+
}
|
|
150798
150815
|
var hvacModeToSystemMode = {
|
|
150799
150816
|
[ClimateHvacMode.heat]: Thermostat3.SystemMode.Heat,
|
|
150800
150817
|
[ClimateHvacMode.cool]: Thermostat3.SystemMode.Cool,
|
|
@@ -150848,6 +150865,16 @@ function computeSystemMode(entity, agent) {
|
|
|
150848
150865
|
}
|
|
150849
150866
|
const homeAssistant = agent.get(HomeAssistantEntityBehavior);
|
|
150850
150867
|
const entityId = homeAssistant.entityId;
|
|
150868
|
+
const pinnedMode = pinnedAutoSystemMode(
|
|
150869
|
+
homeAssistant.state.mapping?.climateAutoMode
|
|
150870
|
+
);
|
|
150871
|
+
if (pinnedMode != null) {
|
|
150872
|
+
lastHvacDirection.set(
|
|
150873
|
+
entityId,
|
|
150874
|
+
pinnedMode === Thermostat3.SystemMode.Cool ? "cooling" : "heating"
|
|
150875
|
+
);
|
|
150876
|
+
return pinnedMode;
|
|
150877
|
+
}
|
|
150851
150878
|
const action = attributes5(entity).hvac_action;
|
|
150852
150879
|
if (action === ClimateHvacAction.cooling) {
|
|
150853
150880
|
lastHvacDirection.set(entityId, "cooling");
|
|
@@ -162955,14 +162982,22 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
162955
162982
|
}
|
|
162956
162983
|
}, 55e3);
|
|
162957
162984
|
}
|
|
162958
|
-
|
|
162985
|
+
clearTimers() {
|
|
162959
162986
|
if (this.keepaliveTimer) {
|
|
162960
162987
|
clearInterval(this.keepaliveTimer);
|
|
162961
162988
|
this.keepaliveTimer = void 0;
|
|
162962
162989
|
}
|
|
162963
162990
|
this.flushUpdate.clear();
|
|
162991
|
+
}
|
|
162992
|
+
// dispose calls close(), not delete(), so clean up in both
|
|
162993
|
+
async delete() {
|
|
162994
|
+
this.clearTimers();
|
|
162964
162995
|
await super.delete();
|
|
162965
162996
|
}
|
|
162997
|
+
async close() {
|
|
162998
|
+
this.clearTimers();
|
|
162999
|
+
await super.close();
|
|
163000
|
+
}
|
|
162966
163001
|
/**
|
|
162967
163002
|
* Re-push the latest operational state through setStateOf.
|
|
162968
163003
|
* NoError stays detail-free so controllers do not display a false issue.
|