Add available property to statistics component (#59203)

* Add available property to the statistics component

* Add test for statistics sensor availability

* Clean up availability check

* Improve statistics source sensor tests

* Revert variable rename

* Improve comments
This commit is contained in:
Thomas Dietrich 2021-11-11 17:16:59 +01:00 committed by GitHub
parent 4ecbfe8646
commit 90ee1f4783
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 6 deletions

View File

@ -126,6 +126,7 @@ class StatisticsSensor(SensorEntity):
self._entity_id = entity_id
self.is_binary = self._entity_id.split(".")[0] == "binary_sensor"
self._name = name
self._available = False
self._sampling_size = sampling_size
self._max_age = max_age
self._precision = precision
@ -176,6 +177,7 @@ class StatisticsSensor(SensorEntity):
def _add_state_to_queue(self, new_state):
"""Add the state to the queue."""
self._available = new_state.state != STATE_UNAVAILABLE
if new_state.state in (STATE_UNKNOWN, STATE_UNAVAILABLE, None):
return
@ -184,7 +186,6 @@ class StatisticsSensor(SensorEntity):
self.states.append(new_state.state)
else:
self.states.append(float(new_state.state))
self.ages.append(new_state.last_updated)
except ValueError:
_LOGGER.error(
@ -216,6 +217,11 @@ class StatisticsSensor(SensorEntity):
"""Return the unit the value is expressed in."""
return self._unit_of_measurement if not self.is_binary else None
@property
def available(self):
"""Return the availability of the sensor linked to the source sensor."""
return self._available
@property
def should_poll(self):
"""No polling needed."""

View File

@ -12,6 +12,7 @@ from homeassistant.components.statistics.sensor import DOMAIN, StatisticsSensor
from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT,
SERVICE_RELOAD,
STATE_UNAVAILABLE,
STATE_UNKNOWN,
TEMP_CELSIUS,
)
@ -110,7 +111,6 @@ class TestStatisticsSensor(unittest.TestCase):
self.hass.block_till_done()
state = self.hass.states.get("sensor.test")
assert str(self.mean) == state.state
assert self.min == state.attributes.get("min_value")
assert self.max == state.attributes.get("max_value")
@ -125,13 +125,29 @@ class TestStatisticsSensor(unittest.TestCase):
assert self.change == state.attributes.get("change")
assert self.average_change == state.attributes.get("average_change")
# Source sensor is unavailable, unit and state should not change
self.hass.states.set("sensor.test_monitored", "unavailable", {})
# Source sensor turns unavailable, then available with valid value,
# statistics sensor should follow
state = self.hass.states.get("sensor.test")
self.hass.states.set(
"sensor.test_monitored",
STATE_UNAVAILABLE,
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS},
)
self.hass.block_till_done()
new_state = self.hass.states.get("sensor.test")
assert state == new_state
assert new_state.state == STATE_UNAVAILABLE
self.hass.states.set(
"sensor.test_monitored",
0,
{ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS},
)
self.hass.block_till_done()
new_state = self.hass.states.get("sensor.test")
assert new_state.state != STATE_UNAVAILABLE
assert new_state.attributes.get("count") == state.attributes.get("count") + 1
# Source sensor has a non float state, unit and state should not change
# Source sensor has a non-float state, unit and state should not change
state = self.hass.states.get("sensor.test")
self.hass.states.set("sensor.test_monitored", "beer", {})
self.hass.block_till_done()
new_state = self.hass.states.get("sensor.test")