@riddix/hamh 2.1.0-alpha.528 → 2.1.0-alpha.530

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.
@@ -147567,7 +147567,7 @@ var DiagnosticService = class {
147567
147567
  }
147568
147568
  }
147569
147569
  }
147570
- const entities = this.collectEntities(bridge.aggregator);
147570
+ const entities = bridge.aggregator ? this.collectEntities(bridge.aggregator) : [];
147571
147571
  return {
147572
147572
  bridgeId: data.id,
147573
147573
  bridgeName: data.name,
@@ -167168,9 +167168,9 @@ ${e?.toString()}`);
167168
167168
  `Closing stale session ${s.id} (peer ${s.peerNodeId}, no subscriptions for ${DEAD_SESSION_TIMEOUT_MS / 1e3}s)`
167169
167169
  );
167170
167170
  s.initiateClose().catch(() => {
167171
- s.initiateForceClose().catch(() => {
167172
- });
167173
- });
167171
+ return s.initiateForceClose();
167172
+ }).catch(() => {
167173
+ }).finally(() => this.triggerMdnsReAnnounce());
167174
167174
  break;
167175
167175
  }
167176
167176
  }
@@ -167181,17 +167181,37 @@ ${e?.toString()}`);
167181
167181
  try {
167182
167182
  const sessionManager = this.server.env.get(SessionManager);
167183
167183
  const sessions = [...sessionManager.sessions];
167184
+ const closes = [];
167184
167185
  for (const s of sessions) {
167185
167186
  if (!s.isClosing && s.subscriptions.size === 0) {
167186
167187
  this.log.warn(
167187
167188
  `Closing dead session ${s.id} (peer ${s.peerNodeId}, no subscriptions for ${DEAD_SESSION_TIMEOUT_MS / 1e3}s)`
167188
167189
  );
167189
- s.initiateClose().catch(() => {
167190
- s.initiateForceClose().catch(() => {
167191
- });
167192
- });
167190
+ closes.push(
167191
+ s.initiateClose().catch(() => {
167192
+ return s.initiateForceClose();
167193
+ })
167194
+ );
167193
167195
  }
167194
167196
  }
167197
+ if (closes.length > 0) {
167198
+ Promise.allSettled(closes).then(() => this.triggerMdnsReAnnounce());
167199
+ }
167200
+ } catch {
167201
+ }
167202
+ }
167203
+ /**
167204
+ * Force a fresh mDNS operational advertisement after session cleanup.
167205
+ * matter.js DeviceAdvertiser only re-announces when a subscription is
167206
+ * canceled BY THE PEER. When the server cancels after 3 delivery
167207
+ * timeouts, no re-announcement happens and the controller may not
167208
+ * realize it should reconnect (#266).
167209
+ */
167210
+ triggerMdnsReAnnounce() {
167211
+ try {
167212
+ const advertiser = this.server.env.get(DeviceAdvertiser);
167213
+ advertiser.restartAdvertisement();
167214
+ this.log.info("Triggered mDNS re-announcement after session cleanup");
167195
167215
  } catch {
167196
167216
  }
167197
167217
  }
@@ -167737,6 +167757,26 @@ function PowerSourceServer2(config10) {
167737
167757
  order: PowerSource3.Cluster.id
167738
167758
  });
167739
167759
  }
167760
+ var defaultBatteryConfig = {
167761
+ getBatteryPercent: (entity, agent) => {
167762
+ const homeAssistant = agent.get(HomeAssistantEntityBehavior);
167763
+ const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
167764
+ if (batteryEntity) {
167765
+ const stateProvider = agent.env.get(EntityStateProvider);
167766
+ const battery = stateProvider.getBatteryPercent(batteryEntity);
167767
+ if (battery != null) {
167768
+ return Math.max(0, Math.min(100, battery));
167769
+ }
167770
+ }
167771
+ const attrs = entity.attributes;
167772
+ const level = attrs.battery_level ?? attrs.battery;
167773
+ if (level == null || Number.isNaN(Number(level))) {
167774
+ return null;
167775
+ }
167776
+ return Number(level);
167777
+ }
167778
+ };
167779
+ var DefaultPowerSourceServer = PowerSourceServer2(defaultBatteryConfig);
167740
167780
 
167741
167781
  // src/matter/behaviors/temperature-measurement-server.ts
167742
167782
  init_home_assistant_entity_behavior();
@@ -170824,25 +170864,6 @@ function ClimateThermostatServer(initialState = {}, features2) {
170824
170864
  }
170825
170865
 
170826
170866
  // src/matter/endpoints/legacy/climate/index.ts
170827
- var ClimatePowerSourceServer = PowerSourceServer2({
170828
- getBatteryPercent: (entity, agent) => {
170829
- const homeAssistant = agent.get(HomeAssistantEntityBehavior);
170830
- const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
170831
- if (batteryEntity) {
170832
- const stateProvider = agent.env.get(EntityStateProvider);
170833
- const battery = stateProvider.getBatteryPercent(batteryEntity);
170834
- if (battery != null) {
170835
- return Math.max(0, Math.min(100, battery));
170836
- }
170837
- }
170838
- const attrs = entity.attributes;
170839
- const level = attrs.battery_level ?? attrs.battery;
170840
- if (level == null || Number.isNaN(Number(level))) {
170841
- return null;
170842
- }
170843
- return Number(level);
170844
- }
170845
- });
170846
170867
  var ClimateDeviceType = (supportsOnOff, supportsHumidity, supportsFanMode, hasBattery, features2, initialState = {}) => {
170847
170868
  const additionalClusters = [];
170848
170869
  if (supportsOnOff) {
@@ -170852,7 +170873,7 @@ var ClimateDeviceType = (supportsOnOff, supportsHumidity, supportsFanMode, hasBa
170852
170873
  additionalClusters.push(ClimateHumidityMeasurementServer);
170853
170874
  }
170854
170875
  if (hasBattery) {
170855
- additionalClusters.push(ClimatePowerSourceServer);
170876
+ additionalClusters.push(DefaultPowerSourceServer);
170856
170877
  }
170857
170878
  const thermostatServer = ClimateThermostatServer(initialState, features2);
170858
170879
  if (supportsFanMode) {
@@ -171446,25 +171467,6 @@ var CoverWindowCoveringServer = WindowCoveringServer2(config5);
171446
171467
 
171447
171468
  // src/matter/endpoints/legacy/cover/index.ts
171448
171469
  var logger177 = Logger.get("CoverDevice");
171449
- var CoverPowerSourceServer = PowerSourceServer2({
171450
- getBatteryPercent: (entity, agent) => {
171451
- const homeAssistant = agent.get(HomeAssistantEntityBehavior);
171452
- const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
171453
- if (batteryEntity) {
171454
- const stateProvider = agent.env.get(EntityStateProvider);
171455
- const battery = stateProvider.getBatteryPercent(batteryEntity);
171456
- if (battery != null) {
171457
- return Math.max(0, Math.min(100, battery));
171458
- }
171459
- }
171460
- const attrs = entity.attributes;
171461
- const level = attrs.battery_level ?? attrs.battery;
171462
- if (level == null || Number.isNaN(Number(level))) {
171463
- return null;
171464
- }
171465
- return Number(level);
171466
- }
171467
- });
171468
171470
  var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
171469
171471
  const features2 = /* @__PURE__ */ new Set();
171470
171472
  if (testBit(supportedFeatures, CoverSupportedFeatures.support_open)) {
@@ -171499,7 +171501,10 @@ var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
171499
171501
  CoverWindowCoveringServer.with(...features2)
171500
171502
  ];
171501
171503
  if (hasBattery) {
171502
- return WindowCoveringDevice.with(...baseBehaviors, CoverPowerSourceServer);
171504
+ return WindowCoveringDevice.with(
171505
+ ...baseBehaviors,
171506
+ DefaultPowerSourceServer
171507
+ );
171503
171508
  }
171504
171509
  return WindowCoveringDevice.with(...baseBehaviors);
171505
171510
  };
@@ -171620,25 +171625,6 @@ function EventDevice(homeAssistantEntity) {
171620
171625
  // src/matter/endpoints/legacy/fan/index.ts
171621
171626
  init_dist();
171622
171627
  init_home_assistant_entity_behavior();
171623
- var FanPowerSourceServer = PowerSourceServer2({
171624
- getBatteryPercent: (entity, agent) => {
171625
- const homeAssistant = agent.get(HomeAssistantEntityBehavior);
171626
- const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
171627
- if (batteryEntity) {
171628
- const stateProvider = agent.env.get(EntityStateProvider);
171629
- const battery = stateProvider.getBatteryPercent(batteryEntity);
171630
- if (battery != null) {
171631
- return Math.max(0, Math.min(100, battery));
171632
- }
171633
- }
171634
- const attrs = entity.attributes;
171635
- const level = attrs.battery_level ?? attrs.battery;
171636
- if (level == null || Number.isNaN(Number(level))) {
171637
- return null;
171638
- }
171639
- return Number(level);
171640
- }
171641
- });
171642
171628
  function FanDevice2(homeAssistantEntity) {
171643
171629
  const attributes7 = homeAssistantEntity.entity.state.attributes;
171644
171630
  const supportedFeatures = attributes7.supported_features ?? 0;
@@ -171658,7 +171644,7 @@ function FanDevice2(homeAssistantEntity) {
171658
171644
  BasicInformationServer2,
171659
171645
  HomeAssistantEntityBehavior,
171660
171646
  FanOnOffServer,
171661
- FanPowerSourceServer
171647
+ DefaultPowerSourceServer
171662
171648
  ) : OnOffPlugInUnitDevice.with(
171663
171649
  IdentifyServer2,
171664
171650
  BasicInformationServer2,
@@ -171693,7 +171679,7 @@ function FanDevice2(homeAssistantEntity) {
171693
171679
  HomeAssistantEntityBehavior,
171694
171680
  FanOnOffServer,
171695
171681
  FanFanControlServer.with(...features2),
171696
- FanPowerSourceServer
171682
+ DefaultPowerSourceServer
171697
171683
  ) : FanDevice.with(
171698
171684
  IdentifyServer2,
171699
171685
  BasicInformationServer2,
@@ -172218,25 +172204,6 @@ var ColorTemperatureLightType = ColorTemperatureLightDevice.with(
172218
172204
 
172219
172205
  // src/matter/endpoints/legacy/light/devices/dimmable-light.ts
172220
172206
  init_home_assistant_entity_behavior();
172221
- var LightPowerSourceServer = PowerSourceServer2({
172222
- getBatteryPercent: (entity, agent) => {
172223
- const homeAssistant = agent.get(HomeAssistantEntityBehavior);
172224
- const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
172225
- if (batteryEntity) {
172226
- const stateProvider = agent.env.get(EntityStateProvider);
172227
- const battery = stateProvider.getBatteryPercent(batteryEntity);
172228
- if (battery != null) {
172229
- return Math.max(0, Math.min(100, battery));
172230
- }
172231
- }
172232
- const attrs = entity.attributes;
172233
- const level = attrs.battery_level ?? attrs.battery;
172234
- if (level == null || Number.isNaN(Number(level))) {
172235
- return null;
172236
- }
172237
- return Number(level);
172238
- }
172239
- });
172240
172207
  var DimmableLightType = DimmableLightDevice.with(
172241
172208
  IdentifyServer2,
172242
172209
  BasicInformationServer2,
@@ -172250,30 +172217,11 @@ var DimmableLightWithBatteryType = DimmableLightDevice.with(
172250
172217
  HomeAssistantEntityBehavior,
172251
172218
  LightOnOffServer,
172252
172219
  LightLevelControlServer,
172253
- LightPowerSourceServer
172220
+ DefaultPowerSourceServer
172254
172221
  );
172255
172222
 
172256
172223
  // src/matter/endpoints/legacy/light/devices/extended-color-light.ts
172257
172224
  init_home_assistant_entity_behavior();
172258
- var LightPowerSourceServer2 = PowerSourceServer2({
172259
- getBatteryPercent: (entity, agent) => {
172260
- const homeAssistant = agent.get(HomeAssistantEntityBehavior);
172261
- const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
172262
- if (batteryEntity) {
172263
- const stateProvider = agent.env.get(EntityStateProvider);
172264
- const battery = stateProvider.getBatteryPercent(batteryEntity);
172265
- if (battery != null) {
172266
- return Math.max(0, Math.min(100, battery));
172267
- }
172268
- }
172269
- const attrs = entity.attributes;
172270
- const level = attrs.battery_level ?? attrs.battery;
172271
- if (level == null || Number.isNaN(Number(level))) {
172272
- return null;
172273
- }
172274
- return Number(level);
172275
- }
172276
- });
172277
172225
  var ExtendedColorLightType = (supportsColorControl, supportsTemperature, hasBattery = false) => {
172278
172226
  const features2 = /* @__PURE__ */ new Set();
172279
172227
  if (supportsColorControl) {
@@ -172290,7 +172238,7 @@ var ExtendedColorLightType = (supportsColorControl, supportsTemperature, hasBatt
172290
172238
  LightOnOffServer,
172291
172239
  LightLevelControlServer,
172292
172240
  LightColorControlServer.with(...features2),
172293
- LightPowerSourceServer2
172241
+ DefaultPowerSourceServer
172294
172242
  );
172295
172243
  }
172296
172244
  return ExtendedColorLightDevice.with(
@@ -172305,25 +172253,6 @@ var ExtendedColorLightType = (supportsColorControl, supportsTemperature, hasBatt
172305
172253
 
172306
172254
  // src/matter/endpoints/legacy/light/devices/on-off-light-device.ts
172307
172255
  init_home_assistant_entity_behavior();
172308
- var LightPowerSourceServer3 = PowerSourceServer2({
172309
- getBatteryPercent: (entity, agent) => {
172310
- const homeAssistant = agent.get(HomeAssistantEntityBehavior);
172311
- const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
172312
- if (batteryEntity) {
172313
- const stateProvider = agent.env.get(EntityStateProvider);
172314
- const battery = stateProvider.getBatteryPercent(batteryEntity);
172315
- if (battery != null) {
172316
- return Math.max(0, Math.min(100, battery));
172317
- }
172318
- }
172319
- const attrs = entity.attributes;
172320
- const level = attrs.battery_level ?? attrs.battery;
172321
- if (level == null || Number.isNaN(Number(level))) {
172322
- return null;
172323
- }
172324
- return Number(level);
172325
- }
172326
- });
172327
172256
  var OnOffLightType = OnOffLightDevice.with(
172328
172257
  IdentifyServer2,
172329
172258
  BasicInformationServer2,
@@ -172335,7 +172264,7 @@ var OnOffLightWithBatteryType = OnOffLightDevice.with(
172335
172264
  BasicInformationServer2,
172336
172265
  HomeAssistantEntityBehavior,
172337
172266
  LightOnOffServer,
172338
- LightPowerSourceServer3
172267
+ DefaultPowerSourceServer
172339
172268
  );
172340
172269
 
172341
172270
  // src/matter/endpoints/legacy/light/index.ts
@@ -173026,25 +172955,6 @@ var lockServerConfig = {
173026
172955
  unlock: () => ({ action: "lock.unlock" }),
173027
172956
  unlatch: () => ({ action: "lock.open" })
173028
172957
  };
173029
- var LockPowerSourceServer = PowerSourceServer2({
173030
- getBatteryPercent: (entity, agent) => {
173031
- const homeAssistant = agent.get(HomeAssistantEntityBehavior);
173032
- const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
173033
- if (batteryEntity) {
173034
- const stateProvider = agent.env.get(EntityStateProvider);
173035
- const battery = stateProvider.getBatteryPercent(batteryEntity);
173036
- if (battery != null) {
173037
- return Math.max(0, Math.min(100, battery));
173038
- }
173039
- }
173040
- const attrs = entity.attributes;
173041
- const level = attrs.battery_level ?? attrs.battery;
173042
- if (level == null || Number.isNaN(Number(level))) {
173043
- return null;
173044
- }
173045
- return Number(level);
173046
- }
173047
- });
173048
172958
  var LockDeviceType = DoorLockDevice.with(
173049
172959
  BasicInformationServer2,
173050
172960
  IdentifyServer2,
@@ -173056,7 +172966,7 @@ var LockWithBatteryDeviceType = DoorLockDevice.with(
173056
172966
  IdentifyServer2,
173057
172967
  HomeAssistantEntityBehavior,
173058
172968
  LockServerWithPin(lockServerConfig),
173059
- LockPowerSourceServer
172969
+ DefaultPowerSourceServer
173060
172970
  );
173061
172971
  var LockWithUnlatchDeviceType = DoorLockDevice.with(
173062
172972
  BasicInformationServer2,
@@ -173069,7 +172979,7 @@ var LockWithUnlatchAndBatteryDeviceType = DoorLockDevice.with(
173069
172979
  IdentifyServer2,
173070
172980
  HomeAssistantEntityBehavior,
173071
172981
  LockServerWithPinAndUnbolt(lockServerConfig),
173072
- LockPowerSourceServer
172982
+ DefaultPowerSourceServer
173073
172983
  );
173074
172984
  function LockDevice(homeAssistantEntity) {
173075
172985
  const attrs = homeAssistantEntity.entity.state.attributes;
@@ -173651,25 +173561,7 @@ var PumpWithBatteryType = PumpDevice.with(
173651
173561
  HomeAssistantEntityBehavior,
173652
173562
  PumpOnOffServer,
173653
173563
  PumpConfigurationAndControlServer2,
173654
- PowerSourceServer2({
173655
- getBatteryPercent: (entity, agent) => {
173656
- const homeAssistant = agent.get(HomeAssistantEntityBehavior);
173657
- const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
173658
- if (batteryEntity) {
173659
- const stateProvider = agent.env.get(EntityStateProvider);
173660
- const battery = stateProvider.getBatteryPercent(batteryEntity);
173661
- if (battery != null) {
173662
- return Math.max(0, Math.min(100, battery));
173663
- }
173664
- }
173665
- const attrs = entity.attributes;
173666
- const level = attrs.battery_level ?? attrs.battery;
173667
- if (level == null || Number.isNaN(Number(level))) {
173668
- return null;
173669
- }
173670
- return Number(level);
173671
- }
173672
- })
173564
+ DefaultPowerSourceServer
173673
173565
  );
173674
173566
  function PumpEndpoint(homeAssistantEntity) {
173675
173567
  const attrs = homeAssistantEntity.entity.state.attributes;
@@ -175481,25 +175373,7 @@ var SwitchWithBatteryEndpointType = OnOffPlugInUnitDevice.with(
175481
175373
  IdentifyServer2,
175482
175374
  HomeAssistantEntityBehavior,
175483
175375
  SwitchOnOffServer,
175484
- PowerSourceServer2({
175485
- getBatteryPercent: (entity, agent) => {
175486
- const homeAssistant = agent.get(HomeAssistantEntityBehavior);
175487
- const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
175488
- if (batteryEntity) {
175489
- const stateProvider = agent.env.get(EntityStateProvider);
175490
- const battery = stateProvider.getBatteryPercent(batteryEntity);
175491
- if (battery != null) {
175492
- return Math.max(0, Math.min(100, battery));
175493
- }
175494
- }
175495
- const attrs = entity.attributes;
175496
- const level = attrs.battery_level ?? attrs.battery;
175497
- if (level == null || Number.isNaN(Number(level))) {
175498
- return null;
175499
- }
175500
- return Number(level);
175501
- }
175502
- })
175376
+ DefaultPowerSourceServer
175503
175377
  );
175504
175378
  function SwitchDevice(homeAssistantEntity) {
175505
175379
  const attrs = homeAssistantEntity.entity.state.attributes;
@@ -177701,25 +177575,7 @@ var ValveWithBatteryEndpointType = WaterValveDevice.with(
177701
177575
  IdentifyServer2,
177702
177576
  HomeAssistantEntityBehavior,
177703
177577
  ValveServer,
177704
- PowerSourceServer2({
177705
- getBatteryPercent: (entity, agent) => {
177706
- const homeAssistant = agent.get(HomeAssistantEntityBehavior);
177707
- const batteryEntity = homeAssistant.state.mapping?.batteryEntity;
177708
- if (batteryEntity) {
177709
- const stateProvider = agent.env.get(EntityStateProvider);
177710
- const battery = stateProvider.getBatteryPercent(batteryEntity);
177711
- if (battery != null) {
177712
- return Math.max(0, Math.min(100, battery));
177713
- }
177714
- }
177715
- const attrs = entity.attributes;
177716
- const level = attrs.battery_level ?? attrs.battery;
177717
- if (level == null || Number.isNaN(Number(level))) {
177718
- return null;
177719
- }
177720
- return Number(level);
177721
- }
177722
- })
177578
+ DefaultPowerSourceServer
177723
177579
  );
177724
177580
  function ValveDevice(homeAssistantEntity) {
177725
177581
  const attrs = homeAssistantEntity.entity.state.attributes;
@@ -180215,9 +180071,9 @@ ${e?.toString()}`);
180215
180071
  `Closing stale session ${s.id} (peer ${s.peerNodeId}, no subscriptions for ${DEAD_SESSION_TIMEOUT_MS2 / 1e3}s)`
180216
180072
  );
180217
180073
  s.initiateClose().catch(() => {
180218
- s.initiateForceClose().catch(() => {
180219
- });
180220
- });
180074
+ return s.initiateForceClose();
180075
+ }).catch(() => {
180076
+ }).finally(() => this.triggerMdnsReAnnounce());
180221
180077
  break;
180222
180078
  }
180223
180079
  }
@@ -180228,17 +180084,37 @@ ${e?.toString()}`);
180228
180084
  try {
180229
180085
  const sessionManager = this.server.env.get(SessionManager);
180230
180086
  const sessions = [...sessionManager.sessions];
180087
+ const closes = [];
180231
180088
  for (const s of sessions) {
180232
180089
  if (!s.isClosing && s.subscriptions.size === 0) {
180233
180090
  this.log.warn(
180234
180091
  `Closing dead session ${s.id} (peer ${s.peerNodeId}, no subscriptions for ${DEAD_SESSION_TIMEOUT_MS2 / 1e3}s)`
180235
180092
  );
180236
- s.initiateClose().catch(() => {
180237
- s.initiateForceClose().catch(() => {
180238
- });
180239
- });
180093
+ closes.push(
180094
+ s.initiateClose().catch(() => {
180095
+ return s.initiateForceClose();
180096
+ })
180097
+ );
180240
180098
  }
180241
180099
  }
180100
+ if (closes.length > 0) {
180101
+ Promise.allSettled(closes).then(() => this.triggerMdnsReAnnounce());
180102
+ }
180103
+ } catch {
180104
+ }
180105
+ }
180106
+ /**
180107
+ * Force a fresh mDNS operational advertisement after session cleanup.
180108
+ * matter.js DeviceAdvertiser only re-announces when a subscription is
180109
+ * canceled BY THE PEER. When the server cancels after 3 delivery
180110
+ * timeouts, no re-announcement happens and the controller may not
180111
+ * realize it should reconnect (#266).
180112
+ */
180113
+ triggerMdnsReAnnounce() {
180114
+ try {
180115
+ const advertiser = this.server.env.get(DeviceAdvertiser);
180116
+ advertiser.restartAdvertisement();
180117
+ this.log.info("Triggered mDNS re-announcement after session cleanup");
180242
180118
  } catch {
180243
180119
  }
180244
180120
  }