@riddix/hamh 2.1.0-alpha.615 → 2.1.0-alpha.617

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.
@@ -11896,7 +11896,7 @@ var init_ServerAddress = __esm({
11896
11896
  return Diagnostic.squash(...diagnostic);
11897
11897
  }
11898
11898
  ServerAddress2.diagnosticFor = diagnosticFor;
11899
- function isEqual(a, b) {
11899
+ function isEqual2(a, b) {
11900
11900
  if (a.type !== b.type) {
11901
11901
  return false;
11902
11902
  }
@@ -11908,7 +11908,7 @@ var init_ServerAddress = __esm({
11908
11908
  }
11909
11909
  return false;
11910
11910
  }
11911
- ServerAddress2.isEqual = isEqual;
11911
+ ServerAddress2.isEqual = isEqual2;
11912
11912
  function healthOf(health) {
11913
11913
  if (health.unhealthyAt === void 0) {
11914
11914
  return health;
@@ -146105,6 +146105,7 @@ var init_clusters2 = __esm({
146105
146105
  ClusterId3["bridgedDeviceBasicInformation"] = "bridgedDeviceBasicInformation";
146106
146106
  ClusterId3["airQuality"] = "airQuality";
146107
146107
  ClusterId3["booleanState"] = "booleanState";
146108
+ ClusterId3["booleanStateConfiguration"] = "booleanStateConfiguration";
146108
146109
  ClusterId3["carbonDioxideConcentrationMeasurement"] = "carbonDioxideConcentrationMeasurement";
146109
146110
  ClusterId3["carbonMonoxideConcentrationMeasurement"] = "carbonMonoxideConcentrationMeasurement";
146110
146111
  ClusterId3["colorControl"] = "colorControl";
@@ -146779,7 +146780,7 @@ var init_bridge_config_schema = __esm({
146779
146780
  },
146780
146781
  autoComposedDevices: {
146781
146782
  title: "Auto Composed Devices",
146782
- description: "Master toggle: automatically combine related entities from the same Home Assistant device into single Matter endpoints. Enables battery, humidity, pressure, power, and energy auto-mapping at once. This provides a cleaner device experience in Matter controllers (e.g., a Shelly Plug appears as one device with power monitoring).",
146783
+ description: "Master toggle: combine related entities from the same Home Assistant device into a single Matter endpoint. Turns on battery, humidity, pressure, power, and energy auto-mapping at once \u2014 a Shelly Plug shows up as one device with power monitoring instead of several siblings.",
146783
146784
  type: "boolean",
146784
146785
  default: false
146785
146786
  },
@@ -147038,10 +147039,13 @@ var init_color_converter = __esm({
147038
147039
  }
147039
147040
  /**
147040
147041
  * Convert Color Tempareture from Mireds to Kelvin
147041
- * @param temperatureMireds Temperature in Mireds
147042
- * @return Temperature in Kelvin
147042
+ * @param temperatureMireds Temperature in Mireds (must be finite and > 0)
147043
+ * @return Temperature in Kelvin, or null if the input is 0 / negative / non-finite
147043
147044
  */
147044
147045
  static temperatureMiredsToKelvin(temperatureMireds) {
147046
+ if (!Number.isFinite(temperatureMireds) || temperatureMireds <= 0) {
147047
+ return null;
147048
+ }
147045
147049
  return 1e6 / temperatureMireds;
147046
147050
  }
147047
147051
  /**
@@ -150371,9 +150375,7 @@ var PluginInstaller = class {
150371
150375
  return;
150372
150376
  }
150373
150377
  const version = this.getInstalledVersion(packageName);
150374
- logger143.info(
150375
- `Successfully installed ${packageName}@${version || "unknown"}`
150376
- );
150378
+ logger143.info(`Installed ${packageName}@${version || "unknown"}`);
150377
150379
  resolve6({
150378
150380
  success: true,
150379
150381
  packageName,
@@ -150413,7 +150415,7 @@ var PluginInstaller = class {
150413
150415
  });
150414
150416
  return;
150415
150417
  }
150416
- logger143.info(`Successfully uninstalled ${packageName}`);
150418
+ logger143.info(`Uninstalled ${packageName}`);
150417
150419
  resolve6({ success: true, packageName });
150418
150420
  }
150419
150421
  );
@@ -152332,23 +152334,30 @@ var BridgeService = class extends Service {
152332
152334
  }
152333
152335
  }
152334
152336
  async stopAll() {
152335
- for (const bridge of this.bridges) {
152336
- try {
152337
- await bridge.stop();
152338
- this.onBridgeChanged?.(bridge.id);
152339
- } catch (e) {
152340
- this.log.error(`Failed to stop bridge ${bridge.id}:`, e);
152341
- }
152342
- }
152337
+ await Promise.all(
152338
+ this.bridges.map(async (bridge) => {
152339
+ try {
152340
+ await bridge.stop();
152341
+ this.onBridgeChanged?.(bridge.id);
152342
+ } catch (e) {
152343
+ this.log.error(`Failed to stop bridge ${bridge.id}:`, e);
152344
+ }
152345
+ })
152346
+ );
152343
152347
  }
152344
152348
  async restartAll() {
152345
- for (const bridge of this.bridges) {
152346
- try {
152347
- await bridge.stop();
152348
- } catch (e) {
152349
- this.log.error(`Failed to stop bridge ${bridge.id} during restart:`, e);
152350
- }
152351
- }
152349
+ await Promise.all(
152350
+ this.bridges.map(async (bridge) => {
152351
+ try {
152352
+ await bridge.stop();
152353
+ } catch (e) {
152354
+ this.log.error(
152355
+ `Failed to stop bridge ${bridge.id} during restart:`,
152356
+ e
152357
+ );
152358
+ }
152359
+ })
152360
+ );
152352
152361
  const sortedBridges = [...this.bridges].sort((a, b) => {
152353
152362
  const priorityA = a.data.priority ?? 100;
152354
152363
  const priorityB = b.data.priority ?? 100;
@@ -152769,19 +152778,15 @@ var HomeAssistantRegistry = class extends Service {
152769
152778
  }
152770
152779
  });
152771
152780
  }
152772
- const entityRegistry = await getRegistry(connection);
152773
- const statesList = await getStates(connection);
152774
- const deviceRegistry = await getDeviceRegistry(connection);
152775
- let labels = [];
152776
- try {
152777
- labels = await getLabelRegistry(connection);
152778
- } catch {
152779
- }
152780
- let areas = [];
152781
- try {
152782
- areas = await getAreaRegistry(connection);
152783
- } catch {
152784
- }
152781
+ const [entityRegistry, statesList, deviceRegistry, labels, areas] = await Promise.all([
152782
+ getRegistry(connection),
152783
+ getStates(connection),
152784
+ getDeviceRegistry(connection),
152785
+ getLabelRegistry(connection).catch(() => []),
152786
+ getAreaRegistry(connection).catch(
152787
+ () => []
152788
+ )
152789
+ ]);
152785
152790
  const hash2 = createHash("md5");
152786
152791
  for (const e of entityRegistry) {
152787
152792
  hash2.update(
@@ -168081,6 +168086,7 @@ init_dist();
168081
168086
  init_esm();
168082
168087
  init_home_assistant_entity_behavior();
168083
168088
  import debounce5 from "debounce";
168089
+ import { isEqual } from "lodash-es";
168084
168090
 
168085
168091
  // src/matter/endpoints/entity-endpoint.ts
168086
168092
  init_esm7();
@@ -168891,12 +168897,10 @@ var LevelControlServerBase = class extends FeaturedBase4 {
168891
168897
  this.state.maxLevel = 254;
168892
168898
  }
168893
168899
  this.state.onLevel = null;
168894
- logger169.debug(`initialize: calling super.initialize()`);
168895
168900
  try {
168896
168901
  await super.initialize();
168897
- logger169.debug(`initialize: super.initialize() completed successfully`);
168898
168902
  } catch (error) {
168899
- logger169.error(`initialize: super.initialize() FAILED:`, error);
168903
+ logger169.error("super.initialize() failed:", error);
168900
168904
  throw error;
168901
168905
  }
168902
168906
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
@@ -170505,13 +170509,15 @@ var ContactSensorType = ContactSensorDevice.with(
170505
170509
  BasicInformationServer2,
170506
170510
  IdentifyServer2,
170507
170511
  HomeAssistantEntityBehavior,
170508
- BooleanStateServer2({ inverted: true })
170512
+ BooleanStateServer2({ inverted: true }),
170513
+ BooleanStateConfigurationServer
170509
170514
  );
170510
170515
  var ContactSensorWithBatteryType = ContactSensorDevice.with(
170511
170516
  BasicInformationServer2,
170512
170517
  IdentifyServer2,
170513
170518
  HomeAssistantEntityBehavior,
170514
170519
  BooleanStateServer2({ inverted: true }),
170520
+ BooleanStateConfigurationServer,
170515
170521
  PowerSourceServer2({
170516
170522
  getBatteryPercent: (entity, agent) => {
170517
170523
  const homeAssistant = agent.get(HomeAssistantEntityBehavior);
@@ -170717,7 +170723,8 @@ var RainSensorType = RainSensorDevice.with(
170717
170723
  BasicInformationServer2,
170718
170724
  IdentifyServer2,
170719
170725
  HomeAssistantEntityBehavior,
170720
- BooleanStateServer2()
170726
+ BooleanStateServer2(),
170727
+ BooleanStateConfigurationServer
170721
170728
  );
170722
170729
 
170723
170730
  // ../../node_modules/.pnpm/@matter+main@0.16.11/node_modules/@matter/main/dist/esm/forwards/behaviors/smoke-co-alarm.js
@@ -170807,7 +170814,8 @@ var WaterFreezeDetectorType = WaterFreezeDetectorDevice.with(
170807
170814
  BasicInformationServer2,
170808
170815
  IdentifyServer2,
170809
170816
  HomeAssistantEntityBehavior,
170810
- BooleanStateServer2()
170817
+ BooleanStateServer2(),
170818
+ BooleanStateConfigurationServer
170811
170819
  );
170812
170820
 
170813
170821
  // src/matter/endpoints/legacy/binary-sensor/water-leak-detector.ts
@@ -170816,7 +170824,8 @@ var WaterLeakDetectorType = WaterLeakDetectorDevice.with(
170816
170824
  BasicInformationServer2,
170817
170825
  IdentifyServer2,
170818
170826
  HomeAssistantEntityBehavior,
170819
- BooleanStateServer2()
170827
+ BooleanStateServer2(),
170828
+ BooleanStateConfigurationServer
170820
170829
  );
170821
170830
 
170822
170831
  // src/matter/endpoints/legacy/binary-sensor/index.ts
@@ -171140,8 +171149,8 @@ async function thermostatPostInitialize(self) {
171140
171149
  }
171141
171150
  var ThermostatServerBase = class extends FullFeaturedBase {
171142
171151
  // State class only declares the config property type.
171143
- // ALL defaults are set via .set() in the ThermostatServer function below.
171144
- // This ensures Matter.js's internal cluster data store receives the values.
171152
+ // ALL defaults are set via .set() in the ThermostatServer function below
171153
+ // so matter.js's internal cluster data store picks them up before init.
171145
171154
  static State = class State extends FullFeaturedBase.State {
171146
171155
  config;
171147
171156
  };
@@ -171450,6 +171459,8 @@ var ThermostatServerBase = class extends FullFeaturedBase {
171450
171459
  default:
171451
171460
  return allOff;
171452
171461
  }
171462
+ default:
171463
+ return allOff;
171453
171464
  }
171454
171465
  }
171455
171466
  clampControlSequence(value) {
@@ -171621,7 +171632,10 @@ var hvacActionToRunningMode = {
171621
171632
  [ClimateHvacAction.preheating]: Thermostat3.ThermostatRunningMode.Heat,
171622
171633
  [ClimateHvacAction.defrosting]: Thermostat3.ThermostatRunningMode.Heat,
171623
171634
  [ClimateHvacAction.heating]: Thermostat3.ThermostatRunningMode.Heat,
171624
- [ClimateHvacAction.drying]: Thermostat3.ThermostatRunningMode.Heat,
171635
+ // Drying has no dedicated Matter RunningMode; reporting Heat made Apple
171636
+ // Home display "Heating to …" during dehumidification. Off is neutral and
171637
+ // getRunningState() downgrades it to FanOnly/Dry via systemMode.
171638
+ [ClimateHvacAction.drying]: Thermostat3.ThermostatRunningMode.Off,
171625
171639
  [ClimateHvacAction.cooling]: Thermostat3.ThermostatRunningMode.Cool,
171626
171640
  [ClimateHvacAction.fan]: Thermostat3.ThermostatRunningMode.Off,
171627
171641
  [ClimateHvacAction.idle]: Thermostat3.ThermostatRunningMode.Off,
@@ -172242,7 +172256,7 @@ function WindowCoveringServer2(config10) {
172242
172256
  }
172243
172257
 
172244
172258
  // src/matter/endpoints/legacy/cover/behaviors/cover-position-utils.ts
172245
- function adjustPositionForReading(position, flags2, matterSemantics) {
172259
+ function adjustPosition(position, flags2, matterSemantics) {
172246
172260
  if (position == null) {
172247
172261
  return null;
172248
172262
  }
@@ -172255,18 +172269,11 @@ function adjustPositionForReading(position, flags2, matterSemantics) {
172255
172269
  }
172256
172270
  return position;
172257
172271
  }
172272
+ function adjustPositionForReading(position, flags2, matterSemantics) {
172273
+ return adjustPosition(position, flags2, matterSemantics);
172274
+ }
172258
172275
  function adjustPositionForWriting(position, flags2, matterSemantics) {
172259
- if (position == null) {
172260
- return null;
172261
- }
172262
- const skipInversion = flags2?.coverDoNotInvertPercentage === true || flags2?.coverUseHomeAssistantPercentage === true || matterSemantics;
172263
- if (flags2?.coverSwapOpenClose === true && !skipInversion) {
172264
- return position;
172265
- }
172266
- if (!skipInversion) {
172267
- return 100 - position;
172268
- }
172269
- return position;
172276
+ return adjustPosition(position, flags2, matterSemantics);
172270
172277
  }
172271
172278
 
172272
172279
  // src/matter/endpoints/legacy/cover/behaviors/cover-window-covering-server.ts
@@ -172808,12 +172815,16 @@ function FanDevice2(homeAssistantEntity) {
172808
172815
  IdentifyServer2,
172809
172816
  BasicInformationServer2,
172810
172817
  HomeAssistantEntityBehavior,
172818
+ GroupsServer,
172819
+ ScenesManagementServer,
172811
172820
  FanOnOffServer,
172812
172821
  DefaultPowerSourceServer
172813
172822
  ) : OnOffPlugInUnitDevice.with(
172814
172823
  IdentifyServer2,
172815
172824
  BasicInformationServer2,
172816
172825
  HomeAssistantEntityBehavior,
172826
+ GroupsServer,
172827
+ ScenesManagementServer,
172817
172828
  FanOnOffServer
172818
172829
  );
172819
172830
  return onOffDevice.set({ homeAssistantEntity });
@@ -172842,6 +172853,7 @@ function FanDevice2(homeAssistantEntity) {
172842
172853
  IdentifyServer2,
172843
172854
  BasicInformationServer2,
172844
172855
  HomeAssistantEntityBehavior,
172856
+ GroupsServer,
172845
172857
  FanOnOffServer,
172846
172858
  FanFanControlServer.with(...features2),
172847
172859
  DefaultPowerSourceServer
@@ -172849,6 +172861,7 @@ function FanDevice2(homeAssistantEntity) {
172849
172861
  IdentifyServer2,
172850
172862
  BasicInformationServer2,
172851
172863
  HomeAssistantEntityBehavior,
172864
+ GroupsServer,
172852
172865
  FanOnOffServer,
172853
172866
  FanFanControlServer.with(...features2)
172854
172867
  );
@@ -173161,9 +173174,12 @@ var ColorControlServerBase = class extends FeaturedBase7 {
173161
173174
  ...skipColorTemp ? {} : { colorTemperatureMireds: effectiveMireds }
173162
173175
  });
173163
173176
  }
173177
+ const writingHueSat = this.features.hueSaturation && !skipHueSat;
173178
+ const writingColorTemp = !skipColorTemp && newColorMode === ColorControl3.ColorMode.ColorTemperatureMireds;
173179
+ const shouldPublishColorMode = writingHueSat && newColorMode !== ColorControl3.ColorMode.ColorTemperatureMireds || writingColorTemp;
173164
173180
  applyPatchState(this.state, {
173165
- ...skipColorTemp && skipHueSat ? {} : { colorMode: newColorMode },
173166
- ...this.features.hueSaturation && !skipHueSat ? {
173181
+ ...shouldPublishColorMode ? { colorMode: newColorMode } : {},
173182
+ ...writingHueSat ? {
173167
173183
  currentHue: hue,
173168
173184
  currentSaturation: saturation
173169
173185
  } : {}
@@ -173181,6 +173197,9 @@ var ColorControlServerBase = class extends FeaturedBase7 {
173181
173197
  this.agent
173182
173198
  );
173183
173199
  const targetKelvin = ColorConverter.temperatureMiredsToKelvin(targetMireds);
173200
+ if (targetKelvin == null) {
173201
+ return;
173202
+ }
173184
173203
  if (currentKelvin === targetKelvin) {
173185
173204
  return;
173186
173205
  }
@@ -173368,6 +173387,8 @@ var ColorTemperatureLightType = ColorTemperatureLightDevice.with(
173368
173387
  IdentifyServer2,
173369
173388
  BasicInformationServer2,
173370
173389
  HomeAssistantEntityBehavior,
173390
+ GroupsServer,
173391
+ ScenesManagementServer,
173371
173392
  LightOnOffServer,
173372
173393
  LightLevelControlServer,
173373
173394
  LightColorControlServer.with("ColorTemperature")
@@ -173379,6 +173400,8 @@ var DimmableLightType = DimmableLightDevice.with(
173379
173400
  IdentifyServer2,
173380
173401
  BasicInformationServer2,
173381
173402
  HomeAssistantEntityBehavior,
173403
+ GroupsServer,
173404
+ ScenesManagementServer,
173382
173405
  LightOnOffServer,
173383
173406
  LightLevelControlServer
173384
173407
  );
@@ -173386,6 +173409,8 @@ var DimmableLightWithBatteryType = DimmableLightDevice.with(
173386
173409
  IdentifyServer2,
173387
173410
  BasicInformationServer2,
173388
173411
  HomeAssistantEntityBehavior,
173412
+ GroupsServer,
173413
+ ScenesManagementServer,
173389
173414
  LightOnOffServer,
173390
173415
  LightLevelControlServer,
173391
173416
  DefaultPowerSourceServer
@@ -173406,6 +173431,8 @@ var ExtendedColorLightType = (supportsColorControl, supportsTemperature, hasBatt
173406
173431
  IdentifyServer2,
173407
173432
  BasicInformationServer2,
173408
173433
  HomeAssistantEntityBehavior,
173434
+ GroupsServer,
173435
+ ScenesManagementServer,
173409
173436
  LightOnOffServer,
173410
173437
  LightLevelControlServer,
173411
173438
  LightColorControlServer.with(...features2),
@@ -173416,6 +173443,8 @@ var ExtendedColorLightType = (supportsColorControl, supportsTemperature, hasBatt
173416
173443
  IdentifyServer2,
173417
173444
  BasicInformationServer2,
173418
173445
  HomeAssistantEntityBehavior,
173446
+ GroupsServer,
173447
+ ScenesManagementServer,
173419
173448
  LightOnOffServer,
173420
173449
  LightLevelControlServer,
173421
173450
  LightColorControlServer.with(...features2)
@@ -173428,12 +173457,16 @@ var OnOffLightType = OnOffLightDevice.with(
173428
173457
  IdentifyServer2,
173429
173458
  BasicInformationServer2,
173430
173459
  HomeAssistantEntityBehavior,
173460
+ GroupsServer,
173461
+ ScenesManagementServer,
173431
173462
  LightOnOffServer
173432
173463
  );
173433
173464
  var OnOffLightWithBatteryType = OnOffLightDevice.with(
173434
173465
  IdentifyServer2,
173435
173466
  BasicInformationServer2,
173436
173467
  HomeAssistantEntityBehavior,
173468
+ GroupsServer,
173469
+ ScenesManagementServer,
173437
173470
  LightOnOffServer,
173438
173471
  DefaultPowerSourceServer
173439
173472
  );
@@ -176477,6 +176510,8 @@ var DimmablePlugInUnitType = DimmablePlugInUnitDevice.with(
176477
176510
  IdentifyServer2,
176478
176511
  BasicInformationServer2,
176479
176512
  HomeAssistantEntityBehavior,
176513
+ GroupsServer,
176514
+ ScenesManagementServer,
176480
176515
  LightOnOffServer,
176481
176516
  LightLevelControlServer
176482
176517
  );
@@ -176488,12 +176523,16 @@ var SwitchEndpointType = OnOffPlugInUnitDevice.with(
176488
176523
  BasicInformationServer2,
176489
176524
  IdentifyServer2,
176490
176525
  HomeAssistantEntityBehavior,
176526
+ GroupsServer,
176527
+ ScenesManagementServer,
176491
176528
  SwitchOnOffServer
176492
176529
  );
176493
176530
  var SwitchWithBatteryEndpointType = OnOffPlugInUnitDevice.with(
176494
176531
  BasicInformationServer2,
176495
176532
  IdentifyServer2,
176496
176533
  HomeAssistantEntityBehavior,
176534
+ GroupsServer,
176535
+ ScenesManagementServer,
176497
176536
  SwitchOnOffServer,
176498
176537
  DefaultPowerSourceServer
176499
176538
  );
@@ -176877,7 +176916,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
176877
176916
  this.state.currentMode = newMode;
176878
176917
  return {
176879
176918
  status: ModeBase3.ModeChangeStatus.Success,
176880
- statusText: "Successfully switched mode"
176919
+ statusText: "Mode switched"
176881
176920
  };
176882
176921
  }
176883
176922
  };
@@ -179762,7 +179801,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
179762
179801
  async updateStates(states) {
179763
179802
  const state = states[this.entityId] ?? {};
179764
179803
  const mappedChanged = this.hasMappedEntityChanged(states);
179765
- if (!mappedChanged && state.state === this.lastState?.state && JSON.stringify(state.attributes) === JSON.stringify(this.lastState?.attributes)) {
179804
+ if (!mappedChanged && state.state === this.lastState?.state && isEqual(state.attributes, this.lastState?.attributes)) {
179766
179805
  return;
179767
179806
  }
179768
179807
  if (mappedChanged) {
@@ -180683,10 +180722,10 @@ var BridgeRegistry = class _BridgeRegistry {
180683
180722
  /**
180684
180723
  * Check if auto composed devices mode is enabled.
180685
180724
  * When enabled, temperature sensors with auto-mapped humidity/pressure/battery
180686
- * create real Matter Composed Devices (BridgedNodeEndpoint with sub-endpoints)
180687
- * instead of adding extra clusters to a flat TemperatureSensor endpoint.
180688
- * This ensures Apple Home, Google Home, and Alexa properly display
180689
- * humidity and pressure readings using their correct device types.
180725
+ * build real Matter Composed Devices (BridgedNodeEndpoint with sub-endpoints)
180726
+ * rather than stacking extra clusters onto a flat TemperatureSensor
180727
+ * Apple Home, Google Home, and Alexa render each sub-endpoint using its
180728
+ * own device type.
180690
180729
  */
180691
180730
  isAutoComposedDevicesEnabled() {
180692
180731
  return this.dataProvider.featureFlags?.autoComposedDevices === true;
@@ -181375,7 +181414,7 @@ var ServerModeBridge = class {
181375
181414
  this.wireSessionDiagnostics();
181376
181415
  this.scheduleWarmStart();
181377
181416
  logMemoryUsage(this.log, "server mode bridge running");
181378
- this.log.info("Server mode bridge started successfully");
181417
+ this.log.info("Server mode bridge started");
181379
181418
  diagnosticEventBus.emit("bridge_started", "Server mode bridge started", {
181380
181419
  bridgeId: this.id,
181381
181420
  bridgeName: this.dataProvider.name