@riddix/hamh 2.1.0-alpha.795 → 2.1.0-alpha.797

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.
@@ -127325,6 +127325,9 @@ function entityMappingApi(mappingStorage) {
127325
127325
  valetudoIdentifier: body.valetudoIdentifier,
127326
127326
  coverSwapOpenClose: body.coverSwapOpenClose,
127327
127327
  coverExposeAsDimmableLight: body.coverExposeAsDimmableLight,
127328
+ selectExposeAsSwitch: body.selectExposeAsSwitch,
127329
+ selectSwitchOnOption: body.selectSwitchOnOption,
127330
+ selectSwitchOffOption: body.selectSwitchOffOption,
127328
127331
  coverSliderDebounceMs: body.coverSliderDebounceMs,
127329
127332
  updateThrottleMs: body.updateThrottleMs,
127330
127333
  disableClimateOnOff: body.disableClimateOnOff,
@@ -132133,6 +132136,9 @@ var EntityMappingStorage = class extends Service {
132133
132136
  valetudoIdentifier: request.valetudoIdentifier?.trim() || void 0,
132134
132137
  coverSwapOpenClose: request.coverSwapOpenClose || void 0,
132135
132138
  coverExposeAsDimmableLight: request.coverExposeAsDimmableLight || void 0,
132139
+ selectExposeAsSwitch: request.selectExposeAsSwitch || void 0,
132140
+ selectSwitchOnOption: request.selectSwitchOnOption || void 0,
132141
+ selectSwitchOffOption: request.selectSwitchOffOption || void 0,
132136
132142
  coverSliderDebounceMs: sanitizeDebounceMs(request.coverSliderDebounceMs),
132137
132143
  updateThrottleMs: sanitizeThrottleMs(request.updateThrottleMs),
132138
132144
  disableClimateOnOff: request.disableClimateOnOff || void 0,
@@ -132142,7 +132148,7 @@ var EntityMappingStorage = class extends Service {
132142
132148
  climateAutoMode: request.climateAutoMode || void 0,
132143
132149
  composedEntities: request.composedEntities?.filter((e) => e.entityId?.trim()) ?? void 0
132144
132150
  };
132145
- 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.chargingStateEntity && !config11.roomEntities && !config11.disableLockPin && !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.coverSliderDebounceMs && !config11.updateThrottleMs && !config11.disableClimateOnOff && !config11.disableClimateFanControl && !config11.climateKeepModeOnIdle && !config11.climateExposeFan && !config11.climateAutoMode && (!config11.composedEntities || config11.composedEntities.length === 0)) {
132151
+ 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.chargingStateEntity && !config11.roomEntities && !config11.disableLockPin && !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)) {
132146
132152
  bridgeMap.delete(request.entityId);
132147
132153
  } else {
132148
132154
  bridgeMap.set(request.entityId, config11);
@@ -148902,14 +148908,26 @@ var STALE_SESSION_QUIET_WINDOW_MS = 5 * 60 * 1e3;
148902
148908
  function staleSessionQuietWindowMs(flags2) {
148903
148909
  return flags2?.fastSessionRecovery ? 0 : STALE_SESSION_QUIET_WINDOW_MS;
148904
148910
  }
148905
- function staleSessionShouldClose(session, quietWindowMs = STALE_SESSION_QUIET_WINDOW_MS, now = Date.now()) {
148906
- if (session.subscriptions.size > 0 || session.isClosing) return false;
148911
+ function sessionIsQuiet(session, quietWindowMs = STALE_SESSION_QUIET_WINDOW_MS, now = Date.now()) {
148912
+ if (session.isClosing) return false;
148907
148913
  if (session.isPeerActive) return false;
148908
148914
  if (quietWindowMs > 0 && typeof session.timestamp === "number" && now - session.timestamp < quietWindowMs) {
148909
148915
  return false;
148910
148916
  }
148911
148917
  return true;
148912
148918
  }
148919
+ function staleSessionShouldClose(session, quietWindowMs = STALE_SESSION_QUIET_WINDOW_MS, now = Date.now()) {
148920
+ return session.subscriptions.size === 0 && sessionIsQuiet(session, quietWindowMs, now);
148921
+ }
148922
+ function selectSupersededSessions(sessions, newSession, quietWindowMs = STALE_SESSION_QUIET_WINDOW_MS, now = Date.now()) {
148923
+ const ids = [];
148924
+ for (const s of sessions) {
148925
+ if (s.id !== newSession.id && s.peerNodeId === newSession.peerNodeId && s.fabric?.fabricIndex === newSession.fabric?.fabricIndex && !s.isClosing && sessionIsQuiet(s, quietWindowMs, now)) {
148926
+ ids.push(s.id);
148927
+ }
148928
+ }
148929
+ return ids;
148930
+ }
148913
148931
  function seedExistingSessionStarts(startedAt, sessions, now = Date.now()) {
148914
148932
  for (const session of sessions) {
148915
148933
  if (!startedAt.has(session.id)) {
@@ -149296,6 +149314,36 @@ ${e?.toString()}`);
149296
149314
  });
149297
149315
  }
149298
149316
  }
149317
+ const quietWindowMs = staleSessionQuietWindowMs(
149318
+ this.dataProvider.featureFlags
149319
+ );
149320
+ const now = Date.now();
149321
+ const supersededIds = new Set(
149322
+ selectSupersededSessions(
149323
+ [...sessionManager.sessions],
149324
+ newSession,
149325
+ quietWindowMs,
149326
+ now
149327
+ )
149328
+ );
149329
+ const closes = [];
149330
+ for (const s of [...sessionManager.sessions]) {
149331
+ if (!supersededIds.has(s.id) || s.subscriptions.size === 0) continue;
149332
+ const quietSec = Math.round((now - s.timestamp) / 1e3);
149333
+ this.log.info(
149334
+ `Closing superseded session ${s.id} (peer ${s.peerNodeId}, ${s.subscriptions.size} subs, quiet ${quietSec}s), replaced by session ${newSession.id}`
149335
+ );
149336
+ closes.push(
149337
+ s.initiateClose().catch(
149338
+ () => s.initiateForceClose({
149339
+ cause: new Error("superseded session, forcing")
149340
+ })
149341
+ )
149342
+ );
149343
+ }
149344
+ if (closes.length > 0) {
149345
+ Promise.allSettled(closes).then(() => this.triggerMdnsReAnnounce());
149346
+ }
149299
149347
  };
149300
149348
  this.sessionDeletedHandler = (session) => {
149301
149349
  this.sessionStartedAt.delete(session.id);
@@ -158252,6 +158300,43 @@ var SelectModeServer = buildSelectModeServer("select.select_option");
158252
158300
  var InputSelectModeServer = buildSelectModeServer(
158253
158301
  "input_select.select_option"
158254
158302
  );
158303
+ function buildSelectSwitchType(action) {
158304
+ const option = (agent, key) => {
158305
+ const mapping = agent.get(HomeAssistantEntityBehavior).state.mapping;
158306
+ return key === "on" ? mapping?.selectSwitchOnOption : mapping?.selectSwitchOffOption;
158307
+ };
158308
+ return OnOffPlugInUnitDevice.with(
158309
+ BasicInformationServer2,
158310
+ IdentifyServer2,
158311
+ HomeAssistantEntityBehavior,
158312
+ GroupsServer,
158313
+ ScenesManagementServer,
158314
+ OnOffServer2({
158315
+ // Case-insensitive like the ModeSelect path, some integrations
158316
+ // report options with different casing.
158317
+ isOn: (state, agent) => state.state?.toLowerCase() === option(agent, "on")?.toLowerCase(),
158318
+ turnOn: (_, agent) => ({
158319
+ action,
158320
+ data: { option: option(agent, "on") }
158321
+ }),
158322
+ turnOff: (_, agent) => ({
158323
+ action,
158324
+ data: { option: option(agent, "off") }
158325
+ })
158326
+ })
158327
+ );
158328
+ }
158329
+ var SelectSwitchType = buildSelectSwitchType("select.select_option");
158330
+ var InputSelectSwitchType = buildSelectSwitchType(
158331
+ "input_select.select_option"
158332
+ );
158333
+ function selectAsSwitch(homeAssistantEntity, type) {
158334
+ const mapping = homeAssistantEntity.mapping;
158335
+ if (mapping?.selectExposeAsSwitch !== true || !mapping.selectSwitchOnOption || !mapping.selectSwitchOffOption) {
158336
+ return void 0;
158337
+ }
158338
+ return type.set({ homeAssistantEntity });
158339
+ }
158255
158340
  var SelectEndpointType = ModeSelectDevice.with(
158256
158341
  BasicInformationServer2,
158257
158342
  IdentifyServer2,
@@ -158265,6 +158350,10 @@ var InputSelectEndpointType = ModeSelectDevice.with(
158265
158350
  InputSelectModeServer
158266
158351
  );
158267
158352
  function SelectDevice(homeAssistantEntity) {
158353
+ const asSwitch = selectAsSwitch(homeAssistantEntity, SelectSwitchType);
158354
+ if (asSwitch) {
158355
+ return asSwitch;
158356
+ }
158268
158357
  const attrs = homeAssistantEntity.entity.state.attributes;
158269
158358
  const options = attrs.options ?? [];
158270
158359
  if (options.length === 0) {
@@ -158282,6 +158371,10 @@ function SelectDevice(homeAssistantEntity) {
158282
158371
  });
158283
158372
  }
158284
158373
  function InputSelectDevice(homeAssistantEntity) {
158374
+ const asSwitch = selectAsSwitch(homeAssistantEntity, InputSelectSwitchType);
158375
+ if (asSwitch) {
158376
+ return asSwitch;
158377
+ }
158285
158378
  const attrs = homeAssistantEntity.entity.state.attributes;
158286
158379
  const options = attrs.options ?? [];
158287
158380
  if (options.length === 0) {
@@ -165497,6 +165590,36 @@ ${e?.toString()}`);
165497
165590
  });
165498
165591
  }
165499
165592
  }
165593
+ const quietWindowMs = staleSessionQuietWindowMs(
165594
+ this.dataProvider.featureFlags
165595
+ );
165596
+ const now = Date.now();
165597
+ const supersededIds = new Set(
165598
+ selectSupersededSessions(
165599
+ [...sessionManager.sessions],
165600
+ newSession,
165601
+ quietWindowMs,
165602
+ now
165603
+ )
165604
+ );
165605
+ const closes = [];
165606
+ for (const s of [...sessionManager.sessions]) {
165607
+ if (!supersededIds.has(s.id) || s.subscriptions.size === 0) continue;
165608
+ const quietSec = Math.round((now - s.timestamp) / 1e3);
165609
+ this.log.info(
165610
+ `Closing superseded session ${s.id} (peer ${s.peerNodeId}, ${s.subscriptions.size} subs, quiet ${quietSec}s), replaced by session ${newSession.id}`
165611
+ );
165612
+ closes.push(
165613
+ s.initiateClose().catch(
165614
+ () => s.initiateForceClose({
165615
+ cause: new Error("superseded session, forcing")
165616
+ })
165617
+ )
165618
+ );
165619
+ }
165620
+ if (closes.length > 0) {
165621
+ Promise.allSettled(closes).then(() => this.triggerMdnsReAnnounce());
165622
+ }
165500
165623
  };
165501
165624
  this.sessionDeletedHandler = (session) => {
165502
165625
  this.sessionStartedAt.delete(session.id);