@riddix/hamh 2.1.0-alpha.840 → 2.1.0-alpha.842

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.
@@ -1767,8 +1767,8 @@ var init_Cancelable = __esm({
1767
1767
  };
1768
1768
  return result;
1769
1769
  }
1770
- static set logger(logger250) {
1771
- this.#logger = logger250;
1770
+ static set logger(logger251) {
1771
+ this.#logger = logger251;
1772
1772
  }
1773
1773
  static get logger() {
1774
1774
  return this.#logger;
@@ -3475,13 +3475,13 @@ var init_Logger = __esm({
3475
3475
  *
3476
3476
  * @deprecated use {@link destinations}
3477
3477
  */
3478
- static addLogger(identifier, logger250, options) {
3478
+ static addLogger(identifier, logger251, options) {
3479
3479
  if (identifier in this.destinations) {
3480
3480
  throw new ImplementationError(`Logger "${identifier}" already exists`);
3481
3481
  }
3482
3482
  const dest = LogDestination({ name: identifier });
3483
3483
  const legacy = adaptDestinationToLegacy(dest);
3484
- legacy.log = logger250;
3484
+ legacy.log = logger251;
3485
3485
  if (options?.defaultLogLevel !== void 0) {
3486
3486
  legacy.defaultLogLevel = options.defaultLogLevel;
3487
3487
  }
@@ -5687,8 +5687,8 @@ var init_Construction = __esm({
5687
5687
  }
5688
5688
  }
5689
5689
  #unhandledError(...args) {
5690
- const logger250 = Logger.get(this.#subject.constructor.name);
5691
- logger250.error(...args);
5690
+ const logger251 = Logger.get(this.#subject.constructor.name);
5691
+ logger251.error(...args);
5692
5692
  }
5693
5693
  #createErrorHandler(name) {
5694
5694
  return (e) => {
@@ -11712,18 +11712,18 @@ var init_FileHandleTracker = __esm({
11712
11712
  logger12 = Logger.get("FileHandleTracker");
11713
11713
  ((FileHandleTracker2) => {
11714
11714
  const openHandles = /* @__PURE__ */ new Set();
11715
- const registry2 = new FinalizationRegistry((info) => {
11715
+ const registry3 = new FinalizationRegistry((info) => {
11716
11716
  logger12.warn(`File handle GC'd without close: "${info.purpose}" for ${info.path}`);
11717
11717
  });
11718
11718
  function register(handle) {
11719
11719
  const info = { purpose: handle.purpose, path: handle.path };
11720
- registry2.register(handle, info, handle);
11720
+ registry3.register(handle, info, handle);
11721
11721
  const ref = new WeakRef(handle);
11722
11722
  openHandles.add(ref);
11723
11723
  }
11724
11724
  FileHandleTracker2.register = register;
11725
11725
  function unregister(handle) {
11726
- registry2.unregister(handle);
11726
+ registry3.unregister(handle);
11727
11727
  for (const ref of openHandles) {
11728
11728
  if (ref.deref() === handle) {
11729
11729
  openHandles.delete(ref);
@@ -64070,8 +64070,8 @@ var init_NodeSession = __esm({
64070
64070
  return session?.type === SessionType.Unicast;
64071
64071
  }
64072
64072
  NodeSession2.is = is;
64073
- function logNew(logger250, operation, session, messenger, fabric, peerNodeId) {
64074
- logger250.info(
64073
+ function logNew(logger251, operation, session, messenger, fabric, peerNodeId) {
64074
+ logger251.info(
64075
64075
  session.via,
64076
64076
  `${operation} session with`,
64077
64077
  Diagnostic.strong(PeerAddress({ fabricIndex: fabric.fabricIndex, nodeId: peerNodeId }).toString()),
@@ -117714,11 +117714,11 @@ var init_Api = __esm({
117714
117714
  }
117715
117715
  Api2.resourceFor = resourceFor;
117716
117716
  function log(level, facility, id, ...message) {
117717
- let logger250 = loggers.get(facility);
117718
- if (!logger250) {
117719
- loggers.set(facility, logger250 = Logger.get(facility));
117717
+ let logger251 = loggers.get(facility);
117718
+ if (!logger251) {
117719
+ loggers.set(facility, logger251 = Logger.get(facility));
117720
117720
  }
117721
- logger250[level](Diagnostic.via(id || "(anon)"), message);
117721
+ logger251[level](Diagnostic.via(id || "(anon)"), message);
117722
117722
  }
117723
117723
  Api2.log = log;
117724
117724
  function logRequest(facility, id, method, target) {
@@ -132631,10 +132631,10 @@ var init_home_assistant_actions = __esm({
132631
132631
  circuitBreakerResetMs: 3e4
132632
132632
  };
132633
132633
  HomeAssistantActions = class extends Service {
132634
- constructor(logger250, client, config11) {
132634
+ constructor(logger251, client, config11) {
132635
132635
  super("HomeAssistantActions");
132636
132636
  this.client = client;
132637
- this.log = logger250.get(this);
132637
+ this.log = logger251.get(this);
132638
132638
  this.config = { ...defaultConfig, ...config11 };
132639
132639
  this.circuitBreaker = new CircuitBreaker(
132640
132640
  this.config.circuitBreakerThreshold,
@@ -132980,10 +132980,10 @@ var DiagnosticService = class {
132980
132980
  };
132981
132981
 
132982
132982
  // src/api/access-log.ts
132983
- function accessLogger(logger250) {
132983
+ function accessLogger(logger251) {
132984
132984
  return (req, res, next) => {
132985
132985
  res.on("finish", () => {
132986
- logger250.debug(
132986
+ logger251.debug(
132987
132987
  `${req.method} ${decodeURI(req.originalUrl)} ${res.statusCode} ${res.statusMessage} from ${req.socket.remoteAddress}`
132988
132988
  );
132989
132989
  });
@@ -136617,7 +136617,7 @@ var BLOCKED_PREFIXES = [
136617
136617
  function pluginApi(bridgeService, storageLocation) {
136618
136618
  const router = express14.Router();
136619
136619
  const installer = new PluginInstaller(storageLocation);
136620
- const registry2 = new PluginRegistry(storageLocation);
136620
+ const registry3 = new PluginRegistry(storageLocation);
136621
136621
  router.get("/", (_req, res) => {
136622
136622
  const result = [];
136623
136623
  for (const bridge of bridgeService.bridges) {
@@ -136702,7 +136702,7 @@ function pluginApi(bridgeService, storageLocation) {
136702
136702
  res.json({ success: true, pluginName, reset: true });
136703
136703
  });
136704
136704
  router.get("/installed", (_req, res) => {
136705
- const registered = registry2.getAll();
136705
+ const registered = registry3.getAll();
136706
136706
  const npmInstalled = installer.listInstalled();
136707
136707
  const result = registered.map((entry) => {
136708
136708
  const npm = npmInstalled.find((p) => p.name === entry.packageName);
@@ -136732,7 +136732,7 @@ function pluginApi(bridgeService, storageLocation) {
136732
136732
  });
136733
136733
  return;
136734
136734
  }
136735
- registry2.add(packageName, config11 ?? {});
136735
+ registry3.add(packageName, config11 ?? {});
136736
136736
  res.json({
136737
136737
  success: true,
136738
136738
  packageName,
@@ -136760,7 +136760,7 @@ function pluginApi(bridgeService, storageLocation) {
136760
136760
  });
136761
136761
  return;
136762
136762
  }
136763
- registry2.remove(packageName);
136763
+ registry3.remove(packageName);
136764
136764
  res.json({
136765
136765
  success: true,
136766
136766
  packageName,
@@ -136800,7 +136800,7 @@ function pluginApi(bridgeService, storageLocation) {
136800
136800
  });
136801
136801
  return;
136802
136802
  }
136803
- registry2.add(result.packageName, {});
136803
+ registry3.add(result.packageName, {});
136804
136804
  res.json({
136805
136805
  success: true,
136806
136806
  packageName: result.packageName,
@@ -136833,7 +136833,7 @@ function pluginApi(bridgeService, storageLocation) {
136833
136833
  });
136834
136834
  return;
136835
136835
  }
136836
- registry2.add(result.packageName, {});
136836
+ registry3.add(result.packageName, {});
136837
136837
  res.json({
136838
136838
  success: true,
136839
136839
  packageName: result.packageName,
@@ -137530,7 +137530,7 @@ var WebSocketApi = class {
137530
137530
 
137531
137531
  // src/api/web-api.ts
137532
137532
  var WebApi = class extends Service {
137533
- constructor(logger250, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, identityStorage, lockCredentialStorage, settingsStorage, backupService, props) {
137533
+ constructor(logger251, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, identityStorage, lockCredentialStorage, settingsStorage, backupService, props) {
137534
137534
  super("WebApi");
137535
137535
  this.bridgeService = bridgeService;
137536
137536
  this.haClient = haClient;
@@ -137542,8 +137542,8 @@ var WebApi = class extends Service {
137542
137542
  this.settingsStorage = settingsStorage;
137543
137543
  this.backupService = backupService;
137544
137544
  this.props = props;
137545
- this.logger = logger250;
137546
- this.log = logger250.get(this);
137545
+ this.logger = logger251;
137546
+ this.log = logger251.get(this);
137547
137547
  this.accessLogger = accessLogger(this.log.createChild("Access Log"));
137548
137548
  this.startTime = Date.now();
137549
137549
  this.wsApi = new WebSocketApi(
@@ -138734,10 +138734,10 @@ function isTransientConnectError(reason) {
138734
138734
  return msg.includes("socket hang up") || msg.includes("tls") || msg.includes("TLS");
138735
138735
  }
138736
138736
  var HomeAssistantClient = class extends Service {
138737
- constructor(logger250, options) {
138737
+ constructor(logger251, options) {
138738
138738
  super("HomeAssistantClient");
138739
138739
  this.options = options;
138740
- this.log = logger250.get(this);
138740
+ this.log = logger251.get(this);
138741
138741
  }
138742
138742
  options;
138743
138743
  static Options = /* @__PURE__ */ Symbol.for("HomeAssistantClientProps");
@@ -156524,8 +156524,8 @@ var PluginManager = class {
156524
156524
  this.storageDir = storageDir;
156525
156525
  this.homeAssistant = homeAssistant;
156526
156526
  }
156527
- setRegistry(registry2) {
156528
- this.registry = registry2;
156527
+ setRegistry(registry3) {
156528
+ this.registry = registry3;
156529
156529
  }
156530
156530
  /**
156531
156531
  * Load and register a built-in plugin instance.
@@ -157335,11 +157335,11 @@ var AUTO_FORCE_SYNC_INTERVAL_MS = 9e4;
157335
157335
  var SHUTDOWN_SESSION_CLOSE_TIMEOUT_MS = 2500;
157336
157336
  var MDNS_ADDRESS_CHECK_INTERVAL_MS = 6e4;
157337
157337
  var Bridge = class {
157338
- constructor(env, logger250, dataProvider, endpointManager, serverOptions) {
157338
+ constructor(env, logger251, dataProvider, endpointManager, serverOptions) {
157339
157339
  this.dataProvider = dataProvider;
157340
157340
  this.endpointManager = endpointManager;
157341
157341
  this.serverOptions = serverOptions;
157342
- this.log = logger250.get(`Bridge / ${dataProvider.id}`);
157342
+ this.log = logger251.get(`Bridge / ${dataProvider.id}`);
157343
157343
  this.server = new BridgeServerNode(
157344
157344
  env,
157345
157345
  this.dataProvider,
@@ -158471,9 +158471,9 @@ function resolveBatteryPercent(state) {
158471
158471
  return BATTERY_ENUM_PERCENT[state.toLowerCase()] ?? null;
158472
158472
  }
158473
158473
  var EntityStateProvider = class extends Service {
158474
- constructor(registry2) {
158474
+ constructor(registry3) {
158475
158475
  super("EntityStateProvider");
158476
- this.registry = registry2;
158476
+ this.registry = registry3;
158477
158477
  }
158478
158478
  registry;
158479
158479
  /**
@@ -160391,11 +160391,11 @@ function createEndpointId2(entityId, customName) {
160391
160391
  const baseName = customName || entityId;
160392
160392
  return baseName.replace(/\./g, "_").replace(/\s+/g, "_");
160393
160393
  }
160394
- function buildEntityPayload(registry2, entityId) {
160395
- const state = registry2.initialState(entityId);
160394
+ function buildEntityPayload(registry3, entityId) {
160395
+ const state = registry3.initialState(entityId);
160396
160396
  if (!state) return void 0;
160397
- const entity = registry2.entity(entityId);
160398
- const deviceRegistry = registry2.deviceOf(entityId);
160397
+ const entity = registry3.entity(entityId);
160398
+ const deviceRegistry = registry3.deviceOf(entityId);
160399
160399
  return {
160400
160400
  entity_id: entityId,
160401
160401
  state,
@@ -160410,8 +160410,8 @@ var ComposedAirPurifierEndpoint = class _ComposedAirPurifierEndpoint extends End
160410
160410
  lastStates = /* @__PURE__ */ new Map();
160411
160411
  debouncedUpdates = /* @__PURE__ */ new Map();
160412
160412
  static async create(config11) {
160413
- const { registry: registry2, primaryEntityId } = config11;
160414
- const primaryPayload = buildEntityPayload(registry2, primaryEntityId);
160413
+ const { registry: registry3, primaryEntityId } = config11;
160414
+ const primaryPayload = buildEntityPayload(registry3, primaryEntityId);
160415
160415
  if (!primaryPayload) return void 0;
160416
160416
  const airPurifierAttributes = primaryPayload.state.attributes;
160417
160417
  const supportedFeatures = airPurifierAttributes.supported_features ?? 0;
@@ -160499,7 +160499,7 @@ var ComposedAirPurifierEndpoint = class _ComposedAirPurifierEndpoint extends End
160499
160499
  let tempSub;
160500
160500
  if (config11.temperatureEntityId) {
160501
160501
  const tempPayload = buildEntityPayload(
160502
- registry2,
160502
+ registry3,
160503
160503
  config11.temperatureEntityId
160504
160504
  );
160505
160505
  if (tempPayload) {
@@ -160514,7 +160514,7 @@ var ComposedAirPurifierEndpoint = class _ComposedAirPurifierEndpoint extends End
160514
160514
  }
160515
160515
  let humSub;
160516
160516
  if (config11.humidityEntityId) {
160517
- const humPayload = buildEntityPayload(registry2, config11.humidityEntityId);
160517
+ const humPayload = buildEntityPayload(registry3, config11.humidityEntityId);
160518
160518
  if (humPayload) {
160519
160519
  humSub = new Endpoint(
160520
160520
  HumiditySubType.set({
@@ -161968,14 +161968,14 @@ function createEndpointId3(entityId, customName) {
161968
161968
  const baseName = customName || entityId;
161969
161969
  return baseName.replace(/\./g, "_").replace(/\s+/g, "_");
161970
161970
  }
161971
- function buildEntityPayload2(registry2, entityId) {
161972
- const state = registry2.initialState(entityId);
161971
+ function buildEntityPayload2(registry3, entityId) {
161972
+ const state = registry3.initialState(entityId);
161973
161973
  if (!state) return void 0;
161974
161974
  return {
161975
161975
  entity_id: entityId,
161976
161976
  state,
161977
- registry: registry2.entity(entityId),
161978
- deviceRegistry: registry2.deviceOf(entityId)
161977
+ registry: registry3.entity(entityId),
161978
+ deviceRegistry: registry3.deviceOf(entityId)
161979
161979
  };
161980
161980
  }
161981
161981
  var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpoint {
@@ -161985,8 +161985,8 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
161985
161985
  lastStates = /* @__PURE__ */ new Map();
161986
161986
  debouncedUpdates = /* @__PURE__ */ new Map();
161987
161987
  static async create(config11) {
161988
- const { registry: registry2, primaryEntityId } = config11;
161989
- const payload = buildEntityPayload2(registry2, primaryEntityId);
161988
+ const { registry: registry3, primaryEntityId } = config11;
161989
+ const payload = buildEntityPayload2(registry3, primaryEntityId);
161990
161990
  if (!payload) return void 0;
161991
161991
  const endpointId = config11.endpointId ?? createEndpointId3(primaryEntityId, config11.customName);
161992
161992
  const mapping = config11.mapping ?? {
@@ -162244,11 +162244,11 @@ function createEndpointId4(entityId, customName) {
162244
162244
  const baseName = customName || entityId;
162245
162245
  return baseName.replace(/\./g, "_").replace(/\s+/g, "_");
162246
162246
  }
162247
- function buildEntityPayload3(registry2, entityId) {
162248
- const state = registry2.initialStateIncludingUnfiltered(entityId);
162247
+ function buildEntityPayload3(registry3, entityId) {
162248
+ const state = registry3.initialStateIncludingUnfiltered(entityId);
162249
162249
  if (!state) return void 0;
162250
- const entity = registry2.entityIncludingUnfiltered(entityId);
162251
- const deviceRegistry = registry2.deviceOfIncludingUnfiltered(entityId);
162250
+ const entity = registry3.entityIncludingUnfiltered(entityId);
162251
+ const deviceRegistry = registry3.deviceOfIncludingUnfiltered(entityId);
162252
162252
  return {
162253
162253
  entity_id: entityId,
162254
162254
  state,
@@ -162263,8 +162263,8 @@ var ComposedSensorEndpoint = class _ComposedSensorEndpoint extends Endpoint {
162263
162263
  lastStates = /* @__PURE__ */ new Map();
162264
162264
  debouncedUpdates = /* @__PURE__ */ new Map();
162265
162265
  static async create(config11) {
162266
- const { registry: registry2, primaryEntityId } = config11;
162267
- const primaryPayload = buildEntityPayload3(registry2, primaryEntityId);
162266
+ const { registry: registry3, primaryEntityId } = config11;
162267
+ const primaryPayload = buildEntityPayload3(registry3, primaryEntityId);
162268
162268
  if (!primaryPayload) return void 0;
162269
162269
  let parentType = BridgedNodeEndpoint.with(
162270
162270
  BasicInformationServer2,
@@ -162308,7 +162308,7 @@ var ComposedSensorEndpoint = class _ComposedSensorEndpoint extends Endpoint {
162308
162308
  parts.push(tempSub);
162309
162309
  let humSub;
162310
162310
  if (config11.humidityEntityId) {
162311
- const humPayload = buildEntityPayload3(registry2, config11.humidityEntityId);
162311
+ const humPayload = buildEntityPayload3(registry3, config11.humidityEntityId);
162312
162312
  if (humPayload) {
162313
162313
  humSub = new Endpoint(
162314
162314
  HumiditySubType2.set({
@@ -162322,7 +162322,7 @@ var ComposedSensorEndpoint = class _ComposedSensorEndpoint extends Endpoint {
162322
162322
  let pressSub;
162323
162323
  if (config11.pressureEntityId) {
162324
162324
  const pressPayload = buildEntityPayload3(
162325
- registry2,
162325
+ registry3,
162326
162326
  config11.pressureEntityId
162327
162327
  );
162328
162328
  if (pressPayload) {
@@ -163276,6 +163276,15 @@ function clearPendingTilt(st) {
163276
163276
  st.pendingTilt = null;
163277
163277
  }
163278
163278
  var coverOptimistic = /* @__PURE__ */ new WeakMap();
163279
+ function haRestEnd(action) {
163280
+ if (action.action.includes("open_cover")) {
163281
+ return "open";
163282
+ }
163283
+ if (action.action.includes("close_cover")) {
163284
+ return "close";
163285
+ }
163286
+ return null;
163287
+ }
163279
163288
  function getCoverOptimistic(endpoint) {
163280
163289
  let st = coverOptimistic.get(endpoint);
163281
163290
  if (!st) {
@@ -163390,7 +163399,10 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
163390
163399
  if (!entry) {
163391
163400
  return MovementStatus.Stopped;
163392
163401
  }
163393
- const reachedTarget = positionAware && current100ths != null && existingTarget != null && Math.abs(current100ths - existingTarget) < 100;
163402
+ const getExpected = config11.getExpectedRestPosition;
163403
+ const expectedPercent = entry.expectedRestEnd != null && getExpected != null ? getExpected(entry.expectedRestEnd, this.agent) : null;
163404
+ const goal = expectedPercent != null ? expectedPercent * 100 : existingTarget;
163405
+ const reachedTarget = positionAware && current100ths != null && goal != null && Math.abs(current100ths - goal) < 100;
163394
163406
  const expired = Date.now() - entry.startedAt >= optimisticMovementTimeoutMs;
163395
163407
  if (reachedTarget || expired) {
163396
163408
  clearOptimisticAxis(optimistic, axis);
@@ -163495,7 +163507,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
163495
163507
  }
163496
163508
  // Record the optimistic direction and emit it now so a controller gets the
163497
163509
  // moving->stopped edge even when HA never reports a transitional state (#429).
163498
- startOptimisticMovement(axis, status3) {
163510
+ startOptimisticMovement(axis, status3, expectedRestEnd) {
163499
163511
  const optimistic = getCoverOptimistic(this.endpoint);
163500
163512
  clearOptimisticAxis(optimistic, axis);
163501
163513
  const endpoint = this.endpoint;
@@ -163540,7 +163552,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
163540
163552
  })();
163541
163553
  }, optimisticMovementTimeoutMs);
163542
163554
  timer.unref?.();
163543
- optimistic[axis] = { status: status3, startedAt, timer };
163555
+ optimistic[axis] = { status: status3, startedAt, timer, expectedRestEnd };
163544
163556
  this.writeOperationalStatus({ [axis]: status3 });
163545
163557
  }
163546
163558
  async handleMovement(type, _, direction, targetPercent100ths) {
@@ -163599,17 +163611,25 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
163599
163611
  }
163600
163612
  handleLiftOpen() {
163601
163613
  clearPendingLift(getCoverDebounce(this.endpoint));
163602
- this.startOptimisticMovement("lift", MovementStatus.Opening);
163603
163614
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
163604
163615
  const action = this.state.config.openCoverLift(void 0, this.agent);
163616
+ this.startOptimisticMovement(
163617
+ "lift",
163618
+ MovementStatus.Opening,
163619
+ haRestEnd(action)
163620
+ );
163605
163621
  logger218.info(`handleLiftOpen: calling action=${action.action}`);
163606
163622
  homeAssistant.callAction(action);
163607
163623
  }
163608
163624
  handleLiftClose() {
163609
163625
  clearPendingLift(getCoverDebounce(this.endpoint));
163610
- this.startOptimisticMovement("lift", MovementStatus.Closing);
163611
163626
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
163612
163627
  const action = this.state.config.closeCoverLift(void 0, this.agent);
163628
+ this.startOptimisticMovement(
163629
+ "lift",
163630
+ MovementStatus.Closing,
163631
+ haRestEnd(action)
163632
+ );
163613
163633
  logger218.info(`handleLiftClose: calling action=${action.action}`);
163614
163634
  homeAssistant.callAction(action);
163615
163635
  }
@@ -163620,14 +163640,15 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
163620
163640
  return;
163621
163641
  }
163622
163642
  this.state.targetPositionLiftPercent100ths = targetPercent100ths;
163623
- this.startOptimisticMovement(
163624
- "lift",
163625
- currentPositionMatter != null && targetPercent100ths < currentPositionMatter ? MovementStatus.Opening : MovementStatus.Closing
163626
- );
163627
163643
  const targetPosition = targetPercent100ths / 100;
163628
163644
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
163629
163645
  const action = config11.setLiftPosition(targetPosition, this.agent);
163630
163646
  const entityId = homeAssistant.entityId;
163647
+ this.startOptimisticMovement(
163648
+ "lift",
163649
+ currentPositionMatter != null && targetPercent100ths < currentPositionMatter ? MovementStatus.Opening : MovementStatus.Closing,
163650
+ haRestEnd(action)
163651
+ );
163631
163652
  const actions = this.env.get(HomeAssistantActions);
163632
163653
  const st = getCoverDebounce(this.endpoint);
163633
163654
  st.pendingLift = { action, entityId, actions };
@@ -163660,21 +163681,27 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
163660
163681
  const st = getCoverDebounce(this.endpoint);
163661
163682
  clearPendingTilt(st);
163662
163683
  if (st.pendingLift?.action.action.includes("tilt")) clearPendingLift(st);
163663
- this.startOptimisticMovement("tilt", MovementStatus.Opening);
163664
- const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
163665
- homeAssistant.callAction(
163666
- this.state.config.openCoverTilt(void 0, this.agent)
163684
+ const action = this.state.config.openCoverTilt(void 0, this.agent);
163685
+ this.startOptimisticMovement(
163686
+ "tilt",
163687
+ MovementStatus.Opening,
163688
+ haRestEnd(action)
163667
163689
  );
163690
+ const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
163691
+ homeAssistant.callAction(action);
163668
163692
  }
163669
163693
  handleTiltClose() {
163670
163694
  const st = getCoverDebounce(this.endpoint);
163671
163695
  clearPendingTilt(st);
163672
163696
  if (st.pendingLift?.action.action.includes("tilt")) clearPendingLift(st);
163673
- this.startOptimisticMovement("tilt", MovementStatus.Closing);
163674
- const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
163675
- homeAssistant.callAction(
163676
- this.state.config.closeCoverTilt(void 0, this.agent)
163697
+ const action = this.state.config.closeCoverTilt(void 0, this.agent);
163698
+ this.startOptimisticMovement(
163699
+ "tilt",
163700
+ MovementStatus.Closing,
163701
+ haRestEnd(action)
163677
163702
  );
163703
+ const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
163704
+ homeAssistant.callAction(action);
163678
163705
  }
163679
163706
  handleGoToTiltPosition(targetPercent100ths) {
163680
163707
  const config11 = this.state.config;
@@ -163683,14 +163710,15 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
163683
163710
  return;
163684
163711
  }
163685
163712
  this.state.targetPositionTiltPercent100ths = targetPercent100ths;
163686
- this.startOptimisticMovement(
163687
- "tilt",
163688
- currentPositionMatter != null && targetPercent100ths < currentPositionMatter ? MovementStatus.Opening : MovementStatus.Closing
163689
- );
163690
163713
  const targetPosition = targetPercent100ths / 100;
163691
163714
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
163692
163715
  const action = config11.setTiltPosition(targetPosition, this.agent);
163693
163716
  const entityId = homeAssistant.entityId;
163717
+ this.startOptimisticMovement(
163718
+ "tilt",
163719
+ currentPositionMatter != null && targetPercent100ths < currentPositionMatter ? MovementStatus.Opening : MovementStatus.Closing,
163720
+ haRestEnd(action)
163721
+ );
163694
163722
  const actions = this.env.get(HomeAssistantActions);
163695
163723
  const st = getCoverDebounce(this.endpoint);
163696
163724
  st.pendingTilt = { action, entityId, actions };
@@ -163832,6 +163860,7 @@ var adjustPositionForWriting2 = (position, agent) => {
163832
163860
  const matterSem = usesMatterSemantics(agent);
163833
163861
  return adjustPositionForWriting(position, featureFlags, matterSem);
163834
163862
  };
163863
+ var expectedRestPosition = (end, agent) => adjustPositionForReading2(end === "open" ? 100 : 0, agent);
163835
163864
  var shouldSwapOpenClose = (agent) => {
163836
163865
  const homeAssistant = agent.get(HomeAssistantEntityBehavior);
163837
163866
  const entitySwap = homeAssistant.state.mapping?.coverSwapOpenClose;
@@ -163919,11 +163948,11 @@ var config6 = {
163919
163948
  }
163920
163949
  return position == null ? null : adjustPositionForReading2(position, agent);
163921
163950
  },
163951
+ getExpectedRestPosition: expectedRestPosition,
163922
163952
  getCoverType: (entity) => deviceClassMapping(entity)?.type,
163923
163953
  getEndProductType: (entity) => deviceClassMapping(entity)?.endProductType,
163924
163954
  getMovementStatus: (entity, agent) => {
163925
- const { featureFlags } = agent.env.get(BridgeDataProvider);
163926
- const swapped = featureFlags?.coverSwapOpenClose === true;
163955
+ const swapped = shouldSwapOpenClose(agent);
163927
163956
  const coverState = entity.state;
163928
163957
  if (coverState === CoverDeviceState.opening) {
163929
163958
  return swapped ? WindowCovering3.MovementStatus.Closing : WindowCovering3.MovementStatus.Opening;
@@ -169774,8 +169803,8 @@ var VacuumIdentifyServer = class extends IdentifyServer2 {
169774
169803
  #findIdentifyButton(homeAssistant) {
169775
169804
  const deviceId = homeAssistant.entity.registry?.device_id;
169776
169805
  if (!deviceId) return void 0;
169777
- const registry2 = this.env.get(HomeAssistantRegistry);
169778
- for (const entity of Object.values(registry2.entities)) {
169806
+ const registry3 = this.env.get(HomeAssistantRegistry);
169807
+ for (const entity of Object.values(registry3.entities)) {
169779
169808
  if (entity.device_id !== deviceId) continue;
169780
169809
  if (!entity.entity_id.startsWith("button.")) continue;
169781
169810
  const uniqueId = entity.unique_id ?? "";
@@ -172178,11 +172207,11 @@ function createEndpointId5(entityId, customName) {
172178
172207
  const baseName = customName || entityId;
172179
172208
  return baseName.replace(/\./g, "_").replace(/\s+/g, "_");
172180
172209
  }
172181
- function buildEntityPayload4(registry2, entityId) {
172182
- const state = registry2.initialStateIncludingUnfiltered(entityId);
172210
+ function buildEntityPayload4(registry3, entityId) {
172211
+ const state = registry3.initialStateIncludingUnfiltered(entityId);
172183
172212
  if (!state) return void 0;
172184
- const entity = registry2.entityIncludingUnfiltered(entityId);
172185
- const deviceRegistry = registry2.deviceOfIncludingUnfiltered(entityId);
172213
+ const entity = registry3.entityIncludingUnfiltered(entityId);
172214
+ const deviceRegistry = registry3.deviceOfIncludingUnfiltered(entityId);
172186
172215
  return {
172187
172216
  entity_id: entityId,
172188
172217
  state,
@@ -172198,8 +172227,8 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
172198
172227
  lastMappedStates = /* @__PURE__ */ new Map();
172199
172228
  debouncedUpdates = /* @__PURE__ */ new Map();
172200
172229
  static async create(config11) {
172201
- const { registry: registry2, primaryEntityId, composedEntities } = config11;
172202
- const primaryPayload = buildEntityPayload4(registry2, primaryEntityId);
172230
+ const { registry: registry3, primaryEntityId, composedEntities } = config11;
172231
+ const primaryPayload = buildEntityPayload4(registry3, primaryEntityId);
172203
172232
  if (!primaryPayload) return void 0;
172204
172233
  let parentType = BridgedNodeEndpoint.with(
172205
172234
  BasicInformationServer2,
@@ -172241,7 +172270,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
172241
172270
  primarySubPayload,
172242
172271
  primaryMapping,
172243
172272
  config11.areaName,
172244
- { vacuumOnOff: registry2.isVacuumOnOffEnabled() }
172273
+ { vacuumOnOff: registry3.isVacuumOnOffEnabled() }
172245
172274
  );
172246
172275
  if (!primaryType) {
172247
172276
  logger242.warn(
@@ -172257,7 +172286,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
172257
172286
  for (let i = 0; i < composedEntities.length; i++) {
172258
172287
  const sub = composedEntities[i];
172259
172288
  if (!sub.entityId) continue;
172260
- const subPayload = buildEntityPayload4(registry2, sub.entityId);
172289
+ const subPayload = buildEntityPayload4(registry3, sub.entityId);
172261
172290
  if (!subPayload) {
172262
172291
  logger242.warn(
172263
172292
  `Cannot find state for composed sub-entity ${sub.entityId}, it does not exist in Home Assistant (removed or renamed?)`
@@ -172419,32 +172448,32 @@ function asStandaloneEndpointType(type) {
172419
172448
  // src/matter/endpoints/legacy/legacy-endpoint.ts
172420
172449
  var logger243 = Logger.get("LegacyEndpoint");
172421
172450
  var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172422
- static async create(registry2, entityId, mapping, pluginDomainMappings, standalone = false, endpointId, identityAnchor) {
172423
- const deviceRegistry = registry2.deviceOf(entityId);
172424
- let state = registry2.initialState(entityId);
172425
- const entity = registry2.entity(entityId);
172451
+ static async create(registry3, entityId, mapping, pluginDomainMappings, standalone = false, endpointId, identityAnchor) {
172452
+ const deviceRegistry = registry3.deviceOf(entityId);
172453
+ let state = registry3.initialState(entityId);
172454
+ const entity = registry3.entity(entityId);
172426
172455
  if (!state) {
172427
172456
  return;
172428
172457
  }
172429
- if (registry2.isAutoBatteryMappingEnabled() && registry2.isBatteryEntityUsed(entityId)) {
172458
+ if (registry3.isAutoBatteryMappingEnabled() && registry3.isBatteryEntityUsed(entityId)) {
172430
172459
  logger243.debug(
172431
172460
  `Skipping ${entityId} - already auto-assigned as battery to another device`
172432
172461
  );
172433
172462
  return;
172434
172463
  }
172435
- if (registry2.isAutoHumidityMappingEnabled() && registry2.isHumidityEntityUsed(entityId)) {
172464
+ if (registry3.isAutoHumidityMappingEnabled() && registry3.isHumidityEntityUsed(entityId)) {
172436
172465
  logger243.debug(
172437
172466
  `Skipping ${entityId} - already auto-assigned as humidity to a temperature sensor`
172438
172467
  );
172439
172468
  return;
172440
172469
  }
172441
- if (registry2.isAutoPressureMappingEnabled() && registry2.isPressureEntityUsed(entityId)) {
172470
+ if (registry3.isAutoPressureMappingEnabled() && registry3.isPressureEntityUsed(entityId)) {
172442
172471
  logger243.debug(
172443
172472
  `Skipping ${entityId} - already auto-assigned as pressure to a temperature sensor`
172444
172473
  );
172445
172474
  return;
172446
172475
  }
172447
- if (registry2.isAutoComposedDevicesEnabled() && registry2.isComposedSubEntityUsed(entityId)) {
172476
+ if (registry3.isAutoComposedDevicesEnabled() && registry3.isComposedSubEntityUsed(entityId)) {
172448
172477
  logger243.debug(
172449
172478
  `Skipping ${entityId} - already consumed by a composed device`
172450
172479
  );
@@ -172452,10 +172481,10 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172452
172481
  }
172453
172482
  let effectiveMapping = mapping;
172454
172483
  if (entity.device_id) {
172455
- if (registry2.isAutoHumidityMappingEnabled()) {
172484
+ if (registry3.isAutoHumidityMappingEnabled()) {
172456
172485
  const attrs = state.attributes;
172457
172486
  if (!mapping?.humidityEntity && entityId.startsWith("sensor.") && attrs.device_class === SensorDeviceClass.temperature) {
172458
- const humidityEntityId = registry2.findHumidityEntityForDevice(
172487
+ const humidityEntityId = registry3.findHumidityEntityForDevice(
172459
172488
  entity.device_id
172460
172489
  );
172461
172490
  if (humidityEntityId && humidityEntityId !== entityId) {
@@ -172464,17 +172493,17 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172464
172493
  entityId: effectiveMapping?.entityId ?? entityId,
172465
172494
  humidityEntity: humidityEntityId
172466
172495
  };
172467
- registry2.markHumidityEntityUsed(humidityEntityId);
172496
+ registry3.markHumidityEntityUsed(humidityEntityId);
172468
172497
  logger243.debug(
172469
172498
  `Auto-assigned humidity ${humidityEntityId} to ${entityId}`
172470
172499
  );
172471
172500
  }
172472
172501
  }
172473
172502
  }
172474
- if (registry2.isAutoPressureMappingEnabled()) {
172503
+ if (registry3.isAutoPressureMappingEnabled()) {
172475
172504
  const attrs = state.attributes;
172476
172505
  if (!mapping?.pressureEntity && entityId.startsWith("sensor.") && attrs.device_class === SensorDeviceClass.temperature) {
172477
- const pressureEntityId = registry2.findPressureEntityForDevice(
172506
+ const pressureEntityId = registry3.findPressureEntityForDevice(
172478
172507
  entity.device_id
172479
172508
  );
172480
172509
  if (pressureEntityId && pressureEntityId !== entityId) {
@@ -172483,7 +172512,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172483
172512
  entityId: effectiveMapping?.entityId ?? entityId,
172484
172513
  pressureEntity: pressureEntityId
172485
172514
  };
172486
- registry2.markPressureEntityUsed(pressureEntityId);
172515
+ registry3.markPressureEntityUsed(pressureEntityId);
172487
172516
  logger243.debug(
172488
172517
  `Auto-assigned pressure ${pressureEntityId} to ${entityId}`
172489
172518
  );
@@ -172491,8 +172520,8 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172491
172520
  }
172492
172521
  }
172493
172522
  const isVacuum = entityId.startsWith("vacuum.");
172494
- if ((registry2.isAutoBatteryMappingEnabled() || isVacuum) && !mapping?.batteryEntity && !mapping?.disableBatteryMapping) {
172495
- const batteryEntityId = registry2.findBatteryEntityForDevice(
172523
+ if ((registry3.isAutoBatteryMappingEnabled() || isVacuum) && !mapping?.batteryEntity && !mapping?.disableBatteryMapping) {
172524
+ const batteryEntityId = registry3.findBatteryEntityForDevice(
172496
172525
  entity.device_id
172497
172526
  );
172498
172527
  if (batteryEntityId && batteryEntityId !== entityId) {
@@ -172501,7 +172530,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172501
172530
  entityId: effectiveMapping?.entityId ?? entityId,
172502
172531
  batteryEntity: batteryEntityId
172503
172532
  };
172504
- registry2.markBatteryEntityUsed(batteryEntityId);
172533
+ registry3.markBatteryEntityUsed(batteryEntityId);
172505
172534
  logger243.debug(
172506
172535
  `Auto-assigned battery ${batteryEntityId} to ${entityId}`
172507
172536
  );
@@ -172509,8 +172538,8 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172509
172538
  }
172510
172539
  const alarmDeviceClass = state.attributes.device_class;
172511
172540
  const isSmokeCoAlarm = mapping?.matterDeviceType === "smoke_co_alarm" || entityId.startsWith("binary_sensor.") && (alarmDeviceClass === "smoke" || alarmDeviceClass === "carbon_monoxide" || alarmDeviceClass === "gas");
172512
- if (registry2.isAutoBatteryMappingEnabled() && !mapping?.faultEntity && isSmokeCoAlarm) {
172513
- const faultEntityId = registry2.findProblemEntityForDevice(
172541
+ if (registry3.isAutoBatteryMappingEnabled() && !mapping?.faultEntity && isSmokeCoAlarm) {
172542
+ const faultEntityId = registry3.findProblemEntityForDevice(
172514
172543
  entity.device_id
172515
172544
  );
172516
172545
  if (faultEntityId && faultEntityId !== entityId) {
@@ -172525,7 +172554,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172525
172554
  if (!mapping?.powerEntity) {
172526
172555
  const domain = entityId.split(".")[0];
172527
172556
  if (domain === "switch") {
172528
- const powerEntityId = registry2.findPowerEntityForDevice(
172557
+ const powerEntityId = registry3.findPowerEntityForDevice(
172529
172558
  entity.device_id
172530
172559
  );
172531
172560
  if (powerEntityId && powerEntityId !== entityId) {
@@ -172534,7 +172563,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172534
172563
  entityId: effectiveMapping?.entityId ?? entityId,
172535
172564
  powerEntity: powerEntityId
172536
172565
  };
172537
- registry2.markPowerEntityUsed(powerEntityId);
172566
+ registry3.markPowerEntityUsed(powerEntityId);
172538
172567
  logger243.debug(`Auto-assigned power ${powerEntityId} to ${entityId}`);
172539
172568
  }
172540
172569
  }
@@ -172542,7 +172571,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172542
172571
  if (!mapping?.energyEntity) {
172543
172572
  const domain = entityId.split(".")[0];
172544
172573
  if (domain === "switch") {
172545
- const energyEntityId = registry2.findEnergyEntityForDevice(
172574
+ const energyEntityId = registry3.findEnergyEntityForDevice(
172546
172575
  entity.device_id
172547
172576
  );
172548
172577
  if (energyEntityId && energyEntityId !== entityId) {
@@ -172551,7 +172580,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172551
172580
  entityId: effectiveMapping?.entityId ?? entityId,
172552
172581
  energyEntity: energyEntityId
172553
172582
  };
172554
- registry2.markEnergyEntityUsed(energyEntityId);
172583
+ registry3.markEnergyEntityUsed(energyEntityId);
172555
172584
  logger243.debug(
172556
172585
  `Auto-assigned energy ${energyEntityId} to ${entityId}`
172557
172586
  );
@@ -172559,7 +172588,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172559
172588
  }
172560
172589
  }
172561
172590
  if (entityId.startsWith("vacuum.")) {
172562
- const vacuumEntities = registry2.findVacuumSelectEntities(
172591
+ const vacuumEntities = registry3.findVacuumSelectEntities(
172563
172592
  entity.device_id
172564
172593
  );
172565
172594
  if (!effectiveMapping?.cleaningModeEntity && vacuumEntities.cleaningModeEntity) {
@@ -172603,7 +172632,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172603
172632
  );
172604
172633
  }
172605
172634
  const supportedFeatures = state.attributes.supported_features ?? 0;
172606
- const cleanAreaRooms = await registry2.resolveCleanAreaRooms(
172635
+ const cleanAreaRooms = await registry3.resolveCleanAreaRooms(
172607
172636
  entityId,
172608
172637
  supportedFeatures
172609
172638
  );
@@ -172619,7 +172648,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172619
172648
  }
172620
172649
  const vacAttrs = state.attributes;
172621
172650
  if (cleanAreaRooms.length === 0 && !vacAttrs.rooms && !vacAttrs.segments && !vacAttrs.room_mapping) {
172622
- const valetudoRooms = registry2.findValetudoMapSegments(
172651
+ const valetudoRooms = registry3.findValetudoMapSegments(
172623
172652
  entity.device_id
172624
172653
  );
172625
172654
  if (valetudoRooms.length > 0) {
@@ -172638,7 +172667,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172638
172667
  `Auto-detected ${valetudoRooms.length} Valetudo segments for ${entityId}`
172639
172668
  );
172640
172669
  } else {
172641
- const roborockRooms = await registry2.resolveRoborockRooms(entityId);
172670
+ const roborockRooms = await registry3.resolveRoborockRooms(entityId);
172642
172671
  if (roborockRooms.length > 0) {
172643
172672
  const roomsObj = {};
172644
172673
  for (const r of roborockRooms) {
@@ -172664,10 +172693,10 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172664
172693
  `Composed mappings are not supported in server mode, exposing ${entityId} as a flat standalone endpoint`
172665
172694
  );
172666
172695
  }
172667
- if (!standalone && registry2.isAutoComposedDevicesEnabled() && effectiveMapping?.composedEntities && effectiveMapping.composedEntities.length > 0) {
172668
- const composedAreaName = registry2.getAreaName(entityId);
172696
+ if (!standalone && registry3.isAutoComposedDevicesEnabled() && effectiveMapping?.composedEntities && effectiveMapping.composedEntities.length > 0) {
172697
+ const composedAreaName = registry3.getAreaName(entityId);
172669
172698
  const composed = await UserComposedEndpoint.create({
172670
- registry: registry2,
172699
+ registry: registry3,
172671
172700
  primaryEntityId: entityId,
172672
172701
  mapping: effectiveMapping,
172673
172702
  composedEntities: effectiveMapping.composedEntities,
@@ -172683,12 +172712,12 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172683
172712
  `User composed device creation failed for ${entityId}, falling back to standalone`
172684
172713
  );
172685
172714
  }
172686
- if (!standalone && registry2.isAutoComposedDevicesEnabled()) {
172715
+ if (!standalone && registry3.isAutoComposedDevicesEnabled()) {
172687
172716
  const attrs = state.attributes;
172688
172717
  if (entityId.startsWith("sensor.") && attrs.device_class === SensorDeviceClass.temperature && (effectiveMapping?.humidityEntity || effectiveMapping?.pressureEntity)) {
172689
- const composedAreaName = registry2.getAreaName(entityId);
172718
+ const composedAreaName = registry3.getAreaName(entityId);
172690
172719
  const composed = await ComposedSensorEndpoint.create({
172691
- registry: registry2,
172720
+ registry: registry3,
172692
172721
  primaryEntityId: entityId,
172693
172722
  humidityEntityId: effectiveMapping?.humidityEntity,
172694
172723
  pressureEntityId: effectiveMapping?.pressureEntity,
@@ -172704,12 +172733,12 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172704
172733
  }
172705
172734
  const resolvedMatterType = mapping?.matterDeviceType ?? (entityId.startsWith("fan.") ? "fan" : void 0);
172706
172735
  if (resolvedMatterType === "air_purifier") {
172707
- const temperatureEntityId = effectiveMapping?.temperatureEntity || (entity.device_id ? registry2.findTemperatureEntityForDevice(entity.device_id) : void 0);
172708
- const humidityEntityId = effectiveMapping?.humidityEntity || (entity.device_id ? registry2.findHumidityEntityForDevice(entity.device_id) : void 0);
172736
+ const temperatureEntityId = effectiveMapping?.temperatureEntity || (entity.device_id ? registry3.findTemperatureEntityForDevice(entity.device_id) : void 0);
172737
+ const humidityEntityId = effectiveMapping?.humidityEntity || (entity.device_id ? registry3.findHumidityEntityForDevice(entity.device_id) : void 0);
172709
172738
  if (temperatureEntityId || humidityEntityId) {
172710
- const composedAreaName = registry2.getAreaName(entityId);
172739
+ const composedAreaName = registry3.getAreaName(entityId);
172711
172740
  const composed = await ComposedAirPurifierEndpoint.create({
172712
- registry: registry2,
172741
+ registry: registry3,
172713
172742
  primaryEntityId: entityId,
172714
172743
  temperatureEntityId,
172715
172744
  humidityEntityId,
@@ -172731,9 +172760,9 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172731
172760
  if (!standalone && entityId.startsWith("climate.") && effectiveMapping?.climateExposeFan === true) {
172732
172761
  const climateFeatures = state.attributes.supported_features ?? 0;
172733
172762
  if ((climateFeatures & ClimateDeviceFeature.FAN_MODE) !== 0) {
172734
- const composedAreaName = registry2.getAreaName(entityId);
172763
+ const composedAreaName = registry3.getAreaName(entityId);
172735
172764
  const composed = await ComposedClimateFanEndpoint.create({
172736
- registry: registry2,
172765
+ registry: registry3,
172737
172766
  primaryEntityId: entityId,
172738
172767
  mapping: effectiveMapping,
172739
172768
  customName: effectiveMapping?.customName,
@@ -172758,7 +172787,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172758
172787
  let cleaningModeOptions;
172759
172788
  if (entityId.startsWith("vacuum.")) {
172760
172789
  if (effectiveMapping?.cleaningModeEntity) {
172761
- const cmState = registry2.initialState(
172790
+ const cmState = registry3.initialState(
172762
172791
  effectiveMapping.cleaningModeEntity
172763
172792
  );
172764
172793
  cleaningModeOptions = cmState?.attributes?.options;
@@ -172772,13 +172801,13 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172772
172801
  ];
172773
172802
  }
172774
172803
  }
172775
- const areaName = registry2.getAreaName(entityId);
172804
+ const areaName = registry3.getAreaName(entityId);
172776
172805
  let type = createLegacyEndpointType(
172777
172806
  payload,
172778
172807
  effectiveMapping,
172779
172808
  areaName,
172780
172809
  {
172781
- vacuumOnOff: registry2.isVacuumOnOffEnabled(),
172810
+ vacuumOnOff: registry3.isVacuumOnOffEnabled(),
172782
172811
  cleaningModeOptions,
172783
172812
  pluginDomainMappings
172784
172813
  },
@@ -172960,27 +172989,181 @@ var CameraAvStreamServer = class extends Base4 {
172960
172989
  init_esm();
172961
172990
  init_esm7();
172962
172991
  init_esm3();
172963
- var logger244 = Logger.get("CameraWebRtc");
172992
+
172993
+ // src/plugins/builtin/camera/requestor-client.ts
172994
+ init_esm();
172995
+ init_esm4();
172996
+ var logger244 = Logger.get("CameraWebRtcRequestor");
172997
+ var registry2 = /* @__PURE__ */ new Map();
172998
+ var pendingDeliveries = /* @__PURE__ */ new Map();
172999
+ var invokeTransport = defaultInvoke;
173000
+ function registerRequestor(sessionId, registration) {
173001
+ registry2.set(sessionId, registration);
173002
+ }
173003
+ function unregisterRequestor(sessionId) {
173004
+ registry2.delete(sessionId);
173005
+ const timer = pendingDeliveries.get(sessionId);
173006
+ if (timer) {
173007
+ clearTimeout(timer);
173008
+ pendingDeliveries.delete(sessionId);
173009
+ }
173010
+ }
173011
+ function unregisterAllRequestors() {
173012
+ for (const id of [...registry2.keys()]) unregisterRequestor(id);
173013
+ for (const timer of pendingDeliveries.values()) clearTimeout(timer);
173014
+ pendingDeliveries.clear();
173015
+ }
173016
+ function deliverAnswerDeferred(sessionId, sdp, onGiveUp) {
173017
+ const prior = pendingDeliveries.get(sessionId);
173018
+ if (prior) clearTimeout(prior);
173019
+ const owner = registry2.get(sessionId);
173020
+ const timer = setTimeout(() => {
173021
+ void (async () => {
173022
+ try {
173023
+ for (const delayMs of [0, 250, 500]) {
173024
+ if (delayMs > 0) await new Promise((r) => setTimeout(r, delayMs));
173025
+ if (registry2.get(sessionId) !== owner || pendingDeliveries.get(sessionId) !== timer) {
173026
+ return;
173027
+ }
173028
+ if (await sendAnswer(sessionId, sdp)) {
173029
+ logger244.info(`answer delivered for session ${sessionId}`);
173030
+ return;
173031
+ }
173032
+ }
173033
+ if (registry2.get(sessionId) !== owner || pendingDeliveries.get(sessionId) !== timer) {
173034
+ return;
173035
+ }
173036
+ logger244.info(
173037
+ `answer delivery failed for session ${sessionId}, giving up`
173038
+ );
173039
+ await onGiveUp();
173040
+ } catch (err) {
173041
+ logger244.info(
173042
+ `answer delivery for session ${sessionId} threw: ${errText(err)}`
173043
+ );
173044
+ } finally {
173045
+ if (pendingDeliveries.get(sessionId) === timer) {
173046
+ pendingDeliveries.delete(sessionId);
173047
+ }
173048
+ }
173049
+ })();
173050
+ }, 0);
173051
+ timer.unref?.();
173052
+ pendingDeliveries.set(sessionId, timer);
173053
+ }
173054
+ function hasRequestor(sessionId) {
173055
+ return registry2.has(sessionId);
173056
+ }
173057
+ function sendAnswer(sessionId, sdp) {
173058
+ return invokeRequestor(sessionId, "answer", {
173059
+ webRtcSessionId: sessionId,
173060
+ sdp
173061
+ });
173062
+ }
173063
+ async function invokeRequestor(sessionId, command, fields) {
173064
+ const registration = registry2.get(sessionId);
173065
+ if (!registration) {
173066
+ logger244.info(`requestor ${command}: no session ${sessionId} registered`);
173067
+ return false;
173068
+ }
173069
+ if (registration.session.isClosed) {
173070
+ logger244.info(`requestor ${command}: session ${sessionId} already closed`);
173071
+ return false;
173072
+ }
173073
+ const request = {
173074
+ endpoint: registration.requestorEndpoint,
173075
+ cluster: WebRtcTransportRequestor3.Cluster,
173076
+ command,
173077
+ fields
173078
+ };
173079
+ try {
173080
+ return await invokeTransport({ registration, request });
173081
+ } catch (err) {
173082
+ logger244.info(
173083
+ `requestor ${command} failed for session ${sessionId}: ${errText(err)}`
173084
+ );
173085
+ return false;
173086
+ }
173087
+ }
173088
+ async function defaultInvoke({
173089
+ registration,
173090
+ request
173091
+ }) {
173092
+ const { session, env } = registration;
173093
+ const exchangeManager = env.get(ExchangeManager);
173094
+ const exchangeProvider = new DedicatedChannelExchangeProvider(
173095
+ exchangeManager,
173096
+ session
173097
+ );
173098
+ const client = new ClientInteraction({ environment: env, exchangeProvider });
173099
+ try {
173100
+ const result = client.invoke(
173101
+ Invoke({
173102
+ commands: [
173103
+ {
173104
+ endpoint: request.endpoint,
173105
+ cluster: request.cluster,
173106
+ command: request.command,
173107
+ // biome-ignore lint/suspicious/noExplicitAny: fields typed per command by caller
173108
+ fields: request.fields
173109
+ }
173110
+ ]
173111
+ })
173112
+ );
173113
+ for await (const chunk of result) {
173114
+ for (const entry of chunk) {
173115
+ if (entry.kind === "cmd-status") {
173116
+ if (entry.status !== Status2.Success) {
173117
+ logger244.info(
173118
+ `requestor ${request.command} status ${entry.status} for session ${String(request.fields.webRtcSessionId)}`
173119
+ );
173120
+ return false;
173121
+ }
173122
+ return true;
173123
+ }
173124
+ }
173125
+ }
173126
+ return true;
173127
+ } finally {
173128
+ await client.close().catch(() => {
173129
+ });
173130
+ }
173131
+ }
173132
+ function errText(err) {
173133
+ return err instanceof Error ? err.message : String(err);
173134
+ }
173135
+
173136
+ // src/plugins/builtin/camera/webrtc-provider-server.ts
173137
+ var logger245 = Logger.get("CameraWebRtc");
173138
+ var nextGlobalSessionId = 0;
173139
+ function mintSessionId() {
173140
+ for (let i = 0; i <= 65534; i++) {
173141
+ const id = nextGlobalSessionId;
173142
+ nextGlobalSessionId = nextGlobalSessionId >= 65534 ? 0 : nextGlobalSessionId + 1;
173143
+ if (!hasRequestor(id)) return id;
173144
+ }
173145
+ return nextGlobalSessionId;
173146
+ }
172964
173147
  var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
172965
173148
  solicitOffer(request) {
172966
- const id = this.state.nextSessionId++;
173149
+ const id = mintSessionId();
172967
173150
  this.trackSession(id, request.streamUsage, request.originatingEndpointId);
172968
- logger244.info(
173151
+ logger245.info(
172969
173152
  `solicitOffer session=${id} (${this.state.entityId}), deferred offer`
172970
173153
  );
172971
173154
  void this.state.bridge.startSession(id, this.state.entityId, {
172972
173155
  iceServers: request.iceServers,
172973
173156
  iceTransportPolicy: request.iceTransportPolicy
172974
173157
  }).catch(
172975
- (err) => logger244.info(
172976
- `solicitOffer startSession failed for ${this.state.entityId}: ${errText(err)}`
173158
+ (err) => logger245.info(
173159
+ `solicitOffer startSession failed for ${this.state.entityId}: ${errText2(err)}`
172977
173160
  )
172978
173161
  );
172979
173162
  return { webRtcSessionId: id, deferredOffer: true };
172980
173163
  }
172981
173164
  async provideOffer(request) {
172982
- const id = request.webRtcSessionId ?? this.state.nextSessionId++;
172983
- logger244.info(
173165
+ const id = request.webRtcSessionId ?? mintSessionId();
173166
+ logger245.info(
172984
173167
  `provideOffer entry: entityId=${this.state.entityId} session=${id} (sdp ${request.sdp.length} chars)`
172985
173168
  );
172986
173169
  if (request.webRtcSessionId == null) {
@@ -172990,6 +173173,15 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
172990
173173
  request.originatingEndpointId ?? EndpointNumber(0)
172991
173174
  );
172992
173175
  }
173176
+ const requestorEndpoint = request.originatingEndpointId ?? EndpointNumber(0);
173177
+ const session = this.context.session;
173178
+ if (session) {
173179
+ registerRequestor(id, {
173180
+ session,
173181
+ requestorEndpoint,
173182
+ env: this.env
173183
+ });
173184
+ }
172993
173185
  let answerSdp;
172994
173186
  try {
172995
173187
  answerSdp = await this.state.bridge.acceptControllerOffer(
@@ -173002,10 +173194,11 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
173002
173194
  }
173003
173195
  );
173004
173196
  } catch (err) {
173005
- const message = errText(err);
173006
- logger244.info(
173197
+ const message = errText2(err);
173198
+ logger245.info(
173007
173199
  `provideOffer failed for ${this.state.entityId} session=${id}: ${message}`
173008
173200
  );
173201
+ unregisterRequestor(id);
173009
173202
  this.state.currentSessions = this.state.currentSessions.filter(
173010
173203
  (s) => s.id !== id
173011
173204
  );
@@ -173014,14 +173207,26 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
173014
173207
  StatusCode.Failure
173015
173208
  );
173016
173209
  }
173017
- logger244.info(
173018
- `provideOffer answer computed for ${this.state.entityId} session=${id} (${answerSdp.length} chars); awaiting requestor delivery path`
173210
+ logger245.info(
173211
+ `provideOffer answer computed for ${this.state.entityId} session=${id} (${answerSdp.length} chars); delivering via requestor`
173019
173212
  );
173020
- void answerSdp;
173213
+ const bridge = this.state.bridge;
173214
+ const state = this.state;
173215
+ deliverAnswerDeferred(id, answerSdp, async () => {
173216
+ await bridge.endSession(id).catch(() => {
173217
+ });
173218
+ unregisterRequestor(id);
173219
+ try {
173220
+ state.currentSessions = state.currentSessions.filter(
173221
+ (s) => s.id !== id
173222
+ );
173223
+ } catch {
173224
+ }
173225
+ });
173021
173226
  return { webRtcSessionId: id };
173022
173227
  }
173023
173228
  provideAnswer(request) {
173024
- logger244.info(
173229
+ logger245.info(
173025
173230
  `provideAnswer session=${request.webRtcSessionId} (sdp ${request.sdp.length} chars, ${this.state.entityId})`
173026
173231
  );
173027
173232
  return this.state.bridge.acceptControllerAnswer(
@@ -173030,7 +173235,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
173030
173235
  );
173031
173236
  }
173032
173237
  async provideIceCandidates(request) {
173033
- logger244.info(
173238
+ logger245.info(
173034
173239
  `provideIceCandidates session=${request.webRtcSessionId}: ${request.iceCandidates.length} candidate(s) (${this.state.entityId})`
173035
173240
  );
173036
173241
  for (const c of request.iceCandidates) {
@@ -173043,16 +173248,21 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
173043
173248
  }
173044
173249
  }
173045
173250
  async endSession(request) {
173046
- logger244.info(
173251
+ logger245.info(
173047
173252
  `endSession session=${request.webRtcSessionId} (${this.state.entityId})`
173048
173253
  );
173049
173254
  await this.state.bridge.endSession(request.webRtcSessionId);
173255
+ unregisterRequestor(request.webRtcSessionId);
173050
173256
  this.state.currentSessions = this.state.currentSessions.filter(
173051
173257
  (s) => s.id !== request.webRtcSessionId
173052
173258
  );
173053
173259
  }
173054
173260
  trackSession(id, streamUsage, peerEndpointId) {
173055
173261
  const session = this.context.session;
173262
+ const fabricIndex = session?.associatedFabric?.fabricIndex;
173263
+ if (fabricIndex == null) {
173264
+ return;
173265
+ }
173056
173266
  this.state.currentSessions = [
173057
173267
  ...this.state.currentSessions,
173058
173268
  {
@@ -173061,19 +173271,18 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
173061
173271
  peerEndpointId,
173062
173272
  streamUsage,
173063
173273
  metadataEnabled: false,
173064
- fabricIndex: session?.associatedFabric?.fabricIndex ?? FabricIndex3(0)
173274
+ fabricIndex
173065
173275
  }
173066
173276
  ];
173067
173277
  }
173068
173278
  };
173069
- function errText(err) {
173279
+ function errText2(err) {
173070
173280
  return err instanceof Error ? err.message : String(err);
173071
173281
  }
173072
173282
  ((CameraWebRtcProviderServer2) => {
173073
173283
  class State extends WebRtcTransportProviderServer.State {
173074
173284
  bridge;
173075
173285
  entityId;
173076
- nextSessionId = 1;
173077
173286
  }
173078
173287
  CameraWebRtcProviderServer2.State = State;
173079
173288
  })(CameraWebRtcProviderServer || (CameraWebRtcProviderServer = {}));
@@ -173092,8 +173301,7 @@ function createCameraEndpointType(bridge, entityId, sensor = defaultSensorParams
173092
173301
  webRtcTransportProvider: {
173093
173302
  bridge,
173094
173303
  entityId,
173095
- currentSessions: [],
173096
- nextSessionId: 1
173304
+ currentSessions: []
173097
173305
  },
173098
173306
  cameraAvStreamManagement: {
173099
173307
  bridge,
@@ -173161,7 +173369,7 @@ import {
173161
173369
  createLongLivedTokenAuth as createLongLivedTokenAuth2
173162
173370
  } from "home-assistant-js-websocket";
173163
173371
  import { RTCPeerConnection } from "werift";
173164
- var logger245 = Logger.get("CameraWebRtc");
173372
+ var logger246 = Logger.get("CameraWebRtc");
173165
173373
  var DEFAULT_HA_WEBRTC_TIMEOUT_MS = 15e3;
173166
173374
  var haWebRtcTimeoutMs = DEFAULT_HA_WEBRTC_TIMEOUT_MS;
173167
173375
  var WebRtcBridge = class {
@@ -173200,6 +173408,7 @@ var WebRtcBridge = class {
173200
173408
  controllerPeer.addTransceiver("video", { direction: "sendonly" })
173201
173409
  );
173202
173410
  this.forwardHaTracks(haPeer, senders, entityId);
173411
+ await this.closeExistingPeers(matterSessionId);
173203
173412
  this.sessions.set(matterSessionId, { entityId, haPeer, controllerPeer });
173204
173413
  try {
173205
173414
  haPeer.addTransceiver("video", { direction: "recvonly" });
@@ -173207,7 +173416,7 @@ var WebRtcBridge = class {
173207
173416
  const haOffer = await haPeer.createOffer();
173208
173417
  await haPeer.setLocalDescription(haOffer);
173209
173418
  const haOfferSdp = this.localSdp(haPeer);
173210
- logger245.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
173419
+ logger246.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
173211
173420
  const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
173212
173421
  entityId,
173213
173422
  haOfferSdp,
@@ -173230,12 +173439,12 @@ var WebRtcBridge = class {
173230
173439
  const controllerOffer = await controllerPeer.createOffer();
173231
173440
  await controllerPeer.setLocalDescription(controllerOffer);
173232
173441
  const sdp = this.localSdp(controllerPeer);
173233
- logger245.info(
173442
+ logger246.info(
173234
173443
  `controller offer created for ${entityId} (${sdp.length} chars)`
173235
173444
  );
173236
173445
  return { sdp, iceCandidates };
173237
173446
  } catch (err) {
173238
- logger245.info(`startSession failed for ${entityId}: ${errText2(err)}`);
173447
+ logger246.info(`startSession failed for ${entityId}: ${errText3(err)}`);
173239
173448
  await this.endSession(matterSessionId);
173240
173449
  throw err;
173241
173450
  }
@@ -173257,6 +173466,7 @@ var WebRtcBridge = class {
173257
173466
  );
173258
173467
  }
173259
173468
  this.forwardHaTracks(haPeer, senders, entityId);
173469
+ await this.closeExistingPeers(matterSessionId);
173260
173470
  this.sessions.set(matterSessionId, { entityId, haPeer, controllerPeer });
173261
173471
  try {
173262
173472
  haPeer.addTransceiver("video", { direction: "recvonly" });
@@ -173264,7 +173474,7 @@ var WebRtcBridge = class {
173264
173474
  const haOffer = await haPeer.createOffer();
173265
173475
  await haPeer.setLocalDescription(haOffer);
173266
173476
  const haOfferSdp = this.localSdp(haPeer);
173267
- logger245.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
173477
+ logger246.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
173268
173478
  const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
173269
173479
  entityId,
173270
173480
  haOfferSdp,
@@ -173283,13 +173493,13 @@ var WebRtcBridge = class {
173283
173493
  const controllerAnswer = await controllerPeer.createAnswer();
173284
173494
  await controllerPeer.setLocalDescription(controllerAnswer);
173285
173495
  const answerSdp = this.localSdp(controllerPeer);
173286
- logger245.info(
173496
+ logger246.info(
173287
173497
  `controller answer created for ${entityId} (${answerSdp.length} chars)`
173288
173498
  );
173289
173499
  return answerSdp;
173290
173500
  } catch (err) {
173291
- logger245.info(
173292
- `acceptControllerOffer failed for ${entityId}: ${errText2(err)}`
173501
+ logger246.info(
173502
+ `acceptControllerOffer failed for ${entityId}: ${errText3(err)}`
173293
173503
  );
173294
173504
  await this.endSession(matterSessionId);
173295
173505
  throw err;
@@ -173299,14 +173509,14 @@ var WebRtcBridge = class {
173299
173509
  async acceptControllerAnswer(matterSessionId, sdp) {
173300
173510
  const session = this.sessions.get(matterSessionId);
173301
173511
  if (!session) return;
173302
- logger245.debug(`controller answer applied for ${session.entityId}`);
173512
+ logger246.debug(`controller answer applied for ${session.entityId}`);
173303
173513
  await session.controllerPeer.setRemoteDescription({ type: "answer", sdp });
173304
173514
  }
173305
173515
  /** Add a remote ICE candidate from the Matter controller. */
173306
173516
  async addControllerIceCandidate(matterSessionId, candidate, sdpMid, sdpMLineIndex) {
173307
173517
  const session = this.sessions.get(matterSessionId);
173308
173518
  if (!session) return;
173309
- logger245.debug(
173519
+ logger246.debug(
173310
173520
  `controller ICE candidate for ${session.entityId}: ${candidate}`
173311
173521
  );
173312
173522
  await session.controllerPeer.addIceCandidate({
@@ -173315,32 +173525,53 @@ var WebRtcBridge = class {
173315
173525
  sdpMLineIndex: sdpMLineIndex ?? void 0
173316
173526
  });
173317
173527
  }
173528
+ // Close the peers of a session we are about to overwrite. Leaves no map
173529
+ // entry; the caller replaces it with fresh peers under the same id.
173530
+ async closeExistingPeers(matterSessionId) {
173531
+ const prior = this.sessions.get(matterSessionId);
173532
+ if (!prior) return;
173533
+ logger246.info(
173534
+ `replacing session ${matterSessionId} (${prior.entityId}), closing prior peers`
173535
+ );
173536
+ if (prior.haUnsubscribe) {
173537
+ await Promise.resolve(prior.haUnsubscribe()).catch(
173538
+ (err) => logger246.debug(`HA unsubscribe failed: ${errText3(err)}`)
173539
+ );
173540
+ }
173541
+ await prior.haPeer.close().catch(() => {
173542
+ });
173543
+ await prior.controllerPeer.close().catch(() => {
173544
+ });
173545
+ await this.stopHaStream(prior).catch(() => {
173546
+ });
173547
+ }
173318
173548
  async endSession(matterSessionId) {
173319
173549
  const session = this.sessions.get(matterSessionId);
173320
173550
  if (!session) return;
173321
- logger245.info(`ending session ${matterSessionId} (${session.entityId})`);
173551
+ logger246.info(`ending session ${matterSessionId} (${session.entityId})`);
173322
173552
  this.sessions.delete(matterSessionId);
173323
173553
  if (session.haUnsubscribe) {
173324
173554
  await Promise.resolve(session.haUnsubscribe()).catch(
173325
- (err) => logger245.debug(`HA unsubscribe failed: ${errText2(err)}`)
173555
+ (err) => logger246.debug(`HA unsubscribe failed: ${errText3(err)}`)
173326
173556
  );
173327
173557
  }
173328
173558
  await session.haPeer.close().catch(() => {
173329
173559
  });
173330
173560
  await session.controllerPeer.close().catch(() => {
173331
173561
  });
173332
- if (session.haSessionId) {
173333
- try {
173334
- const conn = await this.ha();
173335
- await conn.sendMessagePromise({
173336
- type: "camera/webrtc/candidate",
173337
- entity_id: session.entityId,
173338
- session_id: session.haSessionId,
173339
- candidate: { candidate: "" }
173340
- });
173341
- } catch {
173342
- }
173343
- }
173562
+ await this.stopHaStream(session).catch(() => {
173563
+ });
173564
+ }
173565
+ // Tell HA to stop the stream if we tracked an HA session id. Best effort.
173566
+ async stopHaStream(session) {
173567
+ if (!session.haSessionId) return;
173568
+ const conn = await this.ha();
173569
+ await conn.sendMessagePromise({
173570
+ type: "camera/webrtc/candidate",
173571
+ entity_id: session.entityId,
173572
+ session_id: session.haSessionId,
173573
+ candidate: { candidate: "" }
173574
+ });
173344
173575
  }
173345
173576
  // Grab a still JPEG via HA's camera proxy (for CaptureSnapshot).
173346
173577
  async snapshot(entityId) {
@@ -173351,11 +173582,11 @@ var WebRtcBridge = class {
173351
173582
  headers: { Authorization: `Bearer ${this.config.haToken}` }
173352
173583
  });
173353
173584
  } catch (err) {
173354
- logger245.info(`snapshot fetch failed for ${entityId}: ${errText2(err)}`);
173585
+ logger246.info(`snapshot fetch failed for ${entityId}: ${errText3(err)}`);
173355
173586
  throw err;
173356
173587
  }
173357
173588
  if (!res.ok) {
173358
- logger245.info(
173589
+ logger246.info(
173359
173590
  `snapshot fetch failed for ${entityId}: camera_proxy ${res.status}`
173360
173591
  );
173361
173592
  throw new Error(`HA camera_proxy ${entityId}: ${res.status}`);
@@ -173372,10 +173603,10 @@ var WebRtcBridge = class {
173372
173603
  // Forward every track HA sends into the matching pre-added controller sender.
173373
173604
  forwardHaTracks(haPeer, senders, entityId) {
173374
173605
  haPeer.onTrack.subscribe((track) => {
173375
- logger245.info(`onTrack ${track.kind} from HA (${entityId})`);
173606
+ logger246.info(`onTrack ${track.kind} from HA (${entityId})`);
173376
173607
  const transceiver = senders.get(track.kind);
173377
173608
  if (!transceiver) {
173378
- logger245.info(
173609
+ logger246.info(
173379
173610
  `no controller transceiver for ${track.kind} (${entityId})`
173380
173611
  );
173381
173612
  return;
@@ -173384,7 +173615,7 @@ var WebRtcBridge = class {
173384
173615
  track.onReceiveRtp.subscribe((rtp) => {
173385
173616
  if (!firstLogged) {
173386
173617
  firstLogged = true;
173387
- logger245.info(`first RTP forwarded for ${track.kind} (${entityId})`);
173618
+ logger246.info(`first RTP forwarded for ${track.kind} (${entityId})`);
173388
173619
  }
173389
173620
  transceiver.sender.sendRtp(rtp);
173390
173621
  });
@@ -173393,10 +173624,10 @@ var WebRtcBridge = class {
173393
173624
  // Log connection/ice state transitions (these events fire on change only).
173394
173625
  wireStateLogging(peer, label, entityId) {
173395
173626
  peer.connectionStateChange.subscribe(
173396
- (s) => logger245.info(`${label} connectionState=${s} (${entityId})`)
173627
+ (s) => logger246.info(`${label} connectionState=${s} (${entityId})`)
173397
173628
  );
173398
173629
  peer.iceConnectionStateChange.subscribe(
173399
- (s) => logger245.info(`${label} iceConnectionState=${s} (${entityId})`)
173630
+ (s) => logger246.info(`${label} iceConnectionState=${s} (${entityId})`)
173400
173631
  );
173401
173632
  }
173402
173633
  // Map the Matter ICE struct onto werift's config. Only the controller peer
@@ -173410,11 +173641,11 @@ var WebRtcBridge = class {
173410
173641
  }))
173411
173642
  );
173412
173643
  if (iceServers.length === 0) {
173413
- logger245.info(`controller peer using default ICE servers (${entityId})`);
173644
+ logger246.info(`controller peer using default ICE servers (${entityId})`);
173414
173645
  return void 0;
173415
173646
  }
173416
173647
  const policy = ice?.iceTransportPolicy === "relay" || ice?.iceTransportPolicy === "all" ? ice.iceTransportPolicy : void 0;
173417
- logger245.info(
173648
+ logger246.info(
173418
173649
  `controller peer using ${iceServers.length} controller ICE server(s)${policy ? ` policy=${policy}` : ""} (${entityId})`
173419
173650
  );
173420
173651
  return policy ? { iceServers, iceTransportPolicy: policy } : { iceServers };
@@ -173428,14 +173659,14 @@ var WebRtcBridge = class {
173428
173659
  feedHaCandidate(entityId, haPeer, candidate) {
173429
173660
  const value = candidate?.candidate;
173430
173661
  if (!value) return;
173431
- logger245.debug(`HA ICE candidate for ${entityId}: ${value}`);
173662
+ logger246.debug(`HA ICE candidate for ${entityId}: ${value}`);
173432
173663
  void haPeer.addIceCandidate({
173433
173664
  candidate: value,
173434
173665
  sdpMid: candidate?.sdpMid ?? void 0,
173435
173666
  sdpMLineIndex: candidate?.sdpMLineIndex ?? void 0
173436
173667
  }).catch(
173437
- (e) => logger245.debug(
173438
- `HA addIceCandidate failed for ${entityId}: ${errText2(e)}`
173668
+ (e) => logger246.debug(
173669
+ `HA addIceCandidate failed for ${entityId}: ${errText3(e)}`
173439
173670
  )
173440
173671
  );
173441
173672
  }
@@ -173463,7 +173694,7 @@ var WebRtcBridge = class {
173463
173694
  reject(err);
173464
173695
  });
173465
173696
  timer = setTimeout(() => {
173466
- logger245.info(
173697
+ logger246.info(
173467
173698
  `HA WebRTC timed out after ${haWebRtcTimeoutMs}ms for ${entityId}`
173468
173699
  );
173469
173700
  fail(
@@ -173481,7 +173712,7 @@ var WebRtcBridge = class {
173481
173712
  if (msg.session_id) sessionId = msg.session_id;
173482
173713
  const ans = msg.answer;
173483
173714
  settle(() => {
173484
- logger245.info(
173715
+ logger246.info(
173485
173716
  `HA answer received for ${entityId} (${ans.length} chars)`
173486
173717
  );
173487
173718
  resolve11(ans);
@@ -173490,7 +173721,7 @@ var WebRtcBridge = class {
173490
173721
  break;
173491
173722
  case "error": {
173492
173723
  const detail = msg.message ?? msg.code ?? "unknown error";
173493
- logger245.info(`HA WebRTC error for ${entityId}: ${detail}`);
173724
+ logger246.info(`HA WebRTC error for ${entityId}: ${detail}`);
173494
173725
  fail(new Error(`HA WebRTC error: ${detail}`));
173495
173726
  break;
173496
173727
  }
@@ -173517,7 +173748,7 @@ function offerKinds(sdp) {
173517
173748
  }
173518
173749
  return kinds;
173519
173750
  }
173520
- function errText2(err) {
173751
+ function errText3(err) {
173521
173752
  return err instanceof Error ? err.message : String(err);
173522
173753
  }
173523
173754
 
@@ -173652,6 +173883,7 @@ var CameraPlugin = class {
173652
173883
  await this.bridge?.close().catch(() => {
173653
173884
  });
173654
173885
  this.bridge = void 0;
173886
+ unregisterAllRequestors();
173655
173887
  }
173656
173888
  };
173657
173889
 
@@ -173665,7 +173897,7 @@ import {
173665
173897
  getCollection
173666
173898
  } from "home-assistant-js-websocket";
173667
173899
  import { atLeastHaVersion } from "home-assistant-js-websocket/dist/util.js";
173668
- var logger246 = Logger.get("SubscribeEntities");
173900
+ var logger247 = Logger.get("SubscribeEntities");
173669
173901
  function processEvent(store, updates) {
173670
173902
  const state = { ...store.state };
173671
173903
  if (updates.a) {
@@ -173691,7 +173923,7 @@ function processEvent(store, updates) {
173691
173923
  for (const entityId in updates.c) {
173692
173924
  let entityState = state[entityId];
173693
173925
  if (!entityState) {
173694
- logger246.warn("Received state update for unknown entity", entityId);
173926
+ logger247.warn("Received state update for unknown entity", entityId);
173695
173927
  continue;
173696
173928
  }
173697
173929
  entityState = { ...entityState };
@@ -173780,7 +174012,7 @@ var subscribeEntities = (conn, onChange, entityIds) => {
173780
174012
  // src/services/bridges/entity-isolation-service.ts
173781
174013
  init_esm();
173782
174014
  init_diagnostic_event_bus();
173783
- var logger247 = Logger.get("EntityIsolation");
174015
+ var logger248 = Logger.get("EntityIsolation");
173784
174016
  var EntityIsolationServiceImpl = class {
173785
174017
  isolatedEntities = /* @__PURE__ */ new Map();
173786
174018
  isolationCallbacks = /* @__PURE__ */ new Map();
@@ -173845,13 +174077,13 @@ var EntityIsolationServiceImpl = class {
173845
174077
  }
173846
174078
  const parsed = this.parseEndpointPath(msg);
173847
174079
  if (!parsed) {
173848
- logger247.warn("Could not parse entity from error:", msg);
174080
+ logger248.warn("Could not parse entity from error:", msg);
173849
174081
  return false;
173850
174082
  }
173851
174083
  const { bridgeId, entityName } = parsed;
173852
174084
  const callback = this.isolationCallbacks.get(bridgeId);
173853
174085
  if (!callback) {
173854
- logger247.warn(
174086
+ logger248.warn(
173855
174087
  `No isolation callback registered for bridge ${bridgeId}, entity: ${entityName}`
173856
174088
  );
173857
174089
  return false;
@@ -173866,7 +174098,7 @@ var EntityIsolationServiceImpl = class {
173866
174098
  reason,
173867
174099
  failedAt: (/* @__PURE__ */ new Date()).toISOString()
173868
174100
  });
173869
- logger247.warn(
174101
+ logger248.warn(
173870
174102
  `Isolating entity "${entityName}" from bridge ${bridgeId} due to: ${reason}`
173871
174103
  );
173872
174104
  diagnosticEventBus.emit("entity_error", `Entity isolated: ${entityName}`, {
@@ -173878,7 +174110,7 @@ var EntityIsolationServiceImpl = class {
173878
174110
  await callback(entityName);
173879
174111
  return true;
173880
174112
  } catch (e) {
173881
- logger247.error(`Failed to isolate entity ${entityName}:`, e);
174113
+ logger248.error(`Failed to isolate entity ${entityName}:`, e);
173882
174114
  return false;
173883
174115
  }
173884
174116
  }
@@ -173911,10 +174143,10 @@ var EntityIsolationService = new EntityIsolationServiceImpl();
173911
174143
  var MAX_ENTITY_ID_LENGTH = 150;
173912
174144
  var ENDPOINT_REMOVAL_GRACE_MS = 6e4;
173913
174145
  var BridgeEndpointManager = class extends Service {
173914
- constructor(client, registry2, mappingStorage, identityStorage, bridgeId, log, pluginManager, pluginRegistry, pluginInstaller) {
174146
+ constructor(client, registry3, mappingStorage, identityStorage, bridgeId, log, pluginManager, pluginRegistry, pluginInstaller) {
173915
174147
  super("BridgeEndpointManager");
173916
174148
  this.client = client;
173917
- this.registry = registry2;
174149
+ this.registry = registry3;
173918
174150
  this.mappingStorage = mappingStorage;
173919
174151
  this.identityStorage = identityStorage;
173920
174152
  this.bridgeId = bridgeId;
@@ -174625,8 +174857,8 @@ init_send_ha_message();
174625
174857
  import { callService as callService2 } from "home-assistant-js-websocket";
174626
174858
  import { keys as keys2, pickBy, values as values3 } from "lodash-es";
174627
174859
  var BridgeRegistry = class _BridgeRegistry {
174628
- constructor(registry2, dataProvider, client) {
174629
- this.registry = registry2;
174860
+ constructor(registry3, dataProvider, client) {
174861
+ this.registry = registry3;
174630
174862
  this.dataProvider = dataProvider;
174631
174863
  this.client = client;
174632
174864
  this.refresh();
@@ -175396,11 +175628,11 @@ function makeWarmStartState(state, now = (/* @__PURE__ */ new Date()).toISOStrin
175396
175628
  return { ...state, last_updated: now };
175397
175629
  }
175398
175630
  var ServerModeBridge = class {
175399
- constructor(logger250, dataProvider, endpointManager, server) {
175631
+ constructor(logger251, dataProvider, endpointManager, server) {
175400
175632
  this.dataProvider = dataProvider;
175401
175633
  this.endpointManager = endpointManager;
175402
175634
  this.server = server;
175403
- this.log = logger250.get(`ServerModeBridge / ${dataProvider.id}`);
175635
+ this.log = logger251.get(`ServerModeBridge / ${dataProvider.id}`);
175404
175636
  }
175405
175637
  dataProvider;
175406
175638
  endpointManager;
@@ -176430,12 +176662,12 @@ function ServerModeVacuumDevice(homeAssistantEntity, includeOnOff = false, clean
176430
176662
  }
176431
176663
 
176432
176664
  // src/matter/endpoints/server-mode-vacuum-endpoint.ts
176433
- var logger248 = Logger.get("ServerModeVacuumEndpoint");
176665
+ var logger249 = Logger.get("ServerModeVacuumEndpoint");
176434
176666
  var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEndpoint {
176435
- static async create(registry2, entityId, mapping, endpointId) {
176436
- const deviceRegistry = registry2.deviceOf(entityId);
176437
- let state = registry2.initialState(entityId);
176438
- const entity = registry2.entity(entityId);
176667
+ static async create(registry3, entityId, mapping, endpointId) {
176668
+ const deviceRegistry = registry3.deviceOf(entityId);
176669
+ let state = registry3.initialState(entityId);
176670
+ const entity = registry3.entity(entityId);
176439
176671
  if (!state) {
176440
176672
  return void 0;
176441
176673
  }
@@ -176443,12 +176675,12 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176443
176675
  if (mapping?.disableBatteryMapping && mapping.batteryEntity) {
176444
176676
  effectiveMapping = { ...mapping, batteryEntity: void 0 };
176445
176677
  }
176446
- logger248.info(
176678
+ logger249.info(
176447
176679
  `${entityId}: device_id=${entity.device_id}, manualBattery=${mapping?.batteryEntity ?? "none"}`
176448
176680
  );
176449
176681
  if (entity.device_id) {
176450
176682
  if (!mapping?.batteryEntity && !mapping?.disableBatteryMapping) {
176451
- const batteryEntityId = registry2.findBatteryEntityForDevice(
176683
+ const batteryEntityId = registry3.findBatteryEntityForDevice(
176452
176684
  entity.device_id
176453
176685
  );
176454
176686
  if (batteryEntityId && batteryEntityId !== entityId) {
@@ -176457,22 +176689,22 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176457
176689
  entityId: effectiveMapping?.entityId ?? entityId,
176458
176690
  batteryEntity: batteryEntityId
176459
176691
  };
176460
- registry2.markBatteryEntityUsed(batteryEntityId);
176461
- logger248.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
176692
+ registry3.markBatteryEntityUsed(batteryEntityId);
176693
+ logger249.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
176462
176694
  } else {
176463
176695
  const attrs = state.attributes;
176464
176696
  if (attrs.battery_level != null || attrs.battery != null) {
176465
- logger248.info(
176697
+ logger249.info(
176466
176698
  `${entityId}: No battery entity found, using battery attribute from vacuum state`
176467
176699
  );
176468
176700
  } else {
176469
- logger248.warn(
176701
+ logger249.warn(
176470
176702
  `${entityId}: No battery entity found for device ${entity.device_id}`
176471
176703
  );
176472
176704
  }
176473
176705
  }
176474
176706
  }
176475
- const vacuumEntities = registry2.findVacuumSelectEntities(
176707
+ const vacuumEntities = registry3.findVacuumSelectEntities(
176476
176708
  entity.device_id
176477
176709
  );
176478
176710
  if (!effectiveMapping?.cleaningModeEntity && vacuumEntities.cleaningModeEntity) {
@@ -176481,7 +176713,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176481
176713
  entityId: effectiveMapping?.entityId ?? entityId,
176482
176714
  cleaningModeEntity: vacuumEntities.cleaningModeEntity
176483
176715
  };
176484
- logger248.info(
176716
+ logger249.info(
176485
176717
  `${entityId}: Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity}`
176486
176718
  );
176487
176719
  }
@@ -176491,7 +176723,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176491
176723
  entityId: effectiveMapping?.entityId ?? entityId,
176492
176724
  suctionLevelEntity: vacuumEntities.suctionLevelEntity
176493
176725
  };
176494
- logger248.info(
176726
+ logger249.info(
176495
176727
  `${entityId}: Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity}`
176496
176728
  );
176497
176729
  }
@@ -176501,7 +176733,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176501
176733
  entityId: effectiveMapping?.entityId ?? entityId,
176502
176734
  mopIntensityEntity: vacuumEntities.mopIntensityEntity
176503
176735
  };
176504
- logger248.info(
176736
+ logger249.info(
176505
176737
  `${entityId}: Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity}`
176506
176738
  );
176507
176739
  }
@@ -176511,12 +176743,12 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176511
176743
  entityId: effectiveMapping?.entityId ?? entityId,
176512
176744
  currentRoomEntity: vacuumEntities.currentRoomEntity
176513
176745
  };
176514
- logger248.info(
176746
+ logger249.info(
176515
176747
  `${entityId}: Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity}`
176516
176748
  );
176517
176749
  }
176518
176750
  const supportedFeatures = state.attributes.supported_features ?? 0;
176519
- const cleanAreaRooms = await registry2.resolveCleanAreaRooms(
176751
+ const cleanAreaRooms = await registry3.resolveCleanAreaRooms(
176520
176752
  entityId,
176521
176753
  supportedFeatures
176522
176754
  );
@@ -176526,13 +176758,13 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176526
176758
  entityId: effectiveMapping?.entityId ?? entityId,
176527
176759
  cleanAreaRooms
176528
176760
  };
176529
- logger248.info(
176761
+ logger249.info(
176530
176762
  `${entityId}: Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA`
176531
176763
  );
176532
176764
  }
176533
176765
  const vacAttrs = state.attributes;
176534
176766
  if (cleanAreaRooms.length === 0 && !vacAttrs.rooms && !vacAttrs.segments && !vacAttrs.room_mapping) {
176535
- const valetudoRooms = registry2.findValetudoMapSegments(
176767
+ const valetudoRooms = registry3.findValetudoMapSegments(
176536
176768
  entity.device_id
176537
176769
  );
176538
176770
  if (valetudoRooms.length > 0) {
@@ -176547,11 +176779,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176547
176779
  rooms: roomsObj
176548
176780
  }
176549
176781
  };
176550
- logger248.info(
176782
+ logger249.info(
176551
176783
  `${entityId}: Auto-detected ${valetudoRooms.length} Valetudo segments`
176552
176784
  );
176553
176785
  } else {
176554
- const roborockRooms = await registry2.resolveRoborockRooms(entityId);
176786
+ const roborockRooms = await registry3.resolveRoborockRooms(entityId);
176555
176787
  if (roborockRooms.length > 0) {
176556
176788
  const roomsObj = {};
176557
176789
  for (const r of roborockRooms) {
@@ -176564,14 +176796,14 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176564
176796
  rooms: roomsObj
176565
176797
  }
176566
176798
  };
176567
- logger248.info(
176799
+ logger249.info(
176568
176800
  `${entityId}: Auto-detected ${roborockRooms.length} Roborock rooms`
176569
176801
  );
176570
176802
  }
176571
176803
  }
176572
176804
  }
176573
176805
  } else {
176574
- logger248.warn(`${entityId}: No device_id, cannot auto-assign battery`);
176806
+ logger249.warn(`${entityId}: No device_id, cannot auto-assign battery`);
176575
176807
  }
176576
176808
  const payload = {
176577
176809
  entity_id: entityId,
@@ -176582,7 +176814,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176582
176814
  const vacAttrsForClean = state.attributes;
176583
176815
  let cleaningModeOptions;
176584
176816
  if (effectiveMapping?.cleaningModeEntity) {
176585
- const cmState = registry2.initialState(
176817
+ const cmState = registry3.initialState(
176586
176818
  effectiveMapping.cleaningModeEntity
176587
176819
  );
176588
176820
  cleaningModeOptions = cmState?.attributes?.options;
@@ -176602,7 +176834,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176602
176834
  customName,
176603
176835
  mapping: effectiveMapping
176604
176836
  },
176605
- registry2.isServerModeVacuumOnOffEnabled(),
176837
+ registry3.isServerModeVacuumOnOffEnabled(),
176606
176838
  cleaningModeOptions
176607
176839
  );
176608
176840
  if (!endpointType) {
@@ -176644,11 +176876,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176644
176876
  }
176645
176877
  if (mappedChanged) {
176646
176878
  this.pendingMappedChange = true;
176647
- logger248.debug(
176879
+ logger249.debug(
176648
176880
  `Mapped entity change detected for ${this.entityId}, forcing update`
176649
176881
  );
176650
176882
  }
176651
- logger248.debug(
176883
+ logger249.debug(
176652
176884
  `State update received for ${this.entityId}: state=${state.state}`
176653
176885
  );
176654
176886
  this.lastState = state;
@@ -176688,11 +176920,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176688
176920
  // src/services/bridges/server-mode-endpoint-manager.ts
176689
176921
  var MAX_SERVER_MODE_DEVICES = 10;
176690
176922
  var ServerModeEndpointManager = class extends Service {
176691
- constructor(serverNode, client, registry2, mappingStorage, identityStorage, dataProvider, log) {
176923
+ constructor(serverNode, client, registry3, mappingStorage, identityStorage, dataProvider, log) {
176692
176924
  super("ServerModeEndpointManager");
176693
176925
  this.serverNode = serverNode;
176694
176926
  this.client = client;
176695
- this.registry = registry2;
176927
+ this.registry = registry3;
176696
176928
  this.mappingStorage = mappingStorage;
176697
176929
  this.identityStorage = identityStorage;
176698
176930
  this.dataProvider = dataProvider;
@@ -177226,10 +177458,10 @@ var BridgeEnvironmentFactory = class extends BridgeFactory {
177226
177458
  // src/core/ioc/app-environment.ts
177227
177459
  var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177228
177460
  constructor(rootEnv, options) {
177229
- const logger250 = rootEnv.get(LoggerService);
177461
+ const logger251 = rootEnv.get(LoggerService);
177230
177462
  super({
177231
177463
  id: "App",
177232
- log: logger250.get("AppContainer"),
177464
+ log: logger251.get("AppContainer"),
177233
177465
  parent: rootEnv
177234
177466
  });
177235
177467
  this.options = options;
@@ -177243,8 +177475,8 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177243
177475
  }
177244
177476
  construction;
177245
177477
  async init() {
177246
- const logger250 = this.get(LoggerService);
177247
- this.set(LoggerService, logger250);
177478
+ const logger251 = this.get(LoggerService);
177479
+ this.set(LoggerService, logger251);
177248
177480
  this.set(AppStorage, new AppStorage(await this.load(StorageService)));
177249
177481
  this.set(BridgeStorage, new BridgeStorage(await this.load(AppStorage)));
177250
177482
  this.set(
@@ -177265,7 +177497,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177265
177497
  );
177266
177498
  this.set(
177267
177499
  HomeAssistantClient,
177268
- new HomeAssistantClient(logger250, this.options.homeAssistant)
177500
+ new HomeAssistantClient(logger251, this.options.homeAssistant)
177269
177501
  );
177270
177502
  this.set(
177271
177503
  HomeAssistantConfig,
@@ -177273,7 +177505,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177273
177505
  );
177274
177506
  this.set(
177275
177507
  HomeAssistantActions,
177276
- new HomeAssistantActions(logger250, await this.load(HomeAssistantClient))
177508
+ new HomeAssistantActions(logger251, await this.load(HomeAssistantClient))
177277
177509
  );
177278
177510
  this.set(
177279
177511
  HomeAssistantRegistry,
@@ -177309,7 +177541,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177309
177541
  this.set(
177310
177542
  WebApi,
177311
177543
  new WebApi(
177312
- logger250,
177544
+ logger251,
177313
177545
  await this.load(BridgeService),
177314
177546
  await this.load(HomeAssistantClient),
177315
177547
  await this.load(HomeAssistantRegistry),
@@ -177330,7 +177562,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177330
177562
 
177331
177563
  // src/matter/patches/patch-level-control-tlv.ts
177332
177564
  init_esm();
177333
- var logger249 = Logger.get("PatchLevelControlTlv");
177565
+ var logger250 = Logger.get("PatchLevelControlTlv");
177334
177566
  var optionalFieldModels = /* @__PURE__ */ new WeakSet();
177335
177567
  var fieldModelMandatoryGetterPatched = false;
177336
177568
  function patchLevelControlTlv() {
@@ -177386,11 +177618,11 @@ function patchLevelControlTlv() {
177386
177618
  patched++;
177387
177619
  }
177388
177620
  if (patched > 0) {
177389
- logger249.info(
177621
+ logger250.info(
177390
177622
  `Patched ${patched} LevelControl TLV schema(s): transitionTime is now optional (Google Home compatibility)`
177391
177623
  );
177392
177624
  } else {
177393
- logger249.warn(
177625
+ logger250.warn(
177394
177626
  "Failed to patch LevelControl TLV schemas, field definitions not found. Google Home brightness adjustment may not work.",
177395
177627
  {
177396
177628
  moveToLevel: describeFields(