@riddix/hamh 2.1.0-alpha.614 → 2.1.0-alpha.616

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.
@@ -1743,8 +1743,8 @@ var init_Cancelable = __esm({
1743
1743
  };
1744
1744
  return result;
1745
1745
  }
1746
- static set logger(logger205) {
1747
- this.#logger = logger205;
1746
+ static set logger(logger206) {
1747
+ this.#logger = logger206;
1748
1748
  }
1749
1749
  static get logger() {
1750
1750
  return this.#logger;
@@ -3422,13 +3422,13 @@ var init_Logger = __esm({
3422
3422
  *
3423
3423
  * @deprecated use {@link destinations}
3424
3424
  */
3425
- static addLogger(identifier, logger205, options) {
3425
+ static addLogger(identifier, logger206, options) {
3426
3426
  if (identifier in this.destinations) {
3427
3427
  throw new ImplementationError(`Logger "${identifier}" already exists`);
3428
3428
  }
3429
3429
  const dest = LogDestination({ name: identifier });
3430
3430
  const legacy = adaptDestinationToLegacy(dest);
3431
- legacy.log = logger205;
3431
+ legacy.log = logger206;
3432
3432
  if (options?.defaultLogLevel !== void 0) {
3433
3433
  legacy.defaultLogLevel = options.defaultLogLevel;
3434
3434
  }
@@ -5538,8 +5538,8 @@ function Construction(subject, initializer) {
5538
5538
  }
5539
5539
  }
5540
5540
  function unhandledError(...args) {
5541
- const logger205 = Logger.get(subject.constructor.name);
5542
- logger205.error(...args);
5541
+ const logger206 = Logger.get(subject.constructor.name);
5542
+ logger206.error(...args);
5543
5543
  }
5544
5544
  function createErrorHandler(name) {
5545
5545
  return (e) => {
@@ -11896,7 +11896,7 @@ var init_ServerAddress = __esm({
11896
11896
  return Diagnostic.squash(...diagnostic);
11897
11897
  }
11898
11898
  ServerAddress2.diagnosticFor = diagnosticFor;
11899
- function isEqual(a, b) {
11899
+ function isEqual2(a, b) {
11900
11900
  if (a.type !== b.type) {
11901
11901
  return false;
11902
11902
  }
@@ -11908,7 +11908,7 @@ var init_ServerAddress = __esm({
11908
11908
  }
11909
11909
  return false;
11910
11910
  }
11911
- ServerAddress2.isEqual = isEqual;
11911
+ ServerAddress2.isEqual = isEqual2;
11912
11912
  function healthOf(health) {
11913
11913
  if (health.unhealthyAt === void 0) {
11914
11914
  return health;
@@ -135998,11 +135998,11 @@ var init_Api = __esm({
135998
135998
  }
135999
135999
  Api2.resourceFor = resourceFor;
136000
136000
  function log(level, facility, id, ...message) {
136001
- let logger205 = loggers.get(facility);
136002
- if (!logger205) {
136003
- loggers.set(facility, logger205 = Logger.get(facility));
136001
+ let logger206 = loggers.get(facility);
136002
+ if (!logger206) {
136003
+ loggers.set(facility, logger206 = Logger.get(facility));
136004
136004
  }
136005
- logger205[level](Diagnostic.via(id || "(anon)"), message);
136005
+ logger206[level](Diagnostic.via(id || "(anon)"), message);
136006
136006
  }
136007
136007
  Api2.log = log;
136008
136008
  function logRequest(facility, id, method, target) {
@@ -146105,6 +146105,7 @@ var init_clusters2 = __esm({
146105
146105
  ClusterId3["bridgedDeviceBasicInformation"] = "bridgedDeviceBasicInformation";
146106
146106
  ClusterId3["airQuality"] = "airQuality";
146107
146107
  ClusterId3["booleanState"] = "booleanState";
146108
+ ClusterId3["booleanStateConfiguration"] = "booleanStateConfiguration";
146108
146109
  ClusterId3["carbonDioxideConcentrationMeasurement"] = "carbonDioxideConcentrationMeasurement";
146109
146110
  ClusterId3["carbonMonoxideConcentrationMeasurement"] = "carbonMonoxideConcentrationMeasurement";
146110
146111
  ClusterId3["colorControl"] = "colorControl";
@@ -147038,10 +147039,13 @@ var init_color_converter = __esm({
147038
147039
  }
147039
147040
  /**
147040
147041
  * Convert Color Tempareture from Mireds to Kelvin
147041
- * @param temperatureMireds Temperature in Mireds
147042
- * @return Temperature in Kelvin
147042
+ * @param temperatureMireds Temperature in Mireds (must be finite and > 0)
147043
+ * @return Temperature in Kelvin, or null if the input is 0 / negative / non-finite
147043
147044
  */
147044
147045
  static temperatureMiredsToKelvin(temperatureMireds) {
147046
+ if (!Number.isFinite(temperatureMireds) || temperatureMireds <= 0) {
147047
+ return null;
147048
+ }
147045
147049
  return 1e6 / temperatureMireds;
147046
147050
  }
147047
147051
  /**
@@ -147327,10 +147331,10 @@ var init_home_assistant_actions = __esm({
147327
147331
  circuitBreakerResetMs: 3e4
147328
147332
  };
147329
147333
  HomeAssistantActions = class extends Service {
147330
- constructor(logger205, client, config10) {
147334
+ constructor(logger206, client, config10) {
147331
147335
  super("HomeAssistantActions");
147332
147336
  this.client = client;
147333
- this.log = logger205.get(this);
147337
+ this.log = logger206.get(this);
147334
147338
  this.config = { ...defaultConfig, ...config10 };
147335
147339
  this.circuitBreaker = new CircuitBreaker(
147336
147340
  this.config.circuitBreakerThreshold,
@@ -147670,10 +147674,10 @@ var DiagnosticService = class {
147670
147674
  };
147671
147675
 
147672
147676
  // src/api/access-log.ts
147673
- function accessLogger(logger205) {
147677
+ function accessLogger(logger206) {
147674
147678
  return (req, res, next) => {
147675
147679
  res.on("finish", () => {
147676
- logger205.debug(
147680
+ logger206.debug(
147677
147681
  `${req.method} ${decodeURI(req.originalUrl)} ${res.statusCode} ${res.statusMessage} from ${req.socket.remoteAddress}`
147678
147682
  );
147679
147683
  });
@@ -148153,7 +148157,9 @@ async function restoreBridgeIcon(zipDirectory, bridgeId, storageLocation) {
148153
148157
 
148154
148158
  // src/api/bridge-export-api.ts
148155
148159
  init_dist();
148160
+ init_esm();
148156
148161
  import express2 from "express";
148162
+ var logger142 = Logger.get("BridgeExportApi");
148157
148163
  function migrateFilter(legacyFilter) {
148158
148164
  if (!legacyFilter) {
148159
148165
  return { include: [], exclude: [] };
@@ -148302,8 +148308,10 @@ function bridgeExportApi(bridgeStorage) {
148302
148308
  }
148303
148309
  const result = { imported, skipped, errors };
148304
148310
  res.json(result);
148305
- } catch {
148306
- res.status(400).json({ error: "Failed to import bridges" });
148311
+ } catch (e) {
148312
+ const message = e instanceof Error ? e.message : String(e);
148313
+ logger142.warn(`Failed to import bridges: ${message}`, e);
148314
+ res.status(400).json({ error: `Failed to import bridges: ${message}` });
148307
148315
  }
148308
148316
  });
148309
148317
  return router;
@@ -150303,7 +150311,7 @@ init_esm();
150303
150311
  import { execFile } from "node:child_process";
150304
150312
  import * as fs4 from "node:fs";
150305
150313
  import * as path4 from "node:path";
150306
- var logger142 = Logger.get("PluginInstaller");
150314
+ var logger143 = Logger.get("PluginInstaller");
150307
150315
  var VALID_PACKAGE_RE = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*(@[^@\s]+)?$/;
150308
150316
  var PluginInstaller = class {
150309
150317
  pluginDir;
@@ -150343,7 +150351,7 @@ var PluginInstaller = class {
150343
150351
  error: `Invalid package name: "${packageName}"`
150344
150352
  };
150345
150353
  }
150346
- logger142.info(`Installing plugin: ${packageName}`);
150354
+ logger143.info(`Installing plugin: ${packageName}`);
150347
150355
  return new Promise((resolve6) => {
150348
150356
  execFile(
150349
150357
  "npm",
@@ -150355,7 +150363,7 @@ var PluginInstaller = class {
150355
150363
  },
150356
150364
  (error, _stdout, stderr) => {
150357
150365
  if (error) {
150358
- logger142.error(
150366
+ logger143.error(
150359
150367
  `Failed to install ${packageName}:`,
150360
150368
  stderr || error.message
150361
150369
  );
@@ -150367,7 +150375,7 @@ var PluginInstaller = class {
150367
150375
  return;
150368
150376
  }
150369
150377
  const version = this.getInstalledVersion(packageName);
150370
- logger142.info(
150378
+ logger143.info(
150371
150379
  `Successfully installed ${packageName}@${version || "unknown"}`
150372
150380
  );
150373
150381
  resolve6({
@@ -150387,7 +150395,7 @@ var PluginInstaller = class {
150387
150395
  error: `Invalid package name: "${packageName}"`
150388
150396
  };
150389
150397
  }
150390
- logger142.info(`Uninstalling plugin: ${packageName}`);
150398
+ logger143.info(`Uninstalling plugin: ${packageName}`);
150391
150399
  return new Promise((resolve6) => {
150392
150400
  execFile(
150393
150401
  "npm",
@@ -150398,7 +150406,7 @@ var PluginInstaller = class {
150398
150406
  },
150399
150407
  (error, _stdout, stderr) => {
150400
150408
  if (error) {
150401
- logger142.error(
150409
+ logger143.error(
150402
150410
  `Failed to uninstall ${packageName}:`,
150403
150411
  stderr || error.message
150404
150412
  );
@@ -150409,7 +150417,7 @@ var PluginInstaller = class {
150409
150417
  });
150410
150418
  return;
150411
150419
  }
150412
- logger142.info(`Successfully uninstalled ${packageName}`);
150420
+ logger143.info(`Successfully uninstalled ${packageName}`);
150413
150421
  resolve6({ success: true, packageName });
150414
150422
  }
150415
150423
  );
@@ -150459,7 +150467,7 @@ var PluginInstaller = class {
150459
150467
  return result;
150460
150468
  } catch (e) {
150461
150469
  const msg = e instanceof Error ? e.message : String(e);
150462
- logger142.error("Failed to install from tgz:", msg);
150470
+ logger143.error("Failed to install from tgz:", msg);
150463
150471
  return { success: false, packageName: "unknown", error: msg };
150464
150472
  } finally {
150465
150473
  try {
@@ -150546,7 +150554,7 @@ var PluginInstaller = class {
150546
150554
  }
150547
150555
  fs4.mkdirSync(path4.dirname(targetLink), { recursive: true });
150548
150556
  fs4.symlinkSync(resolvedPath, targetLink, "dir");
150549
- logger142.info(
150557
+ logger143.info(
150550
150558
  `Linked local plugin: ${packageName}@${pkg.version || "unknown"} \u2192 ${resolvedPath}`
150551
150559
  );
150552
150560
  return {
@@ -150577,7 +150585,7 @@ var PluginInstaller = class {
150577
150585
  init_esm();
150578
150586
  import * as fs5 from "node:fs";
150579
150587
  import * as path5 from "node:path";
150580
- var logger143 = Logger.get("PluginRegistry");
150588
+ var logger144 = Logger.get("PluginRegistry");
150581
150589
  var PluginRegistry = class {
150582
150590
  plugins = [];
150583
150591
  filePath;
@@ -150592,7 +150600,7 @@ var PluginRegistry = class {
150592
150600
  this.plugins = JSON.parse(raw);
150593
150601
  }
150594
150602
  } catch (e) {
150595
- logger143.warn("Failed to load plugin registry:", e);
150603
+ logger144.warn("Failed to load plugin registry:", e);
150596
150604
  this.plugins = [];
150597
150605
  }
150598
150606
  }
@@ -150608,7 +150616,7 @@ var PluginRegistry = class {
150608
150616
  "utf-8"
150609
150617
  );
150610
150618
  } catch (e) {
150611
- logger143.error("Failed to save plugin registry:", e);
150619
+ logger144.error("Failed to save plugin registry:", e);
150612
150620
  }
150613
150621
  }
150614
150622
  getAll() {
@@ -151022,7 +151030,7 @@ import { promisify } from "node:util";
151022
151030
  import v8 from "node:v8";
151023
151031
  import express15 from "express";
151024
151032
  var execAsync = promisify(exec);
151025
- var logger144 = Logger.get("SystemApi");
151033
+ var logger145 = Logger.get("SystemApi");
151026
151034
  function detectEnvironment2() {
151027
151035
  if (process.env.SUPERVISOR_TOKEN || process.env.HASSIO_TOKEN) {
151028
151036
  return "Home Assistant Add-on";
@@ -151067,7 +151075,7 @@ function systemApi(version) {
151067
151075
  environment: detectEnvironment2()
151068
151076
  });
151069
151077
  } catch (error) {
151070
- logger144.error("Failed to check for updates:", error);
151078
+ logger145.error("Failed to check for updates:", error);
151071
151079
  res.status(500).json({ error: "Failed to check for updates" });
151072
151080
  }
151073
151081
  });
@@ -151116,7 +151124,7 @@ function systemApi(version) {
151116
151124
  };
151117
151125
  res.json(systemInfo);
151118
151126
  } catch (error) {
151119
- logger144.error("Failed to get system info:", error);
151127
+ logger145.error("Failed to get system info:", error);
151120
151128
  res.status(500).json({ error: "Failed to get system info" });
151121
151129
  }
151122
151130
  });
@@ -151159,7 +151167,7 @@ async function getStorageInfo() {
151159
151167
  return await getUnixStorageInfo(pathToCheck);
151160
151168
  }
151161
151169
  } catch (error) {
151162
- logger144.error("Failed to get storage info:", error);
151170
+ logger145.error("Failed to get storage info:", error);
151163
151171
  return { total: 0, used: 0, free: 0 };
151164
151172
  }
151165
151173
  }
@@ -151389,7 +151397,7 @@ var WebSocketApi = class {
151389
151397
 
151390
151398
  // src/api/web-api.ts
151391
151399
  var WebApi = class extends Service {
151392
- constructor(logger205, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, lockCredentialStorage, settingsStorage, backupService, props) {
151400
+ constructor(logger206, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, lockCredentialStorage, settingsStorage, backupService, props) {
151393
151401
  super("WebApi");
151394
151402
  this.bridgeService = bridgeService;
151395
151403
  this.haClient = haClient;
@@ -151400,8 +151408,8 @@ var WebApi = class extends Service {
151400
151408
  this.settingsStorage = settingsStorage;
151401
151409
  this.backupService = backupService;
151402
151410
  this.props = props;
151403
- this.logger = logger205;
151404
- this.log = logger205.get(this);
151411
+ this.logger = logger206;
151412
+ this.log = logger206.get(this);
151405
151413
  this.accessLogger = accessLogger(this.log.createChild("Access Log"));
151406
151414
  this.startTime = Date.now();
151407
151415
  this.wsApi = new WebSocketApi(
@@ -151887,12 +151895,12 @@ var CustomStorage = class extends StorageBackendDisk {
151887
151895
 
151888
151896
  // src/core/app/storage.ts
151889
151897
  function storage(environment, options) {
151890
- const logger205 = environment.get(LoggerService).get("CustomStorage");
151898
+ const logger206 = environment.get(LoggerService).get("CustomStorage");
151891
151899
  const location2 = resolveStorageLocation(options.location);
151892
151900
  fs8.mkdirSync(location2, { recursive: true });
151893
151901
  const storageService = environment.get(StorageService);
151894
151902
  storageService.location = location2;
151895
- storageService.factory = (ns) => new CustomStorage(logger205, path8.resolve(location2, ns));
151903
+ storageService.factory = (ns) => new CustomStorage(logger206, path8.resolve(location2, ns));
151896
151904
  }
151897
151905
  function resolveStorageLocation(storageLocation) {
151898
151906
  const homedir = os5.homedir();
@@ -152328,23 +152336,30 @@ var BridgeService = class extends Service {
152328
152336
  }
152329
152337
  }
152330
152338
  async stopAll() {
152331
- for (const bridge of this.bridges) {
152332
- try {
152333
- await bridge.stop();
152334
- this.onBridgeChanged?.(bridge.id);
152335
- } catch (e) {
152336
- this.log.error(`Failed to stop bridge ${bridge.id}:`, e);
152337
- }
152338
- }
152339
+ await Promise.all(
152340
+ this.bridges.map(async (bridge) => {
152341
+ try {
152342
+ await bridge.stop();
152343
+ this.onBridgeChanged?.(bridge.id);
152344
+ } catch (e) {
152345
+ this.log.error(`Failed to stop bridge ${bridge.id}:`, e);
152346
+ }
152347
+ })
152348
+ );
152339
152349
  }
152340
152350
  async restartAll() {
152341
- for (const bridge of this.bridges) {
152342
- try {
152343
- await bridge.stop();
152344
- } catch (e) {
152345
- this.log.error(`Failed to stop bridge ${bridge.id} during restart:`, e);
152346
- }
152347
- }
152351
+ await Promise.all(
152352
+ this.bridges.map(async (bridge) => {
152353
+ try {
152354
+ await bridge.stop();
152355
+ } catch (e) {
152356
+ this.log.error(
152357
+ `Failed to stop bridge ${bridge.id} during restart:`,
152358
+ e
152359
+ );
152360
+ }
152361
+ })
152362
+ );
152348
152363
  const sortedBridges = [...this.bridges].sort((a, b) => {
152349
152364
  const priorityA = a.data.priority ?? 100;
152350
152365
  const priorityB = b.data.priority ?? 100;
@@ -152466,11 +152481,28 @@ import {
152466
152481
  ERR_INVALID_AUTH,
152467
152482
  getConfig
152468
152483
  } from "home-assistant-js-websocket";
152484
+ var TRANSIENT_CONNECT_ERROR_CODES = /* @__PURE__ */ new Set([
152485
+ "ECONNREFUSED",
152486
+ "ECONNRESET",
152487
+ "ETIMEDOUT",
152488
+ "ENOTFOUND",
152489
+ "EAI_AGAIN",
152490
+ "EHOSTUNREACH",
152491
+ "ENETUNREACH",
152492
+ "EPIPE"
152493
+ ]);
152494
+ function isTransientConnectError(reason) {
152495
+ if (reason === ERR_CANNOT_CONNECT) return true;
152496
+ const code = reason?.code;
152497
+ if (code && TRANSIENT_CONNECT_ERROR_CODES.has(code)) return true;
152498
+ const msg = reason instanceof Error ? reason.message : String(reason);
152499
+ return msg.includes("socket hang up") || msg.includes("tls") || msg.includes("TLS");
152500
+ }
152469
152501
  var HomeAssistantClient = class extends Service {
152470
- constructor(logger205, options) {
152502
+ constructor(logger206, options) {
152471
152503
  super("HomeAssistantClient");
152472
152504
  this.options = options;
152473
- this.log = logger205.get(this);
152505
+ this.log = logger206.get(this);
152474
152506
  }
152475
152507
  options;
152476
152508
  static Options = /* @__PURE__ */ Symbol.for("HomeAssistantClientProps");
@@ -152498,16 +152530,6 @@ var HomeAssistantClient = class extends Service {
152498
152530
  await this.waitForHomeAssistantToBeUpAndRunning(connection);
152499
152531
  return connection;
152500
152532
  } catch (reason) {
152501
- if (reason === ERR_CANNOT_CONNECT) {
152502
- this.log.warnCtx("Unable to connect to Home Assistant, retrying...", {
152503
- url: props.url,
152504
- attempt,
152505
- maxAttempts: maxConnectAttempts,
152506
- retryDelayMs: 5e3
152507
- });
152508
- await new Promise((resolve6) => setTimeout(resolve6, 5e3));
152509
- continue;
152510
- }
152511
152533
  if (reason === ERR_INVALID_AUTH) {
152512
152534
  this.log.errorCtx(
152513
152535
  "Authentication failed",
@@ -152518,6 +152540,17 @@ var HomeAssistantClient = class extends Service {
152518
152540
  "Authentication failed while connecting to home assistant"
152519
152541
  );
152520
152542
  }
152543
+ if (isTransientConnectError(reason)) {
152544
+ this.log.warnCtx("Unable to connect to Home Assistant, retrying...", {
152545
+ url: props.url,
152546
+ attempt,
152547
+ maxAttempts: maxConnectAttempts,
152548
+ retryDelayMs: 5e3,
152549
+ reason: reason instanceof Error ? reason.message : String(reason)
152550
+ });
152551
+ await new Promise((resolve6) => setTimeout(resolve6, 5e3));
152552
+ continue;
152553
+ }
152521
152554
  throw new Error(`Unable to connect to home assistant: ${reason}`);
152522
152555
  }
152523
152556
  }
@@ -152648,7 +152681,7 @@ async function getAreaRegistry(connection) {
152648
152681
  }
152649
152682
 
152650
152683
  // src/services/home-assistant/home-assistant-registry.ts
152651
- var logger145 = Logger.get("HomeAssistantRegistry");
152684
+ var logger146 = Logger.get("HomeAssistantRegistry");
152652
152685
  var HomeAssistantRegistry = class extends Service {
152653
152686
  constructor(client, options) {
152654
152687
  super("HomeAssistantRegistry");
@@ -152687,14 +152720,22 @@ var HomeAssistantRegistry = class extends Service {
152687
152720
  }
152688
152721
  enableAutoRefresh(onRefresh) {
152689
152722
  this.disableAutoRefresh();
152723
+ let refreshing = false;
152690
152724
  this.autoRefresh = setInterval(async () => {
152725
+ if (refreshing) {
152726
+ logger146.debug("Skipping registry refresh \u2014 previous tick still running");
152727
+ return;
152728
+ }
152729
+ refreshing = true;
152691
152730
  try {
152692
152731
  const changed = await this.reload();
152693
152732
  if (changed) {
152694
152733
  await onRefresh();
152695
152734
  }
152696
152735
  } catch (e) {
152697
- logger145.warn("Failed to refresh registry, will retry next interval:", e);
152736
+ logger146.warn("Failed to refresh registry, will retry next interval:", e);
152737
+ } finally {
152738
+ refreshing = false;
152698
152739
  }
152699
152740
  }, this.options.refreshInterval * 1e3);
152700
152741
  }
@@ -152710,7 +152751,7 @@ var HomeAssistantRegistry = class extends Service {
152710
152751
  baseDelayMs: 2e3,
152711
152752
  maxDelayMs: 3e4,
152712
152753
  onRetry: (attempt, error, delayMs) => {
152713
- logger145.warn(
152754
+ logger146.warn(
152714
152755
  `Registry fetch failed (attempt ${attempt}), retrying in ${delayMs}ms:`,
152715
152756
  error
152716
152757
  );
@@ -152720,7 +152761,7 @@ var HomeAssistantRegistry = class extends Service {
152720
152761
  async fetchRegistries() {
152721
152762
  const connection = this.client.connection;
152722
152763
  if (!connection.connected) {
152723
- logger145.debug("Connection not ready, waiting for reconnect...");
152764
+ logger146.debug("Connection not ready, waiting for reconnect...");
152724
152765
  await new Promise((resolve6) => {
152725
152766
  const timeout = setTimeout(() => {
152726
152767
  connection.removeEventListener("ready", onReady);
@@ -152739,19 +152780,15 @@ var HomeAssistantRegistry = class extends Service {
152739
152780
  }
152740
152781
  });
152741
152782
  }
152742
- const entityRegistry = await getRegistry(connection);
152743
- const statesList = await getStates(connection);
152744
- const deviceRegistry = await getDeviceRegistry(connection);
152745
- let labels = [];
152746
- try {
152747
- labels = await getLabelRegistry(connection);
152748
- } catch {
152749
- }
152750
- let areas = [];
152751
- try {
152752
- areas = await getAreaRegistry(connection);
152753
- } catch {
152754
- }
152783
+ const [entityRegistry, statesList, deviceRegistry, labels, areas] = await Promise.all([
152784
+ getRegistry(connection),
152785
+ getStates(connection),
152786
+ getDeviceRegistry(connection),
152787
+ getLabelRegistry(connection).catch(() => []),
152788
+ getAreaRegistry(connection).catch(
152789
+ () => []
152790
+ )
152791
+ ]);
152755
152792
  const hash2 = createHash("md5");
152756
152793
  for (const e of entityRegistry) {
152757
152794
  hash2.update(
@@ -152776,7 +152813,7 @@ var HomeAssistantRegistry = class extends Service {
152776
152813
  const fingerprint = hash2.digest("hex");
152777
152814
  this._states = keyBy(statesList, "entity_id");
152778
152815
  if (fingerprint === this.lastRegistryFingerprint) {
152779
- logger145.debug("Registry unchanged, skipping full refresh");
152816
+ logger146.debug("Registry unchanged, skipping full refresh");
152780
152817
  return false;
152781
152818
  }
152782
152819
  this.lastRegistryFingerprint = fingerprint;
@@ -152797,10 +152834,10 @@ var HomeAssistantRegistry = class extends Service {
152797
152834
  const missingDevices = fromPairs(missingDeviceIds.map((d) => [d, { id: d }]));
152798
152835
  this._devices = { ...missingDevices, ...realDevices };
152799
152836
  this._entities = allEntities;
152800
- logger145.debug(
152837
+ logger146.debug(
152801
152838
  `Loaded HA registry: ${keys(allEntities).length} entities, ${keys(realDevices).length} devices, ${keys(this._states).length} states`
152802
152839
  );
152803
- logMemoryUsage(logger145, "after HA registry load");
152840
+ logMemoryUsage(logger146, "after HA registry load");
152804
152841
  this._labels = labels;
152805
152842
  this._areas = new Map(areas.map((a) => [a.area_id, a.name]));
152806
152843
  return true;
@@ -153518,7 +153555,7 @@ var __privateIn2 = (member, obj) => Object(obj) !== obj ? __typeError40('Cannot
153518
153555
  var __privateGet2 = (obj, member, getter) => (__accessCheck2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
153519
153556
  var __privateSet2 = (obj, member, value, setter) => (__accessCheck2(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
153520
153557
  var __privateMethod2 = (obj, member, method) => (__accessCheck2(obj, member, "access private method"), method);
153521
- var logger146 = Logger.get("ScenesManagementServer");
153558
+ var logger147 = Logger.get("ScenesManagementServer");
153522
153559
  var UNDEFINED_SCENE_ID = 255;
153523
153560
  var GLOBAL_SCENE_ID = 0;
153524
153561
  var UNDEFINED_GROUP = GroupId(0);
@@ -153677,11 +153714,11 @@ var ScenesManagementServer = class extends ScenesManagementBase {
153677
153714
  return { status: Status2.ResourceExhausted, groupId: groupId22, sceneId };
153678
153715
  }
153679
153716
  this.state.sceneTable.push(sceneData);
153680
- logger146.debug(`Added scene ${sceneId} in group ${groupId22} for fabric ${fabricIndex}`);
153717
+ logger147.debug(`Added scene ${sceneId} in group ${groupId22} for fabric ${fabricIndex}`);
153681
153718
  this.#updateFabricSceneInfoCountsForFabric(fabricIndex);
153682
153719
  } else {
153683
153720
  this.state.sceneTable[existingSceneIndex] = sceneData;
153684
- logger146.debug(`Updated scene ${sceneId} in group ${groupId22} for fabric ${fabricIndex}`);
153721
+ logger147.debug(`Updated scene ${sceneId} in group ${groupId22} for fabric ${fabricIndex}`);
153685
153722
  }
153686
153723
  return { status: Status2.Success, groupId: groupId22, sceneId };
153687
153724
  }
@@ -153984,20 +154021,20 @@ var ScenesManagementServer = class extends ScenesManagementBase {
153984
154021
  }
153985
154022
  }
153986
154023
  if (fieldCount !== 2) {
153987
- logger146.warn(
154024
+ logger147.warn(
153988
154025
  `AttributeValuePair has invalid number (${fieldCount}) of fields (${serialize(attributeValuePair)})`
153989
154026
  );
153990
154027
  return void 0;
153991
154028
  }
153992
154029
  const value = attributeValuePair[mappedType];
153993
154030
  if (value === void 0) {
153994
- logger146.warn(
154031
+ logger147.warn(
153995
154032
  `AttributeValuePair missing value for mappedType ${mappedType} (${serialize(attributeValuePair)})`
153996
154033
  );
153997
154034
  return void 0;
153998
154035
  }
153999
154036
  if (typeof value !== "number" && typeof value !== "bigint") {
154000
- logger146.warn(
154037
+ logger147.warn(
154001
154038
  `AttributeValuePair has invalid non-numeric value for mappedType ${mappedType} (${serialize(attributeValuePair)})`
154002
154039
  // Should never happen
154003
154040
  );
@@ -154095,7 +154132,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
154095
154132
  } else if (schema6.schema.baseTypeMin < 0 && schema6.schema.min > schema6.schema.baseTypeMin) {
154096
154133
  return { attributeId, [mappedType]: schema6.schema.baseTypeMin };
154097
154134
  } else {
154098
- logger146.warn(
154135
+ logger147.warn(
154099
154136
  `Cannot determine out-of-bounds value for attribute schema, returning min value of datatype schema`
154100
154137
  );
154101
154138
  }
@@ -154116,7 +154153,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
154116
154153
  }
154117
154154
  }
154118
154155
  });
154119
- logger146.debug(`Collected scene attribute values on Endpoint ${this.endpoint.id}: ${serialize(sceneValues)}`);
154156
+ logger147.debug(`Collected scene attribute values on Endpoint ${this.endpoint.id}: ${serialize(sceneValues)}`);
154120
154157
  return sceneValues;
154121
154158
  }
154122
154159
  /**
@@ -154155,7 +154192,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
154155
154192
  }
154156
154193
  const attrType = attribute2.primitiveBase?.name;
154157
154194
  if (attrType === void 0 || DataTypeToSceneAttributeDataMap[attrType] === void 0) {
154158
- logger146.warn(
154195
+ logger147.warn(
154159
154196
  `Scene Attribute ${attribute2.name} on Cluster ${clusterName} has unsupported datatype ${attrType} for scene management on Endpoint ${this.endpoint.id}`
154160
154197
  );
154161
154198
  continue;
@@ -154170,7 +154207,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
154170
154207
  });
154171
154208
  }
154172
154209
  if (sceneClusterDetails) {
154173
- logger146.info(
154210
+ logger147.info(
154174
154211
  `Registered ${sceneClusterDetails.attributes.size} scene attributes for Cluster ${clusterName} on Endpoint ${this.endpoint.id}`
154175
154212
  );
154176
154213
  this.internal.endpointSceneableBehaviors.add(sceneClusterDetails);
@@ -154178,7 +154215,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
154178
154215
  }
154179
154216
  /** Apply scene attribute values in the various clusters on the endpoint. */
154180
154217
  #applySceneAttributeValues(sceneValues, transitionTime = null) {
154181
- logger146.debug(`Recalling scene on Endpoint ${this.endpoint.id} with values: ${serialize(sceneValues)}`);
154218
+ logger147.debug(`Recalling scene on Endpoint ${this.endpoint.id} with values: ${serialize(sceneValues)}`);
154182
154219
  const agent = this.endpoint.agentFor(this.context);
154183
154220
  const promises = [];
154184
154221
  for (const [clusterName, clusterAttributes] of Object.entries(sceneValues)) {
@@ -154189,7 +154226,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
154189
154226
  promises.push(result);
154190
154227
  }
154191
154228
  } else {
154192
- logger146.warn(
154229
+ logger147.warn(
154193
154230
  `No scenes implementation found for cluster ${clusterName} on Endpoint ${this.endpoint.id} during scene recall. Values are ignored`
154194
154231
  );
154195
154232
  }
@@ -154197,7 +154234,7 @@ var ScenesManagementServer = class extends ScenesManagementBase {
154197
154234
  if (promises.length) {
154198
154235
  return Promise.all(promises).then(
154199
154236
  () => void 0,
154200
- (error) => logger146.warn(`Error applying scene attribute values on Endpoint ${this.endpoint.id}:`, error)
154237
+ (error) => logger147.warn(`Error applying scene attribute values on Endpoint ${this.endpoint.id}:`, error)
154201
154238
  );
154202
154239
  }
154203
154240
  }
@@ -154388,7 +154425,7 @@ var GroupsBehaviorConstructor = ClusterBehavior.withInterface().for(Groups3.Clus
154388
154425
  var GroupsBehavior = GroupsBehaviorConstructor;
154389
154426
 
154390
154427
  // ../../node_modules/.pnpm/@matter+node@0.16.11/node_modules/@matter/node/dist/esm/behaviors/groups/GroupsServer.js
154391
- var logger147 = Logger.get("GroupsServer");
154428
+ var logger148 = Logger.get("GroupsServer");
154392
154429
  Groups3.Cluster.commands = {
154393
154430
  ...Groups3.Cluster.commands,
154394
154431
  addGroup: Command(
@@ -154452,7 +154489,7 @@ var GroupsServer = class extends GroupsBase {
154452
154489
  (fabric2, gkm) => gkm.addEndpointForGroup(fabric2, groupId3, endpointNumber, groupName)
154453
154490
  );
154454
154491
  } catch (error) {
154455
- logger147.error(error);
154492
+ logger148.error(error);
154456
154493
  StatusResponseError.accept(error);
154457
154494
  return { status: error.code, groupId: groupId3 };
154458
154495
  }
@@ -157492,7 +157529,7 @@ function miredsToXy(mireds) {
157492
157529
  }
157493
157530
 
157494
157531
  // ../../node_modules/.pnpm/@matter+node@0.16.11/node_modules/@matter/node/dist/esm/behaviors/color-control/ColorControlServer.js
157495
- var logger148 = Logger.get("ColorControlServer");
157532
+ var logger149 = Logger.get("ColorControlServer");
157496
157533
  var ColorControlBase = ColorControlBehavior.with(
157497
157534
  ColorControl3.Feature.HueSaturation,
157498
157535
  ColorControl3.Feature.EnhancedHue,
@@ -158673,7 +158710,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
158673
158710
  switch (oldMode) {
158674
158711
  case ColorControl3.ColorMode.CurrentHueAndCurrentSaturation:
158675
158712
  if (this.state.currentHue === void 0 || this.state.currentSaturation === void 0) {
158676
- logger148.warn("Could not convert from hue/saturation because one of them is undefined");
158713
+ logger149.warn("Could not convert from hue/saturation because one of them is undefined");
158677
158714
  break;
158678
158715
  }
158679
158716
  switch (newMode) {
@@ -158685,7 +158722,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
158685
158722
  case ColorControl3.ColorMode.ColorTemperatureMireds:
158686
158723
  const mireds = hsvToMireds(this.hue, this.saturation);
158687
158724
  if (mireds === void 0) {
158688
- logger148.warn(
158725
+ logger149.warn(
158689
158726
  `Could not convert hue/saturation (${this.hue}/${this.saturation}) to color temperature`
158690
158727
  );
158691
158728
  } else {
@@ -158696,7 +158733,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
158696
158733
  break;
158697
158734
  case ColorControl3.ColorMode.CurrentXAndCurrentY:
158698
158735
  if (this.state.currentX === void 0 || this.state.currentY === void 0) {
158699
- logger148.warn("Could not convert from xy because one of them is undefined");
158736
+ logger149.warn("Could not convert from xy because one of them is undefined");
158700
158737
  break;
158701
158738
  }
158702
158739
  switch (newMode) {
@@ -158708,7 +158745,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
158708
158745
  case ColorControl3.ColorMode.ColorTemperatureMireds:
158709
158746
  const mireds = xyToMireds(this.x, this.y);
158710
158747
  if (mireds === void 0) {
158711
- logger148.warn(`Could not convert xy ${this.x / this.y} to color temperature`);
158748
+ logger149.warn(`Could not convert xy ${this.x / this.y} to color temperature`);
158712
158749
  } else {
158713
158750
  this.mireds = mireds;
158714
158751
  }
@@ -158717,14 +158754,14 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
158717
158754
  break;
158718
158755
  case ColorControl3.ColorMode.ColorTemperatureMireds:
158719
158756
  if (this.state.colorTemperatureMireds === void 0) {
158720
- logger148.warn("Could not convert from color temperature because it is undefined");
158757
+ logger149.warn("Could not convert from color temperature because it is undefined");
158721
158758
  break;
158722
158759
  }
158723
158760
  switch (newMode) {
158724
158761
  case ColorControl3.ColorMode.CurrentHueAndCurrentSaturation:
158725
158762
  const hsvResult = miredsToHsv(this.mireds);
158726
158763
  if (hsvResult === void 0) {
158727
- logger148.warn(`Could not convert color temperature ${this.mireds} to hue/saturation`);
158764
+ logger149.warn(`Could not convert color temperature ${this.mireds} to hue/saturation`);
158728
158765
  } else {
158729
158766
  const [hue, saturation] = hsvResult;
158730
158767
  this.hue = hue;
@@ -158734,7 +158771,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
158734
158771
  case ColorControl3.ColorMode.CurrentXAndCurrentY:
158735
158772
  const xyResult = miredsToXy(this.mireds);
158736
158773
  if (xyResult === void 0) {
158737
- logger148.warn("Could not convert color temperature to xy");
158774
+ logger149.warn("Could not convert color temperature to xy");
158738
158775
  } else {
158739
158776
  const [x, y] = xyResult;
158740
158777
  this.x = x;
@@ -158783,7 +158820,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
158783
158820
  );
158784
158821
  newColorTemp = tempPhysMax - tempDelta;
158785
158822
  }
158786
- logger148.debug(`Synced color temperature with level: ${level}, new color temperature: ${newColorTemp}`);
158823
+ logger149.debug(`Synced color temperature with level: ${level}, new color temperature: ${newColorTemp}`);
158787
158824
  return this.moveToColorTemperatureLogic(newColorTemp, 0);
158788
158825
  }
158789
158826
  #assertRate(mode, rate) {
@@ -158987,7 +159024,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
158987
159024
  targetEnhancedColorMode = values4.enhancedColorMode;
158988
159025
  }
158989
159026
  if (!this.#supportsColorMode(targetEnhancedColorMode)) {
158990
- logger148.info(
159027
+ logger149.info(
158991
159028
  `Can not apply scene with unsupported color mode: ${ColorControl3.EnhancedColorMode[targetEnhancedColorMode]} (${targetEnhancedColorMode})`
158992
159029
  );
158993
159030
  }
@@ -159029,7 +159066,7 @@ var ColorControlBaseServer = class _ColorControlBaseServer extends ColorControlB
159029
159066
  }
159030
159067
  break;
159031
159068
  default:
159032
- logger148.info(
159069
+ logger149.info(
159033
159070
  `No supported color mode found to apply scene: ${ColorControl3.EnhancedColorMode[targetEnhancedColorMode]} (${targetEnhancedColorMode})`
159034
159071
  );
159035
159072
  break;
@@ -159122,7 +159159,7 @@ init_esm();
159122
159159
  init_ServerNode();
159123
159160
  init_esm4();
159124
159161
  init_esm3();
159125
- var logger149 = Logger.get("LevelControlServer");
159162
+ var logger150 = Logger.get("LevelControlServer");
159126
159163
  var LevelControlBase = LevelControlBehavior.with(LevelControl3.Feature.OnOff, LevelControl3.Feature.Lighting);
159127
159164
  var LevelControlBaseServer = class _LevelControlBaseServer extends LevelControlBase {
159128
159165
  /** Returns the minimum level, including feature specific fallback value handling. */
@@ -159209,17 +159246,17 @@ var LevelControlBaseServer = class _LevelControlBaseServer extends LevelControlB
159209
159246
  */
159210
159247
  initializeLighting() {
159211
159248
  if (this.state.currentLevel === 0) {
159212
- logger149.warn(
159249
+ logger150.warn(
159213
159250
  `The currentLevel value of ${this.state.currentLevel} is invalid according to Matter specification. The value must not be 0.`
159214
159251
  );
159215
159252
  }
159216
159253
  if (this.minLevel !== 1) {
159217
- logger149.warn(
159254
+ logger150.warn(
159218
159255
  `The minLevel value of ${this.minLevel} is invalid according to Matter specification. The value should be 1.`
159219
159256
  );
159220
159257
  }
159221
159258
  if (this.maxLevel !== 254) {
159222
- logger149.warn(
159259
+ logger150.warn(
159223
159260
  `The maxLevel value of ${this.maxLevel} is invalid according to Matter specification. The value should be 254.`
159224
159261
  );
159225
159262
  }
@@ -159530,7 +159567,7 @@ var LevelControlBaseServer = class _LevelControlBaseServer extends LevelControlB
159530
159567
  if (!onOff || this.state.onLevel === null) {
159531
159568
  return;
159532
159569
  }
159533
- logger149.debug(`OnOff changed to ON, setting level to onLevel value of ${this.state.onLevel}`);
159570
+ logger150.debug(`OnOff changed to ON, setting level to onLevel value of ${this.state.onLevel}`);
159534
159571
  this.state.currentLevel = this.state.onLevel;
159535
159572
  }
159536
159573
  #calculateEffectiveOptions(optionsMask, optionsOverride) {
@@ -160567,7 +160604,7 @@ var SwitchBehavior = SwitchBehaviorConstructor;
160567
160604
  // ../../node_modules/.pnpm/@matter+node@0.16.11/node_modules/@matter/node/dist/esm/behaviors/switch/SwitchServer.js
160568
160605
  var DEFAULT_MULTIPRESS_DELAY = Millis(300);
160569
160606
  var DEFAULT_LONG_PRESS_DELAY = Seconds(2);
160570
- var logger150 = Logger.get("SwitchServer");
160607
+ var logger151 = Logger.get("SwitchServer");
160571
160608
  var SwitchServerBase = SwitchBehavior.for(Switch3.Complete).with(
160572
160609
  Switch3.Feature.LatchingSwitch,
160573
160610
  Switch3.Feature.MomentarySwitch,
@@ -160621,7 +160658,7 @@ var SwitchBaseServer = class extends SwitchServerBase {
160621
160658
  this.internal.currentIsLongPress = false;
160622
160659
  this.internal.multiPressTimer?.stop();
160623
160660
  this.internal.longPressTimer?.stop();
160624
- logger150.info("State of Switch got reset");
160661
+ logger151.info("State of Switch got reset");
160625
160662
  }
160626
160663
  // TODO remove when Validator logic can assess that with 1.3 introduction
160627
160664
  #assertPositionInRange(position) {
@@ -161148,7 +161185,7 @@ var ModeSelectBehaviorConstructor = ClusterBehavior.withInterface().for(ModeSele
161148
161185
  var ModeSelectBehavior = ModeSelectBehaviorConstructor;
161149
161186
 
161150
161187
  // ../../node_modules/.pnpm/@matter+node@0.16.11/node_modules/@matter/node/dist/esm/behaviors/mode-select/ModeSelectServer.js
161151
- var logger151 = Logger.get("ModeSelectServer");
161188
+ var logger152 = Logger.get("ModeSelectServer");
161152
161189
  var ModeSelectBase = ModeSelectBehavior.with(ModeSelect3.Feature.OnOff);
161153
161190
  var ModeSelectBaseServer = class extends ModeSelectBase {
161154
161191
  initialize() {
@@ -161165,7 +161202,7 @@ var ModeSelectBaseServer = class extends ModeSelectBase {
161165
161202
  }
161166
161203
  this.reactTo(onOffServer.events.onOff$Changed, this.#handleOnOffDependency);
161167
161204
  } else {
161168
- logger151.warn("OnOffServer not found on endpoint, but OnMode is set.");
161205
+ logger152.warn("OnOffServer not found on endpoint, but OnMode is set.");
161169
161206
  }
161170
161207
  }
161171
161208
  if (!currentModeOverridden && this.state.startUpMode !== void 0 && this.state.startUpMode !== null && this.#getBootReason() !== GeneralDiagnostics3.BootReason.SoftwareUpdateCompleted) {
@@ -161386,7 +161423,7 @@ init_IdentifyServer();
161386
161423
  // ../../node_modules/.pnpm/@matter+node@0.16.11/node_modules/@matter/node/dist/esm/behaviors/occupancy-sensing/OccupancySensingServer.js
161387
161424
  init_occupancy_sensing();
161388
161425
  init_esm();
161389
- var logger152 = Logger.get("OccupancySensingServer");
161426
+ var logger153 = Logger.get("OccupancySensingServer");
161390
161427
  var holdTimeDependencies = [
161391
161428
  "holdTimeLimits",
161392
161429
  "pirOccupiedToUnoccupiedDelay",
@@ -161402,7 +161439,7 @@ var holdTimeDependencies = [
161402
161439
  var OccupancySensingServer = class extends OccupancySensingBehavior {
161403
161440
  initialize() {
161404
161441
  if (!Object.values(this.features).some((feature) => feature)) {
161405
- logger152.error(
161442
+ logger153.error(
161406
161443
  `OccupancySensingServer: Since revision 5 of the cluster features need to be set based on the detector type. Currently no features are enabled.`
161407
161444
  );
161408
161445
  } else if (!Object.values(this.state.occupancySensorTypeBitmap).some((feature) => feature) || this.state.occupancySensorType === void 0) {
@@ -161429,7 +161466,7 @@ var OccupancySensingServer = class extends OccupancySensingBehavior {
161429
161466
  } else if (this.state.occupancySensorTypeBitmap.physicalContact) {
161430
161467
  this.state.occupancySensorType = OccupancySensing3.OccupancySensorType.PhysicalContact;
161431
161468
  }
161432
- logger152.debug(
161469
+ logger153.debug(
161433
161470
  "Sync occupancySensorType to",
161434
161471
  OccupancySensing3.OccupancySensorType[this.state.occupancySensorType],
161435
161472
  "and occupancySensorTypeBitmap to",
@@ -162394,7 +162431,7 @@ init_esm3();
162394
162431
 
162395
162432
  // ../../node_modules/.pnpm/@matter+node@0.16.11/node_modules/@matter/node/dist/esm/behaviors/thermostat/AtomicWriteState.js
162396
162433
  init_esm();
162397
- var logger153 = Logger.get("AtomicWriteState");
162434
+ var logger154 = Logger.get("AtomicWriteState");
162398
162435
  var MAXIMUM_ALLOWED_TIMEOUT = Seconds(9);
162399
162436
  var AtomicWriteState = class {
162400
162437
  peerAddress;
@@ -162429,19 +162466,19 @@ var AtomicWriteState = class {
162429
162466
  });
162430
162467
  }
162431
162468
  start() {
162432
- logger153.debug(
162469
+ logger154.debug(
162433
162470
  `Starting atomic write state for peer ${this.peerAddress.toString()} on endpoint ${this.endpoint.id}`
162434
162471
  );
162435
162472
  this.#timer.start();
162436
162473
  }
162437
162474
  #timeoutTriggered() {
162438
- logger153.debug(
162475
+ logger154.debug(
162439
162476
  `Atomic write state for peer ${this.peerAddress.toString()} on endpoint ${this.endpoint.id} timed out`
162440
162477
  );
162441
162478
  this.close();
162442
162479
  }
162443
162480
  close() {
162444
- logger153.debug(
162481
+ logger154.debug(
162445
162482
  `Closing atomic write state for peer ${this.peerAddress.toString()} on endpoint ${this.endpoint.id}`
162446
162483
  );
162447
162484
  if (this.#timer.isRunning) {
@@ -162452,7 +162489,7 @@ var AtomicWriteState = class {
162452
162489
  };
162453
162490
 
162454
162491
  // ../../node_modules/.pnpm/@matter+node@0.16.11/node_modules/@matter/node/dist/esm/behaviors/thermostat/AtomicWriteHandler.js
162455
- var logger154 = Logger.get("AtomicWriteHandler");
162492
+ var logger155 = Logger.get("AtomicWriteHandler");
162456
162493
  var AtomicWriteHandler = class _AtomicWriteHandler {
162457
162494
  #observers = new ObserverGroup();
162458
162495
  #pendingWrites = new BasicSet();
@@ -162522,7 +162559,7 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
162522
162559
  );
162523
162560
  this.#pendingWrites.add(state);
162524
162561
  state.closed.on(() => void this.#pendingWrites.delete(state));
162525
- logger154.debug("Added atomic write state:", state);
162562
+ logger155.debug("Added atomic write state:", state);
162526
162563
  return state;
162527
162564
  }
162528
162565
  if (existingState === void 0) {
@@ -162589,10 +162626,10 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
162589
162626
  writeAttribute(context, endpoint, cluster2, attribute2, value) {
162590
162627
  const state = this.#assertPendingWriteForAttributeAndPeer(context, endpoint, cluster2, attribute2);
162591
162628
  const attributeName = state.attributeNames.get(attribute2);
162592
- logger154.debug(`Writing pending value for attribute ${attributeName}, ${attribute2} in atomic write`, value);
162629
+ logger155.debug(`Writing pending value for attribute ${attributeName}, ${attribute2} in atomic write`, value);
162593
162630
  endpoint.eventsOf(cluster2.id)[`${attributeName}$AtomicChanging`]?.emit(value, state.pendingAttributeValues[attribute2] !== void 0 ? state.pendingAttributeValues[attribute2] : state.initialValues[attribute2], context);
162594
162631
  state.pendingAttributeValues[attribute2] = value;
162595
- logger154.debug("Atomic write state after current write:", state);
162632
+ logger155.debug("Atomic write state after current write:", state);
162596
162633
  }
162597
162634
  /**
162598
162635
  * Implements the commit logic for an atomic write.
@@ -162611,7 +162648,7 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
162611
162648
  await context.transaction?.commit();
162612
162649
  } catch (error) {
162613
162650
  await context.transaction?.rollback();
162614
- logger154.info(`Failed to write attribute ${attr} during atomic write commit: ${error}`);
162651
+ logger155.info(`Failed to write attribute ${attr} during atomic write commit: ${error}`);
162615
162652
  statusCode = error instanceof StatusResponseError ? error.code : Status2.Failure;
162616
162653
  commandStatusCode = commandStatusCode === Status2.Failure ? Status2.Failure : commandStatusCode === Status2.ConstraintError ? Status2.ConstraintError : Status2.Failure;
162617
162654
  }
@@ -162647,7 +162684,7 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
162647
162684
  const fabricIndex = fabric.fabricIndex;
162648
162685
  for (const writeState of Array.from(this.#pendingWrites)) {
162649
162686
  if (writeState.peerAddress.fabricIndex === fabricIndex) {
162650
- logger154.debug(
162687
+ logger155.debug(
162651
162688
  `Closing atomic write state for peer ${writeState.peerAddress.toString()} on endpoint ${writeState.endpoint.id} due to fabric removal`
162652
162689
  );
162653
162690
  writeState.close();
@@ -162688,7 +162725,7 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
162688
162725
  if (!PeerAddress.is(attrWriteState.peerAddress, peerAddress)) {
162689
162726
  return void 0;
162690
162727
  }
162691
- logger154.debug(
162728
+ logger155.debug(
162692
162729
  `Found pending value for attribute ${attribute2} for peer ${peerAddress.nodeId}`,
162693
162730
  serialize(attrWriteState.pendingAttributeValues[attribute2])
162694
162731
  );
@@ -162724,7 +162761,7 @@ var AtomicWriteHandler = class _AtomicWriteHandler {
162724
162761
  };
162725
162762
 
162726
162763
  // ../../node_modules/.pnpm/@matter+node@0.16.11/node_modules/@matter/node/dist/esm/behaviors/thermostat/ThermostatServer.js
162727
- var logger155 = Logger.get("ThermostatServer");
162764
+ var logger156 = Logger.get("ThermostatServer");
162728
162765
  var ThermostatBehaviorLogicBase = ThermostatBehavior.with(
162729
162766
  Thermostat3.Feature.Heating,
162730
162767
  Thermostat3.Feature.Cooling,
@@ -162753,7 +162790,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
162753
162790
  throw new ImplementationError("Setback feature is deprecated and not allowed to be enabled");
162754
162791
  }
162755
162792
  if (this.features.matterScheduleConfiguration) {
162756
- logger155.warn("MatterScheduleConfiguration feature is not yet implemented. Please do not activate it");
162793
+ logger156.warn("MatterScheduleConfiguration feature is not yet implemented. Please do not activate it");
162757
162794
  }
162758
162795
  const options = this.endpoint.behaviors.optionsFor(_ThermostatBaseServer);
162759
162796
  if (this.features.presets && this.state.persistedPresets === void 0) {
@@ -162871,7 +162908,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
162871
162908
  throw new StatusResponse.InvalidCommandError("Requested PresetHandle not found");
162872
162909
  }
162873
162910
  }
162874
- logger155.info(`Setting active preset handle to`, presetHandle);
162911
+ logger156.info(`Setting active preset handle to`, presetHandle);
162875
162912
  this.state.activePresetHandle = presetHandle;
162876
162913
  return preset;
162877
162914
  }
@@ -162941,7 +162978,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
162941
162978
  }
162942
162979
  if (this.state.setpointHoldExpiryTimestamp === void 0) {
162943
162980
  } else {
162944
- logger155.warn(
162981
+ logger156.warn(
162945
162982
  "Handling for setpointHoldExpiryTimestamp is not yet implemented. To use this attribute you need to install the needed logic yourself"
162946
162983
  );
162947
162984
  }
@@ -163014,7 +163051,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163014
163051
  "RemoteSensing cannot be set to LocalTemperature when LocalTemperatureNotExposed feature is enabled"
163015
163052
  );
163016
163053
  }
163017
- logger155.debug("LocalTemperatureNotExposed feature is enabled, ignoring local temperature measurement");
163054
+ logger156.debug("LocalTemperatureNotExposed feature is enabled, ignoring local temperature measurement");
163018
163055
  this.state.localTemperature = null;
163019
163056
  }
163020
163057
  let localTemperature = null;
@@ -163023,11 +163060,11 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163023
163060
  const endpoints = this.env.get(ServerNode).endpoints;
163024
163061
  const endpoint = endpoints.has(localTempEndpoint) ? endpoints.for(localTempEndpoint) : void 0;
163025
163062
  if (endpoint !== void 0 && endpoint.behaviors.has(TemperatureMeasurementServer)) {
163026
- logger155.debug(
163063
+ logger156.debug(
163027
163064
  `Using existing TemperatureMeasurement cluster on endpoint #${localTempEndpoint} for local temperature measurement`
163028
163065
  );
163029
163066
  if (this.state.externalMeasuredIndoorTemperature !== void 0) {
163030
- logger155.warn(
163067
+ logger156.warn(
163031
163068
  "Both local TemperatureMeasurement cluster and externalMeasuredIndoorTemperature state are set, using local cluster"
163032
163069
  );
163033
163070
  }
@@ -163037,19 +163074,19 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163037
163074
  );
163038
163075
  localTemperature = endpoint.stateOf(TemperatureMeasurementServer).measuredValue;
163039
163076
  } else {
163040
- logger155.warn(
163077
+ logger156.warn(
163041
163078
  `No TemperatureMeasurement cluster found on endpoint #${localTempEndpoint}, falling back to externalMeasuredIndoorTemperature state if set`
163042
163079
  );
163043
163080
  }
163044
163081
  } else {
163045
163082
  if (this.state.externalMeasuredIndoorTemperature === void 0) {
163046
163083
  if (this.state.localTemperatureCalibration !== void 0) {
163047
- logger155.warn(
163084
+ logger156.warn(
163048
163085
  "No local TemperatureMeasurement cluster available, externalMeasuredIndoorTemperature state not set but localTemperatureCalibration is used: Ensure to correctly consider the calibration when updating the localTemperature value"
163049
163086
  );
163050
163087
  }
163051
163088
  } else {
163052
- logger155.info("Using measured temperature via externalMeasuredIndoorTemperature state");
163089
+ logger156.info("Using measured temperature via externalMeasuredIndoorTemperature state");
163053
163090
  localTemperature = this.state.externalMeasuredIndoorTemperature ?? null;
163054
163091
  }
163055
163092
  this.reactTo(this.events.externalMeasuredIndoorTemperature$Changed, this.#handleMeasuredTemperatureChange);
@@ -163089,28 +163126,28 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163089
163126
  const endpoints = this.env.get(ServerNode).endpoints;
163090
163127
  const endpoint = endpoints.has(localOccupancyEndpoint) ? endpoints.for(localOccupancyEndpoint) : void 0;
163091
163128
  if (endpoint !== void 0 && endpoint.behaviors.has(OccupancySensingServer)) {
163092
- logger155.debug(
163129
+ logger156.debug(
163093
163130
  `Using existing OccupancySensing cluster on endpoint ${localOccupancyEndpoint} for local occupancy sensing`
163094
163131
  );
163095
163132
  if (this.state.externallyMeasuredOccupancy !== void 0) {
163096
- logger155.warn(
163133
+ logger156.warn(
163097
163134
  "Both local OccupancySensing cluster and externallyMeasuredOccupancy state are set, using local cluster"
163098
163135
  );
163099
163136
  }
163100
163137
  this.reactTo(endpoint.eventsOf(OccupancySensingServer).occupancy$Changed, this.#handleOccupancyChange);
163101
163138
  currentOccupancy = !!endpoint.stateOf(OccupancySensingServer).occupancy.occupied;
163102
163139
  } else {
163103
- logger155.warn(
163140
+ logger156.warn(
163104
163141
  `No OccupancySensing cluster found on endpoint ${localOccupancyEndpoint}, falling back to externallyMeasuredOccupancy state if set`
163105
163142
  );
163106
163143
  }
163107
163144
  } else {
163108
163145
  if (this.state.externallyMeasuredOccupancy === void 0) {
163109
- logger155.warn(
163146
+ logger156.warn(
163110
163147
  "No local OccupancySensing cluster available and externallyMeasuredOccupancy state not set"
163111
163148
  );
163112
163149
  } else {
163113
- logger155.info("Using occupancy via externallyMeasuredOccupancy state");
163150
+ logger156.info("Using occupancy via externallyMeasuredOccupancy state");
163114
163151
  currentOccupancy = this.state.externallyMeasuredOccupancy;
163115
163152
  }
163116
163153
  this.reactTo(this.events.externallyMeasuredOccupancy$Changed, this.#handleExternalOccupancyChange);
@@ -163377,7 +163414,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163377
163414
  max = this.state[`max${scope}`] ?? defaults.absMax,
163378
163415
  absMax = this.state[`absMax${scope}`] ?? defaults.absMax
163379
163416
  } = details;
163380
- logger155.debug(
163417
+ logger156.debug(
163381
163418
  `Validating user setpoint limits for ${scope}: absMin=${absMin}, min=${min}, max=${max}, absMax=${absMax}`
163382
163419
  );
163383
163420
  if (absMin > min) {
@@ -163424,7 +163461,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163424
163461
  const limitMax = scope === "Heat" ? this.heatSetpointMaximum : this.coolSetpointMaximum;
163425
163462
  const result = cropValueRange(setpoint, limitMin, limitMax);
163426
163463
  if (result !== setpoint) {
163427
- logger155.debug(
163464
+ logger156.debug(
163428
163465
  `${scope} setpoint (${setpoint}) is out of limits [${limitMin}, ${limitMax}], clamping to ${result}`
163429
163466
  );
163430
163467
  }
@@ -163461,7 +163498,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163461
163498
  const otherLimit = otherType === "Heating" ? this.heatSetpointMinimum : this.coolSetpointMaximum;
163462
163499
  if (otherType === "Cooling") {
163463
163500
  const minValidSetpoint = value + deadband;
163464
- logger155.debug(
163501
+ logger156.debug(
163465
163502
  `Ensuring deadband for ${type}${otherType}Setpoint, min valid setpoint is ${minValidSetpoint}`
163466
163503
  );
163467
163504
  if (otherSetpoint >= minValidSetpoint) {
@@ -163472,11 +163509,11 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163472
163509
  `Cannot adjust cooling setpoint to maintain deadband, would exceed max cooling setpoint (${otherLimit})`
163473
163510
  );
163474
163511
  }
163475
- logger155.debug(`Adjusting ${type}${otherType}Setpoint to ${minValidSetpoint} to maintain deadband`);
163512
+ logger156.debug(`Adjusting ${type}${otherType}Setpoint to ${minValidSetpoint} to maintain deadband`);
163476
163513
  this.state[`${type}${otherType}Setpoint`] = minValidSetpoint;
163477
163514
  } else {
163478
163515
  const maxValidSetpoint = value - deadband;
163479
- logger155.debug(
163516
+ logger156.debug(
163480
163517
  `Ensuring deadband for ${type}${otherType}Setpoint, max valid setpoint is ${maxValidSetpoint}`
163481
163518
  );
163482
163519
  if (otherSetpoint <= maxValidSetpoint) {
@@ -163487,7 +163524,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163487
163524
  `Cannot adjust heating setpoint to maintain deadband, would exceed min heating setpoint (${otherLimit})`
163488
163525
  );
163489
163526
  }
163490
- logger155.debug(`Adjusting ${type}${otherType}Setpoint to ${maxValidSetpoint} to maintain deadband`);
163527
+ logger156.debug(`Adjusting ${type}${otherType}Setpoint to ${maxValidSetpoint} to maintain deadband`);
163491
163528
  this.state[`${type}${otherType}Setpoint`] = maxValidSetpoint;
163492
163529
  }
163493
163530
  }
@@ -163755,7 +163792,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163755
163792
  */
163756
163793
  #handlePersistedPresetsChanged(newPresets, oldPresets) {
163757
163794
  if (oldPresets === void 0) {
163758
- logger155.debug(
163795
+ logger156.debug(
163759
163796
  "Old presets is undefined, skipping some checks. This should only happen on setup of the behavior."
163760
163797
  );
163761
163798
  }
@@ -163764,7 +163801,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163764
163801
  const newPresetHandles = /* @__PURE__ */ new Set();
163765
163802
  for (const preset of newPresets) {
163766
163803
  if (preset.presetHandle === null) {
163767
- logger155.error("Preset is missing presetHandle, generating a new one");
163804
+ logger156.error("Preset is missing presetHandle, generating a new one");
163768
163805
  preset.presetHandle = entropy.randomBytes(16);
163769
163806
  changed = true;
163770
163807
  }
@@ -163813,7 +163850,7 @@ var ThermostatBaseServer = class _ThermostatBaseServer extends ThermostatBehavio
163813
163850
  throw new StatusResponse.InvalidInStateError(`ActivePresetHandle references non-existing presetHandle`);
163814
163851
  }
163815
163852
  if (changed) {
163816
- logger155.error("PresetHandles or BuiltIn flags were updated, updating persistedPresets");
163853
+ logger156.error("PresetHandles or BuiltIn flags were updated, updating persistedPresets");
163817
163854
  this.state.persistedPresets = deepCopy(newPresets);
163818
163855
  }
163819
163856
  }
@@ -164716,7 +164753,7 @@ init_IdentifyServer();
164716
164753
  init_window_covering();
164717
164754
  init_esm();
164718
164755
  init_esm3();
164719
- var logger156 = Logger.get("WindowCoveringServer");
164756
+ var logger157 = Logger.get("WindowCoveringServer");
164720
164757
  var WindowCoveringBase = WindowCoveringBehavior.with(
164721
164758
  WindowCovering3.Feature.Lift,
164722
164759
  WindowCovering3.Feature.Tilt,
@@ -164801,7 +164838,7 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
164801
164838
  this.state.configStatus = configStatus;
164802
164839
  });
164803
164840
  }
164804
- logger156.debug(
164841
+ logger157.debug(
164805
164842
  `Mode changed to ${Diagnostic.json(mode)} and config status to ${Diagnostic.json(configStatus)} and internal calibration mode to ${this.internal.calibrationMode}`
164806
164843
  );
164807
164844
  }
@@ -164809,7 +164846,7 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
164809
164846
  #handleOperationalStatusChanging(operationalStatus) {
164810
164847
  const globalStatus = operationalStatus.lift !== WindowCovering3.MovementStatus.Stopped ? operationalStatus.lift : operationalStatus.tilt;
164811
164848
  operationalStatus.global = globalStatus;
164812
- logger156.debug(
164849
+ logger157.debug(
164813
164850
  `Operational status changed to ${Diagnostic.json(operationalStatus)} with new global status ${globalStatus}`
164814
164851
  );
164815
164852
  this.state.operationalStatus = operationalStatus;
@@ -164838,10 +164875,10 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
164838
164875
  this.state.currentPositionLiftPercentage = percent100ths3 === null ? percent100ths3 : Math.floor(percent100ths3 / WC_PERCENT100THS_COEFFICIENT);
164839
164876
  if (this.state.operationalStatus.lift !== WindowCovering3.MovementStatus.Stopped && percent100ths3 === this.state.targetPositionLiftPercent100ths) {
164840
164877
  this.state.operationalStatus.lift = WindowCovering3.MovementStatus.Stopped;
164841
- logger156.debug("Lift movement stopped, target value reached");
164878
+ logger157.debug("Lift movement stopped, target value reached");
164842
164879
  }
164843
164880
  }
164844
- logger156.debug(
164881
+ logger157.debug(
164845
164882
  `Syncing lift position ${this.state.currentPositionLiftPercent100ths === null ? null : (this.state.currentPositionLiftPercent100ths / 100).toFixed(2)} to ${this.state.currentPositionLiftPercentage}%`
164846
164883
  );
164847
164884
  }
@@ -164851,10 +164888,10 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
164851
164888
  this.state.currentPositionTiltPercentage = percent100ths3 === null ? percent100ths3 : Math.floor(percent100ths3 / WC_PERCENT100THS_COEFFICIENT);
164852
164889
  if (this.state.operationalStatus.tilt !== WindowCovering3.MovementStatus.Stopped && percent100ths3 === this.state.targetPositionTiltPercent100ths) {
164853
164890
  this.state.operationalStatus.tilt = WindowCovering3.MovementStatus.Stopped;
164854
- logger156.debug("Tilt movement stopped, target value reached");
164891
+ logger157.debug("Tilt movement stopped, target value reached");
164855
164892
  }
164856
164893
  }
164857
- logger156.debug(
164894
+ logger157.debug(
164858
164895
  `Syncing tilt position ${this.state.currentPositionTiltPercent100ths === null ? null : (this.state.currentPositionTiltPercent100ths / 100).toFixed(2)} to ${this.state.currentPositionTiltPercentage}%`
164859
164896
  );
164860
164897
  }
@@ -164942,7 +164979,7 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
164942
164979
  }
164943
164980
  const directionInfo = direction === 2 ? ` in direction by position` : ` in direction ${direction === 1 ? "Close" : "Open"}`;
164944
164981
  const targetInfo = targetPercent100ths === void 0 ? "" : ` to target position ${(targetPercent100ths / 100).toFixed(2)}`;
164945
- logger156.debug(
164982
+ logger157.debug(
164946
164983
  `Moving the device ${type === 0 ? "Lift" : "Tilt"}${directionInfo} (reversed=${reversed})${targetInfo}`
164947
164984
  );
164948
164985
  }
@@ -164964,7 +165001,7 @@ var WindowCoveringBaseServer = class extends WindowCoveringBase {
164964
165001
  );
164965
165002
  }
164966
165003
  if (type === 0 && this.state.configStatus.liftMovementReversed) {
164967
- logger156.debug("Lift movement is reversed");
165004
+ logger157.debug("Lift movement is reversed");
164968
165005
  }
164969
165006
  switch (type) {
164970
165007
  case 0:
@@ -165194,7 +165231,7 @@ init_esm3();
165194
165231
 
165195
165232
  // src/utils/apply-patch-state.ts
165196
165233
  init_esm();
165197
- var logger157 = Logger.get("ApplyPatchState");
165234
+ var logger158 = Logger.get("ApplyPatchState");
165198
165235
  function applyPatchState(state, patch, options) {
165199
165236
  return applyPatch(state, patch, options?.force);
165200
165237
  }
@@ -165221,23 +165258,23 @@ function applyPatch(state, patch, force = false) {
165221
165258
  if (errorMessage.includes(
165222
165259
  "Endpoint storage inaccessible because endpoint is not a node and is not owned by another endpoint"
165223
165260
  )) {
165224
- logger157.debug(
165261
+ logger158.debug(
165225
165262
  `Suppressed endpoint storage error, patch not applied: ${JSON.stringify(actualPatch)}`
165226
165263
  );
165227
165264
  return actualPatch;
165228
165265
  }
165229
165266
  if (errorMessage.includes("synchronous-transaction-conflict")) {
165230
- logger157.warn(
165267
+ logger158.warn(
165231
165268
  `Transaction conflict, state update DROPPED: ${JSON.stringify(actualPatch)}`
165232
165269
  );
165233
165270
  return actualPatch;
165234
165271
  }
165235
165272
  failedKeys.push(key);
165236
- logger157.warn(`Failed to set property '${key}': ${errorMessage}`);
165273
+ logger158.warn(`Failed to set property '${key}': ${errorMessage}`);
165237
165274
  }
165238
165275
  }
165239
165276
  if (failedKeys.length > 0) {
165240
- logger157.warn(
165277
+ logger158.warn(
165241
165278
  `${failedKeys.length} properties failed to update: [${failedKeys.join(", ")}]`
165242
165279
  );
165243
165280
  }
@@ -165446,7 +165483,7 @@ init_basic_information2();
165446
165483
  init_descriptor2();
165447
165484
  init_aggregator();
165448
165485
  init_esm();
165449
- var logger158 = Logger.get("BridgedDeviceBasicInformationServer");
165486
+ var logger159 = Logger.get("BridgedDeviceBasicInformationServer");
165450
165487
  var BridgedDeviceBasicInformationServer = class extends BridgedDeviceBasicInformationBehavior {
165451
165488
  async initialize() {
165452
165489
  if (this.endpoint.lifecycle.isInstalled) {
@@ -165461,7 +165498,7 @@ var BridgedDeviceBasicInformationServer = class extends BridgedDeviceBasicInform
165461
165498
  this.state.uniqueId = BasicInformationServer.createUniqueId();
165462
165499
  }
165463
165500
  if (serialNumber !== void 0 && uniqueId === this.state.serialNumber) {
165464
- logger158.warn("uniqueId and serialNumber shall not be the same.");
165501
+ logger159.warn("uniqueId and serialNumber shall not be the same.");
165465
165502
  }
165466
165503
  }
165467
165504
  static schema = BasicInformationServer.enableUniqueIdPersistence(
@@ -166333,7 +166370,7 @@ var IdentifyServer2 = class extends IdentifyServer {
166333
166370
  // src/matter/endpoints/validate-endpoint-type.ts
166334
166371
  init_esm();
166335
166372
  init_esm7();
166336
- var logger159 = Logger.get("EndpointValidation");
166373
+ var logger160 = Logger.get("EndpointValidation");
166337
166374
  function toCamelCase(name) {
166338
166375
  return name.charAt(0).toLowerCase() + name.slice(1);
166339
166376
  }
@@ -166363,12 +166400,12 @@ function validateEndpointType(endpointType, entityId) {
166363
166400
  }
166364
166401
  const prefix = entityId ? `[${entityId}] ` : "";
166365
166402
  if (missingMandatory.length > 0) {
166366
- logger159.warn(
166403
+ logger160.warn(
166367
166404
  `${prefix}${deviceTypeModel.name} (0x${endpointType.deviceType.toString(16)}): missing mandatory clusters: ${missingMandatory.join(", ")}`
166368
166405
  );
166369
166406
  }
166370
166407
  if (availableOptional.length > 0) {
166371
- logger159.debug(
166408
+ logger160.debug(
166372
166409
  `${prefix}${deviceTypeModel.name} (0x${endpointType.deviceType.toString(16)}): optional clusters not used: ${availableOptional.join(", ")}`
166373
166410
  );
166374
166411
  }
@@ -166522,7 +166559,7 @@ function truncate(maxLength, value) {
166522
166559
  }
166523
166560
 
166524
166561
  // src/plugins/plugin-device-factory.ts
166525
- var logger160 = Logger.get("PluginDeviceFactory");
166562
+ var logger161 = Logger.get("PluginDeviceFactory");
166526
166563
  var deviceTypeMap = {
166527
166564
  on_off_light: () => OnOffLightDevice.with(
166528
166565
  IdentifyServer2,
@@ -166628,7 +166665,7 @@ var deviceTypeMap = {
166628
166665
  function createPluginEndpointType(deviceType) {
166629
166666
  const factory = deviceTypeMap[deviceType];
166630
166667
  if (!factory) {
166631
- logger160.warn(`Unsupported plugin device type: "${deviceType}"`);
166668
+ logger161.warn(`Unsupported plugin device type: "${deviceType}"`);
166632
166669
  return void 0;
166633
166670
  }
166634
166671
  const endpoint = factory();
@@ -166643,7 +166680,7 @@ function getSupportedPluginDeviceTypes() {
166643
166680
  init_esm();
166644
166681
  import * as fs10 from "node:fs";
166645
166682
  import * as path11 from "node:path";
166646
- var logger161 = Logger.get("PluginStorage");
166683
+ var logger162 = Logger.get("PluginStorage");
166647
166684
  var SAVE_DEBOUNCE_MS = 500;
166648
166685
  var FilePluginStorage = class {
166649
166686
  data = {};
@@ -166679,7 +166716,7 @@ var FilePluginStorage = class {
166679
166716
  this.data = JSON.parse(raw);
166680
166717
  }
166681
166718
  } catch (e) {
166682
- logger161.warn(`Failed to load plugin storage from ${this.filePath}:`, e);
166719
+ logger162.warn(`Failed to load plugin storage from ${this.filePath}:`, e);
166683
166720
  this.data = {};
166684
166721
  }
166685
166722
  }
@@ -166701,7 +166738,7 @@ var FilePluginStorage = class {
166701
166738
  fs10.writeFileSync(this.filePath, JSON.stringify(this.data, null, 2));
166702
166739
  this.dirty = false;
166703
166740
  } catch (e) {
166704
- logger161.warn(`Failed to save plugin storage to ${this.filePath}:`, e);
166741
+ logger162.warn(`Failed to save plugin storage to ${this.filePath}:`, e);
166705
166742
  }
166706
166743
  }
166707
166744
  flush() {
@@ -166711,7 +166748,7 @@ var FilePluginStorage = class {
166711
166748
 
166712
166749
  // src/plugins/safe-plugin-runner.ts
166713
166750
  init_esm();
166714
- var logger162 = Logger.get("SafePluginRunner");
166751
+ var logger163 = Logger.get("SafePluginRunner");
166715
166752
  var DEFAULT_TIMEOUT_MS = 1e4;
166716
166753
  var CIRCUIT_BREAKER_THRESHOLD = 3;
166717
166754
  var SafePluginRunner = class {
@@ -166744,7 +166781,7 @@ var SafePluginRunner = class {
166744
166781
  async run(pluginName, operation, fn, timeoutMs = DEFAULT_TIMEOUT_MS) {
166745
166782
  const state = this.getState(pluginName);
166746
166783
  if (state.disabled) {
166747
- logger162.debug(
166784
+ logger163.debug(
166748
166785
  `Plugin "${pluginName}" is disabled (circuit breaker open), skipping ${operation}`
166749
166786
  );
166750
166787
  return void 0;
@@ -166762,13 +166799,13 @@ var SafePluginRunner = class {
166762
166799
  timeout.clear();
166763
166800
  state.failures++;
166764
166801
  state.lastError = error instanceof Error ? error.message : String(error);
166765
- logger162.error(
166802
+ logger163.error(
166766
166803
  `Plugin "${pluginName}" failed during ${operation} (failure ${state.failures}/${CIRCUIT_BREAKER_THRESHOLD}): ${state.lastError}`
166767
166804
  );
166768
166805
  if (state.failures >= CIRCUIT_BREAKER_THRESHOLD) {
166769
166806
  state.disabled = true;
166770
166807
  state.disabledAt = Date.now();
166771
- logger162.error(
166808
+ logger163.error(
166772
166809
  `Plugin "${pluginName}" DISABLED after ${CIRCUIT_BREAKER_THRESHOLD} consecutive failures. Last error: ${state.lastError}`
166773
166810
  );
166774
166811
  }
@@ -166790,13 +166827,13 @@ var SafePluginRunner = class {
166790
166827
  } catch (error) {
166791
166828
  state.failures++;
166792
166829
  state.lastError = error instanceof Error ? error.message : String(error);
166793
- logger162.error(
166830
+ logger163.error(
166794
166831
  `Plugin "${pluginName}" failed during ${operation} (sync, failure ${state.failures}/${CIRCUIT_BREAKER_THRESHOLD}): ${state.lastError}`
166795
166832
  );
166796
166833
  if (state.failures >= CIRCUIT_BREAKER_THRESHOLD) {
166797
166834
  state.disabled = true;
166798
166835
  state.disabledAt = Date.now();
166799
- logger162.error(
166836
+ logger163.error(
166800
166837
  `Plugin "${pluginName}" DISABLED after ${CIRCUIT_BREAKER_THRESHOLD} consecutive failures.`
166801
166838
  );
166802
166839
  }
@@ -166822,7 +166859,7 @@ var SafePluginRunner = class {
166822
166859
  };
166823
166860
 
166824
166861
  // src/plugins/plugin-manager.ts
166825
- var logger163 = Logger.get("PluginManager");
166862
+ var logger164 = Logger.get("PluginManager");
166826
166863
  var PLUGIN_API_VERSION = 1;
166827
166864
  var MAX_PLUGIN_DEVICE_ID_LENGTH = 100;
166828
166865
  function validatePluginDevice(device) {
@@ -166905,7 +166942,7 @@ var PluginManager = class {
166905
166942
  throw new Error(`Plugin at ${packagePath} package.json missing "main"`);
166906
166943
  }
166907
166944
  if (manifest.hamhPluginApiVersion != null && manifest.hamhPluginApiVersion !== PLUGIN_API_VERSION) {
166908
- logger163.warn(
166945
+ logger164.warn(
166909
166946
  `Plugin "${manifest.name}" declares API version ${manifest.hamhPluginApiVersion}, current is ${PLUGIN_API_VERSION}. It may not work correctly.`
166910
166947
  );
166911
166948
  }
@@ -166936,7 +166973,7 @@ var PluginManager = class {
166936
166973
  };
166937
166974
  await this.register(plugin, metadata);
166938
166975
  } catch (e) {
166939
- logger163.error(`Failed to load external plugin from ${packagePath}:`, e);
166976
+ logger164.error(`Failed to load external plugin from ${packagePath}:`, e);
166940
166977
  throw e;
166941
166978
  }
166942
166979
  }
@@ -167013,7 +167050,7 @@ var PluginManager = class {
167013
167050
  devices,
167014
167051
  started: false
167015
167052
  });
167016
- logger163.info(
167053
+ logger164.info(
167017
167054
  `Registered plugin: ${plugin.name} v${plugin.version} (${metadata.source})`
167018
167055
  );
167019
167056
  }
@@ -167024,13 +167061,13 @@ var PluginManager = class {
167024
167061
  for (const [name, instance] of this.instances) {
167025
167062
  if (!instance.metadata.enabled) continue;
167026
167063
  if (this.runner.isDisabled(name)) {
167027
- logger163.warn(
167064
+ logger164.warn(
167028
167065
  `Plugin "${name}" is disabled (circuit breaker), skipping start`
167029
167066
  );
167030
167067
  instance.metadata.enabled = false;
167031
167068
  continue;
167032
167069
  }
167033
- logger163.info(`Starting plugin: ${name}`);
167070
+ logger164.info(`Starting plugin: ${name}`);
167034
167071
  await this.runner.run(
167035
167072
  name,
167036
167073
  "onStart",
@@ -167078,7 +167115,7 @@ var PluginManager = class {
167078
167115
  storage2.flush();
167079
167116
  }
167080
167117
  instance.started = false;
167081
- logger163.info(`Plugin "${name}" shut down`);
167118
+ logger164.info(`Plugin "${name}" shut down`);
167082
167119
  }
167083
167120
  this.instances.clear();
167084
167121
  }
@@ -167489,10 +167526,10 @@ init_diagnostic_event_bus();
167489
167526
  var AUTO_FORCE_SYNC_INTERVAL_MS = 9e4;
167490
167527
  var DEAD_SESSION_TIMEOUT_MS = 6e4;
167491
167528
  var Bridge = class {
167492
- constructor(env, logger205, dataProvider, endpointManager) {
167529
+ constructor(env, logger206, dataProvider, endpointManager) {
167493
167530
  this.dataProvider = dataProvider;
167494
167531
  this.endpointManager = endpointManager;
167495
- this.log = logger205.get(`Bridge / ${dataProvider.id}`);
167532
+ this.log = logger206.get(`Bridge / ${dataProvider.id}`);
167496
167533
  this.server = new BridgeServerNode(
167497
167534
  env,
167498
167535
  this.dataProvider,
@@ -167524,6 +167561,10 @@ var Bridge = class {
167524
167561
  autoForceSyncTimer = null;
167525
167562
  deadSessionTimer = null;
167526
167563
  staleSessionTimers = /* @__PURE__ */ new Map();
167564
+ // Serialize concurrent lifecycle calls so auto-recovery and a manual
167565
+ // restartBridge can't race past each other's Starting/Stopping states.
167566
+ startInFlight;
167567
+ stopInFlight;
167527
167568
  // Tracks the last synced state JSON per entity to avoid pushing unchanged states.
167528
167569
  // Key: entity_id, Value: JSON.stringify of entity.state
167529
167570
  lastSyncedStates = /* @__PURE__ */ new Map();
@@ -167640,6 +167681,15 @@ var Bridge = class {
167640
167681
  if (this.status.code === BridgeStatus.Running) {
167641
167682
  return;
167642
167683
  }
167684
+ if (this.startInFlight) {
167685
+ return this.startInFlight;
167686
+ }
167687
+ this.startInFlight = this.runStart().finally(() => {
167688
+ this.startInFlight = void 0;
167689
+ });
167690
+ return this.startInFlight;
167691
+ }
167692
+ async runStart() {
167643
167693
  this.lastSyncedStates.clear();
167644
167694
  try {
167645
167695
  this.setStatus({
@@ -167677,6 +167727,15 @@ ${e?.toString()}`);
167677
167727
  }
167678
167728
  }
167679
167729
  async stop(code = BridgeStatus.Stopped, reason = "Manually stopped") {
167730
+ if (this.stopInFlight) {
167731
+ return this.stopInFlight;
167732
+ }
167733
+ this.stopInFlight = this.runStop(code, reason).finally(() => {
167734
+ this.stopInFlight = void 0;
167735
+ });
167736
+ return this.stopInFlight;
167737
+ }
167738
+ async runStop(code, reason) {
167680
167739
  this.unwireSessionDiagnostics();
167681
167740
  this.stopAutoForceSync();
167682
167741
  await this.endpointManager.stopPlugins();
@@ -168029,6 +168088,7 @@ init_dist();
168029
168088
  init_esm();
168030
168089
  init_home_assistant_entity_behavior();
168031
168090
  import debounce5 from "debounce";
168091
+ import { isEqual } from "lodash-es";
168032
168092
 
168033
168093
  // src/matter/endpoints/entity-endpoint.ts
168034
168094
  init_esm7();
@@ -168290,7 +168350,7 @@ init_clusters();
168290
168350
 
168291
168351
  // src/matter/behaviors/electrical-energy-measurement-server.ts
168292
168352
  init_home_assistant_entity_behavior();
168293
- var logger164 = Logger.get("ElectricalEnergyMeasurementServer");
168353
+ var logger165 = Logger.get("ElectricalEnergyMeasurementServer");
168294
168354
  var FeaturedBase = ElectricalEnergyMeasurementServer.with("CumulativeEnergy", "ImportedEnergy");
168295
168355
  var ElectricalEnergyMeasurementServerBase = class extends FeaturedBase {
168296
168356
  async initialize() {
@@ -168299,7 +168359,7 @@ var ElectricalEnergyMeasurementServerBase = class extends FeaturedBase {
168299
168359
  const entityId = homeAssistant.entityId;
168300
168360
  const energyEntity = homeAssistant.state.mapping?.energyEntity;
168301
168361
  if (energyEntity) {
168302
- logger164.debug(
168362
+ logger165.debug(
168303
168363
  `[${entityId}] ElectricalEnergyMeasurement using mapped energy entity: ${energyEntity}`
168304
168364
  );
168305
168365
  }
@@ -168351,7 +168411,7 @@ var HaElectricalEnergyMeasurementServer = ElectricalEnergyMeasurementServerBase.
168351
168411
  // src/matter/behaviors/electrical-power-measurement-server.ts
168352
168412
  init_esm();
168353
168413
  init_home_assistant_entity_behavior();
168354
- var logger165 = Logger.get("ElectricalPowerMeasurementServer");
168414
+ var logger166 = Logger.get("ElectricalPowerMeasurementServer");
168355
168415
  var ElectricalPowerMeasurementServerBase = class extends ElectricalPowerMeasurementServer {
168356
168416
  async initialize() {
168357
168417
  await super.initialize();
@@ -168359,7 +168419,7 @@ var ElectricalPowerMeasurementServerBase = class extends ElectricalPowerMeasurem
168359
168419
  const entityId = homeAssistant.entityId;
168360
168420
  const powerEntity = homeAssistant.state.mapping?.powerEntity;
168361
168421
  if (powerEntity) {
168362
- logger165.debug(
168422
+ logger166.debug(
168363
168423
  `[${entityId}] ElectricalPowerMeasurement using mapped power entity: ${powerEntity}`
168364
168424
  );
168365
168425
  }
@@ -168411,7 +168471,7 @@ init_home_assistant_entity_behavior();
168411
168471
  // src/matter/behaviors/humidity-measurement-server.ts
168412
168472
  init_esm();
168413
168473
  init_home_assistant_entity_behavior();
168414
- var logger166 = Logger.get("HumidityMeasurementServer");
168474
+ var logger167 = Logger.get("HumidityMeasurementServer");
168415
168475
  var HumidityMeasurementServerBase = class extends RelativeHumidityMeasurementServer {
168416
168476
  async initialize() {
168417
168477
  await super.initialize();
@@ -168424,7 +168484,7 @@ var HumidityMeasurementServerBase = class extends RelativeHumidityMeasurementSer
168424
168484
  return;
168425
168485
  }
168426
168486
  const humidity = this.getHumidity(this.state.config, entity.state);
168427
- logger166.debug(
168487
+ logger167.debug(
168428
168488
  `Humidity ${entity.state.entity_id} raw=${entity.state.state} measuredValue=${humidity}`
168429
168489
  );
168430
168490
  applyPatchState(this.state, {
@@ -168454,7 +168514,7 @@ function HumidityMeasurementServer(config10) {
168454
168514
  // src/matter/behaviors/power-source-server.ts
168455
168515
  init_esm();
168456
168516
  init_home_assistant_entity_behavior();
168457
- var logger167 = Logger.get("PowerSourceServer");
168517
+ var logger168 = Logger.get("PowerSourceServer");
168458
168518
  var FeaturedBase2 = PowerSourceServer.with("Battery", "Rechargeable");
168459
168519
  var PowerSourceServerBase = class extends FeaturedBase2 {
168460
168520
  async initialize() {
@@ -168466,17 +168526,17 @@ var PowerSourceServerBase = class extends FeaturedBase2 {
168466
168526
  applyPatchState(this.state, {
168467
168527
  endpointList: [endpointNumber]
168468
168528
  });
168469
- logger167.debug(
168529
+ logger168.debug(
168470
168530
  `[${entityId}] PowerSource initialized with endpointList=[${endpointNumber}]`
168471
168531
  );
168472
168532
  } else {
168473
- logger167.warn(
168533
+ logger168.warn(
168474
168534
  `[${entityId}] PowerSource endpoint number is null during initialize - endpointList will be empty!`
168475
168535
  );
168476
168536
  }
168477
168537
  const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
168478
168538
  if (batteryEntity) {
168479
- logger167.debug(
168539
+ logger168.debug(
168480
168540
  `[${entityId}] PowerSource using mapped battery entity: ${batteryEntity}`
168481
168541
  );
168482
168542
  }
@@ -168801,13 +168861,30 @@ init_home_assistant_entity_behavior();
168801
168861
  init_esm();
168802
168862
  init_home_assistant_entity_behavior();
168803
168863
  var lastTurnOnTimestamps = /* @__PURE__ */ new Map();
168864
+ var LAST_TURN_ON_TTL_MS = 6e4;
168804
168865
  var optimisticLevelState = /* @__PURE__ */ new Map();
168805
168866
  var OPTIMISTIC_TIMEOUT_MS = 3e3;
168806
168867
  var OPTIMISTIC_TOLERANCE = 5;
168868
+ function sweepOptimisticLevel(now) {
168869
+ for (const [key, value] of optimisticLevelState) {
168870
+ if (now - value.timestamp > OPTIMISTIC_TIMEOUT_MS) {
168871
+ optimisticLevelState.delete(key);
168872
+ }
168873
+ }
168874
+ }
168875
+ function sweepLastTurnOn(now) {
168876
+ for (const [key, ts] of lastTurnOnTimestamps) {
168877
+ if (now - ts > LAST_TURN_ON_TTL_MS) {
168878
+ lastTurnOnTimestamps.delete(key);
168879
+ }
168880
+ }
168881
+ }
168807
168882
  function notifyLightTurnedOn(entityId) {
168808
- lastTurnOnTimestamps.set(entityId, Date.now());
168883
+ const now = Date.now();
168884
+ sweepLastTurnOn(now);
168885
+ lastTurnOnTimestamps.set(entityId, now);
168809
168886
  }
168810
- var logger168 = Logger.get("LevelControlServer");
168887
+ var logger169 = Logger.get("LevelControlServer");
168811
168888
  var FeaturedBase4 = LevelControlServer.with("OnOff", "Lighting");
168812
168889
  var LevelControlServerBase = class extends FeaturedBase4 {
168813
168890
  pendingTransitionTime;
@@ -168822,12 +168899,12 @@ var LevelControlServerBase = class extends FeaturedBase4 {
168822
168899
  this.state.maxLevel = 254;
168823
168900
  }
168824
168901
  this.state.onLevel = null;
168825
- logger168.debug(`initialize: calling super.initialize()`);
168902
+ logger169.debug(`initialize: calling super.initialize()`);
168826
168903
  try {
168827
168904
  await super.initialize();
168828
- logger168.debug(`initialize: super.initialize() completed successfully`);
168905
+ logger169.debug(`initialize: super.initialize() completed successfully`);
168829
168906
  } catch (error) {
168830
- logger168.error(`initialize: super.initialize() FAILED:`, error);
168907
+ logger169.error(`initialize: super.initialize() FAILED:`, error);
168831
168908
  throw error;
168832
168909
  }
168833
168910
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
@@ -168904,7 +168981,7 @@ var LevelControlServerBase = class extends FeaturedBase4 {
168904
168981
  const lastTurnOn = lastTurnOnTimestamps.get(entityId);
168905
168982
  const timeSinceTurnOn = lastTurnOn ? Date.now() - lastTurnOn : Infinity;
168906
168983
  if (level >= this.maxLevel && timeSinceTurnOn < 200) {
168907
- logger168.debug(
168984
+ logger169.debug(
168908
168985
  `[${entityId}] Ignoring moveToLevel(${level}) - Alexa brightness reset detected (${timeSinceTurnOn}ms after turn-on)`
168909
168986
  );
168910
168987
  return;
@@ -168927,9 +169004,11 @@ var LevelControlServerBase = class extends FeaturedBase4 {
168927
169004
  };
168928
169005
  }
168929
169006
  this.state.currentLevel = level;
169007
+ const now = Date.now();
169008
+ sweepOptimisticLevel(now);
168930
169009
  optimisticLevelState.set(entityId, {
168931
169010
  expectedLevel: level,
168932
- timestamp: Date.now()
169011
+ timestamp: now
168933
169012
  });
168934
169013
  homeAssistant.callAction(action);
168935
169014
  }
@@ -168948,9 +169027,16 @@ function LevelControlServer2(config10) {
168948
169027
  }
168949
169028
 
168950
169029
  // src/matter/behaviors/on-off-server.ts
168951
- var logger169 = Logger.get("OnOffServer");
169030
+ var logger170 = Logger.get("OnOffServer");
168952
169031
  var optimisticOnOffState = /* @__PURE__ */ new Map();
168953
169032
  var OPTIMISTIC_TIMEOUT_MS2 = 3e3;
169033
+ function sweepOptimisticOnOff(now) {
169034
+ for (const [key, value] of optimisticOnOffState) {
169035
+ if (now - value.timestamp > OPTIMISTIC_TIMEOUT_MS2) {
169036
+ optimisticOnOffState.delete(key);
169037
+ }
169038
+ }
169039
+ }
168954
169040
  var OnOffServerBase = class extends OnOffServer {
168955
169041
  async initialize() {
168956
169042
  await super.initialize();
@@ -168992,11 +169078,13 @@ var OnOffServerBase = class extends OnOffServer {
168992
169078
  if (!action) {
168993
169079
  return;
168994
169080
  }
168995
- logger169.info(`[${homeAssistant.entityId}] Turning ON -> ${action.action}`);
169081
+ logger170.info(`[${homeAssistant.entityId}] Turning ON -> ${action.action}`);
168996
169082
  notifyLightTurnedOn(homeAssistant.entityId);
169083
+ const now = Date.now();
169084
+ sweepOptimisticOnOff(now);
168997
169085
  optimisticOnOffState.set(homeAssistant.entityId, {
168998
169086
  expectedOnOff: true,
168999
- timestamp: Date.now()
169087
+ timestamp: now
169000
169088
  });
169001
169089
  homeAssistant.callAction(action);
169002
169090
  if (turnOff === null) {
@@ -169015,10 +169103,12 @@ var OnOffServerBase = class extends OnOffServer {
169015
169103
  if (!action) {
169016
169104
  return;
169017
169105
  }
169018
- logger169.info(`[${homeAssistant.entityId}] Turning OFF -> ${action.action}`);
169106
+ logger170.info(`[${homeAssistant.entityId}] Turning OFF -> ${action.action}`);
169107
+ const now = Date.now();
169108
+ sweepOptimisticOnOff(now);
169019
169109
  optimisticOnOffState.set(homeAssistant.entityId, {
169020
169110
  expectedOnOff: false,
169021
- timestamp: Date.now()
169111
+ timestamp: now
169022
169112
  });
169023
169113
  homeAssistant.callAction(action);
169024
169114
  }
@@ -169038,14 +169128,16 @@ function OnOffServer2(config10 = {}) {
169038
169128
  return OnOffServerBase.set({ config: config10 });
169039
169129
  }
169040
169130
  function setOptimisticOnOff(entityId, expectedOnOff) {
169131
+ const now = Date.now();
169132
+ sweepOptimisticOnOff(now);
169041
169133
  optimisticOnOffState.set(entityId, {
169042
169134
  expectedOnOff,
169043
- timestamp: Date.now()
169135
+ timestamp: now
169044
169136
  });
169045
169137
  }
169046
169138
 
169047
169139
  // src/matter/behaviors/fan-control-server.ts
169048
- var logger170 = Logger.get("FanControlServer");
169140
+ var logger171 = Logger.get("FanControlServer");
169049
169141
  var defaultStepSize = 33.33;
169050
169142
  var minSpeedMax = 3;
169051
169143
  var maxSpeedMax = 100;
@@ -169421,7 +169513,7 @@ var FanControlServerBase = class extends FeaturedBase5 {
169421
169513
  const entityId = this.agent.get(HomeAssistantEntityBehavior).entity.entity_id;
169422
169514
  setOptimisticOnOff(entityId, on);
169423
169515
  } catch (e) {
169424
- logger170.debug(
169516
+ logger171.debug(
169425
169517
  `syncOnOff(${on}) failed: ${e instanceof Error ? e.message : String(e)}`
169426
169518
  );
169427
169519
  }
@@ -169509,7 +169601,7 @@ var FanOnOffServer = OnOffServer2({
169509
169601
  });
169510
169602
 
169511
169603
  // src/matter/endpoints/composed/composed-air-purifier-endpoint.ts
169512
- var logger171 = Logger.get("ComposedAirPurifierEndpoint");
169604
+ var logger172 = Logger.get("ComposedAirPurifierEndpoint");
169513
169605
  var temperatureConfig = {
169514
169606
  getValue(entity, agent) {
169515
169607
  const fallbackUnit = agent.env.get(HomeAssistantConfig).unitSystem.temperature;
@@ -169722,7 +169814,7 @@ var ComposedAirPurifierEndpoint = class _ComposedAirPurifierEndpoint extends End
169722
169814
  config10.powerEntityId ? "+Pwr" : "",
169723
169815
  config10.energyEntityId ? "+Nrg" : ""
169724
169816
  ].filter(Boolean).join("");
169725
- logger171.info(
169817
+ logger172.info(
169726
169818
  `Created composed air purifier ${primaryEntityId}: ${clusterLabels}`
169727
169819
  );
169728
169820
  return endpoint;
@@ -169822,7 +169914,7 @@ init_home_assistant_entity_behavior();
169822
169914
  // src/matter/behaviors/pressure-measurement-server.ts
169823
169915
  init_esm();
169824
169916
  init_home_assistant_entity_behavior();
169825
- var logger172 = Logger.get("PressureMeasurementServer");
169917
+ var logger173 = Logger.get("PressureMeasurementServer");
169826
169918
  var MIN_PRESSURE = 300;
169827
169919
  var MAX_PRESSURE = 1100;
169828
169920
  var PressureMeasurementServerBase = class extends PressureMeasurementServer {
@@ -169850,7 +169942,7 @@ var PressureMeasurementServerBase = class extends PressureMeasurementServer {
169850
169942
  }
169851
169943
  const rounded = Math.round(value);
169852
169944
  if (rounded < MIN_PRESSURE || rounded > MAX_PRESSURE) {
169853
- logger172.warn(
169945
+ logger173.warn(
169854
169946
  `Pressure value ${rounded} (raw: ${value}) for ${entity.entity_id} is outside valid range [${MIN_PRESSURE}-${MAX_PRESSURE}], ignoring`
169855
169947
  );
169856
169948
  return null;
@@ -169869,7 +169961,7 @@ function PressureMeasurementServer2(config10) {
169869
169961
  }
169870
169962
 
169871
169963
  // src/matter/endpoints/composed/composed-sensor-endpoint.ts
169872
- var logger173 = Logger.get("ComposedSensorEndpoint");
169964
+ var logger174 = Logger.get("ComposedSensorEndpoint");
169873
169965
  var temperatureConfig2 = {
169874
169966
  getValue(entity, agent) {
169875
169967
  const fallbackUnit = agent.env.get(HomeAssistantConfig).unitSystem.temperature;
@@ -170043,7 +170135,7 @@ var ComposedSensorEndpoint = class _ComposedSensorEndpoint extends Endpoint {
170043
170135
  if (config10.pressureEntityId && pressSub) {
170044
170136
  endpoint.subEndpoints.set(config10.pressureEntityId, pressSub);
170045
170137
  }
170046
- logger173.info(
170138
+ logger174.info(
170047
170139
  `Created composed sensor ${primaryEntityId} with ${parts.length} sub-endpoint(s): T${humSub ? "+H" : ""}${pressSub ? "+P" : ""}${config10.batteryEntityId ? "+Bat" : ""}${config10.powerEntityId ? "+Pwr" : ""}${config10.energyEntityId ? "+Nrg" : ""}`
170048
170140
  );
170049
170141
  return endpoint;
@@ -170179,7 +170271,7 @@ init_home_assistant_entity_behavior();
170179
170271
  // src/matter/behaviors/mode-select-server.ts
170180
170272
  init_esm();
170181
170273
  init_home_assistant_entity_behavior();
170182
- var logger174 = Logger.get("ModeSelectServer");
170274
+ var logger175 = Logger.get("ModeSelectServer");
170183
170275
  var ModeSelectServerBase = class extends ModeSelectServer {
170184
170276
  async initialize() {
170185
170277
  await super.initialize();
@@ -170208,13 +170300,13 @@ var ModeSelectServerBase = class extends ModeSelectServer {
170208
170300
  const options = config10.getOptions(homeAssistant.entity);
170209
170301
  const { newMode } = request;
170210
170302
  if (newMode < 0 || newMode >= options.length) {
170211
- logger174.warn(
170303
+ logger175.warn(
170212
170304
  `[${homeAssistant.entityId}] Invalid mode ${newMode}, options: [${options.join(", ")}]`
170213
170305
  );
170214
170306
  return;
170215
170307
  }
170216
170308
  const option = options[newMode];
170217
- logger174.info(
170309
+ logger175.info(
170218
170310
  `[${homeAssistant.entityId}] changeToMode(${newMode}) -> "${option}"`
170219
170311
  );
170220
170312
  applyPatchState(this.state, { currentMode: newMode });
@@ -170421,13 +170513,15 @@ var ContactSensorType = ContactSensorDevice.with(
170421
170513
  BasicInformationServer2,
170422
170514
  IdentifyServer2,
170423
170515
  HomeAssistantEntityBehavior,
170424
- BooleanStateServer2({ inverted: true })
170516
+ BooleanStateServer2({ inverted: true }),
170517
+ BooleanStateConfigurationServer
170425
170518
  );
170426
170519
  var ContactSensorWithBatteryType = ContactSensorDevice.with(
170427
170520
  BasicInformationServer2,
170428
170521
  IdentifyServer2,
170429
170522
  HomeAssistantEntityBehavior,
170430
170523
  BooleanStateServer2({ inverted: true }),
170524
+ BooleanStateConfigurationServer,
170431
170525
  PowerSourceServer2({
170432
170526
  getBatteryPercent: (entity, agent) => {
170433
170527
  const homeAssistant = agent.get(HomeAssistantEntityBehavior);
@@ -170633,7 +170727,8 @@ var RainSensorType = RainSensorDevice.with(
170633
170727
  BasicInformationServer2,
170634
170728
  IdentifyServer2,
170635
170729
  HomeAssistantEntityBehavior,
170636
- BooleanStateServer2()
170730
+ BooleanStateServer2(),
170731
+ BooleanStateConfigurationServer
170637
170732
  );
170638
170733
 
170639
170734
  // ../../node_modules/.pnpm/@matter+main@0.16.11/node_modules/@matter/main/dist/esm/forwards/behaviors/smoke-co-alarm.js
@@ -170723,7 +170818,8 @@ var WaterFreezeDetectorType = WaterFreezeDetectorDevice.with(
170723
170818
  BasicInformationServer2,
170724
170819
  IdentifyServer2,
170725
170820
  HomeAssistantEntityBehavior,
170726
- BooleanStateServer2()
170821
+ BooleanStateServer2(),
170822
+ BooleanStateConfigurationServer
170727
170823
  );
170728
170824
 
170729
170825
  // src/matter/endpoints/legacy/binary-sensor/water-leak-detector.ts
@@ -170732,11 +170828,12 @@ var WaterLeakDetectorType = WaterLeakDetectorDevice.with(
170732
170828
  BasicInformationServer2,
170733
170829
  IdentifyServer2,
170734
170830
  HomeAssistantEntityBehavior,
170735
- BooleanStateServer2()
170831
+ BooleanStateServer2(),
170832
+ BooleanStateConfigurationServer
170736
170833
  );
170737
170834
 
170738
170835
  // src/matter/endpoints/legacy/binary-sensor/index.ts
170739
- var logger175 = Logger.get("BinarySensorDevice");
170836
+ var logger176 = Logger.get("BinarySensorDevice");
170740
170837
  var deviceClasses = {
170741
170838
  [BinarySensorDeviceClass.CarbonMonoxide]: CoAlarmType,
170742
170839
  [BinarySensorDeviceClass.Gas]: CoAlarmType,
@@ -170788,11 +170885,11 @@ function BinarySensorDevice(homeAssistantEntity) {
170788
170885
  const originalTypeName = type.name;
170789
170886
  if (hasBattery && batteryTypes.has(type)) {
170790
170887
  type = batteryTypes.get(type);
170791
- logger175.info(
170888
+ logger176.info(
170792
170889
  `[${entityId}] Using battery variant: ${originalTypeName} -> ${type.name}, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
170793
170890
  );
170794
170891
  } else if (hasBattery) {
170795
- logger175.warn(
170892
+ logger176.warn(
170796
170893
  `[${entityId}] Has battery but no variant available for ${originalTypeName}`
170797
170894
  );
170798
170895
  }
@@ -170946,7 +171043,7 @@ init_home_assistant_entity_behavior();
170946
171043
  // src/matter/behaviors/thermostat-server.ts
170947
171044
  init_esm();
170948
171045
  init_home_assistant_entity_behavior();
170949
- var logger176 = Logger.get("ThermostatServer");
171046
+ var logger177 = Logger.get("ThermostatServer");
170950
171047
  var SystemMode = Thermostat3.SystemMode;
170951
171048
  var RunningMode = Thermostat3.ThermostatRunningMode;
170952
171049
  var nudgingSetpoints = /* @__PURE__ */ new Set();
@@ -171004,7 +171101,7 @@ var HeatingAndCoolingFeaturedBase = ThermostatServer.with("Heating", "Cooling").
171004
171101
  );
171005
171102
  function thermostatPreInitialize(self) {
171006
171103
  const currentLocal = self.state.localTemperature;
171007
- logger176.debug(
171104
+ logger177.debug(
171008
171105
  `initialize: features - heating=${self.features.heating}, cooling=${self.features.cooling}`
171009
171106
  );
171010
171107
  const localValue = typeof currentLocal === "number" && !Number.isNaN(currentLocal) ? currentLocal : currentLocal === null ? null : 2100;
@@ -171027,7 +171124,7 @@ function thermostatPreInitialize(self) {
171027
171124
  const coolingValue = typeof currentCooling === "number" && !Number.isNaN(currentCooling) ? currentCooling : 2400;
171028
171125
  self.state.occupiedCoolingSetpoint = coolingValue;
171029
171126
  }
171030
- logger176.debug(
171127
+ logger177.debug(
171031
171128
  `initialize: after force-set - local=${self.state.localTemperature}`
171032
171129
  );
171033
171130
  self.state.thermostatRunningState = runningStateAllOff;
@@ -171109,7 +171206,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171109
171206
  maxCoolLimit,
171110
171207
  "cool"
171111
171208
  );
171112
- logger176.debug(
171209
+ logger177.debug(
171113
171210
  `update: limits heat=[${minHeatLimit}, ${maxHeatLimit}], cool=[${minCoolLimit}, ${maxCoolLimit}], systemMode=${systemMode}, runningMode=${runningMode}`
171114
171211
  );
171115
171212
  let controlSequence = config10.getControlSequence(entity.state, this.agent);
@@ -171182,18 +171279,18 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171182
171279
  */
171183
171280
  // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Called via thermostatPostInitialize + prototype copy
171184
171281
  heatingSetpointChanging(value, _oldValue, context) {
171185
- logger176.debug(
171282
+ logger177.debug(
171186
171283
  `heatingSetpointChanging: value=${value}, oldValue=${_oldValue}, isOffline=${transactionIsOffline(context)}`
171187
171284
  );
171188
171285
  if (transactionIsOffline(context)) {
171189
- logger176.debug(
171286
+ logger177.debug(
171190
171287
  "heatingSetpointChanging: skipping - transaction is offline"
171191
171288
  );
171192
171289
  return;
171193
171290
  }
171194
171291
  const next = Temperature.celsius(value / 100);
171195
171292
  if (!next) {
171196
- logger176.debug("heatingSetpointChanging: skipping - invalid temperature");
171293
+ logger177.debug("heatingSetpointChanging: skipping - invalid temperature");
171197
171294
  return;
171198
171295
  }
171199
171296
  this.agent.asLocalActor(() => {
@@ -171204,7 +171301,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171204
171301
  this.agent
171205
171302
  );
171206
171303
  const currentMode = this.state.systemMode;
171207
- logger176.debug(
171304
+ logger177.debug(
171208
171305
  `heatingSetpointChanging: supportsRange=${supportsRange}, systemMode=${currentMode}, features.heating=${this.features.heating}, features.cooling=${this.features.cooling}`
171209
171306
  );
171210
171307
  if (!supportsRange) {
@@ -171214,12 +171311,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171214
171311
  const isOff = currentMode === Thermostat3.SystemMode.Off;
171215
171312
  if (isOff && this.features.heating) {
171216
171313
  if (nudgingSetpoints.has(homeAssistant.entityId)) {
171217
- logger176.debug(
171314
+ logger177.debug(
171218
171315
  `heatingSetpointChanging: skipping auto-resume - nudge write in progress`
171219
171316
  );
171220
171317
  return;
171221
171318
  }
171222
- logger176.info(
171319
+ logger177.info(
171223
171320
  `heatingSetpointChanging: auto-resume - switching to Heat (was Off)`
171224
171321
  );
171225
171322
  const modeAction = config10.setSystemMode(
@@ -171228,17 +171325,17 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171228
171325
  );
171229
171326
  homeAssistant.callAction(modeAction);
171230
171327
  } else if (!isAutoMode && !isHeatingMode) {
171231
- logger176.debug(
171328
+ logger177.debug(
171232
171329
  `heatingSetpointChanging: skipping - not in heating/auto mode (mode=${currentMode}, haMode=${haHvacMode})`
171233
171330
  );
171234
171331
  return;
171235
171332
  }
171236
- logger176.debug(
171333
+ logger177.debug(
171237
171334
  `heatingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isHeatingMode=${isHeatingMode}, isOff=${isOff}, haMode=${haHvacMode}`
171238
171335
  );
171239
171336
  }
171240
171337
  const coolingSetpoint = this.features.cooling ? this.state.occupiedCoolingSetpoint : value;
171241
- logger176.debug(
171338
+ logger177.debug(
171242
171339
  `heatingSetpointChanging: calling setTemperature with heat=${next.celsius(true)}, cool=${coolingSetpoint}`
171243
171340
  );
171244
171341
  this.setTemperature(
@@ -171277,12 +171374,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171277
171374
  const isOff = currentMode === Thermostat3.SystemMode.Off;
171278
171375
  if (isOff && !this.features.heating && this.features.cooling) {
171279
171376
  if (nudgingSetpoints.has(homeAssistant.entityId)) {
171280
- logger176.debug(
171377
+ logger177.debug(
171281
171378
  `coolingSetpointChanging: skipping auto-resume - nudge write in progress`
171282
171379
  );
171283
171380
  return;
171284
171381
  }
171285
- logger176.info(
171382
+ logger177.info(
171286
171383
  `coolingSetpointChanging: auto-resume - switching to Cool (was Off)`
171287
171384
  );
171288
171385
  const modeAction = config10.setSystemMode(
@@ -171291,12 +171388,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171291
171388
  );
171292
171389
  homeAssistant.callAction(modeAction);
171293
171390
  } else if (!isAutoMode && !isCoolingMode) {
171294
- logger176.debug(
171391
+ logger177.debug(
171295
171392
  `coolingSetpointChanging: skipping - not in cooling/auto mode (mode=${currentMode}, haMode=${haHvacMode})`
171296
171393
  );
171297
171394
  return;
171298
171395
  }
171299
- logger176.debug(
171396
+ logger177.debug(
171300
171397
  `coolingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isCoolingMode=${isCoolingMode}, isOff=${isOff}, haMode=${haHvacMode}`
171301
171398
  );
171302
171399
  }
@@ -171366,6 +171463,8 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171366
171463
  default:
171367
171464
  return allOff;
171368
171465
  }
171466
+ default:
171467
+ return allOff;
171369
171468
  }
171370
171469
  }
171371
171470
  clampControlSequence(value) {
@@ -171393,7 +171492,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171393
171492
  const effectiveMax = max ?? 5e3;
171394
171493
  if (value == null || Number.isNaN(value)) {
171395
171494
  const defaultValue = type === "heat" ? 2e3 : 2400;
171396
- logger176.debug(
171495
+ logger177.debug(
171397
171496
  `${type} setpoint is undefined, using default: ${defaultValue}`
171398
171497
  );
171399
171498
  return Math.max(effectiveMin, Math.min(effectiveMax, defaultValue));
@@ -171537,7 +171636,10 @@ var hvacActionToRunningMode = {
171537
171636
  [ClimateHvacAction.preheating]: Thermostat3.ThermostatRunningMode.Heat,
171538
171637
  [ClimateHvacAction.defrosting]: Thermostat3.ThermostatRunningMode.Heat,
171539
171638
  [ClimateHvacAction.heating]: Thermostat3.ThermostatRunningMode.Heat,
171540
- [ClimateHvacAction.drying]: Thermostat3.ThermostatRunningMode.Heat,
171639
+ // Drying has no dedicated Matter RunningMode; reporting Heat made Apple
171640
+ // Home display "Heating to …" during dehumidification. Off is neutral and
171641
+ // getRunningState() downgrades it to FanOnly/Dry via systemMode.
171642
+ [ClimateHvacAction.drying]: Thermostat3.ThermostatRunningMode.Off,
171541
171643
  [ClimateHvacAction.cooling]: Thermostat3.ThermostatRunningMode.Cool,
171542
171644
  [ClimateHvacAction.fan]: Thermostat3.ThermostatRunningMode.Off,
171543
171645
  [ClimateHvacAction.idle]: Thermostat3.ThermostatRunningMode.Off,
@@ -171838,7 +171940,7 @@ init_home_assistant_entity_behavior();
171838
171940
  init_esm();
171839
171941
  init_home_assistant_actions();
171840
171942
  init_home_assistant_entity_behavior();
171841
- var logger177 = Logger.get("WindowCoveringServer");
171943
+ var logger178 = Logger.get("WindowCoveringServer");
171842
171944
  var MovementStatus = WindowCovering3.MovementStatus;
171843
171945
  var FeaturedBase6 = WindowCoveringServer.with(
171844
171946
  "Lift",
@@ -171954,7 +172056,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
171954
172056
  }
171955
172057
  return existing100ths ?? current100ths;
171956
172058
  };
171957
- logger177.debug(
172059
+ logger178.debug(
171958
172060
  `Cover update for ${entity.entity_id}: state=${state.state}, lift=${currentLift}%, tilt=${currentTilt}%, movement=${MovementStatus[movementStatus]}`
171959
172061
  );
171960
172062
  const appliedPatch = applyPatchState(
@@ -171997,9 +172099,9 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
171997
172099
  );
171998
172100
  if (Object.keys(appliedPatch).length > 0) {
171999
172101
  const hasOperationalChange = "operationalStatus" in appliedPatch;
172000
- const log = hasOperationalChange ? logger177.info : logger177.debug;
172102
+ const log = hasOperationalChange ? logger178.info : logger178.debug;
172001
172103
  log.call(
172002
- logger177,
172104
+ logger178,
172003
172105
  `Cover ${entity.entity_id} state changed: ${JSON.stringify(appliedPatch)}`
172004
172106
  );
172005
172107
  }
@@ -172007,7 +172109,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
172007
172109
  async handleMovement(type, _, direction, targetPercent100ths) {
172008
172110
  const currentLift = this.state.currentPositionLiftPercent100ths ?? 0;
172009
172111
  const currentTilt = this.state.currentPositionTiltPercent100ths ?? 0;
172010
- logger177.info(
172112
+ logger178.info(
172011
172113
  `handleMovement: type=${MovementType[type]}, direction=${MovementDirection[direction]}, target=${targetPercent100ths}, currentLift=${currentLift}, currentTilt=${currentTilt}, absolutePosition=${this.features.absolutePosition}`
172012
172114
  );
172013
172115
  if (type === MovementType.Lift) {
@@ -172026,7 +172128,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
172026
172128
  }
172027
172129
  } else if (type === MovementType.Tilt) {
172028
172130
  if (targetPercent100ths == null && this.lastLiftMovementDirection === direction && Date.now() - this.lastLiftMovementMs < 50) {
172029
- logger177.info(
172131
+ logger178.info(
172030
172132
  `Skipping tilt ${MovementDirection[direction]} \u2014 lift already moving in same direction`
172031
172133
  );
172032
172134
  return;
@@ -172051,13 +172153,13 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
172051
172153
  handleLiftOpen() {
172052
172154
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
172053
172155
  const action = this.state.config.openCoverLift(void 0, this.agent);
172054
- logger177.info(`handleLiftOpen: calling action=${action.action}`);
172156
+ logger178.info(`handleLiftOpen: calling action=${action.action}`);
172055
172157
  homeAssistant.callAction(action);
172056
172158
  }
172057
172159
  handleLiftClose() {
172058
172160
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
172059
172161
  const action = this.state.config.closeCoverLift(void 0, this.agent);
172060
- logger177.info(`handleLiftClose: calling action=${action.action}`);
172162
+ logger178.info(`handleLiftClose: calling action=${action.action}`);
172061
172163
  homeAssistant.callAction(action);
172062
172164
  }
172063
172165
  handleGoToLiftPosition(targetPercent100ths) {
@@ -172078,7 +172180,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
172078
172180
  this.lastLiftCommandTime = now;
172079
172181
  const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
172080
172182
  const debounceMs = isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
172081
- logger177.debug(
172183
+ logger178.debug(
172082
172184
  `Lift command: target=${targetPosition}%, debounce=${debounceMs}ms (${isFirstInSequence ? "initial" : "subsequent"})`
172083
172185
  );
172084
172186
  if (this.liftDebounceTimer) {
@@ -172127,7 +172229,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
172127
172229
  this.lastTiltCommandTime = now;
172128
172230
  const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
172129
172231
  const debounceMs = isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
172130
- logger177.debug(
172232
+ logger178.debug(
172131
172233
  `Tilt command: target=${targetPosition}%, debounce=${debounceMs}ms (${isFirstInSequence ? "initial" : "subsequent"})`
172132
172234
  );
172133
172235
  if (this.tiltDebounceTimer) {
@@ -172158,7 +172260,7 @@ function WindowCoveringServer2(config10) {
172158
172260
  }
172159
172261
 
172160
172262
  // src/matter/endpoints/legacy/cover/behaviors/cover-position-utils.ts
172161
- function adjustPositionForReading(position, flags2, matterSemantics) {
172263
+ function adjustPosition(position, flags2, matterSemantics) {
172162
172264
  if (position == null) {
172163
172265
  return null;
172164
172266
  }
@@ -172171,22 +172273,15 @@ function adjustPositionForReading(position, flags2, matterSemantics) {
172171
172273
  }
172172
172274
  return position;
172173
172275
  }
172276
+ function adjustPositionForReading(position, flags2, matterSemantics) {
172277
+ return adjustPosition(position, flags2, matterSemantics);
172278
+ }
172174
172279
  function adjustPositionForWriting(position, flags2, matterSemantics) {
172175
- if (position == null) {
172176
- return null;
172177
- }
172178
- const skipInversion = flags2?.coverDoNotInvertPercentage === true || flags2?.coverUseHomeAssistantPercentage === true || matterSemantics;
172179
- if (flags2?.coverSwapOpenClose === true && !skipInversion) {
172180
- return position;
172181
- }
172182
- if (!skipInversion) {
172183
- return 100 - position;
172184
- }
172185
- return position;
172280
+ return adjustPosition(position, flags2, matterSemantics);
172186
172281
  }
172187
172282
 
172188
172283
  // src/matter/endpoints/legacy/cover/behaviors/cover-window-covering-server.ts
172189
- var logger178 = Logger.get("CoverWindowCoveringServer");
172284
+ var logger179 = Logger.get("CoverWindowCoveringServer");
172190
172285
  var attributes5 = (entity) => entity.attributes;
172191
172286
  var MATTER_SEMANTIC_PLATFORMS = [
172192
172287
  // Currently empty - no known platforms use Matter semantics by default
@@ -172204,7 +172299,7 @@ var adjustPositionForReading2 = (position, agent) => {
172204
172299
  const { featureFlags } = agent.env.get(BridgeDataProvider);
172205
172300
  const matterSem = usesMatterSemantics(agent);
172206
172301
  const result = adjustPositionForReading(position, featureFlags, matterSem);
172207
- logger178.debug(`adjustPositionForReading: HA=${position}%, result=${result}%`);
172302
+ logger179.debug(`adjustPositionForReading: HA=${position}%, result=${result}%`);
172208
172303
  return result;
172209
172304
  };
172210
172305
  var adjustPositionForWriting2 = (position, agent) => {
@@ -172311,7 +172406,7 @@ var config5 = {
172311
172406
  var CoverWindowCoveringServer = WindowCoveringServer2(config5);
172312
172407
 
172313
172408
  // src/matter/endpoints/legacy/cover/index.ts
172314
- var logger179 = Logger.get("CoverDevice");
172409
+ var logger180 = Logger.get("CoverDevice");
172315
172410
  var DISCRETE_COVER_CLASSES = /* @__PURE__ */ new Set(["garage", "gate"]);
172316
172411
  var CoverDeviceType = (supportedFeatures, hasBattery, entityId, isDiscrete) => {
172317
172412
  const features2 = /* @__PURE__ */ new Set();
@@ -172322,7 +172417,7 @@ var CoverDeviceType = (supportedFeatures, hasBattery, entityId, isDiscrete) => {
172322
172417
  features2.add("AbsolutePosition");
172323
172418
  }
172324
172419
  } else {
172325
- logger179.warn(
172420
+ logger180.warn(
172326
172421
  `[${entityId}] Cover has no support_open feature (supported_features=${supportedFeatures}), adding Lift anyway`
172327
172422
  );
172328
172423
  features2.add("Lift");
@@ -172341,7 +172436,7 @@ var CoverDeviceType = (supportedFeatures, hasBattery, entityId, isDiscrete) => {
172341
172436
  features2.add("AbsolutePosition");
172342
172437
  }
172343
172438
  }
172344
- logger179.info(
172439
+ logger180.info(
172345
172440
  `[${entityId}] Creating WindowCovering with features: [${[...features2].join(", ")}], supported_features=${supportedFeatures}`
172346
172441
  );
172347
172442
  const baseBehaviors = [
@@ -172365,18 +172460,18 @@ function CoverDevice(homeAssistantEntity) {
172365
172460
  const hasBatteryEntity = !!homeAssistantEntity.mapping?.batteryEntity;
172366
172461
  const hasBattery = hasBatteryAttr || hasBatteryEntity;
172367
172462
  if (hasBattery) {
172368
- logger179.info(
172463
+ logger180.info(
172369
172464
  `[${entityId}] Creating cover with PowerSource cluster, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
172370
172465
  );
172371
172466
  } else {
172372
- logger179.debug(
172467
+ logger180.debug(
172373
172468
  `[${entityId}] Creating cover without battery (batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"})`
172374
172469
  );
172375
172470
  }
172376
172471
  const deviceClass = attributes7.device_class;
172377
172472
  const isDiscrete = typeof deviceClass === "string" && DISCRETE_COVER_CLASSES.has(deviceClass.toLowerCase());
172378
172473
  if (isDiscrete) {
172379
- logger179.info(
172474
+ logger180.info(
172380
172475
  `[${entityId}] Garage/gate cover (device_class=${deviceClass}): using discrete Open/Close mode`
172381
172476
  );
172382
172477
  }
@@ -172493,7 +172588,7 @@ function DishwasherEndpoint(homeAssistantEntity) {
172493
172588
  // src/matter/behaviors/generic-switch-server.ts
172494
172589
  init_esm();
172495
172590
  init_home_assistant_entity_behavior();
172496
- var logger180 = Logger.get("GenericSwitchServer");
172591
+ var logger181 = Logger.get("GenericSwitchServer");
172497
172592
  var SimpleBase = SwitchServer.with(
172498
172593
  "MomentarySwitch",
172499
172594
  "MomentarySwitchRelease",
@@ -172535,7 +172630,7 @@ var HaGenericSwitchServerBase = class extends SimpleBase {
172535
172630
  await super.initialize();
172536
172631
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
172537
172632
  const entityId = homeAssistant.entityId;
172538
- logger180.debug(`[${entityId}] GenericSwitch initialized (simple)`);
172633
+ logger181.debug(`[${entityId}] GenericSwitch initialized (simple)`);
172539
172634
  this.reactTo(homeAssistant.onChange, this.handleEventChange);
172540
172635
  }
172541
172636
  handleEventChange() {
@@ -172546,7 +172641,7 @@ var HaGenericSwitchServerBase = class extends SimpleBase {
172546
172641
  const eventType = attrs.event_type;
172547
172642
  if (!eventType) return;
172548
172643
  const entityId = homeAssistant.entityId;
172549
- logger180.debug(`[${entityId}] Event fired: ${eventType}`);
172644
+ logger181.debug(`[${entityId}] Event fired: ${eventType}`);
172550
172645
  this.triggerPress(eventType);
172551
172646
  }
172552
172647
  triggerPress(eventType) {
@@ -172592,7 +172687,7 @@ var HaGenericSwitchServerMultiBase = class extends FullBase {
172592
172687
  await super.initialize();
172593
172688
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
172594
172689
  const entityId = homeAssistant.entityId;
172595
- logger180.debug(`[${entityId}] GenericSwitch initialized (multi)`);
172690
+ logger181.debug(`[${entityId}] GenericSwitch initialized (multi)`);
172596
172691
  this.reactTo(homeAssistant.onChange, this.handleEventChange);
172597
172692
  }
172598
172693
  handleEventChange() {
@@ -172603,7 +172698,7 @@ var HaGenericSwitchServerMultiBase = class extends FullBase {
172603
172698
  const eventType = attrs.event_type;
172604
172699
  if (!eventType) return;
172605
172700
  const entityId = homeAssistant.entityId;
172606
- logger180.debug(`[${entityId}] Event fired: ${eventType}`);
172701
+ logger181.debug(`[${entityId}] Event fired: ${eventType}`);
172607
172702
  this.triggerPress(eventType);
172608
172703
  }
172609
172704
  triggerPress(eventType) {
@@ -172724,12 +172819,16 @@ function FanDevice2(homeAssistantEntity) {
172724
172819
  IdentifyServer2,
172725
172820
  BasicInformationServer2,
172726
172821
  HomeAssistantEntityBehavior,
172822
+ GroupsServer,
172823
+ ScenesManagementServer,
172727
172824
  FanOnOffServer,
172728
172825
  DefaultPowerSourceServer
172729
172826
  ) : OnOffPlugInUnitDevice.with(
172730
172827
  IdentifyServer2,
172731
172828
  BasicInformationServer2,
172732
172829
  HomeAssistantEntityBehavior,
172830
+ GroupsServer,
172831
+ ScenesManagementServer,
172733
172832
  FanOnOffServer
172734
172833
  );
172735
172834
  return onOffDevice.set({ homeAssistantEntity });
@@ -172758,6 +172857,7 @@ function FanDevice2(homeAssistantEntity) {
172758
172857
  IdentifyServer2,
172759
172858
  BasicInformationServer2,
172760
172859
  HomeAssistantEntityBehavior,
172860
+ GroupsServer,
172761
172861
  FanOnOffServer,
172762
172862
  FanFanControlServer.with(...features2),
172763
172863
  DefaultPowerSourceServer
@@ -172765,6 +172865,7 @@ function FanDevice2(homeAssistantEntity) {
172765
172865
  IdentifyServer2,
172766
172866
  BasicInformationServer2,
172767
172867
  HomeAssistantEntityBehavior,
172868
+ GroupsServer,
172768
172869
  FanOnOffServer,
172769
172870
  FanFanControlServer.with(...features2)
172770
172871
  );
@@ -172933,7 +173034,7 @@ init_nodejs();
172933
173034
 
172934
173035
  // src/matter/behaviors/color-control-server.ts
172935
173036
  init_home_assistant_entity_behavior();
172936
- var logger181 = Logger.get("ColorControlServer");
173037
+ var logger182 = Logger.get("ColorControlServer");
172937
173038
  var optimisticColorState = /* @__PURE__ */ new Map();
172938
173039
  var OPTIMISTIC_TIMEOUT_MS3 = 3e3;
172939
173040
  var OPTIMISTIC_TOLERANCE2 = 5;
@@ -172972,7 +173073,7 @@ var ColorControlServerBase = class extends FeaturedBase7 {
172972
173073
  if (this.state.startUpColorTemperatureMireds == null) {
172973
173074
  this.state.startUpColorTemperatureMireds = defaultMireds;
172974
173075
  }
172975
- logger181.debug(
173076
+ logger182.debug(
172976
173077
  `initialize: set ColorTemperature defaults - min=${this.state.colorTempPhysicalMinMireds}, max=${this.state.colorTempPhysicalMaxMireds}, current=${this.state.colorTemperatureMireds}`
172977
173078
  );
172978
173079
  }
@@ -173077,9 +173178,12 @@ var ColorControlServerBase = class extends FeaturedBase7 {
173077
173178
  ...skipColorTemp ? {} : { colorTemperatureMireds: effectiveMireds }
173078
173179
  });
173079
173180
  }
173181
+ const writingHueSat = this.features.hueSaturation && !skipHueSat;
173182
+ const writingColorTemp = !skipColorTemp && newColorMode === ColorControl3.ColorMode.ColorTemperatureMireds;
173183
+ const shouldPublishColorMode = writingHueSat && newColorMode !== ColorControl3.ColorMode.ColorTemperatureMireds || writingColorTemp;
173080
173184
  applyPatchState(this.state, {
173081
- ...skipColorTemp && skipHueSat ? {} : { colorMode: newColorMode },
173082
- ...this.features.hueSaturation && !skipHueSat ? {
173185
+ ...shouldPublishColorMode ? { colorMode: newColorMode } : {},
173186
+ ...writingHueSat ? {
173083
173187
  currentHue: hue,
173084
173188
  currentSaturation: saturation
173085
173189
  } : {}
@@ -173097,6 +173201,9 @@ var ColorControlServerBase = class extends FeaturedBase7 {
173097
173201
  this.agent
173098
173202
  );
173099
173203
  const targetKelvin = ColorConverter.temperatureMiredsToKelvin(targetMireds);
173204
+ if (targetKelvin == null) {
173205
+ return;
173206
+ }
173100
173207
  if (currentKelvin === targetKelvin) {
173101
173208
  return;
173102
173209
  }
@@ -173284,6 +173391,8 @@ var ColorTemperatureLightType = ColorTemperatureLightDevice.with(
173284
173391
  IdentifyServer2,
173285
173392
  BasicInformationServer2,
173286
173393
  HomeAssistantEntityBehavior,
173394
+ GroupsServer,
173395
+ ScenesManagementServer,
173287
173396
  LightOnOffServer,
173288
173397
  LightLevelControlServer,
173289
173398
  LightColorControlServer.with("ColorTemperature")
@@ -173295,6 +173404,8 @@ var DimmableLightType = DimmableLightDevice.with(
173295
173404
  IdentifyServer2,
173296
173405
  BasicInformationServer2,
173297
173406
  HomeAssistantEntityBehavior,
173407
+ GroupsServer,
173408
+ ScenesManagementServer,
173298
173409
  LightOnOffServer,
173299
173410
  LightLevelControlServer
173300
173411
  );
@@ -173302,6 +173413,8 @@ var DimmableLightWithBatteryType = DimmableLightDevice.with(
173302
173413
  IdentifyServer2,
173303
173414
  BasicInformationServer2,
173304
173415
  HomeAssistantEntityBehavior,
173416
+ GroupsServer,
173417
+ ScenesManagementServer,
173305
173418
  LightOnOffServer,
173306
173419
  LightLevelControlServer,
173307
173420
  DefaultPowerSourceServer
@@ -173322,6 +173435,8 @@ var ExtendedColorLightType = (supportsColorControl, supportsTemperature, hasBatt
173322
173435
  IdentifyServer2,
173323
173436
  BasicInformationServer2,
173324
173437
  HomeAssistantEntityBehavior,
173438
+ GroupsServer,
173439
+ ScenesManagementServer,
173325
173440
  LightOnOffServer,
173326
173441
  LightLevelControlServer,
173327
173442
  LightColorControlServer.with(...features2),
@@ -173332,6 +173447,8 @@ var ExtendedColorLightType = (supportsColorControl, supportsTemperature, hasBatt
173332
173447
  IdentifyServer2,
173333
173448
  BasicInformationServer2,
173334
173449
  HomeAssistantEntityBehavior,
173450
+ GroupsServer,
173451
+ ScenesManagementServer,
173335
173452
  LightOnOffServer,
173336
173453
  LightLevelControlServer,
173337
173454
  LightColorControlServer.with(...features2)
@@ -173344,12 +173461,16 @@ var OnOffLightType = OnOffLightDevice.with(
173344
173461
  IdentifyServer2,
173345
173462
  BasicInformationServer2,
173346
173463
  HomeAssistantEntityBehavior,
173464
+ GroupsServer,
173465
+ ScenesManagementServer,
173347
173466
  LightOnOffServer
173348
173467
  );
173349
173468
  var OnOffLightWithBatteryType = OnOffLightDevice.with(
173350
173469
  IdentifyServer2,
173351
173470
  BasicInformationServer2,
173352
173471
  HomeAssistantEntityBehavior,
173472
+ GroupsServer,
173473
+ ScenesManagementServer,
173353
173474
  LightOnOffServer,
173354
173475
  DefaultPowerSourceServer
173355
173476
  );
@@ -173405,7 +173526,7 @@ init_home_assistant_entity_behavior();
173405
173526
  // src/matter/behaviors/lock-server.ts
173406
173527
  init_esm();
173407
173528
  init_home_assistant_entity_behavior();
173408
- var logger182 = Logger.get("LockServer");
173529
+ var logger183 = Logger.get("LockServer");
173409
173530
  function hasStoredCredentialHelper(env, entityId) {
173410
173531
  try {
173411
173532
  const storage2 = env.get(LockCredentialStorage);
@@ -173563,7 +173684,7 @@ var LockServerWithPinBase = class extends PinCredentialBase {
173563
173684
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
173564
173685
  const action = this.state.config.lock(void 0, this.agent);
173565
173686
  const hasPinProvided = !!request.pinCode;
173566
- logger182.debug(
173687
+ logger183.debug(
173567
173688
  `lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
173568
173689
  );
173569
173690
  if (request.pinCode) {
@@ -173576,12 +173697,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
173576
173697
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
173577
173698
  const action = this.state.config.unlock(void 0, this.agent);
173578
173699
  const hasPinProvided = !!request.pinCode;
173579
- logger182.debug(
173700
+ logger183.debug(
173580
173701
  `unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
173581
173702
  );
173582
173703
  if (this.state.requirePinForRemoteOperation) {
173583
173704
  if (!request.pinCode) {
173584
- logger182.info(
173705
+ logger183.info(
173585
173706
  `unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
173586
173707
  );
173587
173708
  throw new StatusResponseError(
@@ -173591,12 +173712,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
173591
173712
  }
173592
173713
  const providedPin = new TextDecoder().decode(request.pinCode);
173593
173714
  if (!this.verifyStoredPin(homeAssistant.entityId, providedPin)) {
173594
- logger182.info(
173715
+ logger183.info(
173595
173716
  `unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
173596
173717
  );
173597
173718
  throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
173598
173719
  }
173599
- logger182.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
173720
+ logger183.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
173600
173721
  action.data = { ...action.data, code: providedPin };
173601
173722
  }
173602
173723
  homeAssistant.callAction(action);
@@ -173757,7 +173878,7 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
173757
173878
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
173758
173879
  const action = this.state.config.lock(void 0, this.agent);
173759
173880
  const hasPinProvided = !!request.pinCode;
173760
- logger182.debug(
173881
+ logger183.debug(
173761
173882
  `lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
173762
173883
  );
173763
173884
  if (request.pinCode) {
@@ -173771,12 +173892,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
173771
173892
  const unlatchConfig = this.state.config.unlatch;
173772
173893
  const action = unlatchConfig ? unlatchConfig(void 0, this.agent) : this.state.config.unlock(void 0, this.agent);
173773
173894
  const hasPinProvided = !!request.pinCode;
173774
- logger182.debug(
173895
+ logger183.debug(
173775
173896
  `unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}, usingUnlatch: ${!!unlatchConfig}`
173776
173897
  );
173777
173898
  if (this.state.requirePinForRemoteOperation) {
173778
173899
  if (!request.pinCode) {
173779
- logger182.info(
173900
+ logger183.info(
173780
173901
  `unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
173781
173902
  );
173782
173903
  throw new StatusResponseError(
@@ -173786,12 +173907,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
173786
173907
  }
173787
173908
  const providedPin = new TextDecoder().decode(request.pinCode);
173788
173909
  if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
173789
- logger182.info(
173910
+ logger183.info(
173790
173911
  `unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
173791
173912
  );
173792
173913
  throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
173793
173914
  }
173794
- logger182.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
173915
+ logger183.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
173795
173916
  action.data = { ...action.data, code: providedPin };
173796
173917
  }
173797
173918
  homeAssistant.callAction(action);
@@ -173806,12 +173927,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
173806
173927
  }
173807
173928
  const action = unlatchConfig(void 0, this.agent);
173808
173929
  const hasPinProvided = !!request.pinCode;
173809
- logger182.debug(
173930
+ logger183.debug(
173810
173931
  `unboltDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
173811
173932
  );
173812
173933
  if (this.state.requirePinForRemoteOperation) {
173813
173934
  if (!request.pinCode) {
173814
- logger182.info(
173935
+ logger183.info(
173815
173936
  `unboltDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
173816
173937
  );
173817
173938
  throw new StatusResponseError(
@@ -173821,12 +173942,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
173821
173942
  }
173822
173943
  const providedPin = new TextDecoder().decode(request.pinCode);
173823
173944
  if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
173824
- logger182.info(
173945
+ logger183.info(
173825
173946
  `unboltDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
173826
173947
  );
173827
173948
  throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
173828
173949
  }
173829
- logger182.debug(`unboltDoor PIN verified for ${homeAssistant.entityId}`);
173950
+ logger183.debug(`unboltDoor PIN verified for ${homeAssistant.entityId}`);
173830
173951
  action.data = { ...action.data, code: providedPin };
173831
173952
  }
173832
173953
  homeAssistant.callAction(action);
@@ -173977,7 +174098,7 @@ init_home_assistant_entity_behavior();
173977
174098
  init_dist();
173978
174099
  init_esm();
173979
174100
  init_home_assistant_entity_behavior();
173980
- var logger183 = Logger.get("MediaPlayerKeypadInputServer");
174101
+ var logger184 = Logger.get("MediaPlayerKeypadInputServer");
173981
174102
  var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
173982
174103
  sendKey(request) {
173983
174104
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
@@ -173988,12 +174109,12 @@ var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
173988
174109
  const features2 = attributes7.supported_features ?? 0;
173989
174110
  const action = this.mapKeyToAction(request.keyCode, features2);
173990
174111
  if (!action) {
173991
- logger183.debug(
174112
+ logger184.debug(
173992
174113
  `Unsupported key code ${request.keyCode} for ${homeAssistant.entityId}`
173993
174114
  );
173994
174115
  return { status: KeypadInput3.Status.UnsupportedKey };
173995
174116
  }
173996
- logger183.debug(
174117
+ logger184.debug(
173997
174118
  `sendKey(${request.keyCode}) \u2192 ${action} for ${homeAssistant.entityId}`
173998
174119
  );
173999
174120
  homeAssistant.callAction({ action });
@@ -174272,10 +174393,17 @@ init_home_assistant_entity_behavior();
174272
174393
  // src/matter/behaviors/speaker-level-control-server.ts
174273
174394
  init_esm();
174274
174395
  init_home_assistant_entity_behavior();
174275
- var logger184 = Logger.get("SpeakerLevelControlServer");
174396
+ var logger185 = Logger.get("SpeakerLevelControlServer");
174276
174397
  var optimisticLevelState2 = /* @__PURE__ */ new Map();
174277
174398
  var OPTIMISTIC_TIMEOUT_MS4 = 3e3;
174278
174399
  var OPTIMISTIC_TOLERANCE3 = 5;
174400
+ function sweepOptimisticLevel2(now) {
174401
+ for (const [key, value] of optimisticLevelState2) {
174402
+ if (now - value.timestamp > OPTIMISTIC_TIMEOUT_MS4) {
174403
+ optimisticLevelState2.delete(key);
174404
+ }
174405
+ }
174406
+ }
174279
174407
  var FeaturedBase8 = LevelControlServer.with("OnOff");
174280
174408
  var SpeakerLevelControlServerBase = class extends FeaturedBase8 {
174281
174409
  async initialize() {
@@ -174308,7 +174436,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase8 {
174308
174436
  currentLevel = Math.min(Math.max(minLevel, currentLevel), maxLevel);
174309
174437
  }
174310
174438
  const entityId = this.agent.get(HomeAssistantEntityBehavior).entity.entity_id;
174311
- logger184.debug(
174439
+ logger185.debug(
174312
174440
  `[${entityId}] Volume update: HA=${currentLevelPercent != null ? Math.round(currentLevelPercent * 100) : "null"}% -> currentLevel=${currentLevel}`
174313
174441
  );
174314
174442
  const optimistic = optimisticLevelState2.get(entity.entity_id);
@@ -174356,7 +174484,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase8 {
174356
174484
  const config10 = this.state.config;
174357
174485
  const entityId = homeAssistant.entity.entity_id;
174358
174486
  const levelPercent = level / 254;
174359
- logger184.debug(
174487
+ logger185.debug(
174360
174488
  `[${entityId}] Volume command: level=${level} -> HA volume_level=${levelPercent}`
174361
174489
  );
174362
174490
  const current = config10.getValuePercent(
@@ -174367,9 +174495,11 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase8 {
174367
174495
  return;
174368
174496
  }
174369
174497
  this.state.currentLevel = level;
174498
+ const now = Date.now();
174499
+ sweepOptimisticLevel2(now);
174370
174500
  optimisticLevelState2.set(entityId, {
174371
174501
  expectedLevel: level,
174372
- timestamp: Date.now()
174502
+ timestamp: now
174373
174503
  });
174374
174504
  homeAssistant.callAction(
174375
174505
  config10.moveToLevelPercent(levelPercent, this.agent)
@@ -175718,7 +175848,7 @@ var TvocConcentrationMeasurementServer = class extends TvocConcentrationMeasurem
175718
175848
  };
175719
175849
 
175720
175850
  // src/matter/endpoints/legacy/sensor/devices/tvoc-sensor.ts
175721
- var logger185 = Logger.get("TvocSensor");
175851
+ var logger186 = Logger.get("TvocSensor");
175722
175852
  function airQualityFromUgm3(value) {
175723
175853
  if (value <= 300) return AirQuality3.AirQualityEnum.Good;
175724
175854
  if (value <= 1e3) return AirQuality3.AirQualityEnum.Fair;
@@ -175759,17 +175889,17 @@ var TvocAirQualityServer = class extends TvocAirQualityServerBase {
175759
175889
  const attributes7 = entity.state.attributes;
175760
175890
  const deviceClass = attributes7.device_class;
175761
175891
  let airQuality = AirQuality3.AirQualityEnum.Unknown;
175762
- logger185.debug(
175892
+ logger186.debug(
175763
175893
  `[${entity.entity_id}] TVOC update: state="${state}", device_class="${deviceClass}"`
175764
175894
  );
175765
175895
  if (state != null && !Number.isNaN(+state)) {
175766
175896
  const value = +state;
175767
175897
  airQuality = deviceClass === SensorDeviceClass.volatile_organic_compounds ? airQualityFromUgm3(value) : airQualityFromPpb(value);
175768
- logger185.debug(
175898
+ logger186.debug(
175769
175899
  `[${entity.entity_id}] TVOC value=${value} (${deviceClass}) -> airQuality=${AirQuality3.AirQualityEnum[airQuality]}`
175770
175900
  );
175771
175901
  } else {
175772
- logger185.warn(
175902
+ logger186.warn(
175773
175903
  `[${entity.entity_id}] TVOC state not a valid number: "${state}"`
175774
175904
  );
175775
175905
  }
@@ -175983,7 +176113,7 @@ init_home_assistant_entity_behavior();
175983
176113
  // src/matter/behaviors/pm25-concentration-measurement-server.ts
175984
176114
  init_esm();
175985
176115
  init_home_assistant_entity_behavior();
175986
- var logger186 = Logger.get("Pm25ConcentrationMeasurementServer");
176116
+ var logger187 = Logger.get("Pm25ConcentrationMeasurementServer");
175987
176117
  var Pm25ConcentrationMeasurementServerBase = Pm25ConcentrationMeasurementServer.with(
175988
176118
  ConcentrationMeasurement3.Feature.NumericMeasurement
175989
176119
  );
@@ -176007,11 +176137,11 @@ var Pm25ConcentrationMeasurementServer2 = class extends Pm25ConcentrationMeasure
176007
176137
  if (this.state.measurementMedium === void 0) {
176008
176138
  this.state.measurementMedium = ConcentrationMeasurement3.MeasurementMedium.Air;
176009
176139
  }
176010
- logger186.debug(
176140
+ logger187.debug(
176011
176141
  "Pm25ConcentrationMeasurementServer: before super.initialize()"
176012
176142
  );
176013
176143
  await super.initialize();
176014
- logger186.debug(
176144
+ logger187.debug(
176015
176145
  "Pm25ConcentrationMeasurementServer: after super.initialize()"
176016
176146
  );
176017
176147
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
@@ -176034,7 +176164,7 @@ var Pm25ConcentrationMeasurementServer2 = class extends Pm25ConcentrationMeasure
176034
176164
  };
176035
176165
 
176036
176166
  // src/matter/endpoints/legacy/sensor/devices/pm25-sensor.ts
176037
- var logger187 = Logger.get("Pm25AirQualityServer");
176167
+ var logger188 = Logger.get("Pm25AirQualityServer");
176038
176168
  var Pm25AirQualityServerBase = AirQualityServer.with(
176039
176169
  AirQuality3.Feature.Fair,
176040
176170
  AirQuality3.Feature.Moderate,
@@ -176046,9 +176176,9 @@ var Pm25AirQualityServer = class extends Pm25AirQualityServerBase {
176046
176176
  if (this.state.airQuality === void 0) {
176047
176177
  this.state.airQuality = AirQuality3.AirQualityEnum.Unknown;
176048
176178
  }
176049
- logger187.debug("Pm25AirQualityServer: before super.initialize()");
176179
+ logger188.debug("Pm25AirQualityServer: before super.initialize()");
176050
176180
  await super.initialize();
176051
- logger187.debug("Pm25AirQualityServer: after super.initialize()");
176181
+ logger188.debug("Pm25AirQualityServer: after super.initialize()");
176052
176182
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
176053
176183
  this.update(homeAssistant.entity);
176054
176184
  this.reactTo(homeAssistant.onChange, this.update);
@@ -176384,6 +176514,8 @@ var DimmablePlugInUnitType = DimmablePlugInUnitDevice.with(
176384
176514
  IdentifyServer2,
176385
176515
  BasicInformationServer2,
176386
176516
  HomeAssistantEntityBehavior,
176517
+ GroupsServer,
176518
+ ScenesManagementServer,
176387
176519
  LightOnOffServer,
176388
176520
  LightLevelControlServer
176389
176521
  );
@@ -176395,12 +176527,16 @@ var SwitchEndpointType = OnOffPlugInUnitDevice.with(
176395
176527
  BasicInformationServer2,
176396
176528
  IdentifyServer2,
176397
176529
  HomeAssistantEntityBehavior,
176530
+ GroupsServer,
176531
+ ScenesManagementServer,
176398
176532
  SwitchOnOffServer
176399
176533
  );
176400
176534
  var SwitchWithBatteryEndpointType = OnOffPlugInUnitDevice.with(
176401
176535
  BasicInformationServer2,
176402
176536
  IdentifyServer2,
176403
176537
  HomeAssistantEntityBehavior,
176538
+ GroupsServer,
176539
+ ScenesManagementServer,
176404
176540
  SwitchOnOffServer,
176405
176541
  DefaultPowerSourceServer
176406
176542
  );
@@ -176428,7 +176564,7 @@ init_home_assistant_entity_behavior();
176428
176564
  init_dist();
176429
176565
  init_esm();
176430
176566
  init_home_assistant_entity_behavior();
176431
- var logger188 = Logger.get("VacuumIdentifyServer");
176567
+ var logger189 = Logger.get("VacuumIdentifyServer");
176432
176568
  var VacuumIdentifyServer = class extends IdentifyServer2 {
176433
176569
  triggerEffect(effect) {
176434
176570
  this.#locate("triggerEffect");
@@ -176445,11 +176581,11 @@ var VacuumIdentifyServer = class extends IdentifyServer2 {
176445
176581
  const features2 = homeAssistant.entity.state.attributes.supported_features ?? 0;
176446
176582
  const hasLocate = testBit(features2, VacuumDeviceFeature.LOCATE);
176447
176583
  if (!hasLocate) {
176448
- logger188.warn(
176584
+ logger189.warn(
176449
176585
  `${source} for ${homeAssistant.entityId} \u2014 LOCATE not in supported_features (${features2}), calling vacuum.locate anyway`
176450
176586
  );
176451
176587
  } else {
176452
- logger188.info(`${source} \u2192 vacuum.locate for ${homeAssistant.entityId}`);
176588
+ logger189.info(`${source} \u2192 vacuum.locate for ${homeAssistant.entityId}`);
176453
176589
  }
176454
176590
  homeAssistant.callAction({ action: "vacuum.locate" });
176455
176591
  }
@@ -176468,7 +176604,7 @@ init_rvc_run_mode();
176468
176604
 
176469
176605
  // src/matter/behaviors/rvc-run-mode-server.ts
176470
176606
  init_home_assistant_entity_behavior();
176471
- var logger189 = Logger.get("RvcRunModeServer");
176607
+ var logger190 = Logger.get("RvcRunModeServer");
176472
176608
  var ROOM_MODE_BASE = 100;
176473
176609
  function isRoomMode(mode) {
176474
176610
  return mode >= ROOM_MODE_BASE;
@@ -176549,7 +176685,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
176549
176685
  const s = getSession(this.endpoint);
176550
176686
  if (s.loggedShortCircuits.has(reason)) return;
176551
176687
  s.loggedShortCircuits.add(reason);
176552
- logger189.info(message);
176688
+ logger190.info(message);
176553
176689
  }
176554
176690
  /**
176555
176691
  * Read the currentRoomEntity sensor and update currentArea + progress
@@ -176610,7 +176746,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
176610
176746
  }
176611
176747
  }
176612
176748
  if (matchedAreaId === null) {
176613
- logger189.info(
176749
+ logger190.info(
176614
176750
  `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(", ")}]`
176615
176751
  );
176616
176752
  return;
@@ -176620,14 +176756,14 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
176620
176756
  s.completedAreas.add(s.lastCurrentArea);
176621
176757
  }
176622
176758
  s.lastCurrentArea = matchedAreaId;
176623
- logger189.info(
176759
+ logger190.info(
176624
176760
  `currentRoom sensor: transition to area ${matchedAreaId} ("${roomName}"), completed: [${[...s.completedAreas].join(", ")}]`
176625
176761
  );
176626
176762
  this.trySetCurrentArea(matchedAreaId);
176627
176763
  } catch (e) {
176628
176764
  const msg = e instanceof Error ? e.message : String(e);
176629
176765
  if (!msg.includes("No provider for") && !msg.includes("not supported")) {
176630
- logger189.warn(`currentRoom sensor update failed: ${msg}`);
176766
+ logger190.warn(`currentRoom sensor update failed: ${msg}`);
176631
176767
  }
176632
176768
  }
176633
176769
  }
@@ -176642,7 +176778,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
176642
176778
  const serviceArea = this.agent.get(ServiceAreaBehavior);
176643
176779
  if (serviceArea.state.currentArea !== areaId) {
176644
176780
  serviceArea.state.currentArea = areaId;
176645
- logger189.debug(`currentArea set to ${areaId}`);
176781
+ logger190.debug(`currentArea set to ${areaId}`);
176646
176782
  }
176647
176783
  this.updateProgress(serviceArea, areaId);
176648
176784
  } catch {
@@ -176990,14 +177126,14 @@ init_esm();
176990
177126
 
176991
177127
  // src/matter/behaviors/service-area-server.ts
176992
177128
  init_esm();
176993
- var logger190 = Logger.get("ServiceAreaServer");
177129
+ var logger191 = Logger.get("ServiceAreaServer");
176994
177130
  var ServiceAreaWithProgress = ServiceAreaBehavior.with(
176995
177131
  ServiceArea3.Feature.ProgressReporting
176996
177132
  );
176997
177133
  var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
176998
177134
  selectAreas(request) {
176999
177135
  const { newAreas } = request;
177000
- logger190.info(
177136
+ logger191.info(
177001
177137
  `ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
177002
177138
  );
177003
177139
  const uniqueAreas = [...new Set(newAreas)];
@@ -177006,7 +177142,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
177006
177142
  (id) => !supportedAreaIds.includes(id)
177007
177143
  );
177008
177144
  if (invalidAreas.length > 0) {
177009
- logger190.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
177145
+ logger191.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
177010
177146
  return {
177011
177147
  status: ServiceArea3.SelectAreasStatus.UnsupportedArea,
177012
177148
  statusText: `Invalid area IDs: ${invalidAreas.join(", ")}`
@@ -177017,7 +177153,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
177017
177153
  areaId,
177018
177154
  status: ServiceArea3.OperationalStatus.Pending
177019
177155
  }));
177020
- logger190.info(
177156
+ logger191.info(
177021
177157
  `ServiceArea: Stored ${uniqueAreas.length} areas for cleaning: ${uniqueAreas.join(", ")}`
177022
177158
  );
177023
177159
  return {
@@ -177038,7 +177174,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
177038
177174
  ServiceAreaServerBase2.State = State;
177039
177175
  })(ServiceAreaServerBase || (ServiceAreaServerBase = {}));
177040
177176
  function ServiceAreaServer2(initialState) {
177041
- logger190.info(
177177
+ logger191.info(
177042
177178
  `Creating ServiceAreaServer with ${initialState.supportedAreas.length} areas`
177043
177179
  );
177044
177180
  return ServiceAreaServerBase.set({
@@ -177055,7 +177191,7 @@ var ServiceAreaWithMapsAndProgress = ServiceAreaBehavior.with(
177055
177191
  var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress {
177056
177192
  selectAreas(request) {
177057
177193
  const { newAreas } = request;
177058
- logger190.info(
177194
+ logger191.info(
177059
177195
  `ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
177060
177196
  );
177061
177197
  const uniqueAreas = [...new Set(newAreas)];
@@ -177064,7 +177200,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
177064
177200
  (id) => !supportedAreaIds.includes(id)
177065
177201
  );
177066
177202
  if (invalidAreas.length > 0) {
177067
- logger190.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
177203
+ logger191.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
177068
177204
  return {
177069
177205
  status: ServiceArea3.SelectAreasStatus.UnsupportedArea,
177070
177206
  statusText: `Invalid area IDs: ${invalidAreas.join(", ")}`
@@ -177075,7 +177211,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
177075
177211
  areaId,
177076
177212
  status: ServiceArea3.OperationalStatus.Pending
177077
177213
  }));
177078
- logger190.info(
177214
+ logger191.info(
177079
177215
  `ServiceArea: Stored ${uniqueAreas.length} areas for cleaning: ${uniqueAreas.join(", ")}`
177080
177216
  );
177081
177217
  return {
@@ -177096,14 +177232,14 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
177096
177232
  ServiceAreaServerWithMapsBase2.State = State;
177097
177233
  })(ServiceAreaServerWithMapsBase || (ServiceAreaServerWithMapsBase = {}));
177098
177234
  function ServiceAreaServerWithMaps(initialState) {
177099
- logger190.info(
177235
+ logger191.info(
177100
177236
  `Creating ServiceAreaServer with Maps: ${initialState.supportedAreas.length} areas, ${initialState.supportedMaps.length} maps`
177101
177237
  );
177102
177238
  for (const map of initialState.supportedMaps) {
177103
177239
  const areaCount = initialState.supportedAreas.filter(
177104
177240
  (a) => a.mapId === map.mapId
177105
177241
  ).length;
177106
- logger190.info(` Map ${map.mapId}: "${map.name}" (${areaCount} areas)`);
177242
+ logger191.info(` Map ${map.mapId}: "${map.name}" (${areaCount} areas)`);
177107
177243
  }
177108
177244
  return ServiceAreaServerWithMapsBase.set({
177109
177245
  supportedAreas: initialState.supportedAreas,
@@ -177115,7 +177251,7 @@ function ServiceAreaServerWithMaps(initialState) {
177115
177251
  }
177116
177252
 
177117
177253
  // src/matter/endpoints/legacy/vacuum/behaviors/vacuum-service-area-server.ts
177118
- var logger191 = Logger.get("VacuumServiceAreaServer");
177254
+ var logger192 = Logger.get("VacuumServiceAreaServer");
177119
177255
  function toAreaId(roomId) {
177120
177256
  if (typeof roomId === "number") {
177121
177257
  return roomId;
@@ -177194,13 +177330,13 @@ function createVacuumServiceAreaServer(attributes7, roomEntities, includeUnnamed
177194
177330
  let rooms;
177195
177331
  if (roomEntities && roomEntities.length > 0) {
177196
177332
  rooms = buttonEntitiesToRooms(roomEntities, attributes7);
177197
- logger191.info(
177333
+ logger192.info(
177198
177334
  `Using ${rooms.length} button entities as rooms: ${rooms.map((r) => r.name).join(", ")}`
177199
177335
  );
177200
177336
  } else {
177201
177337
  rooms = parseVacuumRooms(attributes7, includeUnnamedRooms);
177202
177338
  if (rooms.length > 0) {
177203
- logger191.info(
177339
+ logger192.info(
177204
177340
  `Using ${rooms.length} rooms from attributes: ${rooms.map((r) => r.name).join(", ")}`
177205
177341
  );
177206
177342
  }
@@ -177254,7 +177390,7 @@ function createCustomServiceAreaServer(customAreas) {
177254
177390
  landmarkInfo: null
177255
177391
  }
177256
177392
  }));
177257
- logger191.info(
177393
+ logger192.info(
177258
177394
  `Using ${customAreas.length} custom service areas: ${customAreas.map((a) => a.name).join(", ")}`
177259
177395
  );
177260
177396
  return ServiceAreaServer2({
@@ -177276,7 +177412,7 @@ function createCleanAreaServiceAreaServer(cleanAreaRooms) {
177276
177412
  landmarkInfo: null
177277
177413
  }
177278
177414
  }));
177279
- logger191.info(
177415
+ logger192.info(
177280
177416
  `Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA: ${cleanAreaRooms.map((r) => r.name).join(", ")}`
177281
177417
  );
177282
177418
  return ServiceAreaServer2({
@@ -177287,11 +177423,11 @@ function createCleanAreaServiceAreaServer(cleanAreaRooms) {
177287
177423
  }
177288
177424
 
177289
177425
  // src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-run-mode-server.ts
177290
- var logger192 = Logger.get("VacuumRvcRunModeServer");
177426
+ var logger193 = Logger.get("VacuumRvcRunModeServer");
177291
177427
  function buildValetudoSegmentAction(vacuumEntityId, segmentIds, valetudoIdentifier) {
177292
177428
  const identifier = valetudoIdentifier || vacuumEntityId.replace(/^vacuum\.valetudo_/, "");
177293
177429
  const topic = `valetudo/${identifier}/MapSegmentationCapability/clean/set`;
177294
- logger192.info(
177430
+ logger193.info(
177295
177431
  `Valetudo: mqtt.publish to ${topic}, segments: ${segmentIds.join(", ")}`
177296
177432
  );
177297
177433
  return {
@@ -177353,12 +177489,12 @@ function handleCustomServiceAreas(selectedAreas, customAreas, homeAssistant, ser
177353
177489
  const matched = selectedAreas.map((areaId) => customAreas[areaId - 1]).filter(Boolean);
177354
177490
  serviceArea.state.selectedAreas = [];
177355
177491
  if (matched.length === 0) {
177356
- logger192.warn(
177492
+ logger193.warn(
177357
177493
  `Custom service areas: no match for selected IDs ${selectedAreas.join(", ")}`
177358
177494
  );
177359
177495
  return { action: "vacuum.start" };
177360
177496
  }
177361
- logger192.info(
177497
+ logger193.info(
177362
177498
  `Custom service areas: calling ${matched.length} service(s): ${matched.map((a) => `${a.service} (${a.name})`).join(", ")}`
177363
177499
  );
177364
177500
  for (let i = 1; i < matched.length; i++) {
@@ -177398,7 +177534,7 @@ var vacuumRvcRunModeConfig = {
177398
177534
  VacuumState.paused
177399
177535
  ];
177400
177536
  const isCleaning = cleaningStates.includes(state);
177401
- logger192.debug(
177537
+ logger193.debug(
177402
177538
  `Vacuum state: "${state}", isCleaning: ${isCleaning}, currentMode: ${isCleaning ? "Cleaning" : "Idle"}`
177403
177539
  );
177404
177540
  return isCleaning ? 1 /* Cleaning */ : 0 /* Idle */;
@@ -177430,7 +177566,7 @@ var vacuumRvcRunModeConfig = {
177430
177566
  const haAreaIds = resolveCleanAreaIds(selectedAreas, cleanAreaRooms);
177431
177567
  serviceArea.state.selectedAreas = [];
177432
177568
  if (haAreaIds.length > 0) {
177433
- logger192.info(
177569
+ logger193.info(
177434
177570
  `CLEAN_AREA: cleaning HA areas: ${haAreaIds.join(", ")}`
177435
177571
  );
177436
177572
  return {
@@ -177451,7 +177587,7 @@ var vacuumRvcRunModeConfig = {
177451
177587
  }
177452
177588
  }
177453
177589
  if (buttonEntityIds.length > 0) {
177454
- logger192.info(
177590
+ logger193.info(
177455
177591
  `Roborock: Pressing button entities for selected rooms: ${buttonEntityIds.join(", ")}`
177456
177592
  );
177457
177593
  serviceArea.state.selectedAreas = [];
@@ -177489,7 +177625,7 @@ var vacuumRvcRunModeConfig = {
177489
177625
  }
177490
177626
  }
177491
177627
  if (roomIds.length > 0) {
177492
- logger192.info(
177628
+ logger193.info(
177493
177629
  `Starting cleaning with selected areas: ${roomIds.join(", ")}`
177494
177630
  );
177495
177631
  serviceArea.state.selectedAreas = [];
@@ -177497,7 +177633,7 @@ var vacuumRvcRunModeConfig = {
177497
177633
  if (targetMapName) {
177498
177634
  const vacName = vacuumEntityId.replace("vacuum.", "");
177499
177635
  const selectedMapEntity = `select.${vacName}_selected_map`;
177500
- logger192.info(
177636
+ logger193.info(
177501
177637
  `Dreame multi-floor: switching to map "${targetMapName}" via ${selectedMapEntity}`
177502
177638
  );
177503
177639
  homeAssistant.callAction({
@@ -177524,7 +177660,7 @@ var vacuumRvcRunModeConfig = {
177524
177660
  }
177525
177661
  if (isEcovacsVacuum(attributes7)) {
177526
177662
  const roomIdStr = roomIds.join(",");
177527
- logger192.info(
177663
+ logger193.info(
177528
177664
  `Ecovacs vacuum: Using spot_area for rooms: ${roomIdStr}`
177529
177665
  );
177530
177666
  return {
@@ -177539,14 +177675,14 @@ var vacuumRvcRunModeConfig = {
177539
177675
  }
177540
177676
  };
177541
177677
  }
177542
- logger192.warn(
177678
+ logger193.warn(
177543
177679
  `Room cleaning via send_command not supported for this vacuum type. Rooms: ${roomIds.join(", ")}. Falling back to vacuum.start`
177544
177680
  );
177545
177681
  }
177546
177682
  }
177547
177683
  } catch {
177548
177684
  }
177549
- logger192.info("Starting regular cleaning (no areas selected)");
177685
+ logger193.info("Starting regular cleaning (no areas selected)");
177550
177686
  return { action: "vacuum.start" };
177551
177687
  },
177552
177688
  returnToBase: () => ({ action: "vacuum.return_to_base" }),
@@ -177561,7 +177697,7 @@ var vacuumRvcRunModeConfig = {
177561
177697
  const homeAssistant = agent.get(HomeAssistantEntityBehavior);
177562
177698
  const entity = homeAssistant.entity;
177563
177699
  const attributes7 = entity.state.attributes;
177564
- logger192.info(`cleanRoom called: roomMode=${roomMode}`);
177700
+ logger193.info(`cleanRoom called: roomMode=${roomMode}`);
177565
177701
  const cleanAreaRooms = homeAssistant.state.mapping?.cleanAreaRooms;
177566
177702
  if (cleanAreaRooms && cleanAreaRooms.length > 0) {
177567
177703
  const sorted = [...cleanAreaRooms].sort(
@@ -177570,7 +177706,7 @@ var vacuumRvcRunModeConfig = {
177570
177706
  const areaIndex = roomMode - ROOM_MODE_BASE2 - 1;
177571
177707
  if (areaIndex >= 0 && areaIndex < sorted.length) {
177572
177708
  const area = sorted[areaIndex];
177573
- logger192.info(
177709
+ logger193.info(
177574
177710
  `cleanRoom: CLEAN_AREA "${area.name}" \u2192 vacuum.clean_area(${area.haAreaId})`
177575
177711
  );
177576
177712
  return {
@@ -177587,7 +177723,7 @@ var vacuumRvcRunModeConfig = {
177587
177723
  const areaIndex = roomMode - ROOM_MODE_BASE2 - 1;
177588
177724
  if (areaIndex >= 0 && areaIndex < sorted.length) {
177589
177725
  const area = sorted[areaIndex];
177590
- logger192.info(
177726
+ logger193.info(
177591
177727
  `cleanRoom: custom service area "${area.name}" \u2192 ${area.service}`
177592
177728
  );
177593
177729
  return {
@@ -177608,7 +177744,7 @@ var vacuumRvcRunModeConfig = {
177608
177744
  }
177609
177745
  const rooms = parseVacuumRooms(attributes7);
177610
177746
  const numericIdFromMode = getRoomIdFromMode(roomMode);
177611
- logger192.info(
177747
+ logger193.info(
177612
177748
  `cleanRoom: numericIdFromMode=${numericIdFromMode}, available rooms: ${JSON.stringify(rooms.map((r) => ({ id: r.id, name: r.name, modeValue: getRoomModeValue(r) })))}`
177613
177749
  );
177614
177750
  const room = rooms.find((r) => getRoomModeValue(r) === roomMode);
@@ -177618,7 +177754,7 @@ var vacuumRvcRunModeConfig = {
177618
177754
  if (room.mapName) {
177619
177755
  const vacuumName = vacuumEntityId.replace("vacuum.", "");
177620
177756
  const selectedMapEntity = `select.${vacuumName}_selected_map`;
177621
- logger192.info(
177757
+ logger193.info(
177622
177758
  `Dreame multi-floor: switching to map "${room.mapName}" via ${selectedMapEntity}`
177623
177759
  );
177624
177760
  homeAssistant.callAction({
@@ -177627,7 +177763,7 @@ var vacuumRvcRunModeConfig = {
177627
177763
  data: { option: room.mapName }
177628
177764
  });
177629
177765
  }
177630
- logger192.debug(
177766
+ logger193.debug(
177631
177767
  `Dreame vacuum detected, using dreame_vacuum.vacuum_clean_segment for room ${room.name} (commandId: ${commandId3}, id: ${room.id})`
177632
177768
  );
177633
177769
  return {
@@ -177638,7 +177774,7 @@ var vacuumRvcRunModeConfig = {
177638
177774
  };
177639
177775
  }
177640
177776
  if (isRoborockVacuum(attributes7) || isXiaomiMiotVacuum(attributes7)) {
177641
- logger192.debug(
177777
+ logger193.debug(
177642
177778
  `Using vacuum.send_command with app_segment_clean for room ${room.name} (commandId: ${commandId3}, id: ${room.id})`
177643
177779
  );
177644
177780
  return {
@@ -177651,7 +177787,7 @@ var vacuumRvcRunModeConfig = {
177651
177787
  }
177652
177788
  if (isEcovacsVacuum(attributes7)) {
177653
177789
  const roomIdStr = String(commandId3);
177654
- logger192.info(
177790
+ logger193.info(
177655
177791
  `Ecovacs vacuum: Using spot_area for room ${room.name} (id: ${roomIdStr})`
177656
177792
  );
177657
177793
  return {
@@ -177666,7 +177802,7 @@ var vacuumRvcRunModeConfig = {
177666
177802
  }
177667
177803
  };
177668
177804
  }
177669
- logger192.warn(
177805
+ logger193.warn(
177670
177806
  `Room cleaning via send_command not supported for this vacuum type. Room: ${room.name} (id=${commandId3}). Falling back to vacuum.start`
177671
177807
  );
177672
177808
  }
@@ -177682,20 +177818,20 @@ function createVacuumRvcRunModeServer(attributes7, includeUnnamedRooms = false,
177682
177818
  includeUnnamedRooms,
177683
177819
  customAreas
177684
177820
  );
177685
- logger192.info(
177821
+ logger193.info(
177686
177822
  `Creating VacuumRvcRunModeServer with ${rooms.length} rooms, ${supportedModes.length} total modes`
177687
177823
  );
177688
177824
  if (rooms.length > 0) {
177689
- logger192.info(`Rooms found: ${rooms.map((r) => r.name).join(", ")}`);
177825
+ logger193.info(`Rooms found: ${rooms.map((r) => r.name).join(", ")}`);
177690
177826
  }
177691
177827
  if (filteredCount > 0) {
177692
177828
  const filtered = allRooms.filter((r) => !rooms.some((x) => x.id === r.id));
177693
- logger192.info(
177829
+ logger193.info(
177694
177830
  `Filtered out ${filteredCount} unnamed room(s): ${filtered.map((r) => r.name).join(", ")}`
177695
177831
  );
177696
177832
  }
177697
177833
  if (allRooms.length === 0) {
177698
- logger192.debug(
177834
+ logger193.debug(
177699
177835
  `No rooms found. Attributes: rooms=${JSON.stringify(attributes7.rooms)}, segments=${JSON.stringify(attributes7.segments)}, room_list=${attributes7.room_list}`
177700
177836
  );
177701
177837
  }
@@ -177729,7 +177865,7 @@ function createCleanAreaRvcRunModeServer(cleanAreaRooms) {
177729
177865
  modeTags: [{ value: RvcRunMode3.ModeTag.Cleaning }]
177730
177866
  });
177731
177867
  }
177732
- logger192.info(
177868
+ logger193.info(
177733
177869
  `Creating CLEAN_AREA RvcRunModeServer with ${cleanAreaRooms.length} HA areas, ${modes.length} total modes`
177734
177870
  );
177735
177871
  return RvcRunModeServer2(vacuumRvcRunModeConfig, {
@@ -177790,7 +177926,7 @@ init_rvc_clean_mode();
177790
177926
 
177791
177927
  // src/matter/behaviors/rvc-clean-mode-server.ts
177792
177928
  init_home_assistant_entity_behavior();
177793
- var logger193 = Logger.get("RvcCleanModeServerBase");
177929
+ var logger194 = Logger.get("RvcCleanModeServerBase");
177794
177930
  var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeServer {
177795
177931
  // Pending mode from a recent changeToMode command.
177796
177932
  // Prevents stale HA state (from a different entity like select.xxx)
@@ -177833,14 +177969,14 @@ var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeS
177833
177969
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
177834
177970
  const { newMode } = request;
177835
177971
  if (newMode !== this.state.currentMode && !this.state.supportedModes.some((m) => m.mode === newMode)) {
177836
- logger193.warn(`changeToMode(${newMode}) rejected: unsupported mode`);
177972
+ logger194.warn(`changeToMode(${newMode}) rejected: unsupported mode`);
177837
177973
  return {
177838
177974
  status: ModeBase3.ModeChangeStatus.UnsupportedMode,
177839
177975
  statusText: `Unsupported mode: ${newMode}`
177840
177976
  };
177841
177977
  }
177842
177978
  const modeLabel = this.state.supportedModes.find((m) => m.mode === newMode);
177843
- logger193.info(
177979
+ logger194.info(
177844
177980
  `changeToMode(${newMode}) "${modeLabel?.label ?? "unknown"}" for ${homeAssistant.entityId}`
177845
177981
  );
177846
177982
  this.pendingMode = newMode;
@@ -177848,7 +177984,7 @@ var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeS
177848
177984
  this.state.currentMode = newMode;
177849
177985
  const action = this.state.config.setCleanMode(newMode, this.agent);
177850
177986
  if (action) {
177851
- logger193.info(
177987
+ logger194.info(
177852
177988
  `changeToMode: dispatching action ${action.action} \u2192 ${action.target ?? homeAssistant.entityId}`
177853
177989
  );
177854
177990
  homeAssistant.callAction(action);
@@ -177881,7 +178017,7 @@ function RvcCleanModeServer2(config10, initialState) {
177881
178017
  }
177882
178018
 
177883
178019
  // src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-clean-mode-server.ts
177884
- var logger194 = Logger.get("VacuumRvcCleanModeServer");
178020
+ var logger195 = Logger.get("VacuumRvcCleanModeServer");
177885
178021
  var MODE_VACUUM = 0;
177886
178022
  var MODE_VACUUM_AND_MOP = 1;
177887
178023
  var MODE_MOP = 2;
@@ -178180,7 +178316,7 @@ function findMatchingCleanOption(ct, availableOptions) {
178180
178316
  if (match) return match;
178181
178317
  }
178182
178318
  }
178183
- logger194.warn(
178319
+ logger195.warn(
178184
178320
  `No match for ${CLEAN_TYPE_LABELS[ct]} in [${availableOptions.join(", ")}]`
178185
178321
  );
178186
178322
  return aliases[0];
@@ -178189,7 +178325,7 @@ function buildCleaningModeAction(targetCleanType, agent) {
178189
178325
  const selectEntityId = getCleaningModeSelectEntity(agent);
178190
178326
  const { options } = readSelectEntity(selectEntityId, agent);
178191
178327
  const optionToUse = findMatchingCleanOption(targetCleanType, options);
178192
- logger194.info(
178328
+ logger195.info(
178193
178329
  `Switching cleaning mode to: ${optionToUse} via ${selectEntityId}`
178194
178330
  );
178195
178331
  return {
@@ -178278,7 +178414,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178278
178414
  }
178279
178415
  }
178280
178416
  if (speedMode !== void 0) {
178281
- logger194.debug(
178417
+ logger195.debug(
178282
178418
  `Current mode: Vacuum + fan_speed="${speedState}" -> mode ${speedMode}`
178283
178419
  );
178284
178420
  return speedMode;
@@ -178299,7 +178435,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178299
178435
  }
178300
178436
  }
178301
178437
  if (mopMode !== void 0) {
178302
- logger194.debug(
178438
+ logger195.debug(
178303
178439
  `Current mode: Mop + intensity="${state}" -> mode ${mopMode}`
178304
178440
  );
178305
178441
  return mopMode;
@@ -178317,14 +178453,14 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178317
178453
  const homeAssistant = agent.get(HomeAssistantEntityBehavior);
178318
178454
  const vacuumEntityId = homeAssistant.entityId;
178319
178455
  const mapping = homeAssistant.state.mapping;
178320
- logger194.info(
178456
+ logger195.info(
178321
178457
  `setCleanMode(${mode}) for ${vacuumEntityId} \u2014 suctionEntity=${mapping?.suctionLevelEntity ?? "none"}, mopEntity=${mapping?.mopIntensityEntity ?? "none"}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})}`
178322
178458
  );
178323
178459
  if (mopIntensityList && mopIntensityList.length > 0 && isMopIntensityMode(mode)) {
178324
178460
  const mopIndex = mode - MOP_INTENSITY_MODE_BASE;
178325
178461
  const mopName = mopIntensityList[mopIndex];
178326
178462
  if (!mopName) {
178327
- logger194.warn(`Invalid mop intensity mode index: ${mopIndex}`);
178463
+ logger195.warn(`Invalid mop intensity mode index: ${mopIndex}`);
178328
178464
  return void 0;
178329
178465
  }
178330
178466
  if (hasCleanTypes) {
@@ -178337,18 +178473,18 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178337
178473
  mapping.mopIntensityEntity,
178338
178474
  agent
178339
178475
  );
178340
- logger194.info(
178476
+ logger195.info(
178341
178477
  `Mop intensity entity ${mapping.mopIntensityEntity}: current="${state}", options=${JSON.stringify(options ?? [])}`
178342
178478
  );
178343
178479
  let option = matchMopIntensityOption(mopName, options);
178344
178480
  if (!option && options && mopIndex < options.length) {
178345
178481
  option = options[mopIndex];
178346
- logger194.info(
178482
+ logger195.info(
178347
178483
  `Positional match for mop "${mopName}" -> "${option}" (index ${mopIndex})`
178348
178484
  );
178349
178485
  }
178350
178486
  if (option) {
178351
- logger194.info(
178487
+ logger195.info(
178352
178488
  `Setting mop intensity to: ${option} via ${mapping.mopIntensityEntity}`
178353
178489
  );
178354
178490
  return {
@@ -178357,11 +178493,11 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178357
178493
  target: mapping.mopIntensityEntity
178358
178494
  };
178359
178495
  }
178360
- logger194.warn(
178496
+ logger195.warn(
178361
178497
  `No match for mop intensity "${mopName}" in options: [${(options ?? []).join(", ")}]`
178362
178498
  );
178363
178499
  } else {
178364
- logger194.warn(
178500
+ logger195.warn(
178365
178501
  `Mop intensity mode ${mode} requested but no mopIntensityEntity configured`
178366
178502
  );
178367
178503
  }
@@ -178371,7 +178507,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178371
178507
  const fanSpeedIndex = mode - FAN_SPEED_MODE_BASE;
178372
178508
  const fanSpeedName = fanSpeedList[fanSpeedIndex];
178373
178509
  if (!fanSpeedName) {
178374
- logger194.warn(`Invalid fan speed mode index: ${fanSpeedIndex}`);
178510
+ logger195.warn(`Invalid fan speed mode index: ${fanSpeedIndex}`);
178375
178511
  return void 0;
178376
178512
  }
178377
178513
  if (mapping?.suctionLevelEntity) {
@@ -178384,7 +178520,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178384
178520
  mapping.suctionLevelEntity,
178385
178521
  agent
178386
178522
  );
178387
- logger194.info(
178523
+ logger195.info(
178388
178524
  `Suction entity ${mapping.suctionLevelEntity}: current="${state}", options=${JSON.stringify(options ?? [])}`
178389
178525
  );
178390
178526
  let option = matchFanSpeedOption(
@@ -178394,12 +178530,12 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178394
178530
  );
178395
178531
  if (!option && options && fanSpeedIndex < options.length) {
178396
178532
  option = options[fanSpeedIndex];
178397
- logger194.info(
178533
+ logger195.info(
178398
178534
  `Positional match for fan "${fanSpeedName}" -> "${option}" (index ${fanSpeedIndex})`
178399
178535
  );
178400
178536
  }
178401
178537
  if (option) {
178402
- logger194.info(
178538
+ logger195.info(
178403
178539
  `Setting suction to: ${option} via ${mapping.suctionLevelEntity}`
178404
178540
  );
178405
178541
  return {
@@ -178408,7 +178544,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178408
178544
  target: mapping.suctionLevelEntity
178409
178545
  };
178410
178546
  }
178411
- logger194.warn(
178547
+ logger195.warn(
178412
178548
  `No match for fan speed "${fanSpeedName}" in suction options: [${(options ?? []).join(", ")}]`
178413
178549
  );
178414
178550
  return void 0;
@@ -178418,7 +178554,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178418
178554
  buildCleaningModeAction(0 /* Sweeping */, agent)
178419
178555
  );
178420
178556
  }
178421
- logger194.info(
178557
+ logger195.info(
178422
178558
  `Setting fan speed to: ${fanSpeedName} via vacuum.set_fan_speed`
178423
178559
  );
178424
178560
  return {
@@ -178428,7 +178564,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178428
178564
  };
178429
178565
  }
178430
178566
  if (!hasCleanTypes) {
178431
- logger194.debug(
178567
+ logger195.debug(
178432
178568
  `Ignoring cleaning type change (mode=${mode}): no cleaning mode entity`
178433
178569
  );
178434
178570
  return void 0;
@@ -178440,7 +178576,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
178440
178576
  agent
178441
178577
  );
178442
178578
  const optionToUse = findMatchingCleanOption(cleanType, availableOptions);
178443
- logger194.info(
178579
+ logger195.info(
178444
178580
  `Setting cleaning mode to: ${optionToUse} (mode=${mode}) via ${selectEntityId}`
178445
178581
  );
178446
178582
  return {
@@ -178458,10 +178594,10 @@ function createVacuumRvcCleanModeServer(_attributes, fanSpeedList, mopIntensityL
178458
178594
  cleaningModeOptions,
178459
178595
  customFanSpeedTags
178460
178596
  );
178461
- logger194.info(
178597
+ logger195.info(
178462
178598
  `Creating VacuumRvcCleanModeServer with ${supportedModes.length} modes (fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, cleaningModeOptions=${JSON.stringify(cleaningModeOptions ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})})`
178463
178599
  );
178464
- logger194.info(
178600
+ logger195.info(
178465
178601
  `Modes: ${supportedModes.map((m) => `${m.mode}:${m.label}[${m.modeTags.map((t) => t.value).join(",")}]`).join(", ")}`
178466
178602
  );
178467
178603
  const initialState = {
@@ -178539,7 +178675,7 @@ init_rvc_operational_state();
178539
178675
  init_home_assistant_entity_behavior();
178540
178676
  var OperationalState4 = RvcOperationalState3.OperationalState;
178541
178677
  var ErrorState = RvcOperationalState3.ErrorState;
178542
- var logger195 = Logger.get("RvcOperationalStateServer");
178678
+ var logger196 = Logger.get("RvcOperationalStateServer");
178543
178679
  var activeStates = /* @__PURE__ */ new Set([
178544
178680
  OperationalState4.Running,
178545
178681
  OperationalState4.SeekingCharger
@@ -178588,7 +178724,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
178588
178724
  { force: true }
178589
178725
  );
178590
178726
  if (activeStates.has(previousState) && !activeStates.has(newState)) {
178591
- logger195.info(
178727
+ logger196.info(
178592
178728
  `Operation completed: ${OperationalState4[previousState]} -> ${OperationalState4[newState]}`
178593
178729
  );
178594
178730
  try {
@@ -178601,7 +178737,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
178601
178737
  this.context
178602
178738
  );
178603
178739
  } catch (e) {
178604
- logger195.debug("Failed to emit operationCompletion event:", e);
178740
+ logger196.debug("Failed to emit operationCompletion event:", e);
178605
178741
  }
178606
178742
  }
178607
178743
  }
@@ -178636,7 +178772,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
178636
178772
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
178637
178773
  homeAssistant.callAction(goHomeAction(void 0, this.agent));
178638
178774
  } else {
178639
- logger195.warn("GoHome command received but no goHome action configured");
178775
+ logger196.warn("GoHome command received but no goHome action configured");
178640
178776
  }
178641
178777
  return {
178642
178778
  commandResponseState: {
@@ -178656,7 +178792,7 @@ function RvcOperationalStateServer2(config10) {
178656
178792
  }
178657
178793
 
178658
178794
  // src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-operational-state-server.ts
178659
- var logger196 = Logger.get("VacuumRvcOperationalStateServer");
178795
+ var logger197 = Logger.get("VacuumRvcOperationalStateServer");
178660
178796
  function isCharging(entity) {
178661
178797
  const attrs = entity.attributes;
178662
178798
  if (attrs.battery_icon?.includes("charging")) return true;
@@ -178698,16 +178834,16 @@ var VacuumRvcOperationalStateServer = RvcOperationalStateServer2({
178698
178834
  operationalState = RvcOperationalState3.OperationalState.Error;
178699
178835
  } else {
178700
178836
  if (state.toLowerCase().includes("clean")) {
178701
- logger196.info(
178837
+ logger197.info(
178702
178838
  `Unknown vacuum state "${state}" contains 'clean', treating as Running`
178703
178839
  );
178704
178840
  operationalState = RvcOperationalState3.OperationalState.Running;
178705
178841
  } else {
178706
- logger196.info(`Unknown vacuum state "${state}", treating as Stopped`);
178842
+ logger197.info(`Unknown vacuum state "${state}", treating as Stopped`);
178707
178843
  operationalState = RvcOperationalState3.OperationalState.Stopped;
178708
178844
  }
178709
178845
  }
178710
- logger196.debug(
178846
+ logger197.debug(
178711
178847
  `Vacuum operationalState: "${state}" -> ${RvcOperationalState3.OperationalState[operationalState]}`
178712
178848
  );
178713
178849
  return operationalState;
@@ -178728,7 +178864,7 @@ var VacuumRvcOperationalStateServer = RvcOperationalStateServer2({
178728
178864
  });
178729
178865
 
178730
178866
  // src/matter/endpoints/legacy/vacuum/index.ts
178731
- var logger197 = Logger.get("VacuumDevice");
178867
+ var logger198 = Logger.get("VacuumDevice");
178732
178868
  var VacuumEndpointType = RoboticVacuumCleanerDevice.with(
178733
178869
  BasicInformationServer2,
178734
178870
  VacuumIdentifyServer,
@@ -178742,7 +178878,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
178742
178878
  const entityId = homeAssistantEntity.entity.entity_id;
178743
178879
  const attributes7 = homeAssistantEntity.entity.state.attributes;
178744
178880
  const customAreas = homeAssistantEntity.mapping?.customServiceAreas;
178745
- logger197.info(
178881
+ logger198.info(
178746
178882
  `Creating vacuum endpoint for ${entityId}, mapping: ${JSON.stringify(homeAssistantEntity.mapping ?? "none")}`
178747
178883
  );
178748
178884
  const cleanAreaRooms = homeAssistantEntity.mapping?.cleanAreaRooms;
@@ -178754,32 +178890,32 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
178754
178890
  )
178755
178891
  ).set({ homeAssistantEntity });
178756
178892
  if (includeOnOff) {
178757
- logger197.info(`${entityId}: Adding OnOff cluster (vacuumOnOff flag enabled)`);
178893
+ logger198.info(`${entityId}: Adding OnOff cluster (vacuumOnOff flag enabled)`);
178758
178894
  device = device.with(VacuumOnOffServer);
178759
178895
  }
178760
178896
  device = device.with(VacuumPowerSourceServer);
178761
178897
  const roomEntities = homeAssistantEntity.mapping?.roomEntities;
178762
178898
  const rooms = parseVacuumRooms(attributes7);
178763
- logger197.info(
178899
+ logger198.info(
178764
178900
  `${entityId}: customAreas=${customAreas?.length ?? 0}, roomEntities=${JSON.stringify(roomEntities ?? [])}, parsedRooms=${rooms.length}, cleanAreaRooms=${cleanAreaRooms?.length ?? 0}`
178765
178901
  );
178766
178902
  if (cleanAreaRooms && cleanAreaRooms.length > 0) {
178767
- logger197.info(
178903
+ logger198.info(
178768
178904
  `${entityId}: Adding ServiceArea (${cleanAreaRooms.length} HA areas via CLEAN_AREA)`
178769
178905
  );
178770
178906
  device = device.with(createCleanAreaServiceAreaServer(cleanAreaRooms));
178771
178907
  } else if (customAreas && customAreas.length > 0) {
178772
- logger197.info(
178908
+ logger198.info(
178773
178909
  `${entityId}: Adding ServiceArea (${customAreas.length} custom areas)`
178774
178910
  );
178775
178911
  device = device.with(createCustomServiceAreaServer(customAreas));
178776
178912
  } else if (rooms.length > 0 || roomEntities && roomEntities.length > 0) {
178777
- logger197.info(`${entityId}: Adding ServiceArea (${rooms.length} rooms)`);
178913
+ logger198.info(`${entityId}: Adding ServiceArea (${rooms.length} rooms)`);
178778
178914
  device = device.with(
178779
178915
  createVacuumServiceAreaServer(attributes7, roomEntities)
178780
178916
  );
178781
178917
  } else {
178782
- logger197.info(`${entityId}: Adding ServiceArea (default single-area)`);
178918
+ logger198.info(`${entityId}: Adding ServiceArea (default single-area)`);
178783
178919
  device = device.with(createDefaultServiceAreaServer());
178784
178920
  }
178785
178921
  const fanSpeedList = resolveFanSpeedList(
@@ -178790,7 +178926,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
178790
178926
  homeAssistantEntity.mapping?.mopIntensityEntity
178791
178927
  );
178792
178928
  if (cleaningModeOptions || fanSpeedList || mopIntensityList) {
178793
- logger197.info(
178929
+ logger198.info(
178794
178930
  `${entityId}: Adding RvcCleanMode (multi-mode, cleaningModeOptions=${JSON.stringify(cleaningModeOptions ?? [])}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])})`
178795
178931
  );
178796
178932
  device = device.with(
@@ -178803,7 +178939,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
178803
178939
  )
178804
178940
  );
178805
178941
  } else {
178806
- logger197.info(`${entityId}: Adding RvcCleanMode (default single-mode)`);
178942
+ logger198.info(`${entityId}: Adding RvcCleanMode (default single-mode)`);
178807
178943
  device = device.with(createDefaultRvcCleanModeServer());
178808
178944
  }
178809
178945
  return device;
@@ -178969,7 +179105,7 @@ var WaterHeaterThermostatServer = ThermostatServer2(
178969
179105
  );
178970
179106
 
178971
179107
  // src/matter/endpoints/legacy/water-heater/index.ts
178972
- var logger198 = Logger.get("WaterHeaterDevice");
179108
+ var logger199 = Logger.get("WaterHeaterDevice");
178973
179109
  var WaterHeaterDeviceType = ThermostatDevice.with(
178974
179110
  BasicInformationServer2,
178975
179111
  IdentifyServer2,
@@ -178985,7 +179121,7 @@ function toMatterTemp2(value) {
178985
179121
  }
178986
179122
  function WaterHeaterDevice(homeAssistantEntity) {
178987
179123
  const attributes7 = homeAssistantEntity.entity.state.attributes;
178988
- logger198.debug(
179124
+ logger199.debug(
178989
179125
  `Creating device for ${homeAssistantEntity.entity.entity_id}, min_temp=${attributes7.min_temp}, max_temp=${attributes7.max_temp}`
178990
179126
  );
178991
179127
  const minLimit = toMatterTemp2(attributes7.min_temp) ?? 0;
@@ -179146,7 +179282,7 @@ var matterDeviceTypeFactories = {
179146
179282
  };
179147
179283
 
179148
179284
  // src/matter/endpoints/composed/user-composed-endpoint.ts
179149
- var logger199 = Logger.get("UserComposedEndpoint");
179285
+ var logger200 = Logger.get("UserComposedEndpoint");
179150
179286
  function stripBasicInformation(type) {
179151
179287
  const behaviors = { ...type.behaviors };
179152
179288
  delete behaviors.bridgedDeviceBasicInformation;
@@ -179202,7 +179338,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
179202
179338
  { vacuumOnOff: registry2.isVacuumOnOffEnabled() }
179203
179339
  );
179204
179340
  if (!primaryType) {
179205
- logger199.warn(
179341
+ logger200.warn(
179206
179342
  `Cannot create endpoint type for primary entity ${primaryEntityId}`
179207
179343
  );
179208
179344
  return void 0;
@@ -179217,7 +179353,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
179217
179353
  if (!sub.entityId) continue;
179218
179354
  const subPayload = buildEntityPayload3(registry2, sub.entityId);
179219
179355
  if (!subPayload) {
179220
- logger199.warn(
179356
+ logger200.warn(
179221
179357
  `Cannot find entity state for composed sub-entity ${sub.entityId}`
179222
179358
  );
179223
179359
  continue;
@@ -179228,7 +179364,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
179228
179364
  };
179229
179365
  const subType = createLegacyEndpointType(subPayload, subMapping);
179230
179366
  if (!subType) {
179231
- logger199.warn(
179367
+ logger200.warn(
179232
179368
  `Cannot create endpoint type for composed sub-entity ${sub.entityId}`
179233
179369
  );
179234
179370
  continue;
@@ -179241,7 +179377,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
179241
179377
  mappedIds.push(sub.entityId);
179242
179378
  }
179243
179379
  if (parts.length < 2) {
179244
- logger199.warn(
179380
+ logger200.warn(
179245
179381
  `User composed device ${primaryEntityId}: only ${parts.length} sub-endpoint(s), need at least 2 (primary + one sub-entity). Falling back to standalone.`
179246
179382
  );
179247
179383
  return void 0;
@@ -179264,7 +179400,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
179264
179400
  const labels = parts.map(
179265
179401
  (_, i) => i === 0 ? primaryEntityId.split(".")[0] : composedEntities[i - 1]?.entityId?.split(".")[0] ?? "?"
179266
179402
  ).join("+");
179267
- logger199.info(
179403
+ logger200.info(
179268
179404
  `Created user composed device ${primaryEntityId}: ${parts.length} sub-endpoint(s) [${labels}]`
179269
179405
  );
179270
179406
  return endpoint;
@@ -179333,7 +179469,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
179333
179469
  };
179334
179470
 
179335
179471
  // src/matter/endpoints/legacy/legacy-endpoint.ts
179336
- var logger200 = Logger.get("LegacyEndpoint");
179472
+ var logger201 = Logger.get("LegacyEndpoint");
179337
179473
  var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179338
179474
  static async create(registry2, entityId, mapping, pluginDomainMappings) {
179339
179475
  const deviceRegistry = registry2.deviceOf(entityId);
@@ -179343,25 +179479,25 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179343
179479
  return;
179344
179480
  }
179345
179481
  if (registry2.isAutoBatteryMappingEnabled() && registry2.isBatteryEntityUsed(entityId)) {
179346
- logger200.debug(
179482
+ logger201.debug(
179347
179483
  `Skipping ${entityId} - already auto-assigned as battery to another device`
179348
179484
  );
179349
179485
  return;
179350
179486
  }
179351
179487
  if (registry2.isAutoHumidityMappingEnabled() && registry2.isHumidityEntityUsed(entityId)) {
179352
- logger200.debug(
179488
+ logger201.debug(
179353
179489
  `Skipping ${entityId} - already auto-assigned as humidity to a temperature sensor`
179354
179490
  );
179355
179491
  return;
179356
179492
  }
179357
179493
  if (registry2.isAutoPressureMappingEnabled() && registry2.isPressureEntityUsed(entityId)) {
179358
- logger200.debug(
179494
+ logger201.debug(
179359
179495
  `Skipping ${entityId} - already auto-assigned as pressure to a temperature sensor`
179360
179496
  );
179361
179497
  return;
179362
179498
  }
179363
179499
  if (registry2.isAutoComposedDevicesEnabled() && registry2.isComposedSubEntityUsed(entityId)) {
179364
- logger200.debug(
179500
+ logger201.debug(
179365
179501
  `Skipping ${entityId} - already consumed by a composed device`
179366
179502
  );
179367
179503
  return;
@@ -179381,7 +179517,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179381
179517
  humidityEntity: humidityEntityId
179382
179518
  };
179383
179519
  registry2.markHumidityEntityUsed(humidityEntityId);
179384
- logger200.debug(
179520
+ logger201.debug(
179385
179521
  `Auto-assigned humidity ${humidityEntityId} to ${entityId}`
179386
179522
  );
179387
179523
  }
@@ -179400,7 +179536,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179400
179536
  pressureEntity: pressureEntityId
179401
179537
  };
179402
179538
  registry2.markPressureEntityUsed(pressureEntityId);
179403
- logger200.debug(
179539
+ logger201.debug(
179404
179540
  `Auto-assigned pressure ${pressureEntityId} to ${entityId}`
179405
179541
  );
179406
179542
  }
@@ -179418,7 +179554,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179418
179554
  batteryEntity: batteryEntityId
179419
179555
  };
179420
179556
  registry2.markBatteryEntityUsed(batteryEntityId);
179421
- logger200.debug(
179557
+ logger201.debug(
179422
179558
  `Auto-assigned battery ${batteryEntityId} to ${entityId}`
179423
179559
  );
179424
179560
  }
@@ -179436,7 +179572,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179436
179572
  powerEntity: powerEntityId
179437
179573
  };
179438
179574
  registry2.markPowerEntityUsed(powerEntityId);
179439
- logger200.debug(`Auto-assigned power ${powerEntityId} to ${entityId}`);
179575
+ logger201.debug(`Auto-assigned power ${powerEntityId} to ${entityId}`);
179440
179576
  }
179441
179577
  }
179442
179578
  }
@@ -179453,7 +179589,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179453
179589
  energyEntity: energyEntityId
179454
179590
  };
179455
179591
  registry2.markEnergyEntityUsed(energyEntityId);
179456
- logger200.debug(
179592
+ logger201.debug(
179457
179593
  `Auto-assigned energy ${energyEntityId} to ${entityId}`
179458
179594
  );
179459
179595
  }
@@ -179469,7 +179605,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179469
179605
  entityId: effectiveMapping?.entityId ?? entityId,
179470
179606
  cleaningModeEntity: vacuumEntities.cleaningModeEntity
179471
179607
  };
179472
- logger200.info(
179608
+ logger201.info(
179473
179609
  `Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity} to ${entityId}`
179474
179610
  );
179475
179611
  }
@@ -179479,7 +179615,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179479
179615
  entityId: effectiveMapping?.entityId ?? entityId,
179480
179616
  suctionLevelEntity: vacuumEntities.suctionLevelEntity
179481
179617
  };
179482
- logger200.info(
179618
+ logger201.info(
179483
179619
  `Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity} to ${entityId}`
179484
179620
  );
179485
179621
  }
@@ -179489,7 +179625,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179489
179625
  entityId: effectiveMapping?.entityId ?? entityId,
179490
179626
  mopIntensityEntity: vacuumEntities.mopIntensityEntity
179491
179627
  };
179492
- logger200.info(
179628
+ logger201.info(
179493
179629
  `Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity} to ${entityId}`
179494
179630
  );
179495
179631
  }
@@ -179499,7 +179635,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179499
179635
  entityId: effectiveMapping?.entityId ?? entityId,
179500
179636
  currentRoomEntity: vacuumEntities.currentRoomEntity
179501
179637
  };
179502
- logger200.info(
179638
+ logger201.info(
179503
179639
  `Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity} to ${entityId}`
179504
179640
  );
179505
179641
  }
@@ -179514,7 +179650,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179514
179650
  entityId: effectiveMapping?.entityId ?? entityId,
179515
179651
  cleanAreaRooms
179516
179652
  };
179517
- logger200.info(
179653
+ logger201.info(
179518
179654
  `Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA for ${entityId}`
179519
179655
  );
179520
179656
  }
@@ -179535,7 +179671,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179535
179671
  rooms: roomsObj
179536
179672
  }
179537
179673
  };
179538
- logger200.debug(
179674
+ logger201.debug(
179539
179675
  `Auto-detected ${valetudoRooms.length} Valetudo segments for ${entityId}`
179540
179676
  );
179541
179677
  } else {
@@ -179552,7 +179688,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179552
179688
  rooms: roomsObj
179553
179689
  }
179554
179690
  };
179555
- logger200.debug(
179691
+ logger201.debug(
179556
179692
  `Auto-detected ${roborockRooms.length} Roborock rooms for ${entityId}`
179557
179693
  );
179558
179694
  }
@@ -179573,7 +179709,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179573
179709
  if (composed) {
179574
179710
  return composed;
179575
179711
  }
179576
- logger200.warn(
179712
+ logger201.warn(
179577
179713
  `User composed device creation failed for ${entityId}, falling back to standalone`
179578
179714
  );
179579
179715
  }
@@ -179669,16 +179805,16 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179669
179805
  async updateStates(states) {
179670
179806
  const state = states[this.entityId] ?? {};
179671
179807
  const mappedChanged = this.hasMappedEntityChanged(states);
179672
- if (!mappedChanged && state.state === this.lastState?.state && JSON.stringify(state.attributes) === JSON.stringify(this.lastState?.attributes)) {
179808
+ if (!mappedChanged && state.state === this.lastState?.state && isEqual(state.attributes, this.lastState?.attributes)) {
179673
179809
  return;
179674
179810
  }
179675
179811
  if (mappedChanged) {
179676
179812
  this.pendingMappedChange = true;
179677
- logger200.debug(
179813
+ logger201.debug(
179678
179814
  `Mapped entity change detected for ${this.entityId}, forcing update`
179679
179815
  );
179680
179816
  }
179681
- logger200.debug(
179817
+ logger201.debug(
179682
179818
  `State update received for ${this.entityId}: state=${state.state}`
179683
179819
  );
179684
179820
  this.lastState = state;
@@ -179731,7 +179867,7 @@ import {
179731
179867
  getCollection
179732
179868
  } from "home-assistant-js-websocket";
179733
179869
  import { atLeastHaVersion } from "home-assistant-js-websocket/dist/util.js";
179734
- var logger201 = Logger.get("SubscribeEntities");
179870
+ var logger202 = Logger.get("SubscribeEntities");
179735
179871
  function processEvent(store, updates) {
179736
179872
  const state = { ...store.state };
179737
179873
  if (updates.a) {
@@ -179757,7 +179893,7 @@ function processEvent(store, updates) {
179757
179893
  for (const entityId in updates.c) {
179758
179894
  let entityState = state[entityId];
179759
179895
  if (!entityState) {
179760
- logger201.warn("Received state update for unknown entity", entityId);
179896
+ logger202.warn("Received state update for unknown entity", entityId);
179761
179897
  continue;
179762
179898
  }
179763
179899
  entityState = { ...entityState };
@@ -179828,7 +179964,7 @@ var subscribeEntities = (conn, onChange, entityIds) => entitiesColl(conn, entity
179828
179964
  // src/services/bridges/entity-isolation-service.ts
179829
179965
  init_esm();
179830
179966
  init_diagnostic_event_bus();
179831
- var logger202 = Logger.get("EntityIsolation");
179967
+ var logger203 = Logger.get("EntityIsolation");
179832
179968
  var EntityIsolationServiceImpl = class {
179833
179969
  isolatedEntities = /* @__PURE__ */ new Map();
179834
179970
  isolationCallbacks = /* @__PURE__ */ new Map();
@@ -179893,13 +180029,13 @@ var EntityIsolationServiceImpl = class {
179893
180029
  }
179894
180030
  const parsed = this.parseEndpointPath(msg);
179895
180031
  if (!parsed) {
179896
- logger202.warn("Could not parse entity from error:", msg);
180032
+ logger203.warn("Could not parse entity from error:", msg);
179897
180033
  return false;
179898
180034
  }
179899
180035
  const { bridgeId, entityName } = parsed;
179900
180036
  const callback = this.isolationCallbacks.get(bridgeId);
179901
180037
  if (!callback) {
179902
- logger202.warn(
180038
+ logger203.warn(
179903
180039
  `No isolation callback registered for bridge ${bridgeId}, entity: ${entityName}`
179904
180040
  );
179905
180041
  return false;
@@ -179910,7 +180046,7 @@ var EntityIsolationServiceImpl = class {
179910
180046
  }
179911
180047
  const reason = `${classification}. Entity isolated to protect bridge stability.`;
179912
180048
  this.isolatedEntities.set(key, { entityId: entityName, reason });
179913
- logger202.warn(
180049
+ logger203.warn(
179914
180050
  `Isolating entity "${entityName}" from bridge ${bridgeId} due to: ${reason}`
179915
180051
  );
179916
180052
  diagnosticEventBus.emit("entity_error", `Entity isolated: ${entityName}`, {
@@ -179922,7 +180058,7 @@ var EntityIsolationServiceImpl = class {
179922
180058
  await callback(entityName);
179923
180059
  return true;
179924
180060
  } catch (e) {
179925
- logger202.error(`Failed to isolate entity ${entityName}:`, e);
180061
+ logger203.error(`Failed to isolate entity ${entityName}:`, e);
179926
180062
  return false;
179927
180063
  }
179928
180064
  }
@@ -179988,6 +180124,7 @@ var BridgeEndpointManager = class extends Service {
179988
180124
  mappingFingerprints = /* @__PURE__ */ new Map();
179989
180125
  pluginEndpoints = /* @__PURE__ */ new Map();
179990
180126
  pluginStateUpdating = /* @__PURE__ */ new Set();
180127
+ pluginListeners = /* @__PURE__ */ new Map();
179991
180128
  get failedEntities() {
179992
180129
  const isolated = EntityIsolationService.getIsolatedEntities(this.bridgeId);
179993
180130
  return [...this._failedEntities, ...isolated];
@@ -180027,6 +180164,16 @@ var BridgeEndpointManager = class extends Service {
180027
180164
  }
180028
180165
  };
180029
180166
  this.pluginManager.onDeviceUnregistered = async (pluginName, deviceId) => {
180167
+ const listeners = this.pluginListeners.get(deviceId);
180168
+ if (listeners) {
180169
+ for (const { observable, listener } of listeners) {
180170
+ try {
180171
+ observable.off(listener);
180172
+ } catch {
180173
+ }
180174
+ }
180175
+ this.pluginListeners.delete(deviceId);
180176
+ }
180030
180177
  const endpoint = this.pluginEndpoints.get(deviceId);
180031
180178
  if (endpoint) {
180032
180179
  try {
@@ -180064,6 +180211,7 @@ var BridgeEndpointManager = class extends Service {
180064
180211
  wirePluginEndpointEvents(device, endpoint) {
180065
180212
  if (!device.onAttributeWrite) return;
180066
180213
  const allEvents = endpoint.events;
180214
+ const listeners = [];
180067
180215
  for (const behaviorId of Object.keys(endpoint.type.behaviors)) {
180068
180216
  if (behaviorId === "pluginDevice") continue;
180069
180217
  const behaviorEvents = allEvents[behaviorId];
@@ -180073,7 +180221,7 @@ var BridgeEndpointManager = class extends Service {
180073
180221
  const observable = behaviorEvents[eventName];
180074
180222
  if (!observable || typeof observable.on !== "function") continue;
180075
180223
  const attrName = eventName.slice(0, -"$Changed".length);
180076
- observable.on((newValue) => {
180224
+ const listener = (newValue) => {
180077
180225
  if (this.pluginStateUpdating.has(device.id)) return;
180078
180226
  device.onAttributeWrite?.(behaviorId, attrName, newValue).catch((e) => {
180079
180227
  this.log.debug(
@@ -180081,9 +180229,14 @@ var BridgeEndpointManager = class extends Service {
180081
180229
  e
180082
180230
  );
180083
180231
  });
180084
- });
180232
+ };
180233
+ observable.on(listener);
180234
+ listeners.push({ observable, listener });
180085
180235
  }
180086
180236
  }
180237
+ if (listeners.length > 0) {
180238
+ this.pluginListeners.set(device.id, listeners);
180239
+ }
180087
180240
  }
180088
180241
  async startPlugins() {
180089
180242
  if (!this.pluginManager) return;
@@ -180376,7 +180529,24 @@ var BridgeEndpointManager = class extends Service {
180376
180529
  this.startObserving();
180377
180530
  }
180378
180531
  }
180532
+ updateInFlight;
180533
+ pendingStates;
180379
180534
  async updateStates(states) {
180535
+ if (this.updateInFlight) {
180536
+ this.pendingStates = states;
180537
+ return this.updateInFlight;
180538
+ }
180539
+ this.updateInFlight = this.runUpdateStates(states).finally(() => {
180540
+ this.updateInFlight = void 0;
180541
+ const queued = this.pendingStates;
180542
+ this.pendingStates = void 0;
180543
+ if (queued) {
180544
+ void this.updateStates(queued);
180545
+ }
180546
+ });
180547
+ return this.updateInFlight;
180548
+ }
180549
+ async runUpdateStates(states) {
180380
180550
  const startMs = performance.now();
180381
180551
  this.registry.mergeExternalStates(states);
180382
180552
  const endpoints = this.root.parts.map((p) => p);
@@ -181141,11 +181311,11 @@ init_diagnostic_event_bus();
181141
181311
  var AUTO_FORCE_SYNC_INTERVAL_MS2 = 9e4;
181142
181312
  var DEAD_SESSION_TIMEOUT_MS2 = 6e4;
181143
181313
  var ServerModeBridge = class {
181144
- constructor(logger205, dataProvider, endpointManager, server) {
181314
+ constructor(logger206, dataProvider, endpointManager, server) {
181145
181315
  this.dataProvider = dataProvider;
181146
181316
  this.endpointManager = endpointManager;
181147
181317
  this.server = server;
181148
- this.log = logger205.get(`ServerModeBridge / ${dataProvider.id}`);
181318
+ this.log = logger206.get(`ServerModeBridge / ${dataProvider.id}`);
181149
181319
  }
181150
181320
  dataProvider;
181151
181321
  endpointManager;
@@ -181667,7 +181837,7 @@ function ServerModeVacuumDevice(homeAssistantEntity, includeOnOff = false, clean
181667
181837
  }
181668
181838
 
181669
181839
  // src/matter/endpoints/server-mode-vacuum-endpoint.ts
181670
- var logger203 = Logger.get("ServerModeVacuumEndpoint");
181840
+ var logger204 = Logger.get("ServerModeVacuumEndpoint");
181671
181841
  var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEndpoint {
181672
181842
  static async create(registry2, entityId, mapping) {
181673
181843
  const deviceRegistry = registry2.deviceOf(entityId);
@@ -181677,7 +181847,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181677
181847
  return void 0;
181678
181848
  }
181679
181849
  let effectiveMapping = mapping;
181680
- logger203.info(
181850
+ logger204.info(
181681
181851
  `${entityId}: device_id=${entity.device_id}, manualBattery=${mapping?.batteryEntity ?? "none"}`
181682
181852
  );
181683
181853
  if (entity.device_id) {
@@ -181692,15 +181862,15 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181692
181862
  batteryEntity: batteryEntityId
181693
181863
  };
181694
181864
  registry2.markBatteryEntityUsed(batteryEntityId);
181695
- logger203.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
181865
+ logger204.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
181696
181866
  } else {
181697
181867
  const attrs = state.attributes;
181698
181868
  if (attrs.battery_level != null || attrs.battery != null) {
181699
- logger203.info(
181869
+ logger204.info(
181700
181870
  `${entityId}: No battery entity found, using battery attribute from vacuum state`
181701
181871
  );
181702
181872
  } else {
181703
- logger203.warn(
181873
+ logger204.warn(
181704
181874
  `${entityId}: No battery entity found for device ${entity.device_id}`
181705
181875
  );
181706
181876
  }
@@ -181715,7 +181885,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181715
181885
  entityId: effectiveMapping?.entityId ?? entityId,
181716
181886
  cleaningModeEntity: vacuumEntities.cleaningModeEntity
181717
181887
  };
181718
- logger203.info(
181888
+ logger204.info(
181719
181889
  `${entityId}: Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity}`
181720
181890
  );
181721
181891
  }
@@ -181725,7 +181895,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181725
181895
  entityId: effectiveMapping?.entityId ?? entityId,
181726
181896
  suctionLevelEntity: vacuumEntities.suctionLevelEntity
181727
181897
  };
181728
- logger203.info(
181898
+ logger204.info(
181729
181899
  `${entityId}: Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity}`
181730
181900
  );
181731
181901
  }
@@ -181735,7 +181905,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181735
181905
  entityId: effectiveMapping?.entityId ?? entityId,
181736
181906
  mopIntensityEntity: vacuumEntities.mopIntensityEntity
181737
181907
  };
181738
- logger203.info(
181908
+ logger204.info(
181739
181909
  `${entityId}: Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity}`
181740
181910
  );
181741
181911
  }
@@ -181745,7 +181915,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181745
181915
  entityId: effectiveMapping?.entityId ?? entityId,
181746
181916
  currentRoomEntity: vacuumEntities.currentRoomEntity
181747
181917
  };
181748
- logger203.info(
181918
+ logger204.info(
181749
181919
  `${entityId}: Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity}`
181750
181920
  );
181751
181921
  }
@@ -181760,7 +181930,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181760
181930
  entityId: effectiveMapping?.entityId ?? entityId,
181761
181931
  cleanAreaRooms
181762
181932
  };
181763
- logger203.info(
181933
+ logger204.info(
181764
181934
  `${entityId}: Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA`
181765
181935
  );
181766
181936
  }
@@ -181781,7 +181951,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181781
181951
  rooms: roomsObj
181782
181952
  }
181783
181953
  };
181784
- logger203.info(
181954
+ logger204.info(
181785
181955
  `${entityId}: Auto-detected ${valetudoRooms.length} Valetudo segments`
181786
181956
  );
181787
181957
  } else {
@@ -181798,14 +181968,14 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181798
181968
  rooms: roomsObj
181799
181969
  }
181800
181970
  };
181801
- logger203.info(
181971
+ logger204.info(
181802
181972
  `${entityId}: Auto-detected ${roborockRooms.length} Roborock rooms`
181803
181973
  );
181804
181974
  }
181805
181975
  }
181806
181976
  }
181807
181977
  } else {
181808
- logger203.warn(`${entityId}: No device_id \u2014 cannot auto-assign battery`);
181978
+ logger204.warn(`${entityId}: No device_id \u2014 cannot auto-assign battery`);
181809
181979
  }
181810
181980
  const payload = {
181811
181981
  entity_id: entityId,
@@ -181902,7 +182072,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181902
182072
  try {
181903
182073
  this.keepaliveCounter++;
181904
182074
  const counter = this.keepaliveCounter;
181905
- logger203.info(`Keepalive #${counter} for ${this.entityId}`);
182075
+ logger204.info(`Keepalive #${counter} for ${this.entityId}`);
181906
182076
  const opState = this.stateOf(RvcOperationalStateServer);
181907
182077
  await this.setStateOf(RvcOperationalStateServer, {
181908
182078
  operationalState: opState.operationalState,
@@ -181917,7 +182087,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181917
182087
  currentMode: runMode.currentMode
181918
182088
  });
181919
182089
  }
181920
- logger203.info(`Keepalive #${counter} committed for ${this.entityId}`);
182090
+ logger204.info(`Keepalive #${counter} committed for ${this.entityId}`);
181921
182091
  } catch (e) {
181922
182092
  if (e instanceof TransactionDestroyedError || e instanceof DestroyedDependencyError) {
181923
182093
  return;
@@ -181926,7 +182096,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181926
182096
  if (msg.includes("Endpoint storage inaccessible")) {
181927
182097
  return;
181928
182098
  }
181929
- logger203.warn(`Keepalive failed for ${this.entityId}: ${msg}`);
182099
+ logger204.warn(`Keepalive failed for ${this.entityId}: ${msg}`);
181930
182100
  }
181931
182101
  }
181932
182102
  async updateStates(states) {
@@ -181937,11 +182107,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
181937
182107
  }
181938
182108
  if (mappedChanged) {
181939
182109
  this.pendingMappedChange = true;
181940
- logger203.debug(
182110
+ logger204.debug(
181941
182111
  `Mapped entity change detected for ${this.entityId}, forcing update`
181942
182112
  );
181943
182113
  }
181944
- logger203.debug(
182114
+ logger204.debug(
181945
182115
  `State update received for ${this.entityId}: state=${state.state}`
181946
182116
  );
181947
182117
  this.lastState = state;
@@ -182377,10 +182547,10 @@ var BridgeEnvironmentFactory = class extends BridgeFactory {
182377
182547
  // src/core/ioc/app-environment.ts
182378
182548
  var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
182379
182549
  constructor(rootEnv, options) {
182380
- const logger205 = rootEnv.get(LoggerService);
182550
+ const logger206 = rootEnv.get(LoggerService);
182381
182551
  super({
182382
182552
  id: "App",
182383
- log: logger205.get("AppContainer"),
182553
+ log: logger206.get("AppContainer"),
182384
182554
  parent: rootEnv
182385
182555
  });
182386
182556
  this.options = options;
@@ -182394,8 +182564,8 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
182394
182564
  }
182395
182565
  construction;
182396
182566
  async init() {
182397
- const logger205 = this.get(LoggerService);
182398
- this.set(LoggerService, logger205);
182567
+ const logger206 = this.get(LoggerService);
182568
+ this.set(LoggerService, logger206);
182399
182569
  this.set(AppStorage, new AppStorage(await this.load(StorageService)));
182400
182570
  this.set(BridgeStorage, new BridgeStorage(await this.load(AppStorage)));
182401
182571
  this.set(
@@ -182412,7 +182582,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
182412
182582
  );
182413
182583
  this.set(
182414
182584
  HomeAssistantClient,
182415
- new HomeAssistantClient(logger205, this.options.homeAssistant)
182585
+ new HomeAssistantClient(logger206, this.options.homeAssistant)
182416
182586
  );
182417
182587
  this.set(
182418
182588
  HomeAssistantConfig,
@@ -182420,7 +182590,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
182420
182590
  );
182421
182591
  this.set(
182422
182592
  HomeAssistantActions,
182423
- new HomeAssistantActions(logger205, await this.load(HomeAssistantClient))
182593
+ new HomeAssistantActions(logger206, await this.load(HomeAssistantClient))
182424
182594
  );
182425
182595
  this.set(
182426
182596
  HomeAssistantRegistry,
@@ -182456,7 +182626,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
182456
182626
  this.set(
182457
182627
  WebApi,
182458
182628
  new WebApi(
182459
- logger205,
182629
+ logger206,
182460
182630
  await this.load(BridgeService),
182461
182631
  await this.load(HomeAssistantClient),
182462
182632
  await this.load(HomeAssistantRegistry),
@@ -182482,7 +182652,7 @@ init_nodejs();
182482
182652
  init_level_control();
182483
182653
 
182484
182654
  // src/matter/patches/patch-level-control-tlv.ts
182485
- var logger204 = Logger.get("PatchLevelControlTlv");
182655
+ var logger205 = Logger.get("PatchLevelControlTlv");
182486
182656
  function patchLevelControlTlv() {
182487
182657
  let patched = 0;
182488
182658
  const moveToLevelFields = LevelControl3.TlvMoveToLevelRequest.fieldDefinitions;
@@ -182496,11 +182666,11 @@ function patchLevelControlTlv() {
182496
182666
  patched++;
182497
182667
  }
182498
182668
  if (patched > 0) {
182499
- logger204.info(
182669
+ logger205.info(
182500
182670
  `Patched ${patched} LevelControl TLV schema(s): transitionTime is now optional (Google Home compatibility)`
182501
182671
  );
182502
182672
  } else {
182503
- logger204.warn(
182673
+ logger205.warn(
182504
182674
  "Failed to patch LevelControl TLV schemas \u2014 field definitions not found. Google Home brightness adjustment may not work."
182505
182675
  );
182506
182676
  }
@@ -182602,8 +182772,8 @@ async function startHandler(startOptions, webUiDist) {
182602
182772
  }
182603
182773
  try {
182604
182774
  await Promise.race([
182605
- bridgeService.dispose(),
182606
- new Promise((resolve6) => setTimeout(resolve6, 1e4))
182775
+ appEnvironment.dispose(),
182776
+ new Promise((resolve6) => setTimeout(resolve6, 15e3))
182607
182777
  ]);
182608
182778
  } catch (e) {
182609
182779
  console.warn("Error during graceful shutdown:", e);