@riddix/hamh 2.1.0-alpha.547 → 2.1.0-alpha.549

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.
@@ -167613,6 +167613,7 @@ function getMappedEntityIds(mapping) {
167613
167613
  if (mapping.filterLifeEntity) ids.push(mapping.filterLifeEntity);
167614
167614
  if (mapping.powerEntity) ids.push(mapping.powerEntity);
167615
167615
  if (mapping.energyEntity) ids.push(mapping.energyEntity);
167616
+ if (mapping.currentRoomEntity) ids.push(mapping.currentRoomEntity);
167616
167617
  if (mapping.composedEntities) {
167617
167618
  for (const sub of mapping.composedEntities) {
167618
167619
  if (sub.entityId) ids.push(sub.entityId);
@@ -175685,6 +175686,10 @@ function isRoomMode(mode) {
175685
175686
  return mode >= ROOM_MODE_BASE;
175686
175687
  }
175687
175688
  var RvcRunModeServerBase = class extends RvcRunModeServer {
175689
+ /** Areas that the vacuum has already finished cleaning in this session */
175690
+ completedAreas = /* @__PURE__ */ new Set();
175691
+ /** Last known currentArea — used to detect room transitions */
175692
+ lastCurrentArea = null;
175688
175693
  async initialize() {
175689
175694
  await super.initialize();
175690
175695
  const homeAssistant = await this.agent.load(HomeAssistantEntityBehavior);
@@ -175706,6 +175711,8 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
175706
175711
  });
175707
175712
  if (previousMode !== newMode) {
175708
175713
  if (newMode === 0 /* Idle */) {
175714
+ this.completedAreas.clear();
175715
+ this.lastCurrentArea = null;
175709
175716
  this.trySetCurrentArea(null);
175710
175717
  } else if (newMode === 1 /* Cleaning */) {
175711
175718
  try {
@@ -175717,6 +175724,53 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
175717
175724
  }
175718
175725
  }
175719
175726
  }
175727
+ if (newMode === 1 /* Cleaning */) {
175728
+ this.updateCurrentRoomFromSensor();
175729
+ }
175730
+ }
175731
+ /**
175732
+ * Read the currentRoomEntity sensor and update currentArea + progress
175733
+ * to reflect which room the vacuum is actually in right now.
175734
+ */
175735
+ updateCurrentRoomFromSensor() {
175736
+ try {
175737
+ const homeAssistant = this.agent.get(HomeAssistantEntityBehavior);
175738
+ const currentRoomEntityId = homeAssistant.state.mapping?.currentRoomEntity;
175739
+ if (!currentRoomEntityId) return;
175740
+ const stateProvider = this.agent.env.get(EntityStateProvider);
175741
+ const roomState = stateProvider.getState(currentRoomEntityId);
175742
+ if (!roomState || !roomState.state) return;
175743
+ const serviceArea = this.agent.get(ServiceAreaBehavior);
175744
+ const selectedAreas = serviceArea.state.selectedAreas;
175745
+ if (!selectedAreas || selectedAreas.length === 0) return;
175746
+ const segmentId = roomState.attributes?.segment_id;
175747
+ const roomName = roomState.state;
175748
+ let matchedAreaId = null;
175749
+ if (segmentId != null) {
175750
+ if (selectedAreas.includes(segmentId)) {
175751
+ matchedAreaId = segmentId;
175752
+ }
175753
+ }
175754
+ if (matchedAreaId === null && roomName) {
175755
+ const area = serviceArea.state.supportedAreas.find(
175756
+ (a) => a.areaInfo.locationInfo?.locationName?.toLowerCase() === roomName.toLowerCase()
175757
+ );
175758
+ if (area && selectedAreas.includes(area.areaId)) {
175759
+ matchedAreaId = area.areaId;
175760
+ }
175761
+ }
175762
+ if (matchedAreaId === null) return;
175763
+ if (matchedAreaId === this.lastCurrentArea) return;
175764
+ if (this.lastCurrentArea !== null) {
175765
+ this.completedAreas.add(this.lastCurrentArea);
175766
+ }
175767
+ this.lastCurrentArea = matchedAreaId;
175768
+ logger189.debug(
175769
+ `currentRoom sensor: area ${matchedAreaId} ("${roomName}"), completed: [${[...this.completedAreas].join(", ")}]`
175770
+ );
175771
+ this.trySetCurrentArea(matchedAreaId);
175772
+ } catch {
175773
+ }
175720
175774
  }
175721
175775
  /**
175722
175776
  * Safely update ServiceArea.currentArea and progress.
@@ -175737,24 +175791,27 @@ var RvcRunModeServerBase = class extends RvcRunModeServer {
175737
175791
  }
175738
175792
  /**
175739
175793
  * Update progress entries to reflect the current operating area.
175740
- * - null: mark all Operating/Pending entries as Completed (cleaning done)
175741
- * - areaId: mark that area as Operating
175794
+ * - null: mark all areas as Completed (cleaning done)
175795
+ * - areaId: mark that area as Operating, others as Pending
175742
175796
  *
175743
- * Note: progress is available because our ServiceAreaServerBase enables
175744
- * ProgressReporting, but the base ServiceAreaBehavior type doesn't expose it.
175797
+ * Rebuilds progress from selectedAreas (plain number array) instead of
175798
+ * reading managed state progress entries, which avoids infinite recursion
175799
+ * in matter.js property getters during transaction pre-commit.
175745
175800
  */
175746
175801
  updateProgress(serviceArea, areaId) {
175747
175802
  const state = serviceArea.state;
175748
- const progress = state.progress;
175749
- if (!progress || progress.length === 0) return;
175803
+ const selectedAreas = serviceArea.state.selectedAreas;
175804
+ if (!selectedAreas || selectedAreas.length === 0) return;
175750
175805
  if (areaId === null) {
175751
- state.progress = progress.map(
175752
- (p) => p.status === ServiceArea3.OperationalStatus.Operating || p.status === ServiceArea3.OperationalStatus.Pending ? { ...p, status: ServiceArea3.OperationalStatus.Completed } : p
175753
- );
175806
+ state.progress = selectedAreas.map((id) => ({
175807
+ areaId: id,
175808
+ status: ServiceArea3.OperationalStatus.Completed
175809
+ }));
175754
175810
  } else {
175755
- state.progress = progress.map(
175756
- (p) => p.areaId === areaId && p.status === ServiceArea3.OperationalStatus.Pending ? { ...p, status: ServiceArea3.OperationalStatus.Operating } : p
175757
- );
175811
+ state.progress = selectedAreas.map((id) => ({
175812
+ areaId: id,
175813
+ status: id === areaId ? ServiceArea3.OperationalStatus.Operating : this.completedAreas.has(id) ? ServiceArea3.OperationalStatus.Completed : ServiceArea3.OperationalStatus.Pending
175814
+ }));
175758
175815
  }
175759
175816
  }
175760
175817
  /**
@@ -178587,6 +178644,16 @@ var LegacyEndpoint = class _LegacyEndpoint extends EntityEndpoint {
178587
178644
  `Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity} to ${entityId}`
178588
178645
  );
178589
178646
  }
178647
+ if (!effectiveMapping?.currentRoomEntity && vacuumEntities.currentRoomEntity) {
178648
+ effectiveMapping = {
178649
+ ...effectiveMapping,
178650
+ entityId: effectiveMapping?.entityId ?? entityId,
178651
+ currentRoomEntity: vacuumEntities.currentRoomEntity
178652
+ };
178653
+ logger200.debug(
178654
+ `Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity} to ${entityId}`
178655
+ );
178656
+ }
178590
178657
  const supportedFeatures = state.attributes.supported_features ?? 0;
178591
178658
  const cleanAreaRooms = await registry2.resolveCleanAreaRooms(
178592
178659
  entityId,
@@ -179765,7 +179832,22 @@ var BridgeRegistry = class _BridgeRegistry {
179765
179832
  mopIntensityEntity = entity.entity_id;
179766
179833
  }
179767
179834
  }
179768
- return { cleaningModeEntity, suctionLevelEntity, mopIntensityEntity };
179835
+ let currentRoomEntity;
179836
+ const sameDeviceSensors = entities.filter(
179837
+ (e) => e.device_id === deviceId && e.entity_id.startsWith("sensor.")
179838
+ );
179839
+ for (const entity of sameDeviceSensors) {
179840
+ if (entity.entity_id.toLowerCase().endsWith("_current_room")) {
179841
+ currentRoomEntity = entity.entity_id;
179842
+ break;
179843
+ }
179844
+ }
179845
+ return {
179846
+ cleaningModeEntity,
179847
+ suctionLevelEntity,
179848
+ mopIntensityEntity,
179849
+ currentRoomEntity
179850
+ };
179769
179851
  }
179770
179852
  static valetudoLogger = Logger.get("ValetudoRooms");
179771
179853
  /**
@@ -180762,6 +180844,16 @@ var ServerModeVacuumEndpoint = class _ServerModeVacuumEndpoint extends EntityEnd
180762
180844
  `${entityId}: Auto-assigned mopIntensity ${vacuumEntities.mopIntensityEntity}`
180763
180845
  );
180764
180846
  }
180847
+ if (!effectiveMapping?.currentRoomEntity && vacuumEntities.currentRoomEntity) {
180848
+ effectiveMapping = {
180849
+ ...effectiveMapping,
180850
+ entityId: effectiveMapping?.entityId ?? entityId,
180851
+ currentRoomEntity: vacuumEntities.currentRoomEntity
180852
+ };
180853
+ logger203.info(
180854
+ `${entityId}: Auto-assigned currentRoom ${vacuumEntities.currentRoomEntity}`
180855
+ );
180856
+ }
180765
180857
  const supportedFeatures = state.attributes.supported_features ?? 0;
180766
180858
  const cleanAreaRooms = await registry2.resolveCleanAreaRooms(
180767
180859
  entityId,