Support for multiple states in history_stats (#43416)
Co-authored-by: Indu Prakash <6459774+InduPrakash@users.noreply.github.com>
This commit is contained in:
parent
f22f568169
commit
7213d5f31b
2 changed files with 113 additions and 8 deletions
|
@ -62,7 +62,7 @@ PLATFORM_SCHEMA = vol.All(
|
|||
PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||
vol.Required(CONF_STATE): cv.string,
|
||||
vol.Required(CONF_STATE): vol.All(cv.ensure_list, [cv.string]),
|
||||
vol.Optional(CONF_START): cv.template,
|
||||
vol.Optional(CONF_END): cv.template,
|
||||
vol.Optional(CONF_DURATION): cv.time_period,
|
||||
|
@ -77,11 +77,10 @@ PLATFORM_SCHEMA = vol.All(
|
|||
# noinspection PyUnusedLocal
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the History Stats sensor."""
|
||||
|
||||
setup_reload_service(hass, DOMAIN, PLATFORMS)
|
||||
|
||||
entity_id = config.get(CONF_ENTITY_ID)
|
||||
entity_state = config.get(CONF_STATE)
|
||||
entity_states = config.get(CONF_STATE)
|
||||
start = config.get(CONF_START)
|
||||
end = config.get(CONF_END)
|
||||
duration = config.get(CONF_DURATION)
|
||||
|
@ -95,7 +94,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
add_entities(
|
||||
[
|
||||
HistoryStatsSensor(
|
||||
hass, entity_id, entity_state, start, end, duration, sensor_type, name
|
||||
hass, entity_id, entity_states, start, end, duration, sensor_type, name
|
||||
)
|
||||
]
|
||||
)
|
||||
|
@ -107,11 +106,11 @@ class HistoryStatsSensor(Entity):
|
|||
"""Representation of a HistoryStats sensor."""
|
||||
|
||||
def __init__(
|
||||
self, hass, entity_id, entity_state, start, end, duration, sensor_type, name
|
||||
self, hass, entity_id, entity_states, start, end, duration, sensor_type, name
|
||||
):
|
||||
"""Initialize the HistoryStats sensor."""
|
||||
self._entity_id = entity_id
|
||||
self._entity_state = entity_state
|
||||
self._entity_states = entity_states
|
||||
self._duration = duration
|
||||
self._start = start
|
||||
self._end = end
|
||||
|
@ -230,14 +229,14 @@ class HistoryStatsSensor(Entity):
|
|||
|
||||
# Get the first state
|
||||
last_state = history.get_state(self.hass, start, self._entity_id)
|
||||
last_state = last_state is not None and last_state == self._entity_state
|
||||
last_state = last_state is not None and last_state in self._entity_states
|
||||
last_time = start_timestamp
|
||||
elapsed = 0
|
||||
count = 0
|
||||
|
||||
# Make calculations
|
||||
for item in history_list.get(self._entity_id):
|
||||
current_state = item.state == self._entity_state
|
||||
current_state = item.state in self._entity_states
|
||||
current_time = item.last_changed.timestamp()
|
||||
|
||||
if last_state:
|
||||
|
|
|
@ -50,6 +50,28 @@ class TestHistoryStatsSensor(unittest.TestCase):
|
|||
state = self.hass.states.get("sensor.test")
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
def test_setup_multiple_states(self):
|
||||
"""Test the history statistics sensor setup for multiple states."""
|
||||
self.init_recorder()
|
||||
config = {
|
||||
"history": {},
|
||||
"sensor": {
|
||||
"platform": "history_stats",
|
||||
"entity_id": "binary_sensor.test_id",
|
||||
"state": ["on", "true"],
|
||||
"start": "{{ now().replace(hour=0)"
|
||||
".replace(minute=0).replace(second=0) }}",
|
||||
"duration": "02:00",
|
||||
"name": "Test",
|
||||
},
|
||||
}
|
||||
|
||||
assert setup_component(self.hass, "sensor", config)
|
||||
self.hass.block_till_done()
|
||||
|
||||
state = self.hass.states.get("sensor.test")
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
@patch(
|
||||
"homeassistant.helpers.template.TemplateEnvironment.is_safe_callable",
|
||||
return_value=True,
|
||||
|
@ -152,6 +174,90 @@ class TestHistoryStatsSensor(unittest.TestCase):
|
|||
assert sensor3.state == 2
|
||||
assert sensor4.state == 50
|
||||
|
||||
def test_measure_multiple(self):
|
||||
"""Test the history statistics sensor measure for multiple states."""
|
||||
t0 = dt_util.utcnow() - timedelta(minutes=40)
|
||||
t1 = t0 + timedelta(minutes=20)
|
||||
t2 = dt_util.utcnow() - timedelta(minutes=10)
|
||||
|
||||
# Start t0 t1 t2 End
|
||||
# |--20min--|--20min--|--10min--|--10min--|
|
||||
# |---------|--orange-|-default-|---blue--|
|
||||
|
||||
fake_states = {
|
||||
"input_select.test_id": [
|
||||
ha.State("input_select.test_id", "orange", last_changed=t0),
|
||||
ha.State("input_select.test_id", "default", last_changed=t1),
|
||||
ha.State("input_select.test_id", "blue", last_changed=t2),
|
||||
]
|
||||
}
|
||||
|
||||
start = Template("{{ as_timestamp(now()) - 3600 }}", self.hass)
|
||||
end = Template("{{ now() }}", self.hass)
|
||||
|
||||
sensor1 = HistoryStatsSensor(
|
||||
self.hass,
|
||||
"input_select.test_id",
|
||||
["orange", "blue"],
|
||||
start,
|
||||
end,
|
||||
None,
|
||||
"time",
|
||||
"Test",
|
||||
)
|
||||
|
||||
sensor2 = HistoryStatsSensor(
|
||||
self.hass,
|
||||
"unknown.id",
|
||||
["orange", "blue"],
|
||||
start,
|
||||
end,
|
||||
None,
|
||||
"time",
|
||||
"Test",
|
||||
)
|
||||
|
||||
sensor3 = HistoryStatsSensor(
|
||||
self.hass,
|
||||
"input_select.test_id",
|
||||
["orange", "blue"],
|
||||
start,
|
||||
end,
|
||||
None,
|
||||
"count",
|
||||
"test",
|
||||
)
|
||||
|
||||
sensor4 = HistoryStatsSensor(
|
||||
self.hass,
|
||||
"input_select.test_id",
|
||||
["orange", "blue"],
|
||||
start,
|
||||
end,
|
||||
None,
|
||||
"ratio",
|
||||
"test",
|
||||
)
|
||||
|
||||
assert sensor1._type == "time"
|
||||
assert sensor3._type == "count"
|
||||
assert sensor4._type == "ratio"
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.history.state_changes_during_period",
|
||||
return_value=fake_states,
|
||||
):
|
||||
with patch("homeassistant.components.history.get_state", return_value=None):
|
||||
sensor1.update()
|
||||
sensor2.update()
|
||||
sensor3.update()
|
||||
sensor4.update()
|
||||
|
||||
assert sensor1.state == 0.5
|
||||
assert sensor2.state is None
|
||||
assert sensor3.state == 2
|
||||
assert sensor4.state == 50
|
||||
|
||||
def test_wrong_date(self):
|
||||
"""Test when start or end value is not a timestamp or a date."""
|
||||
good = Template("{{ now() }}", self.hass)
|
||||
|
|
Loading…
Add table
Reference in a new issue