@riddix/hamh 2.1.0-alpha.770 → 2.1.0-alpha.772

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.
@@ -125230,6 +125230,12 @@ var init_bridge_config_schema = __esm({
125230
125230
  minimum: 0,
125231
125231
  maximum: 5e3,
125232
125232
  default: 0
125233
+ },
125234
+ fastSessionRecovery: {
125235
+ title: "Fast Session Recovery (Google offline workaround)",
125236
+ 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.",
125237
+ type: "boolean",
125238
+ default: false
125233
125239
  }
125234
125240
  }
125235
125241
  };
@@ -126317,6 +126323,7 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
126317
126323
  customServiceAreas: config11.customServiceAreas,
126318
126324
  customFanSpeedTags: config11.customFanSpeedTags,
126319
126325
  fanWindPresets: config11.fanWindPresets,
126326
+ fanRestoreSpeedOnPowerOn: config11.fanRestoreSpeedOnPowerOn,
126320
126327
  composedEntities: config11.composedEntities
126321
126328
  });
126322
126329
  mappingsRestored++;
@@ -127303,6 +127310,7 @@ function entityMappingApi(mappingStorage) {
127303
127310
  customServiceAreas: body.customServiceAreas,
127304
127311
  customFanSpeedTags: body.customFanSpeedTags,
127305
127312
  fanWindPresets: body.fanWindPresets,
127313
+ fanRestoreSpeedOnPowerOn: body.fanRestoreSpeedOnPowerOn,
127306
127314
  currentRoomEntity: body.currentRoomEntity,
127307
127315
  cleanedAreaEntity: body.cleanedAreaEntity,
127308
127316
  disableCustomAreaRoomModes: body.disableCustomAreaRoomModes,
@@ -127789,6 +127797,7 @@ function configToProfileEntry(config11) {
127789
127797
  customServiceAreas: config11.customServiceAreas,
127790
127798
  customFanSpeedTags: config11.customFanSpeedTags,
127791
127799
  fanWindPresets: config11.fanWindPresets,
127800
+ fanRestoreSpeedOnPowerOn: config11.fanRestoreSpeedOnPowerOn,
127792
127801
  valetudoIdentifier: config11.valetudoIdentifier,
127793
127802
  coverSwapOpenClose: config11.coverSwapOpenClose,
127794
127803
  coverSliderDebounceMs: config11.coverSliderDebounceMs,
@@ -127917,6 +127926,7 @@ function mappingProfileApi(mappingStorage) {
127917
127926
  customServiceAreas: entry.customServiceAreas,
127918
127927
  customFanSpeedTags: entry.customFanSpeedTags,
127919
127928
  fanWindPresets: entry.fanWindPresets,
127929
+ fanRestoreSpeedOnPowerOn: entry.fanRestoreSpeedOnPowerOn,
127920
127930
  valetudoIdentifier: entry.valetudoIdentifier,
127921
127931
  coverSwapOpenClose: entry.coverSwapOpenClose,
127922
127932
  coverSliderDebounceMs: entry.coverSliderDebounceMs,
@@ -132080,6 +132090,7 @@ var EntityMappingStorage = class extends Service {
132080
132090
  ) ?? void 0,
132081
132091
  customFanSpeedTags: request.customFanSpeedTags && Object.keys(request.customFanSpeedTags).length > 0 ? request.customFanSpeedTags : void 0,
132082
132092
  fanWindPresets: request.fanWindPresets && ((request.fanWindPresets.natural?.length ?? 0) > 0 || (request.fanWindPresets.sleep?.length ?? 0) > 0) ? request.fanWindPresets : void 0,
132093
+ fanRestoreSpeedOnPowerOn: request.fanRestoreSpeedOnPowerOn || void 0,
132083
132094
  currentRoomEntity: request.currentRoomEntity?.trim() || void 0,
132084
132095
  cleanedAreaEntity: request.cleanedAreaEntity?.trim() || void 0,
132085
132096
  disableCustomAreaRoomModes: request.disableCustomAreaRoomModes || void 0,
@@ -132095,7 +132106,7 @@ var EntityMappingStorage = class extends Service {
132095
132106
  climateAutoMode: request.climateAutoMode || void 0,
132096
132107
  composedEntities: request.composedEntities?.filter((e) => e.entityId?.trim()) ?? void 0
132097
132108
  };
132098
- 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.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)) {
132109
+ 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)) {
132099
132110
  bridgeMap.delete(request.entityId);
132100
132111
  } else {
132101
132112
  bridgeMap.set(request.entityId, config11);
@@ -148857,6 +148868,10 @@ function seedExistingSessionStarts(startedAt, sessions, now = Date.now()) {
148857
148868
  // src/services/bridges/bridge.ts
148858
148869
  var AUTO_FORCE_SYNC_INTERVAL_MS = 9e4;
148859
148870
  var DEAD_SESSION_TIMEOUT_MS = 6e4;
148871
+ var FAST_DEAD_SESSION_TIMEOUT_MS = 5e3;
148872
+ function deadSessionTimeoutMs(flags2) {
148873
+ return flags2?.fastSessionRecovery ? FAST_DEAD_SESSION_TIMEOUT_MS : DEAD_SESSION_TIMEOUT_MS;
148874
+ }
148860
148875
  var SHUTDOWN_SESSION_CLOSE_TIMEOUT_MS = 2500;
148861
148876
  var Bridge = class {
148862
148877
  constructor(env, logger234, dataProvider, endpointManager) {
@@ -149171,12 +149186,15 @@ ${e?.toString()}`);
149171
149186
  `All subscriptions lost, ${sessions.length} session(s) still active, waiting for controller to re-subscribe`
149172
149187
  );
149173
149188
  if (!this.deadSessionTimer) {
149189
+ const timeoutMs = deadSessionTimeoutMs(
149190
+ this.dataProvider.featureFlags
149191
+ );
149174
149192
  this.deadSessionTimer = setTimeout(() => {
149175
149193
  this.deadSessionTimer = null;
149176
149194
  this.closeDeadSessions();
149177
- }, DEAD_SESSION_TIMEOUT_MS);
149195
+ }, timeoutMs);
149178
149196
  this.log.info(
149179
- `Scheduled dead session cleanup in ${DEAD_SESSION_TIMEOUT_MS / 1e3}s`
149197
+ `Scheduled dead session cleanup in ${timeoutMs / 1e3}s`
149180
149198
  );
149181
149199
  }
149182
149200
  } else if (totalSubs > 0 && this.deadSessionTimer) {
@@ -149192,7 +149210,7 @@ ${e?.toString()}`);
149192
149210
  setTimeout(() => {
149193
149211
  this.staleSessionTimers.delete(session.id);
149194
149212
  this.closeStaleSession(session.id);
149195
- }, DEAD_SESSION_TIMEOUT_MS)
149213
+ }, deadSessionTimeoutMs(this.dataProvider.featureFlags))
149196
149214
  );
149197
149215
  } else if (session.subscriptions.size > 0 && this.staleSessionTimers.has(session.id)) {
149198
149216
  clearTimeout(this.staleSessionTimers.get(session.id));
@@ -149256,7 +149274,7 @@ ${e?.toString()}`);
149256
149274
  for (const s of [...sessionManager.sessions]) {
149257
149275
  if (s.id === sessionId && !s.isClosing && s.subscriptions.size === 0) {
149258
149276
  this.log.warn(
149259
- `Closing stale session ${s.id} (peer ${s.peerNodeId}, no subscriptions for ${DEAD_SESSION_TIMEOUT_MS / 1e3}s)`
149277
+ `Closing stale session ${s.id} (peer ${s.peerNodeId}, no subscriptions for ${deadSessionTimeoutMs(this.dataProvider.featureFlags) / 1e3}s)`
149260
149278
  );
149261
149279
  s.initiateClose().catch(() => {
149262
149280
  return s.initiateForceClose({
@@ -149278,7 +149296,7 @@ ${e?.toString()}`);
149278
149296
  for (const s of sessions) {
149279
149297
  if (!s.isClosing && s.subscriptions.size === 0) {
149280
149298
  this.log.warn(
149281
- `Closing dead session ${s.id} (peer ${s.peerNodeId}, no subscriptions for ${DEAD_SESSION_TIMEOUT_MS / 1e3}s)`
149299
+ `Closing dead session ${s.id} (peer ${s.peerNodeId}, no subscriptions for ${deadSessionTimeoutMs(this.dataProvider.featureFlags) / 1e3}s)`
149282
149300
  );
149283
149301
  closes.push(
149284
149302
  s.initiateClose().catch(() => {
@@ -151101,6 +151119,11 @@ var FanControlServerBase = class extends FeaturedBase5 {
151101
151119
  if (!homeAssistant.isAvailable) {
151102
151120
  return;
151103
151121
  }
151122
+ const restoreOnPowerOn = homeAssistant.state.mapping?.fanRestoreSpeedOnPowerOn === true;
151123
+ const wasOff = this.agent.has(OnOffBehavior) && !this.agent.get(OnOffBehavior).state.onOff;
151124
+ if (restoreOnPowerOn && wasOff && this.lastNonZeroPercent > 0 && percentage > 0) {
151125
+ percentage = this.lastNonZeroPercent;
151126
+ }
151104
151127
  const config11 = this.state.config;
151105
151128
  const supportsPercentage = config11.supportsPercentage(
151106
151129
  homeAssistant.entity.state,