@riddix/hamh 2.1.0-alpha.858 → 2.1.0-alpha.860

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.
@@ -1767,8 +1767,8 @@ var init_Cancelable = __esm({
1767
1767
  };
1768
1768
  return result;
1769
1769
  }
1770
- static set logger(logger253) {
1771
- this.#logger = logger253;
1770
+ static set logger(logger254) {
1771
+ this.#logger = logger254;
1772
1772
  }
1773
1773
  static get logger() {
1774
1774
  return this.#logger;
@@ -3475,13 +3475,13 @@ var init_Logger = __esm({
3475
3475
  *
3476
3476
  * @deprecated use {@link destinations}
3477
3477
  */
3478
- static addLogger(identifier, logger253, options) {
3478
+ static addLogger(identifier, logger254, options) {
3479
3479
  if (identifier in this.destinations) {
3480
3480
  throw new ImplementationError(`Logger "${identifier}" already exists`);
3481
3481
  }
3482
3482
  const dest = LogDestination({ name: identifier });
3483
3483
  const legacy = adaptDestinationToLegacy(dest);
3484
- legacy.log = logger253;
3484
+ legacy.log = logger254;
3485
3485
  if (options?.defaultLogLevel !== void 0) {
3486
3486
  legacy.defaultLogLevel = options.defaultLogLevel;
3487
3487
  }
@@ -5687,8 +5687,8 @@ var init_Construction = __esm({
5687
5687
  }
5688
5688
  }
5689
5689
  #unhandledError(...args) {
5690
- const logger253 = Logger.get(this.#subject.constructor.name);
5691
- logger253.error(...args);
5690
+ const logger254 = Logger.get(this.#subject.constructor.name);
5691
+ logger254.error(...args);
5692
5692
  }
5693
5693
  #createErrorHandler(name) {
5694
5694
  return (e) => {
@@ -64126,8 +64126,8 @@ var init_NodeSession = __esm({
64126
64126
  return session?.type === SessionType.Unicast;
64127
64127
  }
64128
64128
  NodeSession2.is = is;
64129
- function logNew(logger253, operation, session, messenger, fabric, peerNodeId) {
64130
- logger253.info(
64129
+ function logNew(logger254, operation, session, messenger, fabric, peerNodeId) {
64130
+ logger254.info(
64131
64131
  session.via,
64132
64132
  `${operation} session with`,
64133
64133
  Diagnostic.strong(PeerAddress({ fabricIndex: fabric.fabricIndex, nodeId: peerNodeId }).toString()),
@@ -118041,11 +118041,11 @@ var init_Api = __esm({
118041
118041
  }
118042
118042
  Api2.resourceFor = resourceFor;
118043
118043
  function log(level, facility, id, ...message) {
118044
- let logger253 = loggers.get(facility);
118045
- if (!logger253) {
118046
- loggers.set(facility, logger253 = Logger.get(facility));
118044
+ let logger254 = loggers.get(facility);
118045
+ if (!logger254) {
118046
+ loggers.set(facility, logger254 = Logger.get(facility));
118047
118047
  }
118048
- logger253[level](Diagnostic.via(id || "(anon)"), message);
118048
+ logger254[level](Diagnostic.via(id || "(anon)"), message);
118049
118049
  }
118050
118050
  Api2.log = log;
118051
118051
  function logRequest(facility, id, method, target) {
@@ -132383,6 +132383,14 @@ var init_bridge_config_schema = __esm({
132383
132383
  maximum: 5e3,
132384
132384
  default: 0
132385
132385
  },
132386
+ fanSliderDebounceMs: {
132387
+ title: "Fan Slider Debounce (ms)",
132388
+ description: "Wait this long after the last inbound fan-speed write before sending it to Home Assistant. Controllers stream percentSetting while the user is still dragging - one Google Home drag was measured emitting nine writes in eight seconds - and on IR or UART bridged air conditioners every write is a device frame that makes the unit beep. 0 (the default) sends every write immediately, matching previous behaviour. Try 1000-2000 ms for bridged ACs. A per-entity override on a single fan or climate wins over this flag.",
132389
+ type: "number",
132390
+ minimum: 0,
132391
+ maximum: 1e4,
132392
+ default: 0
132393
+ },
132386
132394
  fastSessionRecovery: {
132387
132395
  title: "Fast Session Recovery (Google offline workaround)",
132388
132396
  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.",
@@ -132960,10 +132968,10 @@ var init_home_assistant_actions = __esm({
132960
132968
  circuitBreakerResetMs: 3e4
132961
132969
  };
132962
132970
  HomeAssistantActions = class extends Service {
132963
- constructor(logger253, client, config8) {
132971
+ constructor(logger254, client, config8) {
132964
132972
  super("HomeAssistantActions");
132965
132973
  this.client = client;
132966
- this.log = logger253.get(this);
132974
+ this.log = logger254.get(this);
132967
132975
  this.config = { ...defaultConfig, ...config8 };
132968
132976
  this.circuitBreaker = new CircuitBreaker(
132969
132977
  this.config.circuitBreakerThreshold,
@@ -133309,10 +133317,10 @@ var DiagnosticService = class {
133309
133317
  };
133310
133318
 
133311
133319
  // src/api/access-log.ts
133312
- function accessLogger(logger253) {
133320
+ function accessLogger(logger254) {
133313
133321
  return (req, res, next) => {
133314
133322
  res.on("finish", () => {
133315
- logger253.debug(
133323
+ logger254.debug(
133316
133324
  `${req.method} ${decodeURI(req.originalUrl)} ${res.statusCode} ${res.statusMessage} from ${req.socket.remoteAddress}`
133317
133325
  );
133318
133326
  });
@@ -133593,6 +133601,7 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
133593
133601
  valetudoIdentifier: config8.valetudoIdentifier,
133594
133602
  coverSwapOpenClose: config8.coverSwapOpenClose,
133595
133603
  coverSliderDebounceMs: config8.coverSliderDebounceMs,
133604
+ fanSliderDebounceMs: config8.fanSliderDebounceMs,
133596
133605
  disableClimateOnOff: config8.disableClimateOnOff,
133597
133606
  disableClimateFanControl: config8.disableClimateFanControl,
133598
133607
  climateAutoMode: config8.climateAutoMode,
@@ -133762,6 +133771,7 @@ WARNING: ${includeIdentity ? "This backup contains sensitive Matter identity dat
133762
133771
  valetudoIdentifier: config8.valetudoIdentifier,
133763
133772
  coverSwapOpenClose: config8.coverSwapOpenClose,
133764
133773
  coverSliderDebounceMs: config8.coverSliderDebounceMs,
133774
+ fanSliderDebounceMs: config8.fanSliderDebounceMs,
133765
133775
  disableClimateOnOff: config8.disableClimateOnOff,
133766
133776
  disableClimateFanControl: config8.disableClimateFanControl,
133767
133777
  climateAutoMode: config8.climateAutoMode,
@@ -134644,6 +134654,7 @@ function entityMappingApi(mappingStorage, identityStorage) {
134644
134654
  selectSwitchOnOption: body.selectSwitchOnOption,
134645
134655
  selectSwitchOffOption: body.selectSwitchOffOption,
134646
134656
  coverSliderDebounceMs: body.coverSliderDebounceMs,
134657
+ fanSliderDebounceMs: body.fanSliderDebounceMs,
134647
134658
  updateThrottleMs: body.updateThrottleMs,
134648
134659
  disableClimateOnOff: body.disableClimateOnOff,
134649
134660
  disableClimateFanControl: body.disableClimateFanControl,
@@ -135142,6 +135153,7 @@ function configToProfileEntry(config8) {
135142
135153
  valetudoIdentifier: config8.valetudoIdentifier,
135143
135154
  coverSwapOpenClose: config8.coverSwapOpenClose,
135144
135155
  coverSliderDebounceMs: config8.coverSliderDebounceMs,
135156
+ fanSliderDebounceMs: config8.fanSliderDebounceMs,
135145
135157
  disableClimateOnOff: config8.disableClimateOnOff,
135146
135158
  disableClimateFanControl: config8.disableClimateFanControl,
135147
135159
  climateKeepModeOnIdle: config8.climateKeepModeOnIdle,
@@ -135287,6 +135299,7 @@ function mappingProfileApi(mappingStorage) {
135287
135299
  valetudoIdentifier: entry.valetudoIdentifier,
135288
135300
  coverSwapOpenClose: entry.coverSwapOpenClose,
135289
135301
  coverSliderDebounceMs: entry.coverSliderDebounceMs,
135302
+ fanSliderDebounceMs: entry.fanSliderDebounceMs,
135290
135303
  disableClimateOnOff: entry.disableClimateOnOff,
135291
135304
  disableClimateFanControl: entry.disableClimateFanControl,
135292
135305
  climateKeepModeOnIdle: entry.climateKeepModeOnIdle,
@@ -138045,7 +138058,7 @@ var WebSocketApi = class {
138045
138058
 
138046
138059
  // src/api/web-api.ts
138047
138060
  var WebApi = class extends Service {
138048
- constructor(logger253, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, identityStorage, lockCredentialStorage, settingsStorage, backupService, props) {
138061
+ constructor(logger254, bridgeService, haClient, haRegistry, bridgeStorage, mappingStorage, identityStorage, lockCredentialStorage, settingsStorage, backupService, props) {
138049
138062
  super("WebApi");
138050
138063
  this.bridgeService = bridgeService;
138051
138064
  this.haClient = haClient;
@@ -138057,8 +138070,8 @@ var WebApi = class extends Service {
138057
138070
  this.settingsStorage = settingsStorage;
138058
138071
  this.backupService = backupService;
138059
138072
  this.props = props;
138060
- this.logger = logger253;
138061
- this.log = logger253.get(this);
138073
+ this.logger = logger254;
138074
+ this.log = logger254.get(this);
138062
138075
  this.accessLogger = accessLogger(this.log.createChild("Access Log"));
138063
138076
  this.startTime = Date.now();
138064
138077
  this.wsApi = new WebSocketApi(
@@ -139259,10 +139272,10 @@ function isTransientConnectError(reason) {
139259
139272
  return msg.includes("socket hang up") || msg.includes("tls") || msg.includes("TLS");
139260
139273
  }
139261
139274
  var HomeAssistantClient = class extends Service {
139262
- constructor(logger253, options) {
139275
+ constructor(logger254, options) {
139263
139276
  super("HomeAssistantClient");
139264
139277
  this.options = options;
139265
- this.log = logger253.get(this);
139278
+ this.log = logger254.get(this);
139266
139279
  }
139267
139280
  options;
139268
139281
  static Options = /* @__PURE__ */ Symbol.for("HomeAssistantClientProps");
@@ -140103,6 +140116,7 @@ var EntityMappingStorage = class extends Service {
140103
140116
  selectSwitchOnOption: request.selectSwitchOnOption || void 0,
140104
140117
  selectSwitchOffOption: request.selectSwitchOffOption || void 0,
140105
140118
  coverSliderDebounceMs: sanitizeDebounceMs(request.coverSliderDebounceMs),
140119
+ fanSliderDebounceMs: sanitizeDebounceMs(request.fanSliderDebounceMs),
140106
140120
  updateThrottleMs: sanitizeThrottleMs(request.updateThrottleMs),
140107
140121
  disableClimateOnOff: request.disableClimateOnOff || void 0,
140108
140122
  disableClimateFanControl: request.disableClimateFanControl || void 0,
@@ -140112,7 +140126,7 @@ var EntityMappingStorage = class extends Service {
140112
140126
  composedEntities: request.composedEntities?.filter((e) => e.entityId?.trim()) ?? void 0,
140113
140127
  disableMomentaryFlip: request.disableMomentaryFlip || void 0
140114
140128
  };
140115
- if (!config8.matterDeviceType && !config8.customName && !config8.customProductName && !config8.customVendorName && !config8.customSerialNumber && config8.customVendorId === void 0 && config8.disabled !== true && !config8.filterLifeEntity && !config8.cleaningModeEntity && !config8.temperatureEntity && !config8.humidityEntity && !config8.batteryEntity && !config8.disableBatteryMapping && !config8.chargingStateEntity && !config8.roomEntities && !config8.disableLockPin && !config8.lockUsercodeService && config8.lockUsercodeSlot === void 0 && config8.lockPinMinLength === void 0 && config8.lockPinMaxLength === void 0 && !config8.powerEntity && !config8.energyEntity && !config8.meterSerialNumber && !config8.pointOfDelivery && !config8.voltageEntity && !config8.currentEntity && !config8.batteryPowerEntity && !config8.batteryEnergyEntity && !config8.chargingSwitchEntity && !config8.currentLimitEntity && !config8.pressureEntity && !config8.suctionLevelEntity && !config8.mopIntensityEntity && (!config8.customServiceAreas || config8.customServiceAreas.length === 0) && (!config8.customFanSpeedTags || Object.keys(config8.customFanSpeedTags).length === 0) && (!config8.fanWindPresets || (config8.fanWindPresets.natural?.length ?? 0) === 0 && (config8.fanWindPresets.sleep?.length ?? 0) === 0) && !config8.fanRestoreSpeedOnPowerOn && !config8.currentRoomEntity && !config8.cleanedAreaEntity && !config8.vacuumAscendingRoomOrder && !config8.vacuumRoomSwitches && !config8.disableCustomAreaRoomModes && !config8.valetudoIdentifier && !config8.coverSwapOpenClose && !config8.coverExposeAsDimmableLight && !config8.selectExposeAsSwitch && !config8.selectSwitchOnOption && !config8.selectSwitchOffOption && !config8.coverSliderDebounceMs && !config8.updateThrottleMs && !config8.disableClimateOnOff && !config8.disableClimateFanControl && !config8.climateKeepModeOnIdle && !config8.climateExposeFan && !config8.climateAutoMode && (!config8.composedEntities || config8.composedEntities.length === 0) && !config8.disableMomentaryFlip) {
140129
+ if (!config8.matterDeviceType && !config8.customName && !config8.customProductName && !config8.customVendorName && !config8.customSerialNumber && config8.customVendorId === void 0 && config8.disabled !== true && !config8.filterLifeEntity && !config8.cleaningModeEntity && !config8.temperatureEntity && !config8.humidityEntity && !config8.batteryEntity && !config8.disableBatteryMapping && !config8.chargingStateEntity && !config8.roomEntities && !config8.disableLockPin && !config8.lockUsercodeService && config8.lockUsercodeSlot === void 0 && config8.lockPinMinLength === void 0 && config8.lockPinMaxLength === void 0 && !config8.powerEntity && !config8.energyEntity && !config8.meterSerialNumber && !config8.pointOfDelivery && !config8.voltageEntity && !config8.currentEntity && !config8.batteryPowerEntity && !config8.batteryEnergyEntity && !config8.chargingSwitchEntity && !config8.currentLimitEntity && !config8.pressureEntity && !config8.suctionLevelEntity && !config8.mopIntensityEntity && (!config8.customServiceAreas || config8.customServiceAreas.length === 0) && (!config8.customFanSpeedTags || Object.keys(config8.customFanSpeedTags).length === 0) && (!config8.fanWindPresets || (config8.fanWindPresets.natural?.length ?? 0) === 0 && (config8.fanWindPresets.sleep?.length ?? 0) === 0) && !config8.fanRestoreSpeedOnPowerOn && !config8.currentRoomEntity && !config8.cleanedAreaEntity && !config8.vacuumAscendingRoomOrder && !config8.vacuumRoomSwitches && !config8.disableCustomAreaRoomModes && !config8.valetudoIdentifier && !config8.coverSwapOpenClose && !config8.coverExposeAsDimmableLight && !config8.selectExposeAsSwitch && !config8.selectSwitchOnOption && !config8.selectSwitchOffOption && !config8.coverSliderDebounceMs && !config8.fanSliderDebounceMs && !config8.updateThrottleMs && !config8.disableClimateOnOff && !config8.disableClimateFanControl && !config8.climateKeepModeOnIdle && !config8.climateExposeFan && !config8.climateAutoMode && (!config8.composedEntities || config8.composedEntities.length === 0) && !config8.disableMomentaryFlip) {
140116
140130
  bridgeMap.delete(request.entityId);
140117
140131
  } else {
140118
140132
  bridgeMap.set(request.entityId, config8);
@@ -158024,11 +158038,11 @@ var AUTO_FORCE_SYNC_INTERVAL_MS = 9e4;
158024
158038
  var SHUTDOWN_SESSION_CLOSE_TIMEOUT_MS = 2500;
158025
158039
  var MDNS_ADDRESS_CHECK_INTERVAL_MS = 6e4;
158026
158040
  var Bridge = class {
158027
- constructor(env, logger253, dataProvider, endpointManager, serverOptions) {
158041
+ constructor(env, logger254, dataProvider, endpointManager, serverOptions) {
158028
158042
  this.dataProvider = dataProvider;
158029
158043
  this.endpointManager = endpointManager;
158030
158044
  this.serverOptions = serverOptions;
158031
- this.log = logger253.get(`Bridge / ${dataProvider.id}`);
158045
+ this.log = logger254.get(`Bridge / ${dataProvider.id}`);
158032
158046
  this.server = new BridgeServerNode(
158033
158047
  env,
158034
158048
  this.dataProvider,
@@ -160143,6 +160157,7 @@ init_dist();
160143
160157
 
160144
160158
  // src/matter/behaviors/fan-control-server.ts
160145
160159
  init_esm();
160160
+ init_home_assistant_actions();
160146
160161
 
160147
160162
  // src/utils/converters/fan-mode-order.ts
160148
160163
  var SPEED_RANK = {
@@ -160181,26 +160196,36 @@ var SPEED_RANK = {
160181
160196
  boost: 7,
160182
160197
  jet: 7
160183
160198
  };
160184
- function rankOf(token) {
160185
- const key = token.toLowerCase().replace(/[ _-]/g, "");
160186
- if (key in SPEED_RANK) {
160187
- return SPEED_RANK[key];
160188
- }
160199
+ function speedTokenKey(token) {
160200
+ return token.toLowerCase().replace(/[ _-]/g, "");
160201
+ }
160202
+ function speedNumericValue(token) {
160203
+ const key = speedTokenKey(token).replace(/%$/, "");
160189
160204
  const level = key.match(/^level(\d+)$/);
160190
160205
  if (level) {
160191
160206
  return Number(level[1]);
160192
160207
  }
160193
- if (/^\d+$/.test(key)) {
160194
- return Number(key);
160195
- }
160196
- return void 0;
160208
+ return /^\d+$/.test(key) ? Number(key) : void 0;
160209
+ }
160210
+ function rankOf(token) {
160211
+ return SPEED_RANK[speedTokenKey(token)];
160212
+ }
160213
+ function sortByRank(presets, ranks) {
160214
+ return presets.map((value, index) => ({ value, index, rank: ranks[index] })).sort((a, b) => a.rank - b.rank || a.index - b.index).map((entry) => entry.value);
160197
160215
  }
160198
160216
  function toAscendingSpeedPresets(presets) {
160217
+ const numerics = presets.map(speedNumericValue);
160218
+ if (numerics.every((value) => value !== void 0)) {
160219
+ return sortByRank(presets, numerics);
160220
+ }
160221
+ if (numerics.some((value) => value !== void 0)) {
160222
+ return presets.slice();
160223
+ }
160199
160224
  const ranks = presets.map(rankOf);
160200
160225
  if (ranks.some((rank) => rank === void 0)) {
160201
160226
  return presets.slice();
160202
160227
  }
160203
- return presets.map((value, index) => ({ value, index, rank: ranks[index] })).sort((a, b) => a.rank - b.rank || a.index - b.index).map((entry) => entry.value);
160228
+ return sortByRank(presets, ranks);
160204
160229
  }
160205
160230
  function percentToPresetIndex(percentage, count) {
160206
160231
  if (count <= 0) {
@@ -160623,6 +160648,22 @@ var logger210 = Logger.get("FanControlServer");
160623
160648
  var defaultStepSize = 33.33;
160624
160649
  var minSpeedMax = 3;
160625
160650
  var maxSpeedMax = 100;
160651
+ var fanDebounce = /* @__PURE__ */ new WeakMap();
160652
+ function getFanDebounce(endpoint) {
160653
+ let st = fanDebounce.get(endpoint);
160654
+ if (!st) {
160655
+ st = { timer: null, pending: null };
160656
+ fanDebounce.set(endpoint, st);
160657
+ }
160658
+ return st;
160659
+ }
160660
+ function clearFanDebounce(st) {
160661
+ if (st.timer) {
160662
+ clearTimeout(st.timer);
160663
+ st.timer = null;
160664
+ }
160665
+ st.pending = null;
160666
+ }
160626
160667
  var FeaturedBase6 = FanControlServer.with(
160627
160668
  "Step",
160628
160669
  "MultiSpeed",
@@ -160653,6 +160694,14 @@ var FanControlServerBase = class extends FeaturedBase6 {
160653
160694
  auto: this.lastIsAutoMode
160654
160695
  };
160655
160696
  }
160697
+ async [Symbol.asyncDispose]() {
160698
+ const st = fanDebounce.get(this.endpoint);
160699
+ if (st) {
160700
+ clearFanDebounce(st);
160701
+ fanDebounce.delete(this.endpoint);
160702
+ }
160703
+ await super[Symbol.asyncDispose]();
160704
+ }
160656
160705
  async initialize() {
160657
160706
  if (this.state.fanModeSequence == null) {
160658
160707
  this.state.fanModeSequence = this.features.auto ? FanControl3.FanModeSequence.OffLowMedHighAuto : FanControl3.FanModeSequence.OffLowMedHigh;
@@ -160814,7 +160863,7 @@ var FanControlServerBase = class extends FeaturedBase6 {
160814
160863
  if (!homeAssistant.isAvailable) {
160815
160864
  return;
160816
160865
  }
160817
- this.syncOnOff(percentSetting !== 0);
160866
+ this.syncOnOffFromSpeed(percentSetting !== 0);
160818
160867
  if (percentSetting === 0) {
160819
160868
  homeAssistant.callAction(this.state.config.turnOff(void 0, this.agent));
160820
160869
  } else {
@@ -160859,7 +160908,7 @@ var FanControlServerBase = class extends FeaturedBase6 {
160859
160908
  }
160860
160909
  const targetFanMode = FanMode.create(fanMode, this.state.fanModeSequence);
160861
160910
  if (targetFanMode.mode === FanControl3.FanMode.Auto) {
160862
- this.syncOnOff(true);
160911
+ this.syncOnOffFromSpeed(true);
160863
160912
  homeAssistant.callAction(
160864
160913
  this.state.config.setAutoMode(void 0, this.agent)
160865
160914
  );
@@ -160879,6 +160928,52 @@ var FanControlServerBase = class extends FeaturedBase6 {
160879
160928
  this.applyPercentageAction(percentage);
160880
160929
  });
160881
160930
  }
160931
+ // Per-entity override wins over the per-bridge flag; both must be > 0 to
160932
+ // count. Mirrors WindowCoveringServerBase.resolveDebounceOverride.
160933
+ resolveFanDebounceMs(homeAssistant) {
160934
+ const fromEntity = homeAssistant.state.mapping?.fanSliderDebounceMs;
160935
+ if (typeof fromEntity === "number" && fromEntity > 0) {
160936
+ return fromEntity;
160937
+ }
160938
+ const fromBridge = this.env.get(BridgeDataProvider).featureFlags?.fanSliderDebounceMs;
160939
+ if (typeof fromBridge === "number" && fromBridge > 0) {
160940
+ return fromBridge;
160941
+ }
160942
+ return null;
160943
+ }
160944
+ // Send a speed-derived action, or park it in the debounce window so only the
160945
+ // last write of a burst reaches HA. Cluster state was already updated per
160946
+ // write, so the controller sees immediate feedback either way. With no
160947
+ // window configured this is a plain callAction, the historic path.
160948
+ dispatchSpeedAction(homeAssistant, action) {
160949
+ const debounceMs = this.resolveFanDebounceMs(homeAssistant);
160950
+ if (debounceMs == null) {
160951
+ homeAssistant.callAction(action);
160952
+ return;
160953
+ }
160954
+ const entityId = homeAssistant.entityId;
160955
+ const actions = this.env.get(HomeAssistantActions);
160956
+ const st = getFanDebounce(this.endpoint);
160957
+ st.pending = { action, entityId, actions };
160958
+ if (st.timer) {
160959
+ clearTimeout(st.timer);
160960
+ }
160961
+ st.timer = setTimeout(() => {
160962
+ st.timer = null;
160963
+ const pending = st.pending;
160964
+ st.pending = null;
160965
+ if (pending) {
160966
+ pending.actions.call(pending.action, pending.entityId);
160967
+ }
160968
+ }, debounceMs);
160969
+ }
160970
+ // Devices whose fan cannot stop (air conditioners) opt out of driving OnOff
160971
+ // from speed: speed zero is a speed change, not a power change (#442).
160972
+ syncOnOffFromSpeed(on) {
160973
+ if (this.state.config.syncOnOffWithSpeed !== false) {
160974
+ this.syncOnOff(on);
160975
+ }
160976
+ }
160882
160977
  applyPercentageAction(percentage) {
160883
160978
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
160884
160979
  if (!homeAssistant.isAvailable) {
@@ -160911,9 +161006,12 @@ var FanControlServerBase = class extends FeaturedBase6 {
160911
161006
  homeAssistant.entity.state,
160912
161007
  this.agent
160913
161008
  );
160914
- this.syncOnOff(percentage !== 0);
161009
+ this.syncOnOffFromSpeed(percentage !== 0);
160915
161010
  if (percentage === 0) {
160916
- homeAssistant.callAction(config8.turnOff(void 0, this.agent));
161011
+ this.dispatchSpeedAction(
161012
+ homeAssistant,
161013
+ config8.turnOff(void 0, this.agent)
161014
+ );
160917
161015
  } else if (supportsPercentage) {
160918
161016
  const stepSize = config8.getStepSize(
160919
161017
  homeAssistant.entity.state,
@@ -160924,7 +161022,10 @@ var FanControlServerBase = class extends FeaturedBase6 {
160924
161022
  stepSize ?? 1,
160925
161023
  Math.min(100, roundedPercentage)
160926
161024
  );
160927
- homeAssistant.callAction(config8.turnOn(clampedPercentage, this.agent));
161025
+ this.dispatchSpeedAction(
161026
+ homeAssistant,
161027
+ config8.turnOn(clampedPercentage, this.agent)
161028
+ );
160928
161029
  this.rememberSpeed(clampedPercentage);
160929
161030
  } else {
160930
161031
  const presetModes = config8.getPresetModes(homeAssistant.entity.state, this.agent) ?? [];
@@ -160937,7 +161038,8 @@ var FanControlServerBase = class extends FeaturedBase6 {
160937
161038
  speedPresets.length
160938
161039
  );
160939
161040
  const targetPreset = speedPresets[presetIndex];
160940
- homeAssistant.callAction(
161041
+ this.dispatchSpeedAction(
161042
+ homeAssistant,
160941
161043
  config8.setPresetMode(targetPreset, this.agent)
160942
161044
  );
160943
161045
  this.rememberSpeed(percentage);
@@ -161608,6 +161710,19 @@ function rockSettingToSwingMode(setting) {
161608
161710
  }
161609
161711
  return "off";
161610
161712
  }
161713
+ function climateFanOffMode(fanModes) {
161714
+ const modes = fanModes ?? [];
161715
+ const declaredOff = modes.find(
161716
+ (mode) => ["off", "none", "stop"].includes(mode.trim().toLowerCase())
161717
+ );
161718
+ if (declaredOff) {
161719
+ return declaredOff;
161720
+ }
161721
+ const speeds = toAscendingSpeedPresets(
161722
+ modes.filter((mode) => mode.toLowerCase() !== "auto")
161723
+ );
161724
+ return speeds[0] ?? "off";
161725
+ }
161611
161726
  var climateFanControlConfig = {
161612
161727
  getPercentage: () => void 0,
161613
161728
  getStepSize: () => void 0,
@@ -161623,16 +161738,33 @@ var climateFanControlConfig = {
161623
161738
  return attributes4(entity).fan_mode ?? void 0;
161624
161739
  },
161625
161740
  supportsPercentage: () => false,
161741
+ // An AC's fan cannot stop while the compressor runs, so speed zero must not
161742
+ // report the unit as powered off. Without this the Matter OnOff cluster flips
161743
+ // false at zero, the controller shows the AC off, HA reports it still on, and
161744
+ // the tile flaps back. Power stays with the OnOff cluster's own commands.
161745
+ syncOnOffWithSpeed: false,
161626
161746
  isOscillating: (entity) => attributes4(entity).swing_mode?.toLowerCase() !== "off" && attributes4(entity).swing_mode != null,
161627
161747
  supportsOscillation: (entity) => (attributes4(entity).swing_modes?.length ?? 0) > 0,
161628
161748
  getRockSetting: (entity) => swingModeToRockSetting(attributes4(entity).swing_mode),
161629
161749
  // Climate devices don't typically support wind modes
161630
161750
  getWindMode: () => void 0,
161631
161751
  supportsWind: () => false,
161632
- turnOff: () => ({
161633
- action: "climate.set_fan_mode",
161634
- data: { fan_mode: "off" }
161635
- }),
161752
+ // A controller writing percentSetting 0 lands here. An air conditioner's fan
161753
+ // cannot stop independently of the compressor, and HA climate entities almost
161754
+ // never declare an "off" fan mode - sending the literal "off" just fails the
161755
+ // service call, so the slider's bottom position silently does nothing.
161756
+ // Clamp to the slowest real speed instead, unless the entity genuinely offers
161757
+ // an off-like mode, in which case use its own spelling (HA fan mode names are
161758
+ // case-sensitive). Power stays with the OnOff cluster, which is where a
161759
+ // controller's actual "off" belongs.
161760
+ turnOff: (_, agent) => {
161761
+ const entityState = agent.get(HomeAssistantEntityBehavior).state.entity.state;
161762
+ const fanMode = climateFanOffMode(attributes4(entityState).fan_modes);
161763
+ return {
161764
+ action: "climate.set_fan_mode",
161765
+ data: { fan_mode: fanMode }
161766
+ };
161767
+ },
161636
161768
  turnOn: () => ({
161637
161769
  action: "climate.set_fan_mode",
161638
161770
  data: { fan_mode: "on" }
@@ -161721,11 +161853,16 @@ var humidityConfig2 = {
161721
161853
  var ClimateHumidityMeasurementServer = HumidityMeasurementServer(humidityConfig2);
161722
161854
 
161723
161855
  // src/matter/endpoints/legacy/climate/behaviors/climate-on-off-server.ts
161856
+ init_esm();
161724
161857
  init_home_assistant_entity_behavior();
161858
+ var logger212 = Logger.get("ClimateOnOffServer");
161725
161859
  var ClimateOnOffServer = OnOffServer2({
161726
161860
  turnOn: (_value, agent) => {
161727
161861
  const entity = agent.get(HomeAssistantEntityBehavior).entity;
161728
- if (entity.state.state !== "off") {
161862
+ if (entity.state.state !== "off" && agent.get(OnOffServer).state.onOff) {
161863
+ logger212.debug(
161864
+ `[${entity.entity_id}] Skipping redundant OnOff.on(), cached state "${entity.state.state}"`
161865
+ );
161729
161866
  return void 0;
161730
161867
  }
161731
161868
  return { action: "climate.turn_on" };
@@ -161757,7 +161894,7 @@ init_home_assistant_entity_behavior();
161757
161894
  // src/matter/behaviors/thermostat-server.ts
161758
161895
  init_esm();
161759
161896
  init_home_assistant_entity_behavior();
161760
- var logger212 = Logger.get("ThermostatServer");
161897
+ var logger213 = Logger.get("ThermostatServer");
161761
161898
  var SystemMode = Thermostat3.SystemMode;
161762
161899
  var RunningMode = Thermostat3.ThermostatRunningMode;
161763
161900
  var nudgingSetpoints = /* @__PURE__ */ new Set();
@@ -161836,7 +161973,7 @@ function clearInactiveSetpointState(self, scope) {
161836
161973
  }
161837
161974
  function thermostatPreInitialize(self) {
161838
161975
  const currentLocal = self.state.localTemperature;
161839
- logger212.debug(
161976
+ logger213.debug(
161840
161977
  `initialize: features - heating=${self.features.heating}, cooling=${self.features.cooling}`
161841
161978
  );
161842
161979
  const localValue = typeof currentLocal === "number" && !Number.isNaN(currentLocal) ? currentLocal : currentLocal === null ? null : 2100;
@@ -161883,7 +162020,7 @@ function thermostatPreInitialize(self) {
161883
162020
  } else {
161884
162021
  clearInactiveSetpointState(self, "Cool");
161885
162022
  }
161886
- logger212.debug(
162023
+ logger213.debug(
161887
162024
  `initialize: after force-set - local=${self.state.localTemperature}`
161888
162025
  );
161889
162026
  self.state.thermostatRunningState = runningStateAllOff;
@@ -161976,7 +162113,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
161976
162113
  maxCoolLimit,
161977
162114
  "cool"
161978
162115
  );
161979
- logger212.debug(
162116
+ logger213.debug(
161980
162117
  `update: limits heat=[${minHeatLimit}, ${maxHeatLimit}], cool=[${minCoolLimit}, ${maxCoolLimit}], systemMode=${systemMode}, runningMode=${runningMode}`
161981
162118
  );
161982
162119
  let controlSequence = config8.getControlSequence(entity.state, this.agent);
@@ -162049,18 +162186,18 @@ var ThermostatServerBase = class extends FullFeaturedBase {
162049
162186
  */
162050
162187
  // biome-ignore lint/correctness/noUnusedPrivateClassMembers: Called via thermostatPostInitialize + prototype copy
162051
162188
  heatingSetpointChanging(value, _oldValue, context) {
162052
- logger212.debug(
162189
+ logger213.debug(
162053
162190
  `heatingSetpointChanging: value=${value}, oldValue=${_oldValue}, isOffline=${transactionIsOffline(context)}`
162054
162191
  );
162055
162192
  if (transactionIsOffline(context)) {
162056
- logger212.debug(
162193
+ logger213.debug(
162057
162194
  "heatingSetpointChanging: skipping - transaction is offline"
162058
162195
  );
162059
162196
  return;
162060
162197
  }
162061
162198
  const next = Temperature.celsius(value / 100);
162062
162199
  if (!next) {
162063
- logger212.debug("heatingSetpointChanging: skipping - invalid temperature");
162200
+ logger213.debug("heatingSetpointChanging: skipping - invalid temperature");
162064
162201
  return;
162065
162202
  }
162066
162203
  this.agent.asLocalActor(() => {
@@ -162071,7 +162208,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
162071
162208
  this.agent
162072
162209
  );
162073
162210
  const currentMode2 = this.state.systemMode;
162074
- logger212.debug(
162211
+ logger213.debug(
162075
162212
  `heatingSetpointChanging: supportsRange=${supportsRange}, systemMode=${currentMode2}, features.heating=${this.features.heating}, features.cooling=${this.features.cooling}`
162076
162213
  );
162077
162214
  if (!supportsRange) {
@@ -162081,12 +162218,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
162081
162218
  const isOff = currentMode2 === Thermostat3.SystemMode.Off;
162082
162219
  if (isOff && this.features.heating) {
162083
162220
  if (nudgingSetpoints.has(homeAssistant.entityId)) {
162084
- logger212.debug(
162221
+ logger213.debug(
162085
162222
  `heatingSetpointChanging: skipping auto-resume - nudge write in progress`
162086
162223
  );
162087
162224
  return;
162088
162225
  }
162089
- logger212.info(
162226
+ logger213.info(
162090
162227
  `heatingSetpointChanging: auto-resume - switching to Heat (was Off)`
162091
162228
  );
162092
162229
  const modeAction = config8.setSystemMode(
@@ -162095,17 +162232,17 @@ var ThermostatServerBase = class extends FullFeaturedBase {
162095
162232
  );
162096
162233
  homeAssistant.callAction(modeAction);
162097
162234
  } else if (!isAutoMode && !isHeatingMode) {
162098
- logger212.debug(
162235
+ logger213.debug(
162099
162236
  `heatingSetpointChanging: skipping - not in heating/auto mode (mode=${currentMode2}, haMode=${haHvacMode})`
162100
162237
  );
162101
162238
  return;
162102
162239
  }
162103
- logger212.debug(
162240
+ logger213.debug(
162104
162241
  `heatingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isHeatingMode=${isHeatingMode}, isOff=${isOff}, haMode=${haHvacMode}`
162105
162242
  );
162106
162243
  }
162107
162244
  const coolingSetpoint = this.features.cooling ? this.state.occupiedCoolingSetpoint : value;
162108
- logger212.debug(
162245
+ logger213.debug(
162109
162246
  `heatingSetpointChanging: calling setTemperature with heat=${next.celsius(true)}, cool=${coolingSetpoint}`
162110
162247
  );
162111
162248
  this.setTemperature(
@@ -162144,12 +162281,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
162144
162281
  const isOff = currentMode2 === Thermostat3.SystemMode.Off;
162145
162282
  if (isOff && !this.features.heating && this.features.cooling) {
162146
162283
  if (nudgingSetpoints.has(homeAssistant.entityId)) {
162147
- logger212.debug(
162284
+ logger213.debug(
162148
162285
  `coolingSetpointChanging: skipping auto-resume - nudge write in progress`
162149
162286
  );
162150
162287
  return;
162151
162288
  }
162152
- logger212.info(
162289
+ logger213.info(
162153
162290
  `coolingSetpointChanging: auto-resume - switching to Cool (was Off)`
162154
162291
  );
162155
162292
  const modeAction = config8.setSystemMode(
@@ -162158,12 +162295,12 @@ var ThermostatServerBase = class extends FullFeaturedBase {
162158
162295
  );
162159
162296
  homeAssistant.callAction(modeAction);
162160
162297
  } else if (!isAutoMode && !isCoolingMode) {
162161
- logger212.debug(
162298
+ logger213.debug(
162162
162299
  `coolingSetpointChanging: skipping - not in cooling/auto mode (mode=${currentMode2}, haMode=${haHvacMode})`
162163
162300
  );
162164
162301
  return;
162165
162302
  }
162166
- logger212.debug(
162303
+ logger213.debug(
162167
162304
  `coolingSetpointChanging: proceeding - isAutoMode=${isAutoMode}, isCoolingMode=${isCoolingMode}, isOff=${isOff}, haMode=${haHvacMode}`
162168
162305
  );
162169
162306
  }
@@ -162277,7 +162414,7 @@ var ThermostatServerBase = class extends FullFeaturedBase {
162277
162414
  const effectiveMax = max ?? 5e3;
162278
162415
  if (value == null || Number.isNaN(value)) {
162279
162416
  const defaultValue = type === "heat" ? 2e3 : 2400;
162280
- logger212.debug(
162417
+ logger213.debug(
162281
162418
  `${type} setpoint is undefined, using default: ${defaultValue}`
162282
162419
  );
162283
162420
  return Math.max(effectiveMin, Math.min(effectiveMax, defaultValue));
@@ -162855,7 +162992,7 @@ function ClimateDevice(homeAssistantEntity, includeBasicInformation = true) {
162855
162992
  }
162856
162993
 
162857
162994
  // src/matter/endpoints/composed/composed-climate-fan-endpoint.ts
162858
- var logger213 = Logger.get("ComposedClimateFanEndpoint");
162995
+ var logger214 = Logger.get("ComposedClimateFanEndpoint");
162859
162996
  function createEndpointId3(entityId, customName) {
162860
162997
  const baseName = customName || entityId;
162861
162998
  return baseName.replace(/\./g, "_").replace(/\s+/g, "_");
@@ -162893,7 +163030,7 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
162893
163030
  climateSub = new Endpoint(climateType, { id: `${endpointId}_climate` });
162894
163031
  } catch (error) {
162895
163032
  const message = error instanceof Error ? error.message : String(error);
162896
- logger213.warn(
163033
+ logger214.warn(
162897
163034
  `Companion fan: climate sub build failed for ${primaryEntityId}: ${message}`
162898
163035
  );
162899
163036
  return void 0;
@@ -162937,7 +163074,7 @@ var ComposedClimateFanEndpoint = class _ComposedClimateFanEndpoint extends Endpo
162937
163074
  endpointId,
162938
163075
  [climateSub, fanSub]
162939
163076
  );
162940
- logger213.info(`Created composed climate+fan endpoint ${primaryEntityId}`);
163077
+ logger214.info(`Created composed climate+fan endpoint ${primaryEntityId}`);
162941
163078
  return endpoint;
162942
163079
  }
162943
163080
  constructor(type, entityId, id, parts) {
@@ -163032,7 +163169,7 @@ init_home_assistant_entity_behavior();
163032
163169
  // src/matter/behaviors/pressure-measurement-server.ts
163033
163170
  init_esm();
163034
163171
  init_home_assistant_entity_behavior();
163035
- var logger214 = Logger.get("PressureMeasurementServer");
163172
+ var logger215 = Logger.get("PressureMeasurementServer");
163036
163173
  var MIN_PRESSURE = 300;
163037
163174
  var MAX_PRESSURE = 1100;
163038
163175
  var PressureMeasurementServerBase = class extends PressureMeasurementServer {
@@ -163060,7 +163197,7 @@ var PressureMeasurementServerBase = class extends PressureMeasurementServer {
163060
163197
  }
163061
163198
  const rounded = Math.round(value);
163062
163199
  if (rounded < MIN_PRESSURE || rounded > MAX_PRESSURE) {
163063
- logger214.warn(
163200
+ logger215.warn(
163064
163201
  `Pressure value ${rounded} (raw: ${value}) for ${entity.entity_id} is outside valid range [${MIN_PRESSURE}-${MAX_PRESSURE}], ignoring`
163065
163202
  );
163066
163203
  return null;
@@ -163079,7 +163216,7 @@ function PressureMeasurementServer2(config8) {
163079
163216
  }
163080
163217
 
163081
163218
  // src/matter/endpoints/composed/composed-sensor-endpoint.ts
163082
- var logger215 = Logger.get("ComposedSensorEndpoint");
163219
+ var logger216 = Logger.get("ComposedSensorEndpoint");
163083
163220
  var temperatureConfig2 = {
163084
163221
  getValue(entity, agent) {
163085
163222
  const fallbackUnit = agent.env.get(HomeAssistantConfig).unitSystem.temperature;
@@ -163257,7 +163394,7 @@ var ComposedSensorEndpoint = class _ComposedSensorEndpoint extends Endpoint {
163257
163394
  if (config8.pressureEntityId && pressSub) {
163258
163395
  endpoint.subEndpoints.set(config8.pressureEntityId, pressSub);
163259
163396
  }
163260
- logger215.info(
163397
+ logger216.info(
163261
163398
  `Created composed sensor ${primaryEntityId} with ${parts.length} sub-endpoint(s): T${humSub ? "+H" : ""}${pressSub ? "+P" : ""}${config8.batteryEntityId ? "+Bat" : ""}${config8.powerEntityId ? "+Pwr" : ""}${config8.energyEntityId ? "+Nrg" : ""}`
163262
163399
  );
163263
163400
  return endpoint;
@@ -163394,7 +163531,7 @@ init_home_assistant_entity_behavior();
163394
163531
  // src/matter/behaviors/mode-select-server.ts
163395
163532
  init_esm();
163396
163533
  init_home_assistant_entity_behavior();
163397
- var logger216 = Logger.get("ModeSelectServer");
163534
+ var logger217 = Logger.get("ModeSelectServer");
163398
163535
  function buildSupportedModes(options) {
163399
163536
  return options.map((label, index) => ({
163400
163537
  label: label.length > 64 ? label.substring(0, 64) : label,
@@ -163431,13 +163568,13 @@ var ModeSelectServerBase = class extends ModeSelectServer {
163431
163568
  const options = config8.getOptions(homeAssistant.entity);
163432
163569
  const { newMode } = request;
163433
163570
  if (newMode < 0 || newMode >= options.length) {
163434
- logger216.warn(
163571
+ logger217.warn(
163435
163572
  `[${homeAssistant.entityId}] Invalid mode ${newMode}, options: [${options.join(", ")}]`
163436
163573
  );
163437
163574
  return;
163438
163575
  }
163439
163576
  const option = options[newMode];
163440
- logger216.info(
163577
+ logger217.info(
163441
163578
  `[${homeAssistant.entityId}] changeToMode(${newMode}) -> "${option}"`
163442
163579
  );
163443
163580
  applyPatchState(this.state, { currentMode: newMode });
@@ -163988,7 +164125,7 @@ var CoAlarmWithBatteryType = SmokeCoAlarmDevice.with(
163988
164125
  );
163989
164126
 
163990
164127
  // src/matter/endpoints/legacy/binary-sensor/index.ts
163991
- var logger217 = Logger.get("BinarySensorDevice");
164128
+ var logger218 = Logger.get("BinarySensorDevice");
163992
164129
  var deviceClasses = {
163993
164130
  [BinarySensorDeviceClass.CarbonMonoxide]: CoAlarmType,
163994
164131
  [BinarySensorDeviceClass.Gas]: CoAlarmType,
@@ -164039,11 +164176,11 @@ function BinarySensorDevice(homeAssistantEntity) {
164039
164176
  const originalTypeName = type.name;
164040
164177
  if (hasBattery && batteryTypes.has(type)) {
164041
164178
  type = batteryTypes.get(type);
164042
- logger217.info(
164179
+ logger218.info(
164043
164180
  `[${entityId}] Using battery variant: ${originalTypeName} -> ${type.name}, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
164044
164181
  );
164045
164182
  } else if (hasBattery) {
164046
- logger217.warn(
164183
+ logger218.warn(
164047
164184
  `[${entityId}] Has battery but no variant available for ${originalTypeName}`
164048
164185
  );
164049
164186
  }
@@ -164130,7 +164267,7 @@ init_home_assistant_entity_behavior();
164130
164267
  init_esm();
164131
164268
  init_home_assistant_actions();
164132
164269
  init_home_assistant_entity_behavior();
164133
- var logger218 = Logger.get("WindowCoveringServer");
164270
+ var logger219 = Logger.get("WindowCoveringServer");
164134
164271
  var MovementStatus = WindowCovering3.MovementStatus;
164135
164272
  var FeaturedBase7 = WindowCoveringServer.with(
164136
164273
  "Lift",
@@ -164341,7 +164478,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164341
164478
  }
164342
164479
  return existing100ths ?? current100ths;
164343
164480
  };
164344
- logger218.debug(
164481
+ logger219.debug(
164345
164482
  `Cover update for ${entity.entity_id}: state=${state.state}, lift=${currentLift}%, tilt=${currentTilt}%, ha=${MovementStatus[movementStatus]}, effective=${MovementStatus[globalStatus]}`
164346
164483
  );
164347
164484
  const overrideType = config8.getCoverType?.(state, this.agent);
@@ -164386,9 +164523,9 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164386
164523
  );
164387
164524
  if (Object.keys(appliedPatch).length > 0) {
164388
164525
  const hasOperationalChange = "operationalStatus" in appliedPatch;
164389
- const log = hasOperationalChange ? logger218.info : logger218.debug;
164526
+ const log = hasOperationalChange ? logger219.info : logger219.debug;
164390
164527
  log.call(
164391
- logger218,
164528
+ logger219,
164392
164529
  `Cover ${entity.entity_id} state changed: ${JSON.stringify(appliedPatch)}`
164393
164530
  );
164394
164531
  }
@@ -164497,7 +164634,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164497
164634
  }
164498
164635
  });
164499
164636
  } catch (error) {
164500
- logger218.debug(
164637
+ logger219.debug(
164501
164638
  `Optimistic ${axis} timeout write failed (endpoint may be closing): ${error}`
164502
164639
  );
164503
164640
  }
@@ -164512,7 +164649,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164512
164649
  const currentTilt = this.state.currentPositionTiltPercent100ths ?? 0;
164513
164650
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
164514
164651
  const flags2 = this.state.config.getDiagnosticFlags?.(this.agent);
164515
- logger218.info(
164652
+ logger219.info(
164516
164653
  `handleMovement ${homeAssistant.entityId}: type=${MovementType[type]}, direction=${MovementDirection[direction]}, target=${targetPercent100ths}, currentLift=${currentLift}, currentTilt=${currentTilt}${flags2 ? `, ${flags2}` : ""}`
164517
164654
  );
164518
164655
  if (type === MovementType.Lift) {
@@ -164531,7 +164668,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164531
164668
  }
164532
164669
  } else if (type === MovementType.Tilt) {
164533
164670
  if (targetPercent100ths == null && this.lastLiftMovementDirection === direction && Date.now() - this.lastLiftMovementMs < 50) {
164534
- logger218.info(
164671
+ logger219.info(
164535
164672
  `Skipping tilt ${MovementDirection[direction]}, lift already moving in same direction`
164536
164673
  );
164537
164674
  return;
@@ -164576,7 +164713,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164576
164713
  } else {
164577
164714
  this.startOptimisticMovement("lift", MovementStatus.Opening, end);
164578
164715
  }
164579
- logger218.info(
164716
+ logger219.info(
164580
164717
  `handleLiftOpen ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
164581
164718
  );
164582
164719
  homeAssistant.callAction(action);
@@ -164592,7 +164729,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164592
164729
  } else {
164593
164730
  this.startOptimisticMovement("lift", MovementStatus.Closing, end);
164594
164731
  }
164595
- logger218.info(
164732
+ logger219.info(
164596
164733
  `handleLiftClose ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
164597
164734
  );
164598
164735
  homeAssistant.callAction(action);
@@ -164622,7 +164759,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164622
164759
  const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
164623
164760
  const overrideMs = this.resolveDebounceOverride(homeAssistant);
164624
164761
  const debounceMs = overrideMs != null ? overrideMs : isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
164625
- logger218.debug(
164762
+ logger219.debug(
164626
164763
  `Lift command: target=${targetPosition}%, debounce=${debounceMs}ms (${overrideMs != null ? "override" : isFirstInSequence ? "initial" : "subsequent"})`
164627
164764
  );
164628
164765
  if (st.liftTimer) {
@@ -164654,7 +164791,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164654
164791
  this.startOptimisticMovement("tilt", MovementStatus.Opening, end);
164655
164792
  }
164656
164793
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
164657
- logger218.info(
164794
+ logger219.info(
164658
164795
  `handleTiltOpen ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
164659
164796
  );
164660
164797
  homeAssistant.callAction(action);
@@ -164672,7 +164809,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164672
164809
  this.startOptimisticMovement("tilt", MovementStatus.Closing, end);
164673
164810
  }
164674
164811
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
164675
- logger218.info(
164812
+ logger219.info(
164676
164813
  `handleTiltClose ${homeAssistant.entityId}: calling action=${action.action}, atRest=${atRest}, ${this.state.config.getDiagnosticFlags?.(this.agent) ?? ""}`
164677
164814
  );
164678
164815
  homeAssistant.callAction(action);
@@ -164702,7 +164839,7 @@ var WindowCoveringServerBase = class _WindowCoveringServerBase extends FeaturedB
164702
164839
  const isFirstInSequence = timeSinceLastCommand > _WindowCoveringServerBase.COMMAND_SEQUENCE_THRESHOLD_MS;
164703
164840
  const overrideMs = this.resolveDebounceOverride(homeAssistant);
164704
164841
  const debounceMs = overrideMs != null ? overrideMs : isFirstInSequence ? _WindowCoveringServerBase.DEBOUNCE_INITIAL_MS : _WindowCoveringServerBase.DEBOUNCE_SUBSEQUENT_MS;
164705
- logger218.debug(
164842
+ logger219.debug(
164706
164843
  `Tilt command: target=${targetPosition}%, debounce=${debounceMs}ms (${overrideMs != null ? "override" : isFirstInSequence ? "initial" : "subsequent"})`
164707
164844
  );
164708
164845
  if (st.tiltTimer) {
@@ -164754,7 +164891,7 @@ function adjustPositionForWriting(position, flags2, matterSemantics) {
164754
164891
  }
164755
164892
 
164756
164893
  // src/matter/endpoints/legacy/cover/behaviors/cover-window-covering-server.ts
164757
- var logger219 = Logger.get("CoverWindowCoveringServer");
164894
+ var logger220 = Logger.get("CoverWindowCoveringServer");
164758
164895
  var attributes6 = (entity) => entity.attributes;
164759
164896
  var DEVICE_CLASS_TO_MATTER_TYPE = {
164760
164897
  curtain: {
@@ -164826,7 +164963,7 @@ var adjustPositionForReading2 = (position, agent) => {
164826
164963
  const { featureFlags } = agent.env.get(BridgeDataProvider);
164827
164964
  const matterSem = usesMatterSemantics(agent);
164828
164965
  const result = adjustPositionForReading(position, featureFlags, matterSem);
164829
- logger219.debug(`adjustPositionForReading: HA=${position}%, result=${result}%`);
164966
+ logger220.debug(`adjustPositionForReading: HA=${position}%, result=${result}%`);
164830
164967
  return result;
164831
164968
  };
164832
164969
  var adjustPositionForWriting2 = (position, agent) => {
@@ -165051,14 +165188,14 @@ var CoverAsDimmableLightWithBatteryType = DimmableLightDevice.with(
165051
165188
  );
165052
165189
 
165053
165190
  // src/matter/endpoints/legacy/cover/index.ts
165054
- var logger220 = Logger.get("CoverDevice");
165191
+ var logger221 = Logger.get("CoverDevice");
165055
165192
  var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
165056
165193
  const features = /* @__PURE__ */ new Set();
165057
165194
  if (testBit(supportedFeatures, CoverSupportedFeatures.support_open)) {
165058
165195
  features.add("Lift");
165059
165196
  features.add("PositionAwareLift");
165060
165197
  } else {
165061
- logger220.warn(
165198
+ logger221.warn(
165062
165199
  `[${entityId}] Cover has no support_open feature (supported_features=${supportedFeatures}), adding Lift anyway`
165063
165200
  );
165064
165201
  features.add("Lift");
@@ -165073,7 +165210,7 @@ var CoverDeviceType = (supportedFeatures, hasBattery, entityId) => {
165073
165210
  features.add("PositionAwareTilt");
165074
165211
  }
165075
165212
  }
165076
- logger220.info(
165213
+ logger221.info(
165077
165214
  `[${entityId}] Creating WindowCovering with features: [${[...features].join(", ")}], supported_features=${supportedFeatures}`
165078
165215
  );
165079
165216
  const baseBehaviors2 = [
@@ -165097,16 +165234,16 @@ function CoverDevice(homeAssistantEntity) {
165097
165234
  const hasBatteryEntity = !!homeAssistantEntity.mapping?.batteryEntity;
165098
165235
  const hasBattery = hasBatteryAttr || hasBatteryEntity;
165099
165236
  if (hasBattery) {
165100
- logger220.info(
165237
+ logger221.info(
165101
165238
  `[${entityId}] Creating cover with PowerSource cluster, batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"}`
165102
165239
  );
165103
165240
  } else {
165104
- logger220.debug(
165241
+ logger221.debug(
165105
165242
  `[${entityId}] Creating cover without battery (batteryAttr=${hasBatteryAttr}, batteryEntity=${homeAssistantEntity.mapping?.batteryEntity ?? "none"})`
165106
165243
  );
165107
165244
  }
165108
165245
  if (homeAssistantEntity.mapping?.coverExposeAsDimmableLight) {
165109
- logger220.info(`[${entityId}] Exposing cover as a Dimmable Light (#372)`);
165246
+ logger221.info(`[${entityId}] Exposing cover as a Dimmable Light (#372)`);
165110
165247
  const type = hasBattery ? CoverAsDimmableLightWithBatteryType : CoverAsDimmableLightType;
165111
165248
  return type.set({ homeAssistantEntity });
165112
165249
  }
@@ -165221,7 +165358,7 @@ function DishwasherEndpoint(homeAssistantEntity) {
165221
165358
  // src/matter/behaviors/generic-switch-server.ts
165222
165359
  init_esm();
165223
165360
  init_home_assistant_entity_behavior();
165224
- var logger221 = Logger.get("GenericSwitchServer");
165361
+ var logger222 = Logger.get("GenericSwitchServer");
165225
165362
  var SimpleBase = SwitchServer.with(
165226
165363
  "MomentarySwitch",
165227
165364
  "MomentarySwitchRelease",
@@ -165263,7 +165400,7 @@ var HaGenericSwitchServerBase = class extends SimpleBase {
165263
165400
  await super.initialize();
165264
165401
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
165265
165402
  const entityId = homeAssistant.entityId;
165266
- logger221.debug(`[${entityId}] GenericSwitch initialized (simple)`);
165403
+ logger222.debug(`[${entityId}] GenericSwitch initialized (simple)`);
165267
165404
  this.reactTo(homeAssistant.onChange, this.handleEventChange);
165268
165405
  }
165269
165406
  handleEventChange() {
@@ -165274,7 +165411,7 @@ var HaGenericSwitchServerBase = class extends SimpleBase {
165274
165411
  const eventType = attrs.event_type;
165275
165412
  if (!eventType) return;
165276
165413
  const entityId = homeAssistant.entityId;
165277
- logger221.debug(`[${entityId}] Event fired: ${eventType}`);
165414
+ logger222.debug(`[${entityId}] Event fired: ${eventType}`);
165278
165415
  this.triggerPress(eventType);
165279
165416
  }
165280
165417
  triggerPress(eventType) {
@@ -165320,7 +165457,7 @@ var HaGenericSwitchServerMultiBase = class extends FullBase {
165320
165457
  await super.initialize();
165321
165458
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
165322
165459
  const entityId = homeAssistant.entityId;
165323
- logger221.debug(`[${entityId}] GenericSwitch initialized (multi)`);
165460
+ logger222.debug(`[${entityId}] GenericSwitch initialized (multi)`);
165324
165461
  this.reactTo(homeAssistant.onChange, this.handleEventChange);
165325
165462
  }
165326
165463
  handleEventChange() {
@@ -165331,7 +165468,7 @@ var HaGenericSwitchServerMultiBase = class extends FullBase {
165331
165468
  const eventType = attrs.event_type;
165332
165469
  if (!eventType) return;
165333
165470
  const entityId = homeAssistant.entityId;
165334
- logger221.debug(`[${entityId}] Event fired: ${eventType}`);
165471
+ logger222.debug(`[${entityId}] Event fired: ${eventType}`);
165335
165472
  this.triggerPress(eventType);
165336
165473
  }
165337
165474
  triggerPress(eventType) {
@@ -165708,7 +165845,7 @@ init_nodejs();
165708
165845
  init_home_assistant_entity_behavior();
165709
165846
  var OperationalState4 = RvcOperationalState4.OperationalState;
165710
165847
  var ErrorState = RvcOperationalState4.ErrorState;
165711
- var logger222 = Logger.get("RvcOperationalStateServer");
165848
+ var logger223 = Logger.get("RvcOperationalStateServer");
165712
165849
  var activeStates = /* @__PURE__ */ new Set([
165713
165850
  OperationalState4.Running,
165714
165851
  OperationalState4.SeekingCharger
@@ -165760,7 +165897,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
165760
165897
  { force: true }
165761
165898
  );
165762
165899
  if (activeStates.has(previousState) && !activeStates.has(newState)) {
165763
- logger222.info(
165900
+ logger223.info(
165764
165901
  `Operation completed: ${OperationalState4[previousState]} -> ${OperationalState4[newState]}`
165765
165902
  );
165766
165903
  try {
@@ -165773,7 +165910,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
165773
165910
  this.context
165774
165911
  );
165775
165912
  } catch (e) {
165776
- logger222.debug("Failed to emit operationCompletion event:", e);
165913
+ logger223.debug("Failed to emit operationCompletion event:", e);
165777
165914
  }
165778
165915
  }
165779
165916
  }
@@ -165808,7 +165945,7 @@ var RvcOperationalStateServerBase = class extends RvcOperationalStateServer {
165808
165945
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
165809
165946
  homeAssistant.callAction(goHomeAction(void 0, this.agent));
165810
165947
  } else {
165811
- logger222.warn("GoHome command received but no goHome action configured");
165948
+ logger223.warn("GoHome command received but no goHome action configured");
165812
165949
  }
165813
165950
  return {
165814
165951
  commandResponseState: {
@@ -165828,7 +165965,7 @@ function RvcOperationalStateServer2(config8) {
165828
165965
  }
165829
165966
 
165830
165967
  // src/matter/endpoints/legacy/lawn-mower/behaviors/lawn-mower-rvc-operational-state-server.ts
165831
- var logger223 = Logger.get("LawnMowerRvcOperationalStateServer");
165968
+ var logger224 = Logger.get("LawnMowerRvcOperationalStateServer");
165832
165969
  function mapLawnMowerOperationalState(entity) {
165833
165970
  const state = entity.state;
165834
165971
  switch (state) {
@@ -165844,7 +165981,7 @@ function mapLawnMowerOperationalState(entity) {
165844
165981
  case "unavailable":
165845
165982
  return RvcOperationalState4.OperationalState.Error;
165846
165983
  default:
165847
- logger223.info(`Unknown lawn_mower state "${state}", treating as Stopped`);
165984
+ logger224.info(`Unknown lawn_mower state "${state}", treating as Stopped`);
165848
165985
  return RvcOperationalState4.OperationalState.Stopped;
165849
165986
  }
165850
165987
  }
@@ -165898,7 +166035,7 @@ function inferCleanedAreaProgress(cleanedSqm, orderedAreas) {
165898
166035
  }
165899
166036
 
165900
166037
  // src/matter/behaviors/rvc-run-mode-server.ts
165901
- var logger224 = Logger.get("RvcRunModeServer");
166038
+ var logger225 = Logger.get("RvcRunModeServer");
165902
166039
  var ROOM_MODE_BASE = 100;
165903
166040
  function isRoomMode(mode) {
165904
166041
  return mode >= ROOM_MODE_BASE;
@@ -166024,7 +166161,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
166024
166161
  const s = getSession(this.endpoint);
166025
166162
  if (s.loggedShortCircuits.has(reason)) return;
166026
166163
  s.loggedShortCircuits.add(reason);
166027
- logger224.info(message);
166164
+ logger225.info(message);
166028
166165
  }
166029
166166
  /**
166030
166167
  * Read the currentRoomEntity sensor and update currentArea + progress
@@ -166081,7 +166218,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
166081
166218
  }
166082
166219
  }
166083
166220
  if (matchedAreaId === null) {
166084
- logger224.info(
166221
+ logger225.info(
166085
166222
  `currentRoom sensor: no match for "${roomName}" (segmentId=${segmentId}), activeAreas=[${s.activeAreas.join(", ")}], supportedAreas=[${serviceArea.state.supportedAreas.map((a) => `${a.areaId}:${a.areaInfo.locationInfo?.locationName}`).join(", ")}]`
166086
166223
  );
166087
166224
  return;
@@ -166091,14 +166228,14 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
166091
166228
  s.completedAreas.add(s.lastCurrentArea);
166092
166229
  }
166093
166230
  s.lastCurrentArea = matchedAreaId;
166094
- logger224.info(
166231
+ logger225.info(
166095
166232
  `currentRoom sensor: transition to area ${matchedAreaId} ("${roomName}"), completed: [${[...s.completedAreas].join(", ")}]`
166096
166233
  );
166097
166234
  this.trySetCurrentArea(matchedAreaId);
166098
166235
  } catch (e) {
166099
166236
  const msg = e instanceof Error ? e.message : String(e);
166100
166237
  if (!msg.includes("No provider for") && !msg.includes("not supported")) {
166101
- logger224.warn(`currentRoom sensor update failed: ${msg}`);
166238
+ logger225.warn(`currentRoom sensor update failed: ${msg}`);
166102
166239
  }
166103
166240
  }
166104
166241
  }
@@ -166178,7 +166315,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
166178
166315
  cleaned,
166179
166316
  ordered
166180
166317
  );
166181
- logger224.debug(
166318
+ logger225.debug(
166182
166319
  `cleanedArea: raw=${raw} baseline=${s.cleanedAreaBaseline} cleaned=${cleaned} sizes=[${ordered.map((o) => `${o.areaId}:${o.sizeSqm}`).join(",")}] -> current=${currentArea} completed=[${completed.join(",")}]`
166183
166320
  );
166184
166321
  for (const id of completed) {
@@ -166192,7 +166329,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
166192
166329
  } catch (e) {
166193
166330
  const msg = e instanceof Error ? e.message : String(e);
166194
166331
  if (!msg.includes("No provider for") && !msg.includes("not supported")) {
166195
- logger224.warn(`cleanedArea room update failed: ${msg}`);
166332
+ logger225.warn(`cleanedArea room update failed: ${msg}`);
166196
166333
  }
166197
166334
  }
166198
166335
  }
@@ -166207,7 +166344,7 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
166207
166344
  const serviceArea = this.agent.get(ServiceAreaBehavior);
166208
166345
  if (serviceArea.state.currentArea !== areaId) {
166209
166346
  serviceArea.state.currentArea = areaId;
166210
- logger224.debug(`currentArea set to ${areaId}`);
166347
+ logger225.debug(`currentArea set to ${areaId}`);
166211
166348
  }
166212
166349
  this.updateProgress(serviceArea, areaId);
166213
166350
  } catch {
@@ -166490,7 +166627,7 @@ init_nodejs();
166490
166627
 
166491
166628
  // src/matter/behaviors/color-control-server.ts
166492
166629
  init_home_assistant_entity_behavior();
166493
- var logger225 = Logger.get("ColorControlServer");
166630
+ var logger226 = Logger.get("ColorControlServer");
166494
166631
  var optimisticColorState = /* @__PURE__ */ new Map();
166495
166632
  var OPTIMISTIC_TIMEOUT_MS3 = 3e3;
166496
166633
  var OPTIMISTIC_TOLERANCE2 = 5;
@@ -166529,7 +166666,7 @@ var ColorControlServerBase = class extends FeaturedBase8 {
166529
166666
  if (this.state.startUpColorTemperatureMireds == null) {
166530
166667
  this.state.startUpColorTemperatureMireds = defaultMireds;
166531
166668
  }
166532
- logger225.debug(
166669
+ logger226.debug(
166533
166670
  `initialize: set ColorTemperature defaults - min=${this.state.colorTempPhysicalMinMireds}, max=${this.state.colorTempPhysicalMaxMireds}, current=${this.state.colorTemperatureMireds}`
166534
166671
  );
166535
166672
  }
@@ -167084,7 +167221,7 @@ init_home_assistant_entity_behavior();
167084
167221
  // src/matter/behaviors/lock-server.ts
167085
167222
  init_esm();
167086
167223
  init_home_assistant_entity_behavior();
167087
- var logger226 = Logger.get("LockServer");
167224
+ var logger227 = Logger.get("LockServer");
167088
167225
  var SUPPORTED_SLOT = 1;
167089
167226
  function normalizeSupportedIndex(index) {
167090
167227
  if (index === 0 || index === SUPPORTED_SLOT) {
@@ -167425,7 +167562,7 @@ var LockServerWithPinBase = class extends PinCredentialBase {
167425
167562
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
167426
167563
  const action = this.state.config.lock(void 0, this.agent);
167427
167564
  const hasPinProvided = !!request.pinCode;
167428
- logger226.debug(
167565
+ logger227.debug(
167429
167566
  `lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
167430
167567
  );
167431
167568
  if (request.pinCode) {
@@ -167438,12 +167575,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
167438
167575
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
167439
167576
  const action = this.state.config.unlock(void 0, this.agent);
167440
167577
  const hasPinProvided = !!request.pinCode;
167441
- logger226.debug(
167578
+ logger227.debug(
167442
167579
  `unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
167443
167580
  );
167444
167581
  if (this.state.requirePinForRemoteOperation) {
167445
167582
  if (!request.pinCode) {
167446
- logger226.info(
167583
+ logger227.info(
167447
167584
  `unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
167448
167585
  );
167449
167586
  throw new StatusResponseError(
@@ -167453,12 +167590,12 @@ var LockServerWithPinBase = class extends PinCredentialBase {
167453
167590
  }
167454
167591
  const providedPin = new TextDecoder().decode(request.pinCode);
167455
167592
  if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
167456
- logger226.info(
167593
+ logger227.info(
167457
167594
  `unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
167458
167595
  );
167459
167596
  throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
167460
167597
  }
167461
- logger226.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
167598
+ logger227.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
167462
167599
  action.data = { ...action.data, code: providedPin };
167463
167600
  }
167464
167601
  homeAssistant.callAction(action);
@@ -167600,7 +167737,7 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
167600
167737
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
167601
167738
  const action = this.state.config.lock(void 0, this.agent);
167602
167739
  const hasPinProvided = !!request.pinCode;
167603
- logger226.debug(
167740
+ logger227.debug(
167604
167741
  `lockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}`
167605
167742
  );
167606
167743
  if (request.pinCode) {
@@ -167614,12 +167751,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
167614
167751
  const unlatchConfig = this.state.config.unlatch;
167615
167752
  const action = unlatchConfig ? unlatchConfig(void 0, this.agent) : this.state.config.unlock(void 0, this.agent);
167616
167753
  const hasPinProvided = !!request.pinCode;
167617
- logger226.debug(
167754
+ logger227.debug(
167618
167755
  `unlockDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}, usingUnlatch: ${!!unlatchConfig}`
167619
167756
  );
167620
167757
  if (this.state.requirePinForRemoteOperation) {
167621
167758
  if (!request.pinCode) {
167622
- logger226.info(
167759
+ logger227.info(
167623
167760
  `unlockDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
167624
167761
  );
167625
167762
  throw new StatusResponseError(
@@ -167629,12 +167766,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
167629
167766
  }
167630
167767
  const providedPin = new TextDecoder().decode(request.pinCode);
167631
167768
  if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
167632
- logger226.info(
167769
+ logger227.info(
167633
167770
  `unlockDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
167634
167771
  );
167635
167772
  throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
167636
167773
  }
167637
- logger226.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
167774
+ logger227.debug(`unlockDoor PIN verified for ${homeAssistant.entityId}`);
167638
167775
  action.data = { ...action.data, code: providedPin };
167639
167776
  }
167640
167777
  homeAssistant.callAction(action);
@@ -167643,12 +167780,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
167643
167780
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
167644
167781
  const action = this.state.config.unlock(void 0, this.agent);
167645
167782
  const hasPinProvided = !!request.pinCode;
167646
- logger226.debug(
167783
+ logger227.debug(
167647
167784
  `unboltDoor called for ${homeAssistant.entityId}, PIN provided: ${hasPinProvided}, requirePin: ${this.state.requirePinForRemoteOperation}`
167648
167785
  );
167649
167786
  if (this.state.requirePinForRemoteOperation) {
167650
167787
  if (!request.pinCode) {
167651
- logger226.info(
167788
+ logger227.info(
167652
167789
  `unboltDoor REJECTED for ${homeAssistant.entityId} - no PIN provided`
167653
167790
  );
167654
167791
  throw new StatusResponseError(
@@ -167658,12 +167795,12 @@ var LockServerWithPinAndUnboltBase = class extends PinCredentialUnboltBase {
167658
167795
  }
167659
167796
  const providedPin = new TextDecoder().decode(request.pinCode);
167660
167797
  if (!verifyStoredPinHelper(this.env, homeAssistant.entityId, providedPin)) {
167661
- logger226.info(
167798
+ logger227.info(
167662
167799
  `unboltDoor REJECTED for ${homeAssistant.entityId} - invalid PIN`
167663
167800
  );
167664
167801
  throw new StatusResponseError("Invalid PIN code", StatusCode.Failure);
167665
167802
  }
167666
- logger226.debug(`unboltDoor PIN verified for ${homeAssistant.entityId}`);
167803
+ logger227.debug(`unboltDoor PIN verified for ${homeAssistant.entityId}`);
167667
167804
  action.data = { ...action.data, code: providedPin };
167668
167805
  }
167669
167806
  homeAssistant.callAction(action);
@@ -167802,7 +167939,7 @@ init_home_assistant_entity_behavior();
167802
167939
  init_dist();
167803
167940
  init_esm();
167804
167941
  init_home_assistant_entity_behavior();
167805
- var logger227 = Logger.get("MediaPlayerKeypadInputServer");
167942
+ var logger228 = Logger.get("MediaPlayerKeypadInputServer");
167806
167943
  var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
167807
167944
  sendKey(request) {
167808
167945
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
@@ -167813,12 +167950,12 @@ var MediaPlayerKeypadInputServer = class extends KeypadInputServer {
167813
167950
  const features = attributes9.supported_features ?? 0;
167814
167951
  const action = this.mapKeyToAction(request.keyCode, features);
167815
167952
  if (!action) {
167816
- logger227.debug(
167953
+ logger228.debug(
167817
167954
  `Unsupported key code ${request.keyCode} for ${homeAssistant.entityId}`
167818
167955
  );
167819
167956
  return { status: KeypadInput3.Status.UnsupportedKey };
167820
167957
  }
167821
- logger227.debug(
167958
+ logger228.debug(
167822
167959
  `sendKey(${request.keyCode}) \u2192 ${action} for ${homeAssistant.entityId}`
167823
167960
  );
167824
167961
  homeAssistant.callAction({ action });
@@ -168097,7 +168234,7 @@ init_home_assistant_entity_behavior();
168097
168234
  // src/matter/behaviors/speaker-level-control-server.ts
168098
168235
  init_esm();
168099
168236
  init_home_assistant_entity_behavior();
168100
- var logger228 = Logger.get("SpeakerLevelControlServer");
168237
+ var logger229 = Logger.get("SpeakerLevelControlServer");
168101
168238
  var optimisticLevelState2 = /* @__PURE__ */ new Map();
168102
168239
  var OPTIMISTIC_TIMEOUT_MS4 = 3e3;
168103
168240
  var OPTIMISTIC_TOLERANCE3 = 5;
@@ -168140,7 +168277,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase9 {
168140
168277
  currentLevel = Math.min(Math.max(minLevel, currentLevel), maxLevel);
168141
168278
  }
168142
168279
  const entityId = this.agent.get(HomeAssistantEntityBehavior).entity.entity_id;
168143
- logger228.debug(
168280
+ logger229.debug(
168144
168281
  `[${entityId}] Volume update: HA=${currentLevelPercent != null ? Math.round(currentLevelPercent * 100) : "null"}% -> currentLevel=${currentLevel}`
168145
168282
  );
168146
168283
  const optimistic = optimisticLevelState2.get(entity.entity_id);
@@ -168188,7 +168325,7 @@ var SpeakerLevelControlServerBase = class extends FeaturedBase9 {
168188
168325
  const config8 = this.state.config;
168189
168326
  const entityId = homeAssistant.entity.entity_id;
168190
168327
  const levelPercent = level / 254;
168191
- logger228.debug(
168328
+ logger229.debug(
168192
168329
  `[${entityId}] Volume command: level=${level} -> HA volume_level=${levelPercent}`
168193
168330
  );
168194
168331
  const current = config8.getValuePercent(
@@ -169132,7 +169269,7 @@ function mapEvseStatus(rawState, chargingSwitchOn) {
169132
169269
  }
169133
169270
 
169134
169271
  // src/matter/endpoints/legacy/sensor/devices/energy-evse.ts
169135
- var logger229 = Logger.get("EnergyEvse");
169272
+ var logger230 = Logger.get("EnergyEvse");
169136
169273
  var MIN_CHARGE_CURRENT_MA = 6e3;
169137
169274
  var MAX_CHARGE_CURRENT_MA = 32e3;
169138
169275
  var CIRCUIT_CAPACITY_MA = 32e3;
@@ -169216,7 +169353,7 @@ var EvseStatusServer = class _EvseStatusServer extends EnergyEvseServer {
169216
169353
  dispatched = true;
169217
169354
  }
169218
169355
  if (!dispatched) {
169219
- logger229.debug(
169356
+ logger230.debug(
169220
169357
  `enableCharging ignored for ${homeAssistant.entityId}: no charging switch or current limit mapped`
169221
169358
  );
169222
169359
  return;
@@ -169256,7 +169393,7 @@ var EvseStatusServer = class _EvseStatusServer extends EnergyEvseServer {
169256
169393
  chargingEnabledUntil: null
169257
169394
  });
169258
169395
  } catch (error) {
169259
- logger229.debug(
169396
+ logger230.debug(
169260
169397
  `EVSE charge-window expiry write failed (endpoint may be closing): ${error}`
169261
169398
  );
169262
169399
  } finally {
@@ -169287,7 +169424,7 @@ var EvseStatusServer = class _EvseStatusServer extends EnergyEvseServer {
169287
169424
  chargingEnabledUntil: null
169288
169425
  });
169289
169426
  } else {
169290
- logger229.debug(
169427
+ logger230.debug(
169291
169428
  `disable ignored for ${homeAssistant.entityId}: no charging switch mapped`
169292
169429
  );
169293
169430
  }
@@ -170092,7 +170229,7 @@ var TvocConcentrationMeasurementServer = class extends TvocConcentrationMeasurem
170092
170229
  };
170093
170230
 
170094
170231
  // src/matter/endpoints/legacy/sensor/devices/tvoc-sensor.ts
170095
- var logger230 = Logger.get("TvocSensor");
170232
+ var logger231 = Logger.get("TvocSensor");
170096
170233
  function airQualityFromUgm3(value) {
170097
170234
  if (value <= 300) return AirQuality3.AirQualityEnum.Good;
170098
170235
  if (value <= 1e3) return AirQuality3.AirQualityEnum.Fair;
@@ -170133,17 +170270,17 @@ var TvocAirQualityServer = class extends TvocAirQualityServerBase {
170133
170270
  const attributes9 = entity.state.attributes;
170134
170271
  const deviceClass = attributes9.device_class;
170135
170272
  let airQuality = AirQuality3.AirQualityEnum.Unknown;
170136
- logger230.debug(
170273
+ logger231.debug(
170137
170274
  `[${entity.entity_id}] TVOC update: state="${state}", device_class="${deviceClass}"`
170138
170275
  );
170139
170276
  if (state != null && !Number.isNaN(+state)) {
170140
170277
  const value = +state;
170141
170278
  airQuality = deviceClass === SensorDeviceClass.volatile_organic_compounds ? airQualityFromUgm3(value) : airQualityFromPpb(value);
170142
- logger230.debug(
170279
+ logger231.debug(
170143
170280
  `[${entity.entity_id}] TVOC value=${value} (${deviceClass}) -> airQuality=${AirQuality3.AirQualityEnum[airQuality]}`
170144
170281
  );
170145
170282
  } else {
170146
- logger230.warn(
170283
+ logger231.warn(
170147
170284
  `[${entity.entity_id}] TVOC state not a valid number: "${state}"`
170148
170285
  );
170149
170286
  }
@@ -170357,7 +170494,7 @@ init_home_assistant_entity_behavior();
170357
170494
  // src/matter/behaviors/pm25-concentration-measurement-server.ts
170358
170495
  init_esm();
170359
170496
  init_home_assistant_entity_behavior();
170360
- var logger231 = Logger.get("Pm25ConcentrationMeasurementServer");
170497
+ var logger232 = Logger.get("Pm25ConcentrationMeasurementServer");
170361
170498
  var Pm25ConcentrationMeasurementServerBase = Pm25ConcentrationMeasurementServer.with(
170362
170499
  ConcentrationMeasurement3.Feature.NumericMeasurement
170363
170500
  );
@@ -170381,11 +170518,11 @@ var Pm25ConcentrationMeasurementServer2 = class extends Pm25ConcentrationMeasure
170381
170518
  if (this.state.measurementMedium === void 0) {
170382
170519
  this.state.measurementMedium = ConcentrationMeasurement3.MeasurementMedium.Air;
170383
170520
  }
170384
- logger231.debug(
170521
+ logger232.debug(
170385
170522
  "Pm25ConcentrationMeasurementServer: before super.initialize()"
170386
170523
  );
170387
170524
  await super.initialize();
170388
- logger231.debug(
170525
+ logger232.debug(
170389
170526
  "Pm25ConcentrationMeasurementServer: after super.initialize()"
170390
170527
  );
170391
170528
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
@@ -170408,7 +170545,7 @@ var Pm25ConcentrationMeasurementServer2 = class extends Pm25ConcentrationMeasure
170408
170545
  };
170409
170546
 
170410
170547
  // src/matter/endpoints/legacy/sensor/devices/pm25-sensor.ts
170411
- var logger232 = Logger.get("Pm25AirQualityServer");
170548
+ var logger233 = Logger.get("Pm25AirQualityServer");
170412
170549
  var Pm25AirQualityServerBase = AirQualityServer.with(
170413
170550
  AirQuality3.Feature.Fair,
170414
170551
  AirQuality3.Feature.Moderate,
@@ -170420,9 +170557,9 @@ var Pm25AirQualityServer = class extends Pm25AirQualityServerBase {
170420
170557
  if (this.state.airQuality === void 0) {
170421
170558
  this.state.airQuality = AirQuality3.AirQualityEnum.Unknown;
170422
170559
  }
170423
- logger232.debug("Pm25AirQualityServer: before super.initialize()");
170560
+ logger233.debug("Pm25AirQualityServer: before super.initialize()");
170424
170561
  await super.initialize();
170425
- logger232.debug("Pm25AirQualityServer: after super.initialize()");
170562
+ logger233.debug("Pm25AirQualityServer: after super.initialize()");
170426
170563
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
170427
170564
  this.update(homeAssistant.entity);
170428
170565
  this.reactTo(homeAssistant.onChange, this.update, { offline: true });
@@ -170847,7 +170984,7 @@ init_home_assistant_entity_behavior();
170847
170984
  init_dist();
170848
170985
  init_esm();
170849
170986
  init_home_assistant_entity_behavior();
170850
- var logger233 = Logger.get("VacuumIdentifyServer");
170987
+ var logger234 = Logger.get("VacuumIdentifyServer");
170851
170988
  var IDENTIFY_BUTTON_SUFFIXES = ["_identify", "_locate", "_find_me"];
170852
170989
  var VacuumIdentifyServer = class extends IdentifyServer2 {
170853
170990
  triggerEffect(effect) {
@@ -170864,19 +171001,19 @@ var VacuumIdentifyServer = class extends IdentifyServer2 {
170864
171001
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
170865
171002
  const features = homeAssistant.entity.state.attributes.supported_features ?? 0;
170866
171003
  if (testBit(features, VacuumDeviceFeature.LOCATE)) {
170867
- logger233.info(`${source} \u2192 vacuum.locate for ${homeAssistant.entityId}`);
171004
+ logger234.info(`${source} \u2192 vacuum.locate for ${homeAssistant.entityId}`);
170868
171005
  homeAssistant.callAction({ action: "vacuum.locate" });
170869
171006
  return;
170870
171007
  }
170871
171008
  const sibling = this.#findIdentifyButton(homeAssistant);
170872
171009
  if (sibling) {
170873
- logger233.info(
171010
+ logger234.info(
170874
171011
  `${source} \u2192 button.press ${sibling} for ${homeAssistant.entityId}`
170875
171012
  );
170876
171013
  homeAssistant.callAction({ action: "button.press", target: sibling });
170877
171014
  return;
170878
171015
  }
170879
- logger233.warn(
171016
+ logger234.warn(
170880
171017
  `${source} for ${homeAssistant.entityId}, LOCATE not in supported_features (${features}), trying vacuum.locate anyway`
170881
171018
  );
170882
171019
  homeAssistant.callAction({ action: "vacuum.locate" });
@@ -171076,7 +171213,7 @@ init_esm();
171076
171213
  // src/matter/behaviors/service-area-server.ts
171077
171214
  init_esm();
171078
171215
  init_home_assistant_entity_behavior();
171079
- var logger234 = Logger.get("ServiceAreaServer");
171216
+ var logger235 = Logger.get("ServiceAreaServer");
171080
171217
  function orderSelection(areas, agent) {
171081
171218
  try {
171082
171219
  const ascending = agent?.get(HomeAssistantEntityBehavior).state.mapping?.vacuumAscendingRoomOrder === true;
@@ -171091,7 +171228,7 @@ var ServiceAreaWithProgress = ServiceAreaBehavior.with(
171091
171228
  var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
171092
171229
  selectAreas(request) {
171093
171230
  const { newAreas } = request;
171094
- logger234.info(
171231
+ logger235.info(
171095
171232
  `ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
171096
171233
  );
171097
171234
  const uniqueAreas = orderSelection([...new Set(newAreas)], this.agent);
@@ -171100,7 +171237,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
171100
171237
  (id) => !supportedAreaIds.includes(id)
171101
171238
  );
171102
171239
  if (invalidAreas.length > 0) {
171103
- logger234.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
171240
+ logger235.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
171104
171241
  return {
171105
171242
  status: ServiceArea3.SelectAreasStatus.UnsupportedArea,
171106
171243
  statusText: `Invalid area IDs: ${invalidAreas.join(", ")}`
@@ -171112,7 +171249,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
171112
171249
  status: ServiceArea3.OperationalStatus.Pending
171113
171250
  }));
171114
171251
  this.state.currentArea = null;
171115
- logger234.info(
171252
+ logger235.info(
171116
171253
  `ServiceArea: Stored ${uniqueAreas.length} areas for cleaning: ${uniqueAreas.join(", ")}`
171117
171254
  );
171118
171255
  return {
@@ -171133,7 +171270,7 @@ var ServiceAreaServerBase = class extends ServiceAreaWithProgress {
171133
171270
  ServiceAreaServerBase2.State = State;
171134
171271
  })(ServiceAreaServerBase || (ServiceAreaServerBase = {}));
171135
171272
  function ServiceAreaServer2(initialState) {
171136
- logger234.info(
171273
+ logger235.info(
171137
171274
  `Creating ServiceAreaServer with ${initialState.supportedAreas.length} areas`
171138
171275
  );
171139
171276
  return ServiceAreaServerBase.set({
@@ -171150,7 +171287,7 @@ var ServiceAreaWithMapsAndProgress = ServiceAreaBehavior.with(
171150
171287
  var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress {
171151
171288
  selectAreas(request) {
171152
171289
  const { newAreas } = request;
171153
- logger234.info(
171290
+ logger235.info(
171154
171291
  `ServiceArea selectAreas called with: ${JSON.stringify(newAreas)}`
171155
171292
  );
171156
171293
  const uniqueAreas = orderSelection([...new Set(newAreas)], this.agent);
@@ -171159,7 +171296,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
171159
171296
  (id) => !supportedAreaIds.includes(id)
171160
171297
  );
171161
171298
  if (invalidAreas.length > 0) {
171162
- logger234.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
171299
+ logger235.warn(`Invalid area IDs requested: ${invalidAreas.join(", ")}`);
171163
171300
  return {
171164
171301
  status: ServiceArea3.SelectAreasStatus.UnsupportedArea,
171165
171302
  statusText: `Invalid area IDs: ${invalidAreas.join(", ")}`
@@ -171171,7 +171308,7 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
171171
171308
  status: ServiceArea3.OperationalStatus.Pending
171172
171309
  }));
171173
171310
  this.state.currentArea = null;
171174
- logger234.info(
171311
+ logger235.info(
171175
171312
  `ServiceArea: Stored ${uniqueAreas.length} areas for cleaning: ${uniqueAreas.join(", ")}`
171176
171313
  );
171177
171314
  return {
@@ -171192,14 +171329,14 @@ var ServiceAreaServerWithMapsBase = class extends ServiceAreaWithMapsAndProgress
171192
171329
  ServiceAreaServerWithMapsBase2.State = State;
171193
171330
  })(ServiceAreaServerWithMapsBase || (ServiceAreaServerWithMapsBase = {}));
171194
171331
  function ServiceAreaServerWithMaps(initialState) {
171195
- logger234.info(
171332
+ logger235.info(
171196
171333
  `Creating ServiceAreaServer with Maps: ${initialState.supportedAreas.length} areas, ${initialState.supportedMaps.length} maps`
171197
171334
  );
171198
171335
  for (const map of initialState.supportedMaps) {
171199
171336
  const areaCount = initialState.supportedAreas.filter(
171200
171337
  (a) => a.mapId === map.mapId
171201
171338
  ).length;
171202
- logger234.info(` Map ${map.mapId}: "${map.name}" (${areaCount} areas)`);
171339
+ logger235.info(` Map ${map.mapId}: "${map.name}" (${areaCount} areas)`);
171203
171340
  }
171204
171341
  return ServiceAreaServerWithMapsBase.set({
171205
171342
  supportedAreas: initialState.supportedAreas,
@@ -171211,7 +171348,7 @@ function ServiceAreaServerWithMaps(initialState) {
171211
171348
  }
171212
171349
 
171213
171350
  // src/matter/endpoints/legacy/vacuum/behaviors/vacuum-service-area-server.ts
171214
- var logger235 = Logger.get("VacuumServiceAreaServer");
171351
+ var logger236 = Logger.get("VacuumServiceAreaServer");
171215
171352
  function toAreaId(roomId) {
171216
171353
  if (typeof roomId === "number") {
171217
171354
  return roomId;
@@ -171290,13 +171427,13 @@ function createVacuumServiceAreaServer(attributes9, roomEntities, includeUnnamed
171290
171427
  let rooms;
171291
171428
  if (roomEntities && roomEntities.length > 0) {
171292
171429
  rooms = buttonEntitiesToRooms(roomEntities, attributes9);
171293
- logger235.info(
171430
+ logger236.info(
171294
171431
  `Using ${rooms.length} button entities as rooms: ${rooms.map((r) => r.name).join(", ")}`
171295
171432
  );
171296
171433
  } else {
171297
171434
  rooms = parseVacuumRooms(attributes9, includeUnnamedRooms);
171298
171435
  if (rooms.length > 0) {
171299
- logger235.info(
171436
+ logger236.info(
171300
171437
  `Using ${rooms.length} rooms from attributes: ${rooms.map((r) => r.name).join(", ")}`
171301
171438
  );
171302
171439
  }
@@ -171350,7 +171487,7 @@ function createCustomServiceAreaServer(customAreas) {
171350
171487
  landmarkInfo: null
171351
171488
  }
171352
171489
  }));
171353
- logger235.info(
171490
+ logger236.info(
171354
171491
  `Using ${customAreas.length} custom service areas: ${customAreas.map((a) => a.name).join(", ")}`
171355
171492
  );
171356
171493
  return ServiceAreaServer2({
@@ -171372,7 +171509,7 @@ function createCleanAreaServiceAreaServer(cleanAreaRooms) {
171372
171509
  landmarkInfo: null
171373
171510
  }
171374
171511
  }));
171375
- logger235.info(
171512
+ logger236.info(
171376
171513
  `Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA: ${cleanAreaRooms.map((r) => r.name).join(", ")}`
171377
171514
  );
171378
171515
  return ServiceAreaServer2({
@@ -171408,11 +171545,11 @@ function getVacuumServiceAreas(attributes9, mapping) {
171408
171545
  }
171409
171546
 
171410
171547
  // src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-run-mode-server.ts
171411
- var logger236 = Logger.get("VacuumRvcRunModeServer");
171548
+ var logger237 = Logger.get("VacuumRvcRunModeServer");
171412
171549
  function buildValetudoSegmentAction(vacuumEntityId, segmentIds, valetudoIdentifier) {
171413
171550
  const identifier = valetudoIdentifier || vacuumEntityId.replace(/^vacuum\.valetudo_/, "");
171414
171551
  const topic = `valetudo/${identifier}/MapSegmentationCapability/clean/set`;
171415
- logger236.info(
171552
+ logger237.info(
171416
171553
  `Valetudo: mqtt.publish to ${topic}, segments: ${segmentIds.join(", ")}`
171417
171554
  );
171418
171555
  return {
@@ -171517,14 +171654,14 @@ function mergeBatchData(areas) {
171517
171654
  function handleCustomServiceAreas(selectedAreas, customAreas, session) {
171518
171655
  const matched = selectedAreas.map((areaId) => ({ areaId, area: customAreas[areaId - 1] })).filter((m) => !!m.area);
171519
171656
  if (matched.length === 0) {
171520
- logger236.warn(
171657
+ logger237.warn(
171521
171658
  `Custom service areas: no match for selected IDs ${selectedAreas.join(", ")}`
171522
171659
  );
171523
171660
  return { action: "vacuum.start" };
171524
171661
  }
171525
171662
  const batchArea = matched.find(({ area }) => area.batchDispatch === true);
171526
171663
  if (batchArea) {
171527
- logger236.info(
171664
+ logger237.info(
171528
171665
  `Custom service areas (batch): single call for ${matched.length} room(s): ${matched.map(({ area }) => area.name).join(", ")}`
171529
171666
  );
171530
171667
  session.pendingDispatches = [];
@@ -171545,7 +171682,7 @@ function handleCustomServiceAreas(selectedAreas, customAreas, session) {
171545
171682
  }
171546
171683
  };
171547
171684
  }
171548
- logger236.info(
171685
+ logger237.info(
171549
171686
  `Custom service areas: ${matched.length} room(s) queued: ${matched.map(({ area }) => `${area.service} (${area.name})`).join(", ")}`
171550
171687
  );
171551
171688
  session.pendingDispatches = matched.slice(1).map(({ areaId, area }) => ({
@@ -171603,7 +171740,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
171603
171740
  if (cleanAreaRooms && cleanAreaRooms.length > 0) {
171604
171741
  const haAreaIds = resolveCleanAreaIds(selectedAreas, cleanAreaRooms);
171605
171742
  if (haAreaIds.length > 0) {
171606
- logger236.info(`CLEAN_AREA: cleaning HA areas: ${haAreaIds.join(", ")}`);
171743
+ logger237.info(`CLEAN_AREA: cleaning HA areas: ${haAreaIds.join(", ")}`);
171607
171744
  return {
171608
171745
  action: {
171609
171746
  action: "vacuum.clean_area",
@@ -171623,7 +171760,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
171623
171760
  }
171624
171761
  }
171625
171762
  if (matched.length > 0) {
171626
- logger236.info(
171763
+ logger237.info(
171627
171764
  `Roborock: ${matched.length} room button(s) queued: ${matched.map((m) => m.entityId).join(", ")}`
171628
171765
  );
171629
171766
  return {
@@ -171658,12 +171795,12 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
171658
171795
  }
171659
171796
  }
171660
171797
  if (roomIds.length > 0) {
171661
- logger236.info(`Starting cleaning with selected areas: ${roomIds.join(", ")}`);
171798
+ logger237.info(`Starting cleaning with selected areas: ${roomIds.join(", ")}`);
171662
171799
  if (isDreameVacuum(attributes9)) {
171663
171800
  if (targetMapName) {
171664
171801
  const vacName = entityId.replace("vacuum.", "");
171665
171802
  const selectedMapEntity = `select.${vacName}_selected_map`;
171666
- logger236.info(
171803
+ logger237.info(
171667
171804
  `Dreame multi-floor: switching to map "${targetMapName}" via ${selectedMapEntity}`
171668
171805
  );
171669
171806
  seam.callAction({
@@ -171691,7 +171828,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
171691
171828
  }
171692
171829
  if (isEcovacsVacuum(attributes9)) {
171693
171830
  const roomIdStr = roomIds.join(",");
171694
- logger236.info(`Ecovacs vacuum: Using spot_area for rooms: ${roomIdStr}`);
171831
+ logger237.info(`Ecovacs vacuum: Using spot_area for rooms: ${roomIdStr}`);
171695
171832
  return {
171696
171833
  action: {
171697
171834
  action: "vacuum.send_command",
@@ -171703,7 +171840,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
171703
171840
  pending: []
171704
171841
  };
171705
171842
  }
171706
- logger236.warn(
171843
+ logger237.warn(
171707
171844
  `Room cleaning via send_command not supported for this vacuum type. Rooms: ${roomIds.join(", ")}. Falling back to vacuum.start`
171708
171845
  );
171709
171846
  }
@@ -171712,7 +171849,7 @@ function dispatchRoomClean(attributes9, mapping, entityId, selectedAreas, seam)
171712
171849
  var vacuumRvcRunModeConfig = {
171713
171850
  getCurrentMode: (entity) => {
171714
171851
  const isCleaning = vacuumIsCleaning(entity.state);
171715
- logger236.debug(
171852
+ logger237.debug(
171716
171853
  `Vacuum state: "${entity.state}", isCleaning: ${isCleaning}, currentMode: ${isCleaning ? "Cleaning" : "Idle"}`
171717
171854
  );
171718
171855
  return isCleaning ? 1 /* Cleaning */ : 0 /* Idle */;
@@ -171751,7 +171888,7 @@ var vacuumRvcRunModeConfig = {
171751
171888
  }
171752
171889
  } catch {
171753
171890
  }
171754
- logger236.info("Starting regular cleaning (no areas selected)");
171891
+ logger237.info("Starting regular cleaning (no areas selected)");
171755
171892
  return { action: "vacuum.start" };
171756
171893
  },
171757
171894
  returnToBase: () => ({ action: "vacuum.return_to_base" }),
@@ -171766,7 +171903,7 @@ var vacuumRvcRunModeConfig = {
171766
171903
  const homeAssistant = agent.get(HomeAssistantEntityBehavior);
171767
171904
  const entity = homeAssistant.entity;
171768
171905
  const attributes9 = entity.state.attributes;
171769
- logger236.info(`cleanRoom called: roomMode=${roomMode}`);
171906
+ logger237.info(`cleanRoom called: roomMode=${roomMode}`);
171770
171907
  const cleanAreaRooms = homeAssistant.state.mapping?.cleanAreaRooms;
171771
171908
  if (cleanAreaRooms && cleanAreaRooms.length > 0) {
171772
171909
  const sorted = [...cleanAreaRooms].sort(
@@ -171775,7 +171912,7 @@ var vacuumRvcRunModeConfig = {
171775
171912
  const areaIndex = roomMode - ROOM_MODE_BASE2 - 1;
171776
171913
  if (areaIndex >= 0 && areaIndex < sorted.length) {
171777
171914
  const area = sorted[areaIndex];
171778
- logger236.info(
171915
+ logger237.info(
171779
171916
  `cleanRoom: CLEAN_AREA "${area.name}" \u2192 vacuum.clean_area(${area.haAreaId})`
171780
171917
  );
171781
171918
  return {
@@ -171792,7 +171929,7 @@ var vacuumRvcRunModeConfig = {
171792
171929
  const areaIndex = roomMode - ROOM_MODE_BASE2 - 1;
171793
171930
  if (areaIndex >= 0 && areaIndex < sorted.length) {
171794
171931
  const area = sorted[areaIndex];
171795
- logger236.info(
171932
+ logger237.info(
171796
171933
  `cleanRoom: custom service area "${area.name}" \u2192 ${area.service}`
171797
171934
  );
171798
171935
  return {
@@ -171813,7 +171950,7 @@ var vacuumRvcRunModeConfig = {
171813
171950
  }
171814
171951
  const rooms = parseVacuumRooms(attributes9);
171815
171952
  const numericIdFromMode = getRoomIdFromMode(roomMode);
171816
- logger236.info(
171953
+ logger237.info(
171817
171954
  `cleanRoom: numericIdFromMode=${numericIdFromMode}, available rooms: ${JSON.stringify(rooms.map((r) => ({ id: r.id, name: r.name, modeValue: getRoomModeValue(r) })))}`
171818
171955
  );
171819
171956
  const room = rooms.find((r) => getRoomModeValue(r) === roomMode);
@@ -171823,7 +171960,7 @@ var vacuumRvcRunModeConfig = {
171823
171960
  if (room.mapName) {
171824
171961
  const vacuumName = vacuumEntityId.replace("vacuum.", "");
171825
171962
  const selectedMapEntity = `select.${vacuumName}_selected_map`;
171826
- logger236.info(
171963
+ logger237.info(
171827
171964
  `Dreame multi-floor: switching to map "${room.mapName}" via ${selectedMapEntity}`
171828
171965
  );
171829
171966
  homeAssistant.callAction({
@@ -171832,7 +171969,7 @@ var vacuumRvcRunModeConfig = {
171832
171969
  data: { option: room.mapName }
171833
171970
  });
171834
171971
  }
171835
- logger236.debug(
171972
+ logger237.debug(
171836
171973
  `Dreame vacuum detected, using dreame_vacuum.vacuum_clean_segment for room ${room.name} (commandId: ${commandId3}, id: ${room.id})`
171837
171974
  );
171838
171975
  return {
@@ -171843,7 +171980,7 @@ var vacuumRvcRunModeConfig = {
171843
171980
  };
171844
171981
  }
171845
171982
  if (isRoborockVacuum(attributes9) || isXiaomiMiotVacuum(attributes9)) {
171846
- logger236.debug(
171983
+ logger237.debug(
171847
171984
  `Using vacuum.send_command with app_segment_clean for room ${room.name} (commandId: ${commandId3}, id: ${room.id})`
171848
171985
  );
171849
171986
  return {
@@ -171856,7 +171993,7 @@ var vacuumRvcRunModeConfig = {
171856
171993
  }
171857
171994
  if (isEcovacsVacuum(attributes9)) {
171858
171995
  const roomIdStr = String(commandId3);
171859
- logger236.info(
171996
+ logger237.info(
171860
171997
  `Ecovacs vacuum: Using spot_area for room ${room.name} (id: ${roomIdStr})`
171861
171998
  );
171862
171999
  return {
@@ -171871,7 +172008,7 @@ var vacuumRvcRunModeConfig = {
171871
172008
  }
171872
172009
  };
171873
172010
  }
171874
- logger236.warn(
172011
+ logger237.warn(
171875
172012
  `Room cleaning via send_command not supported for this vacuum type. Room: ${room.name} (id=${commandId3}). Falling back to vacuum.start`
171876
172013
  );
171877
172014
  }
@@ -171888,20 +172025,20 @@ function createVacuumRvcRunModeServer(attributes9, includeUnnamedRooms = false,
171888
172025
  customAreas,
171889
172026
  disableRoomModes
171890
172027
  );
171891
- logger236.info(
172028
+ logger237.info(
171892
172029
  `Creating VacuumRvcRunModeServer with ${rooms.length} rooms, ${supportedModes2.length} total modes`
171893
172030
  );
171894
172031
  if (rooms.length > 0) {
171895
- logger236.info(`Rooms found: ${rooms.map((r) => r.name).join(", ")}`);
172032
+ logger237.info(`Rooms found: ${rooms.map((r) => r.name).join(", ")}`);
171896
172033
  }
171897
172034
  if (filteredCount > 0) {
171898
172035
  const filtered = allRooms.filter((r) => !rooms.some((x) => x.id === r.id));
171899
- logger236.info(
172036
+ logger237.info(
171900
172037
  `Filtered out ${filteredCount} unnamed room(s): ${filtered.map((r) => r.name).join(", ")}`
171901
172038
  );
171902
172039
  }
171903
172040
  if (allRooms.length === 0) {
171904
- logger236.debug(
172041
+ logger237.debug(
171905
172042
  `No rooms found. Attributes: rooms=${JSON.stringify(attributes9.rooms)}, segments=${JSON.stringify(attributes9.segments)}, room_list=${attributes9.room_list}`
171906
172043
  );
171907
172044
  }
@@ -171935,7 +172072,7 @@ function createCleanAreaRvcRunModeServer(cleanAreaRooms) {
171935
172072
  modeTags: [{ value: RvcRunMode3.ModeTag.Cleaning }]
171936
172073
  });
171937
172074
  }
171938
- logger236.info(
172075
+ logger237.info(
171939
172076
  `Creating CLEAN_AREA RvcRunModeServer with ${cleanAreaRooms.length} HA areas, ${modes.length} total modes`
171940
172077
  );
171941
172078
  return RvcRunModeServer2(vacuumRvcRunModeConfig, {
@@ -172025,7 +172162,7 @@ init_nodejs();
172025
172162
 
172026
172163
  // src/matter/behaviors/rvc-clean-mode-server.ts
172027
172164
  init_home_assistant_entity_behavior();
172028
- var logger237 = Logger.get("RvcCleanModeServerBase");
172165
+ var logger238 = Logger.get("RvcCleanModeServerBase");
172029
172166
  var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeServer {
172030
172167
  // Pending mode from a recent changeToMode command.
172031
172168
  // Prevents stale HA state (from a different entity like select.xxx)
@@ -172072,14 +172209,14 @@ var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeS
172072
172209
  const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
172073
172210
  const { newMode } = request;
172074
172211
  if (newMode !== this.state.currentMode && !this.state.supportedModes.some((m) => m.mode === newMode)) {
172075
- logger237.warn(`changeToMode(${newMode}) rejected: unsupported mode`);
172212
+ logger238.warn(`changeToMode(${newMode}) rejected: unsupported mode`);
172076
172213
  return {
172077
172214
  status: ModeBase3.ModeChangeStatus.UnsupportedMode,
172078
172215
  statusText: `Unsupported mode: ${newMode}`
172079
172216
  };
172080
172217
  }
172081
172218
  const modeLabel = this.state.supportedModes.find((m) => m.mode === newMode);
172082
- logger237.info(
172219
+ logger238.info(
172083
172220
  `changeToMode(${newMode}) "${modeLabel?.label ?? "unknown"}" for ${homeAssistant.entityId}`
172084
172221
  );
172085
172222
  this.pendingMode = newMode;
@@ -172087,7 +172224,7 @@ var RvcCleanModeServerBase = class _RvcCleanModeServerBase extends RvcCleanModeS
172087
172224
  this.state.currentMode = newMode;
172088
172225
  const action = this.state.config.setCleanMode(newMode, this.agent);
172089
172226
  if (action) {
172090
- logger237.info(
172227
+ logger238.info(
172091
172228
  `changeToMode: dispatching action ${action.action} \u2192 ${action.target ?? homeAssistant.entityId}`
172092
172229
  );
172093
172230
  homeAssistant.callAction(action);
@@ -172120,7 +172257,7 @@ function RvcCleanModeServer2(config8, initialState) {
172120
172257
  }
172121
172258
 
172122
172259
  // src/matter/endpoints/legacy/vacuum/behaviors/vacuum-rvc-clean-mode-server.ts
172123
- var logger238 = Logger.get("VacuumRvcCleanModeServer");
172260
+ var logger239 = Logger.get("VacuumRvcCleanModeServer");
172124
172261
  var MODE_VACUUM = 0;
172125
172262
  var MODE_VACUUM_AND_MOP = 1;
172126
172263
  var MODE_MOP = 2;
@@ -172390,7 +172527,7 @@ function findMatchingCleanOption(ct, availableOptions) {
172390
172527
  const match = availableOptions.find((o) => classifyCleanOption(o) === type);
172391
172528
  if (match) return match;
172392
172529
  }
172393
- logger238.warn(
172530
+ logger239.warn(
172394
172531
  `No match for ${CLEAN_TYPE_LABELS[ct]} in [${availableOptions.join(", ")}]`
172395
172532
  );
172396
172533
  return availableOptions[0];
@@ -172399,7 +172536,7 @@ function buildCleaningModeAction(targetCleanType, agent) {
172399
172536
  const selectEntityId = getCleaningModeSelectEntity(agent);
172400
172537
  const { options } = readSelectEntity(selectEntityId, agent);
172401
172538
  const optionToUse = findMatchingCleanOption(targetCleanType, options);
172402
- logger238.info(
172539
+ logger239.info(
172403
172540
  `Switching cleaning mode to: ${optionToUse} via ${selectEntityId}`
172404
172541
  );
172405
172542
  return {
@@ -172488,7 +172625,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172488
172625
  }
172489
172626
  }
172490
172627
  if (speedMode !== void 0) {
172491
- logger238.debug(
172628
+ logger239.debug(
172492
172629
  `Current mode: Vacuum + fan_speed="${speedState}" -> mode ${speedMode}`
172493
172630
  );
172494
172631
  return speedMode;
@@ -172509,7 +172646,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172509
172646
  }
172510
172647
  }
172511
172648
  if (mopMode !== void 0) {
172512
- logger238.debug(
172649
+ logger239.debug(
172513
172650
  `Current mode: Mop + intensity="${state}" -> mode ${mopMode}`
172514
172651
  );
172515
172652
  return mopMode;
@@ -172527,14 +172664,14 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172527
172664
  const homeAssistant = agent.get(HomeAssistantEntityBehavior);
172528
172665
  const vacuumEntityId = homeAssistant.entityId;
172529
172666
  const mapping = homeAssistant.state.mapping;
172530
- logger238.info(
172667
+ logger239.info(
172531
172668
  `setCleanMode(${mode}) for ${vacuumEntityId}, suctionEntity=${mapping?.suctionLevelEntity ?? "none"}, mopEntity=${mapping?.mopIntensityEntity ?? "none"}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})}`
172532
172669
  );
172533
172670
  if (mopIntensityList && mopIntensityList.length > 0 && isMopIntensityMode(mode)) {
172534
172671
  const mopIndex = mode - MOP_INTENSITY_MODE_BASE;
172535
172672
  const mopName = mopIntensityList[mopIndex];
172536
172673
  if (!mopName) {
172537
- logger238.warn(`Invalid mop intensity mode index: ${mopIndex}`);
172674
+ logger239.warn(`Invalid mop intensity mode index: ${mopIndex}`);
172538
172675
  return void 0;
172539
172676
  }
172540
172677
  if (hasCleanTypes) {
@@ -172547,18 +172684,18 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172547
172684
  mapping.mopIntensityEntity,
172548
172685
  agent
172549
172686
  );
172550
- logger238.info(
172687
+ logger239.info(
172551
172688
  `Mop intensity entity ${mapping.mopIntensityEntity}: current="${state}", options=${JSON.stringify(options ?? [])}`
172552
172689
  );
172553
172690
  let option = matchMopIntensityOption(mopName, options);
172554
172691
  if (!option && options && mopIndex < options.length) {
172555
172692
  option = options[mopIndex];
172556
- logger238.info(
172693
+ logger239.info(
172557
172694
  `Positional match for mop "${mopName}" -> "${option}" (index ${mopIndex})`
172558
172695
  );
172559
172696
  }
172560
172697
  if (option) {
172561
- logger238.info(
172698
+ logger239.info(
172562
172699
  `Setting mop intensity to: ${option} via ${mapping.mopIntensityEntity}`
172563
172700
  );
172564
172701
  return {
@@ -172567,11 +172704,11 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172567
172704
  target: mapping.mopIntensityEntity
172568
172705
  };
172569
172706
  }
172570
- logger238.warn(
172707
+ logger239.warn(
172571
172708
  `No match for mop intensity "${mopName}" in options: [${(options ?? []).join(", ")}]`
172572
172709
  );
172573
172710
  } else {
172574
- logger238.warn(
172711
+ logger239.warn(
172575
172712
  `Mop intensity mode ${mode} requested but no mopIntensityEntity configured`
172576
172713
  );
172577
172714
  }
@@ -172581,7 +172718,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172581
172718
  const fanSpeedIndex = mode - FAN_SPEED_MODE_BASE;
172582
172719
  const fanSpeedName = fanSpeedList[fanSpeedIndex];
172583
172720
  if (!fanSpeedName) {
172584
- logger238.warn(`Invalid fan speed mode index: ${fanSpeedIndex}`);
172721
+ logger239.warn(`Invalid fan speed mode index: ${fanSpeedIndex}`);
172585
172722
  return void 0;
172586
172723
  }
172587
172724
  if (mapping?.suctionLevelEntity) {
@@ -172594,7 +172731,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172594
172731
  mapping.suctionLevelEntity,
172595
172732
  agent
172596
172733
  );
172597
- logger238.info(
172734
+ logger239.info(
172598
172735
  `Suction entity ${mapping.suctionLevelEntity}: current="${state}", options=${JSON.stringify(options ?? [])}`
172599
172736
  );
172600
172737
  let option = matchFanSpeedOption(
@@ -172604,12 +172741,12 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172604
172741
  );
172605
172742
  if (!option && options && fanSpeedIndex < options.length) {
172606
172743
  option = options[fanSpeedIndex];
172607
- logger238.info(
172744
+ logger239.info(
172608
172745
  `Positional match for fan "${fanSpeedName}" -> "${option}" (index ${fanSpeedIndex})`
172609
172746
  );
172610
172747
  }
172611
172748
  if (option) {
172612
- logger238.info(
172749
+ logger239.info(
172613
172750
  `Setting suction to: ${option} via ${mapping.suctionLevelEntity}`
172614
172751
  );
172615
172752
  return {
@@ -172618,7 +172755,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172618
172755
  target: mapping.suctionLevelEntity
172619
172756
  };
172620
172757
  }
172621
- logger238.warn(
172758
+ logger239.warn(
172622
172759
  `No match for fan speed "${fanSpeedName}" in suction options: [${(options ?? []).join(", ")}]`
172623
172760
  );
172624
172761
  return void 0;
@@ -172628,7 +172765,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172628
172765
  buildCleaningModeAction(0 /* Sweeping */, agent)
172629
172766
  );
172630
172767
  }
172631
- logger238.info(
172768
+ logger239.info(
172632
172769
  `Setting fan speed to: ${fanSpeedName} via vacuum.set_fan_speed`
172633
172770
  );
172634
172771
  return {
@@ -172638,7 +172775,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172638
172775
  };
172639
172776
  }
172640
172777
  if (!hasCleanTypes) {
172641
- logger238.debug(
172778
+ logger239.debug(
172642
172779
  `Ignoring cleaning type change (mode=${mode}): no cleaning mode entity`
172643
172780
  );
172644
172781
  return void 0;
@@ -172650,7 +172787,7 @@ function createCleanModeConfig(fanSpeedList, mopIntensityList, cleaningModeOptio
172650
172787
  agent
172651
172788
  );
172652
172789
  const optionToUse = findMatchingCleanOption(cleanType, availableOptions);
172653
- logger238.info(
172790
+ logger239.info(
172654
172791
  `Setting cleaning mode to: ${optionToUse} (mode=${mode}) via ${selectEntityId}`
172655
172792
  );
172656
172793
  return {
@@ -172668,10 +172805,10 @@ function createVacuumRvcCleanModeServer(_attributes, fanSpeedList, mopIntensityL
172668
172805
  cleaningModeOptions,
172669
172806
  customFanSpeedTags
172670
172807
  );
172671
- logger238.info(
172808
+ logger239.info(
172672
172809
  `Creating VacuumRvcCleanModeServer with ${supportedModes2.length} modes (fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])}, cleaningModeOptions=${JSON.stringify(cleaningModeOptions ?? [])}, customTags=${JSON.stringify(customFanSpeedTags ?? {})})`
172673
172810
  );
172674
- logger238.info(
172811
+ logger239.info(
172675
172812
  `Modes: ${supportedModes2.map((m) => `${m.mode}:${m.label}[${m.modeTags.map((t) => t.value).join(",")}]`).join(", ")}`
172676
172813
  );
172677
172814
  const initialState = {
@@ -172734,7 +172871,7 @@ function resolveMopIntensityList(mopIntensityEntity) {
172734
172871
  init_dist();
172735
172872
  init_esm();
172736
172873
  init_home_assistant_entity_behavior();
172737
- var logger239 = Logger.get("VacuumRvcOperationalStateServer");
172874
+ var logger240 = Logger.get("VacuumRvcOperationalStateServer");
172738
172875
  function batteryFromAttributes(attrs) {
172739
172876
  const raw = attrs.battery_level ?? attrs.battery;
172740
172877
  if (raw == null) return null;
@@ -172785,16 +172922,16 @@ function mapVacuumOperationalState(entity, batteryPercent = batteryFromAttribute
172785
172922
  operationalState = RvcOperationalState4.OperationalState.Error;
172786
172923
  } else {
172787
172924
  if (state.toLowerCase().includes("clean")) {
172788
- logger239.info(
172925
+ logger240.info(
172789
172926
  `Unknown vacuum state "${state}" contains 'clean', treating as Running`
172790
172927
  );
172791
172928
  operationalState = RvcOperationalState4.OperationalState.Running;
172792
172929
  } else {
172793
- logger239.info(`Unknown vacuum state "${state}", treating as Stopped`);
172930
+ logger240.info(`Unknown vacuum state "${state}", treating as Stopped`);
172794
172931
  operationalState = RvcOperationalState4.OperationalState.Stopped;
172795
172932
  }
172796
172933
  }
172797
- logger239.debug(
172934
+ logger240.debug(
172798
172935
  `Vacuum operationalState: "${state}" -> ${RvcOperationalState4.OperationalState[operationalState]}`
172799
172936
  );
172800
172937
  return operationalState;
@@ -172823,7 +172960,7 @@ var VacuumRvcOperationalStateServer = RvcOperationalStateServer2({
172823
172960
  });
172824
172961
 
172825
172962
  // src/matter/endpoints/legacy/vacuum/index.ts
172826
- var logger240 = Logger.get("VacuumDevice");
172963
+ var logger241 = Logger.get("VacuumDevice");
172827
172964
  var VacuumEndpointType = RoboticVacuumCleanerDevice.with(
172828
172965
  BasicInformationServer2,
172829
172966
  VacuumIdentifyServer,
@@ -172837,7 +172974,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
172837
172974
  const entityId = homeAssistantEntity.entity.entity_id;
172838
172975
  const attributes9 = homeAssistantEntity.entity.state.attributes;
172839
172976
  const customAreas = homeAssistantEntity.mapping?.customServiceAreas;
172840
- logger240.info(
172977
+ logger241.info(
172841
172978
  `Creating vacuum endpoint for ${entityId}, mapping: ${JSON.stringify(homeAssistantEntity.mapping ?? "none")}`
172842
172979
  );
172843
172980
  const cleanAreaRooms = homeAssistantEntity.mapping?.cleanAreaRooms;
@@ -172850,32 +172987,32 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
172850
172987
  )
172851
172988
  ).set({ homeAssistantEntity });
172852
172989
  if (includeOnOff) {
172853
- logger240.info(`${entityId}: Adding OnOff cluster (vacuumOnOff flag enabled)`);
172990
+ logger241.info(`${entityId}: Adding OnOff cluster (vacuumOnOff flag enabled)`);
172854
172991
  device = device.with(VacuumOnOffServer);
172855
172992
  }
172856
172993
  device = device.with(VacuumPowerSourceServer);
172857
172994
  const roomEntities = homeAssistantEntity.mapping?.roomEntities;
172858
172995
  const rooms = parseVacuumRooms(attributes9);
172859
- logger240.info(
172996
+ logger241.info(
172860
172997
  `${entityId}: customAreas=${customAreas?.length ?? 0}, roomEntities=${JSON.stringify(roomEntities ?? [])}, parsedRooms=${rooms.length}, cleanAreaRooms=${cleanAreaRooms?.length ?? 0}`
172861
172998
  );
172862
172999
  if (cleanAreaRooms && cleanAreaRooms.length > 0) {
172863
- logger240.info(
173000
+ logger241.info(
172864
173001
  `${entityId}: Adding ServiceArea (${cleanAreaRooms.length} HA areas via CLEAN_AREA)`
172865
173002
  );
172866
173003
  device = device.with(createCleanAreaServiceAreaServer(cleanAreaRooms));
172867
173004
  } else if (customAreas && customAreas.length > 0) {
172868
- logger240.info(
173005
+ logger241.info(
172869
173006
  `${entityId}: Adding ServiceArea (${customAreas.length} custom areas)`
172870
173007
  );
172871
173008
  device = device.with(createCustomServiceAreaServer(customAreas));
172872
173009
  } else if (rooms.length > 0 || roomEntities && roomEntities.length > 0) {
172873
- logger240.info(`${entityId}: Adding ServiceArea (${rooms.length} rooms)`);
173010
+ logger241.info(`${entityId}: Adding ServiceArea (${rooms.length} rooms)`);
172874
173011
  device = device.with(
172875
173012
  createVacuumServiceAreaServer(attributes9, roomEntities)
172876
173013
  );
172877
173014
  } else {
172878
- logger240.info(`${entityId}: Adding ServiceArea (default single-area)`);
173015
+ logger241.info(`${entityId}: Adding ServiceArea (default single-area)`);
172879
173016
  device = device.with(createDefaultServiceAreaServer());
172880
173017
  }
172881
173018
  const fanSpeedList = resolveFanSpeedList(
@@ -172886,7 +173023,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
172886
173023
  homeAssistantEntity.mapping?.mopIntensityEntity
172887
173024
  );
172888
173025
  if (cleaningModeOptions || fanSpeedList || mopIntensityList) {
172889
- logger240.info(
173026
+ logger241.info(
172890
173027
  `${entityId}: Adding RvcCleanMode (multi-mode, cleaningModeOptions=${JSON.stringify(cleaningModeOptions ?? [])}, fanSpeedList=${JSON.stringify(fanSpeedList ?? [])}, mopIntensityList=${JSON.stringify(mopIntensityList ?? [])})`
172891
173028
  );
172892
173029
  device = device.with(
@@ -172899,7 +173036,7 @@ function VacuumDevice(homeAssistantEntity, includeOnOff = false, cleaningModeOpt
172899
173036
  )
172900
173037
  );
172901
173038
  } else {
172902
- logger240.info(`${entityId}: Adding RvcCleanMode (default single-mode)`);
173039
+ logger241.info(`${entityId}: Adding RvcCleanMode (default single-mode)`);
172903
173040
  device = device.with(createDefaultRvcCleanModeServer());
172904
173041
  }
172905
173042
  return device;
@@ -173065,7 +173202,7 @@ var WaterHeaterThermostatServer = ThermostatServer2(
173065
173202
  );
173066
173203
 
173067
173204
  // src/matter/endpoints/legacy/water-heater/index.ts
173068
- var logger241 = Logger.get("WaterHeaterDevice");
173205
+ var logger242 = Logger.get("WaterHeaterDevice");
173069
173206
  var WaterHeaterDeviceType = ThermostatDevice.with(
173070
173207
  BasicInformationServer2,
173071
173208
  IdentifyServer2,
@@ -173081,7 +173218,7 @@ function toMatterTemp2(value) {
173081
173218
  }
173082
173219
  function WaterHeaterDevice2(homeAssistantEntity) {
173083
173220
  const attributes9 = homeAssistantEntity.entity.state.attributes;
173084
- logger241.debug(
173221
+ logger242.debug(
173085
173222
  `Creating device for ${homeAssistantEntity.entity.entity_id}, min_temp=${attributes9.min_temp}, max_temp=${attributes9.max_temp}`
173086
173223
  );
173087
173224
  const minLimit = toMatterTemp2(attributes9.min_temp) ?? 0;
@@ -173323,7 +173460,7 @@ function activeHeatSource(attributes9) {
173323
173460
  }
173324
173461
 
173325
173462
  // src/matter/endpoints/legacy/water-heater/behaviors/water-heater-management-server.ts
173326
- var logger242 = Logger.get("WaterHeaterManagementServer");
173463
+ var logger243 = Logger.get("WaterHeaterManagementServer");
173327
173464
  var MAX_TIMER_MS2 = 2147483647;
173328
173465
  var boostSessions = /* @__PURE__ */ new WeakMap();
173329
173466
  function clearBoostTimer(endpoint) {
@@ -173569,7 +173706,7 @@ var WaterHeaterManagementServerBase = class _WaterHeaterManagementServerBase ext
173569
173706
  armBoostTimer(durationSeconds) {
173570
173707
  const delay = durationSeconds * 1e3;
173571
173708
  if (!Number.isFinite(delay) || delay <= 0 || delay > MAX_TIMER_MS2) {
173572
- logger242.debug(
173709
+ logger243.debug(
173573
173710
  `Boost duration ${durationSeconds}s outside the timer range, boost stays active until CancelBoost`
173574
173711
  );
173575
173712
  return;
@@ -173583,7 +173720,7 @@ var WaterHeaterManagementServerBase = class _WaterHeaterManagementServerBase ext
173583
173720
  agent.get(_WaterHeaterManagementServerBase).endBoost({ restoreMode: true });
173584
173721
  });
173585
173722
  } catch (error) {
173586
- logger242.debug(
173723
+ logger243.debug(
173587
173724
  `Boost expiry failed (endpoint may be closing): ${error}`
173588
173725
  );
173589
173726
  }
@@ -173686,13 +173823,13 @@ function WaterHeaterModeServer2(mapping, initialMode) {
173686
173823
  }
173687
173824
 
173688
173825
  // src/matter/endpoints/legacy/water-heater/water-heater-management-device.ts
173689
- var logger243 = Logger.get("WaterHeaterManagementDevice");
173826
+ var logger244 = Logger.get("WaterHeaterManagementDevice");
173690
173827
  function WaterHeaterManagementDevice(homeAssistantEntity) {
173691
173828
  const entityState = homeAssistantEntity.entity.state;
173692
173829
  const attributes9 = entityState.attributes;
173693
173830
  const modeMapping = buildModeMapping(attributes9);
173694
173831
  const initialMode = currentMode(modeMapping, entityState.state, attributes9);
173695
- logger243.debug(
173832
+ logger244.debug(
173696
173833
  `Creating Matter 1.4 water heater for ${homeAssistantEntity.entity.entity_id}, modes=[${modeMapping.supportedModes.map((m) => `${m.mode}:${m.label}`).join(", ")}], boostMode=${modeMapping.boostOperationMode ?? "none"}`
173697
173834
  );
173698
173835
  const minLimit = toMatterTemp2(attributes9.min_temp) ?? 0;
@@ -173963,7 +174100,7 @@ var matterDeviceTypeFactories = {
173963
174100
  };
173964
174101
 
173965
174102
  // src/matter/endpoints/composed/user-composed-endpoint.ts
173966
- var logger244 = Logger.get("UserComposedEndpoint");
174103
+ var logger245 = Logger.get("UserComposedEndpoint");
173967
174104
  function stripBasicInformation(type) {
173968
174105
  const behaviors = { ...type.behaviors };
173969
174106
  delete behaviors.bridgedDeviceBasicInformation;
@@ -174039,7 +174176,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
174039
174176
  { vacuumOnOff: registry3.isVacuumOnOffEnabled() }
174040
174177
  );
174041
174178
  if (!primaryType) {
174042
- logger244.warn(
174179
+ logger245.warn(
174043
174180
  `Cannot create endpoint type for primary entity ${primaryEntityId}`
174044
174181
  );
174045
174182
  return void 0;
@@ -174054,7 +174191,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
174054
174191
  if (!sub.entityId) continue;
174055
174192
  const subPayload = buildEntityPayload4(registry3, sub.entityId);
174056
174193
  if (!subPayload) {
174057
- logger244.warn(
174194
+ logger245.warn(
174058
174195
  `Cannot find state for composed sub-entity ${sub.entityId}, it does not exist in Home Assistant (removed or renamed?)`
174059
174196
  );
174060
174197
  continue;
@@ -174069,7 +174206,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
174069
174206
  config8.areaName
174070
174207
  );
174071
174208
  if (!subType) {
174072
- logger244.warn(
174209
+ logger245.warn(
174073
174210
  `Cannot create endpoint type for composed sub-entity ${sub.entityId}`
174074
174211
  );
174075
174212
  continue;
@@ -174082,7 +174219,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
174082
174219
  mappedIds.push(sub.entityId);
174083
174220
  }
174084
174221
  if (parts.length < 2) {
174085
- logger244.warn(
174222
+ logger245.warn(
174086
174223
  `User composed device ${primaryEntityId}: only ${parts.length} sub-endpoint(s), need at least 2 (primary + one sub-entity). Falling back to standalone.`
174087
174224
  );
174088
174225
  return void 0;
@@ -174106,7 +174243,7 @@ var UserComposedEndpoint = class _UserComposedEndpoint extends Endpoint {
174106
174243
  const labels = parts.map(
174107
174244
  (_, i) => i === 0 ? primaryEntityId.split(".")[0] : composedEntities[i - 1]?.entityId?.split(".")[0] ?? "?"
174108
174245
  ).join("+");
174109
- logger244.info(
174246
+ logger245.info(
174110
174247
  `Created user composed device ${primaryEntityId}: ${parts.length} sub-endpoint(s) [${labels}]`
174111
174248
  );
174112
174249
  return endpoint;
@@ -174212,7 +174349,7 @@ function asStandaloneEndpointType(type) {
174212
174349
  }
174213
174350
 
174214
174351
  // src/matter/endpoints/legacy/legacy-endpoint.ts
174215
- var logger245 = Logger.get("LegacyEndpoint");
174352
+ var logger246 = Logger.get("LegacyEndpoint");
174216
174353
  var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174217
174354
  constructor(type, entityId, customName, mappedEntityIds, throttleMs, endpointId, vacuumEffective) {
174218
174355
  super(type, entityId, customName, mappedEntityIds, endpointId);
@@ -174228,25 +174365,25 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174228
174365
  return;
174229
174366
  }
174230
174367
  if (registry3.isAutoBatteryMappingEnabled() && registry3.isBatteryEntityUsed(entityId)) {
174231
- logger245.debug(
174368
+ logger246.debug(
174232
174369
  `Skipping ${entityId} - already auto-assigned as battery to another device`
174233
174370
  );
174234
174371
  return;
174235
174372
  }
174236
174373
  if (registry3.isAutoHumidityMappingEnabled() && registry3.isHumidityEntityUsed(entityId)) {
174237
- logger245.debug(
174374
+ logger246.debug(
174238
174375
  `Skipping ${entityId} - already auto-assigned as humidity to a temperature sensor`
174239
174376
  );
174240
174377
  return;
174241
174378
  }
174242
174379
  if (registry3.isAutoPressureMappingEnabled() && registry3.isPressureEntityUsed(entityId)) {
174243
- logger245.debug(
174380
+ logger246.debug(
174244
174381
  `Skipping ${entityId} - already auto-assigned as pressure to a temperature sensor`
174245
174382
  );
174246
174383
  return;
174247
174384
  }
174248
174385
  if (registry3.isAutoComposedDevicesEnabled() && registry3.isComposedSubEntityUsed(entityId)) {
174249
- logger245.debug(
174386
+ logger246.debug(
174250
174387
  `Skipping ${entityId} - already consumed by a composed device`
174251
174388
  );
174252
174389
  return;
@@ -174266,7 +174403,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174266
174403
  humidityEntity: humidityEntityId
174267
174404
  };
174268
174405
  registry3.markHumidityEntityUsed(humidityEntityId);
174269
- logger245.debug(
174406
+ logger246.debug(
174270
174407
  `Auto-assigned humidity ${humidityEntityId} to ${entityId}`
174271
174408
  );
174272
174409
  }
@@ -174285,7 +174422,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174285
174422
  pressureEntity: pressureEntityId
174286
174423
  };
174287
174424
  registry3.markPressureEntityUsed(pressureEntityId);
174288
- logger245.debug(
174425
+ logger246.debug(
174289
174426
  `Auto-assigned pressure ${pressureEntityId} to ${entityId}`
174290
174427
  );
174291
174428
  }
@@ -174303,7 +174440,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174303
174440
  batteryEntity: batteryEntityId
174304
174441
  };
174305
174442
  registry3.markBatteryEntityUsed(batteryEntityId);
174306
- logger245.debug(
174443
+ logger246.debug(
174307
174444
  `Auto-assigned battery ${batteryEntityId} to ${entityId}`
174308
174445
  );
174309
174446
  }
@@ -174320,7 +174457,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174320
174457
  entityId: effectiveMapping?.entityId ?? entityId,
174321
174458
  faultEntity: faultEntityId
174322
174459
  };
174323
- logger245.debug(`Auto-assigned fault ${faultEntityId} to ${entityId}`);
174460
+ logger246.debug(`Auto-assigned fault ${faultEntityId} to ${entityId}`);
174324
174461
  }
174325
174462
  }
174326
174463
  if (!mapping?.powerEntity) {
@@ -174336,7 +174473,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174336
174473
  powerEntity: powerEntityId
174337
174474
  };
174338
174475
  registry3.markPowerEntityUsed(powerEntityId);
174339
- logger245.debug(`Auto-assigned power ${powerEntityId} to ${entityId}`);
174476
+ logger246.debug(`Auto-assigned power ${powerEntityId} to ${entityId}`);
174340
174477
  }
174341
174478
  }
174342
174479
  }
@@ -174353,7 +174490,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174353
174490
  energyEntity: energyEntityId
174354
174491
  };
174355
174492
  registry3.markEnergyEntityUsed(energyEntityId);
174356
- logger245.debug(
174493
+ logger246.debug(
174357
174494
  `Auto-assigned energy ${energyEntityId} to ${entityId}`
174358
174495
  );
174359
174496
  }
@@ -174369,7 +174506,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174369
174506
  entityId: effectiveMapping?.entityId ?? entityId,
174370
174507
  cleaningModeEntity: vacuumEntities.cleaningModeEntity
174371
174508
  };
174372
- logger245.info(
174509
+ logger246.info(
174373
174510
  `Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity} to ${entityId}`
174374
174511
  );
174375
174512
  }
@@ -174379,7 +174516,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174379
174516
  entityId: effectiveMapping?.entityId ?? entityId,
174380
174517
  suctionLevelEntity: vacuumEntities.suctionLevelEntity
174381
174518
  };
174382
- logger245.info(
174519
+ logger246.info(
174383
174520
  `Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity} to ${entityId}`
174384
174521
  );
174385
174522
  }
@@ -174389,7 +174526,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174389
174526
  entityId: effectiveMapping?.entityId ?? entityId,
174390
174527
  mopIntensityEntity: vacuumEntities.mopIntensityEntity
174391
174528
  };
174392
- logger245.info(
174529
+ logger246.info(
174393
174530
  `Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity} to ${entityId}`
174394
174531
  );
174395
174532
  }
@@ -174399,7 +174536,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174399
174536
  entityId: effectiveMapping?.entityId ?? entityId,
174400
174537
  currentRoomEntity: vacuumEntities.currentRoomEntity
174401
174538
  };
174402
- logger245.info(
174539
+ logger246.info(
174403
174540
  `Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity} to ${entityId}`
174404
174541
  );
174405
174542
  }
@@ -174414,7 +174551,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174414
174551
  entityId: effectiveMapping?.entityId ?? entityId,
174415
174552
  cleanAreaRooms
174416
174553
  };
174417
- logger245.info(
174554
+ logger246.info(
174418
174555
  `Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA for ${entityId}`
174419
174556
  );
174420
174557
  }
@@ -174435,7 +174572,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174435
174572
  rooms: roomsObj
174436
174573
  }
174437
174574
  };
174438
- logger245.debug(
174575
+ logger246.debug(
174439
174576
  `Auto-detected ${valetudoRooms.length} Valetudo segments for ${entityId}`
174440
174577
  );
174441
174578
  } else {
@@ -174452,7 +174589,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174452
174589
  rooms: roomsObj
174453
174590
  }
174454
174591
  };
174455
- logger245.debug(
174592
+ logger246.debug(
174456
174593
  `Auto-detected ${roborockRooms.length} Roborock rooms for ${entityId}`
174457
174594
  );
174458
174595
  }
@@ -174461,7 +174598,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174461
174598
  }
174462
174599
  }
174463
174600
  if (standalone && ((effectiveMapping?.composedEntities?.length ?? 0) > 0 || effectiveMapping?.climateExposeFan === true)) {
174464
- logger245.warn(
174601
+ logger246.warn(
174465
174602
  `Composed mappings are not supported in server mode, exposing ${entityId} as a flat standalone endpoint`
174466
174603
  );
174467
174604
  }
@@ -174480,7 +174617,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174480
174617
  if (composed) {
174481
174618
  return composed;
174482
174619
  }
174483
- logger245.warn(
174620
+ logger246.warn(
174484
174621
  `User composed device creation failed for ${entityId}, falling back to standalone`
174485
174622
  );
174486
174623
  }
@@ -174545,7 +174682,7 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174545
174682
  if (composed) {
174546
174683
  return composed;
174547
174684
  }
174548
- logger245.warn(
174685
+ logger246.warn(
174549
174686
  `Companion fan creation failed for ${entityId}, falling back to standalone`
174550
174687
  );
174551
174688
  }
@@ -174623,11 +174760,11 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
174623
174760
  }
174624
174761
  if (mappedChanged) {
174625
174762
  this.pendingMappedChange = true;
174626
- logger245.debug(
174763
+ logger246.debug(
174627
174764
  `Mapped entity change detected for ${this.entityId}, forcing update`
174628
174765
  );
174629
174766
  }
174630
- logger245.debug(
174767
+ logger246.debug(
174631
174768
  `State update received for ${this.entityId}: state=${state.state}`
174632
174769
  );
174633
174770
  this.lastState = state;
@@ -174853,7 +174990,7 @@ init_esm3();
174853
174990
  // src/plugins/builtin/camera/requestor-client.ts
174854
174991
  init_esm();
174855
174992
  init_esm4();
174856
- var logger246 = Logger.get("CameraWebRtcRequestor");
174993
+ var logger247 = Logger.get("CameraWebRtcRequestor");
174857
174994
  var registry2 = /* @__PURE__ */ new Map();
174858
174995
  var pendingDeliveries = /* @__PURE__ */ new Map();
174859
174996
  var invokeTransport = defaultInvoke;
@@ -174887,19 +175024,19 @@ function deliverAnswerDeferred(sessionId, sdp, onGiveUp) {
174887
175024
  return;
174888
175025
  }
174889
175026
  if (await sendAnswer(sessionId, sdp)) {
174890
- logger246.info(`answer delivered for session ${sessionId}`);
175027
+ logger247.info(`answer delivered for session ${sessionId}`);
174891
175028
  return;
174892
175029
  }
174893
175030
  }
174894
175031
  if (registry2.get(sessionId) !== owner || pendingDeliveries.get(sessionId) !== timer) {
174895
175032
  return;
174896
175033
  }
174897
- logger246.info(
175034
+ logger247.info(
174898
175035
  `answer delivery failed for session ${sessionId}, giving up`
174899
175036
  );
174900
175037
  await onGiveUp();
174901
175038
  } catch (err) {
174902
- logger246.info(
175039
+ logger247.info(
174903
175040
  `answer delivery for session ${sessionId} threw: ${errText(err)}`
174904
175041
  );
174905
175042
  } finally {
@@ -174924,11 +175061,11 @@ function sendAnswer(sessionId, sdp) {
174924
175061
  async function invokeRequestor(sessionId, command, fields) {
174925
175062
  const registration = registry2.get(sessionId);
174926
175063
  if (!registration) {
174927
- logger246.info(`requestor ${command}: no session ${sessionId} registered`);
175064
+ logger247.info(`requestor ${command}: no session ${sessionId} registered`);
174928
175065
  return false;
174929
175066
  }
174930
175067
  if (registration.session.isClosed) {
174931
- logger246.info(`requestor ${command}: session ${sessionId} already closed`);
175068
+ logger247.info(`requestor ${command}: session ${sessionId} already closed`);
174932
175069
  return false;
174933
175070
  }
174934
175071
  const request = {
@@ -174940,7 +175077,7 @@ async function invokeRequestor(sessionId, command, fields) {
174940
175077
  try {
174941
175078
  return await invokeTransport({ registration, request });
174942
175079
  } catch (err) {
174943
- logger246.info(
175080
+ logger247.info(
174944
175081
  `requestor ${command} failed for session ${sessionId}: ${errText(err)}`
174945
175082
  );
174946
175083
  return false;
@@ -174975,7 +175112,7 @@ async function defaultInvoke({
174975
175112
  for (const entry of chunk) {
174976
175113
  if (entry.kind === "cmd-status") {
174977
175114
  if (entry.status !== Status2.Success) {
174978
- logger246.info(
175115
+ logger247.info(
174979
175116
  `requestor ${request.command} status ${entry.status} for session ${String(request.fields.webRtcSessionId)}`
174980
175117
  );
174981
175118
  return false;
@@ -174995,7 +175132,7 @@ function errText(err) {
174995
175132
  }
174996
175133
 
174997
175134
  // src/plugins/builtin/camera/webrtc-provider-server.ts
174998
- var logger247 = Logger.get("CameraWebRtc");
175135
+ var logger248 = Logger.get("CameraWebRtc");
174999
175136
  var nextGlobalSessionId = 0;
175000
175137
  function mintSessionId() {
175001
175138
  for (let i = 0; i <= 65534; i++) {
@@ -175009,14 +175146,14 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
175009
175146
  solicitOffer(request) {
175010
175147
  const id = mintSessionId();
175011
175148
  this.trackSession(id, request.streamUsage, request.originatingEndpointId);
175012
- logger247.info(
175149
+ logger248.info(
175013
175150
  `solicitOffer session=${id} (${this.state.entityId}), deferred offer`
175014
175151
  );
175015
175152
  void this.state.bridge.startSession(id, this.state.entityId, {
175016
175153
  iceServers: request.iceServers,
175017
175154
  iceTransportPolicy: request.iceTransportPolicy
175018
175155
  }).catch(
175019
- (err) => logger247.info(
175156
+ (err) => logger248.info(
175020
175157
  `solicitOffer startSession failed for ${this.state.entityId}: ${errText2(err)}`
175021
175158
  )
175022
175159
  );
@@ -175024,7 +175161,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
175024
175161
  }
175025
175162
  async provideOffer(request) {
175026
175163
  const id = request.webRtcSessionId ?? mintSessionId();
175027
- logger247.info(
175164
+ logger248.info(
175028
175165
  `provideOffer entry: entityId=${this.state.entityId} session=${id} (sdp ${request.sdp.length} chars)`
175029
175166
  );
175030
175167
  if (request.webRtcSessionId == null) {
@@ -175058,7 +175195,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
175058
175195
  );
175059
175196
  } catch (err) {
175060
175197
  const message = errText2(err);
175061
- logger247.info(
175198
+ logger248.info(
175062
175199
  `provideOffer failed for ${this.state.entityId} session=${id}: ${message}`
175063
175200
  );
175064
175201
  unregisterRequestor(id);
@@ -175070,7 +175207,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
175070
175207
  StatusCode.Failure
175071
175208
  );
175072
175209
  }
175073
- logger247.info(
175210
+ logger248.info(
175074
175211
  `provideOffer answer computed for ${this.state.entityId} session=${id} (${answerSdp.length} chars); delivering via requestor`
175075
175212
  );
175076
175213
  const bridge = this.state.bridge;
@@ -175089,7 +175226,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
175089
175226
  return { webRtcSessionId: id };
175090
175227
  }
175091
175228
  provideAnswer(request) {
175092
- logger247.info(
175229
+ logger248.info(
175093
175230
  `provideAnswer session=${request.webRtcSessionId} (sdp ${request.sdp.length} chars, ${this.state.entityId})`
175094
175231
  );
175095
175232
  return this.state.bridge.acceptControllerAnswer(
@@ -175098,7 +175235,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
175098
175235
  );
175099
175236
  }
175100
175237
  async provideIceCandidates(request) {
175101
- logger247.info(
175238
+ logger248.info(
175102
175239
  `provideIceCandidates session=${request.webRtcSessionId}: ${request.iceCandidates.length} candidate(s) (${this.state.entityId})`
175103
175240
  );
175104
175241
  for (const c of request.iceCandidates) {
@@ -175111,7 +175248,7 @@ var CameraWebRtcProviderServer = class extends WebRtcTransportProviderServer {
175111
175248
  }
175112
175249
  }
175113
175250
  async endSession(request) {
175114
- logger247.info(
175251
+ logger248.info(
175115
175252
  `endSession session=${request.webRtcSessionId} (${this.state.entityId})`
175116
175253
  );
175117
175254
  await this.state.bridge.endSession(request.webRtcSessionId);
@@ -175232,7 +175369,7 @@ import {
175232
175369
  createLongLivedTokenAuth as createLongLivedTokenAuth2
175233
175370
  } from "home-assistant-js-websocket";
175234
175371
  import { RTCPeerConnection } from "werift";
175235
- var logger248 = Logger.get("CameraWebRtc");
175372
+ var logger249 = Logger.get("CameraWebRtc");
175236
175373
  var DEFAULT_HA_WEBRTC_TIMEOUT_MS = 15e3;
175237
175374
  var haWebRtcTimeoutMs = DEFAULT_HA_WEBRTC_TIMEOUT_MS;
175238
175375
  var WebRtcBridge = class {
@@ -175279,7 +175416,7 @@ var WebRtcBridge = class {
175279
175416
  const haOffer = await haPeer.createOffer();
175280
175417
  await haPeer.setLocalDescription(haOffer);
175281
175418
  const haOfferSdp = this.localSdp(haPeer);
175282
- logger248.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
175419
+ logger249.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
175283
175420
  const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
175284
175421
  entityId,
175285
175422
  haOfferSdp,
@@ -175302,12 +175439,12 @@ var WebRtcBridge = class {
175302
175439
  const controllerOffer = await controllerPeer.createOffer();
175303
175440
  await controllerPeer.setLocalDescription(controllerOffer);
175304
175441
  const sdp = this.localSdp(controllerPeer);
175305
- logger248.info(
175442
+ logger249.info(
175306
175443
  `controller offer created for ${entityId} (${sdp.length} chars)`
175307
175444
  );
175308
175445
  return { sdp, iceCandidates };
175309
175446
  } catch (err) {
175310
- logger248.info(`startSession failed for ${entityId}: ${errText3(err)}`);
175447
+ logger249.info(`startSession failed for ${entityId}: ${errText3(err)}`);
175311
175448
  await this.endSession(matterSessionId);
175312
175449
  throw err;
175313
175450
  }
@@ -175337,7 +175474,7 @@ var WebRtcBridge = class {
175337
175474
  const haOffer = await haPeer.createOffer();
175338
175475
  await haPeer.setLocalDescription(haOffer);
175339
175476
  const haOfferSdp = this.localSdp(haPeer);
175340
- logger248.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
175477
+ logger249.info(`HA offer sent for ${entityId} (${haOfferSdp.length} chars)`);
175341
175478
  const { answer, sessionId, unsubscribe } = await this.requestHaWebRtc(
175342
175479
  entityId,
175343
175480
  haOfferSdp,
@@ -175356,12 +175493,12 @@ var WebRtcBridge = class {
175356
175493
  const controllerAnswer = await controllerPeer.createAnswer();
175357
175494
  await controllerPeer.setLocalDescription(controllerAnswer);
175358
175495
  const answerSdp = this.localSdp(controllerPeer);
175359
- logger248.info(
175496
+ logger249.info(
175360
175497
  `controller answer created for ${entityId} (${answerSdp.length} chars)`
175361
175498
  );
175362
175499
  return answerSdp;
175363
175500
  } catch (err) {
175364
- logger248.info(
175501
+ logger249.info(
175365
175502
  `acceptControllerOffer failed for ${entityId}: ${errText3(err)}`
175366
175503
  );
175367
175504
  await this.endSession(matterSessionId);
@@ -175372,14 +175509,14 @@ var WebRtcBridge = class {
175372
175509
  async acceptControllerAnswer(matterSessionId, sdp) {
175373
175510
  const session = this.sessions.get(matterSessionId);
175374
175511
  if (!session) return;
175375
- logger248.debug(`controller answer applied for ${session.entityId}`);
175512
+ logger249.debug(`controller answer applied for ${session.entityId}`);
175376
175513
  await session.controllerPeer.setRemoteDescription({ type: "answer", sdp });
175377
175514
  }
175378
175515
  /** Add a remote ICE candidate from the Matter controller. */
175379
175516
  async addControllerIceCandidate(matterSessionId, candidate, sdpMid, sdpMLineIndex) {
175380
175517
  const session = this.sessions.get(matterSessionId);
175381
175518
  if (!session) return;
175382
- logger248.debug(
175519
+ logger249.debug(
175383
175520
  `controller ICE candidate for ${session.entityId}: ${candidate}`
175384
175521
  );
175385
175522
  await session.controllerPeer.addIceCandidate({
@@ -175393,12 +175530,12 @@ var WebRtcBridge = class {
175393
175530
  async closeExistingPeers(matterSessionId) {
175394
175531
  const prior = this.sessions.get(matterSessionId);
175395
175532
  if (!prior) return;
175396
- logger248.info(
175533
+ logger249.info(
175397
175534
  `replacing session ${matterSessionId} (${prior.entityId}), closing prior peers`
175398
175535
  );
175399
175536
  if (prior.haUnsubscribe) {
175400
175537
  await Promise.resolve(prior.haUnsubscribe()).catch(
175401
- (err) => logger248.debug(`HA unsubscribe failed: ${errText3(err)}`)
175538
+ (err) => logger249.debug(`HA unsubscribe failed: ${errText3(err)}`)
175402
175539
  );
175403
175540
  }
175404
175541
  await prior.haPeer.close().catch(() => {
@@ -175411,11 +175548,11 @@ var WebRtcBridge = class {
175411
175548
  async endSession(matterSessionId) {
175412
175549
  const session = this.sessions.get(matterSessionId);
175413
175550
  if (!session) return;
175414
- logger248.info(`ending session ${matterSessionId} (${session.entityId})`);
175551
+ logger249.info(`ending session ${matterSessionId} (${session.entityId})`);
175415
175552
  this.sessions.delete(matterSessionId);
175416
175553
  if (session.haUnsubscribe) {
175417
175554
  await Promise.resolve(session.haUnsubscribe()).catch(
175418
- (err) => logger248.debug(`HA unsubscribe failed: ${errText3(err)}`)
175555
+ (err) => logger249.debug(`HA unsubscribe failed: ${errText3(err)}`)
175419
175556
  );
175420
175557
  }
175421
175558
  await session.haPeer.close().catch(() => {
@@ -175445,11 +175582,11 @@ var WebRtcBridge = class {
175445
175582
  headers: { Authorization: `Bearer ${this.config.haToken}` }
175446
175583
  });
175447
175584
  } catch (err) {
175448
- logger248.info(`snapshot fetch failed for ${entityId}: ${errText3(err)}`);
175585
+ logger249.info(`snapshot fetch failed for ${entityId}: ${errText3(err)}`);
175449
175586
  throw err;
175450
175587
  }
175451
175588
  if (!res.ok) {
175452
- logger248.info(
175589
+ logger249.info(
175453
175590
  `snapshot fetch failed for ${entityId}: camera_proxy ${res.status}`
175454
175591
  );
175455
175592
  throw new Error(`HA camera_proxy ${entityId}: ${res.status}`);
@@ -175466,10 +175603,10 @@ var WebRtcBridge = class {
175466
175603
  // Forward every track HA sends into the matching pre-added controller sender.
175467
175604
  forwardHaTracks(haPeer, senders, entityId) {
175468
175605
  haPeer.onTrack.subscribe((track) => {
175469
- logger248.info(`onTrack ${track.kind} from HA (${entityId})`);
175606
+ logger249.info(`onTrack ${track.kind} from HA (${entityId})`);
175470
175607
  const transceiver = senders.get(track.kind);
175471
175608
  if (!transceiver) {
175472
- logger248.info(
175609
+ logger249.info(
175473
175610
  `no controller transceiver for ${track.kind} (${entityId})`
175474
175611
  );
175475
175612
  return;
@@ -175478,7 +175615,7 @@ var WebRtcBridge = class {
175478
175615
  track.onReceiveRtp.subscribe((rtp) => {
175479
175616
  if (!firstLogged) {
175480
175617
  firstLogged = true;
175481
- logger248.info(`first RTP forwarded for ${track.kind} (${entityId})`);
175618
+ logger249.info(`first RTP forwarded for ${track.kind} (${entityId})`);
175482
175619
  }
175483
175620
  transceiver.sender.sendRtp(rtp);
175484
175621
  });
@@ -175487,10 +175624,10 @@ var WebRtcBridge = class {
175487
175624
  // Log connection/ice state transitions (these events fire on change only).
175488
175625
  wireStateLogging(peer, label, entityId) {
175489
175626
  peer.connectionStateChange.subscribe(
175490
- (s) => logger248.info(`${label} connectionState=${s} (${entityId})`)
175627
+ (s) => logger249.info(`${label} connectionState=${s} (${entityId})`)
175491
175628
  );
175492
175629
  peer.iceConnectionStateChange.subscribe(
175493
- (s) => logger248.info(`${label} iceConnectionState=${s} (${entityId})`)
175630
+ (s) => logger249.info(`${label} iceConnectionState=${s} (${entityId})`)
175494
175631
  );
175495
175632
  }
175496
175633
  // Map the Matter ICE struct onto werift's config. Only the controller peer
@@ -175504,11 +175641,11 @@ var WebRtcBridge = class {
175504
175641
  }))
175505
175642
  );
175506
175643
  if (iceServers.length === 0) {
175507
- logger248.info(`controller peer using default ICE servers (${entityId})`);
175644
+ logger249.info(`controller peer using default ICE servers (${entityId})`);
175508
175645
  return void 0;
175509
175646
  }
175510
175647
  const policy = ice?.iceTransportPolicy === "relay" || ice?.iceTransportPolicy === "all" ? ice.iceTransportPolicy : void 0;
175511
- logger248.info(
175648
+ logger249.info(
175512
175649
  `controller peer using ${iceServers.length} controller ICE server(s)${policy ? ` policy=${policy}` : ""} (${entityId})`
175513
175650
  );
175514
175651
  return policy ? { iceServers, iceTransportPolicy: policy } : { iceServers };
@@ -175522,13 +175659,13 @@ var WebRtcBridge = class {
175522
175659
  feedHaCandidate(entityId, haPeer, candidate) {
175523
175660
  const value = candidate?.candidate;
175524
175661
  if (!value) return;
175525
- logger248.debug(`HA ICE candidate for ${entityId}: ${value}`);
175662
+ logger249.debug(`HA ICE candidate for ${entityId}: ${value}`);
175526
175663
  void haPeer.addIceCandidate({
175527
175664
  candidate: value,
175528
175665
  sdpMid: candidate?.sdpMid ?? void 0,
175529
175666
  sdpMLineIndex: candidate?.sdpMLineIndex ?? void 0
175530
175667
  }).catch(
175531
- (e) => logger248.debug(
175668
+ (e) => logger249.debug(
175532
175669
  `HA addIceCandidate failed for ${entityId}: ${errText3(e)}`
175533
175670
  )
175534
175671
  );
@@ -175557,7 +175694,7 @@ var WebRtcBridge = class {
175557
175694
  reject(err);
175558
175695
  });
175559
175696
  timer = setTimeout(() => {
175560
- logger248.info(
175697
+ logger249.info(
175561
175698
  `HA WebRTC timed out after ${haWebRtcTimeoutMs}ms for ${entityId}`
175562
175699
  );
175563
175700
  fail(
@@ -175575,7 +175712,7 @@ var WebRtcBridge = class {
175575
175712
  if (msg.session_id) sessionId = msg.session_id;
175576
175713
  const ans = msg.answer;
175577
175714
  settle(() => {
175578
- logger248.info(
175715
+ logger249.info(
175579
175716
  `HA answer received for ${entityId} (${ans.length} chars)`
175580
175717
  );
175581
175718
  resolve11(ans);
@@ -175584,7 +175721,7 @@ var WebRtcBridge = class {
175584
175721
  break;
175585
175722
  case "error": {
175586
175723
  const detail = msg.message ?? msg.code ?? "unknown error";
175587
- logger248.info(`HA WebRTC error for ${entityId}: ${detail}`);
175724
+ logger249.info(`HA WebRTC error for ${entityId}: ${detail}`);
175588
175725
  fail(new Error(`HA WebRTC error: ${detail}`));
175589
175726
  break;
175590
175727
  }
@@ -176741,7 +176878,7 @@ import {
176741
176878
  getCollection
176742
176879
  } from "home-assistant-js-websocket";
176743
176880
  import { atLeastHaVersion } from "home-assistant-js-websocket/dist/util.js";
176744
- var logger249 = Logger.get("SubscribeEntities");
176881
+ var logger250 = Logger.get("SubscribeEntities");
176745
176882
  function processEvent(store, updates) {
176746
176883
  const state = { ...store.state };
176747
176884
  if (updates.a) {
@@ -176767,7 +176904,7 @@ function processEvent(store, updates) {
176767
176904
  for (const entityId in updates.c) {
176768
176905
  let entityState = state[entityId];
176769
176906
  if (!entityState) {
176770
- logger249.warn("Received state update for unknown entity", entityId);
176907
+ logger250.warn("Received state update for unknown entity", entityId);
176771
176908
  continue;
176772
176909
  }
176773
176910
  entityState = { ...entityState };
@@ -176856,7 +176993,7 @@ var subscribeEntities = (conn, onChange, entityIds) => {
176856
176993
  // src/services/bridges/entity-isolation-service.ts
176857
176994
  init_esm();
176858
176995
  init_diagnostic_event_bus();
176859
- var logger250 = Logger.get("EntityIsolation");
176996
+ var logger251 = Logger.get("EntityIsolation");
176860
176997
  var EntityIsolationServiceImpl = class {
176861
176998
  isolatedEntities = /* @__PURE__ */ new Map();
176862
176999
  isolationCallbacks = /* @__PURE__ */ new Map();
@@ -176924,13 +177061,13 @@ var EntityIsolationServiceImpl = class {
176924
177061
  }
176925
177062
  const parsed = this.parseEndpointPath(msg);
176926
177063
  if (!parsed) {
176927
- logger250.warn("Could not parse entity from error:", msg);
177064
+ logger251.warn("Could not parse entity from error:", msg);
176928
177065
  return false;
176929
177066
  }
176930
177067
  const { bridgeId, entityName } = parsed;
176931
177068
  const callback = this.isolationCallbacks.get(bridgeId);
176932
177069
  if (!callback) {
176933
- logger250.warn(
177070
+ logger251.warn(
176934
177071
  `No isolation callback registered for bridge ${bridgeId}, entity: ${entityName}`
176935
177072
  );
176936
177073
  return false;
@@ -176945,7 +177082,7 @@ var EntityIsolationServiceImpl = class {
176945
177082
  reason,
176946
177083
  failedAt: (/* @__PURE__ */ new Date()).toISOString()
176947
177084
  });
176948
- logger250.warn(
177085
+ logger251.warn(
176949
177086
  `Isolating entity "${entityName}" from bridge ${bridgeId} due to: ${reason}`
176950
177087
  );
176951
177088
  diagnosticEventBus.emit("entity_error", `Entity isolated: ${entityName}`, {
@@ -176957,7 +177094,7 @@ var EntityIsolationServiceImpl = class {
176957
177094
  await callback(entityName);
176958
177095
  return true;
176959
177096
  } catch (e) {
176960
- logger250.error(`Failed to isolate entity ${entityName}:`, e);
177097
+ logger251.error(`Failed to isolate entity ${entityName}:`, e);
176961
177098
  return false;
176962
177099
  }
176963
177100
  }
@@ -176989,6 +177126,12 @@ var EntityIsolationService = new EntityIsolationServiceImpl();
176989
177126
  // src/services/bridges/bridge-endpoint-manager.ts
176990
177127
  var MAX_ENTITY_ID_LENGTH = 150;
176991
177128
  var ENDPOINT_REMOVAL_GRACE_MS = 6e4;
177129
+ function isEntityPart(p) {
177130
+ return typeof p.updateStates === "function";
177131
+ }
177132
+ function hasEntityIdentity(p) {
177133
+ return typeof p.entityId === "string";
177134
+ }
176992
177135
  var BridgeEndpointManager = class extends Service {
176993
177136
  constructor(client, registry3, mappingStorage, identityStorage, bridgeId, log, pluginManager, pluginRegistry, pluginInstaller) {
176994
177137
  super("BridgeEndpointManager");
@@ -177278,7 +177421,7 @@ var BridgeEndpointManager = class extends Service {
177278
177421
  * Called by EntityIsolationService when a runtime error is detected.
177279
177422
  */
177280
177423
  async isolateEntity(entityName) {
177281
- const endpoints = this.root.parts.map((p) => p);
177424
+ const endpoints = [...this.root.parts].filter(hasEntityIdentity);
177282
177425
  const endpoint = endpoints.find(
177283
177426
  (e) => !(e instanceof VacuumAreaSwitchEndpoint) && (e.id === entityName || e.entityId === entityName)
177284
177427
  ) ?? endpoints.find((e) => e.id === entityName);
@@ -177389,7 +177532,7 @@ var BridgeEndpointManager = class extends Service {
177389
177532
  async refreshDevices() {
177390
177533
  this.registry.refresh();
177391
177534
  this._failedEntities = [];
177392
- const endpoints = this.root.parts.map((p) => p).filter((p) => !(p instanceof VacuumAreaSwitchEndpoint));
177535
+ const endpoints = [...this.root.parts].filter(hasEntityIdentity).filter((p) => !(p instanceof VacuumAreaSwitchEndpoint));
177393
177536
  this.entityIds = this.registry.entityIds;
177394
177537
  if (this.registry.isAutoComposedDevicesEnabled()) {
177395
177538
  for (const eid of this.entityIds) {
@@ -177757,10 +177900,10 @@ var BridgeEndpointManager = class extends Service {
177757
177900
  this.pendingStates = void 0;
177758
177901
  this.pendingChanged = void 0;
177759
177902
  if (queued) {
177760
- void this.updateStates(
177903
+ this.updateStates(
177761
177904
  queued,
177762
177905
  queuedChanged === void 0 ? null : queuedChanged
177763
- );
177906
+ ).catch((e) => this.log.warn("Queued state update failed:", e));
177764
177907
  }
177765
177908
  });
177766
177909
  return this.updateInFlight;
@@ -177768,9 +177911,9 @@ var BridgeEndpointManager = class extends Service {
177768
177911
  async runUpdateStates(states, changed) {
177769
177912
  const startMs = performance.now();
177770
177913
  this.registry.mergeExternalStates(states);
177771
- const allEndpoints = this.root.parts.map((p) => p);
177914
+ const allEndpoints = [...this.root.parts].filter(isEntityPart);
177772
177915
  const endpoints = changed === null ? allEndpoints : allEndpoints.filter(
177773
- (e) => changed.has(e.entityId) || e.mappedEntityIds.some((id) => changed.has(id))
177916
+ (e) => changed.has(e.entityId) || (e.mappedEntityIds ?? []).some((id) => changed.has(id))
177774
177917
  );
177775
177918
  if (endpoints.length === 0) return;
177776
177919
  const results = await Promise.allSettled(
@@ -178630,11 +178773,11 @@ function makeWarmStartState(state, now = (/* @__PURE__ */ new Date()).toISOStrin
178630
178773
  return { ...state, last_updated: now };
178631
178774
  }
178632
178775
  var ServerModeBridge = class {
178633
- constructor(logger253, dataProvider, endpointManager, server) {
178776
+ constructor(logger254, dataProvider, endpointManager, server) {
178634
178777
  this.dataProvider = dataProvider;
178635
178778
  this.endpointManager = endpointManager;
178636
178779
  this.server = server;
178637
- this.log = logger253.get(`ServerModeBridge / ${dataProvider.id}`);
178780
+ this.log = logger254.get(`ServerModeBridge / ${dataProvider.id}`);
178638
178781
  }
178639
178782
  dataProvider;
178640
178783
  endpointManager;
@@ -179776,7 +179919,7 @@ function ServerModeVacuumDevice(homeAssistantEntity, includeOnOff = false, clean
179776
179919
  }
179777
179920
 
179778
179921
  // src/matter/endpoints/server-mode-vacuum-endpoint.ts
179779
- var logger251 = Logger.get("ServerModeVacuumEndpoint");
179922
+ var logger252 = Logger.get("ServerModeVacuumEndpoint");
179780
179923
  var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEndpoint {
179781
179924
  static async create(registry3, entityId, mapping, endpointId) {
179782
179925
  const deviceRegistry = registry3.deviceOf(entityId);
@@ -179789,7 +179932,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
179789
179932
  if (mapping?.disableBatteryMapping && mapping.batteryEntity) {
179790
179933
  effectiveMapping = { ...mapping, batteryEntity: void 0 };
179791
179934
  }
179792
- logger251.info(
179935
+ logger252.info(
179793
179936
  `${entityId}: device_id=${entity.device_id}, manualBattery=${mapping?.batteryEntity ?? "none"}`
179794
179937
  );
179795
179938
  if (entity.device_id) {
@@ -179804,15 +179947,15 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
179804
179947
  batteryEntity: batteryEntityId
179805
179948
  };
179806
179949
  registry3.markBatteryEntityUsed(batteryEntityId);
179807
- logger251.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
179950
+ logger252.info(`${entityId}: Auto-assigned battery ${batteryEntityId}`);
179808
179951
  } else {
179809
179952
  const attrs = state.attributes;
179810
179953
  if (attrs.battery_level != null || attrs.battery != null) {
179811
- logger251.info(
179954
+ logger252.info(
179812
179955
  `${entityId}: No battery entity found, using battery attribute from vacuum state`
179813
179956
  );
179814
179957
  } else {
179815
- logger251.warn(
179958
+ logger252.warn(
179816
179959
  `${entityId}: No battery entity found for device ${entity.device_id}`
179817
179960
  );
179818
179961
  }
@@ -179827,7 +179970,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
179827
179970
  entityId: effectiveMapping?.entityId ?? entityId,
179828
179971
  cleaningModeEntity: vacuumEntities.cleaningModeEntity
179829
179972
  };
179830
- logger251.info(
179973
+ logger252.info(
179831
179974
  `${entityId}: Auto-assigned cleaningMode ${vacuumEntities.cleaningModeEntity}`
179832
179975
  );
179833
179976
  }
@@ -179837,7 +179980,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
179837
179980
  entityId: effectiveMapping?.entityId ?? entityId,
179838
179981
  suctionLevelEntity: vacuumEntities.suctionLevelEntity
179839
179982
  };
179840
- logger251.info(
179983
+ logger252.info(
179841
179984
  `${entityId}: Auto-assigned suctionLevel ${vacuumEntities.suctionLevelEntity}`
179842
179985
  );
179843
179986
  }
@@ -179847,7 +179990,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
179847
179990
  entityId: effectiveMapping?.entityId ?? entityId,
179848
179991
  mopIntensityEntity: vacuumEntities.mopIntensityEntity
179849
179992
  };
179850
- logger251.info(
179993
+ logger252.info(
179851
179994
  `${entityId}: Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity}`
179852
179995
  );
179853
179996
  }
@@ -179857,7 +180000,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
179857
180000
  entityId: effectiveMapping?.entityId ?? entityId,
179858
180001
  currentRoomEntity: vacuumEntities.currentRoomEntity
179859
180002
  };
179860
- logger251.info(
180003
+ logger252.info(
179861
180004
  `${entityId}: Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity}`
179862
180005
  );
179863
180006
  }
@@ -179872,7 +180015,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
179872
180015
  entityId: effectiveMapping?.entityId ?? entityId,
179873
180016
  cleanAreaRooms
179874
180017
  };
179875
- logger251.info(
180018
+ logger252.info(
179876
180019
  `${entityId}: Using ${cleanAreaRooms.length} HA areas via CLEAN_AREA`
179877
180020
  );
179878
180021
  }
@@ -179893,7 +180036,7 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
179893
180036
  rooms: roomsObj
179894
180037
  }
179895
180038
  };
179896
- logger251.info(
180039
+ logger252.info(
179897
180040
  `${entityId}: Auto-detected ${valetudoRooms.length} Valetudo segments`
179898
180041
  );
179899
180042
  } else {
@@ -179910,14 +180053,14 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
179910
180053
  rooms: roomsObj
179911
180054
  }
179912
180055
  };
179913
- logger251.info(
180056
+ logger252.info(
179914
180057
  `${entityId}: Auto-detected ${roborockRooms.length} Roborock rooms`
179915
180058
  );
179916
180059
  }
179917
180060
  }
179918
180061
  }
179919
180062
  } else {
179920
- logger251.warn(`${entityId}: No device_id, cannot auto-assign battery`);
180063
+ logger252.warn(`${entityId}: No device_id, cannot auto-assign battery`);
179921
180064
  }
179922
180065
  const payload = {
179923
180066
  entity_id: entityId,
@@ -179990,11 +180133,11 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
179990
180133
  }
179991
180134
  if (mappedChanged) {
179992
180135
  this.pendingMappedChange = true;
179993
- logger251.debug(
180136
+ logger252.debug(
179994
180137
  `Mapped entity change detected for ${this.entityId}, forcing update`
179995
180138
  );
179996
180139
  }
179997
- logger251.debug(
180140
+ logger252.debug(
179998
180141
  `State update received for ${this.entityId}: state=${state.state}`
179999
180142
  );
180000
180143
  this.lastState = state;
@@ -180572,10 +180715,10 @@ var BridgeEnvironmentFactory = class extends BridgeFactory {
180572
180715
  // src/core/ioc/app-environment.ts
180573
180716
  var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
180574
180717
  constructor(rootEnv, options) {
180575
- const logger253 = rootEnv.get(LoggerService);
180718
+ const logger254 = rootEnv.get(LoggerService);
180576
180719
  super({
180577
180720
  id: "App",
180578
- log: logger253.get("AppContainer"),
180721
+ log: logger254.get("AppContainer"),
180579
180722
  parent: rootEnv
180580
180723
  });
180581
180724
  this.options = options;
@@ -180589,8 +180732,8 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
180589
180732
  }
180590
180733
  construction;
180591
180734
  async init() {
180592
- const logger253 = this.get(LoggerService);
180593
- this.set(LoggerService, logger253);
180735
+ const logger254 = this.get(LoggerService);
180736
+ this.set(LoggerService, logger254);
180594
180737
  this.set(AppStorage, new AppStorage(await this.load(StorageService)));
180595
180738
  this.set(BridgeStorage, new BridgeStorage(await this.load(AppStorage)));
180596
180739
  this.set(
@@ -180611,7 +180754,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
180611
180754
  );
180612
180755
  this.set(
180613
180756
  HomeAssistantClient,
180614
- new HomeAssistantClient(logger253, this.options.homeAssistant)
180757
+ new HomeAssistantClient(logger254, this.options.homeAssistant)
180615
180758
  );
180616
180759
  this.set(
180617
180760
  HomeAssistantConfig,
@@ -180619,7 +180762,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
180619
180762
  );
180620
180763
  this.set(
180621
180764
  HomeAssistantActions,
180622
- new HomeAssistantActions(logger253, await this.load(HomeAssistantClient))
180765
+ new HomeAssistantActions(logger254, await this.load(HomeAssistantClient))
180623
180766
  );
180624
180767
  this.set(
180625
180768
  HomeAssistantRegistry,
@@ -180655,7 +180798,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
180655
180798
  this.set(
180656
180799
  WebApi,
180657
180800
  new WebApi(
180658
- logger253,
180801
+ logger254,
180659
180802
  await this.load(BridgeService),
180660
180803
  await this.load(HomeAssistantClient),
180661
180804
  await this.load(HomeAssistantRegistry),
@@ -180676,7 +180819,7 @@ var AppEnvironment = class _AppEnvironment extends EnvironmentBase {
180676
180819
 
180677
180820
  // src/matter/patches/patch-level-control-tlv.ts
180678
180821
  init_esm();
180679
- var logger252 = Logger.get("PatchLevelControlTlv");
180822
+ var logger253 = Logger.get("PatchLevelControlTlv");
180680
180823
  var optionalFieldModels = /* @__PURE__ */ new WeakSet();
180681
180824
  var fieldModelMandatoryGetterPatched = false;
180682
180825
  function patchLevelControlTlv() {
@@ -180732,11 +180875,11 @@ function patchLevelControlTlv() {
180732
180875
  patched++;
180733
180876
  }
180734
180877
  if (patched > 0) {
180735
- logger252.info(
180878
+ logger253.info(
180736
180879
  `Patched ${patched} LevelControl TLV schema(s): transitionTime is now optional (Google Home compatibility)`
180737
180880
  );
180738
180881
  } else {
180739
- logger252.warn(
180882
+ logger253.warn(
180740
180883
  "Failed to patch LevelControl TLV schemas, field definitions not found. Google Home brightness adjustment may not work.",
180741
180884
  {
180742
180885
  moveToLevel: describeFields(