From ab128983a3599998749020a9525bb83aaa012e38 Mon Sep 17 00:00:00 2001 From: Michael Wyraz Date: Sun, 26 Mar 2017 20:14:22 +0200 Subject: [PATCH] Fix handling of known->unknown state, extended test, fix lint errors --- homeassistant/components/sensor/min_max.py | 73 +++++++++++----------- tests/components/sensor/test_min_max.py | 8 ++- 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/homeassistant/components/sensor/min_max.py b/homeassistant/components/sensor/min_max.py index 4e7199d4f42..3e863562777 100644 --- a/homeassistant/components/sensor/min_max.py +++ b/homeassistant/components/sensor/min_max.py @@ -65,6 +65,39 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): return True +def calc_min(sensor_values): + """Calculate min value, honoring unknown states.""" + val = STATE_UNKNOWN + for sval in sensor_values: + if sval != STATE_UNKNOWN: + if val == STATE_UNKNOWN or val > sval: + val = sval + return val + + +def calc_max(sensor_values): + """Calculate max value, honoring unknown states.""" + val = STATE_UNKNOWN + for sval in sensor_values: + if sval != STATE_UNKNOWN: + if val == STATE_UNKNOWN or val < sval: + val = sval + return val + + +def calc_mean(sensor_values, round_digits): + """Calculate mean value, honoring unknown states.""" + val = 0 + count = 0 + for sval in sensor_values: + if sval != STATE_UNKNOWN: + val += sval + count += 1 + if count == 0: + return STATE_UNKNOWN + return round(val/count, round_digits) + + class MinMaxSensor(Entity): """Representation of a min/max sensor.""" @@ -91,6 +124,8 @@ class MinMaxSensor(Entity): def async_min_max_sensor_state_listener(entity, old_state, new_state): """Called when the sensor changes state.""" if new_state.state is None or new_state.state in STATE_UNKNOWN: + self.states[entity] = STATE_UNKNOWN + hass.async_add_job(self.async_update_ha_state, True) return if self._unit_of_measurement is None: @@ -152,38 +187,6 @@ class MinMaxSensor(Entity): """Get the latest data and updates the states.""" sensor_values = [self.states[k] for k in self._entity_ids if k in self.states] - self.min_value = self.calc_min(sensor_values) - self.max_value = self.calc_max(sensor_values) - self.mean = self.calc_mean(sensor_values) - - # pylint: disable=R0201 - def calc_min(self, sensor_values): - """Calculate min value, honoring unknown states.""" - val = STATE_UNKNOWN - for sval in sensor_values: - if sval != STATE_UNKNOWN: - if val == STATE_UNKNOWN or val > sval: - val = sval - return val - - # pylint: disable=R0201 - def calc_max(self, sensor_values): - """Calculate max value, honoring unknown states.""" - val = STATE_UNKNOWN - for sval in sensor_values: - if sval != STATE_UNKNOWN: - if val == STATE_UNKNOWN or val < sval: - val = sval - return val - - def calc_mean(self, sensor_values): - """Calculate mean value, honoring unknown states.""" - val = 0 - count = 0 - for sval in sensor_values: - if sval != STATE_UNKNOWN: - val += sval - count += 1 - if count == 0: - return STATE_UNKNOWN - return round(val/count, self._round_digits) + self.min_value = calc_min(sensor_values) + self.max_value = calc_max(sensor_values) + self.mean = calc_mean(sensor_values, self._round_digits) diff --git a/tests/components/sensor/test_min_max.py b/tests/components/sensor/test_min_max.py index 1e95eed7108..c19e2b60627 100644 --- a/tests/components/sensor/test_min_max.py +++ b/tests/components/sensor/test_min_max.py @@ -196,7 +196,7 @@ class TestMinMaxSensor(unittest.TestCase): state = self.hass.states.get('sensor.test_max') self.assertEqual(STATE_UNKNOWN, state.state) - self.hass.states.set(entity_ids[2], self.values[1]) + self.hass.states.set(entity_ids[1], self.values[1]) self.hass.block_till_done() state = self.hass.states.get('sensor.test_max') @@ -207,3 +207,9 @@ class TestMinMaxSensor(unittest.TestCase): state = self.hass.states.get('sensor.test_max') self.assertNotEqual(STATE_UNKNOWN, state.state) + + self.hass.states.set(entity_ids[1], STATE_UNKNOWN) + self.hass.block_till_done() + + state = self.hass.states.get('sensor.test_max') + self.assertEqual(STATE_UNKNOWN, state.state)