@riddix/hamh 2.1.0-alpha.652 → 2.1.0-alpha.654

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.
@@ -146819,6 +146819,14 @@ var init_bridge_config_schema = __esm({
146819
146819
  description: "Fall back to the Home Assistant device registry serial_number when no per-entity customSerialNumber is configured. Default off because changing serialNumber after commissioning can confuse controllers. A per-entity customSerialNumber still takes precedence.",
146820
146820
  type: "boolean",
146821
146821
  default: false
146822
+ },
146823
+ coverSliderDebounceMs: {
146824
+ title: "Cover Slider Debounce (ms)",
146825
+ description: "Override the cover position-update debounce window for this bridge. Some controllers (Apple Home) stream slider updates while the user is still dragging, causing covers to start moving toward an intermediate target. Set to the time the bridge should wait after the last update before sending the final value to Home Assistant. 0 keeps the built-in two-phase debounce (400 ms initial / 150 ms subsequent), which fits most controllers. Try 800\u20131500 ms for slow blinds. A per-entity override on a single cover wins over this flag.",
146826
+ type: "number",
146827
+ minimum: 0,
146828
+ maximum: 5e3,
146829
+ default: 0
146822
146830
  }
146823
146831
  }
146824
146832
  };
@@ -147879,6 +147887,7 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
147879
147887
  mopIntensityEntity: config10.mopIntensityEntity,
147880
147888
  valetudoIdentifier: config10.valetudoIdentifier,
147881
147889
  coverSwapOpenClose: config10.coverSwapOpenClose,
147890
+ coverSliderDebounceMs: config10.coverSliderDebounceMs,
147882
147891
  disableClimateOnOff: config10.disableClimateOnOff,
147883
147892
  disableClimateFanControl: config10.disableClimateFanControl,
147884
147893
  customServiceAreas: config10.customServiceAreas,
@@ -148026,6 +148035,7 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
148026
148035
  temperatureEntity: config10.temperatureEntity,
148027
148036
  valetudoIdentifier: config10.valetudoIdentifier,
148028
148037
  coverSwapOpenClose: config10.coverSwapOpenClose,
148038
+ coverSliderDebounceMs: config10.coverSliderDebounceMs,
148029
148039
  disableClimateOnOff: config10.disableClimateOnOff,
148030
148040
  disableClimateFanControl: config10.disableClimateFanControl,
148031
148041
  customServiceAreas: config10.customServiceAreas,
@@ -148867,6 +148877,7 @@ function entityMappingApi(mappingStorage) {
148867
148877
  currentRoomEntity: body.currentRoomEntity,
148868
148878
  valetudoIdentifier: body.valetudoIdentifier,
148869
148879
  coverSwapOpenClose: body.coverSwapOpenClose,
148880
+ coverSliderDebounceMs: body.coverSliderDebounceMs,
148870
148881
  disableClimateOnOff: body.disableClimateOnOff,
148871
148882
  disableClimateFanControl: body.disableClimateFanControl,
148872
148883
  composedEntities: body.composedEntities
@@ -149332,6 +149343,7 @@ function configToProfileEntry(config10) {
149332
149343
  customFanSpeedTags: config10.customFanSpeedTags,
149333
149344
  valetudoIdentifier: config10.valetudoIdentifier,
149334
149345
  coverSwapOpenClose: config10.coverSwapOpenClose,
149346
+ coverSliderDebounceMs: config10.coverSliderDebounceMs,
149335
149347
  disableClimateOnOff: config10.disableClimateOnOff,
149336
149348
  disableClimateFanControl: config10.disableClimateFanControl
149337
149349
  };
@@ -149455,6 +149467,7 @@ function mappingProfileApi(mappingStorage) {
149455
149467
  customFanSpeedTags: entry.customFanSpeedTags,
149456
149468
  valetudoIdentifier: entry.valetudoIdentifier,
149457
149469
  coverSwapOpenClose: entry.coverSwapOpenClose,
149470
+ coverSliderDebounceMs: entry.coverSliderDebounceMs,
149458
149471
  disableClimateOnOff: entry.disableClimateOnOff,
149459
149472
  disableClimateFanControl: entry.disableClimateFanControl
149460
149473
  });
@@ -153357,11 +153370,12 @@ var EntityMappingStorage = class extends Service {
153357
153370
  currentRoomEntity: request.currentRoomEntity?.trim() || void 0,
153358
153371
  valetudoIdentifier: request.valetudoIdentifier?.trim() || void 0,
153359
153372
  coverSwapOpenClose: request.coverSwapOpenClose || void 0,
153373
+ coverSliderDebounceMs: sanitizeDebounceMs(request.coverSliderDebounceMs),
153360
153374
  disableClimateOnOff: request.disableClimateOnOff || void 0,
153361
153375
  disableClimateFanControl: request.disableClimateFanControl || void 0,
153362
153376
  composedEntities: request.composedEntities?.filter((e) => e.entityId?.trim()) ?? void 0
153363
153377
  };
153364
- if (!config10.matterDeviceType && !config10.customName && !config10.customProductName && !config10.customVendorName && !config10.customSerialNumber && config10.customVendorId === void 0 && config10.disabled !== true && !config10.filterLifeEntity && !config10.cleaningModeEntity && !config10.temperatureEntity && !config10.humidityEntity && !config10.batteryEntity && !config10.roomEntities && !config10.disableLockPin && !config10.powerEntity && !config10.energyEntity && !config10.pressureEntity && !config10.suctionLevelEntity && !config10.mopIntensityEntity && (!config10.customServiceAreas || config10.customServiceAreas.length === 0) && (!config10.customFanSpeedTags || Object.keys(config10.customFanSpeedTags).length === 0) && !config10.currentRoomEntity && !config10.valetudoIdentifier && !config10.coverSwapOpenClose && !config10.disableClimateOnOff && !config10.disableClimateFanControl && (!config10.composedEntities || config10.composedEntities.length === 0)) {
153378
+ if (!config10.matterDeviceType && !config10.customName && !config10.customProductName && !config10.customVendorName && !config10.customSerialNumber && config10.customVendorId === void 0 && config10.disabled !== true && !config10.filterLifeEntity && !config10.cleaningModeEntity && !config10.temperatureEntity && !config10.humidityEntity && !config10.batteryEntity && !config10.roomEntities && !config10.disableLockPin && !config10.powerEntity && !config10.energyEntity && !config10.pressureEntity && !config10.suctionLevelEntity && !config10.mopIntensityEntity && (!config10.customServiceAreas || config10.customServiceAreas.length === 0) && (!config10.customFanSpeedTags || Object.keys(config10.customFanSpeedTags).length === 0) && !config10.currentRoomEntity && !config10.valetudoIdentifier && !config10.coverSwapOpenClose && !config10.coverSliderDebounceMs && !config10.disableClimateOnOff && !config10.disableClimateFanControl && (!config10.composedEntities || config10.composedEntities.length === 0)) {
153365
153379
  bridgeMap.delete(request.entityId);
153366
153380
  } else {
153367
153381
  bridgeMap.set(request.entityId, config10);
@@ -153391,6 +153405,16 @@ function sanitizeVendorId(value) {
153391
153405
  }
153392
153406
  return n;
153393
153407
  }
153408
+ function sanitizeDebounceMs(value) {
153409
+ if (value === void 0 || value === null || value === "") {
153410
+ return void 0;
153411
+ }
153412
+ const n = typeof value === "string" ? Number(value) : value;
153413
+ if (typeof n !== "number" || !Number.isFinite(n) || n <= 0) {
153414
+ return void 0;
153415
+ }
153416
+ return Math.min(5e3, Math.round(n));
153417
+ }
153394
153418
 
153395
153419
  // src/services/storage/lock-credential-storage.ts
153396
153420
  init_service();
@@ -172163,6 +172187,18 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
172163
172187
  static DEBOUNCE_INITIAL_MS = 400;
172164
172188
  static DEBOUNCE_SUBSEQUENT_MS = 150;
172165
172189
  static COMMAND_SEQUENCE_THRESHOLD_MS = 600;
172190
+ // Per-entity override wins over per-bridge flag; both must be > 0 to count.
172191
+ resolveDebounceOverride(homeAssistant) {
172192
+ const fromEntity = homeAssistant.state.mapping?.coverSliderDebounceMs;
172193
+ if (typeof fromEntity === "number" && fromEntity > 0) {
172194
+ return fromEntity;
172195
+ }
172196
+ const fromBridge = this.env.get(BridgeDataProvider).featureFlags?.coverSliderDebounceMs;
172197
+ if (typeof fromBridge === "number" && fromBridge > 0) {
172198
+ return fromBridge;
172199
+ }
172200
+ return null;
172201
+ }
172166
172202
  async [Symbol.asyncDispose]() {
172167
172203
  if (this.liftDebounceTimer) {
172168
172204
  clearTimeout(this.liftDebounceTimer);
@@ -172384,9 +172420,10 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
172384
172420
  const timeSinceLastCommand = now - this.lastLiftCommandTime;
172385
172421
  this.lastLiftCommandTime = now;
172386
172422
  const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
172387
- const debounceMs = isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
172423
+ const overrideMs = this.resolveDebounceOverride(homeAssistant);
172424
+ const debounceMs = overrideMs != null ? overrideMs : isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
172388
172425
  logger179.debug(
172389
- `Lift command: target=${targetPosition}%, debounce=${debounceMs}ms (${isFirstInSequence ? "initial" : "subsequent"})`
172426
+ `Lift command: target=${targetPosition}%, debounce=${debounceMs}ms (${overrideMs != null ? "override" : isFirstInSequence ? "initial" : "subsequent"})`
172390
172427
  );
172391
172428
  if (this.liftDebounceTimer) {
172392
172429
  clearTimeout(this.liftDebounceTimer);
@@ -172433,9 +172470,10 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
172433
172470
  const timeSinceLastCommand = now - this.lastTiltCommandTime;
172434
172471
  this.lastTiltCommandTime = now;
172435
172472
  const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
172436
- const debounceMs = isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
172473
+ const overrideMs = this.resolveDebounceOverride(homeAssistant);
172474
+ const debounceMs = overrideMs != null ? overrideMs : isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
172437
172475
  logger179.debug(
172438
- `Tilt command: target=${targetPosition}%, debounce=${debounceMs}ms (${isFirstInSequence ? "initial" : "subsequent"})`
172476
+ `Tilt command: target=${targetPosition}%, debounce=${debounceMs}ms (${overrideMs != null ? "override" : isFirstInSequence ? "initial" : "subsequent"})`
172439
172477
  );
172440
172478
  if (this.tiltDebounceTimer) {
172441
172479
  clearTimeout(this.tiltDebounceTimer);