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 <glance@acc.umu.se>

* 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 <glance@acc.umu.se>
This commit is contained in:
Anton Lundin 2018-02-09 23:50:05 +01:00 committed by Fabian Affolter
parent b087ea101d
commit b0780110c7

View file

@ -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