@riddix/hamh 2.1.0-alpha.830 → 2.1.0-alpha.832

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.
@@ -130689,7 +130689,14 @@ var init_controller_compat = __esm({
130689
130689
  google: "no",
130690
130690
  alexa: "unknown",
130691
130691
  aqara: "unknown",
130692
- note: "Power/energy is rarely shown unless it is on a smart plug."
130692
+ note: "SolarPower is only rendered standalone by SmartThings today."
130693
+ },
130694
+ 1300: {
130695
+ apple: "no",
130696
+ google: "yes",
130697
+ alexa: "no",
130698
+ aqara: "unknown",
130699
+ note: "ElectricalMeter shows in Google Home and SmartThings; Apple and Alexa do not surface standalone power/energy."
130693
130700
  },
130694
130701
  24: {
130695
130702
  apple: "no",
@@ -131529,6 +131536,12 @@ var init_bridge_config_schema = __esm({
131529
131536
  description: "When a controller drops all subscriptions, clean up the dead session and re-announce after 5 seconds instead of 60. Opt-in for Google Home users whose devices go offline after a cancelled subscription (#386). It shortens the offline window but cannot stop the controller from rejecting the subscription. Default off.",
131530
131537
  type: "boolean",
131531
131538
  default: false
131539
+ },
131540
+ stableIdentity: {
131541
+ title: "Stable Device Identity",
131542
+ description: "Anchor each device to its Home Assistant entity registry id instead of the entity id, so renaming an entity no longer re-adds it in your controller (Alexa, Google Home, Apple Home) and keeps groups and automations. Records are seeded from the start, so enabling this later is safe and never re-adds existing devices. Default off.",
131543
+ type: "boolean",
131544
+ default: false
131532
131545
  }
131533
131546
  }
131534
131547
  };
@@ -132293,6 +132306,12 @@ var init_home_assistant_entity_behavior = __esm({
132293
132306
  customName;
132294
132307
  /** Entity mapping configuration (optional, used for advanced features like filter life sensor) */
132295
132308
  mapping;
132309
+ /**
132310
+ * Stable identity anchor for uniqueId/serialNumber. Set to the entity_id the
132311
+ * identity was first seeded under, so those stay frozen across HA renames.
132312
+ * Undefined falls back to the live entity_id (legacy behaviour).
132313
+ */
132314
+ identityAnchor;
132296
132315
  }
132297
132316
  HomeAssistantEntityBehavior2.State = State;
132298
132317
  class Events2 extends EventEmitter {
@@ -132616,6 +132635,10 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
132616
132635
  lockPinMaxLength: config11.lockPinMaxLength,
132617
132636
  powerEntity: config11.powerEntity,
132618
132637
  energyEntity: config11.energyEntity,
132638
+ voltageEntity: config11.voltageEntity,
132639
+ currentEntity: config11.currentEntity,
132640
+ batteryPowerEntity: config11.batteryPowerEntity,
132641
+ batteryEnergyEntity: config11.batteryEnergyEntity,
132619
132642
  suctionLevelEntity: config11.suctionLevelEntity,
132620
132643
  mopIntensityEntity: config11.mopIntensityEntity,
132621
132644
  valetudoIdentifier: config11.valetudoIdentifier,
@@ -132773,6 +132796,10 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
132773
132796
  lockPinMaxLength: config11.lockPinMaxLength,
132774
132797
  powerEntity: config11.powerEntity,
132775
132798
  energyEntity: config11.energyEntity,
132799
+ voltageEntity: config11.voltageEntity,
132800
+ currentEntity: config11.currentEntity,
132801
+ batteryPowerEntity: config11.batteryPowerEntity,
132802
+ batteryEnergyEntity: config11.batteryEnergyEntity,
132776
132803
  suctionLevelEntity: config11.suctionLevelEntity,
132777
132804
  mopIntensityEntity: config11.mopIntensityEntity,
132778
132805
  temperatureEntity: config11.temperatureEntity,
@@ -133576,7 +133603,7 @@ function diagnosticApi(bridgeService, haClient, haRegistry, version2, startTime)
133576
133603
 
133577
133604
  // src/api/entity-mapping-api.ts
133578
133605
  import express7 from "express";
133579
- function entityMappingApi(mappingStorage) {
133606
+ function entityMappingApi(mappingStorage, identityStorage) {
133580
133607
  const router = express7.Router();
133581
133608
  router.get("/:bridgeId", (req, res) => {
133582
133609
  const { bridgeId } = req.params;
@@ -133621,6 +133648,10 @@ function entityMappingApi(mappingStorage) {
133621
133648
  lockPinMaxLength: body.lockPinMaxLength,
133622
133649
  powerEntity: body.powerEntity,
133623
133650
  energyEntity: body.energyEntity,
133651
+ voltageEntity: body.voltageEntity,
133652
+ currentEntity: body.currentEntity,
133653
+ batteryPowerEntity: body.batteryPowerEntity,
133654
+ batteryEnergyEntity: body.batteryEnergyEntity,
133624
133655
  suctionLevelEntity: body.suctionLevelEntity,
133625
133656
  mopIntensityEntity: body.mopIntensityEntity,
133626
133657
  customServiceAreas: body.customServiceAreas,
@@ -133657,6 +133688,7 @@ function entityMappingApi(mappingStorage) {
133657
133688
  router.delete("/:bridgeId", async (req, res) => {
133658
133689
  const { bridgeId } = req.params;
133659
133690
  await mappingStorage.deleteBridgeMappings(bridgeId);
133691
+ await identityStorage.deleteBridgeIdentities(bridgeId);
133660
133692
  res.status(204).send();
133661
133693
  });
133662
133694
  return router;
@@ -134117,6 +134149,10 @@ function configToProfileEntry(config11) {
134117
134149
  lockPinMaxLength: config11.lockPinMaxLength,
134118
134150
  powerEntity: config11.powerEntity,
134119
134151
  energyEntity: config11.energyEntity,
134152
+ voltageEntity: config11.voltageEntity,
134153
+ currentEntity: config11.currentEntity,
134154
+ batteryPowerEntity: config11.batteryPowerEntity,
134155
+ batteryEnergyEntity: config11.batteryEnergyEntity,
134120
134156
  suctionLevelEntity: config11.suctionLevelEntity,
134121
134157
  mopIntensityEntity: config11.mopIntensityEntity,
134122
134158
  customServiceAreas: config11.customServiceAreas,
@@ -134252,6 +134288,10 @@ function mappingProfileApi(mappingStorage) {
134252
134288
  lockPinMaxLength: entry.lockPinMaxLength,
134253
134289
  powerEntity: entry.powerEntity,
134254
134290
  energyEntity: entry.energyEntity,
134291
+ voltageEntity: entry.voltageEntity,
134292
+ currentEntity: entry.currentEntity,
134293
+ batteryPowerEntity: entry.batteryPowerEntity,
134294
+ batteryEnergyEntity: entry.batteryEnergyEntity,
134255
134295
  suctionLevelEntity: entry.suctionLevelEntity,
134256
134296
  mopIntensityEntity: entry.mopIntensityEntity,
134257
134297
  customServiceAreas: entry.customServiceAreas,
@@ -134523,7 +134563,7 @@ function endpointToJson(endpoint, parentId) {
134523
134563
 
134524
134564
  // src/api/matter-api.ts
134525
134565
  var ajv = new Ajv();
134526
- function matterApi(bridgeService, haRegistry) {
134566
+ function matterApi(bridgeService, haRegistry, identityStorage) {
134527
134567
  const router = express11.Router();
134528
134568
  router.get("/", (_, res) => {
134529
134569
  res.status(200).json({});
@@ -134600,6 +134640,7 @@ function matterApi(bridgeService, haRegistry) {
134600
134640
  const bridgeId = req.params.bridgeId;
134601
134641
  try {
134602
134642
  await bridgeService.delete(bridgeId);
134643
+ await identityStorage?.deleteBridgeIdentities(bridgeId);
134603
134644
  res.status(204).send();
134604
134645
  } catch (e) {
134605
134646
  res.status(500).json({
@@ -134615,6 +134656,7 @@ function matterApi(bridgeService, haRegistry) {
134615
134656
  return;
134616
134657
  }
134617
134658
  try {
134659
+ await identityStorage?.deleteBridgeIdentities(bridgeId);
134618
134660
  await bridge.factoryReset();
134619
134661
  await bridge.start();
134620
134662
  res.status(200).json(bridge.data);
@@ -136597,13 +136639,14 @@ var WebSocketApi = class {
136597
136639
 
136598
136640
  // src/api/web-api.ts
136599
136641
  var WebApi = class extends Service {
136600
- constructor(logger245, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, lockCredentialStorage, settingsStorage, backupService, props) {
136642
+ constructor(logger245, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, identityStorage, lockCredentialStorage, settingsStorage, backupService, props) {
136601
136643
  super("WebApi");
136602
136644
  this.bridgeService = bridgeService;
136603
136645
  this.haClient = haClient;
136604
136646
  this.haRegistry = haRegistry;
136605
136647
  this.bridgeStorage = bridgeStorage;
136606
136648
  this.mappingStorage = mappingStorage;
136649
+ this.identityStorage = identityStorage;
136607
136650
  this.lockCredentialStorage = lockCredentialStorage;
136608
136651
  this.settingsStorage = settingsStorage;
136609
136652
  this.backupService = backupService;
@@ -136623,6 +136666,7 @@ var WebApi = class extends Service {
136623
136666
  haRegistry;
136624
136667
  bridgeStorage;
136625
136668
  mappingStorage;
136669
+ identityStorage;
136626
136670
  lockCredentialStorage;
136627
136671
  settingsStorage;
136628
136672
  backupService;
@@ -136639,7 +136683,10 @@ var WebApi = class extends Service {
136639
136683
  }
136640
136684
  async initialize() {
136641
136685
  const api = express17.Router();
136642
- api.use(express17.json()).use(nocache()).use("/matter", matterApi(this.bridgeService, this.haRegistry)).use(
136686
+ api.use(express17.json()).use(nocache()).use(
136687
+ "/matter",
136688
+ matterApi(this.bridgeService, this.haRegistry, this.identityStorage)
136689
+ ).use(
136643
136690
  "/health",
136644
136691
  healthApi(
136645
136692
  this.bridgeService,
@@ -136650,7 +136697,10 @@ var WebApi = class extends Service {
136650
136697
  ).use("/bridges", bridgeExportApi(this.bridgeStorage)).use("/bridge-icons", bridgeIconApi(this.props.storageLocation)).use(
136651
136698
  "/device-images",
136652
136699
  deviceImageApi(this.props.storageLocation, this.haRegistry)
136653
- ).use("/entity-mappings", entityMappingApi(this.mappingStorage)).use("/mapping-profiles", mappingProfileApi(this.mappingStorage)).use("/lock-credentials", lockCredentialApi(this.lockCredentialStorage)).use(
136700
+ ).use(
136701
+ "/entity-mappings",
136702
+ entityMappingApi(this.mappingStorage, this.identityStorage)
136703
+ ).use("/mapping-profiles", mappingProfileApi(this.mappingStorage)).use("/lock-credentials", lockCredentialApi(this.lockCredentialStorage)).use(
136654
136704
  "/settings",
136655
136705
  settingsApi(this.settingsStorage, this.bridgeService, this.props.auth)
136656
136706
  ).use(
@@ -138355,9 +138405,112 @@ var BridgeStorage = class extends Service {
138355
138405
  }
138356
138406
  };
138357
138407
 
138358
- // src/services/storage/entity-mapping-storage.ts
138408
+ // src/services/storage/entity-identity-storage.ts
138359
138409
  init_service();
138360
138410
  var CURRENT_VERSION = 1;
138411
+ var PERSIST_DEBOUNCE_MS = 500;
138412
+ var EntityIdentityStorage = class extends Service {
138413
+ constructor(appStorage) {
138414
+ super("EntityIdentityStorage");
138415
+ this.appStorage = appStorage;
138416
+ }
138417
+ appStorage;
138418
+ storage;
138419
+ identities = /* @__PURE__ */ new Map();
138420
+ persistTimer = null;
138421
+ async initialize() {
138422
+ this.storage = this.appStorage.createContext("entity-identities");
138423
+ await this.load();
138424
+ }
138425
+ async dispose() {
138426
+ await this.flush();
138427
+ }
138428
+ async load() {
138429
+ const stored = await this.storage.get("data", {
138430
+ version: CURRENT_VERSION,
138431
+ identities: {}
138432
+ });
138433
+ if (!stored || Object.keys(stored).length === 0) {
138434
+ return;
138435
+ }
138436
+ const data = stored;
138437
+ if (data.version !== CURRENT_VERSION) {
138438
+ await this.migrate(data);
138439
+ return;
138440
+ }
138441
+ for (const [bridgeId, records] of Object.entries(data.identities)) {
138442
+ const bridgeMap = /* @__PURE__ */ new Map();
138443
+ for (const [key, record] of Object.entries(records)) {
138444
+ bridgeMap.set(key, record);
138445
+ }
138446
+ this.identities.set(bridgeId, bridgeMap);
138447
+ }
138448
+ }
138449
+ async migrate(data) {
138450
+ if (data.version < CURRENT_VERSION) {
138451
+ for (const [bridgeId, records] of Object.entries(data.identities)) {
138452
+ const bridgeMap = /* @__PURE__ */ new Map();
138453
+ for (const [key, record] of Object.entries(records)) {
138454
+ bridgeMap.set(key, record);
138455
+ }
138456
+ this.identities.set(bridgeId, bridgeMap);
138457
+ }
138458
+ await this.persist();
138459
+ }
138460
+ }
138461
+ async persist() {
138462
+ const data = {
138463
+ version: CURRENT_VERSION,
138464
+ identities: {}
138465
+ };
138466
+ for (const [bridgeId, bridgeMap] of this.identities) {
138467
+ const records = {};
138468
+ for (const [key, record] of bridgeMap) {
138469
+ records[key] = record;
138470
+ }
138471
+ data.identities[bridgeId] = records;
138472
+ }
138473
+ await this.storage.set("data", data);
138474
+ }
138475
+ schedulePersist() {
138476
+ if (this.persistTimer) return;
138477
+ this.persistTimer = setTimeout(() => {
138478
+ this.persistTimer = null;
138479
+ void this.persist();
138480
+ }, PERSIST_DEBOUNCE_MS);
138481
+ }
138482
+ // Flush any pending debounced write, used on dispose and by tests.
138483
+ async flush() {
138484
+ if (this.persistTimer) {
138485
+ clearTimeout(this.persistTimer);
138486
+ this.persistTimer = null;
138487
+ }
138488
+ await this.persist();
138489
+ }
138490
+ getIdentity(bridgeId, key) {
138491
+ return this.identities.get(bridgeId)?.get(key);
138492
+ }
138493
+ getBridgeIdentities(bridgeId) {
138494
+ return this.identities.get(bridgeId) ?? /* @__PURE__ */ new Map();
138495
+ }
138496
+ setIdentity(bridgeId, key, record) {
138497
+ let bridgeMap = this.identities.get(bridgeId);
138498
+ if (!bridgeMap) {
138499
+ bridgeMap = /* @__PURE__ */ new Map();
138500
+ this.identities.set(bridgeId, bridgeMap);
138501
+ }
138502
+ bridgeMap.set(key, record);
138503
+ this.schedulePersist();
138504
+ }
138505
+ async deleteBridgeIdentities(bridgeId) {
138506
+ this.identities.delete(bridgeId);
138507
+ await this.flush();
138508
+ }
138509
+ };
138510
+
138511
+ // src/services/storage/entity-mapping-storage.ts
138512
+ init_service();
138513
+ var CURRENT_VERSION2 = 1;
138361
138514
  var EntityMappingStorage = class extends Service {
138362
138515
  constructor(appStorage) {
138363
138516
  super("EntityMappingStorage");
@@ -138372,14 +138525,14 @@ var EntityMappingStorage = class extends Service {
138372
138525
  }
138373
138526
  async load() {
138374
138527
  const stored = await this.storage.get("data", {
138375
- version: CURRENT_VERSION,
138528
+ version: CURRENT_VERSION2,
138376
138529
  mappings: {}
138377
138530
  });
138378
138531
  if (!stored || Object.keys(stored).length === 0) {
138379
138532
  return;
138380
138533
  }
138381
138534
  const data = stored;
138382
- if (data.version !== CURRENT_VERSION) {
138535
+ if (data.version !== CURRENT_VERSION2) {
138383
138536
  await this.migrate(data);
138384
138537
  return;
138385
138538
  }
@@ -138392,7 +138545,7 @@ var EntityMappingStorage = class extends Service {
138392
138545
  }
138393
138546
  }
138394
138547
  async migrate(data) {
138395
- if (data.version < CURRENT_VERSION) {
138548
+ if (data.version < CURRENT_VERSION2) {
138396
138549
  for (const [bridgeId, configs] of Object.entries(data.mappings)) {
138397
138550
  const bridgeMap = /* @__PURE__ */ new Map();
138398
138551
  for (const config11 of configs) {
@@ -138405,7 +138558,7 @@ var EntityMappingStorage = class extends Service {
138405
138558
  }
138406
138559
  async persist() {
138407
138560
  const data = {
138408
- version: CURRENT_VERSION,
138561
+ version: CURRENT_VERSION2,
138409
138562
  mappings: {}
138410
138563
  };
138411
138564
  for (const [bridgeId, bridgeMap] of this.mappings) {
@@ -138455,6 +138608,10 @@ var EntityMappingStorage = class extends Service {
138455
138608
  lockPinMaxLength: pinLengths.max,
138456
138609
  powerEntity: request.powerEntity?.trim() || void 0,
138457
138610
  energyEntity: request.energyEntity?.trim() || void 0,
138611
+ voltageEntity: request.voltageEntity?.trim() || void 0,
138612
+ currentEntity: request.currentEntity?.trim() || void 0,
138613
+ batteryPowerEntity: request.batteryPowerEntity?.trim() || void 0,
138614
+ batteryEnergyEntity: request.batteryEnergyEntity?.trim() || void 0,
138458
138615
  pressureEntity: request.pressureEntity?.trim() || void 0,
138459
138616
  suctionLevelEntity: request.suctionLevelEntity?.trim() || void 0,
138460
138617
  mopIntensityEntity: request.mopIntensityEntity?.trim() || void 0,
@@ -138483,7 +138640,7 @@ var EntityMappingStorage = class extends Service {
138483
138640
  composedEntities: request.composedEntities?.filter((e) => e.entityId?.trim()) ?? void 0,
138484
138641
  disableMomentaryFlip: request.disableMomentaryFlip || void 0
138485
138642
  };
138486
- if (!config11.matterDeviceType && !config11.customName && !config11.customProductName && !config11.customVendorName && !config11.customSerialNumber && config11.customVendorId === void 0 && config11.disabled !== true && !config11.filterLifeEntity && !config11.cleaningModeEntity && !config11.temperatureEntity && !config11.humidityEntity && !config11.batteryEntity && !config11.disableBatteryMapping && !config11.chargingStateEntity && !config11.roomEntities && !config11.disableLockPin && !config11.lockUsercodeService && config11.lockUsercodeSlot === void 0 && config11.lockPinMinLength === void 0 && config11.lockPinMaxLength === void 0 && !config11.powerEntity && !config11.energyEntity && !config11.pressureEntity && !config11.suctionLevelEntity && !config11.mopIntensityEntity && (!config11.customServiceAreas || config11.customServiceAreas.length === 0) && (!config11.customFanSpeedTags || Object.keys(config11.customFanSpeedTags).length === 0) && (!config11.fanWindPresets || (config11.fanWindPresets.natural?.length ?? 0) === 0 && (config11.fanWindPresets.sleep?.length ?? 0) === 0) && !config11.fanRestoreSpeedOnPowerOn && !config11.currentRoomEntity && !config11.cleanedAreaEntity && !config11.disableCustomAreaRoomModes && !config11.valetudoIdentifier && !config11.coverSwapOpenClose && !config11.coverExposeAsDimmableLight && !config11.selectExposeAsSwitch && !config11.selectSwitchOnOption && !config11.selectSwitchOffOption && !config11.coverSliderDebounceMs && !config11.updateThrottleMs && !config11.disableClimateOnOff && !config11.disableClimateFanControl && !config11.climateKeepModeOnIdle && !config11.climateExposeFan && !config11.climateAutoMode && (!config11.composedEntities || config11.composedEntities.length === 0) && !config11.disableMomentaryFlip) {
138643
+ if (!config11.matterDeviceType && !config11.customName && !config11.customProductName && !config11.customVendorName && !config11.customSerialNumber && config11.customVendorId === void 0 && config11.disabled !== true && !config11.filterLifeEntity && !config11.cleaningModeEntity && !config11.temperatureEntity && !config11.humidityEntity && !config11.batteryEntity && !config11.disableBatteryMapping && !config11.chargingStateEntity && !config11.roomEntities && !config11.disableLockPin && !config11.lockUsercodeService && config11.lockUsercodeSlot === void 0 && config11.lockPinMinLength === void 0 && config11.lockPinMaxLength === void 0 && !config11.powerEntity && !config11.energyEntity && !config11.voltageEntity && !config11.currentEntity && !config11.batteryPowerEntity && !config11.batteryEnergyEntity && !config11.pressureEntity && !config11.suctionLevelEntity && !config11.mopIntensityEntity && (!config11.customServiceAreas || config11.customServiceAreas.length === 0) && (!config11.customFanSpeedTags || Object.keys(config11.customFanSpeedTags).length === 0) && (!config11.fanWindPresets || (config11.fanWindPresets.natural?.length ?? 0) === 0 && (config11.fanWindPresets.sleep?.length ?? 0) === 0) && !config11.fanRestoreSpeedOnPowerOn && !config11.currentRoomEntity && !config11.cleanedAreaEntity && !config11.disableCustomAreaRoomModes && !config11.valetudoIdentifier && !config11.coverSwapOpenClose && !config11.coverExposeAsDimmableLight && !config11.selectExposeAsSwitch && !config11.selectSwitchOnOption && !config11.selectSwitchOffOption && !config11.coverSliderDebounceMs && !config11.updateThrottleMs && !config11.disableClimateOnOff && !config11.disableClimateFanControl && !config11.climateKeepModeOnIdle && !config11.climateExposeFan && !config11.climateAutoMode && (!config11.composedEntities || config11.composedEntities.length === 0) && !config11.disableMomentaryFlip) {
138487
138644
  bridgeMap.delete(request.entityId);
138488
138645
  } else {
138489
138646
  bridgeMap.set(request.entityId, config11);
@@ -138565,7 +138722,7 @@ function sanitizeThrottleMs(value) {
138565
138722
  // src/services/storage/lock-credential-storage.ts
138566
138723
  init_service();
138567
138724
  import { pbkdf2Sync, randomBytes as randomBytes3, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
138568
- var CURRENT_VERSION2 = 2;
138725
+ var CURRENT_VERSION3 = 2;
138569
138726
  var HASH_ITERATIONS = 1e5;
138570
138727
  var HASH_KEY_LENGTH = 64;
138571
138728
  var HASH_ALGORITHM = "sha512";
@@ -138584,14 +138741,14 @@ var LockCredentialStorage = class extends Service {
138584
138741
  }
138585
138742
  async load() {
138586
138743
  const stored = await this.storage.get("data", {
138587
- version: CURRENT_VERSION2,
138744
+ version: CURRENT_VERSION3,
138588
138745
  credentials: []
138589
138746
  });
138590
138747
  if (!stored || Object.keys(stored).length === 0) {
138591
138748
  return;
138592
138749
  }
138593
138750
  const data = stored;
138594
- if (data.version !== CURRENT_VERSION2) {
138751
+ if (data.version !== CURRENT_VERSION3) {
138595
138752
  await this.migrate(data);
138596
138753
  return;
138597
138754
  }
@@ -138620,7 +138777,7 @@ var LockCredentialStorage = class extends Service {
138620
138777
  }
138621
138778
  async persist() {
138622
138779
  const data = {
138623
- version: CURRENT_VERSION2,
138780
+ version: CURRENT_VERSION3,
138624
138781
  credentials: Array.from(this.credentials.values())
138625
138782
  };
138626
138783
  await this.storage.set("data", data);
@@ -148297,6 +148454,7 @@ var ElectricalMeterDeviceDefinition = MutableEndpoint({
148297
148454
  behaviors: SupportedBehaviors()
148298
148455
  });
148299
148456
  Object.freeze(ElectricalMeterDeviceDefinition);
148457
+ var ElectricalMeterDevice = ElectricalMeterDeviceDefinition;
148300
148458
 
148301
148459
  // ../../node_modules/.pnpm/@matter+types@0.17.5/node_modules/@matter/types/dist/esm/clusters/meter-identification.js
148302
148460
  init_ClusterType();
@@ -156975,8 +157133,8 @@ var AggregatorEndpoint2 = class extends Endpoint {
156975
157133
  // src/matter/endpoints/entity-endpoint.ts
156976
157134
  init_esm7();
156977
157135
  var EntityEndpoint = class extends Endpoint {
156978
- constructor(type, entityId, customName, mappedEntityIds) {
156979
- super(type, { id: createEndpointId(entityId, customName) });
157136
+ constructor(type, entityId, customName, mappedEntityIds, endpointId) {
157137
+ super(type, { id: endpointId ?? createEndpointId(entityId, customName) });
156980
157138
  this.entityId = entityId;
156981
157139
  this.mappedEntityIds = mappedEntityIds ?? [];
156982
157140
  }
@@ -157018,6 +157176,10 @@ function getMappedEntityIds(mapping) {
157018
157176
  if (mapping.filterLifeEntity) ids.push(mapping.filterLifeEntity);
157019
157177
  if (mapping.powerEntity) ids.push(mapping.powerEntity);
157020
157178
  if (mapping.energyEntity) ids.push(mapping.energyEntity);
157179
+ if (mapping.voltageEntity) ids.push(mapping.voltageEntity);
157180
+ if (mapping.currentEntity) ids.push(mapping.currentEntity);
157181
+ if (mapping.batteryPowerEntity) ids.push(mapping.batteryPowerEntity);
157182
+ if (mapping.batteryEnergyEntity) ids.push(mapping.batteryEnergyEntity);
157021
157183
  if (mapping.currentRoomEntity) ids.push(mapping.currentRoomEntity);
157022
157184
  if (mapping.cleanedAreaEntity) ids.push(mapping.cleanedAreaEntity);
157023
157185
  if (mapping.composedEntities) {
@@ -157262,13 +157424,14 @@ var BasicInformationServer2 = class extends BridgedDeviceBasicInformationServer
157262
157424
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
157263
157425
  const device = entity.deviceRegistry;
157264
157426
  const mapping = homeAssistant.state.mapping;
157427
+ const anchor = homeAssistant.state.identityAnchor ?? entity.entity_id;
157265
157428
  const registryName = featureFlags?.preferEntityRegistryName ? entity.registry?.name ?? entity.registry?.original_name : void 0;
157266
157429
  const nodeLabel = ellipse(32, homeAssistant.state.customName) ?? ellipse(32, registryName) ?? ellipse(32, entity.state?.attributes?.friendly_name) ?? ellipse(32, entity.entity_id);
157267
157430
  const productNameFromNodeLabel = featureFlags?.productNameFromNodeLabel === true ? ellipse(32, sanitizeMatterString(nodeLabel ?? "")) ?? void 0 : void 0;
157268
157431
  const serialNumberSuffix = this.env.get(BridgeDataProvider).serialNumberSuffix;
157269
157432
  const maxRawLen = 32 - (serialNumberSuffix?.length ?? 0);
157270
157433
  const registrySerial = featureFlags?.useHaRegistrySerial ? ellipse(maxRawLen, device?.serial_number) : void 0;
157271
- const rawSerial = ellipse(maxRawLen, mapping?.customSerialNumber) ?? registrySerial ?? hash(maxRawLen, entity.entity_id);
157434
+ const rawSerial = ellipse(maxRawLen, mapping?.customSerialNumber) ?? registrySerial ?? hash(maxRawLen, anchor);
157272
157435
  const serialNumber = rawSerial && serialNumberSuffix ? `${rawSerial}${serialNumberSuffix}` : rawSerial;
157273
157436
  const customVendorId = mapping?.customVendorId;
157274
157437
  const vendorId3 = isValidVendorId(customVendorId) ? customVendorId : basicInformation.vendorId;
@@ -157288,18 +157451,18 @@ var BasicInformationServer2 = class extends BridgedDeviceBasicInformationServer
157288
157451
  // multiple fabric connections. Using MD5 hash of entity_id for stability.
157289
157452
  // uniqueIdSuffix mints a fresh identity so stale controller cloud
157290
157453
  // records keyed on it can be shed (#385).
157291
- uniqueId: this.frozenUniqueId(entity.entity_id)
157454
+ uniqueId: this.frozenUniqueId(anchor)
157292
157455
  });
157293
157456
  logger201.debug(
157294
157457
  `[${entity.entity_id}] basicInfo vendor=${this.state.vendorName} product=${this.state.productName} label=${this.state.productLabel} serial=${this.state.serialNumber} node=${this.state.nodeLabel} uniqueId=${this.state.uniqueId}`
157295
157458
  );
157296
157459
  }
157297
- frozenUniqueId(entityId) {
157460
+ frozenUniqueId(anchor) {
157298
157461
  const provider = this.env.get(BridgeDataProvider);
157299
- const key = `${provider.id}:${entityId}`;
157462
+ const key = `${provider.id}:${anchor}`;
157300
157463
  let uniqueId = appliedUniqueIds.get(key);
157301
157464
  if (uniqueId == null) {
157302
- uniqueId = crypto6.createHash("md5").update(entityId + (provider.uniqueIdSuffix ?? "")).digest("hex").substring(0, 32);
157465
+ uniqueId = crypto6.createHash("md5").update(anchor + (provider.uniqueIdSuffix ?? "")).digest("hex").substring(0, 32);
157303
157466
  appliedUniqueIds.set(key, uniqueId);
157304
157467
  }
157305
157468
  return uniqueId;
@@ -157459,7 +157622,8 @@ var HaElectricalEnergyMeasurementServer = ElectricalEnergyMeasurementServerBase.
157459
157622
  init_esm();
157460
157623
  init_home_assistant_entity_behavior();
157461
157624
  var logger203 = Logger.get("ElectricalPowerMeasurementServer");
157462
- var ElectricalPowerMeasurementServerBase = class extends ElectricalPowerMeasurementServer {
157625
+ var FeaturedBase2 = ElectricalPowerMeasurementServer.with("AlternatingCurrent");
157626
+ var ElectricalPowerMeasurementServerBase = class extends FeaturedBase2 {
157463
157627
  async initialize() {
157464
157628
  await super.initialize();
157465
157629
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
@@ -157475,23 +157639,38 @@ var ElectricalPowerMeasurementServerBase = class extends ElectricalPowerMeasurem
157475
157639
  }
157476
157640
  update() {
157477
157641
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
157478
- const powerEntity = homeAssistant.state.mapping?.powerEntity;
157479
- if (!powerEntity) return;
157642
+ const mapping = homeAssistant.state.mapping;
157643
+ const powerEntity = mapping?.powerEntity;
157644
+ const voltageEntity = mapping?.voltageEntity;
157645
+ const currentEntity = mapping?.currentEntity;
157646
+ if (!powerEntity && !voltageEntity && !currentEntity) return;
157480
157647
  const stateProvider = this.agent.env.get(EntityStateProvider);
157481
- const powerWatts = stateProvider.getNumericState(powerEntity);
157482
- if (powerWatts == null) return;
157483
- const activePower = Math.round(powerWatts * 1e3);
157484
- applyPatchState(this.state, { activePower });
157648
+ const patch = {};
157649
+ if (powerEntity) {
157650
+ const powerWatts = stateProvider.getNumericState(powerEntity);
157651
+ if (powerWatts != null) patch.activePower = Math.round(powerWatts * 1e3);
157652
+ }
157653
+ if (voltageEntity) {
157654
+ const volts = stateProvider.getNumericState(voltageEntity);
157655
+ if (volts != null) patch.voltage = Math.round(volts * 1e3);
157656
+ }
157657
+ if (currentEntity) {
157658
+ const amps = stateProvider.getNumericState(currentEntity);
157659
+ if (amps != null) patch.activeCurrent = Math.round(amps * 1e3);
157660
+ }
157661
+ if (Object.keys(patch).length > 0) applyPatchState(this.state, patch);
157485
157662
  }
157486
157663
  };
157487
157664
  ((ElectricalPowerMeasurementServerBase2) => {
157488
- class State extends ElectricalPowerMeasurementServer.State {
157665
+ class State extends FeaturedBase2.State {
157489
157666
  }
157490
157667
  ElectricalPowerMeasurementServerBase2.State = State;
157491
157668
  })(ElectricalPowerMeasurementServerBase || (ElectricalPowerMeasurementServerBase = {}));
157492
157669
  var HaElectricalPowerMeasurementServer = ElectricalPowerMeasurementServerBase.set({
157493
157670
  powerMode: ElectricalPowerMeasurement3.PowerMode.Ac,
157494
- numberOfMeasurementTypes: 1,
157671
+ // Voltage and current are folded onto this endpoint when mapped, so the
157672
+ // accuracy list carries an entry for each reported measurement type.
157673
+ numberOfMeasurementTypes: 3,
157495
157674
  accuracy: [
157496
157675
  {
157497
157676
  measurementType: ElectricalPowerMeasurement3.MeasurementType.ActivePower,
@@ -157508,6 +157687,37 @@ var HaElectricalPowerMeasurementServer = ElectricalPowerMeasurementServerBase.se
157508
157687
  // 1W accuracy
157509
157688
  }
157510
157689
  ]
157690
+ },
157691
+ {
157692
+ measurementType: ElectricalPowerMeasurement3.MeasurementType.Voltage,
157693
+ measured: true,
157694
+ minMeasuredValue: 0,
157695
+ maxMeasuredValue: 1e6,
157696
+ // 1000V in mV
157697
+ accuracyRanges: [
157698
+ {
157699
+ rangeMin: 0,
157700
+ rangeMax: 1e6,
157701
+ fixedMax: 1e3
157702
+ // 1V accuracy
157703
+ }
157704
+ ]
157705
+ },
157706
+ {
157707
+ measurementType: ElectricalPowerMeasurement3.MeasurementType.ActiveCurrent,
157708
+ measured: true,
157709
+ minMeasuredValue: -1e6,
157710
+ // -1000A in mA
157711
+ maxMeasuredValue: 1e6,
157712
+ // 1000A in mA
157713
+ accuracyRanges: [
157714
+ {
157715
+ rangeMin: -1e6,
157716
+ rangeMax: 1e6,
157717
+ fixedMax: 1e3
157718
+ // 1A accuracy
157719
+ }
157720
+ ]
157511
157721
  }
157512
157722
  ]
157513
157723
  });
@@ -157603,8 +157813,8 @@ function HumidityMeasurementServer(config11) {
157603
157813
  init_esm();
157604
157814
  init_home_assistant_entity_behavior();
157605
157815
  var logger205 = Logger.get("PowerSourceServer");
157606
- var FeaturedBase2 = PowerSourceServer.with("Battery", "Rechargeable");
157607
- var PowerSourceServerBase = class extends FeaturedBase2 {
157816
+ var FeaturedBase3 = PowerSourceServer.with("Battery", "Rechargeable");
157817
+ var PowerSourceServerBase = class extends FeaturedBase3 {
157608
157818
  async initialize() {
157609
157819
  await super.initialize();
157610
157820
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
@@ -157682,7 +157892,7 @@ var PowerSourceServerBase = class extends FeaturedBase2 {
157682
157892
  }
157683
157893
  };
157684
157894
  ((PowerSourceServerBase2) => {
157685
- class State extends FeaturedBase2.State {
157895
+ class State extends FeaturedBase3.State {
157686
157896
  config;
157687
157897
  }
157688
157898
  PowerSourceServerBase2.State = State;
@@ -157763,8 +157973,8 @@ function TemperatureMeasurementServer2(config11) {
157763
157973
 
157764
157974
  // src/matter/behaviors/hepa-filter-monitoring-server.ts
157765
157975
  init_home_assistant_entity_behavior();
157766
- var FeaturedBase3 = HepaFilterMonitoringServer.with("Condition", "Warning");
157767
- var HepaFilterMonitoringServerBase = class extends FeaturedBase3 {
157976
+ var FeaturedBase4 = HepaFilterMonitoringServer.with("Condition", "Warning");
157977
+ var HepaFilterMonitoringServerBase = class extends FeaturedBase4 {
157768
157978
  async initialize() {
157769
157979
  this.state.condition = 100;
157770
157980
  this.state.degradationDirection = ResourceMonitoring3.DegradationDirection.Down;
@@ -157801,7 +158011,7 @@ var HepaFilterMonitoringServerBase = class extends FeaturedBase3 {
157801
158011
  }
157802
158012
  };
157803
158013
  ((HepaFilterMonitoringServerBase2) => {
157804
- class State extends FeaturedBase3.State {
158014
+ class State extends FeaturedBase4.State {
157805
158015
  config;
157806
158016
  }
157807
158017
  HepaFilterMonitoringServerBase2.State = State;
@@ -158059,8 +158269,8 @@ function notifyLightTurnedOn(entityId) {
158059
158269
  lastTurnOnTimestamps.set(entityId, now);
158060
158270
  }
158061
158271
  var logger206 = Logger.get("LevelControlServer");
158062
- var FeaturedBase4 = LevelControlServer.with("OnOff", "Lighting");
158063
- var LevelControlServerBase = class extends FeaturedBase4 {
158272
+ var FeaturedBase5 = LevelControlServer.with("OnOff", "Lighting");
158273
+ var LevelControlServerBase = class extends FeaturedBase5 {
158064
158274
  pendingTransitionTime;
158065
158275
  async initialize() {
158066
158276
  if (this.state.currentLevel == null) {
@@ -158217,7 +158427,7 @@ var LevelControlServerBase = class extends FeaturedBase4 {
158217
158427
  }
158218
158428
  };
158219
158429
  ((LevelControlServerBase2) => {
158220
- class State extends FeaturedBase4.State {
158430
+ class State extends FeaturedBase5.State {
158221
158431
  config;
158222
158432
  }
158223
158433
  LevelControlServerBase2.State = State;
@@ -158359,7 +158569,7 @@ var logger208 = Logger.get("FanControlServer");
158359
158569
  var defaultStepSize = 33.33;
158360
158570
  var minSpeedMax = 3;
158361
158571
  var maxSpeedMax = 100;
158362
- var FeaturedBase5 = FanControlServer.with(
158572
+ var FeaturedBase6 = FanControlServer.with(
158363
158573
  "Step",
158364
158574
  "MultiSpeed",
158365
158575
  "AirflowDirection",
@@ -158369,7 +158579,7 @@ var FeaturedBase5 = FanControlServer.with(
158369
158579
  ).set({
158370
158580
  windSupport: { naturalWind: true, sleepWind: true }
158371
158581
  });
158372
- var FanControlServerBase = class extends FeaturedBase5 {
158582
+ var FanControlServerBase = class extends FeaturedBase6 {
158373
158583
  // Fallback last-speed tracking for endpoints without FanSpeedMemoryBehavior
158374
158584
  // (climate companion, humidifier). matter.js builds behavior instances per
158375
158585
  // transaction, so these fields only live within one interaction; fans use
@@ -158822,7 +159032,7 @@ var FanControlServerBase = class extends FeaturedBase5 {
158822
159032
  }
158823
159033
  };
158824
159034
  ((FanControlServerBase2) => {
158825
- class State extends FeaturedBase5.State {
159035
+ class State extends FeaturedBase6.State {
158826
159036
  config;
158827
159037
  }
158828
159038
  FanControlServerBase2.State = State;
@@ -159071,7 +159281,7 @@ var ComposedAirPurifierEndpoint = class _ComposedAirPurifierEndpoint extends End
159071
159281
  })
159072
159282
  );
159073
159283
  }
159074
- const endpointId = createEndpointId2(primaryEntityId, config11.customName);
159284
+ const endpointId = config11.endpointId ?? createEndpointId2(primaryEntityId, config11.customName);
159075
159285
  const parts = [];
159076
159286
  const airPurifierSub = new Endpoint(
159077
159287
  airPurifierSubType.set({
@@ -159116,7 +159326,8 @@ var ComposedAirPurifierEndpoint = class _ComposedAirPurifierEndpoint extends End
159116
159326
  homeAssistantEntity: {
159117
159327
  entity: primaryPayload,
159118
159328
  customName: config11.customName,
159119
- mapping: parentMapping
159329
+ mapping: parentMapping,
159330
+ identityAnchor: config11.identityAnchor
159120
159331
  }
159121
159332
  });
159122
159333
  const mappedIds = [];
@@ -160574,7 +160785,7 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
160574
160785
  const { registry: registry2, primaryEntityId } = config11;
160575
160786
  const payload = buildEntityPayload2(registry2, primaryEntityId);
160576
160787
  if (!payload) return void 0;
160577
- const endpointId = createEndpointId3(primaryEntityId, config11.customName);
160788
+ const endpointId = config11.endpointId ?? createEndpointId3(primaryEntityId, config11.customName);
160578
160789
  const mapping = config11.mapping ?? {
160579
160790
  entityId: primaryEntityId
160580
160791
  };
@@ -160618,7 +160829,8 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
160618
160829
  homeAssistantEntity: {
160619
160830
  entity: payload,
160620
160831
  customName: config11.customName,
160621
- mapping
160832
+ mapping,
160833
+ identityAnchor: config11.identityAnchor
160622
160834
  }
160623
160835
  });
160624
160836
  const endpoint = new _ComposedClimateFanEndpoint(
@@ -160882,7 +161094,7 @@ var ComposedSensorEndpoint = class _ComposedSensorEndpoint extends Endpoint {
160882
161094
  })
160883
161095
  );
160884
161096
  }
160885
- const endpointId = createEndpointId4(primaryEntityId, config11.customName);
161097
+ const endpointId = config11.endpointId ?? createEndpointId4(primaryEntityId, config11.customName);
160886
161098
  const parts = [];
160887
161099
  const tempSub = new Endpoint(
160888
161100
  TemperatureSubType2.set({
@@ -160924,7 +161136,8 @@ var ComposedSensorEndpoint = class _ComposedSensorEndpoint extends Endpoint {
160924
161136
  homeAssistantEntity: {
160925
161137
  entity: primaryPayload,
160926
161138
  customName: config11.customName,
160927
- mapping
161139
+ mapping,
161140
+ identityAnchor: config11.identityAnchor
160928
161141
  }
160929
161142
  });
160930
161143
  const mappedIds = [];
@@ -161821,7 +162034,7 @@ init_home_assistant_actions();
161821
162034
  init_home_assistant_entity_behavior();
161822
162035
  var logger216 = Logger.get("WindowCoveringServer");
161823
162036
  var MovementStatus = WindowCovering3.MovementStatus;
161824
- var FeaturedBase6 = WindowCoveringServer.with(
162037
+ var FeaturedBase7 = WindowCoveringServer.with(
161825
162038
  "Lift",
161826
162039
  "PositionAwareLift",
161827
162040
  "Tilt",
@@ -161857,7 +162070,7 @@ function clearPendingTilt(st) {
161857
162070
  }
161858
162071
  st.pendingTilt = null;
161859
162072
  }
161860
- var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedBase6 {
162073
+ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedBase7 {
161861
162074
  // Written and read within one synchronous command (upOrOpen fires lift then
161862
162075
  // tilt on the same instance), so these stay as instance fields (#246).
161863
162076
  lastLiftMovementMs = 0;
@@ -162166,7 +162379,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
162166
162379
  }
162167
162380
  };
162168
162381
  ((WindowCoveringServerBase2) => {
162169
- class State extends FeaturedBase6.State {
162382
+ class State extends FeaturedBase7.State {
162170
162383
  config;
162171
162384
  }
162172
162385
  WindowCoveringServerBase2.State = State;
@@ -163878,8 +164091,8 @@ function consumePendingColorStaging(entityId) {
163878
164091
  pendingColorStaging.delete(entityId);
163879
164092
  return data;
163880
164093
  }
163881
- var FeaturedBase7 = ColorControlServer.with("ColorTemperature", "HueSaturation", "Xy");
163882
- var ColorControlServerBase = class extends FeaturedBase7 {
164094
+ var FeaturedBase8 = ColorControlServer.with("ColorTemperature", "HueSaturation", "Xy");
164095
+ var ColorControlServerBase = class extends FeaturedBase8 {
163883
164096
  pendingTransitionTime;
163884
164097
  async [Symbol.asyncDispose]() {
163885
164098
  const entityId = this.agent.get(HomeAssistantEntityBehavior).entityId;
@@ -164224,7 +164437,7 @@ var ColorControlServerBase = class extends FeaturedBase7 {
164224
164437
  }
164225
164438
  };
164226
164439
  ((ColorControlServerBase2) => {
164227
- class State extends FeaturedBase7.State {
164440
+ class State extends FeaturedBase8.State {
164228
164441
  config;
164229
164442
  }
164230
164443
  ColorControlServerBase2.State = State;
@@ -164441,11 +164654,12 @@ function LightDevice(homeAssistantEntity) {
164441
164654
  ) : supportsBrightness ? hasBattery ? DimmableLightWithBatteryType : DimmableLightType : hasBattery ? OnOffLightWithBatteryType : OnOffLightType;
164442
164655
  const hasPowerEntity = !!homeAssistantEntity.mapping?.powerEntity;
164443
164656
  const hasEnergyEntity = !!homeAssistantEntity.mapping?.energyEntity;
164657
+ const hasElectricalPower = hasPowerEntity || !!homeAssistantEntity.mapping?.voltageEntity || !!homeAssistantEntity.mapping?.currentEntity;
164444
164658
  let device = deviceType;
164445
- if (hasPowerEntity || hasEnergyEntity) {
164659
+ if (hasElectricalPower || hasEnergyEntity) {
164446
164660
  device = device.with(HaPowerTopologyServer);
164447
164661
  }
164448
- if (hasPowerEntity) {
164662
+ if (hasElectricalPower) {
164449
164663
  device = device.with(HaElectricalPowerMeasurementServer);
164450
164664
  }
164451
164665
  if (hasEnergyEntity) {
@@ -165477,8 +165691,8 @@ function sweepOptimisticLevel2(now) {
165477
165691
  }
165478
165692
  }
165479
165693
  }
165480
- var FeaturedBase8 = LevelControlServer.with("OnOff");
165481
- var SpeakerLevelControlServerBase = class extends FeaturedBase8 {
165694
+ var FeaturedBase9 = LevelControlServer.with("OnOff");
165695
+ var SpeakerLevelControlServerBase = class extends FeaturedBase9 {
165482
165696
  async initialize() {
165483
165697
  if (this.state.currentLevel == null) {
165484
165698
  this.state.currentLevel = 0;
@@ -165580,7 +165794,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase8 {
165580
165794
  }
165581
165795
  };
165582
165796
  ((SpeakerLevelControlServerBase2) => {
165583
- class State extends FeaturedBase8.State {
165797
+ class State extends FeaturedBase9.State {
165584
165798
  config;
165585
165799
  }
165586
165800
  SpeakerLevelControlServerBase2.State = State;
@@ -166014,6 +166228,126 @@ var BatterySensorType = BatteryStorageDevice.with(
166014
166228
  })
166015
166229
  );
166016
166230
 
166231
+ // src/matter/endpoints/legacy/sensor/devices/battery-storage-ess.ts
166232
+ init_home_assistant_entity_behavior();
166233
+ var PowerFeaturedBase = ElectricalPowerMeasurementServer.with("DirectCurrent");
166234
+ var EssPowerServer = class extends PowerFeaturedBase {
166235
+ async initialize() {
166236
+ await super.initialize();
166237
+ const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
166238
+ this.update();
166239
+ this.reactTo(homeAssistant.onChange, this.update, { offline: true });
166240
+ }
166241
+ update() {
166242
+ const mapping = this.agent.get(HomeAssistantEntityBehavior).state.mapping;
166243
+ const powerEntity = mapping?.batteryPowerEntity;
166244
+ if (!powerEntity) return;
166245
+ const stateProvider = this.agent.env.get(EntityStateProvider);
166246
+ const watts = stateProvider.getNumericState(powerEntity);
166247
+ if (watts == null) return;
166248
+ applyPatchState(this.state, { activePower: Math.round(watts * -1e3) });
166249
+ }
166250
+ };
166251
+ ((EssPowerServer2) => {
166252
+ class State extends PowerFeaturedBase.State {
166253
+ }
166254
+ EssPowerServer2.State = State;
166255
+ })(EssPowerServer || (EssPowerServer = {}));
166256
+ var EssPower = EssPowerServer.set({
166257
+ powerMode: ElectricalPowerMeasurement3.PowerMode.Dc,
166258
+ numberOfMeasurementTypes: 1,
166259
+ // Seed 0 so the cluster reports a value before the first update (SmartThings).
166260
+ activePower: 0,
166261
+ accuracy: [
166262
+ {
166263
+ measurementType: ElectricalPowerMeasurement3.MeasurementType.ActivePower,
166264
+ measured: true,
166265
+ // Wide symmetric range: batteries both charge (negative) and discharge.
166266
+ minMeasuredValue: -1e8,
166267
+ maxMeasuredValue: 1e8,
166268
+ accuracyRanges: [
166269
+ {
166270
+ rangeMin: -1e8,
166271
+ rangeMax: 1e8,
166272
+ fixedMax: 1e3
166273
+ }
166274
+ ]
166275
+ }
166276
+ ]
166277
+ });
166278
+ var EnergyFeaturedBase = ElectricalEnergyMeasurementServer.with(
166279
+ "CumulativeEnergy",
166280
+ "ImportedEnergy"
166281
+ );
166282
+ var EssEnergyServer = class extends EnergyFeaturedBase {
166283
+ async initialize() {
166284
+ await super.initialize();
166285
+ const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
166286
+ this.update();
166287
+ this.reactTo(homeAssistant.onChange, this.update, { offline: true });
166288
+ }
166289
+ update() {
166290
+ const mapping = this.agent.get(HomeAssistantEntityBehavior).state.mapping;
166291
+ const energyEntity = mapping?.batteryEnergyEntity;
166292
+ if (!energyEntity) return;
166293
+ const stateProvider = this.agent.env.get(EntityStateProvider);
166294
+ const kwh = stateProvider.getNumericState(energyEntity);
166295
+ if (kwh == null) return;
166296
+ const energyImported = { energy: Math.round(kwh * 1e6) };
166297
+ const changed = applyPatchState(this.state, {
166298
+ cumulativeEnergyImported: energyImported
166299
+ });
166300
+ if ("cumulativeEnergyImported" in changed) {
166301
+ this.events.cumulativeEnergyMeasured?.emit(
166302
+ { energyImported, energyExported: void 0 },
166303
+ this.context
166304
+ );
166305
+ }
166306
+ }
166307
+ };
166308
+ ((EssEnergyServer2) => {
166309
+ class State extends EnergyFeaturedBase.State {
166310
+ }
166311
+ EssEnergyServer2.State = State;
166312
+ })(EssEnergyServer || (EssEnergyServer = {}));
166313
+ var EssEnergy = EssEnergyServer.set({
166314
+ cumulativeEnergyImported: { energy: 0 },
166315
+ accuracy: {
166316
+ measurementType: ElectricalPowerMeasurement3.MeasurementType.ElectricalEnergy,
166317
+ measured: true,
166318
+ minMeasuredValue: -1e6,
166319
+ maxMeasuredValue: 1e11,
166320
+ accuracyRanges: [
166321
+ {
166322
+ rangeMin: -1e6,
166323
+ rangeMax: 1e11,
166324
+ fixedMax: 1e3
166325
+ }
166326
+ ]
166327
+ }
166328
+ });
166329
+ var BatteryStorageEssBase = BatteryStorageDevice.with(
166330
+ BasicInformationServer2,
166331
+ IdentifyServer2,
166332
+ HomeAssistantEntityBehavior,
166333
+ HaPowerTopologyServer,
166334
+ PowerSourceServer2({
166335
+ getBatteryPercent(entity) {
166336
+ const state = entity.state;
166337
+ if (state == null || Number.isNaN(+state)) {
166338
+ return null;
166339
+ }
166340
+ return +state;
166341
+ }
166342
+ })
166343
+ );
166344
+ function batteryStorageEssType(mapping) {
166345
+ let device = BatteryStorageEssBase;
166346
+ if (mapping?.batteryPowerEntity) device = device.with(EssPower);
166347
+ if (mapping?.batteryEnergyEntity) device = device.with(EssEnergy);
166348
+ return device;
166349
+ }
166350
+
166017
166351
  // src/matter/behaviors/carbon-monoxide-concentration-measurement-server.ts
166018
166352
  init_home_assistant_entity_behavior();
166019
166353
  var CarbonMonoxideConcentrationMeasurementServerBase = CarbonMonoxideConcentrationMeasurementServer.with(
@@ -166105,10 +166439,14 @@ var CarbonMonoxideSensorType = AirQualitySensorDevice.with(
166105
166439
  CarbonMonoxideConcentrationMeasurementServer2
166106
166440
  );
166107
166441
 
166442
+ // src/matter/endpoints/legacy/sensor/devices/electrical-meter.ts
166443
+ init_home_assistant_entity_behavior();
166444
+
166108
166445
  // src/matter/endpoints/legacy/sensor/devices/electrical-sensor.ts
166109
166446
  init_dist();
166110
166447
  init_home_assistant_entity_behavior();
166111
- var StandalonePowerServer = class extends ElectricalPowerMeasurementServer {
166448
+ var PowerFeaturedBase2 = ElectricalPowerMeasurementServer.with("AlternatingCurrent");
166449
+ var StandalonePowerServer = class extends PowerFeaturedBase2 {
166112
166450
  async initialize() {
166113
166451
  await super.initialize();
166114
166452
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
@@ -166116,36 +166454,48 @@ var StandalonePowerServer = class extends ElectricalPowerMeasurementServer {
166116
166454
  this.reactTo(homeAssistant.onChange, this.update, { offline: true });
166117
166455
  }
166118
166456
  update(entity) {
166119
- if (!entity.state || !entity.state.attributes) {
166120
- return;
166121
- }
166122
- const state = entity.state.state;
166123
- if (state == null || Number.isNaN(+state)) return;
166124
- const attrs = entity.state.attributes;
166125
- const dc = attrs.device_class;
166126
- if (dc === SensorDeviceClass.power) {
166127
- applyPatchState(this.state, {
166128
- activePower: Math.round(+state * 1e3)
166129
- });
166130
- } else if (dc === SensorDeviceClass.voltage) {
166131
- applyPatchState(this.state, {
166132
- voltage: Math.round(+state * 1e3)
166133
- });
166134
- } else if (dc === SensorDeviceClass.current) {
166135
- applyPatchState(this.state, {
166136
- activeCurrent: Math.round(+state * 1e3)
166137
- });
166457
+ const patch = {};
166458
+ const attrs = entity.state?.attributes;
166459
+ const dc = attrs?.device_class;
166460
+ const primary = entity.state?.state;
166461
+ if (primary != null && !Number.isNaN(+primary)) {
166462
+ if (dc === SensorDeviceClass.power) {
166463
+ patch.activePower = Math.round(+primary * 1e3);
166464
+ } else if (dc === SensorDeviceClass.voltage) {
166465
+ patch.voltage = Math.round(+primary * 1e3);
166466
+ } else if (dc === SensorDeviceClass.current) {
166467
+ patch.activeCurrent = Math.round(+primary * 1e3);
166468
+ }
166469
+ }
166470
+ const mapping = this.agent.get(HomeAssistantEntityBehavior).state.mapping;
166471
+ if (mapping?.powerEntity || mapping?.voltageEntity || mapping?.currentEntity) {
166472
+ const stateProvider = this.agent.env.get(EntityStateProvider);
166473
+ if (mapping.powerEntity) {
166474
+ const w = stateProvider.getNumericState(mapping.powerEntity);
166475
+ if (w != null) patch.activePower = Math.round(w * 1e3);
166476
+ }
166477
+ if (mapping.voltageEntity) {
166478
+ const v = stateProvider.getNumericState(mapping.voltageEntity);
166479
+ if (v != null) patch.voltage = Math.round(v * 1e3);
166480
+ }
166481
+ if (mapping.currentEntity) {
166482
+ const a = stateProvider.getNumericState(mapping.currentEntity);
166483
+ if (a != null) patch.activeCurrent = Math.round(a * 1e3);
166484
+ }
166138
166485
  }
166486
+ if (Object.keys(patch).length > 0) applyPatchState(this.state, patch);
166139
166487
  }
166140
166488
  };
166141
166489
  ((StandalonePowerServer2) => {
166142
- class State extends ElectricalPowerMeasurementServer.State {
166490
+ class State extends PowerFeaturedBase2.State {
166143
166491
  }
166144
166492
  StandalonePowerServer2.State = State;
166145
166493
  })(StandalonePowerServer || (StandalonePowerServer = {}));
166146
166494
  var PowerServer = StandalonePowerServer.set({
166147
166495
  powerMode: ElectricalPowerMeasurement3.PowerMode.Ac,
166148
- numberOfMeasurementTypes: 1,
166496
+ // Power, voltage and current can all be folded onto this endpoint, so the
166497
+ // accuracy list carries an entry for each reported measurement type.
166498
+ numberOfMeasurementTypes: 3,
166149
166499
  // SmartThings keeps the endpoint in a "device not yet updated" state
166150
166500
  // when activePower stays null. Seed 0 so the cluster reports a value
166151
166501
  // for energy/voltage/current-only sensors that never feed activePower.
@@ -166163,14 +166513,43 @@ var PowerServer = StandalonePowerServer.set({
166163
166513
  fixedMax: 1e3
166164
166514
  }
166165
166515
  ]
166516
+ },
166517
+ {
166518
+ measurementType: ElectricalPowerMeasurement3.MeasurementType.Voltage,
166519
+ measured: true,
166520
+ minMeasuredValue: 0,
166521
+ maxMeasuredValue: 1e6,
166522
+ // 1000V in mV
166523
+ accuracyRanges: [
166524
+ {
166525
+ rangeMin: 0,
166526
+ rangeMax: 1e6,
166527
+ fixedMax: 1e3
166528
+ }
166529
+ ]
166530
+ },
166531
+ {
166532
+ measurementType: ElectricalPowerMeasurement3.MeasurementType.ActiveCurrent,
166533
+ measured: true,
166534
+ minMeasuredValue: -1e6,
166535
+ // -1000A in mA
166536
+ maxMeasuredValue: 1e6,
166537
+ // 1000A in mA
166538
+ accuracyRanges: [
166539
+ {
166540
+ rangeMin: -1e6,
166541
+ rangeMax: 1e6,
166542
+ fixedMax: 1e3
166543
+ }
166544
+ ]
166166
166545
  }
166167
166546
  ]
166168
166547
  });
166169
- var EnergyFeaturedBase = ElectricalEnergyMeasurementServer.with(
166548
+ var EnergyFeaturedBase2 = ElectricalEnergyMeasurementServer.with(
166170
166549
  "CumulativeEnergy",
166171
166550
  "ImportedEnergy"
166172
166551
  );
166173
- var StandaloneEnergyServer = class extends EnergyFeaturedBase {
166552
+ var StandaloneEnergyServer = class extends EnergyFeaturedBase2 {
166174
166553
  async initialize() {
166175
166554
  await super.initialize();
166176
166555
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
@@ -166178,32 +166557,39 @@ var StandaloneEnergyServer = class extends EnergyFeaturedBase {
166178
166557
  this.reactTo(homeAssistant.onChange, this.update, { offline: true });
166179
166558
  }
166180
166559
  update(entity) {
166181
- if (!entity.state || !entity.state.attributes) {
166182
- return;
166560
+ let energyKwh = null;
166561
+ const attrs = entity.state?.attributes;
166562
+ if (attrs?.device_class === SensorDeviceClass.energy) {
166563
+ const state = entity.state?.state;
166564
+ if (state != null && !Number.isNaN(+state)) energyKwh = +state;
166565
+ }
166566
+ const mapping = this.agent.get(HomeAssistantEntityBehavior).state.mapping;
166567
+ if (mapping?.energyEntity) {
166568
+ const stateProvider = this.agent.env.get(EntityStateProvider);
166569
+ const mapped = stateProvider.getNumericState(mapping.energyEntity);
166570
+ if (mapped != null) energyKwh = mapped;
166183
166571
  }
166184
- const attrs = entity.state.attributes;
166185
- if (attrs.device_class !== SensorDeviceClass.energy) return;
166186
- const state = entity.state.state;
166187
- if (state == null || Number.isNaN(+state)) return;
166188
- const energyMwh = Math.round(+state * 1e6);
166189
- const energyImported = { energy: energyMwh };
166190
- applyPatchState(this.state, {
166572
+ if (energyKwh == null) return;
166573
+ const energyImported = { energy: Math.round(energyKwh * 1e6) };
166574
+ const changed = applyPatchState(this.state, {
166191
166575
  cumulativeEnergyImported: energyImported
166192
166576
  });
166193
- this.events.cumulativeEnergyMeasured?.emit(
166194
- { energyImported, energyExported: void 0 },
166195
- this.context
166196
- );
166577
+ if ("cumulativeEnergyImported" in changed) {
166578
+ this.events.cumulativeEnergyMeasured?.emit(
166579
+ { energyImported, energyExported: void 0 },
166580
+ this.context
166581
+ );
166582
+ }
166197
166583
  }
166198
166584
  };
166199
166585
  ((StandaloneEnergyServer2) => {
166200
- class State extends EnergyFeaturedBase.State {
166586
+ class State extends EnergyFeaturedBase2.State {
166201
166587
  }
166202
166588
  StandaloneEnergyServer2.State = State;
166203
166589
  })(StandaloneEnergyServer || (StandaloneEnergyServer = {}));
166204
166590
  var EnergyServer = StandaloneEnergyServer.set({
166205
166591
  // Match the activePower=0 default so SmartThings doesn't show "- kWh"
166206
- // on a SolarPower endpoint whose mapped entity only carries power data.
166592
+ // on an endpoint whose mapped entity only carries power data.
166207
166593
  cumulativeEnergyImported: { energy: 0 },
166208
166594
  accuracy: {
166209
166595
  measurementType: ElectricalPowerMeasurement3.MeasurementType.ElectricalEnergy,
@@ -166228,6 +166614,15 @@ var ElectricalSensorType = SolarPowerDevice.with(
166228
166614
  EnergyServer
166229
166615
  );
166230
166616
 
166617
+ // src/matter/endpoints/legacy/sensor/devices/electrical-meter.ts
166618
+ var ElectricalMeterType = ElectricalMeterDevice.with(
166619
+ BasicInformationServer2,
166620
+ IdentifyServer2,
166621
+ HomeAssistantEntityBehavior,
166622
+ PowerServer,
166623
+ EnergyServer
166624
+ );
166625
+
166231
166626
  // src/matter/behaviors/flow-measurement-server.ts
166232
166627
  init_home_assistant_entity_behavior();
166233
166628
  var FlowMeasurementServerBase = class extends FlowMeasurementServer {
@@ -167595,9 +167990,12 @@ function SensorDevice(homeAssistantEntity) {
167595
167990
  return RadonSensorType.set({ homeAssistantEntity });
167596
167991
  }
167597
167992
  if (deviceClass === SensorDeviceClass.power || deviceClass === SensorDeviceClass.energy || deviceClass === SensorDeviceClass.voltage || deviceClass === SensorDeviceClass.current) {
167598
- return ElectricalSensorType.set({ homeAssistantEntity });
167993
+ return ElectricalMeterType.set({ homeAssistantEntity });
167599
167994
  }
167600
167995
  if (deviceClass === SensorDeviceClass.battery) {
167996
+ if (mapping?.batteryPowerEntity || mapping?.batteryEnergyEntity) {
167997
+ return batteryStorageEssType(mapping).set({ homeAssistantEntity });
167998
+ }
167601
167999
  return BatterySensorType.set({ homeAssistantEntity });
167602
168000
  }
167603
168001
  if (deviceClass) {
@@ -167671,11 +168069,12 @@ function SwitchDevice(homeAssistantEntity) {
167671
168069
  const hasBatteryEntity = !!homeAssistantEntity.mapping?.batteryEntity;
167672
168070
  const hasPowerEntity = !!homeAssistantEntity.mapping?.powerEntity;
167673
168071
  const hasEnergyEntity = !!homeAssistantEntity.mapping?.energyEntity;
168072
+ const hasElectricalPower = hasPowerEntity || !!homeAssistantEntity.mapping?.voltageEntity || !!homeAssistantEntity.mapping?.currentEntity;
167674
168073
  let device = hasBatteryAttr || hasBatteryEntity ? SwitchWithBatteryEndpointType : SwitchEndpointType;
167675
- if (hasPowerEntity || hasEnergyEntity) {
168074
+ if (hasElectricalPower || hasEnergyEntity) {
167676
168075
  device = device.with(HaPowerTopologyServer);
167677
168076
  }
167678
- if (hasPowerEntity) {
168077
+ if (hasElectricalPower) {
167679
168078
  device = device.with(HaElectricalPowerMeasurementServer);
167680
168079
  }
167681
168080
  if (hasEnergyEntity) {
@@ -169960,7 +170359,7 @@ function WeatherDevice(homeAssistant) {
169960
170359
 
169961
170360
  // src/matter/endpoints/legacy/create-legacy-endpoint-type.ts
169962
170361
  var legacyLogger = Logger.get("LegacyEndpointType");
169963
- function createLegacyEndpointType(entity, mapping, areaName, options) {
170362
+ function createLegacyEndpointType(entity, mapping, areaName, options, identityAnchor) {
169964
170363
  if (mapping?.disableBatteryMapping) {
169965
170364
  entity = {
169966
170365
  ...entity,
@@ -169973,11 +170372,12 @@ function createLegacyEndpointType(entity, mapping, areaName, options) {
169973
170372
  }
169974
170373
  const domain = entity.entity_id.split(".")[0];
169975
170374
  const customName = mapping?.customName;
170375
+ const ha = { entity, customName, mapping, identityAnchor };
169976
170376
  let type;
169977
170377
  if (mapping?.matterDeviceType) {
169978
170378
  const overrideFactory = matterDeviceTypeFactories[mapping.matterDeviceType];
169979
170379
  if (overrideFactory) {
169980
- type = overrideFactory({ entity, customName, mapping });
170380
+ type = overrideFactory(ha);
169981
170381
  if (type && mapping.batteryEntity && !hasPowerSource(type)) {
169982
170382
  type = addPowerSource(type);
169983
170383
  }
@@ -169986,14 +170386,14 @@ function createLegacyEndpointType(entity, mapping, areaName, options) {
169986
170386
  if (!type) {
169987
170387
  if (domain === "vacuum") {
169988
170388
  type = VacuumDevice(
169989
- { entity, customName, mapping },
170389
+ ha,
169990
170390
  options?.vacuumOnOff,
169991
170391
  options?.cleaningModeOptions
169992
170392
  );
169993
170393
  } else {
169994
170394
  const factory = deviceCtrs[domain];
169995
170395
  if (factory) {
169996
- type = factory({ entity, customName, mapping });
170396
+ type = factory(ha);
169997
170397
  } else if (options?.pluginDomainMappings?.has(domain)) {
169998
170398
  const mappedType = options.pluginDomainMappings.get(domain);
169999
170399
  const mappedFactory = matterDeviceTypeFactories[mappedType];
@@ -170001,7 +170401,7 @@ function createLegacyEndpointType(entity, mapping, areaName, options) {
170001
170401
  legacyLogger.info(
170002
170402
  `Using plugin domain mapping for "${domain}" \u2192 "${mappedType}"`
170003
170403
  );
170004
- type = mappedFactory({ entity, customName, mapping });
170404
+ type = mappedFactory(ha);
170005
170405
  }
170006
170406
  } else {
170007
170407
  return void 0;
@@ -170112,7 +170512,12 @@ var matterDeviceTypeFactories = {
170112
170512
  light_sensor: (ha) => IlluminanceSensorType.set({ homeAssistantEntity: ha }),
170113
170513
  flow_sensor: (ha) => FlowSensorType.set({ homeAssistantEntity: ha }),
170114
170514
  air_quality_sensor: (ha) => AirQualitySensorType.set({ homeAssistantEntity: ha }),
170115
- battery_storage: (ha) => BatterySensorType.set({ homeAssistantEntity: ha }),
170515
+ battery_storage: (ha) => {
170516
+ if (ha.mapping?.batteryPowerEntity || ha.mapping?.batteryEnergyEntity) {
170517
+ return batteryStorageEssType(ha.mapping).set({ homeAssistantEntity: ha });
170518
+ }
170519
+ return BatterySensorType.set({ homeAssistantEntity: ha });
170520
+ },
170116
170521
  tvoc_sensor: (ha) => TvocSensorType.set({ homeAssistantEntity: ha }),
170117
170522
  carbon_monoxide_sensor: (ha) => CarbonMonoxideSensorType.set({ homeAssistantEntity: ha }),
170118
170523
  nitrogen_dioxide_sensor: (ha) => NitrogenDioxideSensorType.set({ homeAssistantEntity: ha }),
@@ -170120,7 +170525,10 @@ var matterDeviceTypeFactories = {
170120
170525
  formaldehyde_sensor: (ha) => FormaldehydeSensorType.set({ homeAssistantEntity: ha }),
170121
170526
  radon_sensor: (ha) => RadonSensorType.set({ homeAssistantEntity: ha }),
170122
170527
  pm1_sensor: (ha) => Pm1SensorType.set({ homeAssistantEntity: ha }),
170528
+ electrical_meter: (ha) => ElectricalMeterType.set({ homeAssistantEntity: ha }),
170529
+ // Legacy SolarPower alias, kept for existing mappings.
170123
170530
  electrical_sensor: (ha) => ElectricalSensorType.set({ homeAssistantEntity: ha }),
170531
+ solar_power: (ha) => ElectricalSensorType.set({ homeAssistantEntity: ha }),
170124
170532
  contact_sensor: (ha) => ContactSensorType.set({ homeAssistantEntity: ha }),
170125
170533
  motion_sensor: (ha) => MotionSensorType.set({ homeAssistantEntity: ha }),
170126
170534
  occupancy_sensor: (ha) => OccupancySensorType.set({ homeAssistantEntity: ha }),
@@ -170186,7 +170594,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
170186
170594
  if (hasParentBattery) {
170187
170595
  parentType = parentType.with(DefaultPowerSourceServer);
170188
170596
  }
170189
- const endpointId = createEndpointId5(primaryEntityId, config11.customName);
170597
+ const endpointId = config11.endpointId ?? createEndpointId5(primaryEntityId, config11.customName);
170190
170598
  const parts = [];
170191
170599
  const subEndpointMap = /* @__PURE__ */ new Map();
170192
170600
  const mappedIds = [];
@@ -170264,7 +170672,8 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
170264
170672
  homeAssistantEntity: {
170265
170673
  entity: primaryPayload,
170266
170674
  customName: config11.customName,
170267
- mapping: config11.mapping
170675
+ mapping: config11.mapping,
170676
+ identityAnchor: config11.identityAnchor
170268
170677
  }
170269
170678
  });
170270
170679
  const endpoint = new _UserComposedEndpoint(
@@ -170386,7 +170795,7 @@ function asStandaloneEndpointType(type) {
170386
170795
  // src/matter/endpoints/legacy/legacy-endpoint.ts
170387
170796
  var logger240 = Logger.get("LegacyEndpoint");
170388
170797
  var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
170389
- static async create(registry2, entityId, mapping, pluginDomainMappings, standalone = false) {
170798
+ static async create(registry2, entityId, mapping, pluginDomainMappings, standalone = false, endpointId, identityAnchor) {
170390
170799
  const deviceRegistry = registry2.deviceOf(entityId);
170391
170800
  let state = registry2.initialState(entityId);
170392
170801
  const entity = registry2.entity(entityId);
@@ -170639,7 +171048,9 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
170639
171048
  mapping: effectiveMapping,
170640
171049
  composedEntities: effectiveMapping.composedEntities,
170641
171050
  customName: effectiveMapping?.customName,
170642
- areaName: composedAreaName
171051
+ areaName: composedAreaName,
171052
+ endpointId,
171053
+ identityAnchor
170643
171054
  });
170644
171055
  if (composed) {
170645
171056
  return composed;
@@ -170661,7 +171072,9 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
170661
171072
  powerEntityId: effectiveMapping?.powerEntity,
170662
171073
  energyEntityId: effectiveMapping?.energyEntity,
170663
171074
  customName: effectiveMapping?.customName,
170664
- areaName: composedAreaName
171075
+ areaName: composedAreaName,
171076
+ endpointId,
171077
+ identityAnchor
170665
171078
  });
170666
171079
  return composed;
170667
171080
  }
@@ -170681,7 +171094,9 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
170681
171094
  energyEntityId: effectiveMapping?.energyEntity,
170682
171095
  mapping: effectiveMapping,
170683
171096
  customName: effectiveMapping?.customName,
170684
- areaName: composedAreaName
171097
+ areaName: composedAreaName,
171098
+ endpointId,
171099
+ identityAnchor
170685
171100
  });
170686
171101
  if (composed) {
170687
171102
  return composed;
@@ -170698,7 +171113,9 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
170698
171113
  primaryEntityId: entityId,
170699
171114
  mapping: effectiveMapping,
170700
171115
  customName: effectiveMapping?.customName,
170701
- areaName: composedAreaName
171116
+ areaName: composedAreaName,
171117
+ endpointId,
171118
+ identityAnchor
170702
171119
  });
170703
171120
  if (composed) {
170704
171121
  return composed;
@@ -170732,11 +171149,17 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
170732
171149
  }
170733
171150
  }
170734
171151
  const areaName = registry2.getAreaName(entityId);
170735
- let type = createLegacyEndpointType(payload, effectiveMapping, areaName, {
170736
- vacuumOnOff: registry2.isVacuumOnOffEnabled(),
170737
- cleaningModeOptions,
170738
- pluginDomainMappings
170739
- });
171152
+ let type = createLegacyEndpointType(
171153
+ payload,
171154
+ effectiveMapping,
171155
+ areaName,
171156
+ {
171157
+ vacuumOnOff: registry2.isVacuumOnOffEnabled(),
171158
+ cleaningModeOptions,
171159
+ pluginDomainMappings
171160
+ },
171161
+ identityAnchor
171162
+ );
170740
171163
  if (!type) {
170741
171164
  return;
170742
171165
  }
@@ -170750,11 +171173,12 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
170750
171173
  entityId,
170751
171174
  customName,
170752
171175
  mappedIds,
170753
- effectiveMapping?.updateThrottleMs
171176
+ effectiveMapping?.updateThrottleMs,
171177
+ endpointId
170754
171178
  );
170755
171179
  }
170756
- constructor(type, entityId, customName, mappedEntityIds, throttleMs) {
170757
- super(type, entityId, customName, mappedEntityIds);
171180
+ constructor(type, entityId, customName, mappedEntityIds, throttleMs, endpointId) {
171181
+ super(type, entityId, customName, mappedEntityIds, endpointId);
170758
171182
  this.flushUpdate = throttleMs && throttleMs > 50 ? throttleLatest(this.flushPendingUpdate.bind(this), throttleMs) : debounce6(this.flushPendingUpdate.bind(this), 50);
170759
171183
  }
170760
171184
  lastState;
@@ -171601,11 +172025,124 @@ var EntityIsolationServiceImpl = class {
171601
172025
  };
171602
172026
  var EntityIsolationService = new EntityIsolationServiceImpl();
171603
172027
 
172028
+ // src/services/bridges/identity-resolver.ts
172029
+ var SEP = "\0";
172030
+ function identityKey(entity) {
172031
+ const uniqueId = entity.registry?.unique_id;
172032
+ const platform = entity.registry?.platform;
172033
+ if (!uniqueId || !platform) {
172034
+ return null;
172035
+ }
172036
+ const domain = entity.entity_id.split(".")[0];
172037
+ return platform + SEP + domain + SEP + uniqueId;
172038
+ }
172039
+ var IdentityResolver = class {
172040
+ constructor(identityStorage, mappingStorage) {
172041
+ this.identityStorage = identityStorage;
172042
+ this.mappingStorage = mappingStorage;
172043
+ }
172044
+ identityStorage;
172045
+ mappingStorage;
172046
+ async resolveIdentity(bridgeId, entity, mapping, opts) {
172047
+ const entityId = entity.entity_id;
172048
+ const key = identityKey(entity);
172049
+ if (key == null) {
172050
+ return {
172051
+ endpointId: createEndpointId(entityId, mapping?.customName),
172052
+ anchorEntityId: entityId,
172053
+ protected: false
172054
+ };
172055
+ }
172056
+ const existing = this.identityStorage.getIdentity(bridgeId, key);
172057
+ if (existing) {
172058
+ const renamedFrom = existing.lastEntityId !== entityId ? existing.lastEntityId ?? existing.anchorEntityId : void 0;
172059
+ if (opts.stableIdentity) {
172060
+ if (renamedFrom) {
172061
+ this.identityStorage.setIdentity(bridgeId, key, {
172062
+ ...existing,
172063
+ lastEntityId: entityId
172064
+ });
172065
+ await this.rekeyMapping(bridgeId, renamedFrom, entityId);
172066
+ }
172067
+ return {
172068
+ endpointId: existing.endpointId,
172069
+ anchorEntityId: existing.anchorEntityId,
172070
+ protected: true,
172071
+ renamedFrom
172072
+ };
172073
+ }
172074
+ const liveEndpointId = createEndpointId(entityId, mapping?.customName);
172075
+ if (existing.endpointId !== liveEndpointId || existing.anchorEntityId !== entityId || existing.lastEntityId !== entityId) {
172076
+ this.identityStorage.setIdentity(bridgeId, key, {
172077
+ ...existing,
172078
+ endpointId: liveEndpointId,
172079
+ anchorEntityId: entityId,
172080
+ lastEntityId: entityId
172081
+ });
172082
+ }
172083
+ return {
172084
+ endpointId: liveEndpointId,
172085
+ anchorEntityId: entityId,
172086
+ protected: false,
172087
+ renamedFrom
172088
+ };
172089
+ }
172090
+ const desired = createEndpointId(entityId, mapping?.customName);
172091
+ let endpointId = desired;
172092
+ if (opts.stableIdentity) {
172093
+ let n = 2;
172094
+ while (opts.isEndpointIdTaken(endpointId, key)) {
172095
+ endpointId = `${desired}_${n++}`;
172096
+ }
172097
+ }
172098
+ const record = {
172099
+ endpointId,
172100
+ anchorEntityId: entityId,
172101
+ lastEntityId: entityId,
172102
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
172103
+ };
172104
+ this.identityStorage.setIdentity(bridgeId, key, record);
172105
+ if (opts.stableIdentity) {
172106
+ return {
172107
+ endpointId: record.endpointId,
172108
+ anchorEntityId: record.anchorEntityId,
172109
+ protected: true
172110
+ };
172111
+ }
172112
+ return {
172113
+ endpointId: desired,
172114
+ anchorEntityId: entityId,
172115
+ protected: false
172116
+ };
172117
+ }
172118
+ // Carry a mapping from the old entity_id to the new one on rename. anchorEntityId
172119
+ // never changes, only the mapping key. Skips when no old mapping exists or a new
172120
+ // one already does, so a manual mapping under the new id is never clobbered.
172121
+ async rekeyMapping(bridgeId, oldEntityId, newEntityId) {
172122
+ if (oldEntityId === newEntityId) {
172123
+ return;
172124
+ }
172125
+ const old = this.mappingStorage.getMapping(bridgeId, oldEntityId);
172126
+ if (!old) {
172127
+ return;
172128
+ }
172129
+ if (this.mappingStorage.getMapping(bridgeId, newEntityId)) {
172130
+ return;
172131
+ }
172132
+ await this.mappingStorage.setMapping({
172133
+ ...old,
172134
+ bridgeId,
172135
+ entityId: newEntityId
172136
+ });
172137
+ await this.mappingStorage.deleteMapping(bridgeId, oldEntityId);
172138
+ }
172139
+ };
172140
+
171604
172141
  // src/services/bridges/bridge-endpoint-manager.ts
171605
172142
  var MAX_ENTITY_ID_LENGTH = 150;
171606
172143
  var ENDPOINT_REMOVAL_GRACE_MS = 6e4;
171607
172144
  var BridgeEndpointManager = class extends Service {
171608
- constructor(client, registry2, mappingStorage, bridgeId, log, pluginManager, pluginRegistry, pluginInstaller) {
172145
+ constructor(client, registry2, mappingStorage, identityStorage, bridgeId, log, pluginManager, pluginRegistry, pluginInstaller) {
171609
172146
  super("BridgeEndpointManager");
171610
172147
  this.client = client;
171611
172148
  this.registry = registry2;
@@ -171616,6 +172153,10 @@ var BridgeEndpointManager = class extends Service {
171616
172153
  this.pluginRegistry = pluginRegistry;
171617
172154
  this.pluginInstaller = pluginInstaller;
171618
172155
  this.root = new AggregatorEndpoint2("aggregator");
172156
+ this.identityResolver = new IdentityResolver(
172157
+ identityStorage,
172158
+ mappingStorage
172159
+ );
171619
172160
  EntityIsolationService.registerIsolationCallback(
171620
172161
  bridgeId,
171621
172162
  this.isolateEntity.bind(this)
@@ -171654,6 +172195,7 @@ var BridgeEndpointManager = class extends Service {
171654
172195
  failedAt: (/* @__PURE__ */ new Date()).toISOString()
171655
172196
  });
171656
172197
  }
172198
+ identityResolver;
171657
172199
  wirePluginCallbacks() {
171658
172200
  if (!this.pluginManager) return;
171659
172201
  this.pluginManager.onDeviceRegistered = async (pluginName, device) => {
@@ -171993,10 +172535,57 @@ var BridgeEndpointManager = class extends Service {
171993
172535
  if (humId) this.registry.markComposedSubEntityUsed(humId);
171994
172536
  }
171995
172537
  }
172538
+ const stableIdentity = this.registry.isStableIdentityEnabled();
172539
+ const resolvedByEntity = /* @__PURE__ */ new Map();
172540
+ const endpointIdToEntity = /* @__PURE__ */ new Map();
172541
+ const claimedEndpointIds = /* @__PURE__ */ new Map();
172542
+ for (const entityId of this.entityIds) {
172543
+ const entityInfo = {
172544
+ entity_id: entityId,
172545
+ registry: this.registry.entity(entityId)
172546
+ };
172547
+ const resolved = await this.identityResolver.resolveIdentity(
172548
+ this.bridgeId,
172549
+ entityInfo,
172550
+ this.getEntityMapping(entityId),
172551
+ {
172552
+ stableIdentity,
172553
+ isEndpointIdTaken: (id, key) => claimedEndpointIds.has(id) && claimedEndpointIds.get(id) !== key
172554
+ }
172555
+ );
172556
+ resolvedByEntity.set(entityId, resolved);
172557
+ claimedEndpointIds.set(
172558
+ resolved.endpointId,
172559
+ identityKey(entityInfo) ?? `\0e:${entityId}`
172560
+ );
172561
+ endpointIdToEntity.set(resolved.endpointId, entityId);
172562
+ if (resolved.renamedFrom && this.mappingFingerprints.has(resolved.renamedFrom)) {
172563
+ const fp = this.mappingFingerprints.get(resolved.renamedFrom);
172564
+ this.mappingFingerprints.delete(resolved.renamedFrom);
172565
+ this.mappingFingerprints.set(entityId, fp);
172566
+ }
172567
+ }
171996
172568
  const existingEndpoints = [];
171997
172569
  const now = Date.now();
171998
172570
  for (const endpoint of endpoints) {
171999
172571
  const present = this.entityIds.includes(endpoint.entityId);
172572
+ const claimant = endpointIdToEntity.get(endpoint.id);
172573
+ if (!present && claimant != null && claimant !== endpoint.entityId) {
172574
+ this.log.info(
172575
+ `Entity renamed ${endpoint.entityId} -> ${claimant}, keeping endpoint ${endpoint.id}`
172576
+ );
172577
+ try {
172578
+ await endpoint.close();
172579
+ } catch (e) {
172580
+ this.log.warn(
172581
+ `Failed to close renamed endpoint ${endpoint.entityId}:`,
172582
+ e
172583
+ );
172584
+ }
172585
+ this.pendingRemovals.delete(endpoint.entityId);
172586
+ this.mappingFingerprints.delete(endpoint.entityId);
172587
+ continue;
172588
+ }
172000
172589
  if (present) {
172001
172590
  this.pendingRemovals.delete(endpoint.entityId);
172002
172591
  }
@@ -172039,7 +172628,8 @@ var BridgeEndpointManager = class extends Service {
172039
172628
  this.log.info(
172040
172629
  `Mapping changed for ${endpoint.entityId}, recreating endpoint`
172041
172630
  );
172042
- const sameId = createEndpointId(endpoint.entityId, currentMapping?.customName) === endpoint.id;
172631
+ const resolvedId = resolvedByEntity.get(endpoint.entityId)?.endpointId ?? createEndpointId(endpoint.entityId, currentMapping?.customName);
172632
+ const sameId = resolvedId === endpoint.id;
172043
172633
  try {
172044
172634
  if (sameId) {
172045
172635
  await endpoint.close();
@@ -172097,11 +172687,15 @@ var BridgeEndpointManager = class extends Service {
172097
172687
  if (!endpoint) {
172098
172688
  try {
172099
172689
  const domainMappings = this.getPluginDomainMappings();
172690
+ const resolved = resolvedByEntity.get(entityId);
172100
172691
  endpoint = await LegacyEndpoint.create(
172101
172692
  this.registry,
172102
172693
  entityId,
172103
172694
  mapping,
172104
- domainMappings
172695
+ domainMappings,
172696
+ false,
172697
+ resolved?.endpointId,
172698
+ resolved?.anchorEntityId
172105
172699
  );
172106
172700
  } catch (e) {
172107
172701
  const reason = this.extractErrorReason(e);
@@ -172513,6 +173107,11 @@ var BridgeRegistry = class _BridgeRegistry {
172513
173107
  isVacuumOnOffEnabled() {
172514
173108
  return this.dataProvider.featureFlags?.vacuumOnOff === true;
172515
173109
  }
173110
+ // Consume frozen device identities (#404). Seeding always runs; only
173111
+ // consumption of the stored endpoint id/anchor is gated on this flag.
173112
+ isStableIdentityEnabled() {
173113
+ return this.dataProvider.featureFlags?.stableIdentity === true;
173114
+ }
172516
173115
  /**
172517
173116
  * Check if the vacuum OnOff cluster should be included for server-mode vacuums.
172518
173117
  * Defaults to OFF. OnOff is NOT part of the RoboticVacuumCleaner (0x74) device
@@ -173942,7 +174541,7 @@ function ServerModeVacuumDevice(homeAssistantEntity, includeOnOff = false, clean
173942
174541
  // src/matter/endpoints/server-mode-vacuum-endpoint.ts
173943
174542
  var logger243 = Logger.get("ServerModeVacuumEndpoint");
173944
174543
  var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEndpoint {
173945
- static async create(registry2, entityId, mapping) {
174544
+ static async create(registry2, entityId, mapping, endpointId) {
173946
174545
  const deviceRegistry = registry2.deviceOf(entityId);
173947
174546
  let state = registry2.initialState(entityId);
173948
174547
  const entity = registry2.entity(entityId);
@@ -174123,14 +174722,15 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
174123
174722
  endpointType,
174124
174723
  entityId,
174125
174724
  customName,
174126
- mappedIds
174725
+ mappedIds,
174726
+ endpointId
174127
174727
  );
174128
174728
  }
174129
174729
  lastState;
174130
174730
  pendingMappedChange = false;
174131
174731
  flushUpdate;
174132
- constructor(type, entityId, customName, mappedEntityIds) {
174133
- super(type, entityId, customName, mappedEntityIds);
174732
+ constructor(type, entityId, customName, mappedEntityIds, endpointId) {
174733
+ super(type, entityId, customName, mappedEntityIds, endpointId);
174134
174734
  this.flushUpdate = debounce7(this.flushPendingUpdate.bind(this), 50);
174135
174735
  }
174136
174736
  clearTimers() {
@@ -174197,7 +174797,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
174197
174797
  // src/services/bridges/server-mode-endpoint-manager.ts
174198
174798
  var MAX_SERVER_MODE_DEVICES = 10;
174199
174799
  var ServerModeEndpointManager = class extends Service {
174200
- constructor(serverNode, client, registry2, mappingStorage, dataProvider, log) {
174800
+ constructor(serverNode, client, registry2, mappingStorage, identityStorage, dataProvider, log) {
174201
174801
  super("ServerModeEndpointManager");
174202
174802
  this.serverNode = serverNode;
174203
174803
  this.client = client;
@@ -174205,6 +174805,10 @@ var ServerModeEndpointManager = class extends Service {
174205
174805
  this.mappingStorage = mappingStorage;
174206
174806
  this.dataProvider = dataProvider;
174207
174807
  this.log = log;
174808
+ this.identityResolver = new IdentityResolver(
174809
+ identityStorage,
174810
+ mappingStorage
174811
+ );
174208
174812
  }
174209
174813
  serverNode;
174210
174814
  client;
@@ -174223,6 +174827,7 @@ var ServerModeEndpointManager = class extends Service {
174223
174827
  get devices() {
174224
174828
  return [...this.endpoints.values()].map((entry) => entry.endpoint);
174225
174829
  }
174830
+ identityResolver;
174226
174831
  getEntityMapping(entityId) {
174227
174832
  return this.mappingStorage.getMapping(this.dataProvider.id, entityId);
174228
174833
  }
@@ -174291,6 +174896,19 @@ var ServerModeEndpointManager = class extends Service {
174291
174896
  this.endpoints.delete(entityId);
174292
174897
  }
174293
174898
  }
174899
+ // Like removeEndpoints but close() keeps the persisted number pre-allocated,
174900
+ // so a same-id recreate reuses it. Used on rename and same-id recreates (#404).
174901
+ async closeEndpoint(entityId) {
174902
+ const entry = this.endpoints.get(entityId);
174903
+ if (!entry) return;
174904
+ try {
174905
+ await entry.endpoint.close();
174906
+ } catch (e) {
174907
+ this.log.warn(`Failed to close endpoint ${entityId}:`, e);
174908
+ }
174909
+ this.serverNode.forgetDevice(entry.endpoint);
174910
+ this.endpoints.delete(entityId);
174911
+ }
174294
174912
  async refreshDevices() {
174295
174913
  this.registry.refresh();
174296
174914
  this._failedEntities = [];
@@ -174318,10 +174936,45 @@ var ServerModeEndpointManager = class extends Service {
174318
174936
  `Server mode node is capped at ${MAX_SERVER_MODE_DEVICES} devices, ${surplus.length} entities skipped`
174319
174937
  );
174320
174938
  }
174939
+ const stableIdentity = this.dataProvider.featureFlags?.stableIdentity === true;
174940
+ const resolvedByEntity = /* @__PURE__ */ new Map();
174941
+ const endpointIdToEntity = /* @__PURE__ */ new Map();
174942
+ const claimedEndpointIds = /* @__PURE__ */ new Map();
174943
+ for (const entityId of orderedIds) {
174944
+ const entityInfo = {
174945
+ entity_id: entityId,
174946
+ registry: this.registry.entity(entityId)
174947
+ };
174948
+ const resolved = await this.identityResolver.resolveIdentity(
174949
+ this.dataProvider.id,
174950
+ entityInfo,
174951
+ this.getEntityMapping(entityId),
174952
+ {
174953
+ stableIdentity,
174954
+ isEndpointIdTaken: (id, key) => claimedEndpointIds.has(id) && claimedEndpointIds.get(id) !== key
174955
+ }
174956
+ );
174957
+ resolvedByEntity.set(entityId, resolved);
174958
+ claimedEndpointIds.set(
174959
+ resolved.endpointId,
174960
+ identityKey(entityInfo) ?? `\0e:${entityId}`
174961
+ );
174962
+ endpointIdToEntity.set(resolved.endpointId, entityId);
174963
+ }
174321
174964
  const keep = new Set(orderedIds);
174322
174965
  const removed = [...this.endpoints.keys()].filter((id) => !keep.has(id));
174323
174966
  let structureChanged = removed.length > 0;
174324
- await this.removeEndpoints(removed);
174967
+ const genuinelyRemoved = [];
174968
+ for (const oldId of removed) {
174969
+ const entry = this.endpoints.get(oldId);
174970
+ const claimant = entry ? endpointIdToEntity.get(entry.endpoint.id) : void 0;
174971
+ if (entry && claimant != null && claimant !== oldId) {
174972
+ await this.closeEndpoint(oldId);
174973
+ } else {
174974
+ genuinelyRemoved.push(oldId);
174975
+ }
174976
+ }
174977
+ await this.removeEndpoints(genuinelyRemoved);
174325
174978
  for (const entityId of orderedIds) {
174326
174979
  const mapping = this.getEntityMapping(entityId);
174327
174980
  if (mapping?.disabled) {
@@ -174344,9 +174997,14 @@ var ServerModeEndpointManager = class extends Service {
174344
174997
  this.log.debug(`Device endpoint already exists for ${entityId}`);
174345
174998
  continue;
174346
174999
  }
175000
+ const resolved = resolvedByEntity.get(entityId);
174347
175001
  if (existing) {
174348
175002
  this.log.info(`Mapping changed for ${entityId}, recreating endpoint`);
174349
- await this.removeEndpoints([entityId]);
175003
+ if (resolved && existing.endpoint.id === resolved.endpointId) {
175004
+ await this.closeEndpoint(entityId);
175005
+ } else {
175006
+ await this.removeEndpoints([entityId]);
175007
+ }
174350
175008
  structureChanged = true;
174351
175009
  }
174352
175010
  const claimedBy = [...this.endpoints.entries()].find(
@@ -174359,7 +175017,7 @@ var ServerModeEndpointManager = class extends Service {
174359
175017
  });
174360
175018
  continue;
174361
175019
  }
174362
- const endpointId = createEndpointId(entityId, mapping?.customName);
175020
+ const endpointId = resolved?.endpointId ?? createEndpointId(entityId, mapping?.customName);
174363
175021
  const collision = [...this.endpoints.entries()].find(
174364
175022
  ([, entry]) => entry.endpoint.id === endpointId
174365
175023
  );
@@ -174382,12 +175040,18 @@ var ServerModeEndpointManager = class extends Service {
174382
175040
  }
174383
175041
  try {
174384
175042
  const domain = entityId.split(".")[0];
174385
- const endpoint = domain === "vacuum" ? await this.createServerModeVacuumEndpoint(entityId, mapping) : await LegacyEndpoint.create(
175043
+ const endpoint = domain === "vacuum" ? await this.createServerModeVacuumEndpoint(
175044
+ entityId,
175045
+ mapping,
175046
+ resolved?.endpointId
175047
+ ) : await LegacyEndpoint.create(
174386
175048
  this.registry,
174387
175049
  entityId,
174388
175050
  mapping,
174389
175051
  void 0,
174390
- true
175052
+ true,
175053
+ resolved?.endpointId,
175054
+ resolved?.anchorEntityId
174391
175055
  );
174392
175056
  if (!endpoint) {
174393
175057
  this._failedEntities.push({
@@ -174455,8 +175119,13 @@ var ServerModeEndpointManager = class extends Service {
174455
175119
  * This makes the vacuum appear as a standalone Matter device, which is required
174456
175120
  * for Apple Home Siri voice commands and Alexa discovery.
174457
175121
  */
174458
- async createServerModeVacuumEndpoint(entityId, mapping) {
174459
- return ServerModeVacuumEndpoint.create(this.registry, entityId, mapping);
175122
+ async createServerModeVacuumEndpoint(entityId, mapping, endpointId) {
175123
+ return ServerModeVacuumEndpoint.create(
175124
+ this.registry,
175125
+ entityId,
175126
+ mapping,
175127
+ endpointId
175128
+ );
174460
175129
  }
174461
175130
  };
174462
175131
 
@@ -174540,6 +175209,7 @@ var BridgeEnvironment = class _BridgeEnvironment extends EnvironmentBase {
174540
175209
  await this.load(HomeAssistantClient),
174541
175210
  this.get(BridgeRegistry),
174542
175211
  await this.load(EntityMappingStorage),
175212
+ await this.load(EntityIdentityStorage),
174543
175213
  bridgeId,
174544
175214
  this.endpointManagerLogger,
174545
175215
  pluginManager,
@@ -174625,6 +175295,7 @@ var BridgeEnvironmentFactory = class extends BridgeFactory {
174625
175295
  await env.load(HomeAssistantClient),
174626
175296
  env.get(BridgeRegistry),
174627
175297
  await env.load(EntityMappingStorage),
175298
+ await env.load(EntityIdentityStorage),
174628
175299
  dataProvider,
174629
175300
  loggerService.get("ServerModeEndpointManager")
174630
175301
  );
@@ -174676,6 +175347,10 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
174676
175347
  EntityMappingStorage,
174677
175348
  new EntityMappingStorage(await this.load(AppStorage))
174678
175349
  );
175350
+ this.set(
175351
+ EntityIdentityStorage,
175352
+ new EntityIdentityStorage(await this.load(AppStorage))
175353
+ );
174679
175354
  this.set(
174680
175355
  LockCredentialStorage,
174681
175356
  new LockCredentialStorage(await this.load(AppStorage))
@@ -174736,6 +175411,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
174736
175411
  await this.load(HomeAssistantRegistry),
174737
175412
  await this.load(BridgeStorage),
174738
175413
  await this.load(EntityMappingStorage),
175414
+ await this.load(EntityIdentityStorage),
174739
175415
  await this.load(LockCredentialStorage),
174740
175416
  await this.load(AppSettingsStorage),
174741
175417
  await this.load(BackupService),