From b0780110c7ad54e271532172eda35acdfc04ae8d Mon Sep 17 00:00:00 2001 From: Anton Lundin Date: Fri, 9 Feb 2018 23:50:05 +0100 Subject: [PATCH] One bug fix and one improvement to the statistics sensor. (#12259) * Correct time on recorder loaded values in statistics sensor Previously, the current time was used when initial values was loaded form the recorder component. This changes that to use the stored time from recorder instead. Signed-off-by: Anton Lundin * Expose min / max age of values in the statistics sensor This is very useful when doing derived calculations, for example in a template sensor. Signed-off-by: Anton Lundin --- homeassistant/components/sensor/statistics.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/sensor/statistics.py b/homeassistant/components/sensor/statistics.py index 46c714d0dbf..b26fd5cc804 100644 --- a/homeassistant/components/sensor/statistics.py +++ b/homeassistant/components/sensor/statistics.py @@ -34,6 +34,8 @@ ATTR_VARIANCE = 'variance' ATTR_STANDARD_DEVIATION = 'standard_deviation' ATTR_SAMPLING_SIZE = 'sampling_size' ATTR_TOTAL = 'total' +ATTR_MAX_AGE = 'max_age' +ATTR_MIN_AGE = 'min_age' CONF_SAMPLING_SIZE = 'sampling_size' CONF_MAX_AGE = 'max_age' @@ -88,6 +90,7 @@ class StatisticsSensor(Entity): self.median = self.mean = self.variance = self.stdev = 0 self.min = self.max = self.total = self.count = 0 self.average_change = self.change = 0 + self.max_age = self.min_age = 0 if 'recorder' in self._hass.config.components: # only use the database if it's configured @@ -111,8 +114,7 @@ class StatisticsSensor(Entity): try: self.states.append(float(new_state.state)) if self._max_age is not None: - now = dt_util.utcnow() - self.ages.append(now) + self.ages.append(new_state.last_updated) self.count = self.count + 1 except ValueError: self.count = self.count + 1 @@ -141,7 +143,7 @@ class StatisticsSensor(Entity): def device_state_attributes(self): """Return the state attributes of the sensor.""" if not self.is_binary: - return { + state = { ATTR_MEAN: self.mean, ATTR_COUNT: self.count, ATTR_MAX_VALUE: self.max, @@ -154,6 +156,13 @@ class StatisticsSensor(Entity): ATTR_CHANGE: self.change, ATTR_AVERAGE_CHANGE: self.average_change, } + # Only return min/max age if we have a age span + if self._max_age: + state.update({ + ATTR_MAX_AGE: self.max_age, + ATTR_MIN_AGE: self.min_age, + }) + return state @property def icon(self): @@ -190,6 +199,7 @@ class StatisticsSensor(Entity): self.stdev = self.variance = STATE_UNKNOWN if self.states: + self.count = len(self.states) self.total = round(sum(self.states), 2) self.min = min(self.states) self.max = max(self.states) @@ -197,6 +207,9 @@ class StatisticsSensor(Entity): self.average_change = self.change if len(self.states) > 1: self.average_change /= len(self.states) - 1 + if self._max_age is not None: + self.max_age = max(self.ages) + self.min_age = min(self.ages) else: self.min = self.max = self.total = STATE_UNKNOWN self.average_change = self.change = STATE_UNKNOWN