@riddix/hamh 2.1.0-alpha.377 → 2.1.0-alpha.379

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.
@@ -166424,35 +166424,163 @@ function AirPurifierEndpoint(homeAssistantEntity) {
166424
166424
 
166425
166425
  // src/matter/endpoints/legacy/alarm-control-panel/index.ts
166426
166426
  init_home_assistant_entity_behavior();
166427
- var AlarmPanelOnOffServer = OnOffServer2({
166428
- turnOn: () => ({
166429
- action: "alarm_control_panel.alarm_arm_away"
166430
- }),
166431
- turnOff: () => ({
166427
+
166428
+ // src/matter/behaviors/mode-select-server.ts
166429
+ init_esm();
166430
+ init_home_assistant_entity_behavior();
166431
+ var logger161 = Logger.get("ModeSelectServer");
166432
+ var ModeSelectServerBase = class extends ModeSelectServer {
166433
+ async initialize() {
166434
+ await super.initialize();
166435
+ const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
166436
+ this.update(homeAssistant.entity);
166437
+ this.reactTo(homeAssistant.onChange, this.update);
166438
+ }
166439
+ update(entity) {
166440
+ if (!entity.state) {
166441
+ return;
166442
+ }
166443
+ const config10 = this.state.config;
166444
+ const options = config10.getOptions(entity);
166445
+ const current = config10.getCurrentOption(entity);
166446
+ if (options.length === 0) {
166447
+ return;
166448
+ }
166449
+ const currentIndex = current ? options.findIndex((o) => o.toLowerCase() === current.toLowerCase()) : -1;
166450
+ applyPatchState(this.state, {
166451
+ currentMode: currentIndex >= 0 ? currentIndex : 0
166452
+ });
166453
+ }
166454
+ changeToMode(request) {
166455
+ const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
166456
+ const config10 = this.state.config;
166457
+ const options = config10.getOptions(homeAssistant.entity);
166458
+ const { newMode } = request;
166459
+ if (newMode < 0 || newMode >= options.length) {
166460
+ logger161.warn(
166461
+ `[${homeAssistant.entityId}] Invalid mode ${newMode}, options: [${options.join(", ")}]`
166462
+ );
166463
+ return;
166464
+ }
166465
+ const option = options[newMode];
166466
+ logger161.info(
166467
+ `[${homeAssistant.entityId}] changeToMode(${newMode}) -> "${option}"`
166468
+ );
166469
+ applyPatchState(this.state, { currentMode: newMode });
166470
+ homeAssistant.callAction(config10.selectOption(option));
166471
+ }
166472
+ };
166473
+ ((ModeSelectServerBase2) => {
166474
+ class State extends ModeSelectServer.State {
166475
+ config;
166476
+ }
166477
+ ModeSelectServerBase2.State = State;
166478
+ })(ModeSelectServerBase || (ModeSelectServerBase = {}));
166479
+ function ModeSelectServer2(config10) {
166480
+ return ModeSelectServerBase.set({ config: config10 });
166481
+ }
166482
+
166483
+ // src/matter/endpoints/legacy/alarm-control-panel/index.ts
166484
+ var FEATURE_ARM_HOME = 1;
166485
+ var FEATURE_ARM_AWAY = 2;
166486
+ var FEATURE_ARM_NIGHT = 4;
166487
+ var FEATURE_ARM_CUSTOM_BYPASS = 16;
166488
+ var FEATURE_ARM_VACATION = 32;
166489
+ var ALL_ALARM_MODES = [
166490
+ {
166491
+ label: "Disarmed",
166492
+ haState: "disarmed",
166432
166493
  action: "alarm_control_panel.alarm_disarm"
166433
- }),
166434
- isOn: (state) => {
166435
- const armedStates = [
166436
- "armed_away",
166437
- "armed_home",
166438
- "armed_night",
166439
- "armed_vacation",
166440
- "armed_custom_bypass",
166441
- "arming",
166442
- "pending",
166443
- "triggered"
166444
- ];
166445
- return armedStates.includes(state.state);
166494
+ },
166495
+ {
166496
+ label: "Armed Home",
166497
+ haState: "armed_home",
166498
+ action: "alarm_control_panel.alarm_arm_home",
166499
+ featureFlag: FEATURE_ARM_HOME
166500
+ },
166501
+ {
166502
+ label: "Armed Away",
166503
+ haState: "armed_away",
166504
+ action: "alarm_control_panel.alarm_arm_away",
166505
+ featureFlag: FEATURE_ARM_AWAY
166506
+ },
166507
+ {
166508
+ label: "Armed Night",
166509
+ haState: "armed_night",
166510
+ action: "alarm_control_panel.alarm_arm_night",
166511
+ featureFlag: FEATURE_ARM_NIGHT
166512
+ },
166513
+ {
166514
+ label: "Armed Vacation",
166515
+ haState: "armed_vacation",
166516
+ action: "alarm_control_panel.alarm_arm_vacation",
166517
+ featureFlag: FEATURE_ARM_VACATION
166518
+ },
166519
+ {
166520
+ label: "Armed Custom",
166521
+ haState: "armed_custom_bypass",
166522
+ action: "alarm_control_panel.alarm_arm_custom_bypass",
166523
+ featureFlag: FEATURE_ARM_CUSTOM_BYPASS
166446
166524
  }
166525
+ ];
166526
+ function getAlarmModes(attrs) {
166527
+ const features2 = attrs.supported_features ?? 0;
166528
+ if (features2 === 0) {
166529
+ return ALL_ALARM_MODES.filter(
166530
+ (m) => !m.featureFlag || m.featureFlag === FEATURE_ARM_AWAY
166531
+ );
166532
+ }
166533
+ return ALL_ALARM_MODES.filter(
166534
+ (m) => !m.featureFlag || (features2 & m.featureFlag) !== 0
166535
+ );
166536
+ }
166537
+ function getAlarmOptions(entity) {
166538
+ const attrs = entity.state.attributes;
166539
+ return getAlarmModes(attrs).map((m) => m.label);
166540
+ }
166541
+ function getCurrentAlarmOption(entity) {
166542
+ const attrs = entity.state.attributes;
166543
+ const modes = getAlarmModes(attrs);
166544
+ const mode = modes.find((m) => m.haState === entity.state.state);
166545
+ return mode?.label;
166546
+ }
166547
+ function selectAlarmOption(option) {
166548
+ const mode = ALL_ALARM_MODES.find((m) => m.label === option);
166549
+ return { action: mode?.action ?? "alarm_control_panel.alarm_disarm" };
166550
+ }
166551
+ var AlarmModeServer = ModeSelectServer2({
166552
+ getOptions: getAlarmOptions,
166553
+ getCurrentOption: getCurrentAlarmOption,
166554
+ selectOption: selectAlarmOption
166447
166555
  });
166448
- var AlarmPanelEndpointType = OnOffPlugInUnitDevice.with(
166556
+ var AlarmPanelEndpointType = ModeSelectDevice.with(
166449
166557
  BasicInformationServer2,
166450
166558
  IdentifyServer2,
166451
166559
  HomeAssistantEntityBehavior,
166452
- AlarmPanelOnOffServer
166560
+ AlarmModeServer
166453
166561
  );
166454
166562
  function AlarmControlPanelDevice(homeAssistantEntity) {
166455
- return AlarmPanelEndpointType.set({ homeAssistantEntity });
166563
+ const attrs = homeAssistantEntity.entity.state.attributes;
166564
+ const modes = getAlarmModes(attrs);
166565
+ if (modes.length === 0) {
166566
+ return void 0;
166567
+ }
166568
+ const currentMode = modes.find(
166569
+ (m) => m.haState === homeAssistantEntity.entity.state.state
166570
+ );
166571
+ const currentIndex = currentMode ? modes.indexOf(currentMode) : 0;
166572
+ return AlarmPanelEndpointType.set({
166573
+ homeAssistantEntity,
166574
+ modeSelect: {
166575
+ description: homeAssistantEntity.customName ?? homeAssistantEntity.entity.state.attributes.friendly_name ?? "Alarm Panel",
166576
+ supportedModes: modes.map((m, index) => ({
166577
+ label: m.label,
166578
+ mode: index,
166579
+ semanticTags: []
166580
+ })),
166581
+ currentMode: currentIndex >= 0 ? currentIndex : 0
166582
+ }
166583
+ });
166456
166584
  }
166457
166585
 
166458
166586
  // src/matter/endpoints/legacy/automation/index.ts
@@ -166754,7 +166882,7 @@ var WaterLeakDetectorType = WaterLeakDetectorDevice.with(
166754
166882
  );
166755
166883
 
166756
166884
  // src/matter/endpoints/legacy/binary-sensor/index.ts
166757
- var logger161 = Logger.get("BinarySensorDevice");
166885
+ var logger162 = Logger.get("BinarySensorDevice");
166758
166886
  var deviceClasses = {
166759
166887
  [BinarySensorDeviceClass.CarbonMonoxide]: CoAlarmType,
166760
166888
  [BinarySensorDeviceClass.Gas]: CoAlarmType,
@@ -166804,11 +166932,11 @@ function BinarySensorDevice(homeAssistantEntity) {
166804
166932
  const originalTypeName = type.name;
166805
166933
  if (hasBattery && batteryTypes.has(type)) {
166806
166934
  type = batteryTypes.get(type);
166807
- logger161.info(
166935
+ logger162.info(
166808
166936
  `[${entityId}] Using battery variant: ${originalTypeName} -> ${type.name}, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
166809
166937
  );
166810
166938
  } else if (hasBattery) {
166811
- logger161.warn(
166939
+ logger162.warn(
166812
166940
  `[${entityId}] Has battery but no variant available for ${originalTypeName}`
166813
166941
  );
166814
166942
  }
@@ -166955,7 +167083,7 @@ init_home_assistant_entity_behavior();
166955
167083
  // src/matter/behaviors/thermostat-server.ts
166956
167084
  init_esm();
166957
167085
  init_home_assistant_entity_behavior();
166958
- var logger162 = Logger.get("ThermostatServer");
167086
+ var logger163 = Logger.get("ThermostatServer");
166959
167087
  var SystemMode = Thermostat3.SystemMode;
166960
167088
  var RunningMode = Thermostat3.ThermostatRunningMode;
166961
167089
  var nudgingSetpoints = /* @__PURE__ */ new Set();
@@ -167013,7 +167141,7 @@ var HeatingAndCoolingFeaturedBase = ThermostatServer.with("Heating", "Cooling").
167013
167141
  );
167014
167142
  function thermostatPreInitialize(self) {
167015
167143
  const currentLocal = self.state.localTemperature;
167016
- logger162.debug(
167144
+ logger163.debug(
167017
167145
  `initialize: features - heating=${self.features.heating}, cooling=${self.features.cooling}`
167018
167146
  );
167019
167147
  const localValue = typeof currentLocal === "number" && !Number.isNaN(currentLocal) ? currentLocal : currentLocal === null ? null : 2100;
@@ -167036,7 +167164,7 @@ function thermostatPreInitialize(self) {
167036
167164
  const coolingValue = typeof currentCooling === "number" && !Number.isNaN(currentCooling) ? currentCooling : 2400;
167037
167165
  self.state.occupiedCoolingSetpoint = coolingValue;
167038
167166
  }
167039
- logger162.debug(
167167
+ logger163.debug(
167040
167168
  `initialize: after force-set - local=${self.state.localTemperature}`
167041
167169
  );
167042
167170
  self.state.thermostatRunningState = runningStateAllOff;
@@ -167118,7 +167246,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
167118
167246
  maxCoolLimit,
167119
167247
  "cool"
167120
167248
  );
167121
- logger162.debug(
167249
+ logger163.debug(
167122
167250
  `update: limits heat=[${minHeatLimit}, ${maxHeatLimit}], cool=[${minCoolLimit}, ${maxCoolLimit}], systemMode=${systemMode}, runningMode=${runningMode}`
167123
167251
  );
167124
167252
  applyPatchState(this.state, {
@@ -167191,18 +167319,18 @@ var ThermostatServerBase = class extends FullFeaturedBase {
167191
167319
  */
167192
167320
  // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Called via thermostatPostInitialize + prototype copy
167193
167321
  heatingSetpointChanging(value, _oldValue, context) {
167194
- logger162.debug(
167322
+ logger163.debug(
167195
167323
  `heatingSetpointChanging: value=${value}, oldValue=${_oldValue}, isOffline=${transactionIsOffline(context)}`
167196
167324
  );
167197
167325
  if (transactionIsOffline(context)) {
167198
- logger162.debug(
167326
+ logger163.debug(
167199
167327
  "heatingSetpointChanging: skipping - transaction is offline"
167200
167328
  );
167201
167329
  return;
167202
167330
  }
167203
167331
  const next = Temperature.celsius(value / 100);
167204
167332
  if (!next) {
167205
- logger162.debug("heatingSetpointChanging: skipping - invalid temperature");
167333
+ logger163.debug("heatingSetpointChanging: skipping - invalid temperature");
167206
167334
  return;
167207
167335
  }
167208
167336
  this.agent.asLocalActor(() => {
@@ -167213,7 +167341,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
167213
167341
  this.agent
167214
167342
  );
167215
167343
  const currentMode = this.state.systemMode;
167216
- logger162.debug(
167344
+ logger163.debug(
167217
167345
  `heatingSetpointChanging: supportsRange=${supportsRange}, systemMode=${currentMode}, features.heating=${this.features.heating}, features.cooling=${this.features.cooling}`
167218
167346
  );
167219
167347
  if (!supportsRange) {
@@ -167223,12 +167351,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
167223
167351
  const isOff = currentMode === Thermostat3.SystemMode.Off;
167224
167352
  if (isOff && this.features.heating) {
167225
167353
  if (nudgingSetpoints.has(homeAssistant.entityId)) {
167226
- logger162.debug(
167354
+ logger163.debug(
167227
167355
  `heatingSetpointChanging: skipping auto-resume - nudge write in progress`
167228
167356
  );
167229
167357
  return;
167230
167358
  }
167231
- logger162.info(
167359
+ logger163.info(
167232
167360
  `heatingSetpointChanging: auto-resume - switching to Heat (was Off)`
167233
167361
  );
167234
167362
  const modeAction = config10.setSystemMode(
@@ -167237,17 +167365,17 @@ var ThermostatServerBase = class extends FullFeaturedBase {
167237
167365
  );
167238
167366
  homeAssistant.callAction(modeAction);
167239
167367
  } else if (!isAutoMode && !isHeatingMode) {
167240
- logger162.debug(
167368
+ logger163.debug(
167241
167369
  `heatingSetpointChanging: skipping - not in heating/auto mode (mode=${currentMode}, haMode=${haHvacMode})`
167242
167370
  );
167243
167371
  return;
167244
167372
  }
167245
- logger162.debug(
167373
+ logger163.debug(
167246
167374
  `heatingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isHeatingMode=${isHeatingMode}, isOff=${isOff}, haMode=${haHvacMode}`
167247
167375
  );
167248
167376
  }
167249
167377
  const coolingSetpoint = this.features.cooling ? this.state.occupiedCoolingSetpoint : value;
167250
- logger162.debug(
167378
+ logger163.debug(
167251
167379
  `heatingSetpointChanging: calling setTemperature with heat=${next.celsius(true)}, cool=${coolingSetpoint}`
167252
167380
  );
167253
167381
  this.setTemperature(
@@ -167286,12 +167414,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
167286
167414
  const isOff = currentMode === Thermostat3.SystemMode.Off;
167287
167415
  if (isOff && !this.features.heating && this.features.cooling) {
167288
167416
  if (nudgingSetpoints.has(homeAssistant.entityId)) {
167289
- logger162.debug(
167417
+ logger163.debug(
167290
167418
  `coolingSetpointChanging: skipping auto-resume - nudge write in progress`
167291
167419
  );
167292
167420
  return;
167293
167421
  }
167294
- logger162.info(
167422
+ logger163.info(
167295
167423
  `coolingSetpointChanging: auto-resume - switching to Cool (was Off)`
167296
167424
  );
167297
167425
  const modeAction = config10.setSystemMode(
@@ -167300,12 +167428,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
167300
167428
  );
167301
167429
  homeAssistant.callAction(modeAction);
167302
167430
  } else if (!isAutoMode && !isCoolingMode) {
167303
- logger162.debug(
167431
+ logger163.debug(
167304
167432
  `coolingSetpointChanging: skipping - not in cooling/auto mode (mode=${currentMode}, haMode=${haHvacMode})`
167305
167433
  );
167306
167434
  return;
167307
167435
  }
167308
- logger162.debug(
167436
+ logger163.debug(
167309
167437
  `coolingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isCoolingMode=${isCoolingMode}, isOff=${isOff}, haMode=${haHvacMode}`
167310
167438
  );
167311
167439
  }
@@ -167382,7 +167510,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
167382
167510
  const effectiveMax = max ?? 5e3;
167383
167511
  if (value == null || Number.isNaN(value)) {
167384
167512
  const defaultValue = type === "heat" ? 2e3 : 2400;
167385
- logger162.debug(
167513
+ logger163.debug(
167386
167514
  `${type} setpoint is undefined, using default: ${defaultValue}`
167387
167515
  );
167388
167516
  return Math.max(effectiveMin, Math.min(effectiveMax, defaultValue));
@@ -167822,7 +167950,7 @@ init_home_assistant_entity_behavior();
167822
167950
  init_esm();
167823
167951
  init_home_assistant_actions();
167824
167952
  init_home_assistant_entity_behavior();
167825
- var logger163 = Logger.get("WindowCoveringServer");
167953
+ var logger164 = Logger.get("WindowCoveringServer");
167826
167954
  var MovementStatus = WindowCovering3.MovementStatus;
167827
167955
  var FeaturedBase5 = WindowCoveringServer.with(
167828
167956
  "Lift",
@@ -167906,7 +168034,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
167906
168034
  );
167907
168035
  const currentTilt100ths = currentTilt != null ? currentTilt * 100 : null;
167908
168036
  const isStopped = movementStatus === MovementStatus.Stopped;
167909
- logger163.debug(
168037
+ logger164.debug(
167910
168038
  `Cover update for ${entity.entity_id}: state=${state.state}, lift=${currentLift}%, tilt=${currentTilt}%, movement=${MovementStatus[movementStatus]}`
167911
168039
  );
167912
168040
  const appliedPatch = applyPatchState(
@@ -167945,9 +168073,9 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
167945
168073
  );
167946
168074
  if (Object.keys(appliedPatch).length > 0) {
167947
168075
  const hasOperationalChange = "operationalStatus" in appliedPatch;
167948
- const log = hasOperationalChange ? logger163.info : logger163.debug;
168076
+ const log = hasOperationalChange ? logger164.info : logger164.debug;
167949
168077
  log.call(
167950
- logger163,
168078
+ logger164,
167951
168079
  `Cover ${entity.entity_id} state changed: ${JSON.stringify(appliedPatch)}`
167952
168080
  );
167953
168081
  }
@@ -167955,7 +168083,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
167955
168083
  async handleMovement(type, _, direction, targetPercent100ths) {
167956
168084
  const currentLift = this.state.currentPositionLiftPercent100ths ?? 0;
167957
168085
  const currentTilt = this.state.currentPositionTiltPercent100ths ?? 0;
167958
- logger163.info(
168086
+ logger164.info(
167959
168087
  `handleMovement: type=${MovementType[type]}, direction=${MovementDirection[direction]}, target=${targetPercent100ths}, currentLift=${currentLift}, currentTilt=${currentTilt}, absolutePosition=${this.features.absolutePosition}`
167960
168088
  );
167961
168089
  if (type === MovementType.Lift) {
@@ -167991,13 +168119,13 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
167991
168119
  handleLiftOpen() {
167992
168120
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
167993
168121
  const action = this.state.config.openCoverLift(void 0, this.agent);
167994
- logger163.info(`handleLiftOpen: calling action=${action.action}`);
168122
+ logger164.info(`handleLiftOpen: calling action=${action.action}`);
167995
168123
  homeAssistant.callAction(action);
167996
168124
  }
167997
168125
  handleLiftClose() {
167998
168126
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
167999
168127
  const action = this.state.config.closeCoverLift(void 0, this.agent);
168000
- logger163.info(`handleLiftClose: calling action=${action.action}`);
168128
+ logger164.info(`handleLiftClose: calling action=${action.action}`);
168001
168129
  homeAssistant.callAction(action);
168002
168130
  }
168003
168131
  handleGoToLiftPosition(targetPercent100ths) {
@@ -168018,7 +168146,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
168018
168146
  this.lastLiftCommandTime = now;
168019
168147
  const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
168020
168148
  const debounceMs = isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
168021
- logger163.debug(
168149
+ logger164.debug(
168022
168150
  `Lift command: target=${targetPosition}%, debounce=${debounceMs}ms (${isFirstInSequence ? "initial" : "subsequent"})`
168023
168151
  );
168024
168152
  if (this.liftDebounceTimer) {
@@ -168067,7 +168195,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
168067
168195
  this.lastTiltCommandTime = now;
168068
168196
  const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
168069
168197
  const debounceMs = isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
168070
- logger163.debug(
168198
+ logger164.debug(
168071
168199
  `Tilt command: target=${targetPosition}%, debounce=${debounceMs}ms (${isFirstInSequence ? "initial" : "subsequent"})`
168072
168200
  );
168073
168201
  if (this.tiltDebounceTimer) {
@@ -168126,7 +168254,7 @@ function adjustPositionForWriting(position, flags2, matterSemantics) {
168126
168254
  }
168127
168255
 
168128
168256
  // src/matter/endpoints/legacy/cover/behaviors/cover-window-covering-server.ts
168129
- var logger164 = Logger.get("CoverWindowCoveringServer");
168257
+ var logger165 = Logger.get("CoverWindowCoveringServer");
168130
168258
  var attributes5 = (entity) => entity.attributes;
168131
168259
  var MATTER_SEMANTIC_PLATFORMS = [
168132
168260
  // Currently empty - no known platforms use Matter semantics by default
@@ -168144,7 +168272,7 @@ var adjustPositionForReading2 = (position, agent) => {
168144
168272
  const { featureFlags } = agent.env.get(BridgeDataProvider);
168145
168273
  const matterSem = usesMatterSemantics(agent);
168146
168274
  const result = adjustPositionForReading(position, featureFlags, matterSem);
168147
- logger164.debug(`adjustPositionForReading: HA=${position}%, result=${result}%`);
168275
+ logger165.debug(`adjustPositionForReading: HA=${position}%, result=${result}%`);
168148
168276
  return result;
168149
168277
  };
168150
168278
  var adjustPositionForWriting2 = (position, agent) => {
@@ -168248,7 +168376,7 @@ var config5 = {
168248
168376
  var CoverWindowCoveringServer = WindowCoveringServer2(config5);
168249
168377
 
168250
168378
  // src/matter/endpoints/legacy/cover/index.ts
168251
- var logger165 = Logger.get("CoverDevice");
168379
+ var logger166 = Logger.get("CoverDevice");
168252
168380
  var CoverPowerSourceServer = PowerSourceServer2({
168253
168381
  getBatteryPercent: (entity, agent) => {
168254
168382
  const homeAssistant = agent.get(HomeAssistantEntityBehavior);
@@ -168275,7 +168403,7 @@ var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
168275
168403
  features2.add("PositionAwareLift");
168276
168404
  features2.add("AbsolutePosition");
168277
168405
  } else {
168278
- logger165.warn(
168406
+ logger166.warn(
168279
168407
  `[${entityId}] Cover has no support_open feature (supported_features=${supportedFeatures}), adding Lift anyway`
168280
168408
  );
168281
168409
  features2.add("Lift");
@@ -168292,7 +168420,7 @@ var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
168292
168420
  features2.add("AbsolutePosition");
168293
168421
  }
168294
168422
  }
168295
- logger165.info(
168423
+ logger166.info(
168296
168424
  `[${entityId}] Creating WindowCovering with features: [${[...features2].join(", ")}], supported_features=${supportedFeatures}`
168297
168425
  );
168298
168426
  const baseBehaviors = [
@@ -168313,11 +168441,11 @@ function CoverDevice(homeAssistantEntity) {
168313
168441
  const hasBatteryEntity = !!homeAssistantEntity.mapping?.batteryEntity;
168314
168442
  const hasBattery = hasBatteryAttr || hasBatteryEntity;
168315
168443
  if (hasBattery) {
168316
- logger165.info(
168444
+ logger166.info(
168317
168445
  `[${entityId}] Creating cover with PowerSource cluster, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
168318
168446
  );
168319
168447
  } else {
168320
- logger165.debug(
168448
+ logger166.debug(
168321
168449
  `[${entityId}] Creating cover without battery (batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"})`
168322
168450
  );
168323
168451
  }
@@ -168333,7 +168461,7 @@ function CoverDevice(homeAssistantEntity) {
168333
168461
  // src/matter/behaviors/generic-switch-server.ts
168334
168462
  init_esm();
168335
168463
  init_home_assistant_entity_behavior();
168336
- var logger166 = Logger.get("GenericSwitchServer");
168464
+ var logger167 = Logger.get("GenericSwitchServer");
168337
168465
  var FeaturedBase6 = SwitchServer.with(
168338
168466
  "MomentarySwitch",
168339
168467
  "MomentarySwitchRelease",
@@ -168344,7 +168472,7 @@ var GenericSwitchServerBase = class extends FeaturedBase6 {
168344
168472
  await super.initialize();
168345
168473
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
168346
168474
  const entityId = homeAssistant.entityId;
168347
- logger166.debug(`[${entityId}] GenericSwitch initialized`);
168475
+ logger167.debug(`[${entityId}] GenericSwitch initialized`);
168348
168476
  this.reactTo(homeAssistant.onChange, this.handleEventChange);
168349
168477
  }
168350
168478
  handleEventChange() {
@@ -168355,7 +168483,7 @@ var GenericSwitchServerBase = class extends FeaturedBase6 {
168355
168483
  const eventType = attrs.event_type;
168356
168484
  if (!eventType) return;
168357
168485
  const entityId = homeAssistant.entityId;
168358
- logger166.debug(`[${entityId}] Event fired: ${eventType}`);
168486
+ logger167.debug(`[${entityId}] Event fired: ${eventType}`);
168359
168487
  this.triggerPress(eventType);
168360
168488
  }
168361
168489
  triggerPress(eventType) {
@@ -168654,7 +168782,7 @@ init_nodejs();
168654
168782
 
168655
168783
  // src/matter/behaviors/color-control-server.ts
168656
168784
  init_home_assistant_entity_behavior();
168657
- var logger167 = Logger.get("ColorControlServer");
168785
+ var logger168 = Logger.get("ColorControlServer");
168658
168786
  var FeaturedBase7 = ColorControlServer.with("ColorTemperature", "HueSaturation");
168659
168787
  var ColorControlServerBase = class extends FeaturedBase7 {
168660
168788
  pendingTransitionTime;
@@ -168678,7 +168806,7 @@ var ColorControlServerBase = class extends FeaturedBase7 {
168678
168806
  if (this.state.startUpColorTemperatureMireds == null) {
168679
168807
  this.state.startUpColorTemperatureMireds = defaultMireds;
168680
168808
  }
168681
- logger167.debug(
168809
+ logger168.debug(
168682
168810
  `initialize: set ColorTemperature defaults - min=${this.state.colorTempPhysicalMinMireds}, max=${this.state.colorTempPhysicalMaxMireds}, current=${this.state.colorTemperatureMireds}`
168683
168811
  );
168684
168812
  }
@@ -169061,7 +169189,7 @@ init_dist();
169061
169189
  // src/matter/behaviors/electrical-energy-measurement-server.ts
169062
169190
  init_esm();
169063
169191
  init_home_assistant_entity_behavior();
169064
- var logger168 = Logger.get("ElectricalEnergyMeasurementServer");
169192
+ var logger169 = Logger.get("ElectricalEnergyMeasurementServer");
169065
169193
  var FeaturedBase8 = ElectricalEnergyMeasurementServer.with("CumulativeEnergy", "ImportedEnergy");
169066
169194
  var ElectricalEnergyMeasurementServerBase = class extends FeaturedBase8 {
169067
169195
  async initialize() {
@@ -169070,7 +169198,7 @@ var ElectricalEnergyMeasurementServerBase = class extends FeaturedBase8 {
169070
169198
  const entityId = homeAssistant.entityId;
169071
169199
  const energyEntity = homeAssistant.state.mapping?.energyEntity;
169072
169200
  if (energyEntity) {
169073
- logger168.debug(
169201
+ logger169.debug(
169074
169202
  `[${entityId}] ElectricalEnergyMeasurement using mapped energy entity: ${energyEntity}`
169075
169203
  );
169076
169204
  }
@@ -169122,7 +169250,7 @@ var HaElectricalEnergyMeasurementServer = ElectricalEnergyMeasurementServerBase.
169122
169250
  // src/matter/behaviors/electrical-power-measurement-server.ts
169123
169251
  init_esm();
169124
169252
  init_home_assistant_entity_behavior();
169125
- var logger169 = Logger.get("ElectricalPowerMeasurementServer");
169253
+ var logger170 = Logger.get("ElectricalPowerMeasurementServer");
169126
169254
  var ElectricalPowerMeasurementServerBase = class extends ElectricalPowerMeasurementServer {
169127
169255
  async initialize() {
169128
169256
  await super.initialize();
@@ -169130,7 +169258,7 @@ var ElectricalPowerMeasurementServerBase = class extends ElectricalPowerMeasurem
169130
169258
  const entityId = homeAssistant.entityId;
169131
169259
  const powerEntity = homeAssistant.state.mapping?.powerEntity;
169132
169260
  if (powerEntity) {
169133
- logger169.debug(
169261
+ logger170.debug(
169134
169262
  `[${entityId}] ElectricalPowerMeasurement using mapped power entity: ${powerEntity}`
169135
169263
  );
169136
169264
  }
@@ -169226,7 +169354,7 @@ init_home_assistant_entity_behavior();
169226
169354
  // src/matter/behaviors/lock-server.ts
169227
169355
  init_esm();
169228
169356
  init_home_assistant_entity_behavior();
169229
- var logger170 = Logger.get("LockServer");
169357
+ var logger171 = Logger.get("LockServer");
169230
169358
  function hasStoredCredentialHelper(env, entityId) {
169231
169359
  try {
169232
169360
  const storage2 = env.get(LockCredentialStorage);
@@ -169384,7 +169512,7 @@ var LockServerWithPinBase = class extends PinCredentialBase {
169384
169512
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
169385
169513
  const action = this.state.config.lock(void 0, this.agent);
169386
169514
  const hasPinProvided = !!request.pinCode;
169387
- logger170.debug(
169515
+ logger171.debug(
169388
169516
  `lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
169389
169517
  );
169390
169518
  if (request.pinCode) {
@@ -169397,12 +169525,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
169397
169525
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
169398
169526
  const action = this.state.config.unlock(void 0, this.agent);
169399
169527
  const hasPinProvided = !!request.pinCode;
169400
- logger170.debug(
169528
+ logger171.debug(
169401
169529
  `unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
169402
169530
  );
169403
169531
  if (this.state.requirePinForRemoteOperation) {
169404
169532
  if (!request.pinCode) {
169405
- logger170.info(
169533
+ logger171.info(
169406
169534
  `unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
169407
169535
  );
169408
169536
  throw new StatusResponseError(
@@ -169412,12 +169540,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
169412
169540
  }
169413
169541
  const providedPin = new TextDecoder().decode(request.pinCode);
169414
169542
  if (!this.verifyStoredPin(homeAssistant.entityId, providedPin)) {
169415
- logger170.info(
169543
+ logger171.info(
169416
169544
  `unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
169417
169545
  );
169418
169546
  throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
169419
169547
  }
169420
- logger170.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
169548
+ logger171.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
169421
169549
  action.data = { ...action.data, code: providedPin };
169422
169550
  }
169423
169551
  homeAssistant.callAction(action);
@@ -169578,7 +169706,7 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
169578
169706
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
169579
169707
  const action = this.state.config.lock(void 0, this.agent);
169580
169708
  const hasPinProvided = !!request.pinCode;
169581
- logger170.debug(
169709
+ logger171.debug(
169582
169710
  `lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
169583
169711
  );
169584
169712
  if (request.pinCode) {
@@ -169592,12 +169720,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
169592
169720
  const unlatchConfig = this.state.config.unlatch;
169593
169721
  const action = unlatchConfig ? unlatchConfig(void 0, this.agent) : this.state.config.unlock(void 0, this.agent);
169594
169722
  const hasPinProvided = !!request.pinCode;
169595
- logger170.debug(
169723
+ logger171.debug(
169596
169724
  `unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}, usingUnlatch: ${!!unlatchConfig}`
169597
169725
  );
169598
169726
  if (this.state.requirePinForRemoteOperation) {
169599
169727
  if (!request.pinCode) {
169600
- logger170.info(
169728
+ logger171.info(
169601
169729
  `unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
169602
169730
  );
169603
169731
  throw new StatusResponseError(
@@ -169607,12 +169735,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
169607
169735
  }
169608
169736
  const providedPin = new TextDecoder().decode(request.pinCode);
169609
169737
  if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
169610
- logger170.info(
169738
+ logger171.info(
169611
169739
  `unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
169612
169740
  );
169613
169741
  throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
169614
169742
  }
169615
- logger170.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
169743
+ logger171.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
169616
169744
  action.data = { ...action.data, code: providedPin };
169617
169745
  }
169618
169746
  homeAssistant.callAction(action);
@@ -169627,12 +169755,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
169627
169755
  }
169628
169756
  const action = unlatchConfig(void 0, this.agent);
169629
169757
  const hasPinProvided = !!request.pinCode;
169630
- logger170.debug(
169758
+ logger171.debug(
169631
169759
  `unboltDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
169632
169760
  );
169633
169761
  if (this.state.requirePinForRemoteOperation) {
169634
169762
  if (!request.pinCode) {
169635
- logger170.info(
169763
+ logger171.info(
169636
169764
  `unboltDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
169637
169765
  );
169638
169766
  throw new StatusResponseError(
@@ -169642,12 +169770,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
169642
169770
  }
169643
169771
  const providedPin = new TextDecoder().decode(request.pinCode);
169644
169772
  if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
169645
- logger170.info(
169773
+ logger171.info(
169646
169774
  `unboltDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
169647
169775
  );
169648
169776
  throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
169649
169777
  }
169650
- logger170.debug(`unboltDoor PIN verified for ${homeAssistant.entityId}`);
169778
+ logger171.debug(`unboltDoor PIN verified for ${homeAssistant.entityId}`);
169651
169779
  action.data = { ...action.data, code: providedPin };
169652
169780
  }
169653
169781
  homeAssistant.callAction(action);
@@ -169817,7 +169945,7 @@ init_home_assistant_entity_behavior();
169817
169945
  init_dist();
169818
169946
  init_esm();
169819
169947
  init_home_assistant_entity_behavior();
169820
- var logger171 = Logger.get("MediaPlayerKeypadInputServer");
169948
+ var logger172 = Logger.get("MediaPlayerKeypadInputServer");
169821
169949
  var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
169822
169950
  sendKey(request) {
169823
169951
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
@@ -169828,12 +169956,12 @@ var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
169828
169956
  const features2 = attributes7.supported_features ?? 0;
169829
169957
  const action = this.mapKeyToAction(request.keyCode, features2);
169830
169958
  if (!action) {
169831
- logger171.debug(
169959
+ logger172.debug(
169832
169960
  `Unsupported key code ${request.keyCode} for ${homeAssistant.entityId}`
169833
169961
  );
169834
169962
  return { status: KeypadInput3.Status.UnsupportedKey };
169835
169963
  }
169836
- logger171.debug(
169964
+ logger172.debug(
169837
169965
  `sendKey(${request.keyCode}) \u2192 ${action} for ${homeAssistant.entityId}`
169838
169966
  );
169839
169967
  homeAssistant.callAction({ action });
@@ -170045,7 +170173,7 @@ init_home_assistant_entity_behavior();
170045
170173
  // src/matter/behaviors/speaker-level-control-server.ts
170046
170174
  init_esm();
170047
170175
  init_home_assistant_entity_behavior();
170048
- var logger172 = Logger.get("SpeakerLevelControlServer");
170176
+ var logger173 = Logger.get("SpeakerLevelControlServer");
170049
170177
  var FeaturedBase9 = LevelControlServer.with("OnOff");
170050
170178
  var SpeakerLevelControlServerBase = class extends FeaturedBase9 {
170051
170179
  async initialize() {
@@ -170078,7 +170206,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase9 {
170078
170206
  currentLevel = Math.min(Math.max(minLevel, currentLevel), maxLevel);
170079
170207
  }
170080
170208
  const entityId = this.agent.get(HomeAssistantEntityBehavior).entity.entity_id;
170081
- logger172.debug(
170209
+ logger173.debug(
170082
170210
  `[${entityId}] Volume update: HA=${currentLevelPercent != null ? Math.round(currentLevelPercent * 100) : "null"}% -> currentLevel=${currentLevel}`
170083
170211
  );
170084
170212
  applyPatchState(this.state, {
@@ -170116,7 +170244,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase9 {
170116
170244
  const config10 = this.state.config;
170117
170245
  const entityId = homeAssistant.entity.entity_id;
170118
170246
  const levelPercent = level / 254;
170119
- logger172.debug(
170247
+ logger173.debug(
170120
170248
  `[${entityId}] Volume command: level=${level} -> HA volume_level=${levelPercent}`
170121
170249
  );
170122
170250
  const current = config10.getValuePercent(
@@ -170406,63 +170534,6 @@ function ScriptDevice(homeAssistantEntity) {
170406
170534
 
170407
170535
  // src/matter/endpoints/legacy/select/index.ts
170408
170536
  init_home_assistant_entity_behavior();
170409
-
170410
- // src/matter/behaviors/mode-select-server.ts
170411
- init_esm();
170412
- init_home_assistant_entity_behavior();
170413
- var logger173 = Logger.get("ModeSelectServer");
170414
- var ModeSelectServerBase = class extends ModeSelectServer {
170415
- async initialize() {
170416
- await super.initialize();
170417
- const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
170418
- this.update(homeAssistant.entity);
170419
- this.reactTo(homeAssistant.onChange, this.update);
170420
- }
170421
- update(entity) {
170422
- if (!entity.state) {
170423
- return;
170424
- }
170425
- const config10 = this.state.config;
170426
- const options = config10.getOptions(entity);
170427
- const current = config10.getCurrentOption(entity);
170428
- if (options.length === 0) {
170429
- return;
170430
- }
170431
- const currentIndex = current ? options.findIndex((o) => o.toLowerCase() === current.toLowerCase()) : -1;
170432
- applyPatchState(this.state, {
170433
- currentMode: currentIndex >= 0 ? currentIndex : 0
170434
- });
170435
- }
170436
- changeToMode(request) {
170437
- const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
170438
- const config10 = this.state.config;
170439
- const options = config10.getOptions(homeAssistant.entity);
170440
- const { newMode } = request;
170441
- if (newMode < 0 || newMode >= options.length) {
170442
- logger173.warn(
170443
- `[${homeAssistant.entityId}] Invalid mode ${newMode}, options: [${options.join(", ")}]`
170444
- );
170445
- return;
170446
- }
170447
- const option = options[newMode];
170448
- logger173.info(
170449
- `[${homeAssistant.entityId}] changeToMode(${newMode}) -> "${option}"`
170450
- );
170451
- applyPatchState(this.state, { currentMode: newMode });
170452
- homeAssistant.callAction(config10.selectOption(option));
170453
- }
170454
- };
170455
- ((ModeSelectServerBase2) => {
170456
- class State extends ModeSelectServer.State {
170457
- config;
170458
- }
170459
- ModeSelectServerBase2.State = State;
170460
- })(ModeSelectServerBase || (ModeSelectServerBase = {}));
170461
- function ModeSelectServer2(config10) {
170462
- return ModeSelectServerBase.set({ config: config10 });
170463
- }
170464
-
170465
- // src/matter/endpoints/legacy/select/index.ts
170466
170537
  function getSelectOptions(entity) {
170467
170538
  const attrs = entity.state.attributes;
170468
170539
  return attrs.options ?? [];
@@ -173931,7 +174002,8 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
173931
174002
  effectiveMapping.cleaningModeEntity
173932
174003
  );
173933
174004
  cleaningModeOptions = cmState?.attributes?.options;
173934
- } else if (supportsCleaningModes(state.attributes)) {
174005
+ }
174006
+ if (!cleaningModeOptions && (effectiveMapping?.cleaningModeEntity || supportsCleaningModes(state.attributes))) {
173935
174007
  cleaningModeOptions = [
173936
174008
  "vacuum",
173937
174009
  "mop",
@@ -174582,19 +174654,23 @@ var BridgeRegistry = class _BridgeRegistry {
174582
174654
  }
174583
174655
  /**
174584
174656
  * Check if the vacuum OnOff cluster feature flag is enabled.
174585
- * When enabled, an OnOff cluster is added to vacuum endpoints for Alexa compatibility.
174657
+ * Defaults to OFF. OnOff is NOT part of the RoboticVacuumCleaner (0x74) device
174658
+ * type spec. Adding it makes the device non-conformant and causes Amazon Alexa
174659
+ * to reject it entirely (#185, #183). Only enable if a specific controller needs it.
174586
174660
  */
174587
174661
  isVacuumOnOffEnabled() {
174588
174662
  return this.dataProvider.featureFlags?.vacuumOnOff === true;
174589
174663
  }
174590
174664
  /**
174591
174665
  * Check if the vacuum OnOff cluster should be included for server-mode vacuums.
174592
- * Server mode defaults to INCLUDING OnOff because Amazon Alexa requires
174593
- * PowerController (mapped from OnOff) for robotic vacuum devices.
174594
- * Users can explicitly set vacuumOnOff=false to disable it (e.g. for Apple Home).
174666
+ * Defaults to OFF. OnOff is NOT part of the RoboticVacuumCleaner (0x74) device
174667
+ * type spec. Adding it makes the device non-conformant and causes Amazon Alexa
174668
+ * to reject it entirely (#185, #183). Apple Home may also render the vacuum
174669
+ * incorrectly (shows "Updating" or switch UI). Only enable via feature flag
174670
+ * if a specific controller requires it.
174595
174671
  */
174596
174672
  isServerModeVacuumOnOffEnabled() {
174597
- return this.dataProvider.featureFlags?.vacuumOnOff !== false;
174673
+ return this.dataProvider.featureFlags?.vacuumOnOff === true;
174598
174674
  }
174599
174675
  isVacuumMinimalClustersEnabled() {
174600
174676
  return this.dataProvider.featureFlags?.vacuumMinimalClusters === true;
@@ -175438,7 +175514,8 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
175438
175514
  effectiveMapping.cleaningModeEntity
175439
175515
  );
175440
175516
  cleaningModeOptions = cmState?.attributes?.options;
175441
- } else if (supportsCleaningModes(vacAttrsForClean)) {
175517
+ }
175518
+ if (!cleaningModeOptions && (effectiveMapping?.cleaningModeEntity || supportsCleaningModes(vacAttrsForClean))) {
175442
175519
  cleaningModeOptions = [
175443
175520
  "vacuum",
175444
175521
  "mop",