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

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) {
@@ -169774,8 +169774,8 @@ var VacuumIdentifyServer = class extends IdentifyServer2 {
169774
169774
  #findIdentifyButton(homeAssistant) {
169775
169775
  const deviceId = homeAssistant.entity.registry?.device_id;
169776
169776
  if (!deviceId) return void 0;
169777
- const registry2 = this.env.get(HomeAssistantRegistry);
169778
- for (const entity of Object.values(registry2.entities)) {
169777
+ const registry3 = this.env.get(HomeAssistantRegistry);
169778
+ for (const entity of Object.values(registry3.entities)) {
169779
169779
  if (entity.device_id !== deviceId) continue;
169780
169780
  if (!entity.entity_id.startsWith("button.")) continue;
169781
169781
  const uniqueId = entity.unique_id ?? "";
@@ -172178,11 +172178,11 @@ function createEndpointId5(entityId, customName) {
172178
172178
  const baseName = customName || entityId;
172179
172179
  return baseName.replace(/\./g, "_").replace(/\s+/g, "_");
172180
172180
  }
172181
- function buildEntityPayload4(registry2, entityId) {
172182
- const state = registry2.initialStateIncludingUnfiltered(entityId);
172181
+ function buildEntityPayload4(registry3, entityId) {
172182
+ const state = registry3.initialStateIncludingUnfiltered(entityId);
172183
172183
  if (!state) return void 0;
172184
- const entity = registry2.entityIncludingUnfiltered(entityId);
172185
- const deviceRegistry = registry2.deviceOfIncludingUnfiltered(entityId);
172184
+ const entity = registry3.entityIncludingUnfiltered(entityId);
172185
+ const deviceRegistry = registry3.deviceOfIncludingUnfiltered(entityId);
172186
172186
  return {
172187
172187
  entity_id: entityId,
172188
172188
  state,
@@ -172198,8 +172198,8 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
172198
172198
  lastMappedStates = /* @__PURE__ */ new Map();
172199
172199
  debouncedUpdates = /* @__PURE__ */ new Map();
172200
172200
  static async create(config11) {
172201
- const { registry: registry2, primaryEntityId, composedEntities } = config11;
172202
- const primaryPayload = buildEntityPayload4(registry2, primaryEntityId);
172201
+ const { registry: registry3, primaryEntityId, composedEntities } = config11;
172202
+ const primaryPayload = buildEntityPayload4(registry3, primaryEntityId);
172203
172203
  if (!primaryPayload) return void 0;
172204
172204
  let parentType = BridgedNodeEndpoint.with(
172205
172205
  BasicInformationServer2,
@@ -172241,7 +172241,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
172241
172241
  primarySubPayload,
172242
172242
  primaryMapping,
172243
172243
  config11.areaName,
172244
- { vacuumOnOff: registry2.isVacuumOnOffEnabled() }
172244
+ { vacuumOnOff: registry3.isVacuumOnOffEnabled() }
172245
172245
  );
172246
172246
  if (!primaryType) {
172247
172247
  logger242.warn(
@@ -172257,7 +172257,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
172257
172257
  for (let i = 0; i < composedEntities.length; i++) {
172258
172258
  const sub = composedEntities[i];
172259
172259
  if (!sub.entityId) continue;
172260
- const subPayload = buildEntityPayload4(registry2, sub.entityId);
172260
+ const subPayload = buildEntityPayload4(registry3, sub.entityId);
172261
172261
  if (!subPayload) {
172262
172262
  logger242.warn(
172263
172263
  `Cannot find state for composed sub-entity ${sub.entityId}, it does not exist in Home Assistant (removed or renamed?)`
@@ -172419,32 +172419,32 @@ function asStandaloneEndpointType(type) {
172419
172419
  // src/matter/endpoints/legacy/legacy-endpoint.ts
172420
172420
  var logger243 = Logger.get("LegacyEndpoint");
172421
172421
  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);
172422
+ static async create(registry3, entityId, mapping, pluginDomainMappings, standalone = false, endpointId, identityAnchor) {
172423
+ const deviceRegistry = registry3.deviceOf(entityId);
172424
+ let state = registry3.initialState(entityId);
172425
+ const entity = registry3.entity(entityId);
172426
172426
  if (!state) {
172427
172427
  return;
172428
172428
  }
172429
- if (registry2.isAutoBatteryMappingEnabled() && registry2.isBatteryEntityUsed(entityId)) {
172429
+ if (registry3.isAutoBatteryMappingEnabled() && registry3.isBatteryEntityUsed(entityId)) {
172430
172430
  logger243.debug(
172431
172431
  `Skipping ${entityId} - already auto-assigned as battery to another device`
172432
172432
  );
172433
172433
  return;
172434
172434
  }
172435
- if (registry2.isAutoHumidityMappingEnabled() && registry2.isHumidityEntityUsed(entityId)) {
172435
+ if (registry3.isAutoHumidityMappingEnabled() && registry3.isHumidityEntityUsed(entityId)) {
172436
172436
  logger243.debug(
172437
172437
  `Skipping ${entityId} - already auto-assigned as humidity to a temperature sensor`
172438
172438
  );
172439
172439
  return;
172440
172440
  }
172441
- if (registry2.isAutoPressureMappingEnabled() && registry2.isPressureEntityUsed(entityId)) {
172441
+ if (registry3.isAutoPressureMappingEnabled() && registry3.isPressureEntityUsed(entityId)) {
172442
172442
  logger243.debug(
172443
172443
  `Skipping ${entityId} - already auto-assigned as pressure to a temperature sensor`
172444
172444
  );
172445
172445
  return;
172446
172446
  }
172447
- if (registry2.isAutoComposedDevicesEnabled() && registry2.isComposedSubEntityUsed(entityId)) {
172447
+ if (registry3.isAutoComposedDevicesEnabled() && registry3.isComposedSubEntityUsed(entityId)) {
172448
172448
  logger243.debug(
172449
172449
  `Skipping ${entityId} - already consumed by a composed device`
172450
172450
  );
@@ -172452,10 +172452,10 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172452
172452
  }
172453
172453
  let effectiveMapping = mapping;
172454
172454
  if (entity.device_id) {
172455
- if (registry2.isAutoHumidityMappingEnabled()) {
172455
+ if (registry3.isAutoHumidityMappingEnabled()) {
172456
172456
  const attrs = state.attributes;
172457
172457
  if (!mapping?.humidityEntity && entityId.startsWith("sensor.") && attrs.device_class === SensorDeviceClass.temperature) {
172458
- const humidityEntityId = registry2.findHumidityEntityForDevice(
172458
+ const humidityEntityId = registry3.findHumidityEntityForDevice(
172459
172459
  entity.device_id
172460
172460
  );
172461
172461
  if (humidityEntityId && humidityEntityId !== entityId) {
@@ -172464,17 +172464,17 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172464
172464
  entityId: effectiveMapping?.entityId ?? entityId,
172465
172465
  humidityEntity: humidityEntityId
172466
172466
  };
172467
- registry2.markHumidityEntityUsed(humidityEntityId);
172467
+ registry3.markHumidityEntityUsed(humidityEntityId);
172468
172468
  logger243.debug(
172469
172469
  `Auto-assigned humidity ${humidityEntityId} to ${entityId}`
172470
172470
  );
172471
172471
  }
172472
172472
  }
172473
172473
  }
172474
- if (registry2.isAutoPressureMappingEnabled()) {
172474
+ if (registry3.isAutoPressureMappingEnabled()) {
172475
172475
  const attrs = state.attributes;
172476
172476
  if (!mapping?.pressureEntity && entityId.startsWith("sensor.") && attrs.device_class === SensorDeviceClass.temperature) {
172477
- const pressureEntityId = registry2.findPressureEntityForDevice(
172477
+ const pressureEntityId = registry3.findPressureEntityForDevice(
172478
172478
  entity.device_id
172479
172479
  );
172480
172480
  if (pressureEntityId && pressureEntityId !== entityId) {
@@ -172483,7 +172483,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172483
172483
  entityId: effectiveMapping?.entityId ?? entityId,
172484
172484
  pressureEntity: pressureEntityId
172485
172485
  };
172486
- registry2.markPressureEntityUsed(pressureEntityId);
172486
+ registry3.markPressureEntityUsed(pressureEntityId);
172487
172487
  logger243.debug(
172488
172488
  `Auto-assigned pressure ${pressureEntityId} to ${entityId}`
172489
172489
  );
@@ -172491,8 +172491,8 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172491
172491
  }
172492
172492
  }
172493
172493
  const isVacuum = entityId.startsWith("vacuum.");
172494
- if ((registry2.isAutoBatteryMappingEnabled() || isVacuum) && !mapping?.batteryEntity && !mapping?.disableBatteryMapping) {
172495
- const batteryEntityId = registry2.findBatteryEntityForDevice(
172494
+ if ((registry3.isAutoBatteryMappingEnabled() || isVacuum) && !mapping?.batteryEntity && !mapping?.disableBatteryMapping) {
172495
+ const batteryEntityId = registry3.findBatteryEntityForDevice(
172496
172496
  entity.device_id
172497
172497
  );
172498
172498
  if (batteryEntityId && batteryEntityId !== entityId) {
@@ -172501,7 +172501,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172501
172501
  entityId: effectiveMapping?.entityId ?? entityId,
172502
172502
  batteryEntity: batteryEntityId
172503
172503
  };
172504
- registry2.markBatteryEntityUsed(batteryEntityId);
172504
+ registry3.markBatteryEntityUsed(batteryEntityId);
172505
172505
  logger243.debug(
172506
172506
  `Auto-assigned battery ${batteryEntityId} to ${entityId}`
172507
172507
  );
@@ -172509,8 +172509,8 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172509
172509
  }
172510
172510
  const alarmDeviceClass = state.attributes.device_class;
172511
172511
  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(
172512
+ if (registry3.isAutoBatteryMappingEnabled() && !mapping?.faultEntity && isSmokeCoAlarm) {
172513
+ const faultEntityId = registry3.findProblemEntityForDevice(
172514
172514
  entity.device_id
172515
172515
  );
172516
172516
  if (faultEntityId && faultEntityId !== entityId) {
@@ -172525,7 +172525,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172525
172525
  if (!mapping?.powerEntity) {
172526
172526
  const domain = entityId.split(".")[0];
172527
172527
  if (domain === "switch") {
172528
- const powerEntityId = registry2.findPowerEntityForDevice(
172528
+ const powerEntityId = registry3.findPowerEntityForDevice(
172529
172529
  entity.device_id
172530
172530
  );
172531
172531
  if (powerEntityId && powerEntityId !== entityId) {
@@ -172534,7 +172534,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172534
172534
  entityId: effectiveMapping?.entityId ?? entityId,
172535
172535
  powerEntity: powerEntityId
172536
172536
  };
172537
- registry2.markPowerEntityUsed(powerEntityId);
172537
+ registry3.markPowerEntityUsed(powerEntityId);
172538
172538
  logger243.debug(`Auto-assigned power ${powerEntityId} to ${entityId}`);
172539
172539
  }
172540
172540
  }
@@ -172542,7 +172542,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172542
172542
  if (!mapping?.energyEntity) {
172543
172543
  const domain = entityId.split(".")[0];
172544
172544
  if (domain === "switch") {
172545
- const energyEntityId = registry2.findEnergyEntityForDevice(
172545
+ const energyEntityId = registry3.findEnergyEntityForDevice(
172546
172546
  entity.device_id
172547
172547
  );
172548
172548
  if (energyEntityId && energyEntityId !== entityId) {
@@ -172551,7 +172551,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172551
172551
  entityId: effectiveMapping?.entityId ?? entityId,
172552
172552
  energyEntity: energyEntityId
172553
172553
  };
172554
- registry2.markEnergyEntityUsed(energyEntityId);
172554
+ registry3.markEnergyEntityUsed(energyEntityId);
172555
172555
  logger243.debug(
172556
172556
  `Auto-assigned energy ${energyEntityId} to ${entityId}`
172557
172557
  );
@@ -172559,7 +172559,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172559
172559
  }
172560
172560
  }
172561
172561
  if (entityId.startsWith("vacuum.")) {
172562
- const vacuumEntities = registry2.findVacuumSelectEntities(
172562
+ const vacuumEntities = registry3.findVacuumSelectEntities(
172563
172563
  entity.device_id
172564
172564
  );
172565
172565
  if (!effectiveMapping?.cleaningModeEntity && vacuumEntities.cleaningModeEntity) {
@@ -172603,7 +172603,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172603
172603
  );
172604
172604
  }
172605
172605
  const supportedFeatures = state.attributes.supported_features ?? 0;
172606
- const cleanAreaRooms = await registry2.resolveCleanAreaRooms(
172606
+ const cleanAreaRooms = await registry3.resolveCleanAreaRooms(
172607
172607
  entityId,
172608
172608
  supportedFeatures
172609
172609
  );
@@ -172619,7 +172619,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172619
172619
  }
172620
172620
  const vacAttrs = state.attributes;
172621
172621
  if (cleanAreaRooms.length === 0 && !vacAttrs.rooms && !vacAttrs.segments && !vacAttrs.room_mapping) {
172622
- const valetudoRooms = registry2.findValetudoMapSegments(
172622
+ const valetudoRooms = registry3.findValetudoMapSegments(
172623
172623
  entity.device_id
172624
172624
  );
172625
172625
  if (valetudoRooms.length > 0) {
@@ -172638,7 +172638,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172638
172638
  `Auto-detected ${valetudoRooms.length} Valetudo segments for ${entityId}`
172639
172639
  );
172640
172640
  } else {
172641
- const roborockRooms = await registry2.resolveRoborockRooms(entityId);
172641
+ const roborockRooms = await registry3.resolveRoborockRooms(entityId);
172642
172642
  if (roborockRooms.length > 0) {
172643
172643
  const roomsObj = {};
172644
172644
  for (const r of roborockRooms) {
@@ -172664,10 +172664,10 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172664
172664
  `Composed mappings are not supported in server mode, exposing ${entityId} as a flat standalone endpoint`
172665
172665
  );
172666
172666
  }
172667
- if (!standalone && registry2.isAutoComposedDevicesEnabled() && effectiveMapping?.composedEntities && effectiveMapping.composedEntities.length > 0) {
172668
- const composedAreaName = registry2.getAreaName(entityId);
172667
+ if (!standalone && registry3.isAutoComposedDevicesEnabled() && effectiveMapping?.composedEntities && effectiveMapping.composedEntities.length > 0) {
172668
+ const composedAreaName = registry3.getAreaName(entityId);
172669
172669
  const composed = await UserComposedEndpoint.create({
172670
- registry: registry2,
172670
+ registry: registry3,
172671
172671
  primaryEntityId: entityId,
172672
172672
  mapping: effectiveMapping,
172673
172673
  composedEntities: effectiveMapping.composedEntities,
@@ -172683,12 +172683,12 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172683
172683
  `User composed device creation failed for ${entityId}, falling back to standalone`
172684
172684
  );
172685
172685
  }
172686
- if (!standalone && registry2.isAutoComposedDevicesEnabled()) {
172686
+ if (!standalone && registry3.isAutoComposedDevicesEnabled()) {
172687
172687
  const attrs = state.attributes;
172688
172688
  if (entityId.startsWith("sensor.") && attrs.device_class === SensorDeviceClass.temperature && (effectiveMapping?.humidityEntity || effectiveMapping?.pressureEntity)) {
172689
- const composedAreaName = registry2.getAreaName(entityId);
172689
+ const composedAreaName = registry3.getAreaName(entityId);
172690
172690
  const composed = await ComposedSensorEndpoint.create({
172691
- registry: registry2,
172691
+ registry: registry3,
172692
172692
  primaryEntityId: entityId,
172693
172693
  humidityEntityId: effectiveMapping?.humidityEntity,
172694
172694
  pressureEntityId: effectiveMapping?.pressureEntity,
@@ -172704,12 +172704,12 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172704
172704
  }
172705
172705
  const resolvedMatterType = mapping?.matterDeviceType ?? (entityId.startsWith("fan.") ? "fan" : void 0);
172706
172706
  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);
172707
+ const temperatureEntityId = effectiveMapping?.temperatureEntity || (entity.device_id ? registry3.findTemperatureEntityForDevice(entity.device_id) : void 0);
172708
+ const humidityEntityId = effectiveMapping?.humidityEntity || (entity.device_id ? registry3.findHumidityEntityForDevice(entity.device_id) : void 0);
172709
172709
  if (temperatureEntityId || humidityEntityId) {
172710
- const composedAreaName = registry2.getAreaName(entityId);
172710
+ const composedAreaName = registry3.getAreaName(entityId);
172711
172711
  const composed = await ComposedAirPurifierEndpoint.create({
172712
- registry: registry2,
172712
+ registry: registry3,
172713
172713
  primaryEntityId: entityId,
172714
172714
  temperatureEntityId,
172715
172715
  humidityEntityId,
@@ -172731,9 +172731,9 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172731
172731
  if (!standalone && entityId.startsWith("climate.") && effectiveMapping?.climateExposeFan === true) {
172732
172732
  const climateFeatures = state.attributes.supported_features ?? 0;
172733
172733
  if ((climateFeatures & ClimateDeviceFeature.FAN_MODE) !== 0) {
172734
- const composedAreaName = registry2.getAreaName(entityId);
172734
+ const composedAreaName = registry3.getAreaName(entityId);
172735
172735
  const composed = await ComposedClimateFanEndpoint.create({
172736
- registry: registry2,
172736
+ registry: registry3,
172737
172737
  primaryEntityId: entityId,
172738
172738
  mapping: effectiveMapping,
172739
172739
  customName: effectiveMapping?.customName,
@@ -172758,7 +172758,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172758
172758
  let cleaningModeOptions;
172759
172759
  if (entityId.startsWith("vacuum.")) {
172760
172760
  if (effectiveMapping?.cleaningModeEntity) {
172761
- const cmState = registry2.initialState(
172761
+ const cmState = registry3.initialState(
172762
172762
  effectiveMapping.cleaningModeEntity
172763
172763
  );
172764
172764
  cleaningModeOptions = cmState?.attributes?.options;
@@ -172772,13 +172772,13 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
172772
172772
  ];
172773
172773
  }
172774
172774
  }
172775
- const areaName = registry2.getAreaName(entityId);
172775
+ const areaName = registry3.getAreaName(entityId);
172776
172776
  let type = createLegacyEndpointType(
172777
172777
  payload,
172778
172778
  effectiveMapping,
172779
172779
  areaName,
172780
172780
  {
172781
- vacuumOnOff: registry2.isVacuumOnOffEnabled(),
172781
+ vacuumOnOff: registry3.isVacuumOnOffEnabled(),
172782
172782
  cleaningModeOptions,
172783
172783
  pluginDomainMappings
172784
172784
  },
@@ -172960,27 +172960,181 @@ var CameraAvStreamServer = class extends Base4 {
172960
172960
  init_esm();
172961
172961
  init_esm7();
172962
172962
  init_esm3();
172963
- var logger244 = Logger.get("CameraWebRtc");
172963
+
172964
+ // src/plugins/builtin/camera/requestor-client.ts
172965
+ init_esm();
172966
+ init_esm4();
172967
+ var logger244 = Logger.get("CameraWebRtcRequestor");
172968
+ var registry2 = /* @__PURE__ */ new Map();
172969
+ var pendingDeliveries = /* @__PURE__ */ new Map();
172970
+ var invokeTransport = defaultInvoke;
172971
+ function registerRequestor(sessionId, registration) {
172972
+ registry2.set(sessionId, registration);
172973
+ }
172974
+ function unregisterRequestor(sessionId) {
172975
+ registry2.delete(sessionId);
172976
+ const timer = pendingDeliveries.get(sessionId);
172977
+ if (timer) {
172978
+ clearTimeout(timer);
172979
+ pendingDeliveries.delete(sessionId);
172980
+ }
172981
+ }
172982
+ function unregisterAllRequestors() {
172983
+ for (const id of [...registry2.keys()]) unregisterRequestor(id);
172984
+ for (const timer of pendingDeliveries.values()) clearTimeout(timer);
172985
+ pendingDeliveries.clear();
172986
+ }
172987
+ function deliverAnswerDeferred(sessionId, sdp, onGiveUp) {
172988
+ const prior = pendingDeliveries.get(sessionId);
172989
+ if (prior) clearTimeout(prior);
172990
+ const owner = registry2.get(sessionId);
172991
+ const timer = setTimeout(() => {
172992
+ void (async () => {
172993
+ try {
172994
+ for (const delayMs of [0, 250, 500]) {
172995
+ if (delayMs > 0) await new Promise((r) => setTimeout(r, delayMs));
172996
+ if (registry2.get(sessionId) !== owner || pendingDeliveries.get(sessionId) !== timer) {
172997
+ return;
172998
+ }
172999
+ if (await sendAnswer(sessionId, sdp)) {
173000
+ logger244.info(`answer delivered for session ${sessionId}`);
173001
+ return;
173002
+ }
173003
+ }
173004
+ if (registry2.get(sessionId) !== owner || pendingDeliveries.get(sessionId) !== timer) {
173005
+ return;
173006
+ }
173007
+ logger244.info(
173008
+ `answer delivery failed for session ${sessionId}, giving up`
173009
+ );
173010
+ await onGiveUp();
173011
+ } catch (err) {
173012
+ logger244.info(
173013
+ `answer delivery for session ${sessionId} threw: ${errText(err)}`
173014
+ );
173015
+ } finally {
173016
+ if (pendingDeliveries.get(sessionId) === timer) {
173017
+ pendingDeliveries.delete(sessionId);
173018
+ }
173019
+ }
173020
+ })();
173021
+ }, 0);
173022
+ timer.unref?.();
173023
+ pendingDeliveries.set(sessionId, timer);
173024
+ }
173025
+ function hasRequestor(sessionId) {
173026
+ return registry2.has(sessionId);
173027
+ }
173028
+ function sendAnswer(sessionId, sdp) {
173029
+ return invokeRequestor(sessionId, "answer", {
173030
+ webRtcSessionId: sessionId,
173031
+ sdp
173032
+ });
173033
+ }
173034
+ async function invokeRequestor(sessionId, command, fields) {
173035
+ const registration = registry2.get(sessionId);
173036
+ if (!registration) {
173037
+ logger244.info(`requestor ${command}: no session ${sessionId} registered`);
173038
+ return false;
173039
+ }
173040
+ if (registration.session.isClosed) {
173041
+ logger244.info(`requestor ${command}: session ${sessionId} already closed`);
173042
+ return false;
173043
+ }
173044
+ const request = {
173045
+ endpoint: registration.requestorEndpoint,
173046
+ cluster: WebRtcTransportRequestor3.Cluster,
173047
+ command,
173048
+ fields
173049
+ };
173050
+ try {
173051
+ return await invokeTransport({ registration, request });
173052
+ } catch (err) {
173053
+ logger244.info(
173054
+ `requestor ${command} failed for session ${sessionId}: ${errText(err)}`
173055
+ );
173056
+ return false;
173057
+ }
173058
+ }
173059
+ async function defaultInvoke({
173060
+ registration,
173061
+ request
173062
+ }) {
173063
+ const { session, env } = registration;
173064
+ const exchangeManager = env.get(ExchangeManager);
173065
+ const exchangeProvider = new DedicatedChannelExchangeProvider(
173066
+ exchangeManager,
173067
+ session
173068
+ );
173069
+ const client = new ClientInteraction({ environment: env, exchangeProvider });
173070
+ try {
173071
+ const result = client.invoke(
173072
+ Invoke({
173073
+ commands: [
173074
+ {
173075
+ endpoint: request.endpoint,
173076
+ cluster: request.cluster,
173077
+ command: request.command,
173078
+ // biome-ignore lint/suspicious/noExplicitAny: fields typed per command by caller
173079
+ fields: request.fields
173080
+ }
173081
+ ]
173082
+ })
173083
+ );
173084
+ for await (const chunk of result) {
173085
+ for (const entry of chunk) {
173086
+ if (entry.kind === "cmd-status") {
173087
+ if (entry.status !== Status2.Success) {
173088
+ logger244.info(
173089
+ `requestor ${request.command} status ${entry.status} for session ${String(request.fields.webRtcSessionId)}`
173090
+ );
173091
+ return false;
173092
+ }
173093
+ return true;
173094
+ }
173095
+ }
173096
+ }
173097
+ return true;
173098
+ } finally {
173099
+ await client.close().catch(() => {
173100
+ });
173101
+ }
173102
+ }
173103
+ function errText(err) {
173104
+ return err instanceof Error ? err.message : String(err);
173105
+ }
173106
+
173107
+ // src/plugins/builtin/camera/webrtc-provider-server.ts
173108
+ var logger245 = Logger.get("CameraWebRtc");
173109
+ var nextGlobalSessionId = 0;
173110
+ function mintSessionId() {
173111
+ for (let i = 0; i <= 65534; i++) {
173112
+ const id = nextGlobalSessionId;
173113
+ nextGlobalSessionId = nextGlobalSessionId >= 65534 ? 0 : nextGlobalSessionId + 1;
173114
+ if (!hasRequestor(id)) return id;
173115
+ }
173116
+ return nextGlobalSessionId;
173117
+ }
172964
173118
  var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
172965
173119
  solicitOffer(request) {
172966
- const id = this.state.nextSessionId++;
173120
+ const id = mintSessionId();
172967
173121
  this.trackSession(id, request.streamUsage, request.originatingEndpointId);
172968
- logger244.info(
173122
+ logger245.info(
172969
173123
  `solicitOffer session=${id} (${this.state.entityId}), deferred offer`
172970
173124
  );
172971
173125
  void this.state.bridge.startSession(id, this.state.entityId, {
172972
173126
  iceServers: request.iceServers,
172973
173127
  iceTransportPolicy: request.iceTransportPolicy
172974
173128
  }).catch(
172975
- (err) => logger244.info(
172976
- `solicitOffer startSession failed for ${this.state.entityId}: ${errText(err)}`
173129
+ (err) => logger245.info(
173130
+ `solicitOffer startSession failed for ${this.state.entityId}: ${errText2(err)}`
172977
173131
  )
172978
173132
  );
172979
173133
  return { webRtcSessionId: id, deferredOffer: true };
172980
173134
  }
172981
173135
  async provideOffer(request) {
172982
- const id = request.webRtcSessionId ?? this.state.nextSessionId++;
172983
- logger244.info(
173136
+ const id = request.webRtcSessionId ?? mintSessionId();
173137
+ logger245.info(
172984
173138
  `provideOffer entry: entityId=${this.state.entityId} session=${id} (sdp ${request.sdp.length} chars)`
172985
173139
  );
172986
173140
  if (request.webRtcSessionId == null) {
@@ -172990,6 +173144,15 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
172990
173144
  request.originatingEndpointId ?? EndpointNumber(0)
172991
173145
  );
172992
173146
  }
173147
+ const requestorEndpoint = request.originatingEndpointId ?? EndpointNumber(0);
173148
+ const session = this.context.session;
173149
+ if (session) {
173150
+ registerRequestor(id, {
173151
+ session,
173152
+ requestorEndpoint,
173153
+ env: this.env
173154
+ });
173155
+ }
172993
173156
  let answerSdp;
172994
173157
  try {
172995
173158
  answerSdp = await this.state.bridge.acceptControllerOffer(
@@ -173002,10 +173165,11 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
173002
173165
  }
173003
173166
  );
173004
173167
  } catch (err) {
173005
- const message = errText(err);
173006
- logger244.info(
173168
+ const message = errText2(err);
173169
+ logger245.info(
173007
173170
  `provideOffer failed for ${this.state.entityId} session=${id}: ${message}`
173008
173171
  );
173172
+ unregisterRequestor(id);
173009
173173
  this.state.currentSessions = this.state.currentSessions.filter(
173010
173174
  (s) => s.id !== id
173011
173175
  );
@@ -173014,14 +173178,26 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
173014
173178
  StatusCode.Failure
173015
173179
  );
173016
173180
  }
173017
- logger244.info(
173018
- `provideOffer answer computed for ${this.state.entityId} session=${id} (${answerSdp.length} chars); awaiting requestor delivery path`
173181
+ logger245.info(
173182
+ `provideOffer answer computed for ${this.state.entityId} session=${id} (${answerSdp.length} chars); delivering via requestor`
173019
173183
  );
173020
- void answerSdp;
173184
+ const bridge = this.state.bridge;
173185
+ const state = this.state;
173186
+ deliverAnswerDeferred(id, answerSdp, async () => {
173187
+ await bridge.endSession(id).catch(() => {
173188
+ });
173189
+ unregisterRequestor(id);
173190
+ try {
173191
+ state.currentSessions = state.currentSessions.filter(
173192
+ (s) => s.id !== id
173193
+ );
173194
+ } catch {
173195
+ }
173196
+ });
173021
173197
  return { webRtcSessionId: id };
173022
173198
  }
173023
173199
  provideAnswer(request) {
173024
- logger244.info(
173200
+ logger245.info(
173025
173201
  `provideAnswer session=${request.webRtcSessionId} (sdp ${request.sdp.length} chars, ${this.state.entityId})`
173026
173202
  );
173027
173203
  return this.state.bridge.acceptControllerAnswer(
@@ -173030,7 +173206,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
173030
173206
  );
173031
173207
  }
173032
173208
  async provideIceCandidates(request) {
173033
- logger244.info(
173209
+ logger245.info(
173034
173210
  `provideIceCandidates session=${request.webRtcSessionId}: ${request.iceCandidates.length} candidate(s) (${this.state.entityId})`
173035
173211
  );
173036
173212
  for (const c of request.iceCandidates) {
@@ -173043,16 +173219,21 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
173043
173219
  }
173044
173220
  }
173045
173221
  async endSession(request) {
173046
- logger244.info(
173222
+ logger245.info(
173047
173223
  `endSession session=${request.webRtcSessionId} (${this.state.entityId})`
173048
173224
  );
173049
173225
  await this.state.bridge.endSession(request.webRtcSessionId);
173226
+ unregisterRequestor(request.webRtcSessionId);
173050
173227
  this.state.currentSessions = this.state.currentSessions.filter(
173051
173228
  (s) => s.id !== request.webRtcSessionId
173052
173229
  );
173053
173230
  }
173054
173231
  trackSession(id, streamUsage, peerEndpointId) {
173055
173232
  const session = this.context.session;
173233
+ const fabricIndex = session?.associatedFabric?.fabricIndex;
173234
+ if (fabricIndex == null) {
173235
+ return;
173236
+ }
173056
173237
  this.state.currentSessions = [
173057
173238
  ...this.state.currentSessions,
173058
173239
  {
@@ -173061,19 +173242,18 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
173061
173242
  peerEndpointId,
173062
173243
  streamUsage,
173063
173244
  metadataEnabled: false,
173064
- fabricIndex: session?.associatedFabric?.fabricIndex ?? FabricIndex3(0)
173245
+ fabricIndex
173065
173246
  }
173066
173247
  ];
173067
173248
  }
173068
173249
  };
173069
- function errText(err) {
173250
+ function errText2(err) {
173070
173251
  return err instanceof Error ? err.message : String(err);
173071
173252
  }
173072
173253
  ((CameraWebRtcProviderServer2) => {
173073
173254
  class State extends WebRtcTransportProviderServer.State {
173074
173255
  bridge;
173075
173256
  entityId;
173076
- nextSessionId = 1;
173077
173257
  }
173078
173258
  CameraWebRtcProviderServer2.State = State;
173079
173259
  })(CameraWebRtcProviderServer || (CameraWebRtcProviderServer = {}));
@@ -173092,8 +173272,7 @@ function createCameraEndpointType(bridge, entityId, sensor = defaultSensorParams
173092
173272
  webRtcTransportProvider: {
173093
173273
  bridge,
173094
173274
  entityId,
173095
- currentSessions: [],
173096
- nextSessionId: 1
173275
+ currentSessions: []
173097
173276
  },
173098
173277
  cameraAvStreamManagement: {
173099
173278
  bridge,
@@ -173161,7 +173340,7 @@ import {
173161
173340
  createLongLivedTokenAuth as createLongLivedTokenAuth2
173162
173341
  } from "home-assistant-js-websocket";
173163
173342
  import { RTCPeerConnection } from "werift";
173164
- var logger245 = Logger.get("CameraWebRtc");
173343
+ var logger246 = Logger.get("CameraWebRtc");
173165
173344
  var DEFAULT_HA_WEBRTC_TIMEOUT_MS = 15e3;
173166
173345
  var haWebRtcTimeoutMs = DEFAULT_HA_WEBRTC_TIMEOUT_MS;
173167
173346
  var WebRtcBridge = class {
@@ -173200,6 +173379,7 @@ var WebRtcBridge = class {
173200
173379
  controllerPeer.addTransceiver("video", { direction: "sendonly" })
173201
173380
  );
173202
173381
  this.forwardHaTracks(haPeer, senders, entityId);
173382
+ await this.closeExistingPeers(matterSessionId);
173203
173383
  this.sessions.set(matterSessionId, { entityId, haPeer, controllerPeer });
173204
173384
  try {
173205
173385
  haPeer.addTransceiver("video", { direction: "recvonly" });
@@ -173207,7 +173387,7 @@ var WebRtcBridge = class {
173207
173387
  const haOffer = await haPeer.createOffer();
173208
173388
  await haPeer.setLocalDescription(haOffer);
173209
173389
  const haOfferSdp = this.localSdp(haPeer);
173210
- logger245.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
173390
+ logger246.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
173211
173391
  const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
173212
173392
  entityId,
173213
173393
  haOfferSdp,
@@ -173230,12 +173410,12 @@ var WebRtcBridge = class {
173230
173410
  const controllerOffer = await controllerPeer.createOffer();
173231
173411
  await controllerPeer.setLocalDescription(controllerOffer);
173232
173412
  const sdp = this.localSdp(controllerPeer);
173233
- logger245.info(
173413
+ logger246.info(
173234
173414
  `controller offer created for ${entityId} (${sdp.length} chars)`
173235
173415
  );
173236
173416
  return { sdp, iceCandidates };
173237
173417
  } catch (err) {
173238
- logger245.info(`startSession failed for ${entityId}: ${errText2(err)}`);
173418
+ logger246.info(`startSession failed for ${entityId}: ${errText3(err)}`);
173239
173419
  await this.endSession(matterSessionId);
173240
173420
  throw err;
173241
173421
  }
@@ -173257,6 +173437,7 @@ var WebRtcBridge = class {
173257
173437
  );
173258
173438
  }
173259
173439
  this.forwardHaTracks(haPeer, senders, entityId);
173440
+ await this.closeExistingPeers(matterSessionId);
173260
173441
  this.sessions.set(matterSessionId, { entityId, haPeer, controllerPeer });
173261
173442
  try {
173262
173443
  haPeer.addTransceiver("video", { direction: "recvonly" });
@@ -173264,7 +173445,7 @@ var WebRtcBridge = class {
173264
173445
  const haOffer = await haPeer.createOffer();
173265
173446
  await haPeer.setLocalDescription(haOffer);
173266
173447
  const haOfferSdp = this.localSdp(haPeer);
173267
- logger245.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
173448
+ logger246.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
173268
173449
  const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
173269
173450
  entityId,
173270
173451
  haOfferSdp,
@@ -173283,13 +173464,13 @@ var WebRtcBridge = class {
173283
173464
  const controllerAnswer = await controllerPeer.createAnswer();
173284
173465
  await controllerPeer.setLocalDescription(controllerAnswer);
173285
173466
  const answerSdp = this.localSdp(controllerPeer);
173286
- logger245.info(
173467
+ logger246.info(
173287
173468
  `controller answer created for ${entityId} (${answerSdp.length} chars)`
173288
173469
  );
173289
173470
  return answerSdp;
173290
173471
  } catch (err) {
173291
- logger245.info(
173292
- `acceptControllerOffer failed for ${entityId}: ${errText2(err)}`
173472
+ logger246.info(
173473
+ `acceptControllerOffer failed for ${entityId}: ${errText3(err)}`
173293
173474
  );
173294
173475
  await this.endSession(matterSessionId);
173295
173476
  throw err;
@@ -173299,14 +173480,14 @@ var WebRtcBridge = class {
173299
173480
  async acceptControllerAnswer(matterSessionId, sdp) {
173300
173481
  const session = this.sessions.get(matterSessionId);
173301
173482
  if (!session) return;
173302
- logger245.debug(`controller answer applied for ${session.entityId}`);
173483
+ logger246.debug(`controller answer applied for ${session.entityId}`);
173303
173484
  await session.controllerPeer.setRemoteDescription({ type: "answer", sdp });
173304
173485
  }
173305
173486
  /** Add a remote ICE candidate from the Matter controller. */
173306
173487
  async addControllerIceCandidate(matterSessionId, candidate, sdpMid, sdpMLineIndex) {
173307
173488
  const session = this.sessions.get(matterSessionId);
173308
173489
  if (!session) return;
173309
- logger245.debug(
173490
+ logger246.debug(
173310
173491
  `controller ICE candidate for ${session.entityId}: ${candidate}`
173311
173492
  );
173312
173493
  await session.controllerPeer.addIceCandidate({
@@ -173315,32 +173496,53 @@ var WebRtcBridge = class {
173315
173496
  sdpMLineIndex: sdpMLineIndex ?? void 0
173316
173497
  });
173317
173498
  }
173499
+ // Close the peers of a session we are about to overwrite. Leaves no map
173500
+ // entry; the caller replaces it with fresh peers under the same id.
173501
+ async closeExistingPeers(matterSessionId) {
173502
+ const prior = this.sessions.get(matterSessionId);
173503
+ if (!prior) return;
173504
+ logger246.info(
173505
+ `replacing session ${matterSessionId} (${prior.entityId}), closing prior peers`
173506
+ );
173507
+ if (prior.haUnsubscribe) {
173508
+ await Promise.resolve(prior.haUnsubscribe()).catch(
173509
+ (err) => logger246.debug(`HA unsubscribe failed: ${errText3(err)}`)
173510
+ );
173511
+ }
173512
+ await prior.haPeer.close().catch(() => {
173513
+ });
173514
+ await prior.controllerPeer.close().catch(() => {
173515
+ });
173516
+ await this.stopHaStream(prior).catch(() => {
173517
+ });
173518
+ }
173318
173519
  async endSession(matterSessionId) {
173319
173520
  const session = this.sessions.get(matterSessionId);
173320
173521
  if (!session) return;
173321
- logger245.info(`ending session ${matterSessionId} (${session.entityId})`);
173522
+ logger246.info(`ending session ${matterSessionId} (${session.entityId})`);
173322
173523
  this.sessions.delete(matterSessionId);
173323
173524
  if (session.haUnsubscribe) {
173324
173525
  await Promise.resolve(session.haUnsubscribe()).catch(
173325
- (err) => logger245.debug(`HA unsubscribe failed: ${errText2(err)}`)
173526
+ (err) => logger246.debug(`HA unsubscribe failed: ${errText3(err)}`)
173326
173527
  );
173327
173528
  }
173328
173529
  await session.haPeer.close().catch(() => {
173329
173530
  });
173330
173531
  await session.controllerPeer.close().catch(() => {
173331
173532
  });
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
- }
173533
+ await this.stopHaStream(session).catch(() => {
173534
+ });
173535
+ }
173536
+ // Tell HA to stop the stream if we tracked an HA session id. Best effort.
173537
+ async stopHaStream(session) {
173538
+ if (!session.haSessionId) return;
173539
+ const conn = await this.ha();
173540
+ await conn.sendMessagePromise({
173541
+ type: "camera/webrtc/candidate",
173542
+ entity_id: session.entityId,
173543
+ session_id: session.haSessionId,
173544
+ candidate: { candidate: "" }
173545
+ });
173344
173546
  }
173345
173547
  // Grab a still JPEG via HA's camera proxy (for CaptureSnapshot).
173346
173548
  async snapshot(entityId) {
@@ -173351,11 +173553,11 @@ var WebRtcBridge = class {
173351
173553
  headers: { Authorization: `Bearer ${this.config.haToken}` }
173352
173554
  });
173353
173555
  } catch (err) {
173354
- logger245.info(`snapshot fetch failed for ${entityId}: ${errText2(err)}`);
173556
+ logger246.info(`snapshot fetch failed for ${entityId}: ${errText3(err)}`);
173355
173557
  throw err;
173356
173558
  }
173357
173559
  if (!res.ok) {
173358
- logger245.info(
173560
+ logger246.info(
173359
173561
  `snapshot fetch failed for ${entityId}: camera_proxy ${res.status}`
173360
173562
  );
173361
173563
  throw new Error(`HA camera_proxy ${entityId}: ${res.status}`);
@@ -173372,10 +173574,10 @@ var WebRtcBridge = class {
173372
173574
  // Forward every track HA sends into the matching pre-added controller sender.
173373
173575
  forwardHaTracks(haPeer, senders, entityId) {
173374
173576
  haPeer.onTrack.subscribe((track) => {
173375
- logger245.info(`onTrack ${track.kind} from HA (${entityId})`);
173577
+ logger246.info(`onTrack ${track.kind} from HA (${entityId})`);
173376
173578
  const transceiver = senders.get(track.kind);
173377
173579
  if (!transceiver) {
173378
- logger245.info(
173580
+ logger246.info(
173379
173581
  `no controller transceiver for ${track.kind} (${entityId})`
173380
173582
  );
173381
173583
  return;
@@ -173384,7 +173586,7 @@ var WebRtcBridge = class {
173384
173586
  track.onReceiveRtp.subscribe((rtp) => {
173385
173587
  if (!firstLogged) {
173386
173588
  firstLogged = true;
173387
- logger245.info(`first RTP forwarded for ${track.kind} (${entityId})`);
173589
+ logger246.info(`first RTP forwarded for ${track.kind} (${entityId})`);
173388
173590
  }
173389
173591
  transceiver.sender.sendRtp(rtp);
173390
173592
  });
@@ -173393,10 +173595,10 @@ var WebRtcBridge = class {
173393
173595
  // Log connection/ice state transitions (these events fire on change only).
173394
173596
  wireStateLogging(peer, label, entityId) {
173395
173597
  peer.connectionStateChange.subscribe(
173396
- (s) => logger245.info(`${label} connectionState=${s} (${entityId})`)
173598
+ (s) => logger246.info(`${label} connectionState=${s} (${entityId})`)
173397
173599
  );
173398
173600
  peer.iceConnectionStateChange.subscribe(
173399
- (s) => logger245.info(`${label} iceConnectionState=${s} (${entityId})`)
173601
+ (s) => logger246.info(`${label} iceConnectionState=${s} (${entityId})`)
173400
173602
  );
173401
173603
  }
173402
173604
  // Map the Matter ICE struct onto werift's config. Only the controller peer
@@ -173410,11 +173612,11 @@ var WebRtcBridge = class {
173410
173612
  }))
173411
173613
  );
173412
173614
  if (iceServers.length === 0) {
173413
- logger245.info(`controller peer using default ICE servers (${entityId})`);
173615
+ logger246.info(`controller peer using default ICE servers (${entityId})`);
173414
173616
  return void 0;
173415
173617
  }
173416
173618
  const policy = ice?.iceTransportPolicy === "relay" || ice?.iceTransportPolicy === "all" ? ice.iceTransportPolicy : void 0;
173417
- logger245.info(
173619
+ logger246.info(
173418
173620
  `controller peer using ${iceServers.length} controller ICE server(s)${policy ? ` policy=${policy}` : ""} (${entityId})`
173419
173621
  );
173420
173622
  return policy ? { iceServers, iceTransportPolicy: policy } : { iceServers };
@@ -173428,14 +173630,14 @@ var WebRtcBridge = class {
173428
173630
  feedHaCandidate(entityId, haPeer, candidate) {
173429
173631
  const value = candidate?.candidate;
173430
173632
  if (!value) return;
173431
- logger245.debug(`HA ICE candidate for ${entityId}: ${value}`);
173633
+ logger246.debug(`HA ICE candidate for ${entityId}: ${value}`);
173432
173634
  void haPeer.addIceCandidate({
173433
173635
  candidate: value,
173434
173636
  sdpMid: candidate?.sdpMid ?? void 0,
173435
173637
  sdpMLineIndex: candidate?.sdpMLineIndex ?? void 0
173436
173638
  }).catch(
173437
- (e) => logger245.debug(
173438
- `HA addIceCandidate failed for ${entityId}: ${errText2(e)}`
173639
+ (e) => logger246.debug(
173640
+ `HA addIceCandidate failed for ${entityId}: ${errText3(e)}`
173439
173641
  )
173440
173642
  );
173441
173643
  }
@@ -173463,7 +173665,7 @@ var WebRtcBridge = class {
173463
173665
  reject(err);
173464
173666
  });
173465
173667
  timer = setTimeout(() => {
173466
- logger245.info(
173668
+ logger246.info(
173467
173669
  `HA WebRTC timed out after ${haWebRtcTimeoutMs}ms for ${entityId}`
173468
173670
  );
173469
173671
  fail(
@@ -173481,7 +173683,7 @@ var WebRtcBridge = class {
173481
173683
  if (msg.session_id) sessionId = msg.session_id;
173482
173684
  const ans = msg.answer;
173483
173685
  settle(() => {
173484
- logger245.info(
173686
+ logger246.info(
173485
173687
  `HA answer received for ${entityId} (${ans.length} chars)`
173486
173688
  );
173487
173689
  resolve11(ans);
@@ -173490,7 +173692,7 @@ var WebRtcBridge = class {
173490
173692
  break;
173491
173693
  case "error": {
173492
173694
  const detail = msg.message ?? msg.code ?? "unknown error";
173493
- logger245.info(`HA WebRTC error for ${entityId}: ${detail}`);
173695
+ logger246.info(`HA WebRTC error for ${entityId}: ${detail}`);
173494
173696
  fail(new Error(`HA WebRTC error: ${detail}`));
173495
173697
  break;
173496
173698
  }
@@ -173517,7 +173719,7 @@ function offerKinds(sdp) {
173517
173719
  }
173518
173720
  return kinds;
173519
173721
  }
173520
- function errText2(err) {
173722
+ function errText3(err) {
173521
173723
  return err instanceof Error ? err.message : String(err);
173522
173724
  }
173523
173725
 
@@ -173652,6 +173854,7 @@ var CameraPlugin = class {
173652
173854
  await this.bridge?.close().catch(() => {
173653
173855
  });
173654
173856
  this.bridge = void 0;
173857
+ unregisterAllRequestors();
173655
173858
  }
173656
173859
  };
173657
173860
 
@@ -173665,7 +173868,7 @@ import {
173665
173868
  getCollection
173666
173869
  } from "home-assistant-js-websocket";
173667
173870
  import { atLeastHaVersion } from "home-assistant-js-websocket/dist/util.js";
173668
- var logger246 = Logger.get("SubscribeEntities");
173871
+ var logger247 = Logger.get("SubscribeEntities");
173669
173872
  function processEvent(store, updates) {
173670
173873
  const state = { ...store.state };
173671
173874
  if (updates.a) {
@@ -173691,7 +173894,7 @@ function processEvent(store, updates) {
173691
173894
  for (const entityId in updates.c) {
173692
173895
  let entityState = state[entityId];
173693
173896
  if (!entityState) {
173694
- logger246.warn("Received state update for unknown entity", entityId);
173897
+ logger247.warn("Received state update for unknown entity", entityId);
173695
173898
  continue;
173696
173899
  }
173697
173900
  entityState = { ...entityState };
@@ -173780,7 +173983,7 @@ var subscribeEntities = (conn, onChange, entityIds) => {
173780
173983
  // src/services/bridges/entity-isolation-service.ts
173781
173984
  init_esm();
173782
173985
  init_diagnostic_event_bus();
173783
- var logger247 = Logger.get("EntityIsolation");
173986
+ var logger248 = Logger.get("EntityIsolation");
173784
173987
  var EntityIsolationServiceImpl = class {
173785
173988
  isolatedEntities = /* @__PURE__ */ new Map();
173786
173989
  isolationCallbacks = /* @__PURE__ */ new Map();
@@ -173845,13 +174048,13 @@ var EntityIsolationServiceImpl = class {
173845
174048
  }
173846
174049
  const parsed = this.parseEndpointPath(msg);
173847
174050
  if (!parsed) {
173848
- logger247.warn("Could not parse entity from error:", msg);
174051
+ logger248.warn("Could not parse entity from error:", msg);
173849
174052
  return false;
173850
174053
  }
173851
174054
  const { bridgeId, entityName } = parsed;
173852
174055
  const callback = this.isolationCallbacks.get(bridgeId);
173853
174056
  if (!callback) {
173854
- logger247.warn(
174057
+ logger248.warn(
173855
174058
  `No isolation callback registered for bridge ${bridgeId}, entity: ${entityName}`
173856
174059
  );
173857
174060
  return false;
@@ -173866,7 +174069,7 @@ var EntityIsolationServiceImpl = class {
173866
174069
  reason,
173867
174070
  failedAt: (/* @__PURE__ */ new Date()).toISOString()
173868
174071
  });
173869
- logger247.warn(
174072
+ logger248.warn(
173870
174073
  `Isolating entity "${entityName}" from bridge ${bridgeId} due to: ${reason}`
173871
174074
  );
173872
174075
  diagnosticEventBus.emit("entity_error", `Entity isolated: ${entityName}`, {
@@ -173878,7 +174081,7 @@ var EntityIsolationServiceImpl = class {
173878
174081
  await callback(entityName);
173879
174082
  return true;
173880
174083
  } catch (e) {
173881
- logger247.error(`Failed to isolate entity ${entityName}:`, e);
174084
+ logger248.error(`Failed to isolate entity ${entityName}:`, e);
173882
174085
  return false;
173883
174086
  }
173884
174087
  }
@@ -173911,10 +174114,10 @@ var EntityIsolationService = new EntityIsolationServiceImpl();
173911
174114
  var MAX_ENTITY_ID_LENGTH = 150;
173912
174115
  var ENDPOINT_REMOVAL_GRACE_MS = 6e4;
173913
174116
  var BridgeEndpointManager = class extends Service {
173914
- constructor(client, registry2, mappingStorage, identityStorage, bridgeId, log, pluginManager, pluginRegistry, pluginInstaller) {
174117
+ constructor(client, registry3, mappingStorage, identityStorage, bridgeId, log, pluginManager, pluginRegistry, pluginInstaller) {
173915
174118
  super("BridgeEndpointManager");
173916
174119
  this.client = client;
173917
- this.registry = registry2;
174120
+ this.registry = registry3;
173918
174121
  this.mappingStorage = mappingStorage;
173919
174122
  this.identityStorage = identityStorage;
173920
174123
  this.bridgeId = bridgeId;
@@ -174625,8 +174828,8 @@ init_send_ha_message();
174625
174828
  import { callService as callService2 } from "home-assistant-js-websocket";
174626
174829
  import { keys as keys2, pickBy, values as values3 } from "lodash-es";
174627
174830
  var BridgeRegistry = class _BridgeRegistry {
174628
- constructor(registry2, dataProvider, client) {
174629
- this.registry = registry2;
174831
+ constructor(registry3, dataProvider, client) {
174832
+ this.registry = registry3;
174630
174833
  this.dataProvider = dataProvider;
174631
174834
  this.client = client;
174632
174835
  this.refresh();
@@ -175396,11 +175599,11 @@ function makeWarmStartState(state, now = (/* @__PURE__ */ new Date()).toISOStrin
175396
175599
  return { ...state, last_updated: now };
175397
175600
  }
175398
175601
  var ServerModeBridge = class {
175399
- constructor(logger250, dataProvider, endpointManager, server) {
175602
+ constructor(logger251, dataProvider, endpointManager, server) {
175400
175603
  this.dataProvider = dataProvider;
175401
175604
  this.endpointManager = endpointManager;
175402
175605
  this.server = server;
175403
- this.log = logger250.get(`ServerModeBridge / ${dataProvider.id}`);
175606
+ this.log = logger251.get(`ServerModeBridge / ${dataProvider.id}`);
175404
175607
  }
175405
175608
  dataProvider;
175406
175609
  endpointManager;
@@ -176430,12 +176633,12 @@ function ServerModeVacuumDevice(homeAssistantEntity, includeOnOff = false, clean
176430
176633
  }
176431
176634
 
176432
176635
  // src/matter/endpoints/server-mode-vacuum-endpoint.ts
176433
- var logger248 = Logger.get("ServerModeVacuumEndpoint");
176636
+ var logger249 = Logger.get("ServerModeVacuumEndpoint");
176434
176637
  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);
176638
+ static async create(registry3, entityId, mapping, endpointId) {
176639
+ const deviceRegistry = registry3.deviceOf(entityId);
176640
+ let state = registry3.initialState(entityId);
176641
+ const entity = registry3.entity(entityId);
176439
176642
  if (!state) {
176440
176643
  return void 0;
176441
176644
  }
@@ -176443,12 +176646,12 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176443
176646
  if (mapping?.disableBatteryMapping && mapping.batteryEntity) {
176444
176647
  effectiveMapping = { ...mapping, batteryEntity: void 0 };
176445
176648
  }
176446
- logger248.info(
176649
+ logger249.info(
176447
176650
  `${entityId}: device_id=${entity.device_id}, manualBattery=${mapping?.batteryEntity ?? "none"}`
176448
176651
  );
176449
176652
  if (entity.device_id) {
176450
176653
  if (!mapping?.batteryEntity && !mapping?.disableBatteryMapping) {
176451
- const batteryEntityId = registry2.findBatteryEntityForDevice(
176654
+ const batteryEntityId = registry3.findBatteryEntityForDevice(
176452
176655
  entity.device_id
176453
176656
  );
176454
176657
  if (batteryEntityId && batteryEntityId !== entityId) {
@@ -176457,22 +176660,22 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176457
176660
  entityId: effectiveMapping?.entityId ?? entityId,
176458
176661
  batteryEntity: batteryEntityId
176459
176662
  };
176460
- registry2.markBatteryEntityUsed(batteryEntityId);
176461
- logger248.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
176663
+ registry3.markBatteryEntityUsed(batteryEntityId);
176664
+ logger249.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
176462
176665
  } else {
176463
176666
  const attrs = state.attributes;
176464
176667
  if (attrs.battery_level != null || attrs.battery != null) {
176465
- logger248.info(
176668
+ logger249.info(
176466
176669
  `${entityId}: No battery entity found, using battery attribute from vacuum state`
176467
176670
  );
176468
176671
  } else {
176469
- logger248.warn(
176672
+ logger249.warn(
176470
176673
  `${entityId}: No battery entity found for device ${entity.device_id}`
176471
176674
  );
176472
176675
  }
176473
176676
  }
176474
176677
  }
176475
- const vacuumEntities = registry2.findVacuumSelectEntities(
176678
+ const vacuumEntities = registry3.findVacuumSelectEntities(
176476
176679
  entity.device_id
176477
176680
  );
176478
176681
  if (!effectiveMapping?.cleaningModeEntity && vacuumEntities.cleaningModeEntity) {
@@ -176481,7 +176684,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176481
176684
  entityId: effectiveMapping?.entityId ?? entityId,
176482
176685
  cleaningModeEntity: vacuumEntities.cleaningModeEntity
176483
176686
  };
176484
- logger248.info(
176687
+ logger249.info(
176485
176688
  `${entityId}: Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity}`
176486
176689
  );
176487
176690
  }
@@ -176491,7 +176694,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176491
176694
  entityId: effectiveMapping?.entityId ?? entityId,
176492
176695
  suctionLevelEntity: vacuumEntities.suctionLevelEntity
176493
176696
  };
176494
- logger248.info(
176697
+ logger249.info(
176495
176698
  `${entityId}: Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity}`
176496
176699
  );
176497
176700
  }
@@ -176501,7 +176704,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176501
176704
  entityId: effectiveMapping?.entityId ?? entityId,
176502
176705
  mopIntensityEntity: vacuumEntities.mopIntensityEntity
176503
176706
  };
176504
- logger248.info(
176707
+ logger249.info(
176505
176708
  `${entityId}: Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity}`
176506
176709
  );
176507
176710
  }
@@ -176511,12 +176714,12 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176511
176714
  entityId: effectiveMapping?.entityId ?? entityId,
176512
176715
  currentRoomEntity: vacuumEntities.currentRoomEntity
176513
176716
  };
176514
- logger248.info(
176717
+ logger249.info(
176515
176718
  `${entityId}: Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity}`
176516
176719
  );
176517
176720
  }
176518
176721
  const supportedFeatures = state.attributes.supported_features ?? 0;
176519
- const cleanAreaRooms = await registry2.resolveCleanAreaRooms(
176722
+ const cleanAreaRooms = await registry3.resolveCleanAreaRooms(
176520
176723
  entityId,
176521
176724
  supportedFeatures
176522
176725
  );
@@ -176526,13 +176729,13 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176526
176729
  entityId: effectiveMapping?.entityId ?? entityId,
176527
176730
  cleanAreaRooms
176528
176731
  };
176529
- logger248.info(
176732
+ logger249.info(
176530
176733
  `${entityId}: Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA`
176531
176734
  );
176532
176735
  }
176533
176736
  const vacAttrs = state.attributes;
176534
176737
  if (cleanAreaRooms.length === 0 && !vacAttrs.rooms && !vacAttrs.segments && !vacAttrs.room_mapping) {
176535
- const valetudoRooms = registry2.findValetudoMapSegments(
176738
+ const valetudoRooms = registry3.findValetudoMapSegments(
176536
176739
  entity.device_id
176537
176740
  );
176538
176741
  if (valetudoRooms.length > 0) {
@@ -176547,11 +176750,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176547
176750
  rooms: roomsObj
176548
176751
  }
176549
176752
  };
176550
- logger248.info(
176753
+ logger249.info(
176551
176754
  `${entityId}: Auto-detected ${valetudoRooms.length} Valetudo segments`
176552
176755
  );
176553
176756
  } else {
176554
- const roborockRooms = await registry2.resolveRoborockRooms(entityId);
176757
+ const roborockRooms = await registry3.resolveRoborockRooms(entityId);
176555
176758
  if (roborockRooms.length > 0) {
176556
176759
  const roomsObj = {};
176557
176760
  for (const r of roborockRooms) {
@@ -176564,14 +176767,14 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176564
176767
  rooms: roomsObj
176565
176768
  }
176566
176769
  };
176567
- logger248.info(
176770
+ logger249.info(
176568
176771
  `${entityId}: Auto-detected ${roborockRooms.length} Roborock rooms`
176569
176772
  );
176570
176773
  }
176571
176774
  }
176572
176775
  }
176573
176776
  } else {
176574
- logger248.warn(`${entityId}: No device_id, cannot auto-assign battery`);
176777
+ logger249.warn(`${entityId}: No device_id, cannot auto-assign battery`);
176575
176778
  }
176576
176779
  const payload = {
176577
176780
  entity_id: entityId,
@@ -176582,7 +176785,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176582
176785
  const vacAttrsForClean = state.attributes;
176583
176786
  let cleaningModeOptions;
176584
176787
  if (effectiveMapping?.cleaningModeEntity) {
176585
- const cmState = registry2.initialState(
176788
+ const cmState = registry3.initialState(
176586
176789
  effectiveMapping.cleaningModeEntity
176587
176790
  );
176588
176791
  cleaningModeOptions = cmState?.attributes?.options;
@@ -176602,7 +176805,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176602
176805
  customName,
176603
176806
  mapping: effectiveMapping
176604
176807
  },
176605
- registry2.isServerModeVacuumOnOffEnabled(),
176808
+ registry3.isServerModeVacuumOnOffEnabled(),
176606
176809
  cleaningModeOptions
176607
176810
  );
176608
176811
  if (!endpointType) {
@@ -176644,11 +176847,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176644
176847
  }
176645
176848
  if (mappedChanged) {
176646
176849
  this.pendingMappedChange = true;
176647
- logger248.debug(
176850
+ logger249.debug(
176648
176851
  `Mapped entity change detected for ${this.entityId}, forcing update`
176649
176852
  );
176650
176853
  }
176651
- logger248.debug(
176854
+ logger249.debug(
176652
176855
  `State update received for ${this.entityId}: state=${state.state}`
176653
176856
  );
176654
176857
  this.lastState = state;
@@ -176688,11 +176891,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
176688
176891
  // src/services/bridges/server-mode-endpoint-manager.ts
176689
176892
  var MAX_SERVER_MODE_DEVICES = 10;
176690
176893
  var ServerModeEndpointManager = class extends Service {
176691
- constructor(serverNode, client, registry2, mappingStorage, identityStorage, dataProvider, log) {
176894
+ constructor(serverNode, client, registry3, mappingStorage, identityStorage, dataProvider, log) {
176692
176895
  super("ServerModeEndpointManager");
176693
176896
  this.serverNode = serverNode;
176694
176897
  this.client = client;
176695
- this.registry = registry2;
176898
+ this.registry = registry3;
176696
176899
  this.mappingStorage = mappingStorage;
176697
176900
  this.identityStorage = identityStorage;
176698
176901
  this.dataProvider = dataProvider;
@@ -177226,10 +177429,10 @@ var BridgeEnvironmentFactory = class extends BridgeFactory {
177226
177429
  // src/core/ioc/app-environment.ts
177227
177430
  var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177228
177431
  constructor(rootEnv, options) {
177229
- const logger250 = rootEnv.get(LoggerService);
177432
+ const logger251 = rootEnv.get(LoggerService);
177230
177433
  super({
177231
177434
  id: "App",
177232
- log: logger250.get("AppContainer"),
177435
+ log: logger251.get("AppContainer"),
177233
177436
  parent: rootEnv
177234
177437
  });
177235
177438
  this.options = options;
@@ -177243,8 +177446,8 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177243
177446
  }
177244
177447
  construction;
177245
177448
  async init() {
177246
- const logger250 = this.get(LoggerService);
177247
- this.set(LoggerService, logger250);
177449
+ const logger251 = this.get(LoggerService);
177450
+ this.set(LoggerService, logger251);
177248
177451
  this.set(AppStorage, new AppStorage(await this.load(StorageService)));
177249
177452
  this.set(BridgeStorage, new BridgeStorage(await this.load(AppStorage)));
177250
177453
  this.set(
@@ -177265,7 +177468,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177265
177468
  );
177266
177469
  this.set(
177267
177470
  HomeAssistantClient,
177268
- new HomeAssistantClient(logger250, this.options.homeAssistant)
177471
+ new HomeAssistantClient(logger251, this.options.homeAssistant)
177269
177472
  );
177270
177473
  this.set(
177271
177474
  HomeAssistantConfig,
@@ -177273,7 +177476,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177273
177476
  );
177274
177477
  this.set(
177275
177478
  HomeAssistantActions,
177276
- new HomeAssistantActions(logger250, await this.load(HomeAssistantClient))
177479
+ new HomeAssistantActions(logger251, await this.load(HomeAssistantClient))
177277
177480
  );
177278
177481
  this.set(
177279
177482
  HomeAssistantRegistry,
@@ -177309,7 +177512,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177309
177512
  this.set(
177310
177513
  WebApi,
177311
177514
  new WebApi(
177312
- logger250,
177515
+ logger251,
177313
177516
  await this.load(BridgeService),
177314
177517
  await this.load(HomeAssistantClient),
177315
177518
  await this.load(HomeAssistantRegistry),
@@ -177330,7 +177533,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
177330
177533
 
177331
177534
  // src/matter/patches/patch-level-control-tlv.ts
177332
177535
  init_esm();
177333
- var logger249 = Logger.get("PatchLevelControlTlv");
177536
+ var logger250 = Logger.get("PatchLevelControlTlv");
177334
177537
  var optionalFieldModels = /* @__PURE__ */ new WeakSet();
177335
177538
  var fieldModelMandatoryGetterPatched = false;
177336
177539
  function patchLevelControlTlv() {
@@ -177386,11 +177589,11 @@ function patchLevelControlTlv() {
177386
177589
  patched++;
177387
177590
  }
177388
177591
  if (patched > 0) {
177389
- logger249.info(
177592
+ logger250.info(
177390
177593
  `Patched ${patched} LevelControl TLV schema(s): transitionTime is now optional (Google Home compatibility)`
177391
177594
  );
177392
177595
  } else {
177393
- logger249.warn(
177596
+ logger250.warn(
177394
177597
  "Failed to patch LevelControl TLV schemas, field definitions not found. Google Home brightness adjustment may not work.",
177395
177598
  {
177396
177599
  moveToLevel: describeFields(