@riddix/hamh 2.1.0-alpha.792 → 2.1.0-alpha.794
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/dist/backend/cli.js
CHANGED
|
@@ -125304,6 +125304,12 @@ var init_bridge_config_schema = __esm({
|
|
|
125304
125304
|
description: "Append a suffix to every entity serial number on this bridge. Useful for forcing controllers like Aqara to treat devices as new and bypass cached device data. Leave empty for default behavior.",
|
|
125305
125305
|
maxLength: 16
|
|
125306
125306
|
},
|
|
125307
|
+
uniqueIdSuffix: {
|
|
125308
|
+
title: "Unique ID Suffix",
|
|
125309
|
+
type: "string",
|
|
125310
|
+
description: "Mixed into the unique ID of every bridged device on this bridge (standard bridge mode). Controllers like Alexa cache device records keyed on the unique ID, so setting or changing this can help mint fresh identities. Applies after a bridge restart, then re-discover in the controller. Leave empty for default behavior.",
|
|
125311
|
+
maxLength: 16
|
|
125312
|
+
},
|
|
125307
125313
|
sessionMaxAgeHours: {
|
|
125308
125314
|
title: "Session Rotation Max Age (hours)",
|
|
125309
125315
|
type: "number",
|
|
@@ -147720,6 +147726,9 @@ var BridgeDataProvider = class extends Service {
|
|
|
147720
147726
|
get serialNumberSuffix() {
|
|
147721
147727
|
return this.data.serialNumberSuffix;
|
|
147722
147728
|
}
|
|
147729
|
+
get uniqueIdSuffix() {
|
|
147730
|
+
return this.data.uniqueIdSuffix;
|
|
147731
|
+
}
|
|
147723
147732
|
get sessionMaxAgeHours() {
|
|
147724
147733
|
return this.data.sessionMaxAgeHours;
|
|
147725
147734
|
}
|
|
@@ -147753,6 +147762,7 @@ var BridgeDataProvider = class extends Service {
|
|
|
147753
147762
|
icon: this.icon,
|
|
147754
147763
|
priority: this.priority,
|
|
147755
147764
|
serialNumberSuffix: this.serialNumberSuffix,
|
|
147765
|
+
uniqueIdSuffix: this.uniqueIdSuffix,
|
|
147756
147766
|
sessionMaxAgeHours: this.sessionMaxAgeHours,
|
|
147757
147767
|
status: status3.code,
|
|
147758
147768
|
statusReason: status3.reason,
|
|
@@ -149965,6 +149975,7 @@ init_esm7();
|
|
|
149965
149975
|
import crypto6 from "node:crypto";
|
|
149966
149976
|
init_home_assistant_entity_behavior();
|
|
149967
149977
|
var logger191 = Logger.get("BasicInformationServer");
|
|
149978
|
+
var appliedUniqueIds = /* @__PURE__ */ new Map();
|
|
149968
149979
|
var BasicInformationServer2 = class extends BridgedDeviceBasicInformationServer {
|
|
149969
149980
|
async initialize() {
|
|
149970
149981
|
await super.initialize();
|
|
@@ -150004,12 +150015,24 @@ var BasicInformationServer2 = class extends BridgedDeviceBasicInformationServer
|
|
|
150004
150015
|
serialNumber,
|
|
150005
150016
|
// UniqueId helps controllers (especially Alexa) identify devices across
|
|
150006
150017
|
// multiple fabric connections. Using MD5 hash of entity_id for stability.
|
|
150007
|
-
|
|
150018
|
+
// uniqueIdSuffix mints a fresh identity so stale controller cloud
|
|
150019
|
+
// records keyed on it can be shed (#385).
|
|
150020
|
+
uniqueId: this.frozenUniqueId(entity.entity_id)
|
|
150008
150021
|
});
|
|
150009
150022
|
logger191.debug(
|
|
150010
150023
|
`[${entity.entity_id}] basicInfo vendor=${this.state.vendorName} product=${this.state.productName} label=${this.state.productLabel} serial=${this.state.serialNumber} node=${this.state.nodeLabel}`
|
|
150011
150024
|
);
|
|
150012
150025
|
}
|
|
150026
|
+
frozenUniqueId(entityId) {
|
|
150027
|
+
const provider = this.env.get(BridgeDataProvider);
|
|
150028
|
+
const key = `${provider.id}:${entityId}`;
|
|
150029
|
+
let uniqueId = appliedUniqueIds.get(key);
|
|
150030
|
+
if (uniqueId == null) {
|
|
150031
|
+
uniqueId = crypto6.createHash("md5").update(entityId + (provider.uniqueIdSuffix ?? "")).digest("hex").substring(0, 32);
|
|
150032
|
+
appliedUniqueIds.set(key, uniqueId);
|
|
150033
|
+
}
|
|
150034
|
+
return uniqueId;
|
|
150035
|
+
}
|
|
150013
150036
|
};
|
|
150014
150037
|
function ellipse(maxLength, value) {
|
|
150015
150038
|
return trimToLength(value, maxLength, "...");
|
|
@@ -150216,6 +150239,47 @@ var HaElectricalPowerMeasurementServer = ElectricalPowerMeasurementServerBase.se
|
|
|
150216
150239
|
]
|
|
150217
150240
|
});
|
|
150218
150241
|
|
|
150242
|
+
// src/matter/behaviors/fan-speed-memory.ts
|
|
150243
|
+
init_esm7();
|
|
150244
|
+
|
|
150245
|
+
// ../../node_modules/.pnpm/@matter+main@0.17.3/node_modules/@matter/main/dist/esm/model.js
|
|
150246
|
+
init_nodejs();
|
|
150247
|
+
init_esm2();
|
|
150248
|
+
|
|
150249
|
+
// src/matter/behaviors/fan-speed-memory.ts
|
|
150250
|
+
var FanSpeedMemoryBehavior = class extends Behavior {
|
|
150251
|
+
static id = "fanSpeedMemory";
|
|
150252
|
+
static schema = new DatatypeModel(
|
|
150253
|
+
{ name: "FanSpeedMemoryState", type: "struct" },
|
|
150254
|
+
FieldElement({
|
|
150255
|
+
name: "lastPercent",
|
|
150256
|
+
type: "uint8",
|
|
150257
|
+
quality: "N",
|
|
150258
|
+
default: 0
|
|
150259
|
+
}),
|
|
150260
|
+
FieldElement({
|
|
150261
|
+
name: "lastSpeed",
|
|
150262
|
+
type: "uint8",
|
|
150263
|
+
quality: "N",
|
|
150264
|
+
default: 0
|
|
150265
|
+
}),
|
|
150266
|
+
FieldElement({
|
|
150267
|
+
name: "lastAuto",
|
|
150268
|
+
type: "bool",
|
|
150269
|
+
quality: "N",
|
|
150270
|
+
default: false
|
|
150271
|
+
})
|
|
150272
|
+
);
|
|
150273
|
+
};
|
|
150274
|
+
((FanSpeedMemoryBehavior2) => {
|
|
150275
|
+
class State {
|
|
150276
|
+
lastPercent = 0;
|
|
150277
|
+
lastSpeed = 0;
|
|
150278
|
+
lastAuto = false;
|
|
150279
|
+
}
|
|
150280
|
+
FanSpeedMemoryBehavior2.State = State;
|
|
150281
|
+
})(FanSpeedMemoryBehavior || (FanSpeedMemoryBehavior = {}));
|
|
150282
|
+
|
|
150219
150283
|
// src/matter/endpoints/composed/composed-air-purifier-endpoint.ts
|
|
150220
150284
|
init_home_assistant_entity_behavior();
|
|
150221
150285
|
|
|
@@ -150979,10 +151043,26 @@ var FeaturedBase5 = FanControlServer.with(
|
|
|
150979
151043
|
windSupport: { naturalWind: true, sleepWind: true }
|
|
150980
151044
|
});
|
|
150981
151045
|
var FanControlServerBase = class extends FeaturedBase5 {
|
|
150982
|
-
//
|
|
151046
|
+
// Fallback last-speed tracking for endpoints without FanSpeedMemoryBehavior
|
|
151047
|
+
// (climate companion, humidifier). matter.js builds behavior instances per
|
|
151048
|
+
// transaction, so these fields only live within one interaction; fans use
|
|
151049
|
+
// the persisted memory behavior instead (#225/#387).
|
|
150983
151050
|
lastNonZeroPercent = 0;
|
|
150984
151051
|
lastNonZeroSpeed = 0;
|
|
150985
151052
|
lastIsAutoMode = false;
|
|
151053
|
+
// Remembered speed, read at decision time. Behavior state survives
|
|
151054
|
+
// transactions and restarts, instance fields do not (#387).
|
|
151055
|
+
remembered() {
|
|
151056
|
+
if (this.agent.has(FanSpeedMemoryBehavior)) {
|
|
151057
|
+
const s = this.agent.get(FanSpeedMemoryBehavior).state;
|
|
151058
|
+
return { percent: s.lastPercent, speed: s.lastSpeed, auto: s.lastAuto };
|
|
151059
|
+
}
|
|
151060
|
+
return {
|
|
151061
|
+
percent: this.lastNonZeroPercent,
|
|
151062
|
+
speed: this.lastNonZeroSpeed,
|
|
151063
|
+
auto: this.lastIsAutoMode
|
|
151064
|
+
};
|
|
151065
|
+
}
|
|
150986
151066
|
async initialize() {
|
|
150987
151067
|
if (this.features.multiSpeed) {
|
|
150988
151068
|
if (this.state.speedMax == null || this.state.speedMax < minSpeedMax) {
|
|
@@ -151000,6 +151080,13 @@ var FanControlServerBase = class extends FeaturedBase5 {
|
|
|
151000
151080
|
this.lastNonZeroSpeed = ss;
|
|
151001
151081
|
}
|
|
151002
151082
|
}
|
|
151083
|
+
if (this.agent.has(FanSpeedMemoryBehavior)) {
|
|
151084
|
+
const memory = await this.agent.load(FanSpeedMemoryBehavior);
|
|
151085
|
+
if (memory.state.lastPercent === 0 && this.lastNonZeroPercent > 0) {
|
|
151086
|
+
memory.state.lastPercent = this.lastNonZeroPercent;
|
|
151087
|
+
memory.state.lastSpeed = this.lastNonZeroSpeed;
|
|
151088
|
+
}
|
|
151089
|
+
}
|
|
151003
151090
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
151004
151091
|
this.update(homeAssistant.entity);
|
|
151005
151092
|
this.reactTo(homeAssistant.onChange, this.update);
|
|
@@ -151095,6 +151182,7 @@ var FanControlServerBase = class extends FeaturedBase5 {
|
|
|
151095
151182
|
this.lastNonZeroPercent = percentage;
|
|
151096
151183
|
this.lastNonZeroSpeed = speed;
|
|
151097
151184
|
this.lastIsAutoMode = config11.isInAutoMode(entity.state, this.agent);
|
|
151185
|
+
this.persistSpeed(this.lastIsAutoMode);
|
|
151098
151186
|
}
|
|
151099
151187
|
try {
|
|
151100
151188
|
applyPatchState(this.state, {
|
|
@@ -151207,20 +151295,21 @@ var FanControlServerBase = class extends FeaturedBase5 {
|
|
|
151207
151295
|
}
|
|
151208
151296
|
const restoreOnPowerOn = homeAssistant.state.mapping?.fanRestoreSpeedOnPowerOn === true;
|
|
151209
151297
|
const wasOff = homeAssistant.entity.state?.state === "off" || this.agent.has(OnOffBehavior) && !this.agent.get(OnOffBehavior).state.onOff;
|
|
151298
|
+
const remembered = this.remembered();
|
|
151210
151299
|
if (wasOff) {
|
|
151211
151300
|
logger198.debug(
|
|
151212
|
-
`[${homeAssistant.entityId}] power-on write ${percentage}%: restore flag=${restoreOnPowerOn}, last speed=${
|
|
151301
|
+
`[${homeAssistant.entityId}] power-on write ${percentage}%: restore flag=${restoreOnPowerOn}, last speed=${remembered.percent}`
|
|
151213
151302
|
);
|
|
151214
151303
|
}
|
|
151215
|
-
if (restoreOnPowerOn && wasOff &&
|
|
151216
|
-
percentage =
|
|
151304
|
+
if (restoreOnPowerOn && wasOff && remembered.percent > 0 && percentage > 0) {
|
|
151305
|
+
percentage = remembered.percent;
|
|
151217
151306
|
try {
|
|
151218
151307
|
applyPatchState(this.state, {
|
|
151219
|
-
percentSetting:
|
|
151220
|
-
percentCurrent:
|
|
151221
|
-
...this.features.multiSpeed &&
|
|
151222
|
-
speedSetting:
|
|
151223
|
-
speedCurrent:
|
|
151308
|
+
percentSetting: remembered.percent,
|
|
151309
|
+
percentCurrent: remembered.percent,
|
|
151310
|
+
...this.features.multiSpeed && remembered.speed > 0 ? {
|
|
151311
|
+
speedSetting: remembered.speed,
|
|
151312
|
+
speedCurrent: remembered.speed
|
|
151224
151313
|
} : {}
|
|
151225
151314
|
});
|
|
151226
151315
|
} catch {
|
|
@@ -151279,6 +151368,23 @@ var FanControlServerBase = class extends FeaturedBase5 {
|
|
|
151279
151368
|
Math.ceil(speedMax * (percentage / 100))
|
|
151280
151369
|
);
|
|
151281
151370
|
}
|
|
151371
|
+
this.persistSpeed(false);
|
|
151372
|
+
}
|
|
151373
|
+
// Write the remembered speed through to the memory behavior. Instance
|
|
151374
|
+
// fields die with the transaction, this is what later interactions and
|
|
151375
|
+
// restarts read (#387).
|
|
151376
|
+
persistSpeed(auto) {
|
|
151377
|
+
if (!this.agent.has(FanSpeedMemoryBehavior)) {
|
|
151378
|
+
return;
|
|
151379
|
+
}
|
|
151380
|
+
try {
|
|
151381
|
+
applyPatchState(this.agent.get(FanSpeedMemoryBehavior).state, {
|
|
151382
|
+
lastPercent: this.lastNonZeroPercent,
|
|
151383
|
+
lastSpeed: this.lastNonZeroSpeed,
|
|
151384
|
+
...auto !== void 0 ? { lastAuto: auto } : {}
|
|
151385
|
+
});
|
|
151386
|
+
} catch {
|
|
151387
|
+
}
|
|
151282
151388
|
}
|
|
151283
151389
|
targetAirflowDirectionChanged(airflowDirection, _oldValue, context) {
|
|
151284
151390
|
if (transactionIsOffline(context)) {
|
|
@@ -151341,25 +151447,26 @@ var FanControlServerBase = class extends FeaturedBase5 {
|
|
|
151341
151447
|
if (transactionIsOffline(context)) {
|
|
151342
151448
|
return;
|
|
151343
151449
|
}
|
|
151344
|
-
|
|
151450
|
+
const remembered = this.remembered();
|
|
151451
|
+
if (onOff && remembered.percent > 0) {
|
|
151345
151452
|
this.agent.asLocalActor(() => {
|
|
151346
151453
|
try {
|
|
151347
151454
|
applyPatchState(this.state, {
|
|
151348
|
-
percentSetting:
|
|
151349
|
-
...this.features.multiSpeed &&
|
|
151455
|
+
percentSetting: remembered.percent,
|
|
151456
|
+
...this.features.multiSpeed && remembered.speed > 0 ? { speedSetting: remembered.speed } : {}
|
|
151350
151457
|
});
|
|
151351
151458
|
} catch {
|
|
151352
151459
|
}
|
|
151353
151460
|
});
|
|
151354
151461
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
151355
151462
|
if (homeAssistant.isAvailable) {
|
|
151356
|
-
if (
|
|
151463
|
+
if (remembered.auto) {
|
|
151357
151464
|
homeAssistant.callAction(
|
|
151358
151465
|
this.state.config.setAutoMode(void 0, this.agent)
|
|
151359
151466
|
);
|
|
151360
151467
|
} else {
|
|
151361
151468
|
homeAssistant.callAction(
|
|
151362
|
-
this.state.config.turnOn(
|
|
151469
|
+
this.state.config.turnOn(remembered.percent, this.agent)
|
|
151363
151470
|
);
|
|
151364
151471
|
}
|
|
151365
151472
|
}
|
|
@@ -151593,7 +151700,8 @@ var ComposedAirPurifierEndpoint = class _ComposedAirPurifierEndpoint extends End
|
|
|
151593
151700
|
IdentifyServer2,
|
|
151594
151701
|
HomeAssistantEntityBehavior,
|
|
151595
151702
|
FanOnOffServer,
|
|
151596
|
-
FanFanControlServer.with(...features3)
|
|
151703
|
+
FanFanControlServer.with(...features3),
|
|
151704
|
+
FanSpeedMemoryBehavior
|
|
151597
151705
|
);
|
|
151598
151706
|
const hasFilterLife = airPurifierAttributes.filter_life != null || airPurifierAttributes.filter_life_remaining != null || airPurifierAttributes.filter_life_level != null || !!config11.mapping?.filterLifeEntity;
|
|
151599
151707
|
if (hasFilterLife) {
|
|
@@ -153630,7 +153738,8 @@ function AirPurifierEndpoint(homeAssistantEntity) {
|
|
|
153630
153738
|
BasicInformationServer2,
|
|
153631
153739
|
HomeAssistantEntityBehavior,
|
|
153632
153740
|
FanOnOffServer,
|
|
153633
|
-
FanFanControlServer.with(...features3)
|
|
153741
|
+
FanFanControlServer.with(...features3),
|
|
153742
|
+
FanSpeedMemoryBehavior
|
|
153634
153743
|
);
|
|
153635
153744
|
if (hasFilterLifeSupport(attributes9, mapping)) {
|
|
153636
153745
|
const deviceWithFilter = baseDevice.with(
|
|
@@ -155378,6 +155487,7 @@ function FanDevice2(homeAssistantEntity) {
|
|
|
155378
155487
|
GroupsServer,
|
|
155379
155488
|
FanOnOffServer,
|
|
155380
155489
|
FanFanControlServer.with(...features3),
|
|
155490
|
+
FanSpeedMemoryBehavior,
|
|
155381
155491
|
DefaultPowerSourceServer
|
|
155382
155492
|
) : FanDevice.with(
|
|
155383
155493
|
IdentifyServer2,
|
|
@@ -155385,7 +155495,8 @@ function FanDevice2(homeAssistantEntity) {
|
|
|
155385
155495
|
HomeAssistantEntityBehavior,
|
|
155386
155496
|
GroupsServer,
|
|
155387
155497
|
FanOnOffServer,
|
|
155388
|
-
FanFanControlServer.with(...features3)
|
|
155498
|
+
FanFanControlServer.with(...features3),
|
|
155499
|
+
FanSpeedMemoryBehavior
|
|
155389
155500
|
);
|
|
155390
155501
|
return device.set({ homeAssistantEntity });
|
|
155391
155502
|
}
|
|
@@ -169052,6 +169163,7 @@ export {
|
|
|
169052
169163
|
@matter/types/dist/esm/clusters/web-rtc-transport-definitions.js:
|
|
169053
169164
|
@matter/types/dist/esm/clusters/index.js:
|
|
169054
169165
|
@matter/main/dist/esm/clusters.js:
|
|
169166
|
+
@matter/main/dist/esm/model.js:
|
|
169055
169167
|
@matter/main/dist/esm/forwards/behaviors/boolean-state.js:
|
|
169056
169168
|
@matter/main/dist/esm/forwards/behaviors/smoke-co-alarm.js:
|
|
169057
169169
|
@matter/main/dist/esm/forwards/behaviors/operational-state.js:
|