@riddix/hamh 2.1.0-alpha.712 → 2.1.0-alpha.714
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
|
@@ -1758,8 +1758,8 @@ var init_Cancelable = __esm({
|
|
|
1758
1758
|
};
|
|
1759
1759
|
return result;
|
|
1760
1760
|
}
|
|
1761
|
-
static set logger(
|
|
1762
|
-
this.#logger =
|
|
1761
|
+
static set logger(logger231) {
|
|
1762
|
+
this.#logger = logger231;
|
|
1763
1763
|
}
|
|
1764
1764
|
static get logger() {
|
|
1765
1765
|
return this.#logger;
|
|
@@ -3450,13 +3450,13 @@ var init_Logger = __esm({
|
|
|
3450
3450
|
*
|
|
3451
3451
|
* @deprecated use {@link destinations}
|
|
3452
3452
|
*/
|
|
3453
|
-
static addLogger(identifier,
|
|
3453
|
+
static addLogger(identifier, logger231, options) {
|
|
3454
3454
|
if (identifier in this.destinations) {
|
|
3455
3455
|
throw new ImplementationError(`Logger "${identifier}" already exists`);
|
|
3456
3456
|
}
|
|
3457
3457
|
const dest = LogDestination({ name: identifier });
|
|
3458
3458
|
const legacy = adaptDestinationToLegacy(dest);
|
|
3459
|
-
legacy.log =
|
|
3459
|
+
legacy.log = logger231;
|
|
3460
3460
|
if (options?.defaultLogLevel !== void 0) {
|
|
3461
3461
|
legacy.defaultLogLevel = options.defaultLogLevel;
|
|
3462
3462
|
}
|
|
@@ -5644,8 +5644,8 @@ var init_Construction = __esm({
|
|
|
5644
5644
|
}
|
|
5645
5645
|
}
|
|
5646
5646
|
#unhandledError(...args) {
|
|
5647
|
-
const
|
|
5648
|
-
|
|
5647
|
+
const logger231 = Logger.get(this.#subject.constructor.name);
|
|
5648
|
+
logger231.error(...args);
|
|
5649
5649
|
}
|
|
5650
5650
|
#createErrorHandler(name) {
|
|
5651
5651
|
return (e) => {
|
|
@@ -62023,8 +62023,8 @@ var init_NodeSession = __esm({
|
|
|
62023
62023
|
return session?.type === SessionType.Unicast;
|
|
62024
62024
|
}
|
|
62025
62025
|
NodeSession2.is = is;
|
|
62026
|
-
function logNew(
|
|
62027
|
-
|
|
62026
|
+
function logNew(logger231, operation, session, messenger, fabric, peerNodeId) {
|
|
62027
|
+
logger231.info(
|
|
62028
62028
|
session.via,
|
|
62029
62029
|
`${operation} session with`,
|
|
62030
62030
|
Diagnostic.strong(PeerAddress({ fabricIndex: fabric.fabricIndex, nodeId: peerNodeId }).toString()),
|
|
@@ -110814,11 +110814,11 @@ var init_Api = __esm({
|
|
|
110814
110814
|
}
|
|
110815
110815
|
Api2.resourceFor = resourceFor;
|
|
110816
110816
|
function log(level, facility, id, ...message) {
|
|
110817
|
-
let
|
|
110818
|
-
if (!
|
|
110819
|
-
loggers.set(facility,
|
|
110817
|
+
let logger231 = loggers.get(facility);
|
|
110818
|
+
if (!logger231) {
|
|
110819
|
+
loggers.set(facility, logger231 = Logger.get(facility));
|
|
110820
110820
|
}
|
|
110821
|
-
|
|
110821
|
+
logger231[level](Diagnostic.via(id || "(anon)"), message);
|
|
110822
110822
|
}
|
|
110823
110823
|
Api2.log = log;
|
|
110824
110824
|
function logRequest(facility, id, method, target) {
|
|
@@ -124211,8 +124211,7 @@ var init_bridge_config_schema = __esm({
|
|
|
124211
124211
|
sessionMaxAgeHours: {
|
|
124212
124212
|
title: "Session Rotation Max Age (hours)",
|
|
124213
124213
|
type: "number",
|
|
124214
|
-
description: "
|
|
124215
|
-
default: 4,
|
|
124214
|
+
description: "Rotate matter sessions older than this many hours so controllers re-establish and re-subscribe. Server Mode rotates every 4h by default; standard bridges only rotate when you set a value here. Set 0 to disable. Range 0 to 168. (#287)",
|
|
124216
124215
|
minimum: 0,
|
|
124217
124216
|
maximum: 168
|
|
124218
124217
|
},
|
|
@@ -124692,10 +124691,10 @@ var init_home_assistant_actions = __esm({
|
|
|
124692
124691
|
circuitBreakerResetMs: 3e4
|
|
124693
124692
|
};
|
|
124694
124693
|
HomeAssistantActions = class extends Service {
|
|
124695
|
-
constructor(
|
|
124694
|
+
constructor(logger231, client, config11) {
|
|
124696
124695
|
super("HomeAssistantActions");
|
|
124697
124696
|
this.client = client;
|
|
124698
|
-
this.log =
|
|
124697
|
+
this.log = logger231.get(this);
|
|
124699
124698
|
this.config = { ...defaultConfig, ...config11 };
|
|
124700
124699
|
this.circuitBreaker = new CircuitBreaker(
|
|
124701
124700
|
this.config.circuitBreakerThreshold,
|
|
@@ -125035,10 +125034,10 @@ var DiagnosticService = class {
|
|
|
125035
125034
|
};
|
|
125036
125035
|
|
|
125037
125036
|
// src/api/access-log.ts
|
|
125038
|
-
function accessLogger(
|
|
125037
|
+
function accessLogger(logger231) {
|
|
125039
125038
|
return (req, res, next) => {
|
|
125040
125039
|
res.on("finish", () => {
|
|
125041
|
-
|
|
125040
|
+
logger231.debug(
|
|
125042
125041
|
`${req.method} ${decodeURI(req.originalUrl)} ${res.statusCode} ${res.statusMessage} from ${req.socket.remoteAddress}`
|
|
125043
125042
|
);
|
|
125044
125043
|
});
|
|
@@ -127627,6 +127626,39 @@ function metricsApi(bridgeService, haClient, haRegistry, startTime) {
|
|
|
127627
127626
|
// src/api/network-diagnostic-api.ts
|
|
127628
127627
|
import * as os3 from "node:os";
|
|
127629
127628
|
import express13 from "express";
|
|
127629
|
+
|
|
127630
|
+
// src/core/app/select-mdns-interface.ts
|
|
127631
|
+
var DOCKER_NAME = /^(docker\d*|hassio|veth|cni)/;
|
|
127632
|
+
function inDockerRange(ipv4) {
|
|
127633
|
+
const parts = ipv4.split(".");
|
|
127634
|
+
const second = Number(parts[1]);
|
|
127635
|
+
return parts[0] === "172" && second >= 16 && second <= 31;
|
|
127636
|
+
}
|
|
127637
|
+
function isLinkLocal(family, address) {
|
|
127638
|
+
if (family === "IPv4") return address.startsWith("169.254.");
|
|
127639
|
+
return address.toLowerCase().startsWith("fe80");
|
|
127640
|
+
}
|
|
127641
|
+
function selectMdnsInterface(raw) {
|
|
127642
|
+
const external = [];
|
|
127643
|
+
const dockerLike = [];
|
|
127644
|
+
for (const [name, addrs] of Object.entries(raw)) {
|
|
127645
|
+
if (!addrs) continue;
|
|
127646
|
+
const usable = addrs.filter((a) => !a.internal);
|
|
127647
|
+
if (usable.length === 0) continue;
|
|
127648
|
+
if (DOCKER_NAME.test(name)) dockerLike.push(name);
|
|
127649
|
+
const ipv4 = usable.filter((a) => a.family === "IPv4").map((a) => a.address);
|
|
127650
|
+
const ipv6 = usable.filter((a) => a.family === "IPv6").map((a) => a.address);
|
|
127651
|
+
const routable = usable.some((a) => !isLinkLocal(a.family, a.address));
|
|
127652
|
+
if (!routable) continue;
|
|
127653
|
+
external.push({ name, ipv4, ipv6 });
|
|
127654
|
+
}
|
|
127655
|
+
const lan = external.filter((i) => !DOCKER_NAME.test(i.name));
|
|
127656
|
+
const selected = lan.length === 1 ? lan[0].name : void 0;
|
|
127657
|
+
const suspicious = dockerLike.length > 0 || external.some((i) => i.ipv4.some(inDockerRange));
|
|
127658
|
+
return { selected, external, dockerLike, suspicious };
|
|
127659
|
+
}
|
|
127660
|
+
|
|
127661
|
+
// src/api/network-diagnostic-api.ts
|
|
127630
127662
|
function networkDiagnosticApi(mdnsInterface, mdnsIpv4) {
|
|
127631
127663
|
const router = express13.Router();
|
|
127632
127664
|
router.get("/", (_, res) => {
|
|
@@ -127760,13 +127792,17 @@ function runDiagnostics(mdnsInterface, mdnsIpv4) {
|
|
|
127760
127792
|
detail: "Some controllers (older Alexa, Google Home) may need IPv4 mDNS for discovery. Enable with --mdns-ipv4."
|
|
127761
127793
|
});
|
|
127762
127794
|
}
|
|
127763
|
-
if (
|
|
127764
|
-
|
|
127765
|
-
|
|
127766
|
-
|
|
127767
|
-
|
|
127768
|
-
|
|
127769
|
-
|
|
127795
|
+
if (!mdnsInterface) {
|
|
127796
|
+
const choice = selectMdnsInterface(os3.networkInterfaces());
|
|
127797
|
+
if (choice.suspicious || choice.external.length > 1) {
|
|
127798
|
+
const suggestion = choice.selected ? `Bind to "${choice.selected}" via mdns-network-interface.` : `Set mdns-network-interface to your LAN interface (${choice.external.map((i) => i.name).join(", ")}).`;
|
|
127799
|
+
checks.push({
|
|
127800
|
+
name: "multiple_interfaces",
|
|
127801
|
+
status: "warn",
|
|
127802
|
+
message: choice.suspicious ? "mDNS is advertising on Docker-internal or extra interfaces, which can make controllers show devices as offline" : `${choice.external.length} external interfaces detected without explicit binding`,
|
|
127803
|
+
detail: choice.suspicious ? `Matter bakes every interface address into its operational records, so controllers may pick an unreachable one. ${suggestion}` : `mDNS will broadcast on all interfaces. If controllers are on a specific VLAN, ${suggestion}`
|
|
127804
|
+
});
|
|
127805
|
+
}
|
|
127770
127806
|
}
|
|
127771
127807
|
return {
|
|
127772
127808
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -128607,8 +128643,8 @@ function systemApi(version2) {
|
|
|
128607
128643
|
}
|
|
128608
128644
|
function getNetworkInterfaces2() {
|
|
128609
128645
|
const interfaces = [];
|
|
128610
|
-
const
|
|
128611
|
-
for (const [name, ifaceList] of Object.entries(
|
|
128646
|
+
const networkInterfaces4 = os4.networkInterfaces();
|
|
128647
|
+
for (const [name, ifaceList] of Object.entries(networkInterfaces4)) {
|
|
128612
128648
|
if (!ifaceList) continue;
|
|
128613
128649
|
for (const iface of ifaceList) {
|
|
128614
128650
|
const family = String(iface.family);
|
|
@@ -128872,7 +128908,7 @@ var WebSocketApi = class {
|
|
|
128872
128908
|
|
|
128873
128909
|
// src/api/web-api.ts
|
|
128874
128910
|
var WebApi = class extends Service {
|
|
128875
|
-
constructor(
|
|
128911
|
+
constructor(logger231, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, lockCredentialStorage, settingsStorage, backupService, props) {
|
|
128876
128912
|
super("WebApi");
|
|
128877
128913
|
this.bridgeService = bridgeService;
|
|
128878
128914
|
this.haClient = haClient;
|
|
@@ -128883,8 +128919,8 @@ var WebApi = class extends Service {
|
|
|
128883
128919
|
this.settingsStorage = settingsStorage;
|
|
128884
128920
|
this.backupService = backupService;
|
|
128885
128921
|
this.props = props;
|
|
128886
|
-
this.logger =
|
|
128887
|
-
this.log =
|
|
128922
|
+
this.logger = logger231;
|
|
128923
|
+
this.log = logger231.get(this);
|
|
128888
128924
|
this.accessLogger = accessLogger(this.log.createChild("Access Log"));
|
|
128889
128925
|
this.startTime = Date.now();
|
|
128890
128926
|
this.wsApi = new WebSocketApi(
|
|
@@ -129284,22 +129320,41 @@ var BetterLogger = class _BetterLogger extends Logger {
|
|
|
129284
129320
|
}
|
|
129285
129321
|
};
|
|
129286
129322
|
|
|
129323
|
+
// src/core/app/mdns.ts
|
|
129324
|
+
init_esm();
|
|
129325
|
+
import * as os5 from "node:os";
|
|
129326
|
+
|
|
129287
129327
|
// ../../node_modules/.pnpm/@matter+main@0.17.0/node_modules/@matter/main/dist/esm/protocol.js
|
|
129288
129328
|
init_nodejs();
|
|
129289
129329
|
init_esm4();
|
|
129290
129330
|
|
|
129291
129331
|
// src/core/app/mdns.ts
|
|
129332
|
+
var logger168 = Logger.get("Mdns");
|
|
129292
129333
|
function mdns(env, options) {
|
|
129334
|
+
if (!options.networkInterface) {
|
|
129335
|
+
warnIfMisadvertising();
|
|
129336
|
+
}
|
|
129293
129337
|
new MdnsService(env, {
|
|
129294
129338
|
ipv4: options.ipv4,
|
|
129295
129339
|
networkInterface: options.networkInterface
|
|
129296
129340
|
});
|
|
129297
129341
|
}
|
|
129342
|
+
function warnIfMisadvertising() {
|
|
129343
|
+
const choice = selectMdnsInterface(os5.networkInterfaces());
|
|
129344
|
+
if (!choice.suspicious) {
|
|
129345
|
+
return;
|
|
129346
|
+
}
|
|
129347
|
+
const suggestion = choice.selected ? ` Likely LAN interface: ${choice.selected}.` : "";
|
|
129348
|
+
const list3 = choice.external.map((i) => `${i.name} (${i.ipv4[0] ?? i.ipv6[0] ?? "?"})`).join(", ");
|
|
129349
|
+
logger168.warn(
|
|
129350
|
+
`Matter mDNS is advertising on several interfaces including likely Docker-internal ones, so controllers may show devices as offline (#361). Set mdns-network-interface to your LAN interface.${suggestion} Interfaces: ${list3}.`
|
|
129351
|
+
);
|
|
129352
|
+
}
|
|
129298
129353
|
|
|
129299
129354
|
// src/core/app/storage.ts
|
|
129300
129355
|
init_esm7();
|
|
129301
129356
|
import fs7 from "node:fs";
|
|
129302
|
-
import
|
|
129357
|
+
import os6 from "node:os";
|
|
129303
129358
|
import path8 from "node:path";
|
|
129304
129359
|
|
|
129305
129360
|
// src/core/app/storage/custom-storage.ts
|
|
@@ -129334,7 +129389,7 @@ function storage(environment, options) {
|
|
|
129334
129389
|
storageService.defaultDriver = CustomStorage.driverId;
|
|
129335
129390
|
}
|
|
129336
129391
|
function resolveStorageLocation(storageLocation) {
|
|
129337
|
-
const homedir =
|
|
129392
|
+
const homedir = os6.homedir();
|
|
129338
129393
|
return storageLocation ? path8.resolve(storageLocation.replace(/^~\//, `${homedir}/`)) : path8.join(homedir, ".home-assistant-matter-hub");
|
|
129339
129394
|
}
|
|
129340
129395
|
|
|
@@ -129354,7 +129409,7 @@ function configureDefaultEnvironment(options) {
|
|
|
129354
129409
|
// src/core/app/options.ts
|
|
129355
129410
|
init_esm7();
|
|
129356
129411
|
import { createRequire } from "node:module";
|
|
129357
|
-
import
|
|
129412
|
+
import os7 from "node:os";
|
|
129358
129413
|
import path9 from "node:path";
|
|
129359
129414
|
function resolveAppVersion() {
|
|
129360
129415
|
try {
|
|
@@ -129423,7 +129478,7 @@ var Options = class {
|
|
|
129423
129478
|
}
|
|
129424
129479
|
resolveStorageLocation() {
|
|
129425
129480
|
const storageLocation = notEmpty(this.startOptions.storageLocation);
|
|
129426
|
-
const homedir =
|
|
129481
|
+
const homedir = os7.homedir();
|
|
129427
129482
|
return storageLocation ? path9.resolve(storageLocation.replace(/^~\//, `${homedir}/`)) : path9.join(homedir, ".home-assistant-matter-hub");
|
|
129428
129483
|
}
|
|
129429
129484
|
get bridgeService() {
|
|
@@ -129931,10 +129986,10 @@ function isTransientConnectError(reason) {
|
|
|
129931
129986
|
return msg.includes("socket hang up") || msg.includes("tls") || msg.includes("TLS");
|
|
129932
129987
|
}
|
|
129933
129988
|
var HomeAssistantClient = class extends Service {
|
|
129934
|
-
constructor(
|
|
129989
|
+
constructor(logger231, options) {
|
|
129935
129990
|
super("HomeAssistantClient");
|
|
129936
129991
|
this.options = options;
|
|
129937
|
-
this.log =
|
|
129992
|
+
this.log = logger231.get(this);
|
|
129938
129993
|
}
|
|
129939
129994
|
options;
|
|
129940
129995
|
static Options = /* @__PURE__ */ Symbol.for("HomeAssistantClientProps");
|
|
@@ -130053,7 +130108,7 @@ import { getStates } from "home-assistant-js-websocket";
|
|
|
130053
130108
|
import { fromPairs, keyBy, keys, uniq, values } from "lodash-es";
|
|
130054
130109
|
|
|
130055
130110
|
// src/utils/log-memory.ts
|
|
130056
|
-
import
|
|
130111
|
+
import os8 from "node:os";
|
|
130057
130112
|
import v82 from "node:v8";
|
|
130058
130113
|
var HEAP_PRESSURE_THRESHOLD = 0.85;
|
|
130059
130114
|
var LOW_MEMORY_THRESHOLD_MB = 512;
|
|
@@ -130071,8 +130126,8 @@ function isHeapUnderPressure() {
|
|
|
130071
130126
|
return stats.used_heap_size / stats.heap_size_limit > HEAP_PRESSURE_THRESHOLD;
|
|
130072
130127
|
}
|
|
130073
130128
|
function logStartupMemoryGuard(log) {
|
|
130074
|
-
const totalMB = Math.round(
|
|
130075
|
-
const freeMB = Math.round(
|
|
130129
|
+
const totalMB = Math.round(os8.totalmem() / 1024 / 1024);
|
|
130130
|
+
const freeMB = Math.round(os8.freemem() / 1024 / 1024);
|
|
130076
130131
|
const heapLimitMB = Math.round(
|
|
130077
130132
|
v82.getHeapStatistics().heap_size_limit / 1024 / 1024
|
|
130078
130133
|
);
|
|
@@ -130121,7 +130176,7 @@ async function getAreaRegistry(connection, timeoutMs) {
|
|
|
130121
130176
|
}
|
|
130122
130177
|
|
|
130123
130178
|
// src/services/home-assistant/home-assistant-registry.ts
|
|
130124
|
-
var
|
|
130179
|
+
var logger169 = Logger.get("HomeAssistantRegistry");
|
|
130125
130180
|
var HomeAssistantRegistry = class extends Service {
|
|
130126
130181
|
constructor(client, options) {
|
|
130127
130182
|
super("HomeAssistantRegistry");
|
|
@@ -130156,7 +130211,7 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
130156
130211
|
try {
|
|
130157
130212
|
await this.reload();
|
|
130158
130213
|
} catch (e) {
|
|
130159
|
-
|
|
130214
|
+
logger169.warn(
|
|
130160
130215
|
"Initial registry fetch failed, starting empty and relying on auto-refresh:",
|
|
130161
130216
|
e
|
|
130162
130217
|
);
|
|
@@ -130170,7 +130225,7 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
130170
130225
|
let refreshing = false;
|
|
130171
130226
|
this.autoRefresh = setInterval(async () => {
|
|
130172
130227
|
if (refreshing) {
|
|
130173
|
-
|
|
130228
|
+
logger169.debug("Skipping registry refresh, previous tick still running");
|
|
130174
130229
|
return;
|
|
130175
130230
|
}
|
|
130176
130231
|
refreshing = true;
|
|
@@ -130180,7 +130235,7 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
130180
130235
|
await onRefresh();
|
|
130181
130236
|
}
|
|
130182
130237
|
} catch (e) {
|
|
130183
|
-
|
|
130238
|
+
logger169.warn("Failed to refresh registry, will retry next interval:", e);
|
|
130184
130239
|
} finally {
|
|
130185
130240
|
refreshing = false;
|
|
130186
130241
|
}
|
|
@@ -130198,7 +130253,7 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
130198
130253
|
baseDelayMs: 2e3,
|
|
130199
130254
|
maxDelayMs: 3e4,
|
|
130200
130255
|
onRetry: (attempt, error, delayMs) => {
|
|
130201
|
-
|
|
130256
|
+
logger169.warn(
|
|
130202
130257
|
`Registry fetch failed (attempt ${attempt}), retrying in ${delayMs}ms:`,
|
|
130203
130258
|
error
|
|
130204
130259
|
);
|
|
@@ -130211,7 +130266,7 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
130211
130266
|
return await this.runRegistryQueries();
|
|
130212
130267
|
} catch (e) {
|
|
130213
130268
|
if (!isConnectionLost(e)) throw e;
|
|
130214
|
-
|
|
130269
|
+
logger169.debug("Registry fetch hit connection drop, waiting for reconnect");
|
|
130215
130270
|
await this.waitForConnection(6e4);
|
|
130216
130271
|
return await this.runRegistryQueries();
|
|
130217
130272
|
}
|
|
@@ -130219,7 +130274,7 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
130219
130274
|
async waitForConnection(timeoutMs) {
|
|
130220
130275
|
const connection = this.client.connection;
|
|
130221
130276
|
if (connection.connected) return;
|
|
130222
|
-
|
|
130277
|
+
logger169.debug("Connection not ready, waiting for reconnect...");
|
|
130223
130278
|
await new Promise((resolve11) => {
|
|
130224
130279
|
const timeout = setTimeout(() => {
|
|
130225
130280
|
connection.removeEventListener("ready", onReady);
|
|
@@ -130276,7 +130331,7 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
130276
130331
|
const fingerprint = hash2.digest("hex");
|
|
130277
130332
|
this._states = keyBy(statesList, "entity_id");
|
|
130278
130333
|
if (fingerprint === this.lastRegistryFingerprint) {
|
|
130279
|
-
|
|
130334
|
+
logger169.debug("Registry unchanged, skipping full refresh");
|
|
130280
130335
|
return false;
|
|
130281
130336
|
}
|
|
130282
130337
|
this.lastRegistryFingerprint = fingerprint;
|
|
@@ -130297,10 +130352,10 @@ var HomeAssistantRegistry = class extends Service {
|
|
|
130297
130352
|
const missingDevices = fromPairs(missingDeviceIds.map((d) => [d, { id: d }]));
|
|
130298
130353
|
this._devices = { ...missingDevices, ...realDevices };
|
|
130299
130354
|
this._entities = allEntities;
|
|
130300
|
-
|
|
130355
|
+
logger169.debug(
|
|
130301
130356
|
`Loaded HA registry: ${keys(allEntities).length} entities, ${keys(realDevices).length} devices, ${keys(this._states).length} states`
|
|
130302
130357
|
);
|
|
130303
|
-
logMemoryUsage(
|
|
130358
|
+
logMemoryUsage(logger169, "after HA registry load");
|
|
130304
130359
|
this._labels = labels;
|
|
130305
130360
|
this._areas = new Map(areas.map((a) => [a.area_id, a.name]));
|
|
130306
130361
|
return true;
|
|
@@ -131095,7 +131150,7 @@ var __privateIn3 = (member, obj) => Object(obj) !== obj ? __typeError47('Cannot
|
|
|
131095
131150
|
var __privateGet3 = (obj, member, getter) => (__accessCheck3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
131096
131151
|
var __privateSet3 = (obj, member, value, setter) => (__accessCheck3(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
131097
131152
|
var __privateMethod3 = (obj, member, method) => (__accessCheck3(obj, member, "access private method"), method);
|
|
131098
|
-
var
|
|
131153
|
+
var logger170 = Logger.get("ScenesManagementServer");
|
|
131099
131154
|
var UNDEFINED_SCENE_ID = 255;
|
|
131100
131155
|
function constraintErrorWithSceneId(groupId22, sceneId) {
|
|
131101
131156
|
const response = { status: Status2.ConstraintError, groupId: groupId22, sceneId };
|
|
@@ -131222,11 +131277,11 @@ var ScenesManagementServer = class extends ScenesManagementBase {
|
|
|
131222
131277
|
return { status: Status2.ResourceExhausted, groupId: groupId22, sceneId };
|
|
131223
131278
|
}
|
|
131224
131279
|
this.state.sceneTable.push(sceneData);
|
|
131225
|
-
|
|
131280
|
+
logger170.debug(`Added scene ${sceneId} in group ${groupId22} for fabric ${fabricIndex}`);
|
|
131226
131281
|
this.#updateFabricSceneInfoCountsForFabric(fabricIndex);
|
|
131227
131282
|
} else {
|
|
131228
131283
|
this.state.sceneTable[existingSceneIndex] = sceneData;
|
|
131229
|
-
|
|
131284
|
+
logger170.debug(`Updated scene ${sceneId} in group ${groupId22} for fabric ${fabricIndex}`);
|
|
131230
131285
|
}
|
|
131231
131286
|
return { status: Status2.Success, groupId: groupId22, sceneId };
|
|
131232
131287
|
}
|
|
@@ -131529,20 +131584,20 @@ var ScenesManagementServer = class extends ScenesManagementBase {
|
|
|
131529
131584
|
}
|
|
131530
131585
|
}
|
|
131531
131586
|
if (fieldCount !== 2) {
|
|
131532
|
-
|
|
131587
|
+
logger170.warn(
|
|
131533
131588
|
`AttributeValuePair has invalid number (${fieldCount}) of fields (${serialize(attributeValuePair)})`
|
|
131534
131589
|
);
|
|
131535
131590
|
return void 0;
|
|
131536
131591
|
}
|
|
131537
131592
|
const value = attributeValuePair[mappedType];
|
|
131538
131593
|
if (value === void 0) {
|
|
131539
|
-
|
|
131594
|
+
logger170.warn(
|
|
131540
131595
|
`AttributeValuePair missing value for mappedType ${mappedType} (${serialize(attributeValuePair)})`
|
|
131541
131596
|
);
|
|
131542
131597
|
return void 0;
|
|
131543
131598
|
}
|
|
131544
131599
|
if (typeof value !== "number" && typeof value !== "bigint") {
|
|
131545
|
-
|
|
131600
|
+
logger170.warn(
|
|
131546
131601
|
`AttributeValuePair has invalid non-numeric value for mappedType ${mappedType} (${serialize(attributeValuePair)})`
|
|
131547
131602
|
// Should never happen
|
|
131548
131603
|
);
|
|
@@ -131640,7 +131695,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
|
|
|
131640
131695
|
} else if (schema6.schema.baseTypeMin < 0 && schema6.schema.min > schema6.schema.baseTypeMin) {
|
|
131641
131696
|
return { attributeId, [mappedType]: schema6.schema.baseTypeMin };
|
|
131642
131697
|
} else {
|
|
131643
|
-
|
|
131698
|
+
logger170.warn(
|
|
131644
131699
|
`Cannot determine out-of-bounds value for attribute schema, returning min value of datatype schema`
|
|
131645
131700
|
);
|
|
131646
131701
|
}
|
|
@@ -131661,7 +131716,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
|
|
|
131661
131716
|
}
|
|
131662
131717
|
}
|
|
131663
131718
|
});
|
|
131664
|
-
|
|
131719
|
+
logger170.debug(`Collected scene attribute values on Endpoint ${this.endpoint.id}: ${serialize(sceneValues)}`);
|
|
131665
131720
|
return sceneValues;
|
|
131666
131721
|
}
|
|
131667
131722
|
/**
|
|
@@ -131700,7 +131755,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
|
|
|
131700
131755
|
}
|
|
131701
131756
|
const attrType = attribute.primitiveBase?.name;
|
|
131702
131757
|
if (attrType === void 0 || DataTypeToSceneAttributeDataMap[attrType] === void 0) {
|
|
131703
|
-
|
|
131758
|
+
logger170.warn(
|
|
131704
131759
|
`Scene Attribute ${attribute.name} on Cluster ${clusterName} has unsupported datatype ${attrType} for scene management on Endpoint ${this.endpoint.id}`
|
|
131705
131760
|
);
|
|
131706
131761
|
continue;
|
|
@@ -131715,7 +131770,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
|
|
|
131715
131770
|
});
|
|
131716
131771
|
}
|
|
131717
131772
|
if (sceneClusterDetails) {
|
|
131718
|
-
|
|
131773
|
+
logger170.info(
|
|
131719
131774
|
`Registered ${sceneClusterDetails.attributes.size} scene attributes for Cluster ${clusterName} on Endpoint ${this.endpoint.id}`
|
|
131720
131775
|
);
|
|
131721
131776
|
this.internal.endpointSceneableBehaviors.add(sceneClusterDetails);
|
|
@@ -131723,7 +131778,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
|
|
|
131723
131778
|
}
|
|
131724
131779
|
/** Apply scene attribute values in the various clusters on the endpoint. */
|
|
131725
131780
|
#applySceneAttributeValues(sceneValues, transitionTime = null) {
|
|
131726
|
-
|
|
131781
|
+
logger170.debug(`Recalling scene on Endpoint ${this.endpoint.id} with values: ${serialize(sceneValues)}`);
|
|
131727
131782
|
const agent = this.endpoint.agentFor(this.context);
|
|
131728
131783
|
const promises = [];
|
|
131729
131784
|
for (const [clusterName, clusterAttributes] of Object.entries(sceneValues)) {
|
|
@@ -131734,7 +131789,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
|
|
|
131734
131789
|
promises.push(result);
|
|
131735
131790
|
}
|
|
131736
131791
|
} else {
|
|
131737
|
-
|
|
131792
|
+
logger170.warn(
|
|
131738
131793
|
`No scenes implementation found for cluster ${clusterName} on Endpoint ${this.endpoint.id} during scene recall. Values are ignored`
|
|
131739
131794
|
);
|
|
131740
131795
|
}
|
|
@@ -131742,7 +131797,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
|
|
|
131742
131797
|
if (promises.length) {
|
|
131743
131798
|
return Promise.all(promises).then(
|
|
131744
131799
|
() => void 0,
|
|
131745
|
-
(error) =>
|
|
131800
|
+
(error) => logger170.warn(`Error applying scene attribute values on Endpoint ${this.endpoint.id}:`, error)
|
|
131746
131801
|
);
|
|
131747
131802
|
}
|
|
131748
131803
|
}
|
|
@@ -131935,7 +131990,7 @@ var GroupsBehaviorConstructor = ClusterBehavior.for(Groups4);
|
|
|
131935
131990
|
var GroupsBehavior = GroupsBehaviorConstructor;
|
|
131936
131991
|
|
|
131937
131992
|
// ../../node_modules/.pnpm/@matter+node@0.17.0/node_modules/@matter/node/dist/esm/behaviors/groups/GroupsServer.js
|
|
131938
|
-
var
|
|
131993
|
+
var logger171 = Logger.get("GroupsServer");
|
|
131939
131994
|
var { commands: commands3 } = Groups4.schema;
|
|
131940
131995
|
var addGroup = commands3.require("AddGroup");
|
|
131941
131996
|
var addGroupIfIdentifying = commands3.require("AddGroupIfIdentifying");
|
|
@@ -132002,7 +132057,7 @@ var GroupsServer = class extends GroupsBase {
|
|
|
132002
132057
|
(fabric2, gkm) => gkm.addEndpointForGroup(fabric2, groupId3, endpointNumber, groupName)
|
|
132003
132058
|
);
|
|
132004
132059
|
} catch (error) {
|
|
132005
|
-
|
|
132060
|
+
logger171.error(error);
|
|
132006
132061
|
StatusResponseError.accept(error);
|
|
132007
132062
|
return { status: error.code, groupId: groupId3 };
|
|
132008
132063
|
}
|
|
@@ -132646,7 +132701,7 @@ var SwitchBehavior = SwitchBehaviorConstructor;
|
|
|
132646
132701
|
// ../../node_modules/.pnpm/@matter+node@0.17.0/node_modules/@matter/node/dist/esm/behaviors/switch/SwitchServer.js
|
|
132647
132702
|
var DEFAULT_MULTIPRESS_DELAY = Millis(300);
|
|
132648
132703
|
var DEFAULT_LONG_PRESS_DELAY = Seconds(2);
|
|
132649
|
-
var
|
|
132704
|
+
var logger172 = Logger.get("SwitchServer");
|
|
132650
132705
|
var SwitchServerBase = SwitchBehavior.with(
|
|
132651
132706
|
Switch3.Feature.LatchingSwitch,
|
|
132652
132707
|
Switch3.Feature.MomentarySwitch,
|
|
@@ -132699,7 +132754,7 @@ var SwitchBaseServer = class extends SwitchServerBase {
|
|
|
132699
132754
|
this.internal.currentIsLongPress = false;
|
|
132700
132755
|
this.internal.multiPressTimer?.stop();
|
|
132701
132756
|
this.internal.longPressTimer?.stop();
|
|
132702
|
-
|
|
132757
|
+
logger172.info("State of Switch got reset");
|
|
132703
132758
|
}
|
|
132704
132759
|
// TODO remove when Validator logic can assess that with 1.3 introduction
|
|
132705
132760
|
#assertPositionInRange(position) {
|
|
@@ -133347,11 +133402,11 @@ var OccupancySensingBehaviorConstructor = ClusterBehavior.for(OccupancySensing3)
|
|
|
133347
133402
|
var OccupancySensingBehavior = OccupancySensingBehaviorConstructor;
|
|
133348
133403
|
|
|
133349
133404
|
// ../../node_modules/.pnpm/@matter+node@0.17.0/node_modules/@matter/node/dist/esm/behaviors/occupancy-sensing/OccupancySensingServer.js
|
|
133350
|
-
var
|
|
133405
|
+
var logger173 = Logger.get("OccupancySensingServer");
|
|
133351
133406
|
var OccupancySensingServer = class extends OccupancySensingBehavior {
|
|
133352
133407
|
initialize() {
|
|
133353
133408
|
if (!Object.values(this.features).some((feature) => feature)) {
|
|
133354
|
-
|
|
133409
|
+
logger173.error(
|
|
133355
133410
|
`OccupancySensingServer: Since revision 5 of the cluster features need to be set based on the detector type. Currently no features are enabled.`
|
|
133356
133411
|
);
|
|
133357
133412
|
} else if (!Object.values(this.state.occupancySensorTypeBitmap).some((feature) => feature) || this.state.occupancySensorType === void 0) {
|
|
@@ -133378,7 +133433,7 @@ var OccupancySensingServer = class extends OccupancySensingBehavior {
|
|
|
133378
133433
|
} else if (this.state.occupancySensorTypeBitmap.physicalContact) {
|
|
133379
133434
|
this.state.occupancySensorType = OccupancySensing3.OccupancySensorType.PhysicalContact;
|
|
133380
133435
|
}
|
|
133381
|
-
|
|
133436
|
+
logger173.debug(
|
|
133382
133437
|
"Sync occupancySensorType to",
|
|
133383
133438
|
OccupancySensing3.OccupancySensorType[this.state.occupancySensorType],
|
|
133384
133439
|
"and occupancySensorTypeBitmap to",
|
|
@@ -135976,7 +136031,7 @@ function miredsToXy(mireds) {
|
|
|
135976
136031
|
}
|
|
135977
136032
|
|
|
135978
136033
|
// ../../node_modules/.pnpm/@matter+node@0.17.0/node_modules/@matter/node/dist/esm/behaviors/color-control/ColorControlServer.js
|
|
135979
|
-
var
|
|
136034
|
+
var logger174 = Logger.get("ColorControlServer");
|
|
135980
136035
|
var ColorControlBase = ColorControlBehavior.with(
|
|
135981
136036
|
ColorControl3.Feature.HueSaturation,
|
|
135982
136037
|
ColorControl3.Feature.EnhancedHue,
|
|
@@ -137157,7 +137212,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
|
|
|
137157
137212
|
switch (oldMode) {
|
|
137158
137213
|
case ColorControl3.ColorMode.CurrentHueAndCurrentSaturation:
|
|
137159
137214
|
if (this.state.currentHue === void 0 || this.state.currentSaturation === void 0) {
|
|
137160
|
-
|
|
137215
|
+
logger174.warn("Could not convert from hue/saturation because one of them is undefined");
|
|
137161
137216
|
break;
|
|
137162
137217
|
}
|
|
137163
137218
|
switch (newMode) {
|
|
@@ -137169,7 +137224,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
|
|
|
137169
137224
|
case ColorControl3.ColorMode.ColorTemperatureMireds:
|
|
137170
137225
|
const mireds = hsvToMireds(this.hue, this.saturation);
|
|
137171
137226
|
if (mireds === void 0) {
|
|
137172
|
-
|
|
137227
|
+
logger174.warn(
|
|
137173
137228
|
`Could not convert hue/saturation (${this.hue}/${this.saturation}) to color temperature`
|
|
137174
137229
|
);
|
|
137175
137230
|
} else {
|
|
@@ -137180,7 +137235,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
|
|
|
137180
137235
|
break;
|
|
137181
137236
|
case ColorControl3.ColorMode.CurrentXAndCurrentY:
|
|
137182
137237
|
if (this.state.currentX === void 0 || this.state.currentY === void 0) {
|
|
137183
|
-
|
|
137238
|
+
logger174.warn("Could not convert from xy because one of them is undefined");
|
|
137184
137239
|
break;
|
|
137185
137240
|
}
|
|
137186
137241
|
switch (newMode) {
|
|
@@ -137192,7 +137247,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
|
|
|
137192
137247
|
case ColorControl3.ColorMode.ColorTemperatureMireds:
|
|
137193
137248
|
const mireds = xyToMireds(this.x, this.y);
|
|
137194
137249
|
if (mireds === void 0) {
|
|
137195
|
-
|
|
137250
|
+
logger174.warn(`Could not convert xy ${this.x / this.y} to color temperature`);
|
|
137196
137251
|
} else {
|
|
137197
137252
|
this.mireds = mireds;
|
|
137198
137253
|
}
|
|
@@ -137201,14 +137256,14 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
|
|
|
137201
137256
|
break;
|
|
137202
137257
|
case ColorControl3.ColorMode.ColorTemperatureMireds:
|
|
137203
137258
|
if (this.state.colorTemperatureMireds === void 0) {
|
|
137204
|
-
|
|
137259
|
+
logger174.warn("Could not convert from color temperature because it is undefined");
|
|
137205
137260
|
break;
|
|
137206
137261
|
}
|
|
137207
137262
|
switch (newMode) {
|
|
137208
137263
|
case ColorControl3.ColorMode.CurrentHueAndCurrentSaturation:
|
|
137209
137264
|
const hsvResult = miredsToHsv(this.mireds);
|
|
137210
137265
|
if (hsvResult === void 0) {
|
|
137211
|
-
|
|
137266
|
+
logger174.warn(`Could not convert color temperature ${this.mireds} to hue/saturation`);
|
|
137212
137267
|
} else {
|
|
137213
137268
|
const [hue, saturation] = hsvResult;
|
|
137214
137269
|
this.hue = hue;
|
|
@@ -137218,7 +137273,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
|
|
|
137218
137273
|
case ColorControl3.ColorMode.CurrentXAndCurrentY:
|
|
137219
137274
|
const xyResult = miredsToXy(this.mireds);
|
|
137220
137275
|
if (xyResult === void 0) {
|
|
137221
|
-
|
|
137276
|
+
logger174.warn("Could not convert color temperature to xy");
|
|
137222
137277
|
} else {
|
|
137223
137278
|
const [x, y] = xyResult;
|
|
137224
137279
|
this.x = x;
|
|
@@ -137267,7 +137322,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
|
|
|
137267
137322
|
);
|
|
137268
137323
|
newColorTemp = tempPhysMax - tempDelta;
|
|
137269
137324
|
}
|
|
137270
|
-
|
|
137325
|
+
logger174.debug(`Synced color temperature with level: ${level}, new color temperature: ${newColorTemp}`);
|
|
137271
137326
|
return this.moveToColorTemperatureLogic(newColorTemp, 0);
|
|
137272
137327
|
}
|
|
137273
137328
|
#assertRate(mode, rate) {
|
|
@@ -137471,7 +137526,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
|
|
|
137471
137526
|
targetEnhancedColorMode = values4.enhancedColorMode;
|
|
137472
137527
|
}
|
|
137473
137528
|
if (!this.#supportsColorMode(targetEnhancedColorMode)) {
|
|
137474
|
-
|
|
137529
|
+
logger174.info(
|
|
137475
137530
|
`Can not apply scene with unsupported color mode: ${ColorControl3.EnhancedColorMode[targetEnhancedColorMode]} (${targetEnhancedColorMode})`
|
|
137476
137531
|
);
|
|
137477
137532
|
}
|
|
@@ -137513,7 +137568,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
|
|
|
137513
137568
|
}
|
|
137514
137569
|
break;
|
|
137515
137570
|
default:
|
|
137516
|
-
|
|
137571
|
+
logger174.info(
|
|
137517
137572
|
`No supported color mode found to apply scene: ${ColorControl3.EnhancedColorMode[targetEnhancedColorMode]} (${targetEnhancedColorMode})`
|
|
137518
137573
|
);
|
|
137519
137574
|
break;
|
|
@@ -137607,7 +137662,7 @@ var LevelControlBehaviorConstructor = ClusterBehavior.for(LevelControl3);
|
|
|
137607
137662
|
var LevelControlBehavior = LevelControlBehaviorConstructor;
|
|
137608
137663
|
|
|
137609
137664
|
// ../../node_modules/.pnpm/@matter+node@0.17.0/node_modules/@matter/node/dist/esm/behaviors/level-control/LevelControlServer.js
|
|
137610
|
-
var
|
|
137665
|
+
var logger175 = Logger.get("LevelControlServer");
|
|
137611
137666
|
var LevelControlBase = LevelControlBehavior.with(LevelControl3.Feature.OnOff, LevelControl3.Feature.Lighting);
|
|
137612
137667
|
var LevelControlBaseServer = class _LevelControlBaseServer extends LevelControlBase {
|
|
137613
137668
|
/** Returns the minimum level, including feature specific fallback value handling. */
|
|
@@ -137700,17 +137755,17 @@ var LevelControlBaseServer = class _LevelControlBaseServer extends LevelControlB
|
|
|
137700
137755
|
*/
|
|
137701
137756
|
initializeLighting() {
|
|
137702
137757
|
if (this.state.currentLevel === 0) {
|
|
137703
|
-
|
|
137758
|
+
logger175.warn(
|
|
137704
137759
|
`The currentLevel value of ${this.state.currentLevel} is invalid according to Matter specification. The value must not be 0.`
|
|
137705
137760
|
);
|
|
137706
137761
|
}
|
|
137707
137762
|
if (this.minLevel !== 1) {
|
|
137708
|
-
|
|
137763
|
+
logger175.warn(
|
|
137709
137764
|
`The minLevel value of ${this.minLevel} is invalid according to Matter specification. The value should be 1.`
|
|
137710
137765
|
);
|
|
137711
137766
|
}
|
|
137712
137767
|
if (this.maxLevel !== 254) {
|
|
137713
|
-
|
|
137768
|
+
logger175.warn(
|
|
137714
137769
|
`The maxLevel value of ${this.maxLevel} is invalid according to Matter specification. The value should be 254.`
|
|
137715
137770
|
);
|
|
137716
137771
|
}
|
|
@@ -138021,7 +138076,7 @@ var LevelControlBaseServer = class _LevelControlBaseServer extends LevelControlB
|
|
|
138021
138076
|
if (!onOff || this.state.onLevel === null) {
|
|
138022
138077
|
return;
|
|
138023
138078
|
}
|
|
138024
|
-
|
|
138079
|
+
logger175.debug(`OnOff changed to ON, setting level to onLevel value of ${this.state.onLevel}`);
|
|
138025
138080
|
this.state.currentLevel = this.state.onLevel;
|
|
138026
138081
|
}
|
|
138027
138082
|
#calculateEffectiveOptions(optionsMask, optionsOverride) {
|
|
@@ -141076,7 +141131,7 @@ var ModeSelectBehaviorConstructor = ClusterBehavior.for(ModeSelect3);
|
|
|
141076
141131
|
var ModeSelectBehavior = ModeSelectBehaviorConstructor;
|
|
141077
141132
|
|
|
141078
141133
|
// ../../node_modules/.pnpm/@matter+node@0.17.0/node_modules/@matter/node/dist/esm/behaviors/mode-select/ModeSelectServer.js
|
|
141079
|
-
var
|
|
141134
|
+
var logger176 = Logger.get("ModeSelectServer");
|
|
141080
141135
|
var ModeSelectBase = ModeSelectBehavior.with(ModeSelect3.Feature.OnOff);
|
|
141081
141136
|
var ModeSelectBaseServer = class extends ModeSelectBase {
|
|
141082
141137
|
initialize() {
|
|
@@ -141093,7 +141148,7 @@ var ModeSelectBaseServer = class extends ModeSelectBase {
|
|
|
141093
141148
|
}
|
|
141094
141149
|
this.reactTo(onOffServer.events.onOff$Changed, this.#handleOnOffDependency);
|
|
141095
141150
|
} else {
|
|
141096
|
-
|
|
141151
|
+
logger176.warn("OnOffServer not found on endpoint, but OnMode is set.");
|
|
141097
141152
|
}
|
|
141098
141153
|
}
|
|
141099
141154
|
if (!currentModeOverridden && this.state.startUpMode !== void 0 && this.state.startUpMode !== null && this.#getBootReason() !== GeneralDiagnostics3.BootReason.SoftwareUpdateCompleted) {
|
|
@@ -142291,7 +142346,7 @@ init_esm3();
|
|
|
142291
142346
|
|
|
142292
142347
|
// ../../node_modules/.pnpm/@matter+node@0.17.0/node_modules/@matter/node/dist/esm/behaviors/thermostat/AtomicWriteState.js
|
|
142293
142348
|
init_esm();
|
|
142294
|
-
var
|
|
142349
|
+
var logger177 = Logger.get("AtomicWriteState");
|
|
142295
142350
|
var MAXIMUM_ALLOWED_TIMEOUT = Seconds(9);
|
|
142296
142351
|
var AtomicWriteState = class {
|
|
142297
142352
|
peerAddress;
|
|
@@ -142326,19 +142381,19 @@ var AtomicWriteState = class {
|
|
|
142326
142381
|
});
|
|
142327
142382
|
}
|
|
142328
142383
|
start() {
|
|
142329
|
-
|
|
142384
|
+
logger177.debug(
|
|
142330
142385
|
`Starting atomic write state for peer ${this.peerAddress.toString()} on endpoint ${this.endpoint.id}`
|
|
142331
142386
|
);
|
|
142332
142387
|
this.#timer.start();
|
|
142333
142388
|
}
|
|
142334
142389
|
#timeoutTriggered() {
|
|
142335
|
-
|
|
142390
|
+
logger177.debug(
|
|
142336
142391
|
`Atomic write state for peer ${this.peerAddress.toString()} on endpoint ${this.endpoint.id} timed out`
|
|
142337
142392
|
);
|
|
142338
142393
|
this.close();
|
|
142339
142394
|
}
|
|
142340
142395
|
close() {
|
|
142341
|
-
|
|
142396
|
+
logger177.debug(
|
|
142342
142397
|
`Closing atomic write state for peer ${this.peerAddress.toString()} on endpoint ${this.endpoint.id}`
|
|
142343
142398
|
);
|
|
142344
142399
|
if (this.#timer.isRunning) {
|
|
@@ -142349,7 +142404,7 @@ var AtomicWriteState = class {
|
|
|
142349
142404
|
};
|
|
142350
142405
|
|
|
142351
142406
|
// ../../node_modules/.pnpm/@matter+node@0.17.0/node_modules/@matter/node/dist/esm/behaviors/thermostat/AtomicWriteHandler.js
|
|
142352
|
-
var
|
|
142407
|
+
var logger178 = Logger.get("AtomicWriteHandler");
|
|
142353
142408
|
var AtomicWriteHandler = class _AtomicWriteHandler {
|
|
142354
142409
|
#observers = new ObserverGroup();
|
|
142355
142410
|
#pendingWrites = new BasicSet();
|
|
@@ -142417,7 +142472,7 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
|
|
|
142417
142472
|
);
|
|
142418
142473
|
this.#pendingWrites.add(state);
|
|
142419
142474
|
state.closed.on(() => void this.#pendingWrites.delete(state));
|
|
142420
|
-
|
|
142475
|
+
logger178.debug("Added atomic write state:", state);
|
|
142421
142476
|
return state;
|
|
142422
142477
|
}
|
|
142423
142478
|
if (existingState === void 0) {
|
|
@@ -142484,10 +142539,10 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
|
|
|
142484
142539
|
writeAttribute(context, endpoint, cluster2, attribute, value) {
|
|
142485
142540
|
const state = this.#assertPendingWriteForAttributeAndPeer(context, endpoint, cluster2, attribute);
|
|
142486
142541
|
const attributeName = state.attributeNames.get(attribute);
|
|
142487
|
-
|
|
142542
|
+
logger178.debug(`Writing pending value for attribute ${attributeName}, ${attribute} in atomic write`, value);
|
|
142488
142543
|
endpoint.eventsOf(cluster2.id)[`${attributeName}$AtomicChanging`]?.emit(value, state.pendingAttributeValues[attribute] !== void 0 ? state.pendingAttributeValues[attribute] : state.initialValues[attribute], context);
|
|
142489
142544
|
state.pendingAttributeValues[attribute] = value;
|
|
142490
|
-
|
|
142545
|
+
logger178.debug("Atomic write state after current write:", state);
|
|
142491
142546
|
}
|
|
142492
142547
|
/**
|
|
142493
142548
|
* Implements the commit logic for an atomic write.
|
|
@@ -142506,7 +142561,7 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
|
|
|
142506
142561
|
await context.transaction?.commit();
|
|
142507
142562
|
} catch (error) {
|
|
142508
142563
|
await context.transaction?.rollback();
|
|
142509
|
-
|
|
142564
|
+
logger178.info(`Failed to write attribute ${attr} during atomic write commit: ${error}`);
|
|
142510
142565
|
statusCode = StatusResponseError.of(error)?.code ?? Status2.Failure;
|
|
142511
142566
|
commandStatusCode = commandStatusCode === Status2.Failure ? Status2.Failure : commandStatusCode === Status2.ConstraintError ? Status2.ConstraintError : Status2.Failure;
|
|
142512
142567
|
}
|
|
@@ -142542,7 +142597,7 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
|
|
|
142542
142597
|
const fabricIndex = fabric.fabricIndex;
|
|
142543
142598
|
for (const writeState of Array.from(this.#pendingWrites)) {
|
|
142544
142599
|
if (writeState.peerAddress.fabricIndex === fabricIndex) {
|
|
142545
|
-
|
|
142600
|
+
logger178.debug(
|
|
142546
142601
|
`Closing atomic write state for peer ${writeState.peerAddress.toString()} on endpoint ${writeState.endpoint.id} due to fabric removal`
|
|
142547
142602
|
);
|
|
142548
142603
|
writeState.close();
|
|
@@ -142583,7 +142638,7 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
|
|
|
142583
142638
|
if (!PeerAddress.is(attrWriteState.peerAddress, peerAddress)) {
|
|
142584
142639
|
return void 0;
|
|
142585
142640
|
}
|
|
142586
|
-
|
|
142641
|
+
logger178.debug(
|
|
142587
142642
|
`Found pending value for attribute ${attribute} for peer ${peerAddress.nodeId}`,
|
|
142588
142643
|
serialize(attrWriteState.pendingAttributeValues[attribute])
|
|
142589
142644
|
);
|
|
@@ -142624,7 +142679,7 @@ var ThermostatBehaviorConstructor = ClusterBehavior.for(Thermostat3);
|
|
|
142624
142679
|
var ThermostatBehavior = ThermostatBehaviorConstructor;
|
|
142625
142680
|
|
|
142626
142681
|
// ../../node_modules/.pnpm/@matter+node@0.17.0/node_modules/@matter/node/dist/esm/behaviors/thermostat/ThermostatServer.js
|
|
142627
|
-
var
|
|
142682
|
+
var logger179 = Logger.get("ThermostatServer");
|
|
142628
142683
|
var ThermostatBehaviorLogicBase = ThermostatBehavior.with(
|
|
142629
142684
|
Thermostat3.Feature.Heating,
|
|
142630
142685
|
Thermostat3.Feature.Cooling,
|
|
@@ -142653,7 +142708,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
142653
142708
|
throw new ImplementationError("Setback feature is deprecated and not allowed to be enabled");
|
|
142654
142709
|
}
|
|
142655
142710
|
if (this.features.matterScheduleConfiguration) {
|
|
142656
|
-
|
|
142711
|
+
logger179.warn("MatterScheduleConfiguration feature is not yet implemented. Please do not activate it");
|
|
142657
142712
|
}
|
|
142658
142713
|
if (!this.features.presets && !this.features.matterScheduleConfiguration) {
|
|
142659
142714
|
this.atomicRequest = Behavior.unimplemented;
|
|
@@ -142774,7 +142829,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
142774
142829
|
throw new StatusResponse.InvalidCommandError("Requested PresetHandle not found");
|
|
142775
142830
|
}
|
|
142776
142831
|
}
|
|
142777
|
-
|
|
142832
|
+
logger179.info(`Setting active preset handle to`, presetHandle);
|
|
142778
142833
|
this.state.activePresetHandle = presetHandle;
|
|
142779
142834
|
return preset;
|
|
142780
142835
|
}
|
|
@@ -142844,7 +142899,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
142844
142899
|
}
|
|
142845
142900
|
if (this.state.setpointHoldExpiryTimestamp === void 0) {
|
|
142846
142901
|
} else {
|
|
142847
|
-
|
|
142902
|
+
logger179.warn(
|
|
142848
142903
|
"Handling for setpointHoldExpiryTimestamp is not yet implemented. To use this attribute you need to install the needed logic yourself"
|
|
142849
142904
|
);
|
|
142850
142905
|
}
|
|
@@ -142917,7 +142972,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
142917
142972
|
"RemoteSensing cannot be set to LocalTemperature when LocalTemperatureNotExposed feature is enabled"
|
|
142918
142973
|
);
|
|
142919
142974
|
}
|
|
142920
|
-
|
|
142975
|
+
logger179.debug("LocalTemperatureNotExposed feature is enabled, ignoring local temperature measurement");
|
|
142921
142976
|
this.state.localTemperature = null;
|
|
142922
142977
|
}
|
|
142923
142978
|
let localTemperature = null;
|
|
@@ -142926,11 +142981,11 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
142926
142981
|
const endpoints = this.env.get(ServerNode).endpoints;
|
|
142927
142982
|
const endpoint = endpoints.has(localTempEndpoint) ? endpoints.for(localTempEndpoint) : void 0;
|
|
142928
142983
|
if (endpoint !== void 0 && endpoint.behaviors.has(TemperatureMeasurementServer)) {
|
|
142929
|
-
|
|
142984
|
+
logger179.debug(
|
|
142930
142985
|
`Using existing TemperatureMeasurement cluster on endpoint #${localTempEndpoint} for local temperature measurement`
|
|
142931
142986
|
);
|
|
142932
142987
|
if (this.state.externalMeasuredIndoorTemperature !== void 0) {
|
|
142933
|
-
|
|
142988
|
+
logger179.warn(
|
|
142934
142989
|
"Both local TemperatureMeasurement cluster and externalMeasuredIndoorTemperature state are set, using local cluster"
|
|
142935
142990
|
);
|
|
142936
142991
|
}
|
|
@@ -142940,19 +142995,19 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
142940
142995
|
);
|
|
142941
142996
|
localTemperature = endpoint.stateOf(TemperatureMeasurementServer).measuredValue;
|
|
142942
142997
|
} else {
|
|
142943
|
-
|
|
142998
|
+
logger179.warn(
|
|
142944
142999
|
`No TemperatureMeasurement cluster found on endpoint #${localTempEndpoint}, falling back to externalMeasuredIndoorTemperature state if set`
|
|
142945
143000
|
);
|
|
142946
143001
|
}
|
|
142947
143002
|
} else {
|
|
142948
143003
|
if (this.state.externalMeasuredIndoorTemperature === void 0) {
|
|
142949
143004
|
if (this.state.localTemperatureCalibration !== void 0) {
|
|
142950
|
-
|
|
143005
|
+
logger179.warn(
|
|
142951
143006
|
"No local TemperatureMeasurement cluster available, externalMeasuredIndoorTemperature state not set but localTemperatureCalibration is used: Ensure to correctly consider the calibration when updating the localTemperature value"
|
|
142952
143007
|
);
|
|
142953
143008
|
}
|
|
142954
143009
|
} else {
|
|
142955
|
-
|
|
143010
|
+
logger179.info("Using measured temperature via externalMeasuredIndoorTemperature state");
|
|
142956
143011
|
localTemperature = this.state.externalMeasuredIndoorTemperature ?? null;
|
|
142957
143012
|
}
|
|
142958
143013
|
this.reactTo(this.events.externalMeasuredIndoorTemperature$Changed, this.#handleMeasuredTemperatureChange);
|
|
@@ -142992,28 +143047,28 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
142992
143047
|
const endpoints = this.env.get(ServerNode).endpoints;
|
|
142993
143048
|
const endpoint = endpoints.has(localOccupancyEndpoint) ? endpoints.for(localOccupancyEndpoint) : void 0;
|
|
142994
143049
|
if (endpoint !== void 0 && endpoint.behaviors.has(OccupancySensingServer)) {
|
|
142995
|
-
|
|
143050
|
+
logger179.debug(
|
|
142996
143051
|
`Using existing OccupancySensing cluster on endpoint ${localOccupancyEndpoint} for local occupancy sensing`
|
|
142997
143052
|
);
|
|
142998
143053
|
if (this.state.externallyMeasuredOccupancy !== void 0) {
|
|
142999
|
-
|
|
143054
|
+
logger179.warn(
|
|
143000
143055
|
"Both local OccupancySensing cluster and externallyMeasuredOccupancy state are set, using local cluster"
|
|
143001
143056
|
);
|
|
143002
143057
|
}
|
|
143003
143058
|
this.reactTo(endpoint.eventsOf(OccupancySensingServer).occupancy$Changed, this.#handleOccupancyChange);
|
|
143004
143059
|
currentOccupancy = !!endpoint.stateOf(OccupancySensingServer).occupancy.occupied;
|
|
143005
143060
|
} else {
|
|
143006
|
-
|
|
143061
|
+
logger179.warn(
|
|
143007
143062
|
`No OccupancySensing cluster found on endpoint ${localOccupancyEndpoint}, falling back to externallyMeasuredOccupancy state if set`
|
|
143008
143063
|
);
|
|
143009
143064
|
}
|
|
143010
143065
|
} else {
|
|
143011
143066
|
if (this.state.externallyMeasuredOccupancy === void 0) {
|
|
143012
|
-
|
|
143067
|
+
logger179.warn(
|
|
143013
143068
|
"No local OccupancySensing cluster available and externallyMeasuredOccupancy state not set"
|
|
143014
143069
|
);
|
|
143015
143070
|
} else {
|
|
143016
|
-
|
|
143071
|
+
logger179.info("Using occupancy via externallyMeasuredOccupancy state");
|
|
143017
143072
|
currentOccupancy = this.state.externallyMeasuredOccupancy;
|
|
143018
143073
|
}
|
|
143019
143074
|
this.reactTo(this.events.externallyMeasuredOccupancy$Changed, this.#handleExternalOccupancyChange);
|
|
@@ -143280,7 +143335,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
143280
143335
|
max = this.state[`max${scope}`] ?? defaults.absMax,
|
|
143281
143336
|
absMax = this.state[`absMax${scope}`] ?? defaults.absMax
|
|
143282
143337
|
} = details;
|
|
143283
|
-
|
|
143338
|
+
logger179.debug(
|
|
143284
143339
|
`Validating user setpoint limits for ${scope}: absMin=${absMin}, min=${min}, max=${max}, absMax=${absMax}`
|
|
143285
143340
|
);
|
|
143286
143341
|
if (absMin > min) {
|
|
@@ -143327,7 +143382,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
143327
143382
|
const limitMax = scope === "Heat" ? this.heatSetpointMaximum : this.coolSetpointMaximum;
|
|
143328
143383
|
const result = cropValueRange(setpoint, limitMin, limitMax);
|
|
143329
143384
|
if (result !== setpoint) {
|
|
143330
|
-
|
|
143385
|
+
logger179.debug(
|
|
143331
143386
|
`${scope} setpoint (${setpoint}) is out of limits [${limitMin}, ${limitMax}], clamping to ${result}`
|
|
143332
143387
|
);
|
|
143333
143388
|
}
|
|
@@ -143364,7 +143419,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
143364
143419
|
const otherLimit = otherType === "Heating" ? this.heatSetpointMinimum : this.coolSetpointMaximum;
|
|
143365
143420
|
if (otherType === "Cooling") {
|
|
143366
143421
|
const minValidSetpoint = value + deadband;
|
|
143367
|
-
|
|
143422
|
+
logger179.debug(
|
|
143368
143423
|
`Ensuring deadband for ${type}${otherType}Setpoint, min valid setpoint is ${minValidSetpoint}`
|
|
143369
143424
|
);
|
|
143370
143425
|
if (otherSetpoint >= minValidSetpoint) {
|
|
@@ -143375,11 +143430,11 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
143375
143430
|
`Cannot adjust cooling setpoint to maintain deadband, would exceed max cooling setpoint (${otherLimit})`
|
|
143376
143431
|
);
|
|
143377
143432
|
}
|
|
143378
|
-
|
|
143433
|
+
logger179.debug(`Adjusting ${type}${otherType}Setpoint to ${minValidSetpoint} to maintain deadband`);
|
|
143379
143434
|
this.state[`${type}${otherType}Setpoint`] = minValidSetpoint;
|
|
143380
143435
|
} else {
|
|
143381
143436
|
const maxValidSetpoint = value - deadband;
|
|
143382
|
-
|
|
143437
|
+
logger179.debug(
|
|
143383
143438
|
`Ensuring deadband for ${type}${otherType}Setpoint, max valid setpoint is ${maxValidSetpoint}`
|
|
143384
143439
|
);
|
|
143385
143440
|
if (otherSetpoint <= maxValidSetpoint) {
|
|
@@ -143390,7 +143445,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
143390
143445
|
`Cannot adjust heating setpoint to maintain deadband, would exceed min heating setpoint (${otherLimit})`
|
|
143391
143446
|
);
|
|
143392
143447
|
}
|
|
143393
|
-
|
|
143448
|
+
logger179.debug(`Adjusting ${type}${otherType}Setpoint to ${maxValidSetpoint} to maintain deadband`);
|
|
143394
143449
|
this.state[`${type}${otherType}Setpoint`] = maxValidSetpoint;
|
|
143395
143450
|
}
|
|
143396
143451
|
}
|
|
@@ -143658,7 +143713,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
143658
143713
|
*/
|
|
143659
143714
|
#handlePersistedPresetsChanged(newPresets, oldPresets) {
|
|
143660
143715
|
if (oldPresets === void 0) {
|
|
143661
|
-
|
|
143716
|
+
logger179.debug(
|
|
143662
143717
|
"Old presets is undefined, skipping some checks. This should only happen on setup of the behavior."
|
|
143663
143718
|
);
|
|
143664
143719
|
}
|
|
@@ -143667,7 +143722,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
143667
143722
|
const newPresetHandles = /* @__PURE__ */ new Set();
|
|
143668
143723
|
for (const preset of newPresets) {
|
|
143669
143724
|
if (preset.presetHandle === null) {
|
|
143670
|
-
|
|
143725
|
+
logger179.error("Preset is missing presetHandle, generating a new one");
|
|
143671
143726
|
preset.presetHandle = entropy.randomBytes(16);
|
|
143672
143727
|
changed = true;
|
|
143673
143728
|
}
|
|
@@ -143716,7 +143771,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
|
|
|
143716
143771
|
throw new StatusResponse.InvalidInStateError(`ActivePresetHandle references non-existing presetHandle`);
|
|
143717
143772
|
}
|
|
143718
143773
|
if (changed) {
|
|
143719
|
-
|
|
143774
|
+
logger179.error("PresetHandles or BuiltIn flags were updated, updating persistedPresets");
|
|
143720
143775
|
this.state.persistedPresets = newPresets;
|
|
143721
143776
|
}
|
|
143722
143777
|
}
|
|
@@ -144776,7 +144831,7 @@ var WindowCoveringBehaviorConstructor = ClusterBehavior.for(WindowCovering3);
|
|
|
144776
144831
|
var WindowCoveringBehavior = WindowCoveringBehaviorConstructor;
|
|
144777
144832
|
|
|
144778
144833
|
// ../../node_modules/.pnpm/@matter+node@0.17.0/node_modules/@matter/node/dist/esm/behaviors/window-covering/WindowCoveringServer.js
|
|
144779
|
-
var
|
|
144834
|
+
var logger180 = Logger.get("WindowCoveringServer");
|
|
144780
144835
|
var WindowCoveringBase = WindowCoveringBehavior.with(
|
|
144781
144836
|
WindowCovering3.Feature.Lift,
|
|
144782
144837
|
WindowCovering3.Feature.Tilt,
|
|
@@ -144861,7 +144916,7 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
|
|
|
144861
144916
|
this.state.configStatus = configStatus;
|
|
144862
144917
|
});
|
|
144863
144918
|
}
|
|
144864
|
-
|
|
144919
|
+
logger180.debug(
|
|
144865
144920
|
`Mode changed to ${Diagnostic.json(mode)} and config status to ${Diagnostic.json(configStatus)} and internal calibration mode to ${this.internal.calibrationMode}`
|
|
144866
144921
|
);
|
|
144867
144922
|
}
|
|
@@ -144869,7 +144924,7 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
|
|
|
144869
144924
|
#handleOperationalStatusChanging(operationalStatus) {
|
|
144870
144925
|
const globalStatus = operationalStatus.lift !== WindowCovering3.MovementStatus.Stopped ? operationalStatus.lift : operationalStatus.tilt;
|
|
144871
144926
|
operationalStatus.global = globalStatus;
|
|
144872
|
-
|
|
144927
|
+
logger180.debug(
|
|
144873
144928
|
`Operational status changed to ${Diagnostic.json(operationalStatus)} with new global status ${globalStatus}`
|
|
144874
144929
|
);
|
|
144875
144930
|
this.state.operationalStatus = operationalStatus;
|
|
@@ -144898,10 +144953,10 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
|
|
|
144898
144953
|
this.state.currentPositionLiftPercentage = percent100ths3 === null ? percent100ths3 : Math.floor(percent100ths3 / WC_PERCENT100THS_COEFFICIENT);
|
|
144899
144954
|
if (this.state.operationalStatus.lift !== WindowCovering3.MovementStatus.Stopped && percent100ths3 === this.state.targetPositionLiftPercent100ths) {
|
|
144900
144955
|
this.state.operationalStatus.lift = WindowCovering3.MovementStatus.Stopped;
|
|
144901
|
-
|
|
144956
|
+
logger180.debug("Lift movement stopped, target value reached");
|
|
144902
144957
|
}
|
|
144903
144958
|
}
|
|
144904
|
-
|
|
144959
|
+
logger180.debug(
|
|
144905
144960
|
`Syncing lift position ${this.state.currentPositionLiftPercent100ths === null ? null : (this.state.currentPositionLiftPercent100ths / 100).toFixed(2)} to ${this.state.currentPositionLiftPercentage}%`
|
|
144906
144961
|
);
|
|
144907
144962
|
}
|
|
@@ -144911,10 +144966,10 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
|
|
|
144911
144966
|
this.state.currentPositionTiltPercentage = percent100ths3 === null ? percent100ths3 : Math.floor(percent100ths3 / WC_PERCENT100THS_COEFFICIENT);
|
|
144912
144967
|
if (this.state.operationalStatus.tilt !== WindowCovering3.MovementStatus.Stopped && percent100ths3 === this.state.targetPositionTiltPercent100ths) {
|
|
144913
144968
|
this.state.operationalStatus.tilt = WindowCovering3.MovementStatus.Stopped;
|
|
144914
|
-
|
|
144969
|
+
logger180.debug("Tilt movement stopped, target value reached");
|
|
144915
144970
|
}
|
|
144916
144971
|
}
|
|
144917
|
-
|
|
144972
|
+
logger180.debug(
|
|
144918
144973
|
`Syncing tilt position ${this.state.currentPositionTiltPercent100ths === null ? null : (this.state.currentPositionTiltPercent100ths / 100).toFixed(2)} to ${this.state.currentPositionTiltPercentage}%`
|
|
144919
144974
|
);
|
|
144920
144975
|
}
|
|
@@ -145002,7 +145057,7 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
|
|
|
145002
145057
|
}
|
|
145003
145058
|
const directionInfo = direction === 2 ? ` in direction by position` : ` in direction ${direction === 1 ? "Close" : "Open"}`;
|
|
145004
145059
|
const targetInfo = targetPercent100ths === void 0 ? "" : ` to target position ${(targetPercent100ths / 100).toFixed(2)}`;
|
|
145005
|
-
|
|
145060
|
+
logger180.debug(
|
|
145006
145061
|
`Moving the device ${type === 0 ? "Lift" : "Tilt"}${directionInfo} (reversed=${reversed})${targetInfo}`
|
|
145007
145062
|
);
|
|
145008
145063
|
}
|
|
@@ -145024,7 +145079,7 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
|
|
|
145024
145079
|
);
|
|
145025
145080
|
}
|
|
145026
145081
|
if (type === 0 && this.state.configStatus.liftMovementReversed) {
|
|
145027
|
-
|
|
145082
|
+
logger180.debug("Lift movement is reversed");
|
|
145028
145083
|
}
|
|
145029
145084
|
switch (type) {
|
|
145030
145085
|
case 0:
|
|
@@ -145270,7 +145325,7 @@ function trimToLength(value, maxLength, suffix) {
|
|
|
145270
145325
|
}
|
|
145271
145326
|
|
|
145272
145327
|
// src/matter/endpoints/server-mode-server-node.ts
|
|
145273
|
-
var
|
|
145328
|
+
var logger181 = Logger.get("ServerModeServerNode");
|
|
145274
145329
|
var ServerModeServerNode = class extends ServerNode {
|
|
145275
145330
|
deviceEndpoint;
|
|
145276
145331
|
featureFlags;
|
|
@@ -145356,7 +145411,7 @@ var ServerModeServerNode = class extends ServerNode {
|
|
|
145356
145411
|
await this.set({ basicInformation });
|
|
145357
145412
|
} catch (e) {
|
|
145358
145413
|
const msg = e instanceof Error ? e.message : String(e);
|
|
145359
|
-
|
|
145414
|
+
logger181.warn(
|
|
145360
145415
|
`Failed to apply server-mode identity for ${entityId}: ${msg}`
|
|
145361
145416
|
);
|
|
145362
145417
|
}
|
|
@@ -145367,7 +145422,7 @@ var ServerModeServerNode = class extends ServerNode {
|
|
|
145367
145422
|
await this.set({ productDescription: { deviceType } });
|
|
145368
145423
|
} catch (e) {
|
|
145369
145424
|
const msg = e instanceof Error ? e.message : String(e);
|
|
145370
|
-
|
|
145425
|
+
logger181.warn(`Failed to set server-mode device type: ${msg}`);
|
|
145371
145426
|
}
|
|
145372
145427
|
}
|
|
145373
145428
|
async factoryReset() {
|
|
@@ -145454,7 +145509,7 @@ init_basic_information2();
|
|
|
145454
145509
|
init_descriptor2();
|
|
145455
145510
|
init_aggregator();
|
|
145456
145511
|
init_esm();
|
|
145457
|
-
var
|
|
145512
|
+
var logger182 = Logger.get("BridgedDeviceBasicInformationServer");
|
|
145458
145513
|
var BridgedDeviceBasicInformationServer = class extends BridgedDeviceBasicInformationBehavior {
|
|
145459
145514
|
async initialize() {
|
|
145460
145515
|
if (this.endpoint.lifecycle.isInstalled) {
|
|
@@ -145468,7 +145523,7 @@ var BridgedDeviceBasicInformationServer = class extends BridgedDeviceBasicInform
|
|
|
145468
145523
|
if (uniqueId === void 0) {
|
|
145469
145524
|
this.state.uniqueId = BasicInformationServer.createUniqueId();
|
|
145470
145525
|
}
|
|
145471
|
-
validateBasicInfoAttributes(this.state,
|
|
145526
|
+
validateBasicInfoAttributes(this.state, logger182);
|
|
145472
145527
|
}
|
|
145473
145528
|
static schema = BasicInformationServer.enableUniqueIdPersistence(
|
|
145474
145529
|
BridgedDeviceBasicInformationBehavior.schema
|
|
@@ -146171,7 +146226,7 @@ var IdentifyServer2 = class extends IdentifyServer {
|
|
|
146171
146226
|
// src/matter/endpoints/validate-endpoint-type.ts
|
|
146172
146227
|
init_esm();
|
|
146173
146228
|
init_esm7();
|
|
146174
|
-
var
|
|
146229
|
+
var logger183 = Logger.get("EndpointValidation");
|
|
146175
146230
|
function toCamelCase(name) {
|
|
146176
146231
|
return name.charAt(0).toLowerCase() + name.slice(1);
|
|
146177
146232
|
}
|
|
@@ -146201,12 +146256,12 @@ function validateEndpointType(endpointType, entityId) {
|
|
|
146201
146256
|
}
|
|
146202
146257
|
const prefix = entityId ? `[${entityId}] ` : "";
|
|
146203
146258
|
if (missingMandatory.length > 0) {
|
|
146204
|
-
|
|
146259
|
+
logger183.warn(
|
|
146205
146260
|
`${prefix}${deviceTypeModel.name} (0x${endpointType.deviceType.toString(16)}): missing mandatory clusters: ${missingMandatory.join(", ")}`
|
|
146206
146261
|
);
|
|
146207
146262
|
}
|
|
146208
146263
|
if (availableOptional.length > 0) {
|
|
146209
|
-
|
|
146264
|
+
logger183.debug(
|
|
146210
146265
|
`${prefix}${deviceTypeModel.name} (0x${endpointType.deviceType.toString(16)}): optional clusters not used: ${availableOptional.join(", ")}`
|
|
146211
146266
|
);
|
|
146212
146267
|
}
|
|
@@ -146319,7 +146374,7 @@ var BridgeDataProvider = class extends Service {
|
|
|
146319
146374
|
|
|
146320
146375
|
// src/utils/apply-patch-state.ts
|
|
146321
146376
|
init_esm();
|
|
146322
|
-
var
|
|
146377
|
+
var logger184 = Logger.get("ApplyPatchState");
|
|
146323
146378
|
function applyPatchState(state, patch, options) {
|
|
146324
146379
|
return applyPatch(state, patch, options?.force);
|
|
146325
146380
|
}
|
|
@@ -146346,23 +146401,23 @@ function applyPatch(state, patch, force = false) {
|
|
|
146346
146401
|
if (errorMessage.includes(
|
|
146347
146402
|
"Endpoint storage inaccessible because endpoint is not a node and is not owned by another endpoint"
|
|
146348
146403
|
)) {
|
|
146349
|
-
|
|
146404
|
+
logger184.debug(
|
|
146350
146405
|
`Suppressed endpoint storage error, patch not applied: ${JSON.stringify(actualPatch)}`
|
|
146351
146406
|
);
|
|
146352
146407
|
return actualPatch;
|
|
146353
146408
|
}
|
|
146354
146409
|
if (errorMessage.includes("synchronous-transaction-conflict")) {
|
|
146355
|
-
|
|
146410
|
+
logger184.warn(
|
|
146356
146411
|
`Transaction conflict, state update DROPPED: ${JSON.stringify(actualPatch)}`
|
|
146357
146412
|
);
|
|
146358
146413
|
return actualPatch;
|
|
146359
146414
|
}
|
|
146360
146415
|
failedKeys.push(key);
|
|
146361
|
-
|
|
146416
|
+
logger184.warn(`Failed to set property '${key}': ${errorMessage}`);
|
|
146362
146417
|
}
|
|
146363
146418
|
}
|
|
146364
146419
|
if (failedKeys.length > 0) {
|
|
146365
|
-
|
|
146420
|
+
logger184.warn(
|
|
146366
146421
|
`${failedKeys.length} properties failed to update: [${failedKeys.join(", ")}]`
|
|
146367
146422
|
);
|
|
146368
146423
|
}
|
|
@@ -146432,7 +146487,7 @@ function truncate(maxLength, value) {
|
|
|
146432
146487
|
}
|
|
146433
146488
|
|
|
146434
146489
|
// src/plugins/plugin-device-factory.ts
|
|
146435
|
-
var
|
|
146490
|
+
var logger185 = Logger.get("PluginDeviceFactory");
|
|
146436
146491
|
var deviceTypeMap = {
|
|
146437
146492
|
on_off_light: () => OnOffLightDevice.with(
|
|
146438
146493
|
IdentifyServer2,
|
|
@@ -146538,7 +146593,7 @@ var deviceTypeMap = {
|
|
|
146538
146593
|
function createPluginEndpointType(deviceType) {
|
|
146539
146594
|
const factory = deviceTypeMap[deviceType];
|
|
146540
146595
|
if (!factory) {
|
|
146541
|
-
|
|
146596
|
+
logger185.warn(`Unsupported plugin device type: "${deviceType}"`);
|
|
146542
146597
|
return void 0;
|
|
146543
146598
|
}
|
|
146544
146599
|
const endpoint = factory();
|
|
@@ -146553,7 +146608,7 @@ function getSupportedPluginDeviceTypes() {
|
|
|
146553
146608
|
init_esm();
|
|
146554
146609
|
import * as fs9 from "node:fs";
|
|
146555
146610
|
import * as path11 from "node:path";
|
|
146556
|
-
var
|
|
146611
|
+
var logger186 = Logger.get("PluginStorage");
|
|
146557
146612
|
var SAVE_DEBOUNCE_MS = 500;
|
|
146558
146613
|
var FilePluginStorage = class {
|
|
146559
146614
|
data = {};
|
|
@@ -146589,7 +146644,7 @@ var FilePluginStorage = class {
|
|
|
146589
146644
|
this.data = JSON.parse(raw);
|
|
146590
146645
|
}
|
|
146591
146646
|
} catch (e) {
|
|
146592
|
-
|
|
146647
|
+
logger186.warn(`Failed to load plugin storage from ${this.filePath}:`, e);
|
|
146593
146648
|
this.data = {};
|
|
146594
146649
|
}
|
|
146595
146650
|
}
|
|
@@ -146611,7 +146666,7 @@ var FilePluginStorage = class {
|
|
|
146611
146666
|
fs9.writeFileSync(this.filePath, JSON.stringify(this.data, null, 2));
|
|
146612
146667
|
this.dirty = false;
|
|
146613
146668
|
} catch (e) {
|
|
146614
|
-
|
|
146669
|
+
logger186.warn(`Failed to save plugin storage to ${this.filePath}:`, e);
|
|
146615
146670
|
}
|
|
146616
146671
|
}
|
|
146617
146672
|
flush() {
|
|
@@ -146621,7 +146676,7 @@ var FilePluginStorage = class {
|
|
|
146621
146676
|
|
|
146622
146677
|
// src/plugins/safe-plugin-runner.ts
|
|
146623
146678
|
init_esm();
|
|
146624
|
-
var
|
|
146679
|
+
var logger187 = Logger.get("SafePluginRunner");
|
|
146625
146680
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
146626
146681
|
var CIRCUIT_BREAKER_THRESHOLD = 3;
|
|
146627
146682
|
var SafePluginRunner = class {
|
|
@@ -146654,7 +146709,7 @@ var SafePluginRunner = class {
|
|
|
146654
146709
|
async run(pluginName, operation, fn, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
146655
146710
|
const state = this.getState(pluginName);
|
|
146656
146711
|
if (state.disabled) {
|
|
146657
|
-
|
|
146712
|
+
logger187.debug(
|
|
146658
146713
|
`Plugin "${pluginName}" is disabled (circuit breaker open), skipping ${operation}`
|
|
146659
146714
|
);
|
|
146660
146715
|
return void 0;
|
|
@@ -146672,13 +146727,13 @@ var SafePluginRunner = class {
|
|
|
146672
146727
|
timeout.clear();
|
|
146673
146728
|
state.failures++;
|
|
146674
146729
|
state.lastError = error instanceof Error ? error.message : String(error);
|
|
146675
|
-
|
|
146730
|
+
logger187.error(
|
|
146676
146731
|
`Plugin "${pluginName}" failed during ${operation} (failure ${state.failures}/${CIRCUIT_BREAKER_THRESHOLD}): ${state.lastError}`
|
|
146677
146732
|
);
|
|
146678
146733
|
if (state.failures >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
146679
146734
|
state.disabled = true;
|
|
146680
146735
|
state.disabledAt = Date.now();
|
|
146681
|
-
|
|
146736
|
+
logger187.error(
|
|
146682
146737
|
`Plugin "${pluginName}" DISABLED after ${CIRCUIT_BREAKER_THRESHOLD} consecutive failures. Last error: ${state.lastError}`
|
|
146683
146738
|
);
|
|
146684
146739
|
}
|
|
@@ -146700,13 +146755,13 @@ var SafePluginRunner = class {
|
|
|
146700
146755
|
} catch (error) {
|
|
146701
146756
|
state.failures++;
|
|
146702
146757
|
state.lastError = error instanceof Error ? error.message : String(error);
|
|
146703
|
-
|
|
146758
|
+
logger187.error(
|
|
146704
146759
|
`Plugin "${pluginName}" failed during ${operation} (sync, failure ${state.failures}/${CIRCUIT_BREAKER_THRESHOLD}): ${state.lastError}`
|
|
146705
146760
|
);
|
|
146706
146761
|
if (state.failures >= CIRCUIT_BREAKER_THRESHOLD) {
|
|
146707
146762
|
state.disabled = true;
|
|
146708
146763
|
state.disabledAt = Date.now();
|
|
146709
|
-
|
|
146764
|
+
logger187.error(
|
|
146710
146765
|
`Plugin "${pluginName}" DISABLED after ${CIRCUIT_BREAKER_THRESHOLD} consecutive failures.`
|
|
146711
146766
|
);
|
|
146712
146767
|
}
|
|
@@ -146732,7 +146787,7 @@ var SafePluginRunner = class {
|
|
|
146732
146787
|
};
|
|
146733
146788
|
|
|
146734
146789
|
// src/plugins/plugin-manager.ts
|
|
146735
|
-
var
|
|
146790
|
+
var logger188 = Logger.get("PluginManager");
|
|
146736
146791
|
var PLUGIN_API_VERSION = 1;
|
|
146737
146792
|
var MAX_PLUGIN_DEVICE_ID_LENGTH = 100;
|
|
146738
146793
|
function validatePluginDevice(device) {
|
|
@@ -146815,7 +146870,7 @@ var PluginManager = class {
|
|
|
146815
146870
|
throw new Error(`Plugin at ${packagePath} package.json missing "main"`);
|
|
146816
146871
|
}
|
|
146817
146872
|
if (manifest.hamhPluginApiVersion != null && manifest.hamhPluginApiVersion !== PLUGIN_API_VERSION) {
|
|
146818
|
-
|
|
146873
|
+
logger188.warn(
|
|
146819
146874
|
`Plugin "${manifest.name}" declares API version ${manifest.hamhPluginApiVersion}, current is ${PLUGIN_API_VERSION}. It may not work correctly.`
|
|
146820
146875
|
);
|
|
146821
146876
|
}
|
|
@@ -146846,7 +146901,7 @@ var PluginManager = class {
|
|
|
146846
146901
|
};
|
|
146847
146902
|
await this.register(plugin, metadata);
|
|
146848
146903
|
} catch (e) {
|
|
146849
|
-
|
|
146904
|
+
logger188.error(`Failed to load external plugin from ${packagePath}:`, e);
|
|
146850
146905
|
throw e;
|
|
146851
146906
|
}
|
|
146852
146907
|
}
|
|
@@ -146923,7 +146978,7 @@ var PluginManager = class {
|
|
|
146923
146978
|
devices,
|
|
146924
146979
|
started: false
|
|
146925
146980
|
});
|
|
146926
|
-
|
|
146981
|
+
logger188.info(
|
|
146927
146982
|
`Registered plugin: ${plugin.name} v${plugin.version} (${metadata.source})`
|
|
146928
146983
|
);
|
|
146929
146984
|
}
|
|
@@ -146934,13 +146989,13 @@ var PluginManager = class {
|
|
|
146934
146989
|
for (const [name, instance] of this.instances) {
|
|
146935
146990
|
if (!instance.metadata.enabled) continue;
|
|
146936
146991
|
if (this.runner.isDisabled(name)) {
|
|
146937
|
-
|
|
146992
|
+
logger188.warn(
|
|
146938
146993
|
`Plugin "${name}" is disabled (circuit breaker), skipping start`
|
|
146939
146994
|
);
|
|
146940
146995
|
instance.metadata.enabled = false;
|
|
146941
146996
|
continue;
|
|
146942
146997
|
}
|
|
146943
|
-
|
|
146998
|
+
logger188.info(`Starting plugin: ${name}`);
|
|
146944
146999
|
await this.runner.run(
|
|
146945
147000
|
name,
|
|
146946
147001
|
"onStart",
|
|
@@ -146988,7 +147043,7 @@ var PluginManager = class {
|
|
|
146988
147043
|
storage2.flush();
|
|
146989
147044
|
}
|
|
146990
147045
|
instance.started = false;
|
|
146991
|
-
|
|
147046
|
+
logger188.info(`Plugin "${name}" shut down`);
|
|
146992
147047
|
}
|
|
146993
147048
|
this.instances.clear();
|
|
146994
147049
|
}
|
|
@@ -147398,13 +147453,37 @@ function ensureCommissioningConfig(server) {
|
|
|
147398
147453
|
|
|
147399
147454
|
// src/services/bridges/bridge.ts
|
|
147400
147455
|
init_diagnostic_event_bus();
|
|
147456
|
+
|
|
147457
|
+
// src/services/bridges/session-rotation.ts
|
|
147458
|
+
var DEFAULT_SESSION_MAX_AGE_HOURS = 4;
|
|
147459
|
+
var SESSION_MAX_AGE_HOURS_RANGE = { min: 1, max: 168 };
|
|
147460
|
+
var ROTATION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
147461
|
+
function parseSessionMaxAgeHours(raw) {
|
|
147462
|
+
if (raw == null || raw === "") return DEFAULT_SESSION_MAX_AGE_HOURS;
|
|
147463
|
+
const n = Number.parseInt(raw, 10);
|
|
147464
|
+
if (Number.isNaN(n) || n < 0) return null;
|
|
147465
|
+
if (n === 0) return 0;
|
|
147466
|
+
const { min, max } = SESSION_MAX_AGE_HOURS_RANGE;
|
|
147467
|
+
if (n < min) return min;
|
|
147468
|
+
if (n > max) return max;
|
|
147469
|
+
return n;
|
|
147470
|
+
}
|
|
147471
|
+
function seedExistingSessionStarts(startedAt, sessions, now = Date.now()) {
|
|
147472
|
+
for (const session of sessions) {
|
|
147473
|
+
if (!startedAt.has(session.id)) {
|
|
147474
|
+
startedAt.set(session.id, now);
|
|
147475
|
+
}
|
|
147476
|
+
}
|
|
147477
|
+
}
|
|
147478
|
+
|
|
147479
|
+
// src/services/bridges/bridge.ts
|
|
147401
147480
|
var AUTO_FORCE_SYNC_INTERVAL_MS = 9e4;
|
|
147402
147481
|
var DEAD_SESSION_TIMEOUT_MS = 6e4;
|
|
147403
147482
|
var Bridge = class {
|
|
147404
|
-
constructor(env,
|
|
147483
|
+
constructor(env, logger231, dataProvider, endpointManager) {
|
|
147405
147484
|
this.dataProvider = dataProvider;
|
|
147406
147485
|
this.endpointManager = endpointManager;
|
|
147407
|
-
this.log =
|
|
147486
|
+
this.log = logger231.get(`Bridge / ${dataProvider.id}`);
|
|
147408
147487
|
this.server = new BridgeServerNode(
|
|
147409
147488
|
env,
|
|
147410
147489
|
this.dataProvider,
|
|
@@ -147436,6 +147515,11 @@ var Bridge = class {
|
|
|
147436
147515
|
autoForceSyncTimer = null;
|
|
147437
147516
|
deadSessionTimer = null;
|
|
147438
147517
|
staleSessionTimers = /* @__PURE__ */ new Map();
|
|
147518
|
+
// Age-based session rotation (#287): track when each session opened so an
|
|
147519
|
+
// aged controller session can be rotated, forcing it to re-subscribe.
|
|
147520
|
+
sessionStartedAt = /* @__PURE__ */ new Map();
|
|
147521
|
+
rotationTimer = null;
|
|
147522
|
+
maxSessionAgeMs = 0;
|
|
147439
147523
|
// Serialize concurrent lifecycle calls so auto-recovery and a manual
|
|
147440
147524
|
// restartBridge can't race past each other's Starting/Stopping states.
|
|
147441
147525
|
startInFlight;
|
|
@@ -147588,6 +147672,7 @@ var Bridge = class {
|
|
|
147588
147672
|
});
|
|
147589
147673
|
}
|
|
147590
147674
|
this.wireSessionDiagnostics();
|
|
147675
|
+
this.startSessionRotation();
|
|
147591
147676
|
logMemoryUsage(this.log, "bridge running");
|
|
147592
147677
|
diagnosticEventBus.emit("bridge_started", `Bridge started`, {
|
|
147593
147678
|
bridgeId: this.id,
|
|
@@ -147645,6 +147730,7 @@ ${e?.toString()}`);
|
|
|
147645
147730
|
wireSessionDiagnostics() {
|
|
147646
147731
|
try {
|
|
147647
147732
|
const sessionManager = this.server.env.get(SessionManager);
|
|
147733
|
+
seedExistingSessionStarts(this.sessionStartedAt, sessionManager.sessions);
|
|
147648
147734
|
this.sessionDiagHandler = (session) => {
|
|
147649
147735
|
const sessions = [...sessionManager.sessions];
|
|
147650
147736
|
let totalSubs = 0;
|
|
@@ -147703,6 +147789,7 @@ ${e?.toString()}`);
|
|
|
147703
147789
|
};
|
|
147704
147790
|
sessionManager.subscriptionsChanged.on(this.sessionDiagHandler);
|
|
147705
147791
|
this.sessionAddedHandler = (newSession) => {
|
|
147792
|
+
this.sessionStartedAt.set(newSession.id, Date.now());
|
|
147706
147793
|
this.log.info(
|
|
147707
147794
|
`Session opened: id=${newSession.id} peer=${newSession.peerNodeId}`
|
|
147708
147795
|
);
|
|
@@ -147728,6 +147815,7 @@ ${e?.toString()}`);
|
|
|
147728
147815
|
}
|
|
147729
147816
|
};
|
|
147730
147817
|
this.sessionDeletedHandler = (session) => {
|
|
147818
|
+
this.sessionStartedAt.delete(session.id);
|
|
147731
147819
|
const sessions = [...sessionManager.sessions];
|
|
147732
147820
|
this.log.warn(
|
|
147733
147821
|
`Session closed: id=${session.id} peer=${session.peerNodeId} | remaining sessions=${sessions.length}`
|
|
@@ -147835,6 +147923,8 @@ ${e?.toString()}`);
|
|
|
147835
147923
|
clearTimeout(timer);
|
|
147836
147924
|
}
|
|
147837
147925
|
this.staleSessionTimers.clear();
|
|
147926
|
+
this.stopSessionRotation();
|
|
147927
|
+
this.sessionStartedAt.clear();
|
|
147838
147928
|
}
|
|
147839
147929
|
stopAutoForceSync() {
|
|
147840
147930
|
if (this.autoForceSyncTimer) {
|
|
@@ -147842,12 +147932,100 @@ ${e?.toString()}`);
|
|
|
147842
147932
|
this.autoForceSyncTimer = null;
|
|
147843
147933
|
}
|
|
147844
147934
|
}
|
|
147935
|
+
// Start periodic age-based session rotation (#287). Aging out a controller's
|
|
147936
|
+
// session forces it to re-establish and re-subscribe, recovering a wedged
|
|
147937
|
+
// Alexa subscription that would otherwise stay stuck until a restart.
|
|
147938
|
+
startSessionRotation() {
|
|
147939
|
+
this.stopSessionRotation();
|
|
147940
|
+
const hours = this.readSessionMaxAgeHours();
|
|
147941
|
+
if (hours === 0) {
|
|
147942
|
+
this.log.info(
|
|
147943
|
+
"Session rotation disabled (HAMH_MATTER_SESSION_MAX_AGE_HOURS=0)"
|
|
147944
|
+
);
|
|
147945
|
+
return;
|
|
147946
|
+
}
|
|
147947
|
+
this.maxSessionAgeMs = hours * 60 * 60 * 1e3;
|
|
147948
|
+
this.rotationTimer = setInterval(
|
|
147949
|
+
() => this.rotateAgedSessions(),
|
|
147950
|
+
ROTATION_CHECK_INTERVAL_MS
|
|
147951
|
+
);
|
|
147952
|
+
this.log.info(
|
|
147953
|
+
`Session rotation: max age ${hours}h, check every ${ROTATION_CHECK_INTERVAL_MS / 6e4}min`
|
|
147954
|
+
);
|
|
147955
|
+
}
|
|
147956
|
+
stopSessionRotation() {
|
|
147957
|
+
if (this.rotationTimer) {
|
|
147958
|
+
clearInterval(this.rotationTimer);
|
|
147959
|
+
this.rotationTimer = null;
|
|
147960
|
+
}
|
|
147961
|
+
}
|
|
147962
|
+
// Resolve the rotation max age. Bridge config wins, then the env var. An
|
|
147963
|
+
// aggregator bridge holds many devices on one controller session, so
|
|
147964
|
+
// rotating it re-subscribes them all at once. Rotation is therefore opt-in
|
|
147965
|
+
// here: it stays disabled unless set via config or the env var.
|
|
147966
|
+
readSessionMaxAgeHours() {
|
|
147967
|
+
const { min, max } = SESSION_MAX_AGE_HOURS_RANGE;
|
|
147968
|
+
const fromConfig = this.dataProvider.sessionMaxAgeHours;
|
|
147969
|
+
if (fromConfig != null && Number.isFinite(fromConfig) && fromConfig >= 0) {
|
|
147970
|
+
if (fromConfig === 0) return 0;
|
|
147971
|
+
if (fromConfig < min) return min;
|
|
147972
|
+
if (fromConfig > max) return max;
|
|
147973
|
+
return fromConfig;
|
|
147974
|
+
}
|
|
147975
|
+
const raw = process.env.HAMH_MATTER_SESSION_MAX_AGE_HOURS;
|
|
147976
|
+
if (raw == null || raw === "") {
|
|
147977
|
+
return 0;
|
|
147978
|
+
}
|
|
147979
|
+
const parsed = parseSessionMaxAgeHours(raw);
|
|
147980
|
+
if (parsed == null) {
|
|
147981
|
+
this.log.warn(
|
|
147982
|
+
`Invalid HAMH_MATTER_SESSION_MAX_AGE_HOURS=${raw}, disabling session rotation`
|
|
147983
|
+
);
|
|
147984
|
+
return 0;
|
|
147985
|
+
}
|
|
147986
|
+
return parsed;
|
|
147987
|
+
}
|
|
147988
|
+
// Gracefully close sessions older than maxSessionAgeMs that still hold
|
|
147989
|
+
// subscriptions, so the controller re-establishes CASE and re-subscribes.
|
|
147990
|
+
// 0-sub sessions are handled by the dead/stale-session path.
|
|
147991
|
+
rotateAgedSessions() {
|
|
147992
|
+
if (this.maxSessionAgeMs === 0) return;
|
|
147993
|
+
try {
|
|
147994
|
+
const sessionManager = this.server.env.get(SessionManager);
|
|
147995
|
+
const now = Date.now();
|
|
147996
|
+
const closes = [];
|
|
147997
|
+
for (const s of [...sessionManager.sessions]) {
|
|
147998
|
+
const startedAt = this.sessionStartedAt.get(s.id);
|
|
147999
|
+
if (startedAt == null) continue;
|
|
148000
|
+
const ageMs = now - startedAt;
|
|
148001
|
+
if (ageMs < this.maxSessionAgeMs || s.isClosing || s.subscriptions.size === 0) {
|
|
148002
|
+
continue;
|
|
148003
|
+
}
|
|
148004
|
+
const ageMin = Math.round(ageMs / 6e4);
|
|
148005
|
+
this.log.info(
|
|
148006
|
+
`Rotating session ${s.id} (peer ${s.peerNodeId}, age ${ageMin}min, subs ${s.subscriptions.size})`
|
|
148007
|
+
);
|
|
148008
|
+
closes.push(
|
|
148009
|
+
s.initiateClose().catch(() => {
|
|
148010
|
+
return s.initiateForceClose({
|
|
148011
|
+
cause: new Error("session rotation, forcing")
|
|
148012
|
+
});
|
|
148013
|
+
})
|
|
148014
|
+
);
|
|
148015
|
+
}
|
|
148016
|
+
if (closes.length > 0) {
|
|
148017
|
+
Promise.allSettled(closes).then(() => this.triggerMdnsReAnnounce());
|
|
148018
|
+
}
|
|
148019
|
+
} catch {
|
|
148020
|
+
}
|
|
148021
|
+
}
|
|
147845
148022
|
async update(update) {
|
|
147846
148023
|
try {
|
|
147847
148024
|
this.dataProvider.update(update);
|
|
147848
148025
|
await this.refreshDevices();
|
|
147849
148026
|
if (this.status.code === BridgeStatus.Running) {
|
|
147850
148027
|
this.startAutoForceSyncIfEnabled();
|
|
148028
|
+
this.startSessionRotation();
|
|
147851
148029
|
}
|
|
147852
148030
|
} catch (e) {
|
|
147853
148031
|
const reason = "Failed to update bridge due to error:";
|
|
@@ -148322,7 +148500,7 @@ init_wi_fi_network_diagnostics();
|
|
|
148322
148500
|
|
|
148323
148501
|
// src/matter/behaviors/electrical-energy-measurement-server.ts
|
|
148324
148502
|
init_home_assistant_entity_behavior();
|
|
148325
|
-
var
|
|
148503
|
+
var logger189 = Logger.get("ElectricalEnergyMeasurementServer");
|
|
148326
148504
|
var FeaturedBase = ElectricalEnergyMeasurementServer.with("CumulativeEnergy", "ImportedEnergy");
|
|
148327
148505
|
var ElectricalEnergyMeasurementServerBase = class extends FeaturedBase {
|
|
148328
148506
|
async initialize() {
|
|
@@ -148331,7 +148509,7 @@ var ElectricalEnergyMeasurementServerBase = class extends FeaturedBase {
|
|
|
148331
148509
|
const entityId = homeAssistant.entityId;
|
|
148332
148510
|
const energyEntity = homeAssistant.state.mapping?.energyEntity;
|
|
148333
148511
|
if (energyEntity) {
|
|
148334
|
-
|
|
148512
|
+
logger189.debug(
|
|
148335
148513
|
`[${entityId}] ElectricalEnergyMeasurement using mapped energy entity: ${energyEntity}`
|
|
148336
148514
|
);
|
|
148337
148515
|
}
|
|
@@ -148387,7 +148565,7 @@ var HaElectricalEnergyMeasurementServer = ElectricalEnergyMeasurementServerBase.
|
|
|
148387
148565
|
// src/matter/behaviors/electrical-power-measurement-server.ts
|
|
148388
148566
|
init_esm();
|
|
148389
148567
|
init_home_assistant_entity_behavior();
|
|
148390
|
-
var
|
|
148568
|
+
var logger190 = Logger.get("ElectricalPowerMeasurementServer");
|
|
148391
148569
|
var ElectricalPowerMeasurementServerBase = class extends ElectricalPowerMeasurementServer {
|
|
148392
148570
|
async initialize() {
|
|
148393
148571
|
await super.initialize();
|
|
@@ -148395,7 +148573,7 @@ var ElectricalPowerMeasurementServerBase = class extends ElectricalPowerMeasurem
|
|
|
148395
148573
|
const entityId = homeAssistant.entityId;
|
|
148396
148574
|
const powerEntity = homeAssistant.state.mapping?.powerEntity;
|
|
148397
148575
|
if (powerEntity) {
|
|
148398
|
-
|
|
148576
|
+
logger190.debug(
|
|
148399
148577
|
`[${entityId}] ElectricalPowerMeasurement using mapped power entity: ${powerEntity}`
|
|
148400
148578
|
);
|
|
148401
148579
|
}
|
|
@@ -148447,7 +148625,7 @@ init_home_assistant_entity_behavior();
|
|
|
148447
148625
|
// src/matter/behaviors/humidity-measurement-server.ts
|
|
148448
148626
|
init_esm();
|
|
148449
148627
|
init_home_assistant_entity_behavior();
|
|
148450
|
-
var
|
|
148628
|
+
var logger191 = Logger.get("HumidityMeasurementServer");
|
|
148451
148629
|
var HumidityMeasurementServerBase = class extends RelativeHumidityMeasurementServer {
|
|
148452
148630
|
async initialize() {
|
|
148453
148631
|
await super.initialize();
|
|
@@ -148460,7 +148638,7 @@ var HumidityMeasurementServerBase = class extends RelativeHumidityMeasurementSer
|
|
|
148460
148638
|
return;
|
|
148461
148639
|
}
|
|
148462
148640
|
const humidity = this.getHumidity(this.state.config, entity.state);
|
|
148463
|
-
|
|
148641
|
+
logger191.debug(
|
|
148464
148642
|
`Humidity ${entity.state.entity_id} raw=${entity.state.state} measuredValue=${humidity}`
|
|
148465
148643
|
);
|
|
148466
148644
|
applyPatchState(this.state, {
|
|
@@ -148490,7 +148668,7 @@ function HumidityMeasurementServer(config11) {
|
|
|
148490
148668
|
// src/matter/behaviors/power-source-server.ts
|
|
148491
148669
|
init_esm();
|
|
148492
148670
|
init_home_assistant_entity_behavior();
|
|
148493
|
-
var
|
|
148671
|
+
var logger192 = Logger.get("PowerSourceServer");
|
|
148494
148672
|
var FeaturedBase2 = PowerSourceServer.with("Battery", "Rechargeable");
|
|
148495
148673
|
var PowerSourceServerBase = class extends FeaturedBase2 {
|
|
148496
148674
|
async initialize() {
|
|
@@ -148502,17 +148680,17 @@ var PowerSourceServerBase = class extends FeaturedBase2 {
|
|
|
148502
148680
|
applyPatchState(this.state, {
|
|
148503
148681
|
endpointList: [endpointNumber]
|
|
148504
148682
|
});
|
|
148505
|
-
|
|
148683
|
+
logger192.debug(
|
|
148506
148684
|
`[${entityId}] PowerSource initialized with endpointList=[${endpointNumber}]`
|
|
148507
148685
|
);
|
|
148508
148686
|
} else {
|
|
148509
|
-
|
|
148687
|
+
logger192.warn(
|
|
148510
148688
|
`[${entityId}] PowerSource endpoint number is null during initialize - endpointList will be empty!`
|
|
148511
148689
|
);
|
|
148512
148690
|
}
|
|
148513
148691
|
const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
|
|
148514
148692
|
if (batteryEntity) {
|
|
148515
|
-
|
|
148693
|
+
logger192.debug(
|
|
148516
148694
|
`[${entityId}] PowerSource using mapped battery entity: ${batteryEntity}`
|
|
148517
148695
|
);
|
|
148518
148696
|
}
|
|
@@ -148924,7 +149102,7 @@ function notifyLightTurnedOn(entityId) {
|
|
|
148924
149102
|
sweepLastTurnOn(now);
|
|
148925
149103
|
lastTurnOnTimestamps.set(entityId, now);
|
|
148926
149104
|
}
|
|
148927
|
-
var
|
|
149105
|
+
var logger193 = Logger.get("LevelControlServer");
|
|
148928
149106
|
var FeaturedBase4 = LevelControlServer.with("OnOff", "Lighting");
|
|
148929
149107
|
var LevelControlServerBase = class extends FeaturedBase4 {
|
|
148930
149108
|
pendingTransitionTime;
|
|
@@ -148942,7 +149120,7 @@ var LevelControlServerBase = class extends FeaturedBase4 {
|
|
|
148942
149120
|
try {
|
|
148943
149121
|
await super.initialize();
|
|
148944
149122
|
} catch (error) {
|
|
148945
|
-
|
|
149123
|
+
logger193.error("super.initialize() failed:", error);
|
|
148946
149124
|
throw error;
|
|
148947
149125
|
}
|
|
148948
149126
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
@@ -149019,7 +149197,7 @@ var LevelControlServerBase = class extends FeaturedBase4 {
|
|
|
149019
149197
|
const lastTurnOn = lastTurnOnTimestamps.get(entityId);
|
|
149020
149198
|
const timeSinceTurnOn = lastTurnOn ? Date.now() - lastTurnOn : Infinity;
|
|
149021
149199
|
if (level >= this.maxLevel && timeSinceTurnOn < 200) {
|
|
149022
|
-
|
|
149200
|
+
logger193.debug(
|
|
149023
149201
|
`[${entityId}] Ignoring moveToLevel(${level}) - Alexa brightness reset detected (${timeSinceTurnOn}ms after turn-on)`
|
|
149024
149202
|
);
|
|
149025
149203
|
return;
|
|
@@ -149065,7 +149243,7 @@ function LevelControlServer2(config11) {
|
|
|
149065
149243
|
}
|
|
149066
149244
|
|
|
149067
149245
|
// src/matter/behaviors/on-off-server.ts
|
|
149068
|
-
var
|
|
149246
|
+
var logger194 = Logger.get("OnOffServer");
|
|
149069
149247
|
var optimisticOnOffState = /* @__PURE__ */ new Map();
|
|
149070
149248
|
var OPTIMISTIC_TIMEOUT_MS2 = 3e3;
|
|
149071
149249
|
function sweepOptimisticOnOff(now) {
|
|
@@ -149116,7 +149294,7 @@ var OnOffServerBase = class extends OnOffServer {
|
|
|
149116
149294
|
if (!action) {
|
|
149117
149295
|
return;
|
|
149118
149296
|
}
|
|
149119
|
-
|
|
149297
|
+
logger194.info(`[${homeAssistant.entityId}] Turning ON -> ${action.action}`);
|
|
149120
149298
|
notifyLightTurnedOn(homeAssistant.entityId);
|
|
149121
149299
|
const now = Date.now();
|
|
149122
149300
|
sweepOptimisticOnOff(now);
|
|
@@ -149141,7 +149319,7 @@ var OnOffServerBase = class extends OnOffServer {
|
|
|
149141
149319
|
if (!action) {
|
|
149142
149320
|
return;
|
|
149143
149321
|
}
|
|
149144
|
-
|
|
149322
|
+
logger194.info(`[${homeAssistant.entityId}] Turning OFF -> ${action.action}`);
|
|
149145
149323
|
const now = Date.now();
|
|
149146
149324
|
sweepOptimisticOnOff(now);
|
|
149147
149325
|
optimisticOnOffState.set(homeAssistant.entityId, {
|
|
@@ -149175,7 +149353,7 @@ function setOptimisticOnOff(entityId, expectedOnOff) {
|
|
|
149175
149353
|
}
|
|
149176
149354
|
|
|
149177
149355
|
// src/matter/behaviors/fan-control-server.ts
|
|
149178
|
-
var
|
|
149356
|
+
var logger195 = Logger.get("FanControlServer");
|
|
149179
149357
|
var defaultStepSize = 33.33;
|
|
149180
149358
|
var minSpeedMax = 3;
|
|
149181
149359
|
var maxSpeedMax = 100;
|
|
@@ -149546,7 +149724,7 @@ var FanControlServerBase = class extends FeaturedBase5 {
|
|
|
149546
149724
|
const entityId = this.agent.get(HomeAssistantEntityBehavior).entity.entity_id;
|
|
149547
149725
|
setOptimisticOnOff(entityId, on);
|
|
149548
149726
|
} catch (e) {
|
|
149549
|
-
|
|
149727
|
+
logger195.debug(
|
|
149550
149728
|
`syncOnOff(${on}) failed: ${e instanceof Error ? e.message : String(e)}`
|
|
149551
149729
|
);
|
|
149552
149730
|
}
|
|
@@ -149640,7 +149818,7 @@ var FanOnOffServer = OnOffServer2({
|
|
|
149640
149818
|
});
|
|
149641
149819
|
|
|
149642
149820
|
// src/matter/endpoints/composed/composed-air-purifier-endpoint.ts
|
|
149643
|
-
var
|
|
149821
|
+
var logger196 = Logger.get("ComposedAirPurifierEndpoint");
|
|
149644
149822
|
var temperatureConfig = {
|
|
149645
149823
|
getValue(entity, agent) {
|
|
149646
149824
|
const fallbackUnit = agent.env.get(HomeAssistantConfig).unitSystem.temperature;
|
|
@@ -149856,7 +150034,7 @@ var ComposedAirPurifierEndpoint = class _ComposedAirPurifierEndpoint extends End
|
|
|
149856
150034
|
config11.powerEntityId ? "+Pwr" : "",
|
|
149857
150035
|
config11.energyEntityId ? "+Nrg" : ""
|
|
149858
150036
|
].filter(Boolean).join("");
|
|
149859
|
-
|
|
150037
|
+
logger196.info(
|
|
149860
150038
|
`Created composed air purifier ${primaryEntityId}: ${clusterLabels}`
|
|
149861
150039
|
);
|
|
149862
150040
|
return endpoint;
|
|
@@ -150191,7 +150369,7 @@ init_home_assistant_entity_behavior();
|
|
|
150191
150369
|
// src/matter/behaviors/thermostat-server.ts
|
|
150192
150370
|
init_esm();
|
|
150193
150371
|
init_home_assistant_entity_behavior();
|
|
150194
|
-
var
|
|
150372
|
+
var logger197 = Logger.get("ThermostatServer");
|
|
150195
150373
|
var SystemMode = Thermostat3.SystemMode;
|
|
150196
150374
|
var RunningMode = Thermostat3.ThermostatRunningMode;
|
|
150197
150375
|
var nudgingSetpoints = /* @__PURE__ */ new Set();
|
|
@@ -150249,7 +150427,7 @@ var HeatingAndCoolingFeaturedBase = ThermostatServer.with("Heating", "Cooling").
|
|
|
150249
150427
|
);
|
|
150250
150428
|
function thermostatPreInitialize(self) {
|
|
150251
150429
|
const currentLocal = self.state.localTemperature;
|
|
150252
|
-
|
|
150430
|
+
logger197.debug(
|
|
150253
150431
|
`initialize: features - heating=${self.features.heating}, cooling=${self.features.cooling}`
|
|
150254
150432
|
);
|
|
150255
150433
|
const localValue = typeof currentLocal === "number" && !Number.isNaN(currentLocal) ? currentLocal : currentLocal === null ? null : 2100;
|
|
@@ -150272,7 +150450,7 @@ function thermostatPreInitialize(self) {
|
|
|
150272
150450
|
const coolingValue = typeof currentCooling === "number" && !Number.isNaN(currentCooling) ? currentCooling : 2400;
|
|
150273
150451
|
self.state.occupiedCoolingSetpoint = coolingValue;
|
|
150274
150452
|
}
|
|
150275
|
-
|
|
150453
|
+
logger197.debug(
|
|
150276
150454
|
`initialize: after force-set - local=${self.state.localTemperature}`
|
|
150277
150455
|
);
|
|
150278
150456
|
self.state.thermostatRunningState = runningStateAllOff;
|
|
@@ -150354,7 +150532,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
150354
150532
|
maxCoolLimit,
|
|
150355
150533
|
"cool"
|
|
150356
150534
|
);
|
|
150357
|
-
|
|
150535
|
+
logger197.debug(
|
|
150358
150536
|
`update: limits heat=[${minHeatLimit}, ${maxHeatLimit}], cool=[${minCoolLimit}, ${maxCoolLimit}], systemMode=${systemMode}, runningMode=${runningMode}`
|
|
150359
150537
|
);
|
|
150360
150538
|
let controlSequence = config11.getControlSequence(entity.state, this.agent);
|
|
@@ -150427,18 +150605,18 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
150427
150605
|
*/
|
|
150428
150606
|
// biome-ignore lint/correctness/noUnusedPrivateClassMembers: Called via thermostatPostInitialize + prototype copy
|
|
150429
150607
|
heatingSetpointChanging(value, _oldValue, context) {
|
|
150430
|
-
|
|
150608
|
+
logger197.debug(
|
|
150431
150609
|
`heatingSetpointChanging: value=${value}, oldValue=${_oldValue}, isOffline=${transactionIsOffline(context)}`
|
|
150432
150610
|
);
|
|
150433
150611
|
if (transactionIsOffline(context)) {
|
|
150434
|
-
|
|
150612
|
+
logger197.debug(
|
|
150435
150613
|
"heatingSetpointChanging: skipping - transaction is offline"
|
|
150436
150614
|
);
|
|
150437
150615
|
return;
|
|
150438
150616
|
}
|
|
150439
150617
|
const next = Temperature.celsius(value / 100);
|
|
150440
150618
|
if (!next) {
|
|
150441
|
-
|
|
150619
|
+
logger197.debug("heatingSetpointChanging: skipping - invalid temperature");
|
|
150442
150620
|
return;
|
|
150443
150621
|
}
|
|
150444
150622
|
this.agent.asLocalActor(() => {
|
|
@@ -150449,7 +150627,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
150449
150627
|
this.agent
|
|
150450
150628
|
);
|
|
150451
150629
|
const currentMode = this.state.systemMode;
|
|
150452
|
-
|
|
150630
|
+
logger197.debug(
|
|
150453
150631
|
`heatingSetpointChanging: supportsRange=${supportsRange}, systemMode=${currentMode}, features.heating=${this.features.heating}, features.cooling=${this.features.cooling}`
|
|
150454
150632
|
);
|
|
150455
150633
|
if (!supportsRange) {
|
|
@@ -150459,12 +150637,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
150459
150637
|
const isOff = currentMode === Thermostat3.SystemMode.Off;
|
|
150460
150638
|
if (isOff && this.features.heating) {
|
|
150461
150639
|
if (nudgingSetpoints.has(homeAssistant.entityId)) {
|
|
150462
|
-
|
|
150640
|
+
logger197.debug(
|
|
150463
150641
|
`heatingSetpointChanging: skipping auto-resume - nudge write in progress`
|
|
150464
150642
|
);
|
|
150465
150643
|
return;
|
|
150466
150644
|
}
|
|
150467
|
-
|
|
150645
|
+
logger197.info(
|
|
150468
150646
|
`heatingSetpointChanging: auto-resume - switching to Heat (was Off)`
|
|
150469
150647
|
);
|
|
150470
150648
|
const modeAction = config11.setSystemMode(
|
|
@@ -150473,17 +150651,17 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
150473
150651
|
);
|
|
150474
150652
|
homeAssistant.callAction(modeAction);
|
|
150475
150653
|
} else if (!isAutoMode && !isHeatingMode) {
|
|
150476
|
-
|
|
150654
|
+
logger197.debug(
|
|
150477
150655
|
`heatingSetpointChanging: skipping - not in heating/auto mode (mode=${currentMode}, haMode=${haHvacMode})`
|
|
150478
150656
|
);
|
|
150479
150657
|
return;
|
|
150480
150658
|
}
|
|
150481
|
-
|
|
150659
|
+
logger197.debug(
|
|
150482
150660
|
`heatingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isHeatingMode=${isHeatingMode}, isOff=${isOff}, haMode=${haHvacMode}`
|
|
150483
150661
|
);
|
|
150484
150662
|
}
|
|
150485
150663
|
const coolingSetpoint = this.features.cooling ? this.state.occupiedCoolingSetpoint : value;
|
|
150486
|
-
|
|
150664
|
+
logger197.debug(
|
|
150487
150665
|
`heatingSetpointChanging: calling setTemperature with heat=${next.celsius(true)}, cool=${coolingSetpoint}`
|
|
150488
150666
|
);
|
|
150489
150667
|
this.setTemperature(
|
|
@@ -150522,12 +150700,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
150522
150700
|
const isOff = currentMode === Thermostat3.SystemMode.Off;
|
|
150523
150701
|
if (isOff && !this.features.heating && this.features.cooling) {
|
|
150524
150702
|
if (nudgingSetpoints.has(homeAssistant.entityId)) {
|
|
150525
|
-
|
|
150703
|
+
logger197.debug(
|
|
150526
150704
|
`coolingSetpointChanging: skipping auto-resume - nudge write in progress`
|
|
150527
150705
|
);
|
|
150528
150706
|
return;
|
|
150529
150707
|
}
|
|
150530
|
-
|
|
150708
|
+
logger197.info(
|
|
150531
150709
|
`coolingSetpointChanging: auto-resume - switching to Cool (was Off)`
|
|
150532
150710
|
);
|
|
150533
150711
|
const modeAction = config11.setSystemMode(
|
|
@@ -150536,12 +150714,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
150536
150714
|
);
|
|
150537
150715
|
homeAssistant.callAction(modeAction);
|
|
150538
150716
|
} else if (!isAutoMode && !isCoolingMode) {
|
|
150539
|
-
|
|
150717
|
+
logger197.debug(
|
|
150540
150718
|
`coolingSetpointChanging: skipping - not in cooling/auto mode (mode=${currentMode}, haMode=${haHvacMode})`
|
|
150541
150719
|
);
|
|
150542
150720
|
return;
|
|
150543
150721
|
}
|
|
150544
|
-
|
|
150722
|
+
logger197.debug(
|
|
150545
150723
|
`coolingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isCoolingMode=${isCoolingMode}, isOff=${isOff}, haMode=${haHvacMode}`
|
|
150546
150724
|
);
|
|
150547
150725
|
}
|
|
@@ -150640,7 +150818,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
|
|
|
150640
150818
|
const effectiveMax = max ?? 5e3;
|
|
150641
150819
|
if (value == null || Number.isNaN(value)) {
|
|
150642
150820
|
const defaultValue = type === "heat" ? 2e3 : 2400;
|
|
150643
|
-
|
|
150821
|
+
logger197.debug(
|
|
150644
150822
|
`${type} setpoint is undefined, using default: ${defaultValue}`
|
|
150645
150823
|
);
|
|
150646
150824
|
return Math.max(effectiveMin, Math.min(effectiveMax, defaultValue));
|
|
@@ -151207,7 +151385,7 @@ function ClimateDevice(homeAssistantEntity, includeBasicInformation = true) {
|
|
|
151207
151385
|
}
|
|
151208
151386
|
|
|
151209
151387
|
// src/matter/endpoints/composed/composed-climate-fan-endpoint.ts
|
|
151210
|
-
var
|
|
151388
|
+
var logger198 = Logger.get("ComposedClimateFanEndpoint");
|
|
151211
151389
|
function createEndpointId3(entityId, customName) {
|
|
151212
151390
|
const baseName = customName || entityId;
|
|
151213
151391
|
return baseName.replace(/\./g, "_").replace(/\s+/g, "_");
|
|
@@ -151245,7 +151423,7 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
|
|
|
151245
151423
|
climateSub = new Endpoint(climateType, { id: `${endpointId}_climate` });
|
|
151246
151424
|
} catch (error) {
|
|
151247
151425
|
const message = error instanceof Error ? error.message : String(error);
|
|
151248
|
-
|
|
151426
|
+
logger198.warn(
|
|
151249
151427
|
`Companion fan: climate sub build failed for ${primaryEntityId}: ${message}`
|
|
151250
151428
|
);
|
|
151251
151429
|
return void 0;
|
|
@@ -151285,7 +151463,7 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
|
|
|
151285
151463
|
endpointId,
|
|
151286
151464
|
[climateSub, fanSub]
|
|
151287
151465
|
);
|
|
151288
|
-
|
|
151466
|
+
logger198.info(`Created composed climate+fan endpoint ${primaryEntityId}`);
|
|
151289
151467
|
return endpoint;
|
|
151290
151468
|
}
|
|
151291
151469
|
constructor(type, entityId, id, parts) {
|
|
@@ -151380,7 +151558,7 @@ init_home_assistant_entity_behavior();
|
|
|
151380
151558
|
// src/matter/behaviors/pressure-measurement-server.ts
|
|
151381
151559
|
init_esm();
|
|
151382
151560
|
init_home_assistant_entity_behavior();
|
|
151383
|
-
var
|
|
151561
|
+
var logger199 = Logger.get("PressureMeasurementServer");
|
|
151384
151562
|
var MIN_PRESSURE = 300;
|
|
151385
151563
|
var MAX_PRESSURE = 1100;
|
|
151386
151564
|
var PressureMeasurementServerBase = class extends PressureMeasurementServer {
|
|
@@ -151408,7 +151586,7 @@ var PressureMeasurementServerBase = class extends PressureMeasurementServer {
|
|
|
151408
151586
|
}
|
|
151409
151587
|
const rounded = Math.round(value);
|
|
151410
151588
|
if (rounded < MIN_PRESSURE || rounded > MAX_PRESSURE) {
|
|
151411
|
-
|
|
151589
|
+
logger199.warn(
|
|
151412
151590
|
`Pressure value ${rounded} (raw: ${value}) for ${entity.entity_id} is outside valid range [${MIN_PRESSURE}-${MAX_PRESSURE}], ignoring`
|
|
151413
151591
|
);
|
|
151414
151592
|
return null;
|
|
@@ -151427,7 +151605,7 @@ function PressureMeasurementServer2(config11) {
|
|
|
151427
151605
|
}
|
|
151428
151606
|
|
|
151429
151607
|
// src/matter/endpoints/composed/composed-sensor-endpoint.ts
|
|
151430
|
-
var
|
|
151608
|
+
var logger200 = Logger.get("ComposedSensorEndpoint");
|
|
151431
151609
|
var temperatureConfig2 = {
|
|
151432
151610
|
getValue(entity, agent) {
|
|
151433
151611
|
const fallbackUnit = agent.env.get(HomeAssistantConfig).unitSystem.temperature;
|
|
@@ -151604,7 +151782,7 @@ var ComposedSensorEndpoint = class _ComposedSensorEndpoint extends Endpoint {
|
|
|
151604
151782
|
if (config11.pressureEntityId && pressSub) {
|
|
151605
151783
|
endpoint.subEndpoints.set(config11.pressureEntityId, pressSub);
|
|
151606
151784
|
}
|
|
151607
|
-
|
|
151785
|
+
logger200.info(
|
|
151608
151786
|
`Created composed sensor ${primaryEntityId} with ${parts.length} sub-endpoint(s): T${humSub ? "+H" : ""}${pressSub ? "+P" : ""}${config11.batteryEntityId ? "+Bat" : ""}${config11.powerEntityId ? "+Pwr" : ""}${config11.energyEntityId ? "+Nrg" : ""}`
|
|
151609
151787
|
);
|
|
151610
151788
|
return endpoint;
|
|
@@ -151740,7 +151918,7 @@ init_home_assistant_entity_behavior();
|
|
|
151740
151918
|
// src/matter/behaviors/mode-select-server.ts
|
|
151741
151919
|
init_esm();
|
|
151742
151920
|
init_home_assistant_entity_behavior();
|
|
151743
|
-
var
|
|
151921
|
+
var logger201 = Logger.get("ModeSelectServer");
|
|
151744
151922
|
function buildSupportedModes(options) {
|
|
151745
151923
|
return options.map((label, index) => ({
|
|
151746
151924
|
label: label.length > 64 ? label.substring(0, 64) : label,
|
|
@@ -151777,13 +151955,13 @@ var ModeSelectServerBase = class extends ModeSelectServer {
|
|
|
151777
151955
|
const options = config11.getOptions(homeAssistant.entity);
|
|
151778
151956
|
const { newMode } = request;
|
|
151779
151957
|
if (newMode < 0 || newMode >= options.length) {
|
|
151780
|
-
|
|
151958
|
+
logger201.warn(
|
|
151781
151959
|
`[${homeAssistant.entityId}] Invalid mode ${newMode}, options: [${options.join(", ")}]`
|
|
151782
151960
|
);
|
|
151783
151961
|
return;
|
|
151784
151962
|
}
|
|
151785
151963
|
const option = options[newMode];
|
|
151786
|
-
|
|
151964
|
+
logger201.info(
|
|
151787
151965
|
`[${homeAssistant.entityId}] changeToMode(${newMode}) -> "${option}"`
|
|
151788
151966
|
);
|
|
151789
151967
|
applyPatchState(this.state, { currentMode: newMode });
|
|
@@ -152309,7 +152487,7 @@ var WaterLeakDetectorType = WaterLeakDetectorDevice.with(
|
|
|
152309
152487
|
);
|
|
152310
152488
|
|
|
152311
152489
|
// src/matter/endpoints/legacy/binary-sensor/index.ts
|
|
152312
|
-
var
|
|
152490
|
+
var logger202 = Logger.get("BinarySensorDevice");
|
|
152313
152491
|
var deviceClasses = {
|
|
152314
152492
|
[BinarySensorDeviceClass.CarbonMonoxide]: CoAlarmType,
|
|
152315
152493
|
[BinarySensorDeviceClass.Gas]: CoAlarmType,
|
|
@@ -152361,11 +152539,11 @@ function BinarySensorDevice(homeAssistantEntity) {
|
|
|
152361
152539
|
const originalTypeName = type.name;
|
|
152362
152540
|
if (hasBattery && batteryTypes.has(type)) {
|
|
152363
152541
|
type = batteryTypes.get(type);
|
|
152364
|
-
|
|
152542
|
+
logger202.info(
|
|
152365
152543
|
`[${entityId}] Using battery variant: ${originalTypeName} -> ${type.name}, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
|
|
152366
152544
|
);
|
|
152367
152545
|
} else if (hasBattery) {
|
|
152368
|
-
|
|
152546
|
+
logger202.warn(
|
|
152369
152547
|
`[${entityId}] Has battery but no variant available for ${originalTypeName}`
|
|
152370
152548
|
);
|
|
152371
152549
|
}
|
|
@@ -152415,7 +152593,7 @@ init_home_assistant_entity_behavior();
|
|
|
152415
152593
|
init_esm();
|
|
152416
152594
|
init_home_assistant_actions();
|
|
152417
152595
|
init_home_assistant_entity_behavior();
|
|
152418
|
-
var
|
|
152596
|
+
var logger203 = Logger.get("WindowCoveringServer");
|
|
152419
152597
|
var MovementStatus = WindowCovering3.MovementStatus;
|
|
152420
152598
|
var FeaturedBase6 = WindowCoveringServer.with(
|
|
152421
152599
|
"Lift",
|
|
@@ -152530,7 +152708,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
152530
152708
|
}
|
|
152531
152709
|
return existing100ths ?? current100ths;
|
|
152532
152710
|
};
|
|
152533
|
-
|
|
152711
|
+
logger203.debug(
|
|
152534
152712
|
`Cover update for ${entity.entity_id}: state=${state.state}, lift=${currentLift}%, tilt=${currentTilt}%, movement=${MovementStatus[movementStatus]}`
|
|
152535
152713
|
);
|
|
152536
152714
|
const overrideType = config11.getCoverType?.(state, this.agent);
|
|
@@ -152573,9 +152751,9 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
152573
152751
|
);
|
|
152574
152752
|
if (Object.keys(appliedPatch).length > 0) {
|
|
152575
152753
|
const hasOperationalChange = "operationalStatus" in appliedPatch;
|
|
152576
|
-
const log = hasOperationalChange ?
|
|
152754
|
+
const log = hasOperationalChange ? logger203.info : logger203.debug;
|
|
152577
152755
|
log.call(
|
|
152578
|
-
|
|
152756
|
+
logger203,
|
|
152579
152757
|
`Cover ${entity.entity_id} state changed: ${JSON.stringify(appliedPatch)}`
|
|
152580
152758
|
);
|
|
152581
152759
|
}
|
|
@@ -152583,7 +152761,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
152583
152761
|
async handleMovement(type, _, direction, targetPercent100ths) {
|
|
152584
152762
|
const currentLift = this.state.currentPositionLiftPercent100ths ?? 0;
|
|
152585
152763
|
const currentTilt = this.state.currentPositionTiltPercent100ths ?? 0;
|
|
152586
|
-
|
|
152764
|
+
logger203.info(
|
|
152587
152765
|
`handleMovement: type=${MovementType[type]}, direction=${MovementDirection[direction]}, target=${targetPercent100ths}, currentLift=${currentLift}, currentTilt=${currentTilt}`
|
|
152588
152766
|
);
|
|
152589
152767
|
if (type === MovementType.Lift) {
|
|
@@ -152602,7 +152780,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
152602
152780
|
}
|
|
152603
152781
|
} else if (type === MovementType.Tilt) {
|
|
152604
152782
|
if (targetPercent100ths == null && this.lastLiftMovementDirection === direction && Date.now() - this.lastLiftMovementMs < 50) {
|
|
152605
|
-
|
|
152783
|
+
logger203.info(
|
|
152606
152784
|
`Skipping tilt ${MovementDirection[direction]}, lift already moving in same direction`
|
|
152607
152785
|
);
|
|
152608
152786
|
return;
|
|
@@ -152627,13 +152805,13 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
152627
152805
|
handleLiftOpen() {
|
|
152628
152806
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
152629
152807
|
const action = this.state.config.openCoverLift(void 0, this.agent);
|
|
152630
|
-
|
|
152808
|
+
logger203.info(`handleLiftOpen: calling action=${action.action}`);
|
|
152631
152809
|
homeAssistant.callAction(action);
|
|
152632
152810
|
}
|
|
152633
152811
|
handleLiftClose() {
|
|
152634
152812
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
152635
152813
|
const action = this.state.config.closeCoverLift(void 0, this.agent);
|
|
152636
|
-
|
|
152814
|
+
logger203.info(`handleLiftClose: calling action=${action.action}`);
|
|
152637
152815
|
homeAssistant.callAction(action);
|
|
152638
152816
|
}
|
|
152639
152817
|
handleGoToLiftPosition(targetPercent100ths) {
|
|
@@ -152655,7 +152833,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
152655
152833
|
const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
|
|
152656
152834
|
const overrideMs = this.resolveDebounceOverride(homeAssistant);
|
|
152657
152835
|
const debounceMs = overrideMs != null ? overrideMs : isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
|
|
152658
|
-
|
|
152836
|
+
logger203.debug(
|
|
152659
152837
|
`Lift command: target=${targetPosition}%, debounce=${debounceMs}ms (${overrideMs != null ? "override" : isFirstInSequence ? "initial" : "subsequent"})`
|
|
152660
152838
|
);
|
|
152661
152839
|
if (this.liftDebounceTimer) {
|
|
@@ -152705,7 +152883,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
|
|
|
152705
152883
|
const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
|
|
152706
152884
|
const overrideMs = this.resolveDebounceOverride(homeAssistant);
|
|
152707
152885
|
const debounceMs = overrideMs != null ? overrideMs : isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
|
|
152708
|
-
|
|
152886
|
+
logger203.debug(
|
|
152709
152887
|
`Tilt command: target=${targetPosition}%, debounce=${debounceMs}ms (${overrideMs != null ? "override" : isFirstInSequence ? "initial" : "subsequent"})`
|
|
152710
152888
|
);
|
|
152711
152889
|
if (this.tiltDebounceTimer) {
|
|
@@ -152757,7 +152935,7 @@ function adjustPositionForWriting(position, flags2, matterSemantics) {
|
|
|
152757
152935
|
}
|
|
152758
152936
|
|
|
152759
152937
|
// src/matter/endpoints/legacy/cover/behaviors/cover-window-covering-server.ts
|
|
152760
|
-
var
|
|
152938
|
+
var logger204 = Logger.get("CoverWindowCoveringServer");
|
|
152761
152939
|
var attributes6 = (entity) => entity.attributes;
|
|
152762
152940
|
var DEVICE_CLASS_TO_MATTER_TYPE = {
|
|
152763
152941
|
curtain: {
|
|
@@ -152829,7 +153007,7 @@ var adjustPositionForReading2 = (position, agent) => {
|
|
|
152829
153007
|
const { featureFlags } = agent.env.get(BridgeDataProvider);
|
|
152830
153008
|
const matterSem = usesMatterSemantics(agent);
|
|
152831
153009
|
const result = adjustPositionForReading(position, featureFlags, matterSem);
|
|
152832
|
-
|
|
153010
|
+
logger204.debug(`adjustPositionForReading: HA=${position}%, result=${result}%`);
|
|
152833
153011
|
return result;
|
|
152834
153012
|
};
|
|
152835
153013
|
var adjustPositionForWriting2 = (position, agent) => {
|
|
@@ -152953,14 +153131,14 @@ var config6 = {
|
|
|
152953
153131
|
var CoverWindowCoveringServer = WindowCoveringServer2(config6);
|
|
152954
153132
|
|
|
152955
153133
|
// src/matter/endpoints/legacy/cover/index.ts
|
|
152956
|
-
var
|
|
153134
|
+
var logger205 = Logger.get("CoverDevice");
|
|
152957
153135
|
var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
|
|
152958
153136
|
const features3 = /* @__PURE__ */ new Set();
|
|
152959
153137
|
if (testBit(supportedFeatures, CoverSupportedFeatures.support_open)) {
|
|
152960
153138
|
features3.add("Lift");
|
|
152961
153139
|
features3.add("PositionAwareLift");
|
|
152962
153140
|
} else {
|
|
152963
|
-
|
|
153141
|
+
logger205.warn(
|
|
152964
153142
|
`[${entityId}] Cover has no support_open feature (supported_features=${supportedFeatures}), adding Lift anyway`
|
|
152965
153143
|
);
|
|
152966
153144
|
features3.add("Lift");
|
|
@@ -152975,7 +153153,7 @@ var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
|
|
|
152975
153153
|
features3.add("PositionAwareTilt");
|
|
152976
153154
|
}
|
|
152977
153155
|
}
|
|
152978
|
-
|
|
153156
|
+
logger205.info(
|
|
152979
153157
|
`[${entityId}] Creating WindowCovering with features: [${[...features3].join(", ")}], supported_features=${supportedFeatures}`
|
|
152980
153158
|
);
|
|
152981
153159
|
const baseBehaviors = [
|
|
@@ -152999,11 +153177,11 @@ function CoverDevice(homeAssistantEntity) {
|
|
|
152999
153177
|
const hasBatteryEntity = !!homeAssistantEntity.mapping?.batteryEntity;
|
|
153000
153178
|
const hasBattery = hasBatteryAttr || hasBatteryEntity;
|
|
153001
153179
|
if (hasBattery) {
|
|
153002
|
-
|
|
153180
|
+
logger205.info(
|
|
153003
153181
|
`[${entityId}] Creating cover with PowerSource cluster, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
|
|
153004
153182
|
);
|
|
153005
153183
|
} else {
|
|
153006
|
-
|
|
153184
|
+
logger205.debug(
|
|
153007
153185
|
`[${entityId}] Creating cover without battery (batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"})`
|
|
153008
153186
|
);
|
|
153009
153187
|
}
|
|
@@ -153118,7 +153296,7 @@ function DishwasherEndpoint(homeAssistantEntity) {
|
|
|
153118
153296
|
// src/matter/behaviors/generic-switch-server.ts
|
|
153119
153297
|
init_esm();
|
|
153120
153298
|
init_home_assistant_entity_behavior();
|
|
153121
|
-
var
|
|
153299
|
+
var logger206 = Logger.get("GenericSwitchServer");
|
|
153122
153300
|
var SimpleBase = SwitchServer.with(
|
|
153123
153301
|
"MomentarySwitch",
|
|
153124
153302
|
"MomentarySwitchRelease",
|
|
@@ -153160,7 +153338,7 @@ var HaGenericSwitchServerBase = class extends SimpleBase {
|
|
|
153160
153338
|
await super.initialize();
|
|
153161
153339
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
153162
153340
|
const entityId = homeAssistant.entityId;
|
|
153163
|
-
|
|
153341
|
+
logger206.debug(`[${entityId}] GenericSwitch initialized (simple)`);
|
|
153164
153342
|
this.reactTo(homeAssistant.onChange, this.handleEventChange);
|
|
153165
153343
|
}
|
|
153166
153344
|
handleEventChange() {
|
|
@@ -153171,7 +153349,7 @@ var HaGenericSwitchServerBase = class extends SimpleBase {
|
|
|
153171
153349
|
const eventType = attrs.event_type;
|
|
153172
153350
|
if (!eventType) return;
|
|
153173
153351
|
const entityId = homeAssistant.entityId;
|
|
153174
|
-
|
|
153352
|
+
logger206.debug(`[${entityId}] Event fired: ${eventType}`);
|
|
153175
153353
|
this.triggerPress(eventType);
|
|
153176
153354
|
}
|
|
153177
153355
|
triggerPress(eventType) {
|
|
@@ -153217,7 +153395,7 @@ var HaGenericSwitchServerMultiBase = class extends FullBase {
|
|
|
153217
153395
|
await super.initialize();
|
|
153218
153396
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
153219
153397
|
const entityId = homeAssistant.entityId;
|
|
153220
|
-
|
|
153398
|
+
logger206.debug(`[${entityId}] GenericSwitch initialized (multi)`);
|
|
153221
153399
|
this.reactTo(homeAssistant.onChange, this.handleEventChange);
|
|
153222
153400
|
}
|
|
153223
153401
|
handleEventChange() {
|
|
@@ -153228,7 +153406,7 @@ var HaGenericSwitchServerMultiBase = class extends FullBase {
|
|
|
153228
153406
|
const eventType = attrs.event_type;
|
|
153229
153407
|
if (!eventType) return;
|
|
153230
153408
|
const entityId = homeAssistant.entityId;
|
|
153231
|
-
|
|
153409
|
+
logger206.debug(`[${entityId}] Event fired: ${eventType}`);
|
|
153232
153410
|
this.triggerPress(eventType);
|
|
153233
153411
|
}
|
|
153234
153412
|
triggerPress(eventType) {
|
|
@@ -153564,7 +153742,7 @@ init_nodejs();
|
|
|
153564
153742
|
|
|
153565
153743
|
// src/matter/behaviors/color-control-server.ts
|
|
153566
153744
|
init_home_assistant_entity_behavior();
|
|
153567
|
-
var
|
|
153745
|
+
var logger207 = Logger.get("ColorControlServer");
|
|
153568
153746
|
var optimisticColorState = /* @__PURE__ */ new Map();
|
|
153569
153747
|
var OPTIMISTIC_TIMEOUT_MS3 = 3e3;
|
|
153570
153748
|
var OPTIMISTIC_TOLERANCE2 = 5;
|
|
@@ -153603,7 +153781,7 @@ var ColorControlServerBase = class extends FeaturedBase7 {
|
|
|
153603
153781
|
if (this.state.startUpColorTemperatureMireds == null) {
|
|
153604
153782
|
this.state.startUpColorTemperatureMireds = defaultMireds;
|
|
153605
153783
|
}
|
|
153606
|
-
|
|
153784
|
+
logger207.debug(
|
|
153607
153785
|
`initialize: set ColorTemperature defaults - min=${this.state.colorTempPhysicalMinMireds}, max=${this.state.colorTempPhysicalMaxMireds}, current=${this.state.colorTemperatureMireds}`
|
|
153608
153786
|
);
|
|
153609
153787
|
}
|
|
@@ -154095,7 +154273,7 @@ init_home_assistant_entity_behavior();
|
|
|
154095
154273
|
// src/matter/behaviors/lock-server.ts
|
|
154096
154274
|
init_esm();
|
|
154097
154275
|
init_home_assistant_entity_behavior();
|
|
154098
|
-
var
|
|
154276
|
+
var logger208 = Logger.get("LockServer");
|
|
154099
154277
|
var SUPPORTED_SLOT = 1;
|
|
154100
154278
|
function normalizeSupportedIndex(index) {
|
|
154101
154279
|
if (index === 0 || index === SUPPORTED_SLOT) {
|
|
@@ -154360,7 +154538,7 @@ var LockServerWithPinBase = class extends PinCredentialBase {
|
|
|
154360
154538
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
154361
154539
|
const action = this.state.config.lock(void 0, this.agent);
|
|
154362
154540
|
const hasPinProvided = !!request.pinCode;
|
|
154363
|
-
|
|
154541
|
+
logger208.debug(
|
|
154364
154542
|
`lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
|
|
154365
154543
|
);
|
|
154366
154544
|
if (request.pinCode) {
|
|
@@ -154373,12 +154551,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
|
|
|
154373
154551
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
154374
154552
|
const action = this.state.config.unlock(void 0, this.agent);
|
|
154375
154553
|
const hasPinProvided = !!request.pinCode;
|
|
154376
|
-
|
|
154554
|
+
logger208.debug(
|
|
154377
154555
|
`unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
|
|
154378
154556
|
);
|
|
154379
154557
|
if (this.state.requirePinForRemoteOperation) {
|
|
154380
154558
|
if (!request.pinCode) {
|
|
154381
|
-
|
|
154559
|
+
logger208.info(
|
|
154382
154560
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
|
|
154383
154561
|
);
|
|
154384
154562
|
throw new StatusResponseError(
|
|
@@ -154388,12 +154566,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
|
|
|
154388
154566
|
}
|
|
154389
154567
|
const providedPin = new TextDecoder().decode(request.pinCode);
|
|
154390
154568
|
if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
|
|
154391
|
-
|
|
154569
|
+
logger208.info(
|
|
154392
154570
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
|
|
154393
154571
|
);
|
|
154394
154572
|
throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
|
|
154395
154573
|
}
|
|
154396
|
-
|
|
154574
|
+
logger208.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
|
|
154397
154575
|
action.data = { ...action.data, code: providedPin };
|
|
154398
154576
|
}
|
|
154399
154577
|
homeAssistant.callAction(action);
|
|
@@ -154523,7 +154701,7 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
154523
154701
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
154524
154702
|
const action = this.state.config.lock(void 0, this.agent);
|
|
154525
154703
|
const hasPinProvided = !!request.pinCode;
|
|
154526
|
-
|
|
154704
|
+
logger208.debug(
|
|
154527
154705
|
`lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
|
|
154528
154706
|
);
|
|
154529
154707
|
if (request.pinCode) {
|
|
@@ -154537,12 +154715,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
154537
154715
|
const unlatchConfig = this.state.config.unlatch;
|
|
154538
154716
|
const action = unlatchConfig ? unlatchConfig(void 0, this.agent) : this.state.config.unlock(void 0, this.agent);
|
|
154539
154717
|
const hasPinProvided = !!request.pinCode;
|
|
154540
|
-
|
|
154718
|
+
logger208.debug(
|
|
154541
154719
|
`unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}, usingUnlatch: ${!!unlatchConfig}`
|
|
154542
154720
|
);
|
|
154543
154721
|
if (this.state.requirePinForRemoteOperation) {
|
|
154544
154722
|
if (!request.pinCode) {
|
|
154545
|
-
|
|
154723
|
+
logger208.info(
|
|
154546
154724
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
|
|
154547
154725
|
);
|
|
154548
154726
|
throw new StatusResponseError(
|
|
@@ -154552,12 +154730,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
154552
154730
|
}
|
|
154553
154731
|
const providedPin = new TextDecoder().decode(request.pinCode);
|
|
154554
154732
|
if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
|
|
154555
|
-
|
|
154733
|
+
logger208.info(
|
|
154556
154734
|
`unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
|
|
154557
154735
|
);
|
|
154558
154736
|
throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
|
|
154559
154737
|
}
|
|
154560
|
-
|
|
154738
|
+
logger208.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
|
|
154561
154739
|
action.data = { ...action.data, code: providedPin };
|
|
154562
154740
|
}
|
|
154563
154741
|
homeAssistant.callAction(action);
|
|
@@ -154572,12 +154750,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
154572
154750
|
}
|
|
154573
154751
|
const action = unlatchConfig(void 0, this.agent);
|
|
154574
154752
|
const hasPinProvided = !!request.pinCode;
|
|
154575
|
-
|
|
154753
|
+
logger208.debug(
|
|
154576
154754
|
`unboltDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
|
|
154577
154755
|
);
|
|
154578
154756
|
if (this.state.requirePinForRemoteOperation) {
|
|
154579
154757
|
if (!request.pinCode) {
|
|
154580
|
-
|
|
154758
|
+
logger208.info(
|
|
154581
154759
|
`unboltDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
|
|
154582
154760
|
);
|
|
154583
154761
|
throw new StatusResponseError(
|
|
@@ -154587,12 +154765,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
|
|
|
154587
154765
|
}
|
|
154588
154766
|
const providedPin = new TextDecoder().decode(request.pinCode);
|
|
154589
154767
|
if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
|
|
154590
|
-
|
|
154768
|
+
logger208.info(
|
|
154591
154769
|
`unboltDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
|
|
154592
154770
|
);
|
|
154593
154771
|
throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
|
|
154594
154772
|
}
|
|
154595
|
-
|
|
154773
|
+
logger208.debug(`unboltDoor PIN verified for ${homeAssistant.entityId}`);
|
|
154596
154774
|
action.data = { ...action.data, code: providedPin };
|
|
154597
154775
|
}
|
|
154598
154776
|
homeAssistant.callAction(action);
|
|
@@ -154724,7 +154902,7 @@ init_home_assistant_entity_behavior();
|
|
|
154724
154902
|
init_dist();
|
|
154725
154903
|
init_esm();
|
|
154726
154904
|
init_home_assistant_entity_behavior();
|
|
154727
|
-
var
|
|
154905
|
+
var logger209 = Logger.get("MediaPlayerKeypadInputServer");
|
|
154728
154906
|
var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
|
|
154729
154907
|
sendKey(request) {
|
|
154730
154908
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
@@ -154735,12 +154913,12 @@ var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
|
|
|
154735
154913
|
const features3 = attributes8.supported_features ?? 0;
|
|
154736
154914
|
const action = this.mapKeyToAction(request.keyCode, features3);
|
|
154737
154915
|
if (!action) {
|
|
154738
|
-
|
|
154916
|
+
logger209.debug(
|
|
154739
154917
|
`Unsupported key code ${request.keyCode} for ${homeAssistant.entityId}`
|
|
154740
154918
|
);
|
|
154741
154919
|
return { status: KeypadInput3.Status.UnsupportedKey };
|
|
154742
154920
|
}
|
|
154743
|
-
|
|
154921
|
+
logger209.debug(
|
|
154744
154922
|
`sendKey(${request.keyCode}) \u2192 ${action} for ${homeAssistant.entityId}`
|
|
154745
154923
|
);
|
|
154746
154924
|
homeAssistant.callAction({ action });
|
|
@@ -155019,7 +155197,7 @@ init_home_assistant_entity_behavior();
|
|
|
155019
155197
|
// src/matter/behaviors/speaker-level-control-server.ts
|
|
155020
155198
|
init_esm();
|
|
155021
155199
|
init_home_assistant_entity_behavior();
|
|
155022
|
-
var
|
|
155200
|
+
var logger210 = Logger.get("SpeakerLevelControlServer");
|
|
155023
155201
|
var optimisticLevelState2 = /* @__PURE__ */ new Map();
|
|
155024
155202
|
var OPTIMISTIC_TIMEOUT_MS4 = 3e3;
|
|
155025
155203
|
var OPTIMISTIC_TOLERANCE3 = 5;
|
|
@@ -155062,7 +155240,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase8 {
|
|
|
155062
155240
|
currentLevel = Math.min(Math.max(minLevel, currentLevel), maxLevel);
|
|
155063
155241
|
}
|
|
155064
155242
|
const entityId = this.agent.get(HomeAssistantEntityBehavior).entity.entity_id;
|
|
155065
|
-
|
|
155243
|
+
logger210.debug(
|
|
155066
155244
|
`[${entityId}] Volume update: HA=${currentLevelPercent != null ? Math.round(currentLevelPercent * 100) : "null"}% -> currentLevel=${currentLevel}`
|
|
155067
155245
|
);
|
|
155068
155246
|
const optimistic = optimisticLevelState2.get(entity.entity_id);
|
|
@@ -155110,7 +155288,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase8 {
|
|
|
155110
155288
|
const config11 = this.state.config;
|
|
155111
155289
|
const entityId = homeAssistant.entity.entity_id;
|
|
155112
155290
|
const levelPercent = level / 254;
|
|
155113
|
-
|
|
155291
|
+
logger210.debug(
|
|
155114
155292
|
`[${entityId}] Volume command: level=${level} -> HA volume_level=${levelPercent}`
|
|
155115
155293
|
);
|
|
155116
155294
|
const current = config11.getValuePercent(
|
|
@@ -156475,7 +156653,7 @@ var TvocConcentrationMeasurementServer = class extends TvocConcentrationMeasurem
|
|
|
156475
156653
|
};
|
|
156476
156654
|
|
|
156477
156655
|
// src/matter/endpoints/legacy/sensor/devices/tvoc-sensor.ts
|
|
156478
|
-
var
|
|
156656
|
+
var logger211 = Logger.get("TvocSensor");
|
|
156479
156657
|
function airQualityFromUgm3(value) {
|
|
156480
156658
|
if (value <= 300) return AirQuality3.AirQualityEnum.Good;
|
|
156481
156659
|
if (value <= 1e3) return AirQuality3.AirQualityEnum.Fair;
|
|
@@ -156516,17 +156694,17 @@ var TvocAirQualityServer = class extends TvocAirQualityServerBase {
|
|
|
156516
156694
|
const attributes8 = entity.state.attributes;
|
|
156517
156695
|
const deviceClass = attributes8.device_class;
|
|
156518
156696
|
let airQuality = AirQuality3.AirQualityEnum.Unknown;
|
|
156519
|
-
|
|
156697
|
+
logger211.debug(
|
|
156520
156698
|
`[${entity.entity_id}] TVOC update: state="${state}", device_class="${deviceClass}"`
|
|
156521
156699
|
);
|
|
156522
156700
|
if (state != null && !Number.isNaN(+state)) {
|
|
156523
156701
|
const value = +state;
|
|
156524
156702
|
airQuality = deviceClass === SensorDeviceClass.volatile_organic_compounds ? airQualityFromUgm3(value) : airQualityFromPpb(value);
|
|
156525
|
-
|
|
156703
|
+
logger211.debug(
|
|
156526
156704
|
`[${entity.entity_id}] TVOC value=${value} (${deviceClass}) -> airQuality=${AirQuality3.AirQualityEnum[airQuality]}`
|
|
156527
156705
|
);
|
|
156528
156706
|
} else {
|
|
156529
|
-
|
|
156707
|
+
logger211.warn(
|
|
156530
156708
|
`[${entity.entity_id}] TVOC state not a valid number: "${state}"`
|
|
156531
156709
|
);
|
|
156532
156710
|
}
|
|
@@ -156740,7 +156918,7 @@ init_home_assistant_entity_behavior();
|
|
|
156740
156918
|
// src/matter/behaviors/pm25-concentration-measurement-server.ts
|
|
156741
156919
|
init_esm();
|
|
156742
156920
|
init_home_assistant_entity_behavior();
|
|
156743
|
-
var
|
|
156921
|
+
var logger212 = Logger.get("Pm25ConcentrationMeasurementServer");
|
|
156744
156922
|
var Pm25ConcentrationMeasurementServerBase = Pm25ConcentrationMeasurementServer.with(
|
|
156745
156923
|
ConcentrationMeasurement3.Feature.NumericMeasurement
|
|
156746
156924
|
);
|
|
@@ -156764,11 +156942,11 @@ var Pm25ConcentrationMeasurementServer2 = class extends Pm25ConcentrationMeasure
|
|
|
156764
156942
|
if (this.state.measurementMedium === void 0) {
|
|
156765
156943
|
this.state.measurementMedium = ConcentrationMeasurement3.MeasurementMedium.Air;
|
|
156766
156944
|
}
|
|
156767
|
-
|
|
156945
|
+
logger212.debug(
|
|
156768
156946
|
"Pm25ConcentrationMeasurementServer: before super.initialize()"
|
|
156769
156947
|
);
|
|
156770
156948
|
await super.initialize();
|
|
156771
|
-
|
|
156949
|
+
logger212.debug(
|
|
156772
156950
|
"Pm25ConcentrationMeasurementServer: after super.initialize()"
|
|
156773
156951
|
);
|
|
156774
156952
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
@@ -156791,7 +156969,7 @@ var Pm25ConcentrationMeasurementServer2 = class extends Pm25ConcentrationMeasure
|
|
|
156791
156969
|
};
|
|
156792
156970
|
|
|
156793
156971
|
// src/matter/endpoints/legacy/sensor/devices/pm25-sensor.ts
|
|
156794
|
-
var
|
|
156972
|
+
var logger213 = Logger.get("Pm25AirQualityServer");
|
|
156795
156973
|
var Pm25AirQualityServerBase = AirQualityServer.with(
|
|
156796
156974
|
AirQuality3.Feature.Fair,
|
|
156797
156975
|
AirQuality3.Feature.Moderate,
|
|
@@ -156803,9 +156981,9 @@ var Pm25AirQualityServer = class extends Pm25AirQualityServerBase {
|
|
|
156803
156981
|
if (this.state.airQuality === void 0) {
|
|
156804
156982
|
this.state.airQuality = AirQuality3.AirQualityEnum.Unknown;
|
|
156805
156983
|
}
|
|
156806
|
-
|
|
156984
|
+
logger213.debug("Pm25AirQualityServer: before super.initialize()");
|
|
156807
156985
|
await super.initialize();
|
|
156808
|
-
|
|
156986
|
+
logger213.debug("Pm25AirQualityServer: after super.initialize()");
|
|
156809
156987
|
const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
|
|
156810
156988
|
this.update(homeAssistant.entity);
|
|
156811
156989
|
this.reactTo(homeAssistant.onChange, this.update, { offline: true });
|
|
@@ -157194,7 +157372,7 @@ init_home_assistant_entity_behavior();
|
|
|
157194
157372
|
init_dist();
|
|
157195
157373
|
init_esm();
|
|
157196
157374
|
init_home_assistant_entity_behavior();
|
|
157197
|
-
var
|
|
157375
|
+
var logger214 = Logger.get("VacuumIdentifyServer");
|
|
157198
157376
|
var IDENTIFY_BUTTON_SUFFIXES = ["_identify", "_locate", "_find_me"];
|
|
157199
157377
|
var VacuumIdentifyServer = class extends IdentifyServer2 {
|
|
157200
157378
|
triggerEffect(effect) {
|
|
@@ -157211,19 +157389,19 @@ var VacuumIdentifyServer = class extends IdentifyServer2 {
|
|
|
157211
157389
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
157212
157390
|
const features3 = homeAssistant.entity.state.attributes.supported_features ?? 0;
|
|
157213
157391
|
if (testBit(features3, VacuumDeviceFeature.LOCATE)) {
|
|
157214
|
-
|
|
157392
|
+
logger214.info(`${source} \u2192 vacuum.locate for ${homeAssistant.entityId}`);
|
|
157215
157393
|
homeAssistant.callAction({ action: "vacuum.locate" });
|
|
157216
157394
|
return;
|
|
157217
157395
|
}
|
|
157218
157396
|
const sibling = this.#findIdentifyButton(homeAssistant);
|
|
157219
157397
|
if (sibling) {
|
|
157220
|
-
|
|
157398
|
+
logger214.info(
|
|
157221
157399
|
`${source} \u2192 button.press ${sibling} for ${homeAssistant.entityId}`
|
|
157222
157400
|
);
|
|
157223
157401
|
homeAssistant.callAction({ action: "button.press", target: sibling });
|
|
157224
157402
|
return;
|
|
157225
157403
|
}
|
|
157226
|
-
|
|
157404
|
+
logger214.warn(
|
|
157227
157405
|
`${source} for ${homeAssistant.entityId}, LOCATE not in supported_features (${features3}), trying vacuum.locate anyway`
|
|
157228
157406
|
);
|
|
157229
157407
|
homeAssistant.callAction({ action: "vacuum.locate" });
|
|
@@ -157257,7 +157435,7 @@ init_nodejs();
|
|
|
157257
157435
|
|
|
157258
157436
|
// src/matter/behaviors/rvc-run-mode-server.ts
|
|
157259
157437
|
init_home_assistant_entity_behavior();
|
|
157260
|
-
var
|
|
157438
|
+
var logger215 = Logger.get("RvcRunModeServer");
|
|
157261
157439
|
var ROOM_MODE_BASE = 100;
|
|
157262
157440
|
function isRoomMode(mode) {
|
|
157263
157441
|
return mode >= ROOM_MODE_BASE;
|
|
@@ -157377,7 +157555,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
157377
157555
|
const s = getSession(this.endpoint);
|
|
157378
157556
|
if (s.loggedShortCircuits.has(reason)) return;
|
|
157379
157557
|
s.loggedShortCircuits.add(reason);
|
|
157380
|
-
|
|
157558
|
+
logger215.info(message);
|
|
157381
157559
|
}
|
|
157382
157560
|
/**
|
|
157383
157561
|
* Read the currentRoomEntity sensor and update currentArea + progress
|
|
@@ -157434,7 +157612,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
157434
157612
|
}
|
|
157435
157613
|
}
|
|
157436
157614
|
if (matchedAreaId === null) {
|
|
157437
|
-
|
|
157615
|
+
logger215.info(
|
|
157438
157616
|
`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(", ")}]`
|
|
157439
157617
|
);
|
|
157440
157618
|
return;
|
|
@@ -157444,14 +157622,14 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
157444
157622
|
s.completedAreas.add(s.lastCurrentArea);
|
|
157445
157623
|
}
|
|
157446
157624
|
s.lastCurrentArea = matchedAreaId;
|
|
157447
|
-
|
|
157625
|
+
logger215.info(
|
|
157448
157626
|
`currentRoom sensor: transition to area ${matchedAreaId} ("${roomName}"), completed: [${[...s.completedAreas].join(", ")}]`
|
|
157449
157627
|
);
|
|
157450
157628
|
this.trySetCurrentArea(matchedAreaId);
|
|
157451
157629
|
} catch (e) {
|
|
157452
157630
|
const msg = e instanceof Error ? e.message : String(e);
|
|
157453
157631
|
if (!msg.includes("No provider for") && !msg.includes("not supported")) {
|
|
157454
|
-
|
|
157632
|
+
logger215.warn(`currentRoom sensor update failed: ${msg}`);
|
|
157455
157633
|
}
|
|
157456
157634
|
}
|
|
157457
157635
|
}
|
|
@@ -157466,7 +157644,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
|
|
|
157466
157644
|
const serviceArea = this.agent.get(ServiceAreaBehavior);
|
|
157467
157645
|
if (serviceArea.state.currentArea !== areaId) {
|
|
157468
157646
|
serviceArea.state.currentArea = areaId;
|
|
157469
|
-
|
|
157647
|
+
logger215.debug(`currentArea set to ${areaId}`);
|
|
157470
157648
|
}
|
|
157471
157649
|
this.updateProgress(serviceArea, areaId);
|
|
157472
157650
|
} catch {
|
|
@@ -157819,14 +157997,14 @@ init_esm();
|
|
|
157819
157997
|
|
|
157820
157998
|
// src/matter/behaviors/service-area-server.ts
|
|
157821
157999
|
init_esm();
|
|
157822
|
-
var
|
|
158000
|
+
var logger216 = Logger.get("ServiceAreaServer");
|
|
157823
158001
|
var ServiceAreaWithProgress = ServiceAreaBehavior.with(
|
|
157824
158002
|
ServiceArea3.Feature.ProgressReporting
|
|
157825
158003
|
);
|
|
157826
158004
|
var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
157827
158005
|
selectAreas(request) {
|
|
157828
158006
|
const { newAreas } = request;
|
|
157829
|
-
|
|
158007
|
+
logger216.info(
|
|
157830
158008
|
`ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
|
|
157831
158009
|
);
|
|
157832
158010
|
const uniqueAreas = [...new Set(newAreas)];
|
|
@@ -157835,7 +158013,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
|
157835
158013
|
(id) => !supportedAreaIds.includes(id)
|
|
157836
158014
|
);
|
|
157837
158015
|
if (invalidAreas.length > 0) {
|
|
157838
|
-
|
|
158016
|
+
logger216.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
|
|
157839
158017
|
return {
|
|
157840
158018
|
status: ServiceArea3.SelectAreasStatus.UnsupportedArea,
|
|
157841
158019
|
statusText: `Invalid area IDs: ${invalidAreas.join(", ")}`
|
|
@@ -157846,7 +158024,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
|
157846
158024
|
areaId,
|
|
157847
158025
|
status: ServiceArea3.OperationalStatus.Pending
|
|
157848
158026
|
}));
|
|
157849
|
-
|
|
158027
|
+
logger216.info(
|
|
157850
158028
|
`ServiceArea: Stored ${uniqueAreas.length} areas for cleaning: ${uniqueAreas.join(", ")}`
|
|
157851
158029
|
);
|
|
157852
158030
|
return {
|
|
@@ -157867,7 +158045,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
|
|
|
157867
158045
|
ServiceAreaServerBase2.State = State;
|
|
157868
158046
|
})(ServiceAreaServerBase || (ServiceAreaServerBase = {}));
|
|
157869
158047
|
function ServiceAreaServer2(initialState) {
|
|
157870
|
-
|
|
158048
|
+
logger216.info(
|
|
157871
158049
|
`Creating ServiceAreaServer with ${initialState.supportedAreas.length} areas`
|
|
157872
158050
|
);
|
|
157873
158051
|
return ServiceAreaServerBase.set({
|
|
@@ -157884,7 +158062,7 @@ var ServiceAreaWithMapsAndProgress = ServiceAreaBehavior.with(
|
|
|
157884
158062
|
var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress {
|
|
157885
158063
|
selectAreas(request) {
|
|
157886
158064
|
const { newAreas } = request;
|
|
157887
|
-
|
|
158065
|
+
logger216.info(
|
|
157888
158066
|
`ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
|
|
157889
158067
|
);
|
|
157890
158068
|
const uniqueAreas = [...new Set(newAreas)];
|
|
@@ -157893,7 +158071,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
|
|
|
157893
158071
|
(id) => !supportedAreaIds.includes(id)
|
|
157894
158072
|
);
|
|
157895
158073
|
if (invalidAreas.length > 0) {
|
|
157896
|
-
|
|
158074
|
+
logger216.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
|
|
157897
158075
|
return {
|
|
157898
158076
|
status: ServiceArea3.SelectAreasStatus.UnsupportedArea,
|
|
157899
158077
|
statusText: `Invalid area IDs: ${invalidAreas.join(", ")}`
|
|
@@ -157904,7 +158082,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
|
|
|
157904
158082
|
areaId,
|
|
157905
158083
|
status: ServiceArea3.OperationalStatus.Pending
|
|
157906
158084
|
}));
|
|
157907
|
-
|
|
158085
|
+
logger216.info(
|
|
157908
158086
|
`ServiceArea: Stored ${uniqueAreas.length} areas for cleaning: ${uniqueAreas.join(", ")}`
|
|
157909
158087
|
);
|
|
157910
158088
|
return {
|
|
@@ -157925,14 +158103,14 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
|
|
|
157925
158103
|
ServiceAreaServerWithMapsBase2.State = State;
|
|
157926
158104
|
})(ServiceAreaServerWithMapsBase || (ServiceAreaServerWithMapsBase = {}));
|
|
157927
158105
|
function ServiceAreaServerWithMaps(initialState) {
|
|
157928
|
-
|
|
158106
|
+
logger216.info(
|
|
157929
158107
|
`Creating ServiceAreaServer with Maps: ${initialState.supportedAreas.length} areas, ${initialState.supportedMaps.length} maps`
|
|
157930
158108
|
);
|
|
157931
158109
|
for (const map of initialState.supportedMaps) {
|
|
157932
158110
|
const areaCount = initialState.supportedAreas.filter(
|
|
157933
158111
|
(a) => a.mapId === map.mapId
|
|
157934
158112
|
).length;
|
|
157935
|
-
|
|
158113
|
+
logger216.info(` Map ${map.mapId}: "${map.name}" (${areaCount} areas)`);
|
|
157936
158114
|
}
|
|
157937
158115
|
return ServiceAreaServerWithMapsBase.set({
|
|
157938
158116
|
supportedAreas: initialState.supportedAreas,
|
|
@@ -157944,7 +158122,7 @@ function ServiceAreaServerWithMaps(initialState) {
|
|
|
157944
158122
|
}
|
|
157945
158123
|
|
|
157946
158124
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-service-area-server.ts
|
|
157947
|
-
var
|
|
158125
|
+
var logger217 = Logger.get("VacuumServiceAreaServer");
|
|
157948
158126
|
function toAreaId(roomId) {
|
|
157949
158127
|
if (typeof roomId === "number") {
|
|
157950
158128
|
return roomId;
|
|
@@ -158023,13 +158201,13 @@ function createVacuumServiceAreaServer(attributes8, roomEntities, includeUnnamed
|
|
|
158023
158201
|
let rooms;
|
|
158024
158202
|
if (roomEntities && roomEntities.length > 0) {
|
|
158025
158203
|
rooms = buttonEntitiesToRooms(roomEntities, attributes8);
|
|
158026
|
-
|
|
158204
|
+
logger217.info(
|
|
158027
158205
|
`Using ${rooms.length} button entities as rooms: ${rooms.map((r) => r.name).join(", ")}`
|
|
158028
158206
|
);
|
|
158029
158207
|
} else {
|
|
158030
158208
|
rooms = parseVacuumRooms(attributes8, includeUnnamedRooms);
|
|
158031
158209
|
if (rooms.length > 0) {
|
|
158032
|
-
|
|
158210
|
+
logger217.info(
|
|
158033
158211
|
`Using ${rooms.length} rooms from attributes: ${rooms.map((r) => r.name).join(", ")}`
|
|
158034
158212
|
);
|
|
158035
158213
|
}
|
|
@@ -158083,7 +158261,7 @@ function createCustomServiceAreaServer(customAreas) {
|
|
|
158083
158261
|
landmarkInfo: null
|
|
158084
158262
|
}
|
|
158085
158263
|
}));
|
|
158086
|
-
|
|
158264
|
+
logger217.info(
|
|
158087
158265
|
`Using ${customAreas.length} custom service areas: ${customAreas.map((a) => a.name).join(", ")}`
|
|
158088
158266
|
);
|
|
158089
158267
|
return ServiceAreaServer2({
|
|
@@ -158105,7 +158283,7 @@ function createCleanAreaServiceAreaServer(cleanAreaRooms) {
|
|
|
158105
158283
|
landmarkInfo: null
|
|
158106
158284
|
}
|
|
158107
158285
|
}));
|
|
158108
|
-
|
|
158286
|
+
logger217.info(
|
|
158109
158287
|
`Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA: ${cleanAreaRooms.map((r) => r.name).join(", ")}`
|
|
158110
158288
|
);
|
|
158111
158289
|
return ServiceAreaServer2({
|
|
@@ -158116,11 +158294,11 @@ function createCleanAreaServiceAreaServer(cleanAreaRooms) {
|
|
|
158116
158294
|
}
|
|
158117
158295
|
|
|
158118
158296
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-run-mode-server.ts
|
|
158119
|
-
var
|
|
158297
|
+
var logger218 = Logger.get("VacuumRvcRunModeServer");
|
|
158120
158298
|
function buildValetudoSegmentAction(vacuumEntityId, segmentIds, valetudoIdentifier) {
|
|
158121
158299
|
const identifier = valetudoIdentifier || vacuumEntityId.replace(/^vacuum\.valetudo_/, "");
|
|
158122
158300
|
const topic = `valetudo/${identifier}/MapSegmentationCapability/clean/set`;
|
|
158123
|
-
|
|
158301
|
+
logger218.info(
|
|
158124
158302
|
`Valetudo: mqtt.publish to ${topic}, segments: ${segmentIds.join(", ")}`
|
|
158125
158303
|
);
|
|
158126
158304
|
return {
|
|
@@ -158204,14 +158382,14 @@ function mergeBatchData(areas) {
|
|
|
158204
158382
|
function handleCustomServiceAreas(selectedAreas, customAreas, session) {
|
|
158205
158383
|
const matched = selectedAreas.map((areaId) => ({ areaId, area: customAreas[areaId - 1] })).filter((m) => !!m.area);
|
|
158206
158384
|
if (matched.length === 0) {
|
|
158207
|
-
|
|
158385
|
+
logger218.warn(
|
|
158208
158386
|
`Custom service areas: no match for selected IDs ${selectedAreas.join(", ")}`
|
|
158209
158387
|
);
|
|
158210
158388
|
return { action: "vacuum.start" };
|
|
158211
158389
|
}
|
|
158212
158390
|
const batchArea = matched.find(({ area }) => area.batchDispatch === true);
|
|
158213
158391
|
if (batchArea) {
|
|
158214
|
-
|
|
158392
|
+
logger218.info(
|
|
158215
158393
|
`Custom service areas (batch): single call for ${matched.length} room(s): ${matched.map(({ area }) => area.name).join(", ")}`
|
|
158216
158394
|
);
|
|
158217
158395
|
session.pendingDispatches = [];
|
|
@@ -158232,7 +158410,7 @@ function handleCustomServiceAreas(selectedAreas, customAreas, session) {
|
|
|
158232
158410
|
}
|
|
158233
158411
|
};
|
|
158234
158412
|
}
|
|
158235
|
-
|
|
158413
|
+
logger218.info(
|
|
158236
158414
|
`Custom service areas: ${matched.length} room(s) queued: ${matched.map(({ area }) => `${area.service} (${area.name})`).join(", ")}`
|
|
158237
158415
|
);
|
|
158238
158416
|
session.pendingDispatches = matched.slice(1).map(({ areaId, area }) => ({
|
|
@@ -158268,7 +158446,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158268
158446
|
VacuumState.paused
|
|
158269
158447
|
];
|
|
158270
158448
|
const isCleaning = cleaningStates.includes(state);
|
|
158271
|
-
|
|
158449
|
+
logger218.debug(
|
|
158272
158450
|
`Vacuum state: "${state}", isCleaning: ${isCleaning}, currentMode: ${isCleaning ? "Cleaning" : "Idle"}`
|
|
158273
158451
|
);
|
|
158274
158452
|
return isCleaning ? 1 /* Cleaning */ : 0 /* Idle */;
|
|
@@ -158300,7 +158478,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158300
158478
|
if (cleanAreaRooms && cleanAreaRooms.length > 0) {
|
|
158301
158479
|
const haAreaIds = resolveCleanAreaIds(selectedAreas, cleanAreaRooms);
|
|
158302
158480
|
if (haAreaIds.length > 0) {
|
|
158303
|
-
|
|
158481
|
+
logger218.info(
|
|
158304
158482
|
`CLEAN_AREA: cleaning HA areas: ${haAreaIds.join(", ")}`
|
|
158305
158483
|
);
|
|
158306
158484
|
return {
|
|
@@ -158319,7 +158497,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158319
158497
|
}
|
|
158320
158498
|
}
|
|
158321
158499
|
if (matched.length > 0) {
|
|
158322
|
-
|
|
158500
|
+
logger218.info(
|
|
158323
158501
|
`Roborock: ${matched.length} room button(s) queued: ${matched.map((m) => m.entityId).join(", ")}`
|
|
158324
158502
|
);
|
|
158325
158503
|
session.pendingDispatches = matched.slice(1).map(({ areaId, entityId }) => ({
|
|
@@ -158353,14 +158531,14 @@ var vacuumRvcRunModeConfig = {
|
|
|
158353
158531
|
}
|
|
158354
158532
|
}
|
|
158355
158533
|
if (roomIds.length > 0) {
|
|
158356
|
-
|
|
158534
|
+
logger218.info(
|
|
158357
158535
|
`Starting cleaning with selected areas: ${roomIds.join(", ")}`
|
|
158358
158536
|
);
|
|
158359
158537
|
if (isDreameVacuum(attributes8)) {
|
|
158360
158538
|
if (targetMapName) {
|
|
158361
158539
|
const vacName = vacuumEntityId.replace("vacuum.", "");
|
|
158362
158540
|
const selectedMapEntity = `select.${vacName}_selected_map`;
|
|
158363
|
-
|
|
158541
|
+
logger218.info(
|
|
158364
158542
|
`Dreame multi-floor: switching to map "${targetMapName}" via ${selectedMapEntity}`
|
|
158365
158543
|
);
|
|
158366
158544
|
homeAssistant.callAction({
|
|
@@ -158387,7 +158565,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158387
158565
|
}
|
|
158388
158566
|
if (isEcovacsVacuum(attributes8)) {
|
|
158389
158567
|
const roomIdStr = roomIds.join(",");
|
|
158390
|
-
|
|
158568
|
+
logger218.info(
|
|
158391
158569
|
`Ecovacs vacuum: Using spot_area for rooms: ${roomIdStr}`
|
|
158392
158570
|
);
|
|
158393
158571
|
return {
|
|
@@ -158402,14 +158580,14 @@ var vacuumRvcRunModeConfig = {
|
|
|
158402
158580
|
}
|
|
158403
158581
|
};
|
|
158404
158582
|
}
|
|
158405
|
-
|
|
158583
|
+
logger218.warn(
|
|
158406
158584
|
`Room cleaning via send_command not supported for this vacuum type. Rooms: ${roomIds.join(", ")}. Falling back to vacuum.start`
|
|
158407
158585
|
);
|
|
158408
158586
|
}
|
|
158409
158587
|
}
|
|
158410
158588
|
} catch {
|
|
158411
158589
|
}
|
|
158412
|
-
|
|
158590
|
+
logger218.info("Starting regular cleaning (no areas selected)");
|
|
158413
158591
|
return { action: "vacuum.start" };
|
|
158414
158592
|
},
|
|
158415
158593
|
returnToBase: () => ({ action: "vacuum.return_to_base" }),
|
|
@@ -158424,7 +158602,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158424
158602
|
const homeAssistant = agent.get(HomeAssistantEntityBehavior);
|
|
158425
158603
|
const entity = homeAssistant.entity;
|
|
158426
158604
|
const attributes8 = entity.state.attributes;
|
|
158427
|
-
|
|
158605
|
+
logger218.info(`cleanRoom called: roomMode=${roomMode}`);
|
|
158428
158606
|
const cleanAreaRooms = homeAssistant.state.mapping?.cleanAreaRooms;
|
|
158429
158607
|
if (cleanAreaRooms && cleanAreaRooms.length > 0) {
|
|
158430
158608
|
const sorted = [...cleanAreaRooms].sort(
|
|
@@ -158433,7 +158611,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158433
158611
|
const areaIndex = roomMode - ROOM_MODE_BASE2 - 1;
|
|
158434
158612
|
if (areaIndex >= 0 && areaIndex < sorted.length) {
|
|
158435
158613
|
const area = sorted[areaIndex];
|
|
158436
|
-
|
|
158614
|
+
logger218.info(
|
|
158437
158615
|
`cleanRoom: CLEAN_AREA "${area.name}" \u2192 vacuum.clean_area(${area.haAreaId})`
|
|
158438
158616
|
);
|
|
158439
158617
|
return {
|
|
@@ -158450,7 +158628,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158450
158628
|
const areaIndex = roomMode - ROOM_MODE_BASE2 - 1;
|
|
158451
158629
|
if (areaIndex >= 0 && areaIndex < sorted.length) {
|
|
158452
158630
|
const area = sorted[areaIndex];
|
|
158453
|
-
|
|
158631
|
+
logger218.info(
|
|
158454
158632
|
`cleanRoom: custom service area "${area.name}" \u2192 ${area.service}`
|
|
158455
158633
|
);
|
|
158456
158634
|
return {
|
|
@@ -158471,7 +158649,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158471
158649
|
}
|
|
158472
158650
|
const rooms = parseVacuumRooms(attributes8);
|
|
158473
158651
|
const numericIdFromMode = getRoomIdFromMode(roomMode);
|
|
158474
|
-
|
|
158652
|
+
logger218.info(
|
|
158475
158653
|
`cleanRoom: numericIdFromMode=${numericIdFromMode}, available rooms: ${JSON.stringify(rooms.map((r) => ({ id: r.id, name: r.name, modeValue: getRoomModeValue(r) })))}`
|
|
158476
158654
|
);
|
|
158477
158655
|
const room = rooms.find((r) => getRoomModeValue(r) === roomMode);
|
|
@@ -158481,7 +158659,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158481
158659
|
if (room.mapName) {
|
|
158482
158660
|
const vacuumName = vacuumEntityId.replace("vacuum.", "");
|
|
158483
158661
|
const selectedMapEntity = `select.${vacuumName}_selected_map`;
|
|
158484
|
-
|
|
158662
|
+
logger218.info(
|
|
158485
158663
|
`Dreame multi-floor: switching to map "${room.mapName}" via ${selectedMapEntity}`
|
|
158486
158664
|
);
|
|
158487
158665
|
homeAssistant.callAction({
|
|
@@ -158490,7 +158668,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158490
158668
|
data: { option: room.mapName }
|
|
158491
158669
|
});
|
|
158492
158670
|
}
|
|
158493
|
-
|
|
158671
|
+
logger218.debug(
|
|
158494
158672
|
`Dreame vacuum detected, using dreame_vacuum.vacuum_clean_segment for room ${room.name} (commandId: ${commandId3}, id: ${room.id})`
|
|
158495
158673
|
);
|
|
158496
158674
|
return {
|
|
@@ -158501,7 +158679,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158501
158679
|
};
|
|
158502
158680
|
}
|
|
158503
158681
|
if (isRoborockVacuum(attributes8) || isXiaomiMiotVacuum(attributes8)) {
|
|
158504
|
-
|
|
158682
|
+
logger218.debug(
|
|
158505
158683
|
`Using vacuum.send_command with app_segment_clean for room ${room.name} (commandId: ${commandId3}, id: ${room.id})`
|
|
158506
158684
|
);
|
|
158507
158685
|
return {
|
|
@@ -158514,7 +158692,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158514
158692
|
}
|
|
158515
158693
|
if (isEcovacsVacuum(attributes8)) {
|
|
158516
158694
|
const roomIdStr = String(commandId3);
|
|
158517
|
-
|
|
158695
|
+
logger218.info(
|
|
158518
158696
|
`Ecovacs vacuum: Using spot_area for room ${room.name} (id: ${roomIdStr})`
|
|
158519
158697
|
);
|
|
158520
158698
|
return {
|
|
@@ -158529,7 +158707,7 @@ var vacuumRvcRunModeConfig = {
|
|
|
158529
158707
|
}
|
|
158530
158708
|
};
|
|
158531
158709
|
}
|
|
158532
|
-
|
|
158710
|
+
logger218.warn(
|
|
158533
158711
|
`Room cleaning via send_command not supported for this vacuum type. Room: ${room.name} (id=${commandId3}). Falling back to vacuum.start`
|
|
158534
158712
|
);
|
|
158535
158713
|
}
|
|
@@ -158545,20 +158723,20 @@ function createVacuumRvcRunModeServer(attributes8, includeUnnamedRooms = false,
|
|
|
158545
158723
|
includeUnnamedRooms,
|
|
158546
158724
|
customAreas
|
|
158547
158725
|
);
|
|
158548
|
-
|
|
158726
|
+
logger218.info(
|
|
158549
158727
|
`Creating VacuumRvcRunModeServer with ${rooms.length} rooms, ${supportedModes.length} total modes`
|
|
158550
158728
|
);
|
|
158551
158729
|
if (rooms.length > 0) {
|
|
158552
|
-
|
|
158730
|
+
logger218.info(`Rooms found: ${rooms.map((r) => r.name).join(", ")}`);
|
|
158553
158731
|
}
|
|
158554
158732
|
if (filteredCount > 0) {
|
|
158555
158733
|
const filtered = allRooms.filter((r) => !rooms.some((x) => x.id === r.id));
|
|
158556
|
-
|
|
158734
|
+
logger218.info(
|
|
158557
158735
|
`Filtered out ${filteredCount} unnamed room(s): ${filtered.map((r) => r.name).join(", ")}`
|
|
158558
158736
|
);
|
|
158559
158737
|
}
|
|
158560
158738
|
if (allRooms.length === 0) {
|
|
158561
|
-
|
|
158739
|
+
logger218.debug(
|
|
158562
158740
|
`No rooms found. Attributes: rooms=${JSON.stringify(attributes8.rooms)}, segments=${JSON.stringify(attributes8.segments)}, room_list=${attributes8.room_list}`
|
|
158563
158741
|
);
|
|
158564
158742
|
}
|
|
@@ -158592,7 +158770,7 @@ function createCleanAreaRvcRunModeServer(cleanAreaRooms) {
|
|
|
158592
158770
|
modeTags: [{ value: RvcRunMode3.ModeTag.Cleaning }]
|
|
158593
158771
|
});
|
|
158594
158772
|
}
|
|
158595
|
-
|
|
158773
|
+
logger218.info(
|
|
158596
158774
|
`Creating CLEAN_AREA RvcRunModeServer with ${cleanAreaRooms.length} HA areas, ${modes.length} total modes`
|
|
158597
158775
|
);
|
|
158598
158776
|
return RvcRunModeServer2(vacuumRvcRunModeConfig, {
|
|
@@ -158652,7 +158830,7 @@ init_nodejs();
|
|
|
158652
158830
|
|
|
158653
158831
|
// src/matter/behaviors/rvc-clean-mode-server.ts
|
|
158654
158832
|
init_home_assistant_entity_behavior();
|
|
158655
|
-
var
|
|
158833
|
+
var logger219 = Logger.get("RvcCleanModeServerBase");
|
|
158656
158834
|
var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeServer {
|
|
158657
158835
|
// Pending mode from a recent changeToMode command.
|
|
158658
158836
|
// Prevents stale HA state (from a different entity like select.xxx)
|
|
@@ -158699,14 +158877,14 @@ var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeS
|
|
|
158699
158877
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
158700
158878
|
const { newMode } = request;
|
|
158701
158879
|
if (newMode !== this.state.currentMode && !this.state.supportedModes.some((m) => m.mode === newMode)) {
|
|
158702
|
-
|
|
158880
|
+
logger219.warn(`changeToMode(${newMode}) rejected: unsupported mode`);
|
|
158703
158881
|
return {
|
|
158704
158882
|
status: ModeBase3.ModeChangeStatus.UnsupportedMode,
|
|
158705
158883
|
statusText: `Unsupported mode: ${newMode}`
|
|
158706
158884
|
};
|
|
158707
158885
|
}
|
|
158708
158886
|
const modeLabel = this.state.supportedModes.find((m) => m.mode === newMode);
|
|
158709
|
-
|
|
158887
|
+
logger219.info(
|
|
158710
158888
|
`changeToMode(${newMode}) "${modeLabel?.label ?? "unknown"}" for ${homeAssistant.entityId}`
|
|
158711
158889
|
);
|
|
158712
158890
|
this.pendingMode = newMode;
|
|
@@ -158714,7 +158892,7 @@ var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeS
|
|
|
158714
158892
|
this.state.currentMode = newMode;
|
|
158715
158893
|
const action = this.state.config.setCleanMode(newMode, this.agent);
|
|
158716
158894
|
if (action) {
|
|
158717
|
-
|
|
158895
|
+
logger219.info(
|
|
158718
158896
|
`changeToMode: dispatching action ${action.action} \u2192 ${action.target ?? homeAssistant.entityId}`
|
|
158719
158897
|
);
|
|
158720
158898
|
homeAssistant.callAction(action);
|
|
@@ -158747,7 +158925,7 @@ function RvcCleanModeServer2(config11, initialState) {
|
|
|
158747
158925
|
}
|
|
158748
158926
|
|
|
158749
158927
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-clean-mode-server.ts
|
|
158750
|
-
var
|
|
158928
|
+
var logger220 = Logger.get("VacuumRvcCleanModeServer");
|
|
158751
158929
|
var MODE_VACUUM = 0;
|
|
158752
158930
|
var MODE_VACUUM_AND_MOP = 1;
|
|
158753
158931
|
var MODE_MOP = 2;
|
|
@@ -159017,7 +159195,7 @@ function findMatchingCleanOption(ct, availableOptions) {
|
|
|
159017
159195
|
const match = availableOptions.find((o) => classifyCleanOption(o) === type);
|
|
159018
159196
|
if (match) return match;
|
|
159019
159197
|
}
|
|
159020
|
-
|
|
159198
|
+
logger220.warn(
|
|
159021
159199
|
`No match for ${CLEAN_TYPE_LABELS[ct]} in [${availableOptions.join(", ")}]`
|
|
159022
159200
|
);
|
|
159023
159201
|
return availableOptions[0];
|
|
@@ -159026,7 +159204,7 @@ function buildCleaningModeAction(targetCleanType, agent) {
|
|
|
159026
159204
|
const selectEntityId = getCleaningModeSelectEntity(agent);
|
|
159027
159205
|
const { options } = readSelectEntity(selectEntityId, agent);
|
|
159028
159206
|
const optionToUse = findMatchingCleanOption(targetCleanType, options);
|
|
159029
|
-
|
|
159207
|
+
logger220.info(
|
|
159030
159208
|
`Switching cleaning mode to: ${optionToUse} via ${selectEntityId}`
|
|
159031
159209
|
);
|
|
159032
159210
|
return {
|
|
@@ -159115,7 +159293,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159115
159293
|
}
|
|
159116
159294
|
}
|
|
159117
159295
|
if (speedMode !== void 0) {
|
|
159118
|
-
|
|
159296
|
+
logger220.debug(
|
|
159119
159297
|
`Current mode: Vacuum + fan_speed="${speedState}" -> mode ${speedMode}`
|
|
159120
159298
|
);
|
|
159121
159299
|
return speedMode;
|
|
@@ -159136,7 +159314,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159136
159314
|
}
|
|
159137
159315
|
}
|
|
159138
159316
|
if (mopMode !== void 0) {
|
|
159139
|
-
|
|
159317
|
+
logger220.debug(
|
|
159140
159318
|
`Current mode: Mop + intensity="${state}" -> mode ${mopMode}`
|
|
159141
159319
|
);
|
|
159142
159320
|
return mopMode;
|
|
@@ -159154,14 +159332,14 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159154
159332
|
const homeAssistant = agent.get(HomeAssistantEntityBehavior);
|
|
159155
159333
|
const vacuumEntityId = homeAssistant.entityId;
|
|
159156
159334
|
const mapping = homeAssistant.state.mapping;
|
|
159157
|
-
|
|
159335
|
+
logger220.info(
|
|
159158
159336
|
`setCleanMode(${mode}) for ${vacuumEntityId}, suctionEntity=${mapping?.suctionLevelEntity ?? "none"}, mopEntity=${mapping?.mopIntensityEntity ?? "none"}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})}`
|
|
159159
159337
|
);
|
|
159160
159338
|
if (mopIntensityList && mopIntensityList.length > 0 && isMopIntensityMode(mode)) {
|
|
159161
159339
|
const mopIndex = mode - MOP_INTENSITY_MODE_BASE;
|
|
159162
159340
|
const mopName = mopIntensityList[mopIndex];
|
|
159163
159341
|
if (!mopName) {
|
|
159164
|
-
|
|
159342
|
+
logger220.warn(`Invalid mop intensity mode index: ${mopIndex}`);
|
|
159165
159343
|
return void 0;
|
|
159166
159344
|
}
|
|
159167
159345
|
if (hasCleanTypes) {
|
|
@@ -159174,18 +159352,18 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159174
159352
|
mapping.mopIntensityEntity,
|
|
159175
159353
|
agent
|
|
159176
159354
|
);
|
|
159177
|
-
|
|
159355
|
+
logger220.info(
|
|
159178
159356
|
`Mop intensity entity ${mapping.mopIntensityEntity}: current="${state}", options=${JSON.stringify(options ?? [])}`
|
|
159179
159357
|
);
|
|
159180
159358
|
let option = matchMopIntensityOption(mopName, options);
|
|
159181
159359
|
if (!option && options && mopIndex < options.length) {
|
|
159182
159360
|
option = options[mopIndex];
|
|
159183
|
-
|
|
159361
|
+
logger220.info(
|
|
159184
159362
|
`Positional match for mop "${mopName}" -> "${option}" (index ${mopIndex})`
|
|
159185
159363
|
);
|
|
159186
159364
|
}
|
|
159187
159365
|
if (option) {
|
|
159188
|
-
|
|
159366
|
+
logger220.info(
|
|
159189
159367
|
`Setting mop intensity to: ${option} via ${mapping.mopIntensityEntity}`
|
|
159190
159368
|
);
|
|
159191
159369
|
return {
|
|
@@ -159194,11 +159372,11 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159194
159372
|
target: mapping.mopIntensityEntity
|
|
159195
159373
|
};
|
|
159196
159374
|
}
|
|
159197
|
-
|
|
159375
|
+
logger220.warn(
|
|
159198
159376
|
`No match for mop intensity "${mopName}" in options: [${(options ?? []).join(", ")}]`
|
|
159199
159377
|
);
|
|
159200
159378
|
} else {
|
|
159201
|
-
|
|
159379
|
+
logger220.warn(
|
|
159202
159380
|
`Mop intensity mode ${mode} requested but no mopIntensityEntity configured`
|
|
159203
159381
|
);
|
|
159204
159382
|
}
|
|
@@ -159208,7 +159386,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159208
159386
|
const fanSpeedIndex = mode - FAN_SPEED_MODE_BASE;
|
|
159209
159387
|
const fanSpeedName = fanSpeedList[fanSpeedIndex];
|
|
159210
159388
|
if (!fanSpeedName) {
|
|
159211
|
-
|
|
159389
|
+
logger220.warn(`Invalid fan speed mode index: ${fanSpeedIndex}`);
|
|
159212
159390
|
return void 0;
|
|
159213
159391
|
}
|
|
159214
159392
|
if (mapping?.suctionLevelEntity) {
|
|
@@ -159221,7 +159399,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159221
159399
|
mapping.suctionLevelEntity,
|
|
159222
159400
|
agent
|
|
159223
159401
|
);
|
|
159224
|
-
|
|
159402
|
+
logger220.info(
|
|
159225
159403
|
`Suction entity ${mapping.suctionLevelEntity}: current="${state}", options=${JSON.stringify(options ?? [])}`
|
|
159226
159404
|
);
|
|
159227
159405
|
let option = matchFanSpeedOption(
|
|
@@ -159231,12 +159409,12 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159231
159409
|
);
|
|
159232
159410
|
if (!option && options && fanSpeedIndex < options.length) {
|
|
159233
159411
|
option = options[fanSpeedIndex];
|
|
159234
|
-
|
|
159412
|
+
logger220.info(
|
|
159235
159413
|
`Positional match for fan "${fanSpeedName}" -> "${option}" (index ${fanSpeedIndex})`
|
|
159236
159414
|
);
|
|
159237
159415
|
}
|
|
159238
159416
|
if (option) {
|
|
159239
|
-
|
|
159417
|
+
logger220.info(
|
|
159240
159418
|
`Setting suction to: ${option} via ${mapping.suctionLevelEntity}`
|
|
159241
159419
|
);
|
|
159242
159420
|
return {
|
|
@@ -159245,7 +159423,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159245
159423
|
target: mapping.suctionLevelEntity
|
|
159246
159424
|
};
|
|
159247
159425
|
}
|
|
159248
|
-
|
|
159426
|
+
logger220.warn(
|
|
159249
159427
|
`No match for fan speed "${fanSpeedName}" in suction options: [${(options ?? []).join(", ")}]`
|
|
159250
159428
|
);
|
|
159251
159429
|
return void 0;
|
|
@@ -159255,7 +159433,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159255
159433
|
buildCleaningModeAction(0 /* Sweeping */, agent)
|
|
159256
159434
|
);
|
|
159257
159435
|
}
|
|
159258
|
-
|
|
159436
|
+
logger220.info(
|
|
159259
159437
|
`Setting fan speed to: ${fanSpeedName} via vacuum.set_fan_speed`
|
|
159260
159438
|
);
|
|
159261
159439
|
return {
|
|
@@ -159265,7 +159443,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159265
159443
|
};
|
|
159266
159444
|
}
|
|
159267
159445
|
if (!hasCleanTypes) {
|
|
159268
|
-
|
|
159446
|
+
logger220.debug(
|
|
159269
159447
|
`Ignoring cleaning type change (mode=${mode}): no cleaning mode entity`
|
|
159270
159448
|
);
|
|
159271
159449
|
return void 0;
|
|
@@ -159277,7 +159455,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
|
|
|
159277
159455
|
agent
|
|
159278
159456
|
);
|
|
159279
159457
|
const optionToUse = findMatchingCleanOption(cleanType, availableOptions);
|
|
159280
|
-
|
|
159458
|
+
logger220.info(
|
|
159281
159459
|
`Setting cleaning mode to: ${optionToUse} (mode=${mode}) via ${selectEntityId}`
|
|
159282
159460
|
);
|
|
159283
159461
|
return {
|
|
@@ -159295,10 +159473,10 @@ function createVacuumRvcCleanModeServer(_attributes, fanSpeedList, mopIntensityL
|
|
|
159295
159473
|
cleaningModeOptions,
|
|
159296
159474
|
customFanSpeedTags
|
|
159297
159475
|
);
|
|
159298
|
-
|
|
159476
|
+
logger220.info(
|
|
159299
159477
|
`Creating VacuumRvcCleanModeServer with ${supportedModes.length} modes (fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, cleaningModeOptions=${JSON.stringify(cleaningModeOptions ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})})`
|
|
159300
159478
|
);
|
|
159301
|
-
|
|
159479
|
+
logger220.info(
|
|
159302
159480
|
`Modes: ${supportedModes.map((m) => `${m.mode}:${m.label}[${m.modeTags.map((t) => t.value).join(",")}]`).join(", ")}`
|
|
159303
159481
|
);
|
|
159304
159482
|
const initialState = {
|
|
@@ -159375,7 +159553,7 @@ init_nodejs();
|
|
|
159375
159553
|
init_home_assistant_entity_behavior();
|
|
159376
159554
|
var OperationalState4 = RvcOperationalState4.OperationalState;
|
|
159377
159555
|
var ErrorState = RvcOperationalState4.ErrorState;
|
|
159378
|
-
var
|
|
159556
|
+
var logger221 = Logger.get("RvcOperationalStateServer");
|
|
159379
159557
|
var activeStates = /* @__PURE__ */ new Set([
|
|
159380
159558
|
OperationalState4.Running,
|
|
159381
159559
|
OperationalState4.SeekingCharger
|
|
@@ -159427,7 +159605,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
159427
159605
|
{ force: true }
|
|
159428
159606
|
);
|
|
159429
159607
|
if (activeStates.has(previousState) && !activeStates.has(newState)) {
|
|
159430
|
-
|
|
159608
|
+
logger221.info(
|
|
159431
159609
|
`Operation completed: ${OperationalState4[previousState]} -> ${OperationalState4[newState]}`
|
|
159432
159610
|
);
|
|
159433
159611
|
try {
|
|
@@ -159440,7 +159618,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
159440
159618
|
this.context
|
|
159441
159619
|
);
|
|
159442
159620
|
} catch (e) {
|
|
159443
|
-
|
|
159621
|
+
logger221.debug("Failed to emit operationCompletion event:", e);
|
|
159444
159622
|
}
|
|
159445
159623
|
}
|
|
159446
159624
|
}
|
|
@@ -159475,7 +159653,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
|
|
|
159475
159653
|
const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
|
|
159476
159654
|
homeAssistant.callAction(goHomeAction(void 0, this.agent));
|
|
159477
159655
|
} else {
|
|
159478
|
-
|
|
159656
|
+
logger221.warn("GoHome command received but no goHome action configured");
|
|
159479
159657
|
}
|
|
159480
159658
|
return {
|
|
159481
159659
|
commandResponseState: {
|
|
@@ -159495,7 +159673,7 @@ function RvcOperationalStateServer2(config11) {
|
|
|
159495
159673
|
}
|
|
159496
159674
|
|
|
159497
159675
|
// src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-operational-state-server.ts
|
|
159498
|
-
var
|
|
159676
|
+
var logger222 = Logger.get("VacuumRvcOperationalStateServer");
|
|
159499
159677
|
function isCharging(entity) {
|
|
159500
159678
|
const attrs = entity.attributes;
|
|
159501
159679
|
if (attrs.is_charging === true || attrs.charging === true) return true;
|
|
@@ -159540,16 +159718,16 @@ function mapVacuumOperationalState(entity) {
|
|
|
159540
159718
|
operationalState = RvcOperationalState4.OperationalState.Error;
|
|
159541
159719
|
} else {
|
|
159542
159720
|
if (state.toLowerCase().includes("clean")) {
|
|
159543
|
-
|
|
159721
|
+
logger222.info(
|
|
159544
159722
|
`Unknown vacuum state "${state}" contains 'clean', treating as Running`
|
|
159545
159723
|
);
|
|
159546
159724
|
operationalState = RvcOperationalState4.OperationalState.Running;
|
|
159547
159725
|
} else {
|
|
159548
|
-
|
|
159726
|
+
logger222.info(`Unknown vacuum state "${state}", treating as Stopped`);
|
|
159549
159727
|
operationalState = RvcOperationalState4.OperationalState.Stopped;
|
|
159550
159728
|
}
|
|
159551
159729
|
}
|
|
159552
|
-
|
|
159730
|
+
logger222.debug(
|
|
159553
159731
|
`Vacuum operationalState: "${state}" -> ${RvcOperationalState4.OperationalState[operationalState]}`
|
|
159554
159732
|
);
|
|
159555
159733
|
return operationalState;
|
|
@@ -159574,7 +159752,7 @@ var VacuumRvcOperationalStateServer = RvcOperationalStateServer2({
|
|
|
159574
159752
|
});
|
|
159575
159753
|
|
|
159576
159754
|
// src/matter/endpoints/legacy/vacuum/index.ts
|
|
159577
|
-
var
|
|
159755
|
+
var logger223 = Logger.get("VacuumDevice");
|
|
159578
159756
|
var VacuumEndpointType = RoboticVacuumCleanerDevice.with(
|
|
159579
159757
|
BasicInformationServer2,
|
|
159580
159758
|
VacuumIdentifyServer,
|
|
@@ -159588,7 +159766,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
159588
159766
|
const entityId = homeAssistantEntity.entity.entity_id;
|
|
159589
159767
|
const attributes8 = homeAssistantEntity.entity.state.attributes;
|
|
159590
159768
|
const customAreas = homeAssistantEntity.mapping?.customServiceAreas;
|
|
159591
|
-
|
|
159769
|
+
logger223.info(
|
|
159592
159770
|
`Creating vacuum endpoint for ${entityId}, mapping: ${JSON.stringify(homeAssistantEntity.mapping ?? "none")}`
|
|
159593
159771
|
);
|
|
159594
159772
|
const cleanAreaRooms = homeAssistantEntity.mapping?.cleanAreaRooms;
|
|
@@ -159600,32 +159778,32 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
159600
159778
|
)
|
|
159601
159779
|
).set({ homeAssistantEntity });
|
|
159602
159780
|
if (includeOnOff) {
|
|
159603
|
-
|
|
159781
|
+
logger223.info(`${entityId}: Adding OnOff cluster (vacuumOnOff flag enabled)`);
|
|
159604
159782
|
device = device.with(VacuumOnOffServer);
|
|
159605
159783
|
}
|
|
159606
159784
|
device = device.with(VacuumPowerSourceServer);
|
|
159607
159785
|
const roomEntities = homeAssistantEntity.mapping?.roomEntities;
|
|
159608
159786
|
const rooms = parseVacuumRooms(attributes8);
|
|
159609
|
-
|
|
159787
|
+
logger223.info(
|
|
159610
159788
|
`${entityId}: customAreas=${customAreas?.length ?? 0}, roomEntities=${JSON.stringify(roomEntities ?? [])}, parsedRooms=${rooms.length}, cleanAreaRooms=${cleanAreaRooms?.length ?? 0}`
|
|
159611
159789
|
);
|
|
159612
159790
|
if (cleanAreaRooms && cleanAreaRooms.length > 0) {
|
|
159613
|
-
|
|
159791
|
+
logger223.info(
|
|
159614
159792
|
`${entityId}: Adding ServiceArea (${cleanAreaRooms.length} HA areas via CLEAN_AREA)`
|
|
159615
159793
|
);
|
|
159616
159794
|
device = device.with(createCleanAreaServiceAreaServer(cleanAreaRooms));
|
|
159617
159795
|
} else if (customAreas && customAreas.length > 0) {
|
|
159618
|
-
|
|
159796
|
+
logger223.info(
|
|
159619
159797
|
`${entityId}: Adding ServiceArea (${customAreas.length} custom areas)`
|
|
159620
159798
|
);
|
|
159621
159799
|
device = device.with(createCustomServiceAreaServer(customAreas));
|
|
159622
159800
|
} else if (rooms.length > 0 || roomEntities && roomEntities.length > 0) {
|
|
159623
|
-
|
|
159801
|
+
logger223.info(`${entityId}: Adding ServiceArea (${rooms.length} rooms)`);
|
|
159624
159802
|
device = device.with(
|
|
159625
159803
|
createVacuumServiceAreaServer(attributes8, roomEntities)
|
|
159626
159804
|
);
|
|
159627
159805
|
} else {
|
|
159628
|
-
|
|
159806
|
+
logger223.info(`${entityId}: Adding ServiceArea (default single-area)`);
|
|
159629
159807
|
device = device.with(createDefaultServiceAreaServer());
|
|
159630
159808
|
}
|
|
159631
159809
|
const fanSpeedList = resolveFanSpeedList(
|
|
@@ -159636,7 +159814,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
159636
159814
|
homeAssistantEntity.mapping?.mopIntensityEntity
|
|
159637
159815
|
);
|
|
159638
159816
|
if (cleaningModeOptions || fanSpeedList || mopIntensityList) {
|
|
159639
|
-
|
|
159817
|
+
logger223.info(
|
|
159640
159818
|
`${entityId}: Adding RvcCleanMode (multi-mode, cleaningModeOptions=${JSON.stringify(cleaningModeOptions ?? [])}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])})`
|
|
159641
159819
|
);
|
|
159642
159820
|
device = device.with(
|
|
@@ -159649,7 +159827,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
|
|
|
159649
159827
|
)
|
|
159650
159828
|
);
|
|
159651
159829
|
} else {
|
|
159652
|
-
|
|
159830
|
+
logger223.info(`${entityId}: Adding RvcCleanMode (default single-mode)`);
|
|
159653
159831
|
device = device.with(createDefaultRvcCleanModeServer());
|
|
159654
159832
|
}
|
|
159655
159833
|
return device;
|
|
@@ -159815,7 +159993,7 @@ var WaterHeaterThermostatServer = ThermostatServer2(
|
|
|
159815
159993
|
);
|
|
159816
159994
|
|
|
159817
159995
|
// src/matter/endpoints/legacy/water-heater/index.ts
|
|
159818
|
-
var
|
|
159996
|
+
var logger224 = Logger.get("WaterHeaterDevice");
|
|
159819
159997
|
var WaterHeaterDeviceType = ThermostatDevice.with(
|
|
159820
159998
|
BasicInformationServer2,
|
|
159821
159999
|
IdentifyServer2,
|
|
@@ -159831,7 +160009,7 @@ function toMatterTemp2(value) {
|
|
|
159831
160009
|
}
|
|
159832
160010
|
function WaterHeaterDevice(homeAssistantEntity) {
|
|
159833
160011
|
const attributes8 = homeAssistantEntity.entity.state.attributes;
|
|
159834
|
-
|
|
160012
|
+
logger224.debug(
|
|
159835
160013
|
`Creating device for ${homeAssistantEntity.entity.entity_id}, min_temp=${attributes8.min_temp}, max_temp=${attributes8.max_temp}`
|
|
159836
160014
|
);
|
|
159837
160015
|
const minLimit = toMatterTemp2(attributes8.min_temp) ?? 0;
|
|
@@ -160041,7 +160219,7 @@ var matterDeviceTypeFactories = {
|
|
|
160041
160219
|
};
|
|
160042
160220
|
|
|
160043
160221
|
// src/matter/endpoints/composed/user-composed-endpoint.ts
|
|
160044
|
-
var
|
|
160222
|
+
var logger225 = Logger.get("UserComposedEndpoint");
|
|
160045
160223
|
function stripBasicInformation(type) {
|
|
160046
160224
|
const behaviors = { ...type.behaviors };
|
|
160047
160225
|
delete behaviors.bridgedDeviceBasicInformation;
|
|
@@ -160097,7 +160275,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
160097
160275
|
{ vacuumOnOff: registry2.isVacuumOnOffEnabled() }
|
|
160098
160276
|
);
|
|
160099
160277
|
if (!primaryType) {
|
|
160100
|
-
|
|
160278
|
+
logger225.warn(
|
|
160101
160279
|
`Cannot create endpoint type for primary entity ${primaryEntityId}`
|
|
160102
160280
|
);
|
|
160103
160281
|
return void 0;
|
|
@@ -160112,7 +160290,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
160112
160290
|
if (!sub.entityId) continue;
|
|
160113
160291
|
const subPayload = buildEntityPayload4(registry2, sub.entityId);
|
|
160114
160292
|
if (!subPayload) {
|
|
160115
|
-
|
|
160293
|
+
logger225.warn(
|
|
160116
160294
|
`Cannot find entity state for composed sub-entity ${sub.entityId}`
|
|
160117
160295
|
);
|
|
160118
160296
|
continue;
|
|
@@ -160123,7 +160301,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
160123
160301
|
};
|
|
160124
160302
|
const subType = createLegacyEndpointType(subPayload, subMapping);
|
|
160125
160303
|
if (!subType) {
|
|
160126
|
-
|
|
160304
|
+
logger225.warn(
|
|
160127
160305
|
`Cannot create endpoint type for composed sub-entity ${sub.entityId}`
|
|
160128
160306
|
);
|
|
160129
160307
|
continue;
|
|
@@ -160136,7 +160314,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
160136
160314
|
mappedIds.push(sub.entityId);
|
|
160137
160315
|
}
|
|
160138
160316
|
if (parts.length < 2) {
|
|
160139
|
-
|
|
160317
|
+
logger225.warn(
|
|
160140
160318
|
`User composed device ${primaryEntityId}: only ${parts.length} sub-endpoint(s), need at least 2 (primary + one sub-entity). Falling back to standalone.`
|
|
160141
160319
|
);
|
|
160142
160320
|
return void 0;
|
|
@@ -160159,7 +160337,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
|
|
|
160159
160337
|
const labels = parts.map(
|
|
160160
160338
|
(_, i) => i === 0 ? primaryEntityId.split(".")[0] : composedEntities[i - 1]?.entityId?.split(".")[0] ?? "?"
|
|
160161
160339
|
).join("+");
|
|
160162
|
-
|
|
160340
|
+
logger225.info(
|
|
160163
160341
|
`Created user composed device ${primaryEntityId}: ${parts.length} sub-endpoint(s) [${labels}]`
|
|
160164
160342
|
);
|
|
160165
160343
|
return endpoint;
|
|
@@ -160247,7 +160425,7 @@ function asStandaloneEndpointType(type) {
|
|
|
160247
160425
|
}
|
|
160248
160426
|
|
|
160249
160427
|
// src/matter/endpoints/legacy/legacy-endpoint.ts
|
|
160250
|
-
var
|
|
160428
|
+
var logger226 = Logger.get("LegacyEndpoint");
|
|
160251
160429
|
var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
160252
160430
|
static async create(registry2, entityId, mapping, pluginDomainMappings, standalone = false) {
|
|
160253
160431
|
const deviceRegistry = registry2.deviceOf(entityId);
|
|
@@ -160257,25 +160435,25 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160257
160435
|
return;
|
|
160258
160436
|
}
|
|
160259
160437
|
if (registry2.isAutoBatteryMappingEnabled() && registry2.isBatteryEntityUsed(entityId)) {
|
|
160260
|
-
|
|
160438
|
+
logger226.debug(
|
|
160261
160439
|
`Skipping ${entityId} - already auto-assigned as battery to another device`
|
|
160262
160440
|
);
|
|
160263
160441
|
return;
|
|
160264
160442
|
}
|
|
160265
160443
|
if (registry2.isAutoHumidityMappingEnabled() && registry2.isHumidityEntityUsed(entityId)) {
|
|
160266
|
-
|
|
160444
|
+
logger226.debug(
|
|
160267
160445
|
`Skipping ${entityId} - already auto-assigned as humidity to a temperature sensor`
|
|
160268
160446
|
);
|
|
160269
160447
|
return;
|
|
160270
160448
|
}
|
|
160271
160449
|
if (registry2.isAutoPressureMappingEnabled() && registry2.isPressureEntityUsed(entityId)) {
|
|
160272
|
-
|
|
160450
|
+
logger226.debug(
|
|
160273
160451
|
`Skipping ${entityId} - already auto-assigned as pressure to a temperature sensor`
|
|
160274
160452
|
);
|
|
160275
160453
|
return;
|
|
160276
160454
|
}
|
|
160277
160455
|
if (registry2.isAutoComposedDevicesEnabled() && registry2.isComposedSubEntityUsed(entityId)) {
|
|
160278
|
-
|
|
160456
|
+
logger226.debug(
|
|
160279
160457
|
`Skipping ${entityId} - already consumed by a composed device`
|
|
160280
160458
|
);
|
|
160281
160459
|
return;
|
|
@@ -160295,7 +160473,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160295
160473
|
humidityEntity: humidityEntityId
|
|
160296
160474
|
};
|
|
160297
160475
|
registry2.markHumidityEntityUsed(humidityEntityId);
|
|
160298
|
-
|
|
160476
|
+
logger226.debug(
|
|
160299
160477
|
`Auto-assigned humidity ${humidityEntityId} to ${entityId}`
|
|
160300
160478
|
);
|
|
160301
160479
|
}
|
|
@@ -160314,7 +160492,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160314
160492
|
pressureEntity: pressureEntityId
|
|
160315
160493
|
};
|
|
160316
160494
|
registry2.markPressureEntityUsed(pressureEntityId);
|
|
160317
|
-
|
|
160495
|
+
logger226.debug(
|
|
160318
160496
|
`Auto-assigned pressure ${pressureEntityId} to ${entityId}`
|
|
160319
160497
|
);
|
|
160320
160498
|
}
|
|
@@ -160332,7 +160510,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160332
160510
|
batteryEntity: batteryEntityId
|
|
160333
160511
|
};
|
|
160334
160512
|
registry2.markBatteryEntityUsed(batteryEntityId);
|
|
160335
|
-
|
|
160513
|
+
logger226.debug(
|
|
160336
160514
|
`Auto-assigned battery ${batteryEntityId} to ${entityId}`
|
|
160337
160515
|
);
|
|
160338
160516
|
}
|
|
@@ -160350,7 +160528,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160350
160528
|
powerEntity: powerEntityId
|
|
160351
160529
|
};
|
|
160352
160530
|
registry2.markPowerEntityUsed(powerEntityId);
|
|
160353
|
-
|
|
160531
|
+
logger226.debug(`Auto-assigned power ${powerEntityId} to ${entityId}`);
|
|
160354
160532
|
}
|
|
160355
160533
|
}
|
|
160356
160534
|
}
|
|
@@ -160367,7 +160545,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160367
160545
|
energyEntity: energyEntityId
|
|
160368
160546
|
};
|
|
160369
160547
|
registry2.markEnergyEntityUsed(energyEntityId);
|
|
160370
|
-
|
|
160548
|
+
logger226.debug(
|
|
160371
160549
|
`Auto-assigned energy ${energyEntityId} to ${entityId}`
|
|
160372
160550
|
);
|
|
160373
160551
|
}
|
|
@@ -160383,7 +160561,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160383
160561
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
160384
160562
|
cleaningModeEntity: vacuumEntities.cleaningModeEntity
|
|
160385
160563
|
};
|
|
160386
|
-
|
|
160564
|
+
logger226.info(
|
|
160387
160565
|
`Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity} to ${entityId}`
|
|
160388
160566
|
);
|
|
160389
160567
|
}
|
|
@@ -160393,7 +160571,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160393
160571
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
160394
160572
|
suctionLevelEntity: vacuumEntities.suctionLevelEntity
|
|
160395
160573
|
};
|
|
160396
|
-
|
|
160574
|
+
logger226.info(
|
|
160397
160575
|
`Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity} to ${entityId}`
|
|
160398
160576
|
);
|
|
160399
160577
|
}
|
|
@@ -160403,7 +160581,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160403
160581
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
160404
160582
|
mopIntensityEntity: vacuumEntities.mopIntensityEntity
|
|
160405
160583
|
};
|
|
160406
|
-
|
|
160584
|
+
logger226.info(
|
|
160407
160585
|
`Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity} to ${entityId}`
|
|
160408
160586
|
);
|
|
160409
160587
|
}
|
|
@@ -160413,7 +160591,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160413
160591
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
160414
160592
|
currentRoomEntity: vacuumEntities.currentRoomEntity
|
|
160415
160593
|
};
|
|
160416
|
-
|
|
160594
|
+
logger226.info(
|
|
160417
160595
|
`Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity} to ${entityId}`
|
|
160418
160596
|
);
|
|
160419
160597
|
}
|
|
@@ -160428,7 +160606,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160428
160606
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
160429
160607
|
cleanAreaRooms
|
|
160430
160608
|
};
|
|
160431
|
-
|
|
160609
|
+
logger226.info(
|
|
160432
160610
|
`Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA for ${entityId}`
|
|
160433
160611
|
);
|
|
160434
160612
|
}
|
|
@@ -160449,7 +160627,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160449
160627
|
rooms: roomsObj
|
|
160450
160628
|
}
|
|
160451
160629
|
};
|
|
160452
|
-
|
|
160630
|
+
logger226.debug(
|
|
160453
160631
|
`Auto-detected ${valetudoRooms.length} Valetudo segments for ${entityId}`
|
|
160454
160632
|
);
|
|
160455
160633
|
} else {
|
|
@@ -160466,7 +160644,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160466
160644
|
rooms: roomsObj
|
|
160467
160645
|
}
|
|
160468
160646
|
};
|
|
160469
|
-
|
|
160647
|
+
logger226.debug(
|
|
160470
160648
|
`Auto-detected ${roborockRooms.length} Roborock rooms for ${entityId}`
|
|
160471
160649
|
);
|
|
160472
160650
|
}
|
|
@@ -160487,7 +160665,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160487
160665
|
if (composed) {
|
|
160488
160666
|
return composed;
|
|
160489
160667
|
}
|
|
160490
|
-
|
|
160668
|
+
logger226.warn(
|
|
160491
160669
|
`User composed device creation failed for ${entityId}, falling back to standalone`
|
|
160492
160670
|
);
|
|
160493
160671
|
}
|
|
@@ -160546,7 +160724,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160546
160724
|
if (composed) {
|
|
160547
160725
|
return composed;
|
|
160548
160726
|
}
|
|
160549
|
-
|
|
160727
|
+
logger226.warn(
|
|
160550
160728
|
`Companion fan creation failed for ${entityId}, falling back to standalone`
|
|
160551
160729
|
);
|
|
160552
160730
|
}
|
|
@@ -160613,11 +160791,11 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
|
|
|
160613
160791
|
}
|
|
160614
160792
|
if (mappedChanged) {
|
|
160615
160793
|
this.pendingMappedChange = true;
|
|
160616
|
-
|
|
160794
|
+
logger226.debug(
|
|
160617
160795
|
`Mapped entity change detected for ${this.entityId}, forcing update`
|
|
160618
160796
|
);
|
|
160619
160797
|
}
|
|
160620
|
-
|
|
160798
|
+
logger226.debug(
|
|
160621
160799
|
`State update received for ${this.entityId}: state=${state.state}`
|
|
160622
160800
|
);
|
|
160623
160801
|
this.lastState = state;
|
|
@@ -160670,7 +160848,7 @@ import {
|
|
|
160670
160848
|
getCollection
|
|
160671
160849
|
} from "home-assistant-js-websocket";
|
|
160672
160850
|
import { atLeastHaVersion } from "home-assistant-js-websocket/dist/util.js";
|
|
160673
|
-
var
|
|
160851
|
+
var logger227 = Logger.get("SubscribeEntities");
|
|
160674
160852
|
function processEvent(store, updates) {
|
|
160675
160853
|
const state = { ...store.state };
|
|
160676
160854
|
if (updates.a) {
|
|
@@ -160696,7 +160874,7 @@ function processEvent(store, updates) {
|
|
|
160696
160874
|
for (const entityId in updates.c) {
|
|
160697
160875
|
let entityState = state[entityId];
|
|
160698
160876
|
if (!entityState) {
|
|
160699
|
-
|
|
160877
|
+
logger227.warn("Received state update for unknown entity", entityId);
|
|
160700
160878
|
continue;
|
|
160701
160879
|
}
|
|
160702
160880
|
entityState = { ...entityState };
|
|
@@ -160785,7 +160963,7 @@ var subscribeEntities = (conn, onChange, entityIds) => {
|
|
|
160785
160963
|
// src/services/bridges/entity-isolation-service.ts
|
|
160786
160964
|
init_esm();
|
|
160787
160965
|
init_diagnostic_event_bus();
|
|
160788
|
-
var
|
|
160966
|
+
var logger228 = Logger.get("EntityIsolation");
|
|
160789
160967
|
var EntityIsolationServiceImpl = class {
|
|
160790
160968
|
isolatedEntities = /* @__PURE__ */ new Map();
|
|
160791
160969
|
isolationCallbacks = /* @__PURE__ */ new Map();
|
|
@@ -160850,13 +161028,13 @@ var EntityIsolationServiceImpl = class {
|
|
|
160850
161028
|
}
|
|
160851
161029
|
const parsed = this.parseEndpointPath(msg);
|
|
160852
161030
|
if (!parsed) {
|
|
160853
|
-
|
|
161031
|
+
logger228.warn("Could not parse entity from error:", msg);
|
|
160854
161032
|
return false;
|
|
160855
161033
|
}
|
|
160856
161034
|
const { bridgeId, entityName } = parsed;
|
|
160857
161035
|
const callback = this.isolationCallbacks.get(bridgeId);
|
|
160858
161036
|
if (!callback) {
|
|
160859
|
-
|
|
161037
|
+
logger228.warn(
|
|
160860
161038
|
`No isolation callback registered for bridge ${bridgeId}, entity: ${entityName}`
|
|
160861
161039
|
);
|
|
160862
161040
|
return false;
|
|
@@ -160867,7 +161045,7 @@ var EntityIsolationServiceImpl = class {
|
|
|
160867
161045
|
}
|
|
160868
161046
|
const reason = `${classification}. Entity isolated to protect bridge stability.`;
|
|
160869
161047
|
this.isolatedEntities.set(key, { entityId: entityName, reason });
|
|
160870
|
-
|
|
161048
|
+
logger228.warn(
|
|
160871
161049
|
`Isolating entity "${entityName}" from bridge ${bridgeId} due to: ${reason}`
|
|
160872
161050
|
);
|
|
160873
161051
|
diagnosticEventBus.emit("entity_error", `Entity isolated: ${entityName}`, {
|
|
@@ -160879,7 +161057,7 @@ var EntityIsolationServiceImpl = class {
|
|
|
160879
161057
|
await callback(entityName);
|
|
160880
161058
|
return true;
|
|
160881
161059
|
} catch (e) {
|
|
160882
|
-
|
|
161060
|
+
logger228.error(`Failed to isolate entity ${entityName}:`, e);
|
|
160883
161061
|
return false;
|
|
160884
161062
|
}
|
|
160885
161063
|
}
|
|
@@ -160910,6 +161088,7 @@ var EntityIsolationService = new EntityIsolationServiceImpl();
|
|
|
160910
161088
|
|
|
160911
161089
|
// src/services/bridges/bridge-endpoint-manager.ts
|
|
160912
161090
|
var MAX_ENTITY_ID_LENGTH = 150;
|
|
161091
|
+
var ENDPOINT_REMOVAL_GRACE_MS = 6e4;
|
|
160913
161092
|
var BridgeEndpointManager = class extends Service {
|
|
160914
161093
|
constructor(client, registry2, mappingStorage, bridgeId, log, pluginManager, pluginRegistry, pluginInstaller) {
|
|
160915
161094
|
super("BridgeEndpointManager");
|
|
@@ -160943,6 +161122,9 @@ var BridgeEndpointManager = class extends Service {
|
|
|
160943
161122
|
unsubscribe;
|
|
160944
161123
|
_failedEntities = [];
|
|
160945
161124
|
mappingFingerprints = /* @__PURE__ */ new Map();
|
|
161125
|
+
// entityId -> first time it went missing from the registry (grace window)
|
|
161126
|
+
pendingRemovals = /* @__PURE__ */ new Map();
|
|
161127
|
+
removalRecheckTimer = null;
|
|
160946
161128
|
pluginEndpoints = /* @__PURE__ */ new Map();
|
|
160947
161129
|
pluginStateUpdating = /* @__PURE__ */ new Set();
|
|
160948
161130
|
pluginListeners = /* @__PURE__ */ new Map();
|
|
@@ -161145,7 +161327,25 @@ var BridgeEndpointManager = class extends Service {
|
|
|
161145
161327
|
} catch (e) {
|
|
161146
161328
|
this.log.error(`Failed to delete isolated endpoint:`, e);
|
|
161147
161329
|
}
|
|
161330
|
+
this.pendingRemovals.delete(endpoint.entityId);
|
|
161331
|
+
this.mappingFingerprints.delete(endpoint.entityId);
|
|
161332
|
+
}
|
|
161333
|
+
}
|
|
161334
|
+
// refreshDevices only runs on registry-fingerprint changes, which may not
|
|
161335
|
+
// recur, so drive any held removals to completion ourselves once the grace
|
|
161336
|
+
// window has passed.
|
|
161337
|
+
scheduleRemovalRecheck() {
|
|
161338
|
+
if (this.removalRecheckTimer) {
|
|
161339
|
+
clearTimeout(this.removalRecheckTimer);
|
|
161340
|
+
this.removalRecheckTimer = null;
|
|
161148
161341
|
}
|
|
161342
|
+
if (this.pendingRemovals.size === 0) return;
|
|
161343
|
+
this.removalRecheckTimer = setTimeout(() => {
|
|
161344
|
+
this.removalRecheckTimer = null;
|
|
161345
|
+
this.refreshDevices().catch(
|
|
161346
|
+
(e) => this.log.warn("Endpoint removal recheck failed:", e)
|
|
161347
|
+
);
|
|
161348
|
+
}, ENDPOINT_REMOVAL_GRACE_MS + 5e3);
|
|
161149
161349
|
}
|
|
161150
161350
|
getPluginDomainMappings() {
|
|
161151
161351
|
if (!this.pluginManager) return void 0;
|
|
@@ -161166,6 +161366,11 @@ var BridgeEndpointManager = class extends Service {
|
|
|
161166
161366
|
}
|
|
161167
161367
|
async dispose() {
|
|
161168
161368
|
this.stopObserving();
|
|
161369
|
+
if (this.removalRecheckTimer) {
|
|
161370
|
+
clearTimeout(this.removalRecheckTimer);
|
|
161371
|
+
this.removalRecheckTimer = null;
|
|
161372
|
+
}
|
|
161373
|
+
this.pendingRemovals.clear();
|
|
161169
161374
|
EntityIsolationService.unregisterIsolationCallback(this.bridgeId);
|
|
161170
161375
|
EntityIsolationService.clearIsolatedEntities(this.bridgeId);
|
|
161171
161376
|
const endpoints = this.root.parts.map((p) => p);
|
|
@@ -161232,14 +161437,30 @@ var BridgeEndpointManager = class extends Service {
|
|
|
161232
161437
|
}
|
|
161233
161438
|
}
|
|
161234
161439
|
const existingEndpoints = [];
|
|
161440
|
+
const now = Date.now();
|
|
161235
161441
|
for (const endpoint of endpoints) {
|
|
161236
|
-
|
|
161442
|
+
const present = this.entityIds.includes(endpoint.entityId);
|
|
161443
|
+
if (present) {
|
|
161444
|
+
this.pendingRemovals.delete(endpoint.entityId);
|
|
161445
|
+
}
|
|
161446
|
+
if (!present) {
|
|
161447
|
+
const since = this.pendingRemovals.get(endpoint.entityId);
|
|
161448
|
+
if (since == null) {
|
|
161449
|
+
this.pendingRemovals.set(endpoint.entityId, now);
|
|
161450
|
+
existingEndpoints.push(endpoint);
|
|
161451
|
+
continue;
|
|
161452
|
+
}
|
|
161453
|
+
if (now - since < ENDPOINT_REMOVAL_GRACE_MS) {
|
|
161454
|
+
existingEndpoints.push(endpoint);
|
|
161455
|
+
continue;
|
|
161456
|
+
}
|
|
161237
161457
|
try {
|
|
161238
161458
|
await endpoint.delete();
|
|
161239
161459
|
} catch (e) {
|
|
161240
161460
|
this.log.warn(`Failed to delete endpoint ${endpoint.entityId}:`, e);
|
|
161241
161461
|
}
|
|
161242
161462
|
this.mappingFingerprints.delete(endpoint.entityId);
|
|
161463
|
+
this.pendingRemovals.delete(endpoint.entityId);
|
|
161243
161464
|
} else if (this.registry.isAutoComposedDevicesEnabled() && this.registry.isComposedSubEntityUsed(endpoint.entityId)) {
|
|
161244
161465
|
this.log.info(
|
|
161245
161466
|
`Deleting standalone endpoint ${endpoint.entityId}, consumed by composed device`
|
|
@@ -161275,6 +161496,7 @@ var BridgeEndpointManager = class extends Service {
|
|
|
161275
161496
|
}
|
|
161276
161497
|
}
|
|
161277
161498
|
}
|
|
161499
|
+
this.scheduleRemovalRecheck();
|
|
161278
161500
|
let memoryLimitReached = false;
|
|
161279
161501
|
for (const entityId of this.entityIds) {
|
|
161280
161502
|
if (!memoryLimitReached && isHeapUnderPressure()) {
|
|
@@ -162159,35 +162381,15 @@ init_dist();
|
|
|
162159
162381
|
init_diagnostic_event_bus();
|
|
162160
162382
|
var AUTO_FORCE_SYNC_INTERVAL_MS2 = 9e4;
|
|
162161
162383
|
var DEAD_SESSION_TIMEOUT_MS2 = 6e4;
|
|
162162
|
-
var DEFAULT_SESSION_MAX_AGE_HOURS = 4;
|
|
162163
|
-
var SESSION_MAX_AGE_HOURS_RANGE = { min: 1, max: 168 };
|
|
162164
|
-
var ROTATION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
162165
|
-
function parseSessionMaxAgeHours(raw) {
|
|
162166
|
-
if (raw == null || raw === "") return DEFAULT_SESSION_MAX_AGE_HOURS;
|
|
162167
|
-
const n = Number.parseInt(raw, 10);
|
|
162168
|
-
if (Number.isNaN(n) || n < 0) return null;
|
|
162169
|
-
if (n === 0) return 0;
|
|
162170
|
-
const { min, max } = SESSION_MAX_AGE_HOURS_RANGE;
|
|
162171
|
-
if (n < min) return min;
|
|
162172
|
-
if (n > max) return max;
|
|
162173
|
-
return n;
|
|
162174
|
-
}
|
|
162175
|
-
function seedExistingSessionStarts(startedAt, sessions, now = Date.now()) {
|
|
162176
|
-
for (const session of sessions) {
|
|
162177
|
-
if (!startedAt.has(session.id)) {
|
|
162178
|
-
startedAt.set(session.id, now);
|
|
162179
|
-
}
|
|
162180
|
-
}
|
|
162181
|
-
}
|
|
162182
162384
|
function makeWarmStartState(state, now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
162183
162385
|
return { ...state, last_updated: now };
|
|
162184
162386
|
}
|
|
162185
162387
|
var ServerModeBridge = class {
|
|
162186
|
-
constructor(
|
|
162388
|
+
constructor(logger231, dataProvider, endpointManager, server) {
|
|
162187
162389
|
this.dataProvider = dataProvider;
|
|
162188
162390
|
this.endpointManager = endpointManager;
|
|
162189
162391
|
this.server = server;
|
|
162190
|
-
this.log =
|
|
162392
|
+
this.log = logger231.get(`ServerModeBridge / ${dataProvider.id}`);
|
|
162191
162393
|
}
|
|
162192
162394
|
dataProvider;
|
|
162193
162395
|
endpointManager;
|
|
@@ -162801,7 +163003,7 @@ function ServerModeVacuumDevice(homeAssistantEntity, includeOnOff = false, clean
|
|
|
162801
163003
|
}
|
|
162802
163004
|
|
|
162803
163005
|
// src/matter/endpoints/server-mode-vacuum-endpoint.ts
|
|
162804
|
-
var
|
|
163006
|
+
var logger229 = Logger.get("ServerModeVacuumEndpoint");
|
|
162805
163007
|
var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEndpoint {
|
|
162806
163008
|
static async create(registry2, entityId, mapping) {
|
|
162807
163009
|
const deviceRegistry = registry2.deviceOf(entityId);
|
|
@@ -162811,7 +163013,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
162811
163013
|
return void 0;
|
|
162812
163014
|
}
|
|
162813
163015
|
let effectiveMapping = mapping;
|
|
162814
|
-
|
|
163016
|
+
logger229.info(
|
|
162815
163017
|
`${entityId}: device_id=${entity.device_id}, manualBattery=${mapping?.batteryEntity ?? "none"}`
|
|
162816
163018
|
);
|
|
162817
163019
|
if (entity.device_id) {
|
|
@@ -162826,15 +163028,15 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
162826
163028
|
batteryEntity: batteryEntityId
|
|
162827
163029
|
};
|
|
162828
163030
|
registry2.markBatteryEntityUsed(batteryEntityId);
|
|
162829
|
-
|
|
163031
|
+
logger229.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
|
|
162830
163032
|
} else {
|
|
162831
163033
|
const attrs = state.attributes;
|
|
162832
163034
|
if (attrs.battery_level != null || attrs.battery != null) {
|
|
162833
|
-
|
|
163035
|
+
logger229.info(
|
|
162834
163036
|
`${entityId}: No battery entity found, using battery attribute from vacuum state`
|
|
162835
163037
|
);
|
|
162836
163038
|
} else {
|
|
162837
|
-
|
|
163039
|
+
logger229.warn(
|
|
162838
163040
|
`${entityId}: No battery entity found for device ${entity.device_id}`
|
|
162839
163041
|
);
|
|
162840
163042
|
}
|
|
@@ -162849,7 +163051,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
162849
163051
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
162850
163052
|
cleaningModeEntity: vacuumEntities.cleaningModeEntity
|
|
162851
163053
|
};
|
|
162852
|
-
|
|
163054
|
+
logger229.info(
|
|
162853
163055
|
`${entityId}: Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity}`
|
|
162854
163056
|
);
|
|
162855
163057
|
}
|
|
@@ -162859,7 +163061,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
162859
163061
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
162860
163062
|
suctionLevelEntity: vacuumEntities.suctionLevelEntity
|
|
162861
163063
|
};
|
|
162862
|
-
|
|
163064
|
+
logger229.info(
|
|
162863
163065
|
`${entityId}: Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity}`
|
|
162864
163066
|
);
|
|
162865
163067
|
}
|
|
@@ -162869,7 +163071,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
162869
163071
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
162870
163072
|
mopIntensityEntity: vacuumEntities.mopIntensityEntity
|
|
162871
163073
|
};
|
|
162872
|
-
|
|
163074
|
+
logger229.info(
|
|
162873
163075
|
`${entityId}: Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity}`
|
|
162874
163076
|
);
|
|
162875
163077
|
}
|
|
@@ -162879,7 +163081,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
162879
163081
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
162880
163082
|
currentRoomEntity: vacuumEntities.currentRoomEntity
|
|
162881
163083
|
};
|
|
162882
|
-
|
|
163084
|
+
logger229.info(
|
|
162883
163085
|
`${entityId}: Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity}`
|
|
162884
163086
|
);
|
|
162885
163087
|
}
|
|
@@ -162894,7 +163096,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
162894
163096
|
entityId: effectiveMapping?.entityId ?? entityId,
|
|
162895
163097
|
cleanAreaRooms
|
|
162896
163098
|
};
|
|
162897
|
-
|
|
163099
|
+
logger229.info(
|
|
162898
163100
|
`${entityId}: Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA`
|
|
162899
163101
|
);
|
|
162900
163102
|
}
|
|
@@ -162915,7 +163117,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
162915
163117
|
rooms: roomsObj
|
|
162916
163118
|
}
|
|
162917
163119
|
};
|
|
162918
|
-
|
|
163120
|
+
logger229.info(
|
|
162919
163121
|
`${entityId}: Auto-detected ${valetudoRooms.length} Valetudo segments`
|
|
162920
163122
|
);
|
|
162921
163123
|
} else {
|
|
@@ -162932,14 +163134,14 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
162932
163134
|
rooms: roomsObj
|
|
162933
163135
|
}
|
|
162934
163136
|
};
|
|
162935
|
-
|
|
163137
|
+
logger229.info(
|
|
162936
163138
|
`${entityId}: Auto-detected ${roborockRooms.length} Roborock rooms`
|
|
162937
163139
|
);
|
|
162938
163140
|
}
|
|
162939
163141
|
}
|
|
162940
163142
|
}
|
|
162941
163143
|
} else {
|
|
162942
|
-
|
|
163144
|
+
logger229.warn(`${entityId}: No device_id, cannot auto-assign battery`);
|
|
162943
163145
|
}
|
|
162944
163146
|
const payload = {
|
|
162945
163147
|
entity_id: entityId,
|
|
@@ -163042,7 +163244,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
163042
163244
|
try {
|
|
163043
163245
|
this.keepaliveCounter++;
|
|
163044
163246
|
const counter = this.keepaliveCounter;
|
|
163045
|
-
|
|
163247
|
+
logger229.info(`Keepalive #${counter} for ${this.entityId}`);
|
|
163046
163248
|
const opState = this.stateOf(RvcOperationalStateServer);
|
|
163047
163249
|
await this.setStateOf(RvcOperationalStateServer, {
|
|
163048
163250
|
operationalState: opState.operationalState,
|
|
@@ -163050,7 +163252,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
163050
163252
|
opState.operationalError.errorStateId
|
|
163051
163253
|
)
|
|
163052
163254
|
});
|
|
163053
|
-
|
|
163255
|
+
logger229.info(`Keepalive #${counter} committed for ${this.entityId}`);
|
|
163054
163256
|
} catch (e) {
|
|
163055
163257
|
if (e instanceof TransactionDestroyedError || e instanceof DestroyedDependencyError) {
|
|
163056
163258
|
return;
|
|
@@ -163059,7 +163261,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
163059
163261
|
if (msg.includes("Endpoint storage inaccessible")) {
|
|
163060
163262
|
return;
|
|
163061
163263
|
}
|
|
163062
|
-
|
|
163264
|
+
logger229.warn(`Keepalive failed for ${this.entityId}: ${msg}`);
|
|
163063
163265
|
}
|
|
163064
163266
|
}
|
|
163065
163267
|
async updateStates(states) {
|
|
@@ -163070,11 +163272,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
|
|
|
163070
163272
|
}
|
|
163071
163273
|
if (mappedChanged) {
|
|
163072
163274
|
this.pendingMappedChange = true;
|
|
163073
|
-
|
|
163275
|
+
logger229.debug(
|
|
163074
163276
|
`Mapped entity change detected for ${this.entityId}, forcing update`
|
|
163075
163277
|
);
|
|
163076
163278
|
}
|
|
163077
|
-
|
|
163279
|
+
logger229.debug(
|
|
163078
163280
|
`State update received for ${this.entityId}: state=${state.state}`
|
|
163079
163281
|
);
|
|
163080
163282
|
this.lastState = state;
|
|
@@ -163516,10 +163718,10 @@ var BridgeEnvironmentFactory = class extends BridgeFactory {
|
|
|
163516
163718
|
// src/core/ioc/app-environment.ts
|
|
163517
163719
|
var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
163518
163720
|
constructor(rootEnv, options) {
|
|
163519
|
-
const
|
|
163721
|
+
const logger231 = rootEnv.get(LoggerService);
|
|
163520
163722
|
super({
|
|
163521
163723
|
id: "App",
|
|
163522
|
-
log:
|
|
163724
|
+
log: logger231.get("AppContainer"),
|
|
163523
163725
|
parent: rootEnv
|
|
163524
163726
|
});
|
|
163525
163727
|
this.options = options;
|
|
@@ -163533,8 +163735,8 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
163533
163735
|
}
|
|
163534
163736
|
construction;
|
|
163535
163737
|
async init() {
|
|
163536
|
-
const
|
|
163537
|
-
this.set(LoggerService,
|
|
163738
|
+
const logger231 = this.get(LoggerService);
|
|
163739
|
+
this.set(LoggerService, logger231);
|
|
163538
163740
|
this.set(AppStorage, new AppStorage(await this.load(StorageService)));
|
|
163539
163741
|
this.set(BridgeStorage, new BridgeStorage(await this.load(AppStorage)));
|
|
163540
163742
|
this.set(
|
|
@@ -163551,7 +163753,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
163551
163753
|
);
|
|
163552
163754
|
this.set(
|
|
163553
163755
|
HomeAssistantClient,
|
|
163554
|
-
new HomeAssistantClient(
|
|
163756
|
+
new HomeAssistantClient(logger231, this.options.homeAssistant)
|
|
163555
163757
|
);
|
|
163556
163758
|
this.set(
|
|
163557
163759
|
HomeAssistantConfig,
|
|
@@ -163559,7 +163761,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
163559
163761
|
);
|
|
163560
163762
|
this.set(
|
|
163561
163763
|
HomeAssistantActions,
|
|
163562
|
-
new HomeAssistantActions(
|
|
163764
|
+
new HomeAssistantActions(logger231, await this.load(HomeAssistantClient))
|
|
163563
163765
|
);
|
|
163564
163766
|
this.set(
|
|
163565
163767
|
HomeAssistantRegistry,
|
|
@@ -163595,7 +163797,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
|
|
|
163595
163797
|
this.set(
|
|
163596
163798
|
WebApi,
|
|
163597
163799
|
new WebApi(
|
|
163598
|
-
|
|
163800
|
+
logger231,
|
|
163599
163801
|
await this.load(BridgeService),
|
|
163600
163802
|
await this.load(HomeAssistantClient),
|
|
163601
163803
|
await this.load(HomeAssistantRegistry),
|
|
@@ -163620,7 +163822,7 @@ init_esm();
|
|
|
163620
163822
|
init_nodejs();
|
|
163621
163823
|
|
|
163622
163824
|
// src/matter/patches/patch-level-control-tlv.ts
|
|
163623
|
-
var
|
|
163825
|
+
var logger230 = Logger.get("PatchLevelControlTlv");
|
|
163624
163826
|
function patchLevelControlTlv() {
|
|
163625
163827
|
let patched = 0;
|
|
163626
163828
|
const moveToLevelFields = LevelControl3.MoveToLevelRequest.fieldDefinitions;
|
|
@@ -163634,11 +163836,11 @@ function patchLevelControlTlv() {
|
|
|
163634
163836
|
patched++;
|
|
163635
163837
|
}
|
|
163636
163838
|
if (patched > 0) {
|
|
163637
|
-
|
|
163839
|
+
logger230.info(
|
|
163638
163840
|
`Patched ${patched} LevelControl TLV schema(s): transitionTime is now optional (Google Home compatibility)`
|
|
163639
163841
|
);
|
|
163640
163842
|
} else {
|
|
163641
|
-
|
|
163843
|
+
logger230.warn(
|
|
163642
163844
|
"Failed to patch LevelControl TLV schemas, field definitions not found. Google Home brightness adjustment may not work."
|
|
163643
163845
|
);
|
|
163644
163846
|
}
|