Skip to content

Commit

Permalink
Merge pull request #1665 from bramstroker/fix/group-unavailability
Browse files Browse the repository at this point in the history
Fix energy group won't get unavailable when some member sensors are unavailable
  • Loading branch information
bramstroker committed May 8, 2023
2 parents cde7e5a + c959ab3 commit f845723
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 29 deletions.
37 changes: 9 additions & 28 deletions custom_components/powercalc/sensors/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,34 +531,12 @@ def on_state_change(self, event: Event) -> None:
for state in states
if state and state.state not in [STATE_UNKNOWN, STATE_UNAVAILABLE]
]
unavailable_entities = [
state.entity_id
for state in states
if state and state.state == STATE_UNAVAILABLE
]
if unavailable_entities and isinstance(self, GroupedEnergySensor):
for entity_id in unavailable_entities:
prev_state = self._prev_state_store.get_entity_state(entity_id)
if prev_state:
available_states.append(prev_state)
unavailable_entities.remove(entity_id)

if unavailable_entities:
_LOGGER.warning(
"%s: One or more members of the group are unavailable, setting group to unavailable (%s)",
self.entity_id,
",".join(unavailable_entities),
)
self._attr_available = False
self.async_schedule_update_ha_state(True)
return

if not available_states:
self._attr_available = False
self.async_schedule_update_ha_state(True)
return

summed = self.calculate_new_state(available_states)
summed = self.calculate_new_state(available_states, states)
self._attr_native_value = round(summed, self._rounding_digits)
self._attr_available = True
self.async_schedule_update_ha_state(True)
Expand All @@ -584,7 +562,7 @@ def _get_state_value_in_native_unit(self, state: State) -> Decimal:
return Decimal(value)

@abstractmethod
def calculate_new_state(self, member_states: list[State]) -> Decimal:
def calculate_new_state(self, member_available_states: list[State], member_states: list[State]) -> Decimal:
...


Expand All @@ -595,9 +573,9 @@ class GroupedPowerSensor(GroupedSensor, PowerSensor):
_attr_state_class = SensorStateClass.MEASUREMENT
_attr_native_unit_of_measurement = POWER_WATT

def calculate_new_state(self, member_states: list[State]) -> Decimal:
def calculate_new_state(self, member_available_states: list[State], member_states: list[State]) -> Decimal:
values = [
self._get_state_value_in_native_unit(state) for state in member_states
self._get_state_value_in_native_unit(state) for state in member_available_states
]
return Decimal(sum([value for value in values if value is not None]))

Expand Down Expand Up @@ -655,13 +633,16 @@ def async_reset(self) -> None:
self._attr_last_reset = dt_util.utcnow()
self.async_write_ha_state()

def calculate_new_state(self, member_states: list[State]) -> Decimal:
def calculate_new_state(self, member_available_states: list[State], member_states: list[State]) -> Decimal:
"""Calculate the new group energy sensor state
For each member sensor we calculate the delta by looking at the previous known state and compare it to the current.
"""
group_sum = Decimal(self._attr_native_value) if self._attr_native_value else Decimal(0) # type: ignore
_LOGGER.debug(f"{self.entity_id}: Recalculate, current value: {group_sum}")
for entity_state in member_states:
if entity_state.state in [STATE_UNKNOWN, STATE_UNAVAILABLE]:
_LOGGER.debug(f"skipping state for {entity_state.entity_id}, sensor unavailable or unknown")
continue
prev_state = self._prev_state_store.get_entity_state(entity_state.entity_id)
cur_state_value = self._get_state_value_in_native_unit(entity_state)

Expand All @@ -677,7 +658,7 @@ def calculate_new_state(self, member_states: list[State]) -> Decimal:
)

delta = cur_state_value - prev_state_value
_LOGGER.debug(f"delta for entity {entity_state.entity_id}: {delta}")
_LOGGER.debug(f"delta for entity {entity_state.entity_id}: {delta}, prev={prev_state_value}, cur={cur_state_value}")
if delta < 0:
_LOGGER.warning(
f"skipping state for {entity_state.entity_id}, probably erroneous value or sensor was reset",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ source = ["custom_components/powercalc"]

[tool.ruff]
select = ["E", "W", "F", "B", "C", "I", "N", "UP", "ANN", "BLE", "A", "COM", "C4", "G", "ISC", "NPY", "INP", "PIE", "T20", "PYI", "Q", "RET", "SLF", "SIM", "TID", "RUF"]
ignore = ["ANN101", "ANN401"]
ignore = ["ANN101", "ANN401", "I001"]
line-length = 150
target-version = "py310"

Expand Down

0 comments on commit f845723

Please sign in to comment.