@riddix/hamh 2.1.0-alpha.872 → 2.1.0-alpha.873
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
|
@@ -158205,6 +158205,139 @@ function ensureCommissioningConfig(server) {
|
|
|
158205
158205
|
// src/services/bridges/bridge.ts
|
|
158206
158206
|
init_diagnostic_event_bus();
|
|
158207
158207
|
|
|
158208
|
+
// src/services/bridges/entity-isolation-service.ts
|
|
158209
|
+
init_esm();
|
|
158210
|
+
init_diagnostic_event_bus();
|
|
158211
|
+
var logger204 = Logger.get("EntityIsolation");
|
|
158212
|
+
var EntityIsolationServiceImpl = class {
|
|
158213
|
+
isolatedEntities = /* @__PURE__ */ new Map();
|
|
158214
|
+
isolationCallbacks = /* @__PURE__ */ new Map();
|
|
158215
|
+
/**
|
|
158216
|
+
* Register a callback to be called when an entity needs to be isolated.
|
|
158217
|
+
* The callback should remove the entity from the bridge's aggregator.
|
|
158218
|
+
*/
|
|
158219
|
+
registerIsolationCallback(bridgeId, callback) {
|
|
158220
|
+
this.isolationCallbacks.set(bridgeId, callback);
|
|
158221
|
+
}
|
|
158222
|
+
unregisterIsolationCallback(bridgeId) {
|
|
158223
|
+
this.isolationCallbacks.delete(bridgeId);
|
|
158224
|
+
}
|
|
158225
|
+
/**
|
|
158226
|
+
* Parse the endpoint path from a Matter.js error message and extract the entity name.
|
|
158227
|
+
* Example path: "ed5b4f8d042e4599b833f21da4ededba.aggregator.Küchenlicht.onOff.on"
|
|
158228
|
+
* Returns: { bridgeId: "ed5b4f8d...", entityName: "Küchenlicht" }
|
|
158229
|
+
*/
|
|
158230
|
+
parseEndpointPath(errorMessage) {
|
|
158231
|
+
const match = errorMessage.match(/([a-f0-9]{32})\.aggregator\.([^.\s>]+)/i);
|
|
158232
|
+
if (match) {
|
|
158233
|
+
return {
|
|
158234
|
+
bridgeId: match[1],
|
|
158235
|
+
entityName: match[2]
|
|
158236
|
+
};
|
|
158237
|
+
}
|
|
158238
|
+
return null;
|
|
158239
|
+
}
|
|
158240
|
+
classifyError(msg) {
|
|
158241
|
+
if (msg.includes("Invalid intervalMs")) {
|
|
158242
|
+
return "Subscription timing error (Invalid intervalMs)";
|
|
158243
|
+
}
|
|
158244
|
+
if (msg.includes("Behaviors have errors")) {
|
|
158245
|
+
return "Behavior initialization failure";
|
|
158246
|
+
}
|
|
158247
|
+
if (msg.includes("TransactionDestroyedError")) {
|
|
158248
|
+
return "Transaction destroyed during operation";
|
|
158249
|
+
}
|
|
158250
|
+
if (msg.includes("DestroyedDependencyError")) {
|
|
158251
|
+
return "Dependency destroyed during operation";
|
|
158252
|
+
}
|
|
158253
|
+
if (msg.includes("UninitializedDependencyError")) {
|
|
158254
|
+
return "Uninitialized dependency access";
|
|
158255
|
+
}
|
|
158256
|
+
if (msg.includes("Endpoint storage inaccessible")) {
|
|
158257
|
+
return "Endpoint storage inaccessible";
|
|
158258
|
+
}
|
|
158259
|
+
if (msg.includes("Error initializing part")) {
|
|
158260
|
+
return "Endpoint construction failure";
|
|
158261
|
+
}
|
|
158262
|
+
if (msg.includes("aggregator.")) {
|
|
158263
|
+
return "Runtime error in endpoint";
|
|
158264
|
+
}
|
|
158265
|
+
return null;
|
|
158266
|
+
}
|
|
158267
|
+
/**
|
|
158268
|
+
* Attempt to isolate an entity based on an error.
|
|
158269
|
+
* Returns true if the entity was successfully identified and isolation was triggered.
|
|
158270
|
+
*/
|
|
158271
|
+
async isolateFromError(error) {
|
|
158272
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
158273
|
+
const classification = this.classifyError(msg);
|
|
158274
|
+
if (!classification) {
|
|
158275
|
+
return false;
|
|
158276
|
+
}
|
|
158277
|
+
const parsed = this.parseEndpointPath(msg);
|
|
158278
|
+
if (!parsed) {
|
|
158279
|
+
logger204.warn("Could not parse entity from error:", msg);
|
|
158280
|
+
return false;
|
|
158281
|
+
}
|
|
158282
|
+
const { bridgeId, entityName } = parsed;
|
|
158283
|
+
const callback = this.isolationCallbacks.get(bridgeId);
|
|
158284
|
+
if (!callback) {
|
|
158285
|
+
logger204.warn(
|
|
158286
|
+
`No isolation callback registered for bridge ${bridgeId}, entity: ${entityName}`
|
|
158287
|
+
);
|
|
158288
|
+
return false;
|
|
158289
|
+
}
|
|
158290
|
+
const key = `${bridgeId}:${entityName}`;
|
|
158291
|
+
if (this.isolatedEntities.has(key)) {
|
|
158292
|
+
return true;
|
|
158293
|
+
}
|
|
158294
|
+
const reason = `${classification}. Entity isolated to protect bridge stability.`;
|
|
158295
|
+
this.isolatedEntities.set(key, {
|
|
158296
|
+
entityId: entityName,
|
|
158297
|
+
reason,
|
|
158298
|
+
failedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
158299
|
+
});
|
|
158300
|
+
logger204.warn(
|
|
158301
|
+
`Isolating entity "${entityName}" from bridge ${bridgeId} due to: ${reason}`
|
|
158302
|
+
);
|
|
158303
|
+
diagnosticEventBus.emit("entity_error", `Entity isolated: ${entityName}`, {
|
|
158304
|
+
bridgeId,
|
|
158305
|
+
entityId: entityName,
|
|
158306
|
+
details: { reason: classification }
|
|
158307
|
+
});
|
|
158308
|
+
try {
|
|
158309
|
+
await callback(entityName);
|
|
158310
|
+
return true;
|
|
158311
|
+
} catch (e) {
|
|
158312
|
+
logger204.error(`Failed to isolate entity ${entityName}:`, e);
|
|
158313
|
+
return false;
|
|
158314
|
+
}
|
|
158315
|
+
}
|
|
158316
|
+
/**
|
|
158317
|
+
* Get all isolated entities for a specific bridge.
|
|
158318
|
+
*/
|
|
158319
|
+
getIsolatedEntities(bridgeId) {
|
|
158320
|
+
const result = [];
|
|
158321
|
+
for (const [key, entity] of this.isolatedEntities) {
|
|
158322
|
+
if (key.startsWith(`${bridgeId}:`)) {
|
|
158323
|
+
result.push(entity);
|
|
158324
|
+
}
|
|
158325
|
+
}
|
|
158326
|
+
return result;
|
|
158327
|
+
}
|
|
158328
|
+
/**
|
|
158329
|
+
* Clear isolated entities for a bridge (e.g., on restart).
|
|
158330
|
+
*/
|
|
158331
|
+
clearIsolatedEntities(bridgeId) {
|
|
158332
|
+
for (const key of this.isolatedEntities.keys()) {
|
|
158333
|
+
if (key.startsWith(`${bridgeId}:`)) {
|
|
158334
|
+
this.isolatedEntities.delete(key);
|
|
158335
|
+
}
|
|
158336
|
+
}
|
|
158337
|
+
}
|
|
158338
|
+
};
|
|
158339
|
+
var EntityIsolationService = new EntityIsolationServiceImpl();
|
|
158340
|
+
|
|
158208
158341
|
// src/services/bridges/session-supervisor.ts
|
|
158209
158342
|
init_dist();
|
|
158210
158343
|
init_esm7();
|
|
@@ -159441,6 +159574,7 @@ var Bridge = class {
|
|
|
159441
159574
|
}
|
|
159442
159575
|
async runStart() {
|
|
159443
159576
|
this.lastSyncedStates.clear();
|
|
159577
|
+
EntityIsolationService.clearIsolatedEntities(this.id);
|
|
159444
159578
|
try {
|
|
159445
159579
|
this.setStatus({
|
|
159446
159580
|
code: BridgeStatus.Starting,
|
|
@@ -159974,7 +160108,7 @@ init_esm();
|
|
|
159974
160108
|
init_esm7();
|
|
159975
160109
|
import crypto6 from "node:crypto";
|
|
159976
160110
|
init_home_assistant_entity_behavior();
|
|
159977
|
-
var
|
|
160111
|
+
var logger205 = Logger.get("BasicInformationServer");
|
|
159978
160112
|
var appliedUniqueIds = /* @__PURE__ */ new Map();
|
|
159979
160113
|
var BasicInformationServer2 = class extends BridgedDeviceBasicInformationServer {
|
|
159980
160114
|
async initialize() {
|
|
@@ -160020,7 +160154,7 @@ var BasicInformationServer2 = class extends BridgedDeviceBasicInformationServer
|
|
|
160020
160154
|
// records keyed on it can be shed (#385).
|
|
160021
160155
|
uniqueId: this.frozenUniqueId(anchor)
|
|
160022
160156
|
});
|
|
160023
|
-
|
|
160157
|
+
logger205.debug(
|
|
160024
160158
|
`[${entity.entity_id}] basicInfo vendor=${this.state.vendorName} product=${this.state.productName} label=${this.state.productLabel} serial=${this.state.serialNumber} node=${this.state.nodeLabel} uniqueId=${this.state.uniqueId}`
|
|
160025
160159
|
);
|
|
160026
160160
|
}
|
|
@@ -160050,7 +160184,7 @@ function isValidVendorId(value) {
|
|
|
160050
160184
|
// src/matter/behaviors/electrical-energy-measurement-server.ts
|
|
160051
160185
|
init_esm();
|
|
160052
160186
|
init_home_assistant_entity_behavior();
|
|
160053
|
-
var
|
|
160187
|
+
var logger206 = Logger.get("ElectricalEnergyMeasurementServer");
|
|
160054
160188
|
var FeaturedBase = ElectricalEnergyMeasurementServer.with("CumulativeEnergy", "ImportedEnergy");
|
|
160055
160189
|
var ElectricalEnergyMeasurementServerBase = class extends FeaturedBase {
|
|
160056
160190
|
async initialize() {
|
|
@@ -160059,7 +160193,7 @@ var ElectricalEnergyMeasurementServerBase = class extends FeaturedBase {
|
|
|
160059
160193
|
const entityId = homeAssistant.entityId;
|
|
160060
160194
|
const energyEntity = homeAssistant.state.mapping?.energyEntity;
|
|
160061
160195
|
if (energyEntity) {
|
|
160062
|
-
|
|
160196
|
+
logger206.debug(
|
|
160063
160197
|
`[${entityId}] ElectricalEnergyMeasurement using mapped energy entity: ${energyEntity}`
|
|
160064
160198
|
);
|
|
160065
160199
|
}
|
|
@@ -160115,7 +160249,7 @@ var HaElectricalEnergyMeasurementServer = ElectricalEnergyMeasurementServerBase.
|
|
|
160115
160249
|
// src/matter/behaviors/electrical-power-measurement-server.ts
|
|
160116
160250
|
init_esm();
|
|
160117
160251
|
init_home_assistant_entity_behavior();
|
|
160118
|
-
var
|
|
160252
|
+
var logger207 = Logger.get("ElectricalPowerMeasurementServer");
|
|
160119
160253
|
var FeaturedBase2 = ElectricalPowerMeasurementServer.with("AlternatingCurrent");
|
|
160120
160254
|
var ElectricalPowerMeasurementServerBase = class extends FeaturedBase2 {
|
|
160121
160255
|
async initialize() {
|
|
@@ -160124,7 +160258,7 @@ var ElectricalPowerMeasurementServerBase = class extends FeaturedBase2 {
|
|
|
160124
160258
|
const entityId = homeAssistant.entityId;
|
|
160125
160259
|
const powerEntity = homeAssistant.state.mapping?.powerEntity;
|
|
160126
160260
|
if (powerEntity) {
|
|
160127
|
-
|
|
160261
|
+
logger207.debug(
|
|
160128
160262
|
`[${entityId}] ElectricalPowerMeasurement using mapped power entity: ${powerEntity}`
|
|
160129
160263
|
);
|
|
160130
160264
|
}
|
|
@@ -160257,7 +160391,7 @@ init_home_assistant_entity_behavior();
|
|
|
160257
160391
|
// src/matter/behaviors/humidity-measurement-server.ts
|
|
160258
160392
|
init_esm();
|
|
160259
160393
|
init_home_assistant_entity_behavior();
|
|
160260
|
-
var
|
|
160394
|
+
var logger208 = Logger.get("HumidityMeasurementServer");
|
|
160261
160395
|
var HumidityMeasurementServerBase = class extends RelativeHumidityMeasurementServer {
|
|
160262
160396
|
async initialize() {
|
|
160263
160397
|
await super.initialize();
|
|
@@ -160270,7 +160404,7 @@ var HumidityMeasurementServerBase = class extends RelativeHumidityMeasurementSer
|
|
|
160270
160404
|
return;
|
|
160271
160405
|
}
|
|
160272
160406
|
const humidity = this.getHumidity(this.state.config, entity.state);
|
|
160273
|
-
|
|
160407
|
+
logger208.debug(
|
|
160274
160408
|
`Humidity ${entity.state.entity_id} raw=${entity.state.state} measuredValue=${humidity}`
|
|
160275
160409
|
);
|
|
160276
160410
|
applyPatchState(this.state, {
|
|
@@ -160300,7 +160434,7 @@ function HumidityMeasurementServer(config8) {
|
|
|
160300
160434
|
// src/matter/behaviors/power-source-server.ts
|
|
160301
160435
|
init_esm();
|
|
160302
160436
|
init_home_assistant_entity_behavior();
|
|
160303
|
-
var
|
|
160437
|
+
var logger209 = Logger.get("PowerSourceServer");
|
|
160304
160438
|
var FeaturedBase3 = PowerSourceServer.with("Battery", "Rechargeable");
|
|
160305
160439
|
var PowerSourceServerBase = class extends FeaturedBase3 {
|
|
160306
160440
|
async initialize() {
|
|
@@ -160312,17 +160446,17 @@ var PowerSourceServerBase = class extends FeaturedBase3 {
|
|
|
160312
160446
|
applyPatchState(this.state, {
|
|
160313
160447
|
endpointList: [endpointNumber]
|
|
160314
160448
|
});
|
|
160315
|
-
|
|
160449
|
+
logger209.debug(
|
|
160316
160450
|
`[${entityId}] PowerSource initialized with endpointList=[${endpointNumber}]`
|
|
160317
160451
|
);
|
|
160318
160452
|
} else {
|
|
160319
|
-
|
|
160453
|
+
logger209.warn(
|
|
160320
160454
|
`[${entityId}] PowerSource endpoint number is null during initialize - endpointList will be empty!`
|
|
160321
160455
|
);
|
|
160322
160456
|
}
|
|
160323
160457
|
const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
|
|
160324
160458
|
if (batteryEntity) {
|
|
160325
|
-
|
|
160459
|
+
logger209.debug(
|
|
160326
160460
|
`[${entityId}] PowerSource using mapped battery entity: ${batteryEntity}`
|
|
160327
160461
|
);
|
|
160328
160462
|
}
|
|
@@ -160698,7 +160832,7 @@ function notifyLightTurnedOff(entityId, haLastChanged) {
|
|
|
160698
160832
|
sweepLastTurnOff(now);
|
|
160699
160833
|
lastTurnOffTimestamps.set(entityId, { ts: now, haLastChanged });
|
|
160700
160834
|
}
|
|
160701
|
-
var
|
|
160835
|
+
var logger210 = Logger.get("LevelControlServer");
|
|
160702
160836
|
var FeaturedBase5 = LevelControlServer.with("OnOff", "Lighting");
|
|
160703
160837
|
var LevelControlServerBase = class extends FeaturedBase5 {
|
|
160704
160838
|
pendingTransitionTime;
|
|
@@ -160716,7 +160850,7 @@ var LevelControlServerBase = class extends FeaturedBase5 {
|
|
|
160716
160850
|
try {
|
|
160717
160851
|
await super.initialize();
|
|
160718
160852
|
} catch (error) {
|
|
160719
|
-
|
|
160853
|
+
logger210.error("super.initialize() failed:", error);
|
|
160720
160854
|
throw error;
|
|
160721
160855
|
}
|
|
160722
160856
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
@@ -160834,7 +160968,7 @@ var LevelControlServerBase = class extends FeaturedBase5 {
|
|
|
160834
160968
|
expectedLevel: remembered,
|
|
160835
160969
|
timestamp: now2
|
|
160836
160970
|
});
|
|
160837
|
-
|
|
160971
|
+
logger210.debug(
|
|
160838
160972
|
`[${entityId}] Storing level ${level} without calling HA - moveToLevel arrived ${sinceTurnOff}ms after a Matter off while still off (#434)`
|
|
160839
160973
|
);
|
|
160840
160974
|
return;
|
|
@@ -160845,7 +160979,7 @@ var LevelControlServerBase = class extends FeaturedBase5 {
|
|
|
160845
160979
|
const lastTurnOn = lastTurnOnTimestamps.get(entityId);
|
|
160846
160980
|
const timeSinceTurnOn = lastTurnOn ? Date.now() - lastTurnOn : Infinity;
|
|
160847
160981
|
if (level >= this.maxLevel && timeSinceTurnOn < 200) {
|
|
160848
|
-
|
|
160982
|
+
logger210.debug(
|
|
160849
160983
|
`[${entityId}] Ignoring moveToLevel(${level}) - Alexa brightness reset detected (${timeSinceTurnOn}ms after turn-on)`
|
|
160850
160984
|
);
|
|
160851
160985
|
return;
|
|
@@ -160891,7 +161025,7 @@ function LevelControlServer2(config8) {
|
|
|
160891
161025
|
}
|
|
160892
161026
|
|
|
160893
161027
|
// src/matter/behaviors/on-off-server.ts
|
|
160894
|
-
var
|
|
161028
|
+
var logger211 = Logger.get("OnOffServer");
|
|
160895
161029
|
var optimisticOnOffState = /* @__PURE__ */ new Map();
|
|
160896
161030
|
var OPTIMISTIC_TIMEOUT_MS2 = 3e3;
|
|
160897
161031
|
function sweepOptimisticOnOff(now) {
|
|
@@ -160955,7 +161089,7 @@ var OnOffServerBase = class extends OnOffServer {
|
|
|
160955
161089
|
if (!action) {
|
|
160956
161090
|
return;
|
|
160957
161091
|
}
|
|
160958
|
-
|
|
161092
|
+
logger211.info(`[${homeAssistant.entityId}] Turning ON -> ${action.action}`);
|
|
160959
161093
|
notifyLightTurnedOn(homeAssistant.entityId);
|
|
160960
161094
|
if (!skipMomentaryFlip) {
|
|
160961
161095
|
const now = Date.now();
|
|
@@ -160986,7 +161120,7 @@ var OnOffServerBase = class extends OnOffServer {
|
|
|
160986
161120
|
if (!action) {
|
|
160987
161121
|
return;
|
|
160988
161122
|
}
|
|
160989
|
-
|
|
161123
|
+
logger211.info(`[${homeAssistant.entityId}] Turning OFF -> ${action.action}`);
|
|
160990
161124
|
const now = Date.now();
|
|
160991
161125
|
sweepOptimisticOnOff(now);
|
|
160992
161126
|
optimisticOnOffState.set(homeAssistant.entityId, {
|
|
@@ -161020,7 +161154,7 @@ function setOptimisticOnOff(entityId, expectedOnOff) {
|
|
|
161020
161154
|
}
|
|
161021
161155
|
|
|
161022
161156
|
// src/matter/behaviors/fan-control-server.ts
|
|
161023
|
-
var
|
|
161157
|
+
var logger212 = Logger.get("FanControlServer");
|
|
161024
161158
|
var defaultStepSize = 33.33;
|
|
161025
161159
|
var minSpeedMax = 3;
|
|
161026
161160
|
var maxSpeedMax = 100;
|
|
@@ -161360,7 +161494,7 @@ var FanControlServerBase = class extends FeaturedBase6 {
|
|
|
161360
161494
|
const wasOff = homeAssistant.entity.state?.state === "off" || this.agent.has(OnOffBehavior) && !this.agent.get(OnOffBehavior).state.onOff;
|
|
161361
161495
|
const remembered = this.remembered();
|
|
161362
161496
|
if (wasOff) {
|
|
161363
|
-
|
|
161497
|
+
logger212.debug(
|
|
161364
161498
|
`[${homeAssistant.entityId}] power-on write ${percentage}%: restore flag=${restoreOnPowerOn}, last speed=${remembered.percent}`
|
|
161365
161499
|
);
|
|
161366
161500
|
}
|
|
@@ -161553,7 +161687,7 @@ var FanControlServerBase = class extends FeaturedBase6 {
|
|
|
161553
161687
|
const entityId = this.agent.get(HomeAssistantEntityBehavior).entity.entity_id;
|
|
161554
161688
|
setOptimisticOnOff(entityId, on);
|
|
161555
161689
|
} catch (e) {
|
|
161556
|
-
|
|
161690
|
+
logger212.debug(
|
|
161557
161691
|
`syncOnOff(${on}) failed: ${e instanceof Error ? e.message : String(e)}`
|
|
161558
161692
|
);
|
|
161559
161693
|
}
|
|
@@ -161696,7 +161830,7 @@ var FanOnOffServer = OnOffServer2({
|
|
|
161696
161830
|
});
|
|
161697
161831
|
|
|
161698
161832
|
// src/matter/endpoints/composed/composed-air-purifier-endpoint.ts
|
|
161699
|
-
var
|
|
161833
|
+
var logger213 = Logger.get("ComposedAirPurifierEndpoint");
|
|
161700
161834
|
var temperatureConfig = {
|
|
161701
161835
|
getValue(entity, agent) {
|
|
161702
161836
|
const fallbackUnit = agent.env.get(HomeAssistantConfig).unitSystem.temperature;
|
|
@@ -161914,7 +162048,7 @@ var ComposedAirPurifierEndpoint = class _ComposedAirPurifierEndpoint extends End
|
|
|
161914
162048
|
config8.powerEntityId ? "+Pwr" : "",
|
|
161915
162049
|
config8.energyEntityId ? "+Nrg" : ""
|
|
161916
162050
|
].filter(Boolean).join("");
|
|
161917
|
-
|
|
162051
|
+
logger213.info(
|
|
161918
162052
|
`Created composed air purifier ${primaryEntityId}: ${clusterLabels}`
|
|
161919
162053
|
);
|
|
161920
162054
|
return endpoint;
|
|
@@ -162232,12 +162366,12 @@ var ClimateHumidityMeasurementServer = HumidityMeasurementServer(humidityConfig2
|
|
|
162232
162366
|
// src/matter/endpoints/legacy/climate/behaviors/climate-on-off-server.ts
|
|
162233
162367
|
init_esm();
|
|
162234
162368
|
init_home_assistant_entity_behavior();
|
|
162235
|
-
var
|
|
162369
|
+
var logger214 = Logger.get("ClimateOnOffServer");
|
|
162236
162370
|
var ClimateOnOffServer = OnOffServer2({
|
|
162237
162371
|
turnOn: (_value, agent) => {
|
|
162238
162372
|
const entity = agent.get(HomeAssistantEntityBehavior).entity;
|
|
162239
162373
|
if (entity.state.state !== "off" && agent.get(OnOffServer).state.onOff) {
|
|
162240
|
-
|
|
162374
|
+
logger214.debug(
|
|
162241
162375
|
`[${entity.entity_id}] Skipping redundant OnOff.on(), cached state "${entity.state.state}"`
|
|
162242
162376
|
);
|
|
162243
162377
|
return void 0;
|
|
@@ -162272,7 +162406,7 @@ init_home_assistant_entity_behavior();
|
|
|
162272
162406
|
init_esm();
|
|
162273
162407
|
init_home_assistant_entity_behavior();
|
|
162274
162408
|
init_transaction_is_offline();
|
|
162275
|
-
var
|
|
162409
|
+
var logger215 = Logger.get("ThermostatServer");
|
|
162276
162410
|
var SystemMode = Thermostat3.SystemMode;
|
|
162277
162411
|
var RunningMode = Thermostat3.ThermostatRunningMode;
|
|
162278
162412
|
var nudgingSetpoints = /* @__PURE__ */ new Set();
|
|
@@ -162351,7 +162485,7 @@ function clearInactiveSetpointState(self, scope) {
|
|
|
162351
162485
|
}
|
|
162352
162486
|
function thermostatPreInitialize(self) {
|
|
162353
162487
|
const currentLocal = self.state.localTemperature;
|
|
162354
|
-
|
|
162488
|
+
logger215.debug(
|
|
162355
162489
|
`initialize: features - heating=${self.features.heating}, cooling=${self.features.cooling}`
|
|
162356
162490
|
);
|
|
162357
162491
|
const localValue = typeof currentLocal === "number" && !Number.isNaN(currentLocal) ? currentLocal : currentLocal === null ? null : 2100;
|
|
@@ -162398,7 +162532,7 @@ function thermostatPreInitialize(self) {
|
|
|
162398
162532
|
} else {
|
|
162399
162533
|
clearInactiveSetpointState(self, "Cool");
|
|
162400
162534
|
}
|
|
162401
|
-
|
|
162535
|
+
logger215.debug(
|
|
162402
162536
|
`initialize: after force-set - local=${self.state.localTemperature}`
|
|
162403
162537
|
);
|
|
162404
162538
|
self.state.thermostatRunningState = runningStateAllOff;
|
|
@@ -162491,7 +162625,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162491
162625
|
maxCoolLimit,
|
|
162492
162626
|
"cool"
|
|
162493
162627
|
);
|
|
162494
|
-
|
|
162628
|
+
logger215.debug(
|
|
162495
162629
|
`update: limits heat=[${minHeatLimit}, ${maxHeatLimit}], cool=[${minCoolLimit}, ${maxCoolLimit}], systemMode=${systemMode}, runningMode=${runningMode}`
|
|
162496
162630
|
);
|
|
162497
162631
|
let controlSequence = config8.getControlSequence(entity.state, this.agent);
|
|
@@ -162567,18 +162701,18 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162567
162701
|
*/
|
|
162568
162702
|
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: Called via thermostatPostInitialize + prototype copy
|
|
162569
162703
|
heatingSetpointChanging(value, _oldValue, context) {
|
|
162570
|
-
|
|
162704
|
+
logger215.debug(
|
|
162571
162705
|
`heatingSetpointChanging: value=${value}, oldValue=${_oldValue}, isOffline=${transactionIsOffline(context)}`
|
|
162572
162706
|
);
|
|
162573
162707
|
if (transactionIsOffline(context)) {
|
|
162574
|
-
|
|
162708
|
+
logger215.debug(
|
|
162575
162709
|
"heatingSetpointChanging: skipping - transaction is offline"
|
|
162576
162710
|
);
|
|
162577
162711
|
return;
|
|
162578
162712
|
}
|
|
162579
162713
|
const next = Temperature.celsius(value / 100);
|
|
162580
162714
|
if (!next) {
|
|
162581
|
-
|
|
162715
|
+
logger215.debug("heatingSetpointChanging: skipping - invalid temperature");
|
|
162582
162716
|
return;
|
|
162583
162717
|
}
|
|
162584
162718
|
this.agent.asLocalActor(() => {
|
|
@@ -162589,7 +162723,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162589
162723
|
this.agent
|
|
162590
162724
|
);
|
|
162591
162725
|
const currentMode2 = this.state.systemMode;
|
|
162592
|
-
|
|
162726
|
+
logger215.debug(
|
|
162593
162727
|
`heatingSetpointChanging: supportsRange=${supportsRange}, systemMode=${currentMode2}, features.heating=${this.features.heating}, features.cooling=${this.features.cooling}`
|
|
162594
162728
|
);
|
|
162595
162729
|
if (!supportsRange) {
|
|
@@ -162599,12 +162733,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162599
162733
|
const isOff = currentMode2 === Thermostat3.SystemMode.Off;
|
|
162600
162734
|
if (isOff && this.features.heating) {
|
|
162601
162735
|
if (nudgingSetpoints.has(homeAssistant.entityId)) {
|
|
162602
|
-
|
|
162736
|
+
logger215.debug(
|
|
162603
162737
|
`heatingSetpointChanging: skipping auto-resume - nudge write in progress`
|
|
162604
162738
|
);
|
|
162605
162739
|
return;
|
|
162606
162740
|
}
|
|
162607
|
-
|
|
162741
|
+
logger215.info(
|
|
162608
162742
|
`heatingSetpointChanging: auto-resume - switching to Heat (was Off)`
|
|
162609
162743
|
);
|
|
162610
162744
|
const modeAction = config8.setSystemMode(
|
|
@@ -162613,17 +162747,17 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162613
162747
|
);
|
|
162614
162748
|
homeAssistant.callAction(modeAction);
|
|
162615
162749
|
} else if (!isAutoMode && !isHeatingMode) {
|
|
162616
|
-
|
|
162750
|
+
logger215.debug(
|
|
162617
162751
|
`heatingSetpointChanging: skipping - not in heating/auto mode (mode=${currentMode2}, haMode=${haHvacMode})`
|
|
162618
162752
|
);
|
|
162619
162753
|
return;
|
|
162620
162754
|
}
|
|
162621
|
-
|
|
162755
|
+
logger215.debug(
|
|
162622
162756
|
`heatingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isHeatingMode=${isHeatingMode}, isOff=${isOff}, haMode=${haHvacMode}`
|
|
162623
162757
|
);
|
|
162624
162758
|
}
|
|
162625
162759
|
const coolingSetpoint = this.features.cooling ? this.state.occupiedCoolingSetpoint : value;
|
|
162626
|
-
|
|
162760
|
+
logger215.debug(
|
|
162627
162761
|
`heatingSetpointChanging: calling setTemperature with heat=${next.celsius(true)}, cool=${coolingSetpoint}`
|
|
162628
162762
|
);
|
|
162629
162763
|
this.setTemperature(
|
|
@@ -162662,12 +162796,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162662
162796
|
const isOff = currentMode2 === Thermostat3.SystemMode.Off;
|
|
162663
162797
|
if (isOff && !this.features.heating && this.features.cooling) {
|
|
162664
162798
|
if (nudgingSetpoints.has(homeAssistant.entityId)) {
|
|
162665
|
-
|
|
162799
|
+
logger215.debug(
|
|
162666
162800
|
`coolingSetpointChanging: skipping auto-resume - nudge write in progress`
|
|
162667
162801
|
);
|
|
162668
162802
|
return;
|
|
162669
162803
|
}
|
|
162670
|
-
|
|
162804
|
+
logger215.info(
|
|
162671
162805
|
`coolingSetpointChanging: auto-resume - switching to Cool (was Off)`
|
|
162672
162806
|
);
|
|
162673
162807
|
const modeAction = config8.setSystemMode(
|
|
@@ -162676,12 +162810,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162676
162810
|
);
|
|
162677
162811
|
homeAssistant.callAction(modeAction);
|
|
162678
162812
|
} else if (!isAutoMode && !isCoolingMode) {
|
|
162679
|
-
|
|
162813
|
+
logger215.debug(
|
|
162680
162814
|
`coolingSetpointChanging: skipping - not in cooling/auto mode (mode=${currentMode2}, haMode=${haHvacMode})`
|
|
162681
162815
|
);
|
|
162682
162816
|
return;
|
|
162683
162817
|
}
|
|
162684
|
-
|
|
162818
|
+
logger215.debug(
|
|
162685
162819
|
`coolingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isCoolingMode=${isCoolingMode}, isOff=${isOff}, haMode=${haHvacMode}`
|
|
162686
162820
|
);
|
|
162687
162821
|
}
|
|
@@ -162795,7 +162929,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
162795
162929
|
const effectiveMax = max ?? 5e3;
|
|
162796
162930
|
if (value == null || Number.isNaN(value)) {
|
|
162797
162931
|
const defaultValue = type === "heat" ? 2e3 : 2400;
|
|
162798
|
-
|
|
162932
|
+
logger215.debug(
|
|
162799
162933
|
`${type} setpoint is undefined, using default: ${defaultValue}`
|
|
162800
162934
|
);
|
|
162801
162935
|
return Math.max(effectiveMin, Math.min(effectiveMax, defaultValue));
|
|
@@ -163373,7 +163507,7 @@ function ClimateDevice(homeAssistantEntity, includeBasicInformation = true) {
|
|
|
163373
163507
|
}
|
|
163374
163508
|
|
|
163375
163509
|
// src/matter/endpoints/composed/composed-climate-fan-endpoint.ts
|
|
163376
|
-
var
|
|
163510
|
+
var logger216 = Logger.get("ComposedClimateFanEndpoint");
|
|
163377
163511
|
function createEndpointId3(entityId, customName) {
|
|
163378
163512
|
const baseName = customName || entityId;
|
|
163379
163513
|
return baseName.replace(/\./g, "_").replace(/\s+/g, "_");
|
|
@@ -163411,7 +163545,7 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
|
|
|
163411
163545
|
climateSub = new Endpoint(climateType, { id: `${endpointId}_climate` });
|
|
163412
163546
|
} catch (error) {
|
|
163413
163547
|
const message = error instanceof Error ? error.message : String(error);
|
|
163414
|
-
|
|
163548
|
+
logger216.warn(
|
|
163415
163549
|
`Companion fan: climate sub build failed for ${primaryEntityId}: ${message}`
|
|
163416
163550
|
);
|
|
163417
163551
|
return void 0;
|
|
@@ -163455,7 +163589,7 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
|
|
|
163455
163589
|
endpointId,
|
|
163456
163590
|
[climateSub, fanSub]
|
|
163457
163591
|
);
|
|
163458
|
-
|
|
163592
|
+
logger216.info(`Created composed climate+fan endpoint ${primaryEntityId}`);
|
|
163459
163593
|
return endpoint;
|
|
163460
163594
|
}
|
|
163461
163595
|
constructor(type, entityId, id, parts) {
|
|
@@ -163550,7 +163684,7 @@ init_home_assistant_entity_behavior();
|
|
|
163550
163684
|
// src/matter/behaviors/pressure-measurement-server.ts
|
|
163551
163685
|
init_esm();
|
|
163552
163686
|
init_home_assistant_entity_behavior();
|
|
163553
|
-
var
|
|
163687
|
+
var logger217 = Logger.get("PressureMeasurementServer");
|
|
163554
163688
|
var MIN_PRESSURE = 300;
|
|
163555
163689
|
var MAX_PRESSURE = 1100;
|
|
163556
163690
|
var PressureMeasurementServerBase = class extends PressureMeasurementServer {
|
|
@@ -163578,7 +163712,7 @@ var PressureMeasurementServerBase = class extends PressureMeasurementServer {
|
|
|
163578
163712
|
}
|
|
163579
163713
|
const rounded = Math.round(value);
|
|
163580
163714
|
if (rounded < MIN_PRESSURE || rounded > MAX_PRESSURE) {
|
|
163581
|
-
|
|
163715
|
+
logger217.warn(
|
|
163582
163716
|
`Pressure value ${rounded} (raw: ${value}) for ${entity.entity_id} is outside valid range [${MIN_PRESSURE}-${MAX_PRESSURE}], ignoring`
|
|
163583
163717
|
);
|
|
163584
163718
|
return null;
|
|
@@ -163597,7 +163731,7 @@ function PressureMeasurementServer2(config8) {
|
|
|
163597
163731
|
}
|
|
163598
163732
|
|
|
163599
163733
|
// src/matter/endpoints/composed/composed-sensor-endpoint.ts
|
|
163600
|
-
var
|
|
163734
|
+
var logger218 = Logger.get("ComposedSensorEndpoint");
|
|
163601
163735
|
var temperatureConfig2 = {
|
|
163602
163736
|
getValue(entity, agent) {
|
|
163603
163737
|
const fallbackUnit = agent.env.get(HomeAssistantConfig).unitSystem.temperature;
|
|
@@ -163775,7 +163909,7 @@ var ComposedSensorEndpoint = class _ComposedSensorEndpoint extends Endpoint {
|
|
|
163775
163909
|
if (config8.pressureEntityId && pressSub) {
|
|
163776
163910
|
endpoint.subEndpoints.set(config8.pressureEntityId, pressSub);
|
|
163777
163911
|
}
|
|
163778
|
-
|
|
163912
|
+
logger218.info(
|
|
163779
163913
|
`Created composed sensor ${primaryEntityId} with ${parts.length} sub-endpoint(s): T${humSub ? "+H" : ""}${pressSub ? "+P" : ""}${config8.batteryEntityId ? "+Bat" : ""}${config8.powerEntityId ? "+Pwr" : ""}${config8.energyEntityId ? "+Nrg" : ""}`
|
|
163780
163914
|
);
|
|
163781
163915
|
return endpoint;
|
|
@@ -163912,7 +164046,7 @@ init_home_assistant_entity_behavior();
|
|
|
163912
164046
|
// src/matter/behaviors/mode-select-server.ts
|
|
163913
164047
|
init_esm();
|
|
163914
164048
|
init_home_assistant_entity_behavior();
|
|
163915
|
-
var
|
|
164049
|
+
var logger219 = Logger.get("ModeSelectServer");
|
|
163916
164050
|
function buildSupportedModes(options) {
|
|
163917
164051
|
return options.map((label, index) => ({
|
|
163918
164052
|
label: label.length > 64 ? label.substring(0, 64) : label,
|
|
@@ -163949,13 +164083,13 @@ var ModeSelectServerBase = class extends ModeSelectServer {
|
|
|
163949
164083
|
const options = config8.getOptions(homeAssistant.entity);
|
|
163950
164084
|
const { newMode } = request;
|
|
163951
164085
|
if (newMode < 0 || newMode >= options.length) {
|
|
163952
|
-
|
|
164086
|
+
logger219.warn(
|
|
163953
164087
|
`[${homeAssistant.entityId}] Invalid mode ${newMode}, options: [${options.join(", ")}]`
|
|
163954
164088
|
);
|
|
163955
164089
|
return;
|
|
163956
164090
|
}
|
|
163957
164091
|
const option = options[newMode];
|
|
163958
|
-
|
|
164092
|
+
logger219.info(
|
|
163959
164093
|
`[${homeAssistant.entityId}] changeToMode(${newMode}) -> "${option}"`
|
|
163960
164094
|
);
|
|
163961
164095
|
applyPatchState(this.state, { currentMode: newMode });
|
|
@@ -164506,7 +164640,7 @@ var CoAlarmWithBatteryType = SmokeCoAlarmDevice.with(
|
|
|
164506
164640
|
);
|
|
164507
164641
|
|
|
164508
164642
|
// src/matter/endpoints/legacy/binary-sensor/index.ts
|
|
164509
|
-
var
|
|
164643
|
+
var logger220 = Logger.get("BinarySensorDevice");
|
|
164510
164644
|
var deviceClasses = {
|
|
164511
164645
|
[BinarySensorDeviceClass.CarbonMonoxide]: CoAlarmType,
|
|
164512
164646
|
[BinarySensorDeviceClass.Gas]: CoAlarmType,
|
|
@@ -164557,11 +164691,11 @@ function BinarySensorDevice(homeAssistantEntity) {
|
|
|
164557
164691
|
const originalTypeName = type.name;
|
|
164558
164692
|
if (hasBattery && batteryTypes.has(type)) {
|
|
164559
164693
|
type = batteryTypes.get(type);
|
|
164560
|
-
|
|
164694
|
+
logger220.info(
|
|
164561
164695
|
`[${entityId}] Using battery variant: ${originalTypeName} -> ${type.name}, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
|
|
164562
164696
|
);
|
|
164563
164697
|
} else if (hasBattery) {
|
|
164564
|
-
|
|
164698
|
+
logger220.warn(
|
|
164565
164699
|
`[${entityId}] Has battery but no variant available for ${originalTypeName}`
|
|
164566
164700
|
);
|
|
164567
164701
|
}
|
|
@@ -164648,7 +164782,7 @@ init_home_assistant_entity_behavior();
|
|
|
164648
164782
|
init_esm();
|
|
164649
164783
|
init_home_assistant_actions();
|
|
164650
164784
|
init_home_assistant_entity_behavior();
|
|
164651
|
-
var
|
|
164785
|
+
var logger221 = Logger.get("WindowCoveringServer");
|
|
164652
164786
|
var MovementStatus = WindowCovering3.MovementStatus;
|
|
164653
164787
|
var FeaturedBase7 = WindowCoveringServer.with(
|
|
164654
164788
|
"Lift",
|
|
@@ -164859,7 +164993,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164859
164993
|
}
|
|
164860
164994
|
return existing100ths ?? current100ths;
|
|
164861
164995
|
};
|
|
164862
|
-
|
|
164996
|
+
logger221.debug(
|
|
164863
164997
|
`Cover update for ${entity.entity_id}: state=${state.state}, lift=${currentLift}%, tilt=${currentTilt}%, ha=${MovementStatus[movementStatus]}, effective=${MovementStatus[globalStatus]}`
|
|
164864
164998
|
);
|
|
164865
164999
|
const overrideType = config8.getCoverType?.(state, this.agent);
|
|
@@ -164904,9 +165038,9 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
164904
165038
|
);
|
|
164905
165039
|
if (Object.keys(appliedPatch).length > 0) {
|
|
164906
165040
|
const hasOperationalChange = "operationalStatus" in appliedPatch;
|
|
164907
|
-
const log = hasOperationalChange ?
|
|
165041
|
+
const log = hasOperationalChange ? logger221.info : logger221.debug;
|
|
164908
165042
|
log.call(
|
|
164909
|
-
|
|
165043
|
+
logger221,
|
|
164910
165044
|
`Cover ${entity.entity_id} state changed: ${JSON.stringify(appliedPatch)}`
|
|
164911
165045
|
);
|
|
164912
165046
|
}
|
|
@@ -165015,7 +165149,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
165015
165149
|
}
|
|
165016
165150
|
});
|
|
165017
165151
|
} catch (error) {
|
|
165018
|
-
|
|
165152
|
+
logger221.debug(
|
|
165019
165153
|
`Optimistic ${axis} timeout write failed (endpoint may be closing): ${error}`
|
|
165020
165154
|
);
|
|
165021
165155
|
}
|
|
@@ -165050,7 +165184,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
165050
165184
|
const currentTilt = this.state.currentPositionTiltPercent100ths ?? 0;
|
|
165051
165185
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
165052
165186
|
const flags2 = this.state.config.getDiagnosticFlags?.(this.agent);
|
|
165053
|
-
|
|
165187
|
+
logger221.info(
|
|
165054
165188
|
`handleMovement ${homeAssistant.entityId}: type=${MovementType[type]}, direction=${MovementDirection[direction]}, target=${targetPercent100ths}, currentLift=${currentLift}, currentTilt=${currentTilt}${flags2 ? `, ${flags2}` : ""}`
|
|
165055
165189
|
);
|
|
165056
165190
|
if (type === MovementType.Lift) {
|
|
@@ -165069,7 +165203,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
165069
165203
|
}
|
|
165070
165204
|
} else if (type === MovementType.Tilt) {
|
|
165071
165205
|
if (targetPercent100ths == null && this.lastLiftMovementDirection === direction && Date.now() - this.lastLiftMovementMs < 50) {
|
|
165072
|
-
|
|
165206
|
+
logger221.info(
|
|
165073
165207
|
`Skipping tilt ${MovementDirection[direction]}, lift already moving in same direction`
|
|
165074
165208
|
);
|
|
165075
165209
|
return;
|
|
@@ -165114,7 +165248,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
165114
165248
|
} else {
|
|
165115
165249
|
this.startOptimisticMovement("lift", MovementStatus.Opening, end);
|
|
165116
165250
|
}
|
|
165117
|
-
|
|
165251
|
+
logger221.info(
|
|
165118
165252
|
`handleLiftOpen ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
|
|
165119
165253
|
);
|
|
165120
165254
|
homeAssistant.callAction(action);
|
|
@@ -165130,7 +165264,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
165130
165264
|
} else {
|
|
165131
165265
|
this.startOptimisticMovement("lift", MovementStatus.Closing, end);
|
|
165132
165266
|
}
|
|
165133
|
-
|
|
165267
|
+
logger221.info(
|
|
165134
165268
|
`handleLiftClose ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
|
|
165135
165269
|
);
|
|
165136
165270
|
homeAssistant.callAction(action);
|
|
@@ -165160,7 +165294,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
165160
165294
|
const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
|
|
165161
165295
|
const overrideMs = this.resolveDebounceOverride(homeAssistant);
|
|
165162
165296
|
const debounceMs = overrideMs != null ? overrideMs : isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
|
|
165163
|
-
|
|
165297
|
+
logger221.debug(
|
|
165164
165298
|
`Lift command: target=${targetPosition}%, debounce=${debounceMs}ms (${overrideMs != null ? "override" : isFirstInSequence ? "initial" : "subsequent"})`
|
|
165165
165299
|
);
|
|
165166
165300
|
if (st.liftTimer) {
|
|
@@ -165192,7 +165326,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
165192
165326
|
this.startOptimisticMovement("tilt", MovementStatus.Opening, end);
|
|
165193
165327
|
}
|
|
165194
165328
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
165195
|
-
|
|
165329
|
+
logger221.info(
|
|
165196
165330
|
`handleTiltOpen ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
|
|
165197
165331
|
);
|
|
165198
165332
|
homeAssistant.callAction(action);
|
|
@@ -165210,7 +165344,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
165210
165344
|
this.startOptimisticMovement("tilt", MovementStatus.Closing, end);
|
|
165211
165345
|
}
|
|
165212
165346
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
165213
|
-
|
|
165347
|
+
logger221.info(
|
|
165214
165348
|
`handleTiltClose ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
|
|
165215
165349
|
);
|
|
165216
165350
|
homeAssistant.callAction(action);
|
|
@@ -165240,7 +165374,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
165240
165374
|
const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
|
|
165241
165375
|
const overrideMs = this.resolveDebounceOverride(homeAssistant);
|
|
165242
165376
|
const debounceMs = overrideMs != null ? overrideMs : isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
|
|
165243
|
-
|
|
165377
|
+
logger221.debug(
|
|
165244
165378
|
`Tilt command: target=${targetPosition}%, debounce=${debounceMs}ms (${overrideMs != null ? "override" : isFirstInSequence ? "initial" : "subsequent"})`
|
|
165245
165379
|
);
|
|
165246
165380
|
if (st.tiltTimer) {
|
|
@@ -165292,7 +165426,7 @@ function adjustPositionForWriting(position, flags2, matterSemantics) {
|
|
|
165292
165426
|
}
|
|
165293
165427
|
|
|
165294
165428
|
// src/matter/endpoints/legacy/cover/behaviors/cover-window-covering-server.ts
|
|
165295
|
-
var
|
|
165429
|
+
var logger222 = Logger.get("CoverWindowCoveringServer");
|
|
165296
165430
|
var attributes6 = (entity) => entity.attributes;
|
|
165297
165431
|
var DEVICE_CLASS_TO_MATTER_TYPE = {
|
|
165298
165432
|
curtain: {
|
|
@@ -165370,7 +165504,7 @@ var adjustPositionForReading2 = (position, agent) => {
|
|
|
165370
165504
|
const { featureFlags } = agent.env.get(BridgeDataProvider);
|
|
165371
165505
|
const matterSem = usesMatterSemantics(agent);
|
|
165372
165506
|
const result = adjustPositionForReading(position, featureFlags, matterSem);
|
|
165373
|
-
|
|
165507
|
+
logger222.debug(`adjustPositionForReading: HA=${position}%, result=${result}%`);
|
|
165374
165508
|
return result;
|
|
165375
165509
|
};
|
|
165376
165510
|
var adjustPositionForWriting2 = (position, agent) => {
|
|
@@ -165595,14 +165729,14 @@ var CoverAsDimmableLightWithBatteryType = DimmableLightDevice.with(
|
|
|
165595
165729
|
);
|
|
165596
165730
|
|
|
165597
165731
|
// src/matter/endpoints/legacy/cover/index.ts
|
|
165598
|
-
var
|
|
165732
|
+
var logger223 = Logger.get("CoverDevice");
|
|
165599
165733
|
var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
|
|
165600
165734
|
const features = /* @__PURE__ */ new Set();
|
|
165601
165735
|
if (testBit(supportedFeatures, CoverSupportedFeatures.support_open)) {
|
|
165602
165736
|
features.add("Lift");
|
|
165603
165737
|
features.add("PositionAwareLift");
|
|
165604
165738
|
} else {
|
|
165605
|
-
|
|
165739
|
+
logger223.warn(
|
|
165606
165740
|
`[${entityId}] Cover has no support_open feature (supported_features=${supportedFeatures}), adding Lift anyway`
|
|
165607
165741
|
);
|
|
165608
165742
|
features.add("Lift");
|
|
@@ -165617,7 +165751,7 @@ var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
|
|
|
165617
165751
|
features.add("PositionAwareTilt");
|
|
165618
165752
|
}
|
|
165619
165753
|
}
|
|
165620
|
-
|
|
165754
|
+
logger223.info(
|
|
165621
165755
|
`[${entityId}] Creating WindowCovering with features: [${[...features].join(", ")}], supported_features=${supportedFeatures}`
|
|
165622
165756
|
);
|
|
165623
165757
|
const baseBehaviors2 = [
|
|
@@ -165641,16 +165775,16 @@ function CoverDevice(homeAssistantEntity) {
|
|
|
165641
165775
|
const hasBatteryEntity = !!homeAssistantEntity.mapping?.batteryEntity;
|
|
165642
165776
|
const hasBattery = hasBatteryAttr || hasBatteryEntity;
|
|
165643
165777
|
if (hasBattery) {
|
|
165644
|
-
|
|
165778
|
+
logger223.info(
|
|
165645
165779
|
`[${entityId}] Creating cover with PowerSource cluster, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
|
|
165646
165780
|
);
|
|
165647
165781
|
} else {
|
|
165648
|
-
|
|
165782
|
+
logger223.debug(
|
|
165649
165783
|
`[${entityId}] Creating cover without battery (batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"})`
|
|
165650
165784
|
);
|
|
165651
165785
|
}
|
|
165652
165786
|
if (homeAssistantEntity.mapping?.coverExposeAsDimmableLight) {
|
|
165653
|
-
|
|
165787
|
+
logger223.info(`[${entityId}] Exposing cover as a Dimmable Light (#372)`);
|
|
165654
165788
|
const type = hasBattery ? CoverAsDimmableLightWithBatteryType : CoverAsDimmableLightType;
|
|
165655
165789
|
return type.set({ homeAssistantEntity });
|
|
165656
165790
|
}
|
|
@@ -165765,7 +165899,7 @@ function DishwasherEndpoint(homeAssistantEntity) {
|
|
|
165765
165899
|
// src/matter/behaviors/generic-switch-server.ts
|
|
165766
165900
|
init_esm();
|
|
165767
165901
|
init_home_assistant_entity_behavior();
|
|
165768
|
-
var
|
|
165902
|
+
var logger224 = Logger.get("GenericSwitchServer");
|
|
165769
165903
|
var SimpleBase = SwitchServer.with(
|
|
165770
165904
|
"MomentarySwitch",
|
|
165771
165905
|
"MomentarySwitchRelease",
|
|
@@ -165807,7 +165941,7 @@ var HaGenericSwitchServerBase = class extends SimpleBase {
|
|
|
165807
165941
|
await super.initialize();
|
|
165808
165942
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
165809
165943
|
const entityId = homeAssistant.entityId;
|
|
165810
|
-
|
|
165944
|
+
logger224.debug(`[${entityId}] GenericSwitch initialized (simple)`);
|
|
165811
165945
|
this.reactTo(homeAssistant.onChange, this.handleEventChange);
|
|
165812
165946
|
}
|
|
165813
165947
|
handleEventChange() {
|
|
@@ -165818,7 +165952,7 @@ var HaGenericSwitchServerBase = class extends SimpleBase {
|
|
|
165818
165952
|
const eventType = attrs.event_type;
|
|
165819
165953
|
if (!eventType) return;
|
|
165820
165954
|
const entityId = homeAssistant.entityId;
|
|
165821
|
-
|
|
165955
|
+
logger224.debug(`[${entityId}] Event fired: ${eventType}`);
|
|
165822
165956
|
this.triggerPress(eventType);
|
|
165823
165957
|
}
|
|
165824
165958
|
triggerPress(eventType) {
|
|
@@ -165864,7 +165998,7 @@ var HaGenericSwitchServerMultiBase = class extends FullBase {
|
|
|
165864
165998
|
await super.initialize();
|
|
165865
165999
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
165866
166000
|
const entityId = homeAssistant.entityId;
|
|
165867
|
-
|
|
166001
|
+
logger224.debug(`[${entityId}] GenericSwitch initialized (multi)`);
|
|
165868
166002
|
this.reactTo(homeAssistant.onChange, this.handleEventChange);
|
|
165869
166003
|
}
|
|
165870
166004
|
handleEventChange() {
|
|
@@ -165875,7 +166009,7 @@ var HaGenericSwitchServerMultiBase = class extends FullBase {
|
|
|
165875
166009
|
const eventType = attrs.event_type;
|
|
165876
166010
|
if (!eventType) return;
|
|
165877
166011
|
const entityId = homeAssistant.entityId;
|
|
165878
|
-
|
|
166012
|
+
logger224.debug(`[${entityId}] Event fired: ${eventType}`);
|
|
165879
166013
|
this.triggerPress(eventType);
|
|
165880
166014
|
}
|
|
165881
166015
|
triggerPress(eventType) {
|
|
@@ -166252,7 +166386,7 @@ init_nodejs();
|
|
|
166252
166386
|
init_home_assistant_entity_behavior();
|
|
166253
166387
|
var OperationalState4 = RvcOperationalState4.OperationalState;
|
|
166254
166388
|
var ErrorState = RvcOperationalState4.ErrorState;
|
|
166255
|
-
var
|
|
166389
|
+
var logger225 = Logger.get("RvcOperationalStateServer");
|
|
166256
166390
|
var activeStates = /* @__PURE__ */ new Set([
|
|
166257
166391
|
OperationalState4.Running,
|
|
166258
166392
|
OperationalState4.SeekingCharger
|
|
@@ -166304,7 +166438,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
166304
166438
|
{ force: true }
|
|
166305
166439
|
);
|
|
166306
166440
|
if (activeStates.has(previousState) && !activeStates.has(newState)) {
|
|
166307
|
-
|
|
166441
|
+
logger225.info(
|
|
166308
166442
|
`Operation completed: ${OperationalState4[previousState]} -> ${OperationalState4[newState]}`
|
|
166309
166443
|
);
|
|
166310
166444
|
try {
|
|
@@ -166317,7 +166451,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
166317
166451
|
this.context
|
|
166318
166452
|
);
|
|
166319
166453
|
} catch (e) {
|
|
166320
|
-
|
|
166454
|
+
logger225.debug("Failed to emit operationCompletion event:", e);
|
|
166321
166455
|
}
|
|
166322
166456
|
}
|
|
166323
166457
|
}
|
|
@@ -166352,7 +166486,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
166352
166486
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
166353
166487
|
homeAssistant.callAction(goHomeAction(void 0, this.agent));
|
|
166354
166488
|
} else {
|
|
166355
|
-
|
|
166489
|
+
logger225.warn("GoHome command received but no goHome action configured");
|
|
166356
166490
|
}
|
|
166357
166491
|
return {
|
|
166358
166492
|
commandResponseState: {
|
|
@@ -166372,7 +166506,7 @@ function RvcOperationalStateServer2(config8) {
|
|
|
166372
166506
|
}
|
|
166373
166507
|
|
|
166374
166508
|
// src/matter/endpoints/legacy/lawn-mower/behaviors/lawn-mower-rvc-operational-state-server.ts
|
|
166375
|
-
var
|
|
166509
|
+
var logger226 = Logger.get("LawnMowerRvcOperationalStateServer");
|
|
166376
166510
|
function mapLawnMowerOperationalState(entity) {
|
|
166377
166511
|
const state = entity.state;
|
|
166378
166512
|
switch (state) {
|
|
@@ -166388,7 +166522,7 @@ function mapLawnMowerOperationalState(entity) {
|
|
|
166388
166522
|
case "unavailable":
|
|
166389
166523
|
return RvcOperationalState4.OperationalState.Error;
|
|
166390
166524
|
default:
|
|
166391
|
-
|
|
166525
|
+
logger226.info(`Unknown lawn_mower state "${state}", treating as Stopped`);
|
|
166392
166526
|
return RvcOperationalState4.OperationalState.Stopped;
|
|
166393
166527
|
}
|
|
166394
166528
|
}
|
|
@@ -166442,7 +166576,7 @@ function inferCleanedAreaProgress(cleanedSqm, orderedAreas) {
|
|
|
166442
166576
|
}
|
|
166443
166577
|
|
|
166444
166578
|
// src/matter/behaviors/rvc-run-mode-server.ts
|
|
166445
|
-
var
|
|
166579
|
+
var logger227 = Logger.get("RvcRunModeServer");
|
|
166446
166580
|
var ROOM_MODE_BASE = 100;
|
|
166447
166581
|
function isRoomMode(mode) {
|
|
166448
166582
|
return mode >= ROOM_MODE_BASE;
|
|
@@ -166568,7 +166702,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166568
166702
|
const s = getSession(this.endpoint);
|
|
166569
166703
|
if (s.loggedShortCircuits.has(reason)) return;
|
|
166570
166704
|
s.loggedShortCircuits.add(reason);
|
|
166571
|
-
|
|
166705
|
+
logger227.info(message);
|
|
166572
166706
|
}
|
|
166573
166707
|
/**
|
|
166574
166708
|
* Read the currentRoomEntity sensor and update currentArea + progress
|
|
@@ -166625,7 +166759,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166625
166759
|
}
|
|
166626
166760
|
}
|
|
166627
166761
|
if (matchedAreaId === null) {
|
|
166628
|
-
|
|
166762
|
+
logger227.info(
|
|
166629
166763
|
`currentRoom sensor: no match for "${roomName}" (segmentId=${segmentId}), activeAreas=[${s.activeAreas.join(", ")}], supportedAreas=[${serviceArea.state.supportedAreas.map((a) => `${a.areaId}:${a.areaInfo.locationInfo?.locationName}`).join(", ")}]`
|
|
166630
166764
|
);
|
|
166631
166765
|
return;
|
|
@@ -166635,14 +166769,14 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166635
166769
|
s.completedAreas.add(s.lastCurrentArea);
|
|
166636
166770
|
}
|
|
166637
166771
|
s.lastCurrentArea = matchedAreaId;
|
|
166638
|
-
|
|
166772
|
+
logger227.info(
|
|
166639
166773
|
`currentRoom sensor: transition to area ${matchedAreaId} ("${roomName}"), completed: [${[...s.completedAreas].join(", ")}]`
|
|
166640
166774
|
);
|
|
166641
166775
|
this.trySetCurrentArea(matchedAreaId);
|
|
166642
166776
|
} catch (e) {
|
|
166643
166777
|
const msg = e instanceof Error ? e.message : String(e);
|
|
166644
166778
|
if (!msg.includes("No provider for") && !msg.includes("not supported")) {
|
|
166645
|
-
|
|
166779
|
+
logger227.warn(`currentRoom sensor update failed: ${msg}`);
|
|
166646
166780
|
}
|
|
166647
166781
|
}
|
|
166648
166782
|
}
|
|
@@ -166722,7 +166856,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166722
166856
|
cleaned,
|
|
166723
166857
|
ordered
|
|
166724
166858
|
);
|
|
166725
|
-
|
|
166859
|
+
logger227.debug(
|
|
166726
166860
|
`cleanedArea: raw=${raw} baseline=${s.cleanedAreaBaseline} cleaned=${cleaned} sizes=[${ordered.map((o) => `${o.areaId}:${o.sizeSqm}`).join(",")}] -> current=${currentArea} completed=[${completed.join(",")}]`
|
|
166727
166861
|
);
|
|
166728
166862
|
for (const id of completed) {
|
|
@@ -166736,7 +166870,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166736
166870
|
} catch (e) {
|
|
166737
166871
|
const msg = e instanceof Error ? e.message : String(e);
|
|
166738
166872
|
if (!msg.includes("No provider for") && !msg.includes("not supported")) {
|
|
166739
|
-
|
|
166873
|
+
logger227.warn(`cleanedArea room update failed: ${msg}`);
|
|
166740
166874
|
}
|
|
166741
166875
|
}
|
|
166742
166876
|
}
|
|
@@ -166751,7 +166885,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
166751
166885
|
const serviceArea = this.agent.get(ServiceAreaBehavior);
|
|
166752
166886
|
if (serviceArea.state.currentArea !== areaId) {
|
|
166753
166887
|
serviceArea.state.currentArea = areaId;
|
|
166754
|
-
|
|
166888
|
+
logger227.debug(`currentArea set to ${areaId}`);
|
|
166755
166889
|
}
|
|
166756
166890
|
this.updateProgress(serviceArea, areaId);
|
|
166757
166891
|
} catch {
|
|
@@ -167034,7 +167168,7 @@ init_nodejs();
|
|
|
167034
167168
|
|
|
167035
167169
|
// src/matter/behaviors/color-control-server.ts
|
|
167036
167170
|
init_home_assistant_entity_behavior();
|
|
167037
|
-
var
|
|
167171
|
+
var logger228 = Logger.get("ColorControlServer");
|
|
167038
167172
|
var optimisticColorState = /* @__PURE__ */ new Map();
|
|
167039
167173
|
var OPTIMISTIC_TIMEOUT_MS3 = 3e3;
|
|
167040
167174
|
var OPTIMISTIC_TOLERANCE2 = 5;
|
|
@@ -167073,7 +167207,7 @@ var ColorControlServerBase = class extends FeaturedBase8 {
|
|
|
167073
167207
|
if (this.state.startUpColorTemperatureMireds == null) {
|
|
167074
167208
|
this.state.startUpColorTemperatureMireds = defaultMireds;
|
|
167075
167209
|
}
|
|
167076
|
-
|
|
167210
|
+
logger228.debug(
|
|
167077
167211
|
`initialize: set ColorTemperature defaults - min=${this.state.colorTempPhysicalMinMireds}, max=${this.state.colorTempPhysicalMaxMireds}, current=${this.state.colorTemperatureMireds}`
|
|
167078
167212
|
);
|
|
167079
167213
|
}
|
|
@@ -167627,7 +167761,7 @@ init_home_assistant_entity_behavior();
|
|
|
167627
167761
|
init_esm();
|
|
167628
167762
|
init_types2();
|
|
167629
167763
|
init_home_assistant_entity_behavior();
|
|
167630
|
-
var
|
|
167764
|
+
var logger229 = Logger.get("LockServer");
|
|
167631
167765
|
var SUPPORTED_SLOT = 1;
|
|
167632
167766
|
function normalizeSupportedIndex(index) {
|
|
167633
167767
|
if (index === 0 || index === SUPPORTED_SLOT) {
|
|
@@ -167968,7 +168102,7 @@ var LockServerWithPinBase = class extends PinCredentialBase {
|
|
|
167968
168102
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
167969
168103
|
const action = this.state.config.lock(void 0, this.agent);
|
|
167970
168104
|
const hasPinProvided = !!request.pinCode;
|
|
167971
|
-
|
|
168105
|
+
logger229.debug(
|
|
167972
168106
|
`lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
|
|
167973
168107
|
);
|
|
167974
168108
|
if (request.pinCode) {
|
|
@@ -167981,12 +168115,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
|
|
|
167981
168115
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
167982
168116
|
const action = this.state.config.unlock(void 0, this.agent);
|
|
167983
168117
|
const hasPinProvided = !!request.pinCode;
|
|
167984
|
-
|
|
168118
|
+
logger229.debug(
|
|
167985
168119
|
`unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
|
|
167986
168120
|
);
|
|
167987
168121
|
if (this.state.requirePinForRemoteOperation) {
|
|
167988
168122
|
if (!request.pinCode) {
|
|
167989
|
-
|
|
168123
|
+
logger229.info(
|
|
167990
168124
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
|
|
167991
168125
|
);
|
|
167992
168126
|
throw new StatusResponseError(
|
|
@@ -167996,12 +168130,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
|
|
|
167996
168130
|
}
|
|
167997
168131
|
const providedPin = new TextDecoder().decode(request.pinCode);
|
|
167998
168132
|
if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
|
|
167999
|
-
|
|
168133
|
+
logger229.info(
|
|
168000
168134
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
|
|
168001
168135
|
);
|
|
168002
168136
|
throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
|
|
168003
168137
|
}
|
|
168004
|
-
|
|
168138
|
+
logger229.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
|
|
168005
168139
|
action.data = { ...action.data, code: providedPin };
|
|
168006
168140
|
}
|
|
168007
168141
|
homeAssistant.callAction(action);
|
|
@@ -168143,7 +168277,7 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
168143
168277
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
168144
168278
|
const action = this.state.config.lock(void 0, this.agent);
|
|
168145
168279
|
const hasPinProvided = !!request.pinCode;
|
|
168146
|
-
|
|
168280
|
+
logger229.debug(
|
|
168147
168281
|
`lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
|
|
168148
168282
|
);
|
|
168149
168283
|
if (request.pinCode) {
|
|
@@ -168157,12 +168291,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
168157
168291
|
const unlatchConfig = this.state.config.unlatch;
|
|
168158
168292
|
const action = unlatchConfig ? unlatchConfig(void 0, this.agent) : this.state.config.unlock(void 0, this.agent);
|
|
168159
168293
|
const hasPinProvided = !!request.pinCode;
|
|
168160
|
-
|
|
168294
|
+
logger229.debug(
|
|
168161
168295
|
`unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}, usingUnlatch: ${!!unlatchConfig}`
|
|
168162
168296
|
);
|
|
168163
168297
|
if (this.state.requirePinForRemoteOperation) {
|
|
168164
168298
|
if (!request.pinCode) {
|
|
168165
|
-
|
|
168299
|
+
logger229.info(
|
|
168166
168300
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
|
|
168167
168301
|
);
|
|
168168
168302
|
throw new StatusResponseError(
|
|
@@ -168172,12 +168306,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
168172
168306
|
}
|
|
168173
168307
|
const providedPin = new TextDecoder().decode(request.pinCode);
|
|
168174
168308
|
if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
|
|
168175
|
-
|
|
168309
|
+
logger229.info(
|
|
168176
168310
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
|
|
168177
168311
|
);
|
|
168178
168312
|
throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
|
|
168179
168313
|
}
|
|
168180
|
-
|
|
168314
|
+
logger229.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
|
|
168181
168315
|
action.data = { ...action.data, code: providedPin };
|
|
168182
168316
|
}
|
|
168183
168317
|
homeAssistant.callAction(action);
|
|
@@ -168186,12 +168320,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
168186
168320
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
168187
168321
|
const action = this.state.config.unlock(void 0, this.agent);
|
|
168188
168322
|
const hasPinProvided = !!request.pinCode;
|
|
168189
|
-
|
|
168323
|
+
logger229.debug(
|
|
168190
168324
|
`unboltDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
|
|
168191
168325
|
);
|
|
168192
168326
|
if (this.state.requirePinForRemoteOperation) {
|
|
168193
168327
|
if (!request.pinCode) {
|
|
168194
|
-
|
|
168328
|
+
logger229.info(
|
|
168195
168329
|
`unboltDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
|
|
168196
168330
|
);
|
|
168197
168331
|
throw new StatusResponseError(
|
|
@@ -168201,12 +168335,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
168201
168335
|
}
|
|
168202
168336
|
const providedPin = new TextDecoder().decode(request.pinCode);
|
|
168203
168337
|
if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
|
|
168204
|
-
|
|
168338
|
+
logger229.info(
|
|
168205
168339
|
`unboltDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
|
|
168206
168340
|
);
|
|
168207
168341
|
throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
|
|
168208
168342
|
}
|
|
168209
|
-
|
|
168343
|
+
logger229.debug(`unboltDoor PIN verified for ${homeAssistant.entityId}`);
|
|
168210
168344
|
action.data = { ...action.data, code: providedPin };
|
|
168211
168345
|
}
|
|
168212
168346
|
homeAssistant.callAction(action);
|
|
@@ -168345,7 +168479,7 @@ init_home_assistant_entity_behavior();
|
|
|
168345
168479
|
init_dist();
|
|
168346
168480
|
init_esm();
|
|
168347
168481
|
init_home_assistant_entity_behavior();
|
|
168348
|
-
var
|
|
168482
|
+
var logger230 = Logger.get("MediaPlayerKeypadInputServer");
|
|
168349
168483
|
var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
|
|
168350
168484
|
sendKey(request) {
|
|
168351
168485
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
@@ -168356,12 +168490,12 @@ var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
|
|
|
168356
168490
|
const features = attributes9.supported_features ?? 0;
|
|
168357
168491
|
const action = this.mapKeyToAction(request.keyCode, features);
|
|
168358
168492
|
if (!action) {
|
|
168359
|
-
|
|
168493
|
+
logger230.debug(
|
|
168360
168494
|
`Unsupported key code ${request.keyCode} for ${homeAssistant.entityId}`
|
|
168361
168495
|
);
|
|
168362
168496
|
return { status: KeypadInput3.Status.UnsupportedKey };
|
|
168363
168497
|
}
|
|
168364
|
-
|
|
168498
|
+
logger230.debug(
|
|
168365
168499
|
`sendKey(${request.keyCode}) \u2192 ${action} for ${homeAssistant.entityId}`
|
|
168366
168500
|
);
|
|
168367
168501
|
homeAssistant.callAction({ action });
|
|
@@ -168640,7 +168774,7 @@ init_home_assistant_entity_behavior();
|
|
|
168640
168774
|
// src/matter/behaviors/speaker-level-control-server.ts
|
|
168641
168775
|
init_esm();
|
|
168642
168776
|
init_home_assistant_entity_behavior();
|
|
168643
|
-
var
|
|
168777
|
+
var logger231 = Logger.get("SpeakerLevelControlServer");
|
|
168644
168778
|
var optimisticLevelState2 = /* @__PURE__ */ new Map();
|
|
168645
168779
|
var OPTIMISTIC_TIMEOUT_MS4 = 3e3;
|
|
168646
168780
|
var OPTIMISTIC_TOLERANCE3 = 5;
|
|
@@ -168683,7 +168817,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase9 {
|
|
|
168683
168817
|
currentLevel = Math.min(Math.max(minLevel, currentLevel), maxLevel);
|
|
168684
168818
|
}
|
|
168685
168819
|
const entityId = this.agent.get(HomeAssistantEntityBehavior).entity.entity_id;
|
|
168686
|
-
|
|
168820
|
+
logger231.debug(
|
|
168687
168821
|
`[${entityId}] Volume update: HA=${currentLevelPercent != null ? Math.round(currentLevelPercent * 100) : "null"}% -> currentLevel=${currentLevel}`
|
|
168688
168822
|
);
|
|
168689
168823
|
const optimistic = optimisticLevelState2.get(entity.entity_id);
|
|
@@ -168731,7 +168865,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase9 {
|
|
|
168731
168865
|
const config8 = this.state.config;
|
|
168732
168866
|
const entityId = homeAssistant.entity.entity_id;
|
|
168733
168867
|
const levelPercent = level / 254;
|
|
168734
|
-
|
|
168868
|
+
logger231.debug(
|
|
168735
168869
|
`[${entityId}] Volume command: level=${level} -> HA volume_level=${levelPercent}`
|
|
168736
168870
|
);
|
|
168737
168871
|
const current = config8.getValuePercent(
|
|
@@ -169769,7 +169903,7 @@ function mapEvseStatus(rawState, chargingSwitchOn) {
|
|
|
169769
169903
|
}
|
|
169770
169904
|
|
|
169771
169905
|
// src/matter/endpoints/legacy/sensor/devices/energy-evse.ts
|
|
169772
|
-
var
|
|
169906
|
+
var logger232 = Logger.get("EnergyEvse");
|
|
169773
169907
|
var MIN_CHARGE_CURRENT_MA = 6e3;
|
|
169774
169908
|
var MAX_CHARGE_CURRENT_MA = 32e3;
|
|
169775
169909
|
var CIRCUIT_CAPACITY_MA = 32e3;
|
|
@@ -169853,7 +169987,7 @@ var EvseStatusServer = class _EvseStatusServer extends EnergyEvseServer {
|
|
|
169853
169987
|
dispatched = true;
|
|
169854
169988
|
}
|
|
169855
169989
|
if (!dispatched) {
|
|
169856
|
-
|
|
169990
|
+
logger232.debug(
|
|
169857
169991
|
`enableCharging ignored for ${homeAssistant.entityId}: no charging switch or current limit mapped`
|
|
169858
169992
|
);
|
|
169859
169993
|
return;
|
|
@@ -169893,7 +170027,7 @@ var EvseStatusServer = class _EvseStatusServer extends EnergyEvseServer {
|
|
|
169893
170027
|
chargingEnabledUntil: null
|
|
169894
170028
|
});
|
|
169895
170029
|
} catch (error) {
|
|
169896
|
-
|
|
170030
|
+
logger232.debug(
|
|
169897
170031
|
`EVSE charge-window expiry write failed (endpoint may be closing): ${error}`
|
|
169898
170032
|
);
|
|
169899
170033
|
} finally {
|
|
@@ -169924,7 +170058,7 @@ var EvseStatusServer = class _EvseStatusServer extends EnergyEvseServer {
|
|
|
169924
170058
|
chargingEnabledUntil: null
|
|
169925
170059
|
});
|
|
169926
170060
|
} else {
|
|
169927
|
-
|
|
170061
|
+
logger232.debug(
|
|
169928
170062
|
`disable ignored for ${homeAssistant.entityId}: no charging switch mapped`
|
|
169929
170063
|
);
|
|
169930
170064
|
}
|
|
@@ -170613,7 +170747,7 @@ init_home_assistant_entity_behavior();
|
|
|
170613
170747
|
// src/matter/behaviors/pm25-concentration-measurement-server.ts
|
|
170614
170748
|
init_esm();
|
|
170615
170749
|
init_home_assistant_entity_behavior();
|
|
170616
|
-
var
|
|
170750
|
+
var logger233 = Logger.get("Pm25ConcentrationMeasurementServer");
|
|
170617
170751
|
var Pm25ConcentrationMeasurementServerBase = Pm25ConcentrationMeasurementServer.with(
|
|
170618
170752
|
ConcentrationMeasurement3.Feature.NumericMeasurement
|
|
170619
170753
|
);
|
|
@@ -170637,11 +170771,11 @@ var Pm25ConcentrationMeasurementServer2 = class extends Pm25ConcentrationMeasure
|
|
|
170637
170771
|
if (this.state.measurementMedium === void 0) {
|
|
170638
170772
|
this.state.measurementMedium = ConcentrationMeasurement3.MeasurementMedium.Air;
|
|
170639
170773
|
}
|
|
170640
|
-
|
|
170774
|
+
logger233.debug(
|
|
170641
170775
|
"Pm25ConcentrationMeasurementServer: before super.initialize()"
|
|
170642
170776
|
);
|
|
170643
170777
|
await super.initialize();
|
|
170644
|
-
|
|
170778
|
+
logger233.debug(
|
|
170645
170779
|
"Pm25ConcentrationMeasurementServer: after super.initialize()"
|
|
170646
170780
|
);
|
|
170647
170781
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
@@ -170664,7 +170798,7 @@ var Pm25ConcentrationMeasurementServer2 = class extends Pm25ConcentrationMeasure
|
|
|
170664
170798
|
};
|
|
170665
170799
|
|
|
170666
170800
|
// src/matter/endpoints/legacy/sensor/devices/pm25-sensor.ts
|
|
170667
|
-
var
|
|
170801
|
+
var logger234 = Logger.get("Pm25AirQualityServer");
|
|
170668
170802
|
var Pm25AirQualityServerBase = AirQualityServer.with(
|
|
170669
170803
|
AirQuality3.Feature.Fair,
|
|
170670
170804
|
AirQuality3.Feature.Moderate,
|
|
@@ -170676,9 +170810,9 @@ var Pm25AirQualityServer = class extends Pm25AirQualityServerBase {
|
|
|
170676
170810
|
if (this.state.airQuality === void 0) {
|
|
170677
170811
|
this.state.airQuality = AirQuality3.AirQualityEnum.Unknown;
|
|
170678
170812
|
}
|
|
170679
|
-
|
|
170813
|
+
logger234.debug("Pm25AirQualityServer: before super.initialize()");
|
|
170680
170814
|
await super.initialize();
|
|
170681
|
-
|
|
170815
|
+
logger234.debug("Pm25AirQualityServer: after super.initialize()");
|
|
170682
170816
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
170683
170817
|
this.update(homeAssistant.entity);
|
|
170684
170818
|
this.reactTo(homeAssistant.onChange, this.update, { offline: true });
|
|
@@ -170931,7 +171065,7 @@ var TvocConcentrationMeasurementServer = class extends TvocConcentrationMeasurem
|
|
|
170931
171065
|
};
|
|
170932
171066
|
|
|
170933
171067
|
// src/matter/endpoints/legacy/sensor/devices/tvoc-sensor.ts
|
|
170934
|
-
var
|
|
171068
|
+
var logger235 = Logger.get("TvocSensor");
|
|
170935
171069
|
function airQualityFromUgm3(value) {
|
|
170936
171070
|
if (value <= 300) return AirQuality3.AirQualityEnum.Good;
|
|
170937
171071
|
if (value <= 1e3) return AirQuality3.AirQualityEnum.Fair;
|
|
@@ -170972,17 +171106,17 @@ var TvocAirQualityServer = class extends TvocAirQualityServerBase {
|
|
|
170972
171106
|
const attributes9 = entity.state.attributes;
|
|
170973
171107
|
const deviceClass = attributes9.device_class;
|
|
170974
171108
|
let airQuality = AirQuality3.AirQualityEnum.Unknown;
|
|
170975
|
-
|
|
171109
|
+
logger235.debug(
|
|
170976
171110
|
`[${entity.entity_id}] TVOC update: state="${state}", device_class="${deviceClass}"`
|
|
170977
171111
|
);
|
|
170978
171112
|
if (state != null && !Number.isNaN(+state)) {
|
|
170979
171113
|
const value = +state;
|
|
170980
171114
|
airQuality = deviceClass === SensorDeviceClass.volatile_organic_compounds ? airQualityFromUgm3(value) : airQualityFromPpb(value);
|
|
170981
|
-
|
|
171115
|
+
logger235.debug(
|
|
170982
171116
|
`[${entity.entity_id}] TVOC value=${value} (${deviceClass}) -> airQuality=${AirQuality3.AirQualityEnum[airQuality]}`
|
|
170983
171117
|
);
|
|
170984
171118
|
} else {
|
|
170985
|
-
|
|
171119
|
+
logger235.warn(
|
|
170986
171120
|
`[${entity.entity_id}] TVOC state not a valid number: "${state}"`
|
|
170987
171121
|
);
|
|
170988
171122
|
}
|
|
@@ -171392,13 +171526,13 @@ init_home_assistant_entity_behavior();
|
|
|
171392
171526
|
init_dist();
|
|
171393
171527
|
init_esm();
|
|
171394
171528
|
init_home_assistant_entity_behavior();
|
|
171395
|
-
var
|
|
171529
|
+
var logger236 = Logger.get("VacuumIdentifyServer");
|
|
171396
171530
|
var VacuumIdentifyServer = class extends IdentifyServer2 {
|
|
171397
171531
|
identifyInHomeAssistant(source) {
|
|
171398
171532
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
171399
171533
|
const features = homeAssistant.entity.state.attributes.supported_features ?? 0;
|
|
171400
171534
|
if (testBit(features, VacuumDeviceFeature.LOCATE)) {
|
|
171401
|
-
|
|
171535
|
+
logger236.info(`${source} \u2192 vacuum.locate for ${homeAssistant.entityId}`);
|
|
171402
171536
|
homeAssistant.callAction({ action: "vacuum.locate" });
|
|
171403
171537
|
return;
|
|
171404
171538
|
}
|
|
@@ -171406,7 +171540,7 @@ var VacuumIdentifyServer = class extends IdentifyServer2 {
|
|
|
171406
171540
|
super.identifyInHomeAssistant(source);
|
|
171407
171541
|
return;
|
|
171408
171542
|
}
|
|
171409
|
-
|
|
171543
|
+
logger236.warn(
|
|
171410
171544
|
`${source} for ${homeAssistant.entityId}, LOCATE not in supported_features (${features}), trying vacuum.locate anyway`
|
|
171411
171545
|
);
|
|
171412
171546
|
homeAssistant.callAction({ action: "vacuum.locate" });
|
|
@@ -171590,7 +171724,7 @@ init_esm();
|
|
|
171590
171724
|
// src/matter/behaviors/service-area-server.ts
|
|
171591
171725
|
init_esm();
|
|
171592
171726
|
init_home_assistant_entity_behavior();
|
|
171593
|
-
var
|
|
171727
|
+
var logger237 = Logger.get("ServiceAreaServer");
|
|
171594
171728
|
function orderSelection(areas, agent) {
|
|
171595
171729
|
try {
|
|
171596
171730
|
const ascending = agent?.get(HomeAssistantEntityBehavior).state.mapping?.vacuumAscendingRoomOrder === true;
|
|
@@ -171605,7 +171739,7 @@ var ServiceAreaWithProgress = ServiceAreaBehavior.with(
|
|
|
171605
171739
|
var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
171606
171740
|
selectAreas(request) {
|
|
171607
171741
|
const { newAreas } = request;
|
|
171608
|
-
|
|
171742
|
+
logger237.info(
|
|
171609
171743
|
`ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
|
|
171610
171744
|
);
|
|
171611
171745
|
const uniqueAreas = orderSelection([...new Set(newAreas)], this.agent);
|
|
@@ -171614,7 +171748,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
|
171614
171748
|
(id) => !supportedAreaIds.includes(id)
|
|
171615
171749
|
);
|
|
171616
171750
|
if (invalidAreas.length > 0) {
|
|
171617
|
-
|
|
171751
|
+
logger237.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
|
|
171618
171752
|
return {
|
|
171619
171753
|
status: ServiceArea3.SelectAreasStatus.UnsupportedArea,
|
|
171620
171754
|
statusText: `Invalid area IDs: ${invalidAreas.join(", ")}`
|
|
@@ -171626,7 +171760,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
|
171626
171760
|
status: ServiceArea3.OperationalStatus.Pending
|
|
171627
171761
|
}));
|
|
171628
171762
|
this.state.currentArea = null;
|
|
171629
|
-
|
|
171763
|
+
logger237.info(
|
|
171630
171764
|
`ServiceArea: Stored ${uniqueAreas.length} areas for cleaning: ${uniqueAreas.join(", ")}`
|
|
171631
171765
|
);
|
|
171632
171766
|
return {
|
|
@@ -171647,7 +171781,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
|
171647
171781
|
ServiceAreaServerBase2.State = State;
|
|
171648
171782
|
})(ServiceAreaServerBase || (ServiceAreaServerBase = {}));
|
|
171649
171783
|
function ServiceAreaServer2(initialState) {
|
|
171650
|
-
|
|
171784
|
+
logger237.info(
|
|
171651
171785
|
`Creating ServiceAreaServer with ${initialState.supportedAreas.length} areas`
|
|
171652
171786
|
);
|
|
171653
171787
|
return ServiceAreaServerBase.set({
|
|
@@ -171664,7 +171798,7 @@ var ServiceAreaWithMapsAndProgress = ServiceAreaBehavior.with(
|
|
|
171664
171798
|
var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress {
|
|
171665
171799
|
selectAreas(request) {
|
|
171666
171800
|
const { newAreas } = request;
|
|
171667
|
-
|
|
171801
|
+
logger237.info(
|
|
171668
171802
|
`ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
|
|
171669
171803
|
);
|
|
171670
171804
|
const uniqueAreas = orderSelection([...new Set(newAreas)], this.agent);
|
|
@@ -171673,7 +171807,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
|
|
|
171673
171807
|
(id) => !supportedAreaIds.includes(id)
|
|
171674
171808
|
);
|
|
171675
171809
|
if (invalidAreas.length > 0) {
|
|
171676
|
-
|
|
171810
|
+
logger237.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
|
|
171677
171811
|
return {
|
|
171678
171812
|
status: ServiceArea3.SelectAreasStatus.UnsupportedArea,
|
|
171679
171813
|
statusText: `Invalid area IDs: ${invalidAreas.join(", ")}`
|
|
@@ -171685,7 +171819,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
|
|
|
171685
171819
|
status: ServiceArea3.OperationalStatus.Pending
|
|
171686
171820
|
}));
|
|
171687
171821
|
this.state.currentArea = null;
|
|
171688
|
-
|
|
171822
|
+
logger237.info(
|
|
171689
171823
|
`ServiceArea: Stored ${uniqueAreas.length} areas for cleaning: ${uniqueAreas.join(", ")}`
|
|
171690
171824
|
);
|
|
171691
171825
|
return {
|
|
@@ -171706,14 +171840,14 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
|
|
|
171706
171840
|
ServiceAreaServerWithMapsBase2.State = State;
|
|
171707
171841
|
})(ServiceAreaServerWithMapsBase || (ServiceAreaServerWithMapsBase = {}));
|
|
171708
171842
|
function ServiceAreaServerWithMaps(initialState) {
|
|
171709
|
-
|
|
171843
|
+
logger237.info(
|
|
171710
171844
|
`Creating ServiceAreaServer with Maps: ${initialState.supportedAreas.length} areas, ${initialState.supportedMaps.length} maps`
|
|
171711
171845
|
);
|
|
171712
171846
|
for (const map of initialState.supportedMaps) {
|
|
171713
171847
|
const areaCount = initialState.supportedAreas.filter(
|
|
171714
171848
|
(a) => a.mapId === map.mapId
|
|
171715
171849
|
).length;
|
|
171716
|
-
|
|
171850
|
+
logger237.info(` Map ${map.mapId}: "${map.name}" (${areaCount} areas)`);
|
|
171717
171851
|
}
|
|
171718
171852
|
return ServiceAreaServerWithMapsBase.set({
|
|
171719
171853
|
supportedAreas: initialState.supportedAreas,
|
|
@@ -171725,7 +171859,7 @@ function ServiceAreaServerWithMaps(initialState) {
|
|
|
171725
171859
|
}
|
|
171726
171860
|
|
|
171727
171861
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-service-area-server.ts
|
|
171728
|
-
var
|
|
171862
|
+
var logger238 = Logger.get("VacuumServiceAreaServer");
|
|
171729
171863
|
function toAreaId(roomId) {
|
|
171730
171864
|
if (typeof roomId === "number") {
|
|
171731
171865
|
return roomId;
|
|
@@ -171804,13 +171938,13 @@ function createVacuumServiceAreaServer(attributes9, roomEntities, includeUnnamed
|
|
|
171804
171938
|
let rooms;
|
|
171805
171939
|
if (roomEntities && roomEntities.length > 0) {
|
|
171806
171940
|
rooms = buttonEntitiesToRooms(roomEntities, attributes9);
|
|
171807
|
-
|
|
171941
|
+
logger238.info(
|
|
171808
171942
|
`Using ${rooms.length} button entities as rooms: ${rooms.map((r) => r.name).join(", ")}`
|
|
171809
171943
|
);
|
|
171810
171944
|
} else {
|
|
171811
171945
|
rooms = parseVacuumRooms(attributes9, includeUnnamedRooms);
|
|
171812
171946
|
if (rooms.length > 0) {
|
|
171813
|
-
|
|
171947
|
+
logger238.info(
|
|
171814
171948
|
`Using ${rooms.length} rooms from attributes: ${rooms.map((r) => r.name).join(", ")}`
|
|
171815
171949
|
);
|
|
171816
171950
|
}
|
|
@@ -171864,7 +171998,7 @@ function createCustomServiceAreaServer(customAreas) {
|
|
|
171864
171998
|
landmarkInfo: null
|
|
171865
171999
|
}
|
|
171866
172000
|
}));
|
|
171867
|
-
|
|
172001
|
+
logger238.info(
|
|
171868
172002
|
`Using ${customAreas.length} custom service areas: ${customAreas.map((a) => a.name).join(", ")}`
|
|
171869
172003
|
);
|
|
171870
172004
|
return ServiceAreaServer2({
|
|
@@ -171886,7 +172020,7 @@ function createCleanAreaServiceAreaServer(cleanAreaRooms) {
|
|
|
171886
172020
|
landmarkInfo: null
|
|
171887
172021
|
}
|
|
171888
172022
|
}));
|
|
171889
|
-
|
|
172023
|
+
logger238.info(
|
|
171890
172024
|
`Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA: ${cleanAreaRooms.map((r) => r.name).join(", ")}`
|
|
171891
172025
|
);
|
|
171892
172026
|
return ServiceAreaServer2({
|
|
@@ -171922,11 +172056,11 @@ function getVacuumServiceAreas(attributes9, mapping) {
|
|
|
171922
172056
|
}
|
|
171923
172057
|
|
|
171924
172058
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-run-mode-server.ts
|
|
171925
|
-
var
|
|
172059
|
+
var logger239 = Logger.get("VacuumRvcRunModeServer");
|
|
171926
172060
|
function buildValetudoSegmentAction(vacuumEntityId, segmentIds, valetudoIdentifier) {
|
|
171927
172061
|
const identifier = valetudoIdentifier || vacuumEntityId.replace(/^vacuum\.valetudo_/, "");
|
|
171928
172062
|
const topic = `valetudo/${identifier}/MapSegmentationCapability/clean/set`;
|
|
171929
|
-
|
|
172063
|
+
logger239.info(
|
|
171930
172064
|
`Valetudo: mqtt.publish to ${topic}, segments: ${segmentIds.join(", ")}`
|
|
171931
172065
|
);
|
|
171932
172066
|
return {
|
|
@@ -172031,14 +172165,14 @@ function mergeBatchData(areas) {
|
|
|
172031
172165
|
function handleCustomServiceAreas(selectedAreas, customAreas, session) {
|
|
172032
172166
|
const matched = selectedAreas.map((areaId) => ({ areaId, area: customAreas[areaId - 1] })).filter((m) => !!m.area);
|
|
172033
172167
|
if (matched.length === 0) {
|
|
172034
|
-
|
|
172168
|
+
logger239.warn(
|
|
172035
172169
|
`Custom service areas: no match for selected IDs ${selectedAreas.join(", ")}`
|
|
172036
172170
|
);
|
|
172037
172171
|
return { action: "vacuum.start" };
|
|
172038
172172
|
}
|
|
172039
172173
|
const batchArea = matched.find(({ area }) => area.batchDispatch === true);
|
|
172040
172174
|
if (batchArea) {
|
|
172041
|
-
|
|
172175
|
+
logger239.info(
|
|
172042
172176
|
`Custom service areas (batch): single call for ${matched.length} room(s): ${matched.map(({ area }) => area.name).join(", ")}`
|
|
172043
172177
|
);
|
|
172044
172178
|
session.pendingDispatches = [];
|
|
@@ -172059,7 +172193,7 @@ function handleCustomServiceAreas(selectedAreas, customAreas, session) {
|
|
|
172059
172193
|
}
|
|
172060
172194
|
};
|
|
172061
172195
|
}
|
|
172062
|
-
|
|
172196
|
+
logger239.info(
|
|
172063
172197
|
`Custom service areas: ${matched.length} room(s) queued: ${matched.map(({ area }) => `${area.service} (${area.name})`).join(", ")}`
|
|
172064
172198
|
);
|
|
172065
172199
|
session.pendingDispatches = matched.slice(1).map(({ areaId, area }) => ({
|
|
@@ -172117,7 +172251,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
172117
172251
|
if (cleanAreaRooms && cleanAreaRooms.length > 0) {
|
|
172118
172252
|
const haAreaIds = resolveCleanAreaIds(selectedAreas, cleanAreaRooms);
|
|
172119
172253
|
if (haAreaIds.length > 0) {
|
|
172120
|
-
|
|
172254
|
+
logger239.info(`CLEAN_AREA: cleaning HA areas: ${haAreaIds.join(", ")}`);
|
|
172121
172255
|
return {
|
|
172122
172256
|
action: {
|
|
172123
172257
|
action: "vacuum.clean_area",
|
|
@@ -172137,7 +172271,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
172137
172271
|
}
|
|
172138
172272
|
}
|
|
172139
172273
|
if (matched.length > 0) {
|
|
172140
|
-
|
|
172274
|
+
logger239.info(
|
|
172141
172275
|
`Roborock: ${matched.length} room button(s) queued: ${matched.map((m) => m.entityId).join(", ")}`
|
|
172142
172276
|
);
|
|
172143
172277
|
return {
|
|
@@ -172172,12 +172306,12 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
172172
172306
|
}
|
|
172173
172307
|
}
|
|
172174
172308
|
if (roomIds.length > 0) {
|
|
172175
|
-
|
|
172309
|
+
logger239.info(`Starting cleaning with selected areas: ${roomIds.join(", ")}`);
|
|
172176
172310
|
if (isDreameVacuum(attributes9)) {
|
|
172177
172311
|
if (targetMapName) {
|
|
172178
172312
|
const vacName = entityId.replace("vacuum.", "");
|
|
172179
172313
|
const selectedMapEntity = `select.${vacName}_selected_map`;
|
|
172180
|
-
|
|
172314
|
+
logger239.info(
|
|
172181
172315
|
`Dreame multi-floor: switching to map "${targetMapName}" via ${selectedMapEntity}`
|
|
172182
172316
|
);
|
|
172183
172317
|
seam.callAction({
|
|
@@ -172205,7 +172339,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
172205
172339
|
}
|
|
172206
172340
|
if (isEcovacsVacuum(attributes9)) {
|
|
172207
172341
|
const roomIdStr = roomIds.join(",");
|
|
172208
|
-
|
|
172342
|
+
logger239.info(`Ecovacs vacuum: Using spot_area for rooms: ${roomIdStr}`);
|
|
172209
172343
|
return {
|
|
172210
172344
|
action: {
|
|
172211
172345
|
action: "vacuum.send_command",
|
|
@@ -172217,7 +172351,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
172217
172351
|
pending: []
|
|
172218
172352
|
};
|
|
172219
172353
|
}
|
|
172220
|
-
|
|
172354
|
+
logger239.warn(
|
|
172221
172355
|
`Room cleaning via send_command not supported for this vacuum type. Rooms: ${roomIds.join(", ")}. Falling back to vacuum.start`
|
|
172222
172356
|
);
|
|
172223
172357
|
}
|
|
@@ -172226,7 +172360,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
|
|
|
172226
172360
|
var vacuumRvcRunModeConfig = {
|
|
172227
172361
|
getCurrentMode: (entity) => {
|
|
172228
172362
|
const isCleaning = vacuumIsCleaning(entity.state);
|
|
172229
|
-
|
|
172363
|
+
logger239.debug(
|
|
172230
172364
|
`Vacuum state: "${entity.state}", isCleaning: ${isCleaning}, currentMode: ${isCleaning ? "Cleaning" : "Idle"}`
|
|
172231
172365
|
);
|
|
172232
172366
|
return isCleaning ? 1 /* Cleaning */ : 0 /* Idle */;
|
|
@@ -172265,7 +172399,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172265
172399
|
}
|
|
172266
172400
|
} catch {
|
|
172267
172401
|
}
|
|
172268
|
-
|
|
172402
|
+
logger239.info("Starting regular cleaning (no areas selected)");
|
|
172269
172403
|
return { action: "vacuum.start" };
|
|
172270
172404
|
},
|
|
172271
172405
|
returnToBase: () => ({ action: "vacuum.return_to_base" }),
|
|
@@ -172280,7 +172414,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172280
172414
|
const homeAssistant = agent.get(HomeAssistantEntityBehavior);
|
|
172281
172415
|
const entity = homeAssistant.entity;
|
|
172282
172416
|
const attributes9 = entity.state.attributes;
|
|
172283
|
-
|
|
172417
|
+
logger239.info(`cleanRoom called: roomMode=${roomMode}`);
|
|
172284
172418
|
const cleanAreaRooms = homeAssistant.state.mapping?.cleanAreaRooms;
|
|
172285
172419
|
if (cleanAreaRooms && cleanAreaRooms.length > 0) {
|
|
172286
172420
|
const sorted = [...cleanAreaRooms].sort(
|
|
@@ -172289,7 +172423,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172289
172423
|
const areaIndex = roomMode - ROOM_MODE_BASE2 - 1;
|
|
172290
172424
|
if (areaIndex >= 0 && areaIndex < sorted.length) {
|
|
172291
172425
|
const area = sorted[areaIndex];
|
|
172292
|
-
|
|
172426
|
+
logger239.info(
|
|
172293
172427
|
`cleanRoom: CLEAN_AREA "${area.name}" \u2192 vacuum.clean_area(${area.haAreaId})`
|
|
172294
172428
|
);
|
|
172295
172429
|
return {
|
|
@@ -172306,7 +172440,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172306
172440
|
const areaIndex = roomMode - ROOM_MODE_BASE2 - 1;
|
|
172307
172441
|
if (areaIndex >= 0 && areaIndex < sorted.length) {
|
|
172308
172442
|
const area = sorted[areaIndex];
|
|
172309
|
-
|
|
172443
|
+
logger239.info(
|
|
172310
172444
|
`cleanRoom: custom service area "${area.name}" \u2192 ${area.service}`
|
|
172311
172445
|
);
|
|
172312
172446
|
return {
|
|
@@ -172327,7 +172461,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172327
172461
|
}
|
|
172328
172462
|
const rooms = parseVacuumRooms(attributes9);
|
|
172329
172463
|
const numericIdFromMode = getRoomIdFromMode(roomMode);
|
|
172330
|
-
|
|
172464
|
+
logger239.info(
|
|
172331
172465
|
`cleanRoom: numericIdFromMode=${numericIdFromMode}, available rooms: ${JSON.stringify(rooms.map((r) => ({ id: r.id, name: r.name, modeValue: getRoomModeValue(r) })))}`
|
|
172332
172466
|
);
|
|
172333
172467
|
const room = rooms.find((r) => getRoomModeValue(r) === roomMode);
|
|
@@ -172337,7 +172471,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172337
172471
|
if (room.mapName) {
|
|
172338
172472
|
const vacuumName = vacuumEntityId.replace("vacuum.", "");
|
|
172339
172473
|
const selectedMapEntity = `select.${vacuumName}_selected_map`;
|
|
172340
|
-
|
|
172474
|
+
logger239.info(
|
|
172341
172475
|
`Dreame multi-floor: switching to map "${room.mapName}" via ${selectedMapEntity}`
|
|
172342
172476
|
);
|
|
172343
172477
|
homeAssistant.callAction({
|
|
@@ -172346,7 +172480,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172346
172480
|
data: { option: room.mapName }
|
|
172347
172481
|
});
|
|
172348
172482
|
}
|
|
172349
|
-
|
|
172483
|
+
logger239.debug(
|
|
172350
172484
|
`Dreame vacuum detected, using dreame_vacuum.vacuum_clean_segment for room ${room.name} (commandId: ${commandId3}, id: ${room.id})`
|
|
172351
172485
|
);
|
|
172352
172486
|
return {
|
|
@@ -172357,7 +172491,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172357
172491
|
};
|
|
172358
172492
|
}
|
|
172359
172493
|
if (isRoborockVacuum(attributes9) || isXiaomiMiotVacuum(attributes9)) {
|
|
172360
|
-
|
|
172494
|
+
logger239.debug(
|
|
172361
172495
|
`Using vacuum.send_command with app_segment_clean for room ${room.name} (commandId: ${commandId3}, id: ${room.id})`
|
|
172362
172496
|
);
|
|
172363
172497
|
return {
|
|
@@ -172370,7 +172504,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172370
172504
|
}
|
|
172371
172505
|
if (isEcovacsVacuum(attributes9)) {
|
|
172372
172506
|
const roomIdStr = String(commandId3);
|
|
172373
|
-
|
|
172507
|
+
logger239.info(
|
|
172374
172508
|
`Ecovacs vacuum: Using spot_area for room ${room.name} (id: ${roomIdStr})`
|
|
172375
172509
|
);
|
|
172376
172510
|
return {
|
|
@@ -172385,7 +172519,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
172385
172519
|
}
|
|
172386
172520
|
};
|
|
172387
172521
|
}
|
|
172388
|
-
|
|
172522
|
+
logger239.warn(
|
|
172389
172523
|
`Room cleaning via send_command not supported for this vacuum type. Room: ${room.name} (id=${commandId3}). Falling back to vacuum.start`
|
|
172390
172524
|
);
|
|
172391
172525
|
}
|
|
@@ -172402,20 +172536,20 @@ function createVacuumRvcRunModeServer(attributes9, includeUnnamedRooms = false,
|
|
|
172402
172536
|
customAreas,
|
|
172403
172537
|
disableRoomModes
|
|
172404
172538
|
);
|
|
172405
|
-
|
|
172539
|
+
logger239.info(
|
|
172406
172540
|
`Creating VacuumRvcRunModeServer with ${rooms.length} rooms, ${supportedModes2.length} total modes`
|
|
172407
172541
|
);
|
|
172408
172542
|
if (rooms.length > 0) {
|
|
172409
|
-
|
|
172543
|
+
logger239.info(`Rooms found: ${rooms.map((r) => r.name).join(", ")}`);
|
|
172410
172544
|
}
|
|
172411
172545
|
if (filteredCount > 0) {
|
|
172412
172546
|
const filtered = allRooms.filter((r) => !rooms.some((x) => x.id === r.id));
|
|
172413
|
-
|
|
172547
|
+
logger239.info(
|
|
172414
172548
|
`Filtered out ${filteredCount} unnamed room(s): ${filtered.map((r) => r.name).join(", ")}`
|
|
172415
172549
|
);
|
|
172416
172550
|
}
|
|
172417
172551
|
if (allRooms.length === 0) {
|
|
172418
|
-
|
|
172552
|
+
logger239.debug(
|
|
172419
172553
|
`No rooms found. Attributes: rooms=${JSON.stringify(attributes9.rooms)}, segments=${JSON.stringify(attributes9.segments)}, room_list=${attributes9.room_list}`
|
|
172420
172554
|
);
|
|
172421
172555
|
}
|
|
@@ -172449,7 +172583,7 @@ function createCleanAreaRvcRunModeServer(cleanAreaRooms) {
|
|
|
172449
172583
|
modeTags: [{ value: RvcRunMode3.ModeTag.Cleaning }]
|
|
172450
172584
|
});
|
|
172451
172585
|
}
|
|
172452
|
-
|
|
172586
|
+
logger239.info(
|
|
172453
172587
|
`Creating CLEAN_AREA RvcRunModeServer with ${cleanAreaRooms.length} HA areas, ${modes.length} total modes`
|
|
172454
172588
|
);
|
|
172455
172589
|
return RvcRunModeServer2(vacuumRvcRunModeConfig, {
|
|
@@ -172539,7 +172673,7 @@ init_nodejs();
|
|
|
172539
172673
|
|
|
172540
172674
|
// src/matter/behaviors/rvc-clean-mode-server.ts
|
|
172541
172675
|
init_home_assistant_entity_behavior();
|
|
172542
|
-
var
|
|
172676
|
+
var logger240 = Logger.get("RvcCleanModeServerBase");
|
|
172543
172677
|
var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeServer {
|
|
172544
172678
|
// Pending mode from a recent changeToMode command.
|
|
172545
172679
|
// Prevents stale HA state (from a different entity like select.xxx)
|
|
@@ -172586,14 +172720,14 @@ var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeS
|
|
|
172586
172720
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
172587
172721
|
const { newMode } = request;
|
|
172588
172722
|
if (newMode !== this.state.currentMode && !this.state.supportedModes.some((m) => m.mode === newMode)) {
|
|
172589
|
-
|
|
172723
|
+
logger240.warn(`changeToMode(${newMode}) rejected: unsupported mode`);
|
|
172590
172724
|
return {
|
|
172591
172725
|
status: ModeBase3.ModeChangeStatus.UnsupportedMode,
|
|
172592
172726
|
statusText: `Unsupported mode: ${newMode}`
|
|
172593
172727
|
};
|
|
172594
172728
|
}
|
|
172595
172729
|
const modeLabel = this.state.supportedModes.find((m) => m.mode === newMode);
|
|
172596
|
-
|
|
172730
|
+
logger240.info(
|
|
172597
172731
|
`changeToMode(${newMode}) "${modeLabel?.label ?? "unknown"}" for ${homeAssistant.entityId}`
|
|
172598
172732
|
);
|
|
172599
172733
|
this.pendingMode = newMode;
|
|
@@ -172601,7 +172735,7 @@ var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeS
|
|
|
172601
172735
|
this.state.currentMode = newMode;
|
|
172602
172736
|
const action = this.state.config.setCleanMode(newMode, this.agent);
|
|
172603
172737
|
if (action) {
|
|
172604
|
-
|
|
172738
|
+
logger240.info(
|
|
172605
172739
|
`changeToMode: dispatching action ${action.action} \u2192 ${action.target ?? homeAssistant.entityId}`
|
|
172606
172740
|
);
|
|
172607
172741
|
homeAssistant.callAction(action);
|
|
@@ -172634,7 +172768,7 @@ function RvcCleanModeServer2(config8, initialState) {
|
|
|
172634
172768
|
}
|
|
172635
172769
|
|
|
172636
172770
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-clean-mode-server.ts
|
|
172637
|
-
var
|
|
172771
|
+
var logger241 = Logger.get("VacuumRvcCleanModeServer");
|
|
172638
172772
|
var MODE_VACUUM = 0;
|
|
172639
172773
|
var MODE_VACUUM_AND_MOP = 1;
|
|
172640
172774
|
var MODE_MOP = 2;
|
|
@@ -172904,7 +173038,7 @@ function findMatchingCleanOption(ct, availableOptions) {
|
|
|
172904
173038
|
const match = availableOptions.find((o) => classifyCleanOption(o) === type);
|
|
172905
173039
|
if (match) return match;
|
|
172906
173040
|
}
|
|
172907
|
-
|
|
173041
|
+
logger241.warn(
|
|
172908
173042
|
`No match for ${CLEAN_TYPE_LABELS[ct]} in [${availableOptions.join(", ")}]`
|
|
172909
173043
|
);
|
|
172910
173044
|
return availableOptions[0];
|
|
@@ -172913,7 +173047,7 @@ function buildCleaningModeAction(targetCleanType, agent) {
|
|
|
172913
173047
|
const selectEntityId = getCleaningModeSelectEntity(agent);
|
|
172914
173048
|
const { options } = readSelectEntity(selectEntityId, agent);
|
|
172915
173049
|
const optionToUse = findMatchingCleanOption(targetCleanType, options);
|
|
172916
|
-
|
|
173050
|
+
logger241.info(
|
|
172917
173051
|
`Switching cleaning mode to: ${optionToUse} via ${selectEntityId}`
|
|
172918
173052
|
);
|
|
172919
173053
|
return {
|
|
@@ -173002,7 +173136,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173002
173136
|
}
|
|
173003
173137
|
}
|
|
173004
173138
|
if (speedMode !== void 0) {
|
|
173005
|
-
|
|
173139
|
+
logger241.debug(
|
|
173006
173140
|
`Current mode: Vacuum + fan_speed="${speedState}" -> mode ${speedMode}`
|
|
173007
173141
|
);
|
|
173008
173142
|
return speedMode;
|
|
@@ -173023,7 +173157,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173023
173157
|
}
|
|
173024
173158
|
}
|
|
173025
173159
|
if (mopMode !== void 0) {
|
|
173026
|
-
|
|
173160
|
+
logger241.debug(
|
|
173027
173161
|
`Current mode: Mop + intensity="${state}" -> mode ${mopMode}`
|
|
173028
173162
|
);
|
|
173029
173163
|
return mopMode;
|
|
@@ -173041,14 +173175,14 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173041
173175
|
const homeAssistant = agent.get(HomeAssistantEntityBehavior);
|
|
173042
173176
|
const vacuumEntityId = homeAssistant.entityId;
|
|
173043
173177
|
const mapping = homeAssistant.state.mapping;
|
|
173044
|
-
|
|
173178
|
+
logger241.info(
|
|
173045
173179
|
`setCleanMode(${mode}) for ${vacuumEntityId}, suctionEntity=${mapping?.suctionLevelEntity ?? "none"}, mopEntity=${mapping?.mopIntensityEntity ?? "none"}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})}`
|
|
173046
173180
|
);
|
|
173047
173181
|
if (mopIntensityList && mopIntensityList.length > 0 && isMopIntensityMode(mode)) {
|
|
173048
173182
|
const mopIndex = mode - MOP_INTENSITY_MODE_BASE;
|
|
173049
173183
|
const mopName = mopIntensityList[mopIndex];
|
|
173050
173184
|
if (!mopName) {
|
|
173051
|
-
|
|
173185
|
+
logger241.warn(`Invalid mop intensity mode index: ${mopIndex}`);
|
|
173052
173186
|
return void 0;
|
|
173053
173187
|
}
|
|
173054
173188
|
if (hasCleanTypes) {
|
|
@@ -173061,18 +173195,18 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173061
173195
|
mapping.mopIntensityEntity,
|
|
173062
173196
|
agent
|
|
173063
173197
|
);
|
|
173064
|
-
|
|
173198
|
+
logger241.info(
|
|
173065
173199
|
`Mop intensity entity ${mapping.mopIntensityEntity}: current="${state}", options=${JSON.stringify(options ?? [])}`
|
|
173066
173200
|
);
|
|
173067
173201
|
let option = matchMopIntensityOption(mopName, options);
|
|
173068
173202
|
if (!option && options && mopIndex < options.length) {
|
|
173069
173203
|
option = options[mopIndex];
|
|
173070
|
-
|
|
173204
|
+
logger241.info(
|
|
173071
173205
|
`Positional match for mop "${mopName}" -> "${option}" (index ${mopIndex})`
|
|
173072
173206
|
);
|
|
173073
173207
|
}
|
|
173074
173208
|
if (option) {
|
|
173075
|
-
|
|
173209
|
+
logger241.info(
|
|
173076
173210
|
`Setting mop intensity to: ${option} via ${mapping.mopIntensityEntity}`
|
|
173077
173211
|
);
|
|
173078
173212
|
return {
|
|
@@ -173081,11 +173215,11 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173081
173215
|
target: mapping.mopIntensityEntity
|
|
173082
173216
|
};
|
|
173083
173217
|
}
|
|
173084
|
-
|
|
173218
|
+
logger241.warn(
|
|
173085
173219
|
`No match for mop intensity "${mopName}" in options: [${(options ?? []).join(", ")}]`
|
|
173086
173220
|
);
|
|
173087
173221
|
} else {
|
|
173088
|
-
|
|
173222
|
+
logger241.warn(
|
|
173089
173223
|
`Mop intensity mode ${mode} requested but no mopIntensityEntity configured`
|
|
173090
173224
|
);
|
|
173091
173225
|
}
|
|
@@ -173095,7 +173229,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173095
173229
|
const fanSpeedIndex = mode - FAN_SPEED_MODE_BASE;
|
|
173096
173230
|
const fanSpeedName = fanSpeedList[fanSpeedIndex];
|
|
173097
173231
|
if (!fanSpeedName) {
|
|
173098
|
-
|
|
173232
|
+
logger241.warn(`Invalid fan speed mode index: ${fanSpeedIndex}`);
|
|
173099
173233
|
return void 0;
|
|
173100
173234
|
}
|
|
173101
173235
|
if (mapping?.suctionLevelEntity) {
|
|
@@ -173108,7 +173242,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173108
173242
|
mapping.suctionLevelEntity,
|
|
173109
173243
|
agent
|
|
173110
173244
|
);
|
|
173111
|
-
|
|
173245
|
+
logger241.info(
|
|
173112
173246
|
`Suction entity ${mapping.suctionLevelEntity}: current="${state}", options=${JSON.stringify(options ?? [])}`
|
|
173113
173247
|
);
|
|
173114
173248
|
let option = matchFanSpeedOption(
|
|
@@ -173118,12 +173252,12 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173118
173252
|
);
|
|
173119
173253
|
if (!option && options && fanSpeedIndex < options.length) {
|
|
173120
173254
|
option = options[fanSpeedIndex];
|
|
173121
|
-
|
|
173255
|
+
logger241.info(
|
|
173122
173256
|
`Positional match for fan "${fanSpeedName}" -> "${option}" (index ${fanSpeedIndex})`
|
|
173123
173257
|
);
|
|
173124
173258
|
}
|
|
173125
173259
|
if (option) {
|
|
173126
|
-
|
|
173260
|
+
logger241.info(
|
|
173127
173261
|
`Setting suction to: ${option} via ${mapping.suctionLevelEntity}`
|
|
173128
173262
|
);
|
|
173129
173263
|
return {
|
|
@@ -173132,7 +173266,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173132
173266
|
target: mapping.suctionLevelEntity
|
|
173133
173267
|
};
|
|
173134
173268
|
}
|
|
173135
|
-
|
|
173269
|
+
logger241.warn(
|
|
173136
173270
|
`No match for fan speed "${fanSpeedName}" in suction options: [${(options ?? []).join(", ")}]`
|
|
173137
173271
|
);
|
|
173138
173272
|
return void 0;
|
|
@@ -173142,7 +173276,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173142
173276
|
buildCleaningModeAction(0 /* Sweeping */, agent)
|
|
173143
173277
|
);
|
|
173144
173278
|
}
|
|
173145
|
-
|
|
173279
|
+
logger241.info(
|
|
173146
173280
|
`Setting fan speed to: ${fanSpeedName} via vacuum.set_fan_speed`
|
|
173147
173281
|
);
|
|
173148
173282
|
return {
|
|
@@ -173152,7 +173286,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173152
173286
|
};
|
|
173153
173287
|
}
|
|
173154
173288
|
if (!hasCleanTypes) {
|
|
173155
|
-
|
|
173289
|
+
logger241.debug(
|
|
173156
173290
|
`Ignoring cleaning type change (mode=${mode}): no cleaning mode entity`
|
|
173157
173291
|
);
|
|
173158
173292
|
return void 0;
|
|
@@ -173164,7 +173298,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
173164
173298
|
agent
|
|
173165
173299
|
);
|
|
173166
173300
|
const optionToUse = findMatchingCleanOption(cleanType, availableOptions);
|
|
173167
|
-
|
|
173301
|
+
logger241.info(
|
|
173168
173302
|
`Setting cleaning mode to: ${optionToUse} (mode=${mode}) via ${selectEntityId}`
|
|
173169
173303
|
);
|
|
173170
173304
|
return {
|
|
@@ -173182,10 +173316,10 @@ function createVacuumRvcCleanModeServer(_attributes, fanSpeedList, mopIntensityL
|
|
|
173182
173316
|
cleaningModeOptions,
|
|
173183
173317
|
customFanSpeedTags
|
|
173184
173318
|
);
|
|
173185
|
-
|
|
173319
|
+
logger241.info(
|
|
173186
173320
|
`Creating VacuumRvcCleanModeServer with ${supportedModes2.length} modes (fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, cleaningModeOptions=${JSON.stringify(cleaningModeOptions ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})})`
|
|
173187
173321
|
);
|
|
173188
|
-
|
|
173322
|
+
logger241.info(
|
|
173189
173323
|
`Modes: ${supportedModes2.map((m) => `${m.mode}:${m.label}[${m.modeTags.map((t) => t.value).join(",")}]`).join(", ")}`
|
|
173190
173324
|
);
|
|
173191
173325
|
const initialState = {
|
|
@@ -173248,7 +173382,7 @@ function resolveMopIntensityList(mopIntensityEntity) {
|
|
|
173248
173382
|
init_dist();
|
|
173249
173383
|
init_esm();
|
|
173250
173384
|
init_home_assistant_entity_behavior();
|
|
173251
|
-
var
|
|
173385
|
+
var logger242 = Logger.get("VacuumRvcOperationalStateServer");
|
|
173252
173386
|
function batteryFromAttributes(attrs) {
|
|
173253
173387
|
const raw = attrs.battery_level ?? attrs.battery;
|
|
173254
173388
|
if (raw == null) return null;
|
|
@@ -173301,16 +173435,16 @@ function mapVacuumOperationalState(entity, batteryPercent = batteryFromAttribute
|
|
|
173301
173435
|
operationalState = RvcOperationalState4.OperationalState.Error;
|
|
173302
173436
|
} else {
|
|
173303
173437
|
if (state.toLowerCase().includes("clean")) {
|
|
173304
|
-
|
|
173438
|
+
logger242.info(
|
|
173305
173439
|
`Unknown vacuum state "${state}" contains 'clean', treating as Running`
|
|
173306
173440
|
);
|
|
173307
173441
|
operationalState = RvcOperationalState4.OperationalState.Running;
|
|
173308
173442
|
} else {
|
|
173309
|
-
|
|
173443
|
+
logger242.info(`Unknown vacuum state "${state}", treating as Stopped`);
|
|
173310
173444
|
operationalState = RvcOperationalState4.OperationalState.Stopped;
|
|
173311
173445
|
}
|
|
173312
173446
|
}
|
|
173313
|
-
|
|
173447
|
+
logger242.debug(
|
|
173314
173448
|
`Vacuum operationalState: "${state}" -> ${RvcOperationalState4.OperationalState[operationalState]}`
|
|
173315
173449
|
);
|
|
173316
173450
|
return operationalState;
|
|
@@ -173339,7 +173473,7 @@ var VacuumRvcOperationalStateServer = RvcOperationalStateServer2({
|
|
|
173339
173473
|
});
|
|
173340
173474
|
|
|
173341
173475
|
// src/matter/endpoints/legacy/vacuum/index.ts
|
|
173342
|
-
var
|
|
173476
|
+
var logger243 = Logger.get("VacuumDevice");
|
|
173343
173477
|
var VacuumEndpointType = RoboticVacuumCleanerDevice.with(
|
|
173344
173478
|
BasicInformationServer2,
|
|
173345
173479
|
VacuumIdentifyServer,
|
|
@@ -173353,7 +173487,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
173353
173487
|
const entityId = homeAssistantEntity.entity.entity_id;
|
|
173354
173488
|
const attributes9 = homeAssistantEntity.entity.state.attributes;
|
|
173355
173489
|
const customAreas = homeAssistantEntity.mapping?.customServiceAreas;
|
|
173356
|
-
|
|
173490
|
+
logger243.info(
|
|
173357
173491
|
`Creating vacuum endpoint for ${entityId}, mapping: ${JSON.stringify(homeAssistantEntity.mapping ?? "none")}`
|
|
173358
173492
|
);
|
|
173359
173493
|
const cleanAreaRooms = homeAssistantEntity.mapping?.cleanAreaRooms;
|
|
@@ -173366,32 +173500,32 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
173366
173500
|
)
|
|
173367
173501
|
).set({ homeAssistantEntity });
|
|
173368
173502
|
if (includeOnOff) {
|
|
173369
|
-
|
|
173503
|
+
logger243.info(`${entityId}: Adding OnOff cluster (vacuumOnOff flag enabled)`);
|
|
173370
173504
|
device = device.with(VacuumOnOffServer);
|
|
173371
173505
|
}
|
|
173372
173506
|
device = device.with(VacuumPowerSourceServer);
|
|
173373
173507
|
const roomEntities = homeAssistantEntity.mapping?.roomEntities;
|
|
173374
173508
|
const rooms = parseVacuumRooms(attributes9);
|
|
173375
|
-
|
|
173509
|
+
logger243.info(
|
|
173376
173510
|
`${entityId}: customAreas=${customAreas?.length ?? 0}, roomEntities=${JSON.stringify(roomEntities ?? [])}, parsedRooms=${rooms.length}, cleanAreaRooms=${cleanAreaRooms?.length ?? 0}`
|
|
173377
173511
|
);
|
|
173378
173512
|
if (cleanAreaRooms && cleanAreaRooms.length > 0) {
|
|
173379
|
-
|
|
173513
|
+
logger243.info(
|
|
173380
173514
|
`${entityId}: Adding ServiceArea (${cleanAreaRooms.length} HA areas via CLEAN_AREA)`
|
|
173381
173515
|
);
|
|
173382
173516
|
device = device.with(createCleanAreaServiceAreaServer(cleanAreaRooms));
|
|
173383
173517
|
} else if (customAreas && customAreas.length > 0) {
|
|
173384
|
-
|
|
173518
|
+
logger243.info(
|
|
173385
173519
|
`${entityId}: Adding ServiceArea (${customAreas.length} custom areas)`
|
|
173386
173520
|
);
|
|
173387
173521
|
device = device.with(createCustomServiceAreaServer(customAreas));
|
|
173388
173522
|
} else if (rooms.length > 0 || roomEntities && roomEntities.length > 0) {
|
|
173389
|
-
|
|
173523
|
+
logger243.info(`${entityId}: Adding ServiceArea (${rooms.length} rooms)`);
|
|
173390
173524
|
device = device.with(
|
|
173391
173525
|
createVacuumServiceAreaServer(attributes9, roomEntities)
|
|
173392
173526
|
);
|
|
173393
173527
|
} else {
|
|
173394
|
-
|
|
173528
|
+
logger243.info(`${entityId}: Adding ServiceArea (default single-area)`);
|
|
173395
173529
|
device = device.with(createDefaultServiceAreaServer());
|
|
173396
173530
|
}
|
|
173397
173531
|
const fanSpeedList = resolveFanSpeedList(
|
|
@@ -173402,7 +173536,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
173402
173536
|
homeAssistantEntity.mapping?.mopIntensityEntity
|
|
173403
173537
|
);
|
|
173404
173538
|
if (cleaningModeOptions || fanSpeedList || mopIntensityList) {
|
|
173405
|
-
|
|
173539
|
+
logger243.info(
|
|
173406
173540
|
`${entityId}: Adding RvcCleanMode (multi-mode, cleaningModeOptions=${JSON.stringify(cleaningModeOptions ?? [])}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])})`
|
|
173407
173541
|
);
|
|
173408
173542
|
device = device.with(
|
|
@@ -173415,7 +173549,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
173415
173549
|
)
|
|
173416
173550
|
);
|
|
173417
173551
|
} else {
|
|
173418
|
-
|
|
173552
|
+
logger243.info(`${entityId}: Adding RvcCleanMode (default single-mode)`);
|
|
173419
173553
|
device = device.with(createDefaultRvcCleanModeServer());
|
|
173420
173554
|
}
|
|
173421
173555
|
return device;
|
|
@@ -173581,7 +173715,7 @@ var WaterHeaterThermostatServer = ThermostatServer2(
|
|
|
173581
173715
|
);
|
|
173582
173716
|
|
|
173583
173717
|
// src/matter/endpoints/legacy/water-heater/index.ts
|
|
173584
|
-
var
|
|
173718
|
+
var logger244 = Logger.get("WaterHeaterDevice");
|
|
173585
173719
|
var WaterHeaterDeviceType = ThermostatDevice.with(
|
|
173586
173720
|
BasicInformationServer2,
|
|
173587
173721
|
IdentifyServer2,
|
|
@@ -173597,7 +173731,7 @@ function toMatterTemp2(value) {
|
|
|
173597
173731
|
}
|
|
173598
173732
|
function WaterHeaterDevice2(homeAssistantEntity) {
|
|
173599
173733
|
const attributes9 = homeAssistantEntity.entity.state.attributes;
|
|
173600
|
-
|
|
173734
|
+
logger244.debug(
|
|
173601
173735
|
`Creating device for ${homeAssistantEntity.entity.entity_id}, min_temp=${attributes9.min_temp}, max_temp=${attributes9.max_temp}`
|
|
173602
173736
|
);
|
|
173603
173737
|
const minLimit = toMatterTemp2(attributes9.min_temp) ?? 0;
|
|
@@ -173840,7 +173974,7 @@ function activeHeatSource(attributes9) {
|
|
|
173840
173974
|
}
|
|
173841
173975
|
|
|
173842
173976
|
// src/matter/endpoints/legacy/water-heater/behaviors/water-heater-management-server.ts
|
|
173843
|
-
var
|
|
173977
|
+
var logger245 = Logger.get("WaterHeaterManagementServer");
|
|
173844
173978
|
var MAX_TIMER_MS2 = 2147483647;
|
|
173845
173979
|
var boostSessions = /* @__PURE__ */ new WeakMap();
|
|
173846
173980
|
function clearBoostTimer(endpoint) {
|
|
@@ -174086,7 +174220,7 @@ var WaterHeaterManagementServerBase = class _WaterHeaterManagementServerBase ext
|
|
|
174086
174220
|
armBoostTimer(durationSeconds) {
|
|
174087
174221
|
const delay = durationSeconds * 1e3;
|
|
174088
174222
|
if (!Number.isFinite(delay) || delay <= 0 || delay > MAX_TIMER_MS2) {
|
|
174089
|
-
|
|
174223
|
+
logger245.debug(
|
|
174090
174224
|
`Boost duration ${durationSeconds}s outside the timer range, boost stays active until CancelBoost`
|
|
174091
174225
|
);
|
|
174092
174226
|
return;
|
|
@@ -174100,7 +174234,7 @@ var WaterHeaterManagementServerBase = class _WaterHeaterManagementServerBase ext
|
|
|
174100
174234
|
agent.get(_WaterHeaterManagementServerBase).endBoost({ restoreMode: true });
|
|
174101
174235
|
});
|
|
174102
174236
|
} catch (error) {
|
|
174103
|
-
|
|
174237
|
+
logger245.debug(
|
|
174104
174238
|
`Boost expiry failed (endpoint may be closing): ${error}`
|
|
174105
174239
|
);
|
|
174106
174240
|
}
|
|
@@ -174203,13 +174337,13 @@ function WaterHeaterModeServer2(mapping, initialMode) {
|
|
|
174203
174337
|
}
|
|
174204
174338
|
|
|
174205
174339
|
// src/matter/endpoints/legacy/water-heater/water-heater-management-device.ts
|
|
174206
|
-
var
|
|
174340
|
+
var logger246 = Logger.get("WaterHeaterManagementDevice");
|
|
174207
174341
|
function WaterHeaterManagementDevice(homeAssistantEntity) {
|
|
174208
174342
|
const entityState = homeAssistantEntity.entity.state;
|
|
174209
174343
|
const attributes9 = entityState.attributes;
|
|
174210
174344
|
const modeMapping = buildModeMapping(attributes9);
|
|
174211
174345
|
const initialMode = currentMode(modeMapping, entityState.state, attributes9);
|
|
174212
|
-
|
|
174346
|
+
logger246.debug(
|
|
174213
174347
|
`Creating Matter 1.4 water heater for ${homeAssistantEntity.entity.entity_id}, modes=[${modeMapping.supportedModes.map((m) => `${m.mode}:${m.label}`).join(", ")}], boostMode=${modeMapping.boostOperationMode ?? "none"}`
|
|
174214
174348
|
);
|
|
174215
174349
|
const minLimit = toMatterTemp2(attributes9.min_temp) ?? 0;
|
|
@@ -174483,7 +174617,7 @@ var matterDeviceTypeFactories = {
|
|
|
174483
174617
|
};
|
|
174484
174618
|
|
|
174485
174619
|
// src/matter/endpoints/composed/user-composed-endpoint.ts
|
|
174486
|
-
var
|
|
174620
|
+
var logger247 = Logger.get("UserComposedEndpoint");
|
|
174487
174621
|
function stripBasicInformation(type) {
|
|
174488
174622
|
const behaviors = { ...type.behaviors };
|
|
174489
174623
|
delete behaviors.bridgedDeviceBasicInformation;
|
|
@@ -174559,7 +174693,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
174559
174693
|
{ vacuumOnOff: registry3.isVacuumOnOffEnabled() }
|
|
174560
174694
|
);
|
|
174561
174695
|
if (!primaryType) {
|
|
174562
|
-
|
|
174696
|
+
logger247.warn(
|
|
174563
174697
|
`Cannot create endpoint type for primary entity ${primaryEntityId}`
|
|
174564
174698
|
);
|
|
174565
174699
|
return void 0;
|
|
@@ -174574,7 +174708,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
174574
174708
|
if (!sub.entityId) continue;
|
|
174575
174709
|
const subPayload = buildEntityPayload4(registry3, sub.entityId);
|
|
174576
174710
|
if (!subPayload) {
|
|
174577
|
-
|
|
174711
|
+
logger247.warn(
|
|
174578
174712
|
`Cannot find state for composed sub-entity ${sub.entityId}, it does not exist in Home Assistant (removed or renamed?)`
|
|
174579
174713
|
);
|
|
174580
174714
|
continue;
|
|
@@ -174589,7 +174723,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
174589
174723
|
config8.areaName
|
|
174590
174724
|
);
|
|
174591
174725
|
if (!subType) {
|
|
174592
|
-
|
|
174726
|
+
logger247.warn(
|
|
174593
174727
|
`Cannot create endpoint type for composed sub-entity ${sub.entityId}`
|
|
174594
174728
|
);
|
|
174595
174729
|
continue;
|
|
@@ -174602,7 +174736,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
174602
174736
|
mappedIds.push(sub.entityId);
|
|
174603
174737
|
}
|
|
174604
174738
|
if (parts.length < 2) {
|
|
174605
|
-
|
|
174739
|
+
logger247.warn(
|
|
174606
174740
|
`User composed device ${primaryEntityId}: only ${parts.length} sub-endpoint(s), need at least 2 (primary + one sub-entity). Falling back to standalone.`
|
|
174607
174741
|
);
|
|
174608
174742
|
return void 0;
|
|
@@ -174626,7 +174760,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
174626
174760
|
const labels = parts.map(
|
|
174627
174761
|
(_, i) => i === 0 ? primaryEntityId.split(".")[0] : composedEntities[i - 1]?.entityId?.split(".")[0] ?? "?"
|
|
174628
174762
|
).join("+");
|
|
174629
|
-
|
|
174763
|
+
logger247.info(
|
|
174630
174764
|
`Created user composed device ${primaryEntityId}: ${parts.length} sub-endpoint(s) [${labels}]`
|
|
174631
174765
|
);
|
|
174632
174766
|
return endpoint;
|
|
@@ -174732,7 +174866,7 @@ function asStandaloneEndpointType(type) {
|
|
|
174732
174866
|
}
|
|
174733
174867
|
|
|
174734
174868
|
// src/matter/endpoints/legacy/legacy-endpoint.ts
|
|
174735
|
-
var
|
|
174869
|
+
var logger248 = Logger.get("LegacyEndpoint");
|
|
174736
174870
|
var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
174737
174871
|
constructor(type, entityId, customName, mappedEntityIds, throttleMs, endpointId, vacuumEffective) {
|
|
174738
174872
|
super(type, entityId, customName, mappedEntityIds, endpointId);
|
|
@@ -174748,25 +174882,25 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174748
174882
|
return;
|
|
174749
174883
|
}
|
|
174750
174884
|
if (registry3.isAutoBatteryMappingEnabled() && registry3.isBatteryEntityUsed(entityId)) {
|
|
174751
|
-
|
|
174885
|
+
logger248.debug(
|
|
174752
174886
|
`Skipping ${entityId} - already auto-assigned as battery to another device`
|
|
174753
174887
|
);
|
|
174754
174888
|
return;
|
|
174755
174889
|
}
|
|
174756
174890
|
if (registry3.isAutoHumidityMappingEnabled() && registry3.isHumidityEntityUsed(entityId)) {
|
|
174757
|
-
|
|
174891
|
+
logger248.debug(
|
|
174758
174892
|
`Skipping ${entityId} - already auto-assigned as humidity to a temperature sensor`
|
|
174759
174893
|
);
|
|
174760
174894
|
return;
|
|
174761
174895
|
}
|
|
174762
174896
|
if (registry3.isAutoPressureMappingEnabled() && registry3.isPressureEntityUsed(entityId)) {
|
|
174763
|
-
|
|
174897
|
+
logger248.debug(
|
|
174764
174898
|
`Skipping ${entityId} - already auto-assigned as pressure to a temperature sensor`
|
|
174765
174899
|
);
|
|
174766
174900
|
return;
|
|
174767
174901
|
}
|
|
174768
174902
|
if (registry3.isAutoComposedDevicesEnabled() && registry3.isComposedSubEntityUsed(entityId)) {
|
|
174769
|
-
|
|
174903
|
+
logger248.debug(
|
|
174770
174904
|
`Skipping ${entityId} - already consumed by a composed device`
|
|
174771
174905
|
);
|
|
174772
174906
|
return;
|
|
@@ -174786,7 +174920,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174786
174920
|
humidityEntity: humidityEntityId
|
|
174787
174921
|
};
|
|
174788
174922
|
registry3.markHumidityEntityUsed(humidityEntityId);
|
|
174789
|
-
|
|
174923
|
+
logger248.debug(
|
|
174790
174924
|
`Auto-assigned humidity ${humidityEntityId} to ${entityId}`
|
|
174791
174925
|
);
|
|
174792
174926
|
}
|
|
@@ -174805,7 +174939,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174805
174939
|
pressureEntity: pressureEntityId
|
|
174806
174940
|
};
|
|
174807
174941
|
registry3.markPressureEntityUsed(pressureEntityId);
|
|
174808
|
-
|
|
174942
|
+
logger248.debug(
|
|
174809
174943
|
`Auto-assigned pressure ${pressureEntityId} to ${entityId}`
|
|
174810
174944
|
);
|
|
174811
174945
|
}
|
|
@@ -174823,7 +174957,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174823
174957
|
batteryEntity: batteryEntityId
|
|
174824
174958
|
};
|
|
174825
174959
|
registry3.markBatteryEntityUsed(batteryEntityId);
|
|
174826
|
-
|
|
174960
|
+
logger248.debug(
|
|
174827
174961
|
`Auto-assigned battery ${batteryEntityId} to ${entityId}`
|
|
174828
174962
|
);
|
|
174829
174963
|
}
|
|
@@ -174840,7 +174974,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174840
174974
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174841
174975
|
faultEntity: faultEntityId
|
|
174842
174976
|
};
|
|
174843
|
-
|
|
174977
|
+
logger248.debug(`Auto-assigned fault ${faultEntityId} to ${entityId}`);
|
|
174844
174978
|
}
|
|
174845
174979
|
}
|
|
174846
174980
|
if (!mapping?.powerEntity) {
|
|
@@ -174856,7 +174990,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174856
174990
|
powerEntity: powerEntityId
|
|
174857
174991
|
};
|
|
174858
174992
|
registry3.markPowerEntityUsed(powerEntityId);
|
|
174859
|
-
|
|
174993
|
+
logger248.debug(`Auto-assigned power ${powerEntityId} to ${entityId}`);
|
|
174860
174994
|
}
|
|
174861
174995
|
}
|
|
174862
174996
|
}
|
|
@@ -174873,7 +175007,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174873
175007
|
energyEntity: energyEntityId
|
|
174874
175008
|
};
|
|
174875
175009
|
registry3.markEnergyEntityUsed(energyEntityId);
|
|
174876
|
-
|
|
175010
|
+
logger248.debug(
|
|
174877
175011
|
`Auto-assigned energy ${energyEntityId} to ${entityId}`
|
|
174878
175012
|
);
|
|
174879
175013
|
}
|
|
@@ -174889,7 +175023,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174889
175023
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174890
175024
|
cleaningModeEntity: vacuumEntities.cleaningModeEntity
|
|
174891
175025
|
};
|
|
174892
|
-
|
|
175026
|
+
logger248.info(
|
|
174893
175027
|
`Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity} to ${entityId}`
|
|
174894
175028
|
);
|
|
174895
175029
|
}
|
|
@@ -174899,7 +175033,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174899
175033
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174900
175034
|
suctionLevelEntity: vacuumEntities.suctionLevelEntity
|
|
174901
175035
|
};
|
|
174902
|
-
|
|
175036
|
+
logger248.info(
|
|
174903
175037
|
`Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity} to ${entityId}`
|
|
174904
175038
|
);
|
|
174905
175039
|
}
|
|
@@ -174909,7 +175043,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174909
175043
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174910
175044
|
mopIntensityEntity: vacuumEntities.mopIntensityEntity
|
|
174911
175045
|
};
|
|
174912
|
-
|
|
175046
|
+
logger248.info(
|
|
174913
175047
|
`Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity} to ${entityId}`
|
|
174914
175048
|
);
|
|
174915
175049
|
}
|
|
@@ -174919,7 +175053,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174919
175053
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174920
175054
|
currentRoomEntity: vacuumEntities.currentRoomEntity
|
|
174921
175055
|
};
|
|
174922
|
-
|
|
175056
|
+
logger248.info(
|
|
174923
175057
|
`Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity} to ${entityId}`
|
|
174924
175058
|
);
|
|
174925
175059
|
}
|
|
@@ -174934,7 +175068,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174934
175068
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
174935
175069
|
cleanAreaRooms
|
|
174936
175070
|
};
|
|
174937
|
-
|
|
175071
|
+
logger248.info(
|
|
174938
175072
|
`Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA for ${entityId}`
|
|
174939
175073
|
);
|
|
174940
175074
|
}
|
|
@@ -174955,7 +175089,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174955
175089
|
rooms: roomsObj
|
|
174956
175090
|
}
|
|
174957
175091
|
};
|
|
174958
|
-
|
|
175092
|
+
logger248.debug(
|
|
174959
175093
|
`Auto-detected ${valetudoRooms.length} Valetudo segments for ${entityId}`
|
|
174960
175094
|
);
|
|
174961
175095
|
} else {
|
|
@@ -174972,7 +175106,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174972
175106
|
rooms: roomsObj
|
|
174973
175107
|
}
|
|
174974
175108
|
};
|
|
174975
|
-
|
|
175109
|
+
logger248.debug(
|
|
174976
175110
|
`Auto-detected ${roborockRooms.length} Roborock rooms for ${entityId}`
|
|
174977
175111
|
);
|
|
174978
175112
|
}
|
|
@@ -174981,7 +175115,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
174981
175115
|
}
|
|
174982
175116
|
}
|
|
174983
175117
|
if (standalone && ((effectiveMapping?.composedEntities?.length ?? 0) > 0 || effectiveMapping?.climateExposeFan === true)) {
|
|
174984
|
-
|
|
175118
|
+
logger248.warn(
|
|
174985
175119
|
`Composed mappings are not supported in server mode, exposing ${entityId} as a flat standalone endpoint`
|
|
174986
175120
|
);
|
|
174987
175121
|
}
|
|
@@ -175000,7 +175134,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
175000
175134
|
if (composed) {
|
|
175001
175135
|
return composed;
|
|
175002
175136
|
}
|
|
175003
|
-
|
|
175137
|
+
logger248.warn(
|
|
175004
175138
|
`User composed device creation failed for ${entityId}, falling back to standalone`
|
|
175005
175139
|
);
|
|
175006
175140
|
}
|
|
@@ -175065,7 +175199,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
175065
175199
|
if (composed) {
|
|
175066
175200
|
return composed;
|
|
175067
175201
|
}
|
|
175068
|
-
|
|
175202
|
+
logger248.warn(
|
|
175069
175203
|
`Companion fan creation failed for ${entityId}, falling back to standalone`
|
|
175070
175204
|
);
|
|
175071
175205
|
}
|
|
@@ -175143,11 +175277,11 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
175143
175277
|
}
|
|
175144
175278
|
if (mappedChanged) {
|
|
175145
175279
|
this.pendingMappedChange = true;
|
|
175146
|
-
|
|
175280
|
+
logger248.debug(
|
|
175147
175281
|
`Mapped entity change detected for ${this.entityId}, forcing update`
|
|
175148
175282
|
);
|
|
175149
175283
|
}
|
|
175150
|
-
|
|
175284
|
+
logger248.debug(
|
|
175151
175285
|
`State update received for ${this.entityId}: state=${state.state}`
|
|
175152
175286
|
);
|
|
175153
175287
|
this.lastState = state;
|
|
@@ -175378,7 +175512,7 @@ init_esm3();
|
|
|
175378
175512
|
init_esm();
|
|
175379
175513
|
init_types2();
|
|
175380
175514
|
init_esm4();
|
|
175381
|
-
var
|
|
175515
|
+
var logger249 = Logger.get("CameraWebRtcRequestor");
|
|
175382
175516
|
var registry2 = /* @__PURE__ */ new Map();
|
|
175383
175517
|
var pendingDeliveries = /* @__PURE__ */ new Map();
|
|
175384
175518
|
var invokeTransport = defaultInvoke;
|
|
@@ -175412,19 +175546,19 @@ function deliverAnswerDeferred(sessionId, sdp, onGiveUp) {
|
|
|
175412
175546
|
return;
|
|
175413
175547
|
}
|
|
175414
175548
|
if (await sendAnswer(sessionId, sdp)) {
|
|
175415
|
-
|
|
175549
|
+
logger249.info(`answer delivered for session ${sessionId}`);
|
|
175416
175550
|
return;
|
|
175417
175551
|
}
|
|
175418
175552
|
}
|
|
175419
175553
|
if (registry2.get(sessionId) !== owner || pendingDeliveries.get(sessionId) !== timer) {
|
|
175420
175554
|
return;
|
|
175421
175555
|
}
|
|
175422
|
-
|
|
175556
|
+
logger249.info(
|
|
175423
175557
|
`answer delivery failed for session ${sessionId}, giving up`
|
|
175424
175558
|
);
|
|
175425
175559
|
await onGiveUp();
|
|
175426
175560
|
} catch (err) {
|
|
175427
|
-
|
|
175561
|
+
logger249.info(
|
|
175428
175562
|
`answer delivery for session ${sessionId} threw: ${errText(err)}`
|
|
175429
175563
|
);
|
|
175430
175564
|
} finally {
|
|
@@ -175449,11 +175583,11 @@ function sendAnswer(sessionId, sdp) {
|
|
|
175449
175583
|
async function invokeRequestor(sessionId, command, fields) {
|
|
175450
175584
|
const registration = registry2.get(sessionId);
|
|
175451
175585
|
if (!registration) {
|
|
175452
|
-
|
|
175586
|
+
logger249.info(`requestor ${command}: no session ${sessionId} registered`);
|
|
175453
175587
|
return false;
|
|
175454
175588
|
}
|
|
175455
175589
|
if (registration.session.isClosed) {
|
|
175456
|
-
|
|
175590
|
+
logger249.info(`requestor ${command}: session ${sessionId} already closed`);
|
|
175457
175591
|
return false;
|
|
175458
175592
|
}
|
|
175459
175593
|
const request = {
|
|
@@ -175465,7 +175599,7 @@ async function invokeRequestor(sessionId, command, fields) {
|
|
|
175465
175599
|
try {
|
|
175466
175600
|
return await invokeTransport({ registration, request });
|
|
175467
175601
|
} catch (err) {
|
|
175468
|
-
|
|
175602
|
+
logger249.info(
|
|
175469
175603
|
`requestor ${command} failed for session ${sessionId}: ${errText(err)}`
|
|
175470
175604
|
);
|
|
175471
175605
|
return false;
|
|
@@ -175500,7 +175634,7 @@ async function defaultInvoke({
|
|
|
175500
175634
|
for (const entry of chunk) {
|
|
175501
175635
|
if (entry.kind === "cmd-status") {
|
|
175502
175636
|
if (entry.status !== Status2.Success) {
|
|
175503
|
-
|
|
175637
|
+
logger249.info(
|
|
175504
175638
|
`requestor ${request.command} status ${entry.status} for session ${String(request.fields.webRtcSessionId)}`
|
|
175505
175639
|
);
|
|
175506
175640
|
return false;
|
|
@@ -175520,7 +175654,7 @@ function errText(err) {
|
|
|
175520
175654
|
}
|
|
175521
175655
|
|
|
175522
175656
|
// src/plugins/builtin/camera/webrtc-provider-server.ts
|
|
175523
|
-
var
|
|
175657
|
+
var logger250 = Logger.get("CameraWebRtc");
|
|
175524
175658
|
var nextGlobalSessionId = 0;
|
|
175525
175659
|
function mintSessionId() {
|
|
175526
175660
|
for (let i = 0; i <= 65534; i++) {
|
|
@@ -175534,14 +175668,14 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175534
175668
|
solicitOffer(request) {
|
|
175535
175669
|
const id = mintSessionId();
|
|
175536
175670
|
this.trackSession(id, request.streamUsage, request.originatingEndpointId);
|
|
175537
|
-
|
|
175671
|
+
logger250.info(
|
|
175538
175672
|
`solicitOffer session=${id} (${this.state.entityId}), deferred offer`
|
|
175539
175673
|
);
|
|
175540
175674
|
void this.state.bridge.startSession(id, this.state.entityId, {
|
|
175541
175675
|
iceServers: request.iceServers,
|
|
175542
175676
|
iceTransportPolicy: request.iceTransportPolicy
|
|
175543
175677
|
}).catch(
|
|
175544
|
-
(err) =>
|
|
175678
|
+
(err) => logger250.info(
|
|
175545
175679
|
`solicitOffer startSession failed for ${this.state.entityId}: ${errText2(err)}`
|
|
175546
175680
|
)
|
|
175547
175681
|
);
|
|
@@ -175549,7 +175683,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175549
175683
|
}
|
|
175550
175684
|
async provideOffer(request) {
|
|
175551
175685
|
const id = request.webRtcSessionId ?? mintSessionId();
|
|
175552
|
-
|
|
175686
|
+
logger250.info(
|
|
175553
175687
|
`provideOffer entry: entityId=${this.state.entityId} session=${id} (sdp ${request.sdp.length} chars)`
|
|
175554
175688
|
);
|
|
175555
175689
|
if (request.webRtcSessionId == null) {
|
|
@@ -175583,7 +175717,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175583
175717
|
);
|
|
175584
175718
|
} catch (err) {
|
|
175585
175719
|
const message = errText2(err);
|
|
175586
|
-
|
|
175720
|
+
logger250.info(
|
|
175587
175721
|
`provideOffer failed for ${this.state.entityId} session=${id}: ${message}`
|
|
175588
175722
|
);
|
|
175589
175723
|
unregisterRequestor(id);
|
|
@@ -175595,7 +175729,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175595
175729
|
StatusCode.Failure
|
|
175596
175730
|
);
|
|
175597
175731
|
}
|
|
175598
|
-
|
|
175732
|
+
logger250.info(
|
|
175599
175733
|
`provideOffer answer computed for ${this.state.entityId} session=${id} (${answerSdp.length} chars); delivering via requestor`
|
|
175600
175734
|
);
|
|
175601
175735
|
const bridge = this.state.bridge;
|
|
@@ -175614,7 +175748,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175614
175748
|
return { webRtcSessionId: id };
|
|
175615
175749
|
}
|
|
175616
175750
|
provideAnswer(request) {
|
|
175617
|
-
|
|
175751
|
+
logger250.info(
|
|
175618
175752
|
`provideAnswer session=${request.webRtcSessionId} (sdp ${request.sdp.length} chars, ${this.state.entityId})`
|
|
175619
175753
|
);
|
|
175620
175754
|
return this.state.bridge.acceptControllerAnswer(
|
|
@@ -175623,7 +175757,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175623
175757
|
);
|
|
175624
175758
|
}
|
|
175625
175759
|
async provideIceCandidates(request) {
|
|
175626
|
-
|
|
175760
|
+
logger250.info(
|
|
175627
175761
|
`provideIceCandidates session=${request.webRtcSessionId}: ${request.iceCandidates.length} candidate(s) (${this.state.entityId})`
|
|
175628
175762
|
);
|
|
175629
175763
|
for (const c of request.iceCandidates) {
|
|
@@ -175636,7 +175770,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
|
|
|
175636
175770
|
}
|
|
175637
175771
|
}
|
|
175638
175772
|
async endSession(request) {
|
|
175639
|
-
|
|
175773
|
+
logger250.info(
|
|
175640
175774
|
`endSession session=${request.webRtcSessionId} (${this.state.entityId})`
|
|
175641
175775
|
);
|
|
175642
175776
|
await this.state.bridge.endSession(request.webRtcSessionId);
|
|
@@ -175757,7 +175891,7 @@ import {
|
|
|
175757
175891
|
createLongLivedTokenAuth as createLongLivedTokenAuth2
|
|
175758
175892
|
} from "home-assistant-js-websocket";
|
|
175759
175893
|
import { RTCPeerConnection } from "werift";
|
|
175760
|
-
var
|
|
175894
|
+
var logger251 = Logger.get("CameraWebRtc");
|
|
175761
175895
|
var DEFAULT_HA_WEBRTC_TIMEOUT_MS = 15e3;
|
|
175762
175896
|
var haWebRtcTimeoutMs = DEFAULT_HA_WEBRTC_TIMEOUT_MS;
|
|
175763
175897
|
var WebRtcBridge = class {
|
|
@@ -175804,7 +175938,7 @@ var WebRtcBridge = class {
|
|
|
175804
175938
|
const haOffer = await haPeer.createOffer();
|
|
175805
175939
|
await haPeer.setLocalDescription(haOffer);
|
|
175806
175940
|
const haOfferSdp = this.localSdp(haPeer);
|
|
175807
|
-
|
|
175941
|
+
logger251.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
|
|
175808
175942
|
const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
|
|
175809
175943
|
entityId,
|
|
175810
175944
|
haOfferSdp,
|
|
@@ -175827,12 +175961,12 @@ var WebRtcBridge = class {
|
|
|
175827
175961
|
const controllerOffer = await controllerPeer.createOffer();
|
|
175828
175962
|
await controllerPeer.setLocalDescription(controllerOffer);
|
|
175829
175963
|
const sdp = this.localSdp(controllerPeer);
|
|
175830
|
-
|
|
175964
|
+
logger251.info(
|
|
175831
175965
|
`controller offer created for ${entityId} (${sdp.length} chars)`
|
|
175832
175966
|
);
|
|
175833
175967
|
return { sdp, iceCandidates };
|
|
175834
175968
|
} catch (err) {
|
|
175835
|
-
|
|
175969
|
+
logger251.info(`startSession failed for ${entityId}: ${errText3(err)}`);
|
|
175836
175970
|
await this.endSession(matterSessionId);
|
|
175837
175971
|
throw err;
|
|
175838
175972
|
}
|
|
@@ -175862,7 +175996,7 @@ var WebRtcBridge = class {
|
|
|
175862
175996
|
const haOffer = await haPeer.createOffer();
|
|
175863
175997
|
await haPeer.setLocalDescription(haOffer);
|
|
175864
175998
|
const haOfferSdp = this.localSdp(haPeer);
|
|
175865
|
-
|
|
175999
|
+
logger251.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
|
|
175866
176000
|
const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
|
|
175867
176001
|
entityId,
|
|
175868
176002
|
haOfferSdp,
|
|
@@ -175881,12 +176015,12 @@ var WebRtcBridge = class {
|
|
|
175881
176015
|
const controllerAnswer = await controllerPeer.createAnswer();
|
|
175882
176016
|
await controllerPeer.setLocalDescription(controllerAnswer);
|
|
175883
176017
|
const answerSdp = this.localSdp(controllerPeer);
|
|
175884
|
-
|
|
176018
|
+
logger251.info(
|
|
175885
176019
|
`controller answer created for ${entityId} (${answerSdp.length} chars)`
|
|
175886
176020
|
);
|
|
175887
176021
|
return answerSdp;
|
|
175888
176022
|
} catch (err) {
|
|
175889
|
-
|
|
176023
|
+
logger251.info(
|
|
175890
176024
|
`acceptControllerOffer failed for ${entityId}: ${errText3(err)}`
|
|
175891
176025
|
);
|
|
175892
176026
|
await this.endSession(matterSessionId);
|
|
@@ -175897,14 +176031,14 @@ var WebRtcBridge = class {
|
|
|
175897
176031
|
async acceptControllerAnswer(matterSessionId, sdp) {
|
|
175898
176032
|
const session = this.sessions.get(matterSessionId);
|
|
175899
176033
|
if (!session) return;
|
|
175900
|
-
|
|
176034
|
+
logger251.debug(`controller answer applied for ${session.entityId}`);
|
|
175901
176035
|
await session.controllerPeer.setRemoteDescription({ type: "answer", sdp });
|
|
175902
176036
|
}
|
|
175903
176037
|
/** Add a remote ICE candidate from the Matter controller. */
|
|
175904
176038
|
async addControllerIceCandidate(matterSessionId, candidate, sdpMid, sdpMLineIndex) {
|
|
175905
176039
|
const session = this.sessions.get(matterSessionId);
|
|
175906
176040
|
if (!session) return;
|
|
175907
|
-
|
|
176041
|
+
logger251.debug(
|
|
175908
176042
|
`controller ICE candidate for ${session.entityId}: ${candidate}`
|
|
175909
176043
|
);
|
|
175910
176044
|
await session.controllerPeer.addIceCandidate({
|
|
@@ -175918,12 +176052,12 @@ var WebRtcBridge = class {
|
|
|
175918
176052
|
async closeExistingPeers(matterSessionId) {
|
|
175919
176053
|
const prior = this.sessions.get(matterSessionId);
|
|
175920
176054
|
if (!prior) return;
|
|
175921
|
-
|
|
176055
|
+
logger251.info(
|
|
175922
176056
|
`replacing session ${matterSessionId} (${prior.entityId}), closing prior peers`
|
|
175923
176057
|
);
|
|
175924
176058
|
if (prior.haUnsubscribe) {
|
|
175925
176059
|
await Promise.resolve(prior.haUnsubscribe()).catch(
|
|
175926
|
-
(err) =>
|
|
176060
|
+
(err) => logger251.debug(`HA unsubscribe failed: ${errText3(err)}`)
|
|
175927
176061
|
);
|
|
175928
176062
|
}
|
|
175929
176063
|
await prior.haPeer.close().catch(() => {
|
|
@@ -175936,11 +176070,11 @@ var WebRtcBridge = class {
|
|
|
175936
176070
|
async endSession(matterSessionId) {
|
|
175937
176071
|
const session = this.sessions.get(matterSessionId);
|
|
175938
176072
|
if (!session) return;
|
|
175939
|
-
|
|
176073
|
+
logger251.info(`ending session ${matterSessionId} (${session.entityId})`);
|
|
175940
176074
|
this.sessions.delete(matterSessionId);
|
|
175941
176075
|
if (session.haUnsubscribe) {
|
|
175942
176076
|
await Promise.resolve(session.haUnsubscribe()).catch(
|
|
175943
|
-
(err) =>
|
|
176077
|
+
(err) => logger251.debug(`HA unsubscribe failed: ${errText3(err)}`)
|
|
175944
176078
|
);
|
|
175945
176079
|
}
|
|
175946
176080
|
await session.haPeer.close().catch(() => {
|
|
@@ -175970,11 +176104,11 @@ var WebRtcBridge = class {
|
|
|
175970
176104
|
headers: { Authorization: `Bearer ${this.config.haToken}` }
|
|
175971
176105
|
});
|
|
175972
176106
|
} catch (err) {
|
|
175973
|
-
|
|
176107
|
+
logger251.info(`snapshot fetch failed for ${entityId}: ${errText3(err)}`);
|
|
175974
176108
|
throw err;
|
|
175975
176109
|
}
|
|
175976
176110
|
if (!res.ok) {
|
|
175977
|
-
|
|
176111
|
+
logger251.info(
|
|
175978
176112
|
`snapshot fetch failed for ${entityId}: camera_proxy ${res.status}`
|
|
175979
176113
|
);
|
|
175980
176114
|
throw new Error(`HA camera_proxy ${entityId}: ${res.status}`);
|
|
@@ -175991,10 +176125,10 @@ var WebRtcBridge = class {
|
|
|
175991
176125
|
// Forward every track HA sends into the matching pre-added controller sender.
|
|
175992
176126
|
forwardHaTracks(haPeer, senders, entityId) {
|
|
175993
176127
|
haPeer.onTrack.subscribe((track) => {
|
|
175994
|
-
|
|
176128
|
+
logger251.info(`onTrack ${track.kind} from HA (${entityId})`);
|
|
175995
176129
|
const transceiver = senders.get(track.kind);
|
|
175996
176130
|
if (!transceiver) {
|
|
175997
|
-
|
|
176131
|
+
logger251.info(
|
|
175998
176132
|
`no controller transceiver for ${track.kind} (${entityId})`
|
|
175999
176133
|
);
|
|
176000
176134
|
return;
|
|
@@ -176003,7 +176137,7 @@ var WebRtcBridge = class {
|
|
|
176003
176137
|
track.onReceiveRtp.subscribe((rtp) => {
|
|
176004
176138
|
if (!firstLogged) {
|
|
176005
176139
|
firstLogged = true;
|
|
176006
|
-
|
|
176140
|
+
logger251.info(`first RTP forwarded for ${track.kind} (${entityId})`);
|
|
176007
176141
|
}
|
|
176008
176142
|
transceiver.sender.sendRtp(rtp);
|
|
176009
176143
|
});
|
|
@@ -176012,10 +176146,10 @@ var WebRtcBridge = class {
|
|
|
176012
176146
|
// Log connection/ice state transitions (these events fire on change only).
|
|
176013
176147
|
wireStateLogging(peer, label, entityId) {
|
|
176014
176148
|
peer.connectionStateChange.subscribe(
|
|
176015
|
-
(s) =>
|
|
176149
|
+
(s) => logger251.info(`${label} connectionState=${s} (${entityId})`)
|
|
176016
176150
|
);
|
|
176017
176151
|
peer.iceConnectionStateChange.subscribe(
|
|
176018
|
-
(s) =>
|
|
176152
|
+
(s) => logger251.info(`${label} iceConnectionState=${s} (${entityId})`)
|
|
176019
176153
|
);
|
|
176020
176154
|
}
|
|
176021
176155
|
// Map the Matter ICE struct onto werift's config. Only the controller peer
|
|
@@ -176029,11 +176163,11 @@ var WebRtcBridge = class {
|
|
|
176029
176163
|
}))
|
|
176030
176164
|
);
|
|
176031
176165
|
if (iceServers.length === 0) {
|
|
176032
|
-
|
|
176166
|
+
logger251.info(`controller peer using default ICE servers (${entityId})`);
|
|
176033
176167
|
return void 0;
|
|
176034
176168
|
}
|
|
176035
176169
|
const policy = ice?.iceTransportPolicy === "relay" || ice?.iceTransportPolicy === "all" ? ice.iceTransportPolicy : void 0;
|
|
176036
|
-
|
|
176170
|
+
logger251.info(
|
|
176037
176171
|
`controller peer using ${iceServers.length} controller ICE server(s)${policy ? ` policy=${policy}` : ""} (${entityId})`
|
|
176038
176172
|
);
|
|
176039
176173
|
return policy ? { iceServers, iceTransportPolicy: policy } : { iceServers };
|
|
@@ -176047,13 +176181,13 @@ var WebRtcBridge = class {
|
|
|
176047
176181
|
feedHaCandidate(entityId, haPeer, candidate) {
|
|
176048
176182
|
const value = candidate?.candidate;
|
|
176049
176183
|
if (!value) return;
|
|
176050
|
-
|
|
176184
|
+
logger251.debug(`HA ICE candidate for ${entityId}: ${value}`);
|
|
176051
176185
|
void haPeer.addIceCandidate({
|
|
176052
176186
|
candidate: value,
|
|
176053
176187
|
sdpMid: candidate?.sdpMid ?? void 0,
|
|
176054
176188
|
sdpMLineIndex: candidate?.sdpMLineIndex ?? void 0
|
|
176055
176189
|
}).catch(
|
|
176056
|
-
(e) =>
|
|
176190
|
+
(e) => logger251.debug(
|
|
176057
176191
|
`HA addIceCandidate failed for ${entityId}: ${errText3(e)}`
|
|
176058
176192
|
)
|
|
176059
176193
|
);
|
|
@@ -176082,7 +176216,7 @@ var WebRtcBridge = class {
|
|
|
176082
176216
|
reject(err);
|
|
176083
176217
|
});
|
|
176084
176218
|
timer = setTimeout(() => {
|
|
176085
|
-
|
|
176219
|
+
logger251.info(
|
|
176086
176220
|
`HA WebRTC timed out after ${haWebRtcTimeoutMs}ms for ${entityId}`
|
|
176087
176221
|
);
|
|
176088
176222
|
fail(
|
|
@@ -176100,7 +176234,7 @@ var WebRtcBridge = class {
|
|
|
176100
176234
|
if (msg.session_id) sessionId = msg.session_id;
|
|
176101
176235
|
const ans = msg.answer;
|
|
176102
176236
|
settle(() => {
|
|
176103
|
-
|
|
176237
|
+
logger251.info(
|
|
176104
176238
|
`HA answer received for ${entityId} (${ans.length} chars)`
|
|
176105
176239
|
);
|
|
176106
176240
|
resolve11(ans);
|
|
@@ -176109,7 +176243,7 @@ var WebRtcBridge = class {
|
|
|
176109
176243
|
break;
|
|
176110
176244
|
case "error": {
|
|
176111
176245
|
const detail = msg.message ?? msg.code ?? "unknown error";
|
|
176112
|
-
|
|
176246
|
+
logger251.info(`HA WebRTC error for ${entityId}: ${detail}`);
|
|
176113
176247
|
fail(new Error(`HA WebRTC error: ${detail}`));
|
|
176114
176248
|
break;
|
|
176115
176249
|
}
|
|
@@ -177266,7 +177400,7 @@ import {
|
|
|
177266
177400
|
getCollection
|
|
177267
177401
|
} from "home-assistant-js-websocket";
|
|
177268
177402
|
import { atLeastHaVersion } from "home-assistant-js-websocket/dist/util.js";
|
|
177269
|
-
var
|
|
177403
|
+
var logger252 = Logger.get("SubscribeEntities");
|
|
177270
177404
|
function processEvent(store, updates) {
|
|
177271
177405
|
const state = { ...store.state };
|
|
177272
177406
|
if (updates.a) {
|
|
@@ -177292,7 +177426,7 @@ function processEvent(store, updates) {
|
|
|
177292
177426
|
for (const entityId in updates.c) {
|
|
177293
177427
|
let entityState = state[entityId];
|
|
177294
177428
|
if (!entityState) {
|
|
177295
|
-
|
|
177429
|
+
logger252.warn("Received state update for unknown entity", entityId);
|
|
177296
177430
|
continue;
|
|
177297
177431
|
}
|
|
177298
177432
|
entityState = { ...entityState };
|
|
@@ -178179,138 +178313,130 @@ function hashAreaId(areaId) {
|
|
|
178179
178313
|
return Math.abs(hash2);
|
|
178180
178314
|
}
|
|
178181
178315
|
|
|
178182
|
-
// src/services/bridges/entity-
|
|
178183
|
-
|
|
178184
|
-
|
|
178185
|
-
|
|
178186
|
-
|
|
178187
|
-
|
|
178188
|
-
isolationCallbacks = /* @__PURE__ */ new Map();
|
|
178189
|
-
/**
|
|
178190
|
-
* Register a callback to be called when an entity needs to be isolated.
|
|
178191
|
-
* The callback should remove the entity from the bridge's aggregator.
|
|
178192
|
-
*/
|
|
178193
|
-
registerIsolationCallback(bridgeId, callback) {
|
|
178194
|
-
this.isolationCallbacks.set(bridgeId, callback);
|
|
178316
|
+
// src/services/bridges/entity-mapping-sync.ts
|
|
178317
|
+
var EntityMappingSync = class {
|
|
178318
|
+
constructor(registry3, getMapping, log) {
|
|
178319
|
+
this.registry = registry3;
|
|
178320
|
+
this.getMapping = getMapping;
|
|
178321
|
+
this.log = log;
|
|
178195
178322
|
}
|
|
178196
|
-
|
|
178197
|
-
|
|
178323
|
+
registry;
|
|
178324
|
+
getMapping;
|
|
178325
|
+
log;
|
|
178326
|
+
retryScheduled = false;
|
|
178327
|
+
retryTimer = null;
|
|
178328
|
+
// deviceId -> primary entityId of endpoints that auto-map but carry no
|
|
178329
|
+
// battery, bounds the per-state-batch check to a map hit
|
|
178330
|
+
candidates = /* @__PURE__ */ new Map();
|
|
178331
|
+
// Only endpoints the auto-mapping applies to belong in the candidates: a
|
|
178332
|
+
// manual or disabled mapping, or a sensor endpoint sharing the device,
|
|
178333
|
+
// must not claim the slot (last writer would win) and stall the recovery.
|
|
178334
|
+
eligible(entityId) {
|
|
178335
|
+
const mapping = this.getMapping(entityId);
|
|
178336
|
+
if (mapping?.batteryEntity || mapping?.disableBatteryMapping) return false;
|
|
178337
|
+
if (entityId.startsWith("sensor.") || entityId.startsWith("binary_sensor.")) {
|
|
178338
|
+
return false;
|
|
178339
|
+
}
|
|
178340
|
+
return entityId.startsWith("vacuum.") || !!this.registry.isAutoBatteryMappingEnabled?.();
|
|
178198
178341
|
}
|
|
178199
|
-
|
|
178200
|
-
|
|
178201
|
-
|
|
178202
|
-
|
|
178203
|
-
|
|
178204
|
-
|
|
178205
|
-
const match = errorMessage.match(/([a-f0-9]{32})\.aggregator\.([^.\s>]+)/i);
|
|
178206
|
-
if (match) {
|
|
178207
|
-
return {
|
|
178208
|
-
bridgeId: match[1],
|
|
178209
|
-
entityName: match[2]
|
|
178210
|
-
};
|
|
178211
|
-
}
|
|
178212
|
-
return null;
|
|
178342
|
+
// the auto-resolved battery is part of the endpoint shape, so a sensor
|
|
178343
|
+
// that appears later must change the fingerprint and rebuild. JSON tuple
|
|
178344
|
+
// so mapping text can never collide with a battery marker.
|
|
178345
|
+
computeFingerprint(mapping, entityId) {
|
|
178346
|
+
const battery = entityId ? this.registry.batteryFingerprintFor(entityId, mapping) : "";
|
|
178347
|
+
return JSON.stringify([mapping ?? null, battery || null]);
|
|
178213
178348
|
}
|
|
178214
|
-
|
|
178215
|
-
|
|
178216
|
-
|
|
178217
|
-
|
|
178218
|
-
|
|
178219
|
-
|
|
178220
|
-
|
|
178221
|
-
|
|
178222
|
-
|
|
178223
|
-
|
|
178224
|
-
if (
|
|
178225
|
-
|
|
178226
|
-
|
|
178227
|
-
|
|
178228
|
-
|
|
178229
|
-
|
|
178230
|
-
|
|
178231
|
-
|
|
178232
|
-
|
|
178233
|
-
|
|
178234
|
-
|
|
178235
|
-
|
|
178236
|
-
|
|
178237
|
-
|
|
178349
|
+
// Live fingerprint for reconcile compares: when the resolver finds nothing
|
|
178350
|
+
// right now but the stored fingerprint maps a sensor that still exists on
|
|
178351
|
+
// the SAME device, keep it. An unavailable snapshot (HA restart) must not
|
|
178352
|
+
// strip the mapping and rebuild the endpoint battery-less.
|
|
178353
|
+
compareFingerprint(mapping, entityId, storedFingerprint) {
|
|
178354
|
+
const fingerprint = this.computeFingerprint(mapping, entityId);
|
|
178355
|
+
if (fingerprintBattery(fingerprint) != null || !storedFingerprint)
|
|
178356
|
+
return fingerprint;
|
|
178357
|
+
if (!this.eligible(entityId)) return fingerprint;
|
|
178358
|
+
const battery = fingerprintBattery(storedFingerprint);
|
|
178359
|
+
if (!battery) return fingerprint;
|
|
178360
|
+
const deviceId = this.registry.entity(entityId)?.device_id;
|
|
178361
|
+
const stillSameDevice = !!deviceId && this.registry.fullEntities[battery]?.device_id === deviceId;
|
|
178362
|
+
return stillSameDevice ? JSON.stringify([mapping ?? null, battery]) : fingerprint;
|
|
178363
|
+
}
|
|
178364
|
+
// The stored fingerprint must reflect what the endpoint actually maps: a
|
|
178365
|
+
// battery resolved while it was built without one (sensor outage during a
|
|
178366
|
+
// forced rebuild) would otherwise never trigger the catch-up.
|
|
178367
|
+
fingerprintAsBuilt(mapping, entityId, mappedEntityIds) {
|
|
178368
|
+
const fingerprint = this.computeFingerprint(mapping, entityId);
|
|
178369
|
+
const battery = fingerprintBattery(fingerprint);
|
|
178370
|
+
if (battery == null) return fingerprint;
|
|
178371
|
+
return (mappedEntityIds ?? []).includes(battery) ? fingerprint : JSON.stringify([mapping ?? null, null]);
|
|
178372
|
+
}
|
|
178373
|
+
rebuildCandidates(entries) {
|
|
178374
|
+
this.candidates.clear();
|
|
178375
|
+
for (const [entityId, fingerprint] of entries) {
|
|
178376
|
+
if (fingerprintBattery(fingerprint) != null) continue;
|
|
178377
|
+
if (!this.eligible(entityId)) continue;
|
|
178378
|
+
const deviceId = this.registry.entity(entityId)?.device_id;
|
|
178379
|
+
if (deviceId) this.candidates.set(deviceId, entityId);
|
|
178238
178380
|
}
|
|
178239
|
-
return null;
|
|
178240
178381
|
}
|
|
178241
|
-
|
|
178242
|
-
|
|
178243
|
-
|
|
178244
|
-
|
|
178245
|
-
|
|
178246
|
-
const
|
|
178247
|
-
|
|
178248
|
-
|
|
178249
|
-
|
|
178382
|
+
// battery-less auto-map endpoints watch their device's sensors, an
|
|
178383
|
+
// unresolved battery is not mapped so it would never arrive otherwise
|
|
178384
|
+
candidateSensorIds() {
|
|
178385
|
+
if (this.candidates.size === 0) return [];
|
|
178386
|
+
const ids = [];
|
|
178387
|
+
for (const entity of Object.values(this.registry.fullEntities)) {
|
|
178388
|
+
if (!entity.device_id) continue;
|
|
178389
|
+
if (!this.candidates.has(entity.device_id)) continue;
|
|
178390
|
+
if (entity.entity_id.startsWith("sensor.") || entity.entity_id.startsWith("binary_sensor.")) {
|
|
178391
|
+
ids.push(entity.entity_id);
|
|
178392
|
+
}
|
|
178250
178393
|
}
|
|
178251
|
-
|
|
178252
|
-
|
|
178253
|
-
|
|
178254
|
-
|
|
178394
|
+
return ids;
|
|
178395
|
+
}
|
|
178396
|
+
// An endpoint built while its battery sensor was unavailable stays
|
|
178397
|
+
// battery-less, because registry ticks only refresh on structural changes.
|
|
178398
|
+
// When a same-device sensor state arrives, re-resolve and rebuild once.
|
|
178399
|
+
maybeRetry(states, changed, observing, refresh) {
|
|
178400
|
+
if (!observing || this.retryScheduled || this.candidates.size === 0) {
|
|
178401
|
+
return;
|
|
178255
178402
|
}
|
|
178256
|
-
const
|
|
178257
|
-
|
|
178258
|
-
|
|
178259
|
-
|
|
178260
|
-
|
|
178403
|
+
for (const id of changed ?? Object.keys(states)) {
|
|
178404
|
+
if (!id.startsWith("sensor.") && !id.startsWith("binary_sensor."))
|
|
178405
|
+
continue;
|
|
178406
|
+
const deviceId = this.registry.fullEntities[id]?.device_id;
|
|
178407
|
+
if (!deviceId) continue;
|
|
178408
|
+
const entityId = this.candidates.get(deviceId);
|
|
178409
|
+
if (!entityId) continue;
|
|
178410
|
+
this.registry.forgetBatteryCacheForDevice(deviceId);
|
|
178411
|
+
const resolved = this.registry.batteryFingerprintFor(
|
|
178412
|
+
entityId,
|
|
178413
|
+
this.getMapping(entityId)
|
|
178261
178414
|
);
|
|
178262
|
-
|
|
178263
|
-
|
|
178264
|
-
|
|
178265
|
-
|
|
178266
|
-
|
|
178267
|
-
|
|
178268
|
-
|
|
178269
|
-
|
|
178270
|
-
|
|
178271
|
-
|
|
178272
|
-
|
|
178273
|
-
|
|
178274
|
-
logger252.warn(
|
|
178275
|
-
`Isolating entity "${entityName}" from bridge ${bridgeId} due to: ${reason}`
|
|
178276
|
-
);
|
|
178277
|
-
diagnosticEventBus.emit("entity_error", `Entity isolated: ${entityName}`, {
|
|
178278
|
-
bridgeId,
|
|
178279
|
-
entityId: entityName,
|
|
178280
|
-
details: { reason: classification }
|
|
178281
|
-
});
|
|
178282
|
-
try {
|
|
178283
|
-
await callback(entityName);
|
|
178284
|
-
return true;
|
|
178285
|
-
} catch (e) {
|
|
178286
|
-
logger252.error(`Failed to isolate entity ${entityName}:`, e);
|
|
178287
|
-
return false;
|
|
178415
|
+
if (!resolved) continue;
|
|
178416
|
+
this.retryScheduled = true;
|
|
178417
|
+
this.log.info(
|
|
178418
|
+
`Battery sensor ${resolved} appeared for ${entityId}, rebuilding`
|
|
178419
|
+
);
|
|
178420
|
+
this.retryTimer = setTimeout(() => {
|
|
178421
|
+
this.retryTimer = null;
|
|
178422
|
+
refresh().catch((e) => this.log.warn("Battery retry refresh failed:", e)).finally(() => {
|
|
178423
|
+
this.retryScheduled = false;
|
|
178424
|
+
});
|
|
178425
|
+
}, 0);
|
|
178426
|
+
return;
|
|
178288
178427
|
}
|
|
178289
178428
|
}
|
|
178290
|
-
|
|
178291
|
-
|
|
178292
|
-
|
|
178293
|
-
|
|
178294
|
-
const result = [];
|
|
178295
|
-
for (const [key, entity] of this.isolatedEntities) {
|
|
178296
|
-
if (key.startsWith(`${bridgeId}:`)) {
|
|
178297
|
-
result.push(entity);
|
|
178298
|
-
}
|
|
178429
|
+
cancelRetry() {
|
|
178430
|
+
if (this.retryTimer) {
|
|
178431
|
+
clearTimeout(this.retryTimer);
|
|
178432
|
+
this.retryTimer = null;
|
|
178299
178433
|
}
|
|
178300
|
-
|
|
178434
|
+
this.retryScheduled = false;
|
|
178301
178435
|
}
|
|
178302
|
-
|
|
178303
|
-
|
|
178304
|
-
*/
|
|
178305
|
-
clearIsolatedEntities(bridgeId) {
|
|
178306
|
-
for (const key of this.isolatedEntities.keys()) {
|
|
178307
|
-
if (key.startsWith(`${bridgeId}:`)) {
|
|
178308
|
-
this.isolatedEntities.delete(key);
|
|
178309
|
-
}
|
|
178310
|
-
}
|
|
178436
|
+
get retryPending() {
|
|
178437
|
+
return this.retryScheduled;
|
|
178311
178438
|
}
|
|
178312
178439
|
};
|
|
178313
|
-
var EntityIsolationService = new EntityIsolationServiceImpl();
|
|
178314
178440
|
|
|
178315
178441
|
// src/services/bridges/bridge-endpoint-manager.ts
|
|
178316
178442
|
var MAX_ENTITY_ID_LENGTH = 150;
|
|
@@ -178338,6 +178464,11 @@ var BridgeEndpointManager = class extends Service {
|
|
|
178338
178464
|
identityStorage,
|
|
178339
178465
|
mappingStorage
|
|
178340
178466
|
);
|
|
178467
|
+
this.mappingSync = new EntityMappingSync(
|
|
178468
|
+
registry3,
|
|
178469
|
+
(entityId) => this.getEntityMapping(entityId),
|
|
178470
|
+
log
|
|
178471
|
+
);
|
|
178341
178472
|
EntityIsolationService.registerIsolationCallback(
|
|
178342
178473
|
bridgeId,
|
|
178343
178474
|
this.isolateEntity.bind(this)
|
|
@@ -178361,6 +178492,7 @@ var BridgeEndpointManager = class extends Service {
|
|
|
178361
178492
|
observingRequested = false;
|
|
178362
178493
|
_failedEntities = [];
|
|
178363
178494
|
mappingFingerprints = /* @__PURE__ */ new Map();
|
|
178495
|
+
mappingSync;
|
|
178364
178496
|
// entityId -> first absence stamp (grace window)
|
|
178365
178497
|
pendingRemovals = /* @__PURE__ */ new Map();
|
|
178366
178498
|
removalRecheckTimer = null;
|
|
@@ -178698,95 +178830,6 @@ var BridgeEndpointManager = class extends Service {
|
|
|
178698
178830
|
getEntityMapping(entityId) {
|
|
178699
178831
|
return this.mappingStorage.getMapping(this.bridgeId, entityId);
|
|
178700
178832
|
}
|
|
178701
|
-
// #450: an endpoint built while its battery sensor was unavailable stays
|
|
178702
|
-
// battery-less, because registry ticks only refresh on structural changes.
|
|
178703
|
-
// When a same-device sensor state arrives, re-resolve and rebuild.
|
|
178704
|
-
batteryRetryScheduled = false;
|
|
178705
|
-
batteryRetryTimer = null;
|
|
178706
|
-
// deviceId -> primary entityId of endpoints that auto-map but carry no
|
|
178707
|
-
// battery, bounds the per-state-batch check to a map hit
|
|
178708
|
-
batteryRetryCandidates = /* @__PURE__ */ new Map();
|
|
178709
|
-
// Only endpoints the auto-mapping applies to belong here: a manual or
|
|
178710
|
-
// disabled mapping, or a sensor endpoint sharing the device, must not
|
|
178711
|
-
// claim the slot (last writer would win) and stall the recovery.
|
|
178712
|
-
batteryRetryEligible(entityId) {
|
|
178713
|
-
const mapping = this.getEntityMapping(entityId);
|
|
178714
|
-
if (mapping?.batteryEntity || mapping?.disableBatteryMapping) return false;
|
|
178715
|
-
if (entityId.startsWith("sensor.") || entityId.startsWith("binary_sensor.")) {
|
|
178716
|
-
return false;
|
|
178717
|
-
}
|
|
178718
|
-
return entityId.startsWith("vacuum.") || !!this.registry.isAutoBatteryMappingEnabled?.();
|
|
178719
|
-
}
|
|
178720
|
-
rebuildBatteryRetryCandidates() {
|
|
178721
|
-
this.batteryRetryCandidates.clear();
|
|
178722
|
-
for (const part of this.root.parts) {
|
|
178723
|
-
if (!hasEntityIdentity(part)) continue;
|
|
178724
|
-
const fingerprint = this.mappingFingerprints.get(part.entityId);
|
|
178725
|
-
if (fingerprint === void 0) continue;
|
|
178726
|
-
if (fingerprintBattery(fingerprint) != null) continue;
|
|
178727
|
-
if (!this.batteryRetryEligible(part.entityId)) continue;
|
|
178728
|
-
const deviceId = this.registry.entity(part.entityId)?.device_id;
|
|
178729
|
-
if (deviceId) this.batteryRetryCandidates.set(deviceId, part.entityId);
|
|
178730
|
-
}
|
|
178731
|
-
}
|
|
178732
|
-
maybeRetryBatteryMapping(states, changed) {
|
|
178733
|
-
if (!this.observingRequested || this.batteryRetryScheduled || this.batteryRetryCandidates.size === 0) {
|
|
178734
|
-
return;
|
|
178735
|
-
}
|
|
178736
|
-
for (const id of changed ?? Object.keys(states)) {
|
|
178737
|
-
if (!id.startsWith("sensor.") && !id.startsWith("binary_sensor."))
|
|
178738
|
-
continue;
|
|
178739
|
-
const deviceId = this.registry.fullEntities[id]?.device_id;
|
|
178740
|
-
if (!deviceId) continue;
|
|
178741
|
-
const entityId = this.batteryRetryCandidates.get(deviceId);
|
|
178742
|
-
if (!entityId) continue;
|
|
178743
|
-
this.registry.forgetBatteryCacheForDevice(deviceId);
|
|
178744
|
-
const resolved = this.registry.batteryFingerprintFor(
|
|
178745
|
-
entityId,
|
|
178746
|
-
this.getEntityMapping(entityId)
|
|
178747
|
-
);
|
|
178748
|
-
if (!resolved) continue;
|
|
178749
|
-
this.batteryRetryScheduled = true;
|
|
178750
|
-
this.log.info(
|
|
178751
|
-
`Battery sensor ${resolved} appeared for ${entityId}, rebuilding`
|
|
178752
|
-
);
|
|
178753
|
-
this.batteryRetryTimer = setTimeout(() => {
|
|
178754
|
-
this.batteryRetryTimer = null;
|
|
178755
|
-
this.refreshDevices().catch((e) => this.log.warn("Battery retry refresh failed:", e)).finally(() => {
|
|
178756
|
-
this.batteryRetryScheduled = false;
|
|
178757
|
-
});
|
|
178758
|
-
}, 0);
|
|
178759
|
-
return;
|
|
178760
|
-
}
|
|
178761
|
-
}
|
|
178762
|
-
computeMappingFingerprint(mapping, entityId) {
|
|
178763
|
-
const battery = entityId ? this.registry.batteryFingerprintFor(entityId, mapping) : "";
|
|
178764
|
-
return JSON.stringify([mapping ?? null, battery || null]);
|
|
178765
|
-
}
|
|
178766
|
-
// Live fingerprint for reconcile compares: when the resolver finds nothing
|
|
178767
|
-
// right now but the stored fingerprint maps a sensor that still exists on
|
|
178768
|
-
// the SAME device, keep it. An unavailable snapshot (HA restart) must not
|
|
178769
|
-
// strip the mapping and rebuild the endpoint battery-less (#450).
|
|
178770
|
-
compareFingerprint(mapping, entityId, storedFingerprint) {
|
|
178771
|
-
const fingerprint = this.computeMappingFingerprint(mapping, entityId);
|
|
178772
|
-
if (fingerprintBattery(fingerprint) != null || !storedFingerprint)
|
|
178773
|
-
return fingerprint;
|
|
178774
|
-
if (!this.batteryRetryEligible(entityId)) return fingerprint;
|
|
178775
|
-
const battery = fingerprintBattery(storedFingerprint);
|
|
178776
|
-
if (!battery) return fingerprint;
|
|
178777
|
-
const deviceId = this.registry.entity(entityId)?.device_id;
|
|
178778
|
-
const stillSameDevice = !!deviceId && this.registry.fullEntities[battery]?.device_id === deviceId;
|
|
178779
|
-
return stillSameDevice ? JSON.stringify([mapping ?? null, battery]) : fingerprint;
|
|
178780
|
-
}
|
|
178781
|
-
// The stored fingerprint must reflect what this endpoint actually maps: a
|
|
178782
|
-
// battery resolved while the endpoint was built without one (sensor outage
|
|
178783
|
-
// during a forced rebuild) would otherwise never trigger the catch-up (#450).
|
|
178784
|
-
fingerprintAsBuilt(mapping, entityId, endpoint) {
|
|
178785
|
-
const fingerprint = this.computeMappingFingerprint(mapping, entityId);
|
|
178786
|
-
const battery = fingerprintBattery(fingerprint);
|
|
178787
|
-
if (battery == null) return fingerprint;
|
|
178788
|
-
return (endpoint.mappedEntityIds ?? []).includes(battery) ? fingerprint : JSON.stringify([mapping ?? null, null]);
|
|
178789
|
-
}
|
|
178790
178833
|
async dispose() {
|
|
178791
178834
|
this.stopObserving();
|
|
178792
178835
|
if (this.removalRecheckTimer) {
|
|
@@ -178829,14 +178872,8 @@ var BridgeEndpointManager = class extends Service {
|
|
|
178829
178872
|
}
|
|
178830
178873
|
}
|
|
178831
178874
|
}
|
|
178832
|
-
|
|
178833
|
-
|
|
178834
|
-
if (!entity.device_id) continue;
|
|
178835
|
-
if (!this.batteryRetryCandidates.has(entity.device_id)) continue;
|
|
178836
|
-
if (entity.entity_id.startsWith("sensor.") || entity.entity_id.startsWith("binary_sensor.")) {
|
|
178837
|
-
ids.add(entity.entity_id);
|
|
178838
|
-
}
|
|
178839
|
-
}
|
|
178875
|
+
for (const id of this.mappingSync.candidateSensorIds()) {
|
|
178876
|
+
ids.add(id);
|
|
178840
178877
|
}
|
|
178841
178878
|
return [...ids];
|
|
178842
178879
|
}
|
|
@@ -178852,11 +178889,7 @@ var BridgeEndpointManager = class extends Service {
|
|
|
178852
178889
|
clearTimeout(this.removalRecheckTimer);
|
|
178853
178890
|
this.removalRecheckTimer = null;
|
|
178854
178891
|
}
|
|
178855
|
-
|
|
178856
|
-
clearTimeout(this.batteryRetryTimer);
|
|
178857
|
-
this.batteryRetryTimer = null;
|
|
178858
|
-
}
|
|
178859
|
-
this.batteryRetryScheduled = false;
|
|
178892
|
+
this.mappingSync.cancelRetry();
|
|
178860
178893
|
}
|
|
178861
178894
|
async refreshDevices() {
|
|
178862
178895
|
this.registry.refresh();
|
|
@@ -179009,7 +179042,7 @@ var BridgeEndpointManager = class extends Service {
|
|
|
179009
179042
|
} else {
|
|
179010
179043
|
const currentMapping = this.getEntityMapping(endpoint.entityId);
|
|
179011
179044
|
const storedFp = this.mappingFingerprints.get(endpoint.entityId) ?? "";
|
|
179012
|
-
const currentFp = this.compareFingerprint(
|
|
179045
|
+
const currentFp = this.mappingSync.compareFingerprint(
|
|
179013
179046
|
currentMapping,
|
|
179014
179047
|
endpoint.entityId,
|
|
179015
179048
|
storedFp
|
|
@@ -179100,7 +179133,11 @@ var BridgeEndpointManager = class extends Service {
|
|
|
179100
179133
|
await this.root.add(endpoint);
|
|
179101
179134
|
this.mappingFingerprints.set(
|
|
179102
179135
|
entityId,
|
|
179103
|
-
this.fingerprintAsBuilt(
|
|
179136
|
+
this.mappingSync.fingerprintAsBuilt(
|
|
179137
|
+
mapping,
|
|
179138
|
+
entityId,
|
|
179139
|
+
endpoint.mappedEntityIds
|
|
179140
|
+
)
|
|
179104
179141
|
);
|
|
179105
179142
|
} catch (e) {
|
|
179106
179143
|
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
@@ -179114,7 +179151,12 @@ var BridgeEndpointManager = class extends Service {
|
|
|
179114
179151
|
}
|
|
179115
179152
|
}
|
|
179116
179153
|
await this.reconcileAreaSwitches();
|
|
179117
|
-
this.
|
|
179154
|
+
this.mappingSync.rebuildCandidates(
|
|
179155
|
+
[...this.root.parts].filter(hasEntityIdentity).flatMap((p) => {
|
|
179156
|
+
const fp = this.mappingFingerprints.get(p.entityId);
|
|
179157
|
+
return fp === void 0 ? [] : [[p.entityId, fp]];
|
|
179158
|
+
})
|
|
179159
|
+
);
|
|
179118
179160
|
if (this.observingRequested) {
|
|
179119
179161
|
this.startObserving();
|
|
179120
179162
|
}
|
|
@@ -179258,7 +179300,12 @@ var BridgeEndpointManager = class extends Service {
|
|
|
179258
179300
|
async runUpdateStates(states, changed) {
|
|
179259
179301
|
const startMs = performance.now();
|
|
179260
179302
|
this.registry.mergeExternalStates(states);
|
|
179261
|
-
this.
|
|
179303
|
+
this.mappingSync.maybeRetry(
|
|
179304
|
+
states,
|
|
179305
|
+
changed,
|
|
179306
|
+
this.observingRequested,
|
|
179307
|
+
() => this.refreshDevices()
|
|
179308
|
+
);
|
|
179262
179309
|
const allEndpoints = [...this.root.parts].filter(isEntityPart);
|
|
179263
179310
|
const endpoints = changed === null ? allEndpoints : allEndpoints.filter(
|
|
179264
179311
|
(e) => changed.has(e.entityId) || (e.mappedEntityIds ?? []).some((id) => changed.has(id))
|
|
@@ -180009,6 +180056,11 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180009
180056
|
identityStorage,
|
|
180010
180057
|
mappingStorage
|
|
180011
180058
|
);
|
|
180059
|
+
this.mappingSync = new EntityMappingSync(
|
|
180060
|
+
registry3,
|
|
180061
|
+
(entityId) => this.getEntityMapping(entityId),
|
|
180062
|
+
log
|
|
180063
|
+
);
|
|
180012
180064
|
}
|
|
180013
180065
|
serverNode;
|
|
180014
180066
|
client;
|
|
@@ -180022,6 +180074,7 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180022
180074
|
observingRequested = false;
|
|
180023
180075
|
_failedEntities = [];
|
|
180024
180076
|
endpoints = /* @__PURE__ */ new Map();
|
|
180077
|
+
mappingSync;
|
|
180025
180078
|
// Same grace as the aggregator manager: server mode deleted on the FIRST
|
|
180026
180079
|
// refresh an entity was absent, so one partial HA snapshot re-minted the
|
|
180027
180080
|
// device (#438).
|
|
@@ -180044,83 +180097,6 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180044
180097
|
getEntityMapping(entityId) {
|
|
180045
180098
|
return this.mappingStorage.getMapping(this.dataProvider.id, entityId);
|
|
180046
180099
|
}
|
|
180047
|
-
// #450: an endpoint built while its battery sensor was unavailable stays
|
|
180048
|
-
// battery-less, because registry ticks only refresh on structural changes.
|
|
180049
|
-
// When a same-device sensor state arrives, re-resolve and rebuild.
|
|
180050
|
-
batteryRetryScheduled = false;
|
|
180051
|
-
batteryRetryTimer = null;
|
|
180052
|
-
// deviceId -> primary entityId of endpoints that auto-map but carry no
|
|
180053
|
-
// battery, bounds the per-state-batch check to a map hit
|
|
180054
|
-
batteryRetryCandidates = /* @__PURE__ */ new Map();
|
|
180055
|
-
// Only endpoints the auto-mapping applies to belong here: a manual or
|
|
180056
|
-
// disabled mapping, or a sensor endpoint sharing the device, must not
|
|
180057
|
-
// claim the slot (last writer would win) and stall the recovery.
|
|
180058
|
-
batteryRetryEligible(entityId) {
|
|
180059
|
-
const mapping = this.getEntityMapping(entityId);
|
|
180060
|
-
if (mapping?.batteryEntity || mapping?.disableBatteryMapping) return false;
|
|
180061
|
-
if (entityId.startsWith("sensor.") || entityId.startsWith("binary_sensor.")) {
|
|
180062
|
-
return false;
|
|
180063
|
-
}
|
|
180064
|
-
return entityId.startsWith("vacuum.") || !!this.registry.isAutoBatteryMappingEnabled?.();
|
|
180065
|
-
}
|
|
180066
|
-
rebuildBatteryRetryCandidates() {
|
|
180067
|
-
this.batteryRetryCandidates.clear();
|
|
180068
|
-
for (const [entityId, entry] of this.endpoints) {
|
|
180069
|
-
if (fingerprintBattery(entry.fingerprint) != null) continue;
|
|
180070
|
-
if (!this.batteryRetryEligible(entityId)) continue;
|
|
180071
|
-
const deviceId = this.registry.entity(entityId)?.device_id;
|
|
180072
|
-
if (deviceId) this.batteryRetryCandidates.set(deviceId, entityId);
|
|
180073
|
-
}
|
|
180074
|
-
}
|
|
180075
|
-
maybeRetryBatteryMapping(states) {
|
|
180076
|
-
if (!this.observingRequested || this.batteryRetryScheduled || this.batteryRetryCandidates.size === 0) {
|
|
180077
|
-
return;
|
|
180078
|
-
}
|
|
180079
|
-
for (const id of Object.keys(states)) {
|
|
180080
|
-
if (!id.startsWith("sensor.") && !id.startsWith("binary_sensor."))
|
|
180081
|
-
continue;
|
|
180082
|
-
const deviceId = this.registry.fullEntities[id]?.device_id;
|
|
180083
|
-
if (!deviceId) continue;
|
|
180084
|
-
const entityId = this.batteryRetryCandidates.get(deviceId);
|
|
180085
|
-
if (!entityId) continue;
|
|
180086
|
-
this.registry.forgetBatteryCacheForDevice(deviceId);
|
|
180087
|
-
const resolved = this.registry.batteryFingerprintFor(
|
|
180088
|
-
entityId,
|
|
180089
|
-
this.getEntityMapping(entityId)
|
|
180090
|
-
);
|
|
180091
|
-
if (!resolved) continue;
|
|
180092
|
-
this.batteryRetryScheduled = true;
|
|
180093
|
-
this.log.info(
|
|
180094
|
-
`Battery sensor ${resolved} appeared for ${entityId}, rebuilding`
|
|
180095
|
-
);
|
|
180096
|
-
this.batteryRetryTimer = setTimeout(() => {
|
|
180097
|
-
this.batteryRetryTimer = null;
|
|
180098
|
-
this.refreshDevices().catch((e) => this.log.warn("Battery retry refresh failed:", e)).finally(() => {
|
|
180099
|
-
this.batteryRetryScheduled = false;
|
|
180100
|
-
});
|
|
180101
|
-
}, 0);
|
|
180102
|
-
return;
|
|
180103
|
-
}
|
|
180104
|
-
}
|
|
180105
|
-
computeMappingFingerprint(mapping, entityId) {
|
|
180106
|
-
const battery = entityId ? this.registry.batteryFingerprintFor(entityId, mapping) : "";
|
|
180107
|
-
return JSON.stringify([mapping ?? null, battery || null]);
|
|
180108
|
-
}
|
|
180109
|
-
// Live fingerprint for reconcile compares: when the resolver finds nothing
|
|
180110
|
-
// right now but the stored fingerprint maps a sensor that still exists on
|
|
180111
|
-
// the SAME device, keep it. An unavailable snapshot (HA restart) must not
|
|
180112
|
-
// strip the mapping and rebuild the endpoint battery-less (#450).
|
|
180113
|
-
compareFingerprint(mapping, entityId, storedFingerprint) {
|
|
180114
|
-
const fingerprint = this.computeMappingFingerprint(mapping, entityId);
|
|
180115
|
-
if (fingerprintBattery(fingerprint) != null || !storedFingerprint)
|
|
180116
|
-
return fingerprint;
|
|
180117
|
-
if (!this.batteryRetryEligible(entityId)) return fingerprint;
|
|
180118
|
-
const battery = fingerprintBattery(storedFingerprint);
|
|
180119
|
-
if (!battery) return fingerprint;
|
|
180120
|
-
const deviceId = this.registry.entity(entityId)?.device_id;
|
|
180121
|
-
const stillSameDevice = !!deviceId && this.registry.fullEntities[battery]?.device_id === deviceId;
|
|
180122
|
-
return stillSameDevice ? JSON.stringify([mapping ?? null, battery]) : fingerprint;
|
|
180123
|
-
}
|
|
180124
180100
|
async dispose() {
|
|
180125
180101
|
this.stopObserving();
|
|
180126
180102
|
if (this.removalRecheckTimer) {
|
|
@@ -180160,14 +180136,8 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180160
180136
|
ids.add(mappedId);
|
|
180161
180137
|
}
|
|
180162
180138
|
}
|
|
180163
|
-
|
|
180164
|
-
|
|
180165
|
-
if (!entity.device_id) continue;
|
|
180166
|
-
if (!this.batteryRetryCandidates.has(entity.device_id)) continue;
|
|
180167
|
-
if (entity.entity_id.startsWith("sensor.") || entity.entity_id.startsWith("binary_sensor.")) {
|
|
180168
|
-
ids.add(entity.entity_id);
|
|
180169
|
-
}
|
|
180170
|
-
}
|
|
180139
|
+
for (const id of this.mappingSync.candidateSensorIds()) {
|
|
180140
|
+
ids.add(id);
|
|
180171
180141
|
}
|
|
180172
180142
|
return [...ids];
|
|
180173
180143
|
}
|
|
@@ -180183,11 +180153,7 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180183
180153
|
clearTimeout(this.removalRecheckTimer);
|
|
180184
180154
|
this.removalRecheckTimer = null;
|
|
180185
180155
|
}
|
|
180186
|
-
|
|
180187
|
-
clearTimeout(this.batteryRetryTimer);
|
|
180188
|
-
this.batteryRetryTimer = null;
|
|
180189
|
-
}
|
|
180190
|
-
this.batteryRetryScheduled = false;
|
|
180156
|
+
this.mappingSync.cancelRetry();
|
|
180191
180157
|
}
|
|
180192
180158
|
/** Primary first (the entity the first include matcher tests true for). */
|
|
180193
180159
|
orderEntityIds(ids) {
|
|
@@ -180382,9 +180348,12 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180382
180348
|
});
|
|
180383
180349
|
continue;
|
|
180384
180350
|
}
|
|
180385
|
-
const fingerprint = this.computeMappingFingerprint(mapping, entityId);
|
|
180386
180351
|
const existing = this.endpoints.get(entityId);
|
|
180387
|
-
if (existing && existing.fingerprint === this.compareFingerprint(
|
|
180352
|
+
if (existing && existing.fingerprint === this.mappingSync.compareFingerprint(
|
|
180353
|
+
mapping,
|
|
180354
|
+
entityId,
|
|
180355
|
+
existing.fingerprint
|
|
180356
|
+
)) {
|
|
180388
180357
|
this.log.debug(`Device endpoint already exists for ${entityId}`);
|
|
180389
180358
|
continue;
|
|
180390
180359
|
}
|
|
@@ -180453,9 +180422,14 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180453
180422
|
continue;
|
|
180454
180423
|
}
|
|
180455
180424
|
await this.serverNode.addDevice(endpoint);
|
|
180456
|
-
|
|
180457
|
-
|
|
180458
|
-
|
|
180425
|
+
this.endpoints.set(entityId, {
|
|
180426
|
+
endpoint,
|
|
180427
|
+
fingerprint: this.mappingSync.fingerprintAsBuilt(
|
|
180428
|
+
mapping,
|
|
180429
|
+
entityId,
|
|
180430
|
+
endpoint.mappedEntityIds
|
|
180431
|
+
)
|
|
180432
|
+
});
|
|
180459
180433
|
for (const [id, owner] of this.parkedEndpointIds) {
|
|
180460
180434
|
if (id === endpointId || owner === entityId) {
|
|
180461
180435
|
this.parkedEndpointIds.delete(id);
|
|
@@ -180483,7 +180457,11 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180483
180457
|
if (lifecycle === this.lifecycle) {
|
|
180484
180458
|
this.scheduleRemovalRecheck();
|
|
180485
180459
|
}
|
|
180486
|
-
this.
|
|
180460
|
+
this.mappingSync.rebuildCandidates(
|
|
180461
|
+
[...this.endpoints].map(
|
|
180462
|
+
([entityId, entry]) => [entityId, entry.fingerprint]
|
|
180463
|
+
)
|
|
180464
|
+
);
|
|
180487
180465
|
if (this.observingRequested) {
|
|
180488
180466
|
this.startObserving();
|
|
180489
180467
|
}
|
|
@@ -180491,7 +180469,12 @@ var ServerModeEndpointManager = class extends Service {
|
|
|
180491
180469
|
}
|
|
180492
180470
|
async updateStates(states) {
|
|
180493
180471
|
this.registry.mergeExternalStates(states);
|
|
180494
|
-
this.
|
|
180472
|
+
this.mappingSync.maybeRetry(
|
|
180473
|
+
states,
|
|
180474
|
+
null,
|
|
180475
|
+
this.observingRequested,
|
|
180476
|
+
() => this.refreshDevices()
|
|
180477
|
+
);
|
|
180495
180478
|
for (const [entityId, entry] of this.endpoints) {
|
|
180496
180479
|
try {
|
|
180497
180480
|
await entry.endpoint.updateStates(states);
|