diff --git a/homeassistant/components/sensor/history_stats.py b/homeassistant/components/sensor/history_stats.py index 7d9dfaaa48f..08546e3f0c8 100644 --- a/homeassistant/components/sensor/history_stats.py +++ b/homeassistant/components/sensor/history_stats.py @@ -44,8 +44,6 @@ UNITS = { } ICON = 'mdi:chart-line' -ATTR_START = 'from' -ATTR_END = 'to' ATTR_VALUE = 'value' @@ -157,12 +155,9 @@ class HistoryStatsSensor(Entity): @property def device_state_attributes(self): """Return the state attributes of the sensor.""" - start, end = self._period hsh = HistoryStatsHelper return { ATTR_VALUE: hsh.pretty_duration(self.value), - ATTR_START: start.strftime('%Y-%m-%d %H:%M:%S'), - ATTR_END: end.strftime('%Y-%m-%d %H:%M:%S'), } @property @@ -172,13 +167,33 @@ class HistoryStatsSensor(Entity): def update(self): """Get the latest data and updates the states.""" + # Get previous values of start and end + p_start, p_end = self._period + # Parse templates self.update_period() start, end = self._period - # Convert to UTC + # Convert times to UTC start = dt_util.as_utc(start) end = dt_util.as_utc(end) + p_start = dt_util.as_utc(p_start) + p_end = dt_util.as_utc(p_end) + now = dt_util.as_utc(datetime.datetime.now()) + + # Compute integer timestamps + start_timestamp = math.floor(dt_util.as_timestamp(start)) + end_timestamp = math.floor(dt_util.as_timestamp(end)) + p_start_timestamp = math.floor(dt_util.as_timestamp(p_start)) + p_end_timestamp = math.floor(dt_util.as_timestamp(p_end)) + now_timestamp = math.floor(dt_util.as_timestamp(now)) + + # If period has not changed and current time after the period end... + if start_timestamp == p_start_timestamp and \ + end_timestamp == p_end_timestamp and \ + end_timestamp <= now_timestamp: + # Don't compute anything as the value cannot have changed + return # Get history between start and end history_list = history.state_changes_during_period( @@ -191,7 +206,7 @@ class HistoryStatsSensor(Entity): 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_time = dt_util.as_timestamp(start) + last_time = start_timestamp elapsed = 0 count = 0 @@ -210,8 +225,7 @@ class HistoryStatsSensor(Entity): # Count time elapsed between last history state and end of measure if last_state: - measure_end = min(dt_util.as_timestamp(end), dt_util.as_timestamp( - datetime.datetime.now())) + measure_end = min(end_timestamp, now_timestamp) elapsed += measure_end - last_time # Save value in hours @@ -279,13 +293,11 @@ class HistoryStatsHelper: hours, seconds = divmod(seconds, 3600) minutes, seconds = divmod(seconds, 60) if days > 0: - return '%dd %dh %dm %ds' % (days, hours, minutes, seconds) + return '%dd %dh %dm' % (days, hours, minutes) elif hours > 0: - return '%dh %dm %ds' % (hours, minutes, seconds) - elif minutes > 0: - return '%dm %ds' % (minutes, seconds) + return '%dh %dm' % (hours, minutes) else: - return '%ds' % (seconds,) + return '%dm' % minutes @staticmethod def pretty_ratio(value, period): diff --git a/tests/components/sensor/test_history_stats.py b/tests/components/sensor/test_history_stats.py index 282991fba0b..7fdf732825b 100644 --- a/tests/components/sensor/test_history_stats.py +++ b/tests/components/sensor/test_history_stats.py @@ -58,16 +58,29 @@ class TestHistoryStatsSensor(unittest.TestCase): self.hass, 'test', 'on', None, today, duration, 'time', 'test') sensor1.update_period() + sensor1_start, sensor1_end = sensor1._period sensor2.update_period() + sensor2_start, sensor2_end = sensor2._period - self.assertEqual( - sensor1.device_state_attributes['from'][-8:], '00:00:00') - self.assertEqual( - sensor1.device_state_attributes['to'][-8:], '02:01:00') - self.assertEqual( - sensor2.device_state_attributes['from'][-8:], '21:59:00') - self.assertEqual( - sensor2.device_state_attributes['to'][-8:], '00:00:00') + # Start = 00:00:00 + self.assertEqual(sensor1_start.hour, 0) + self.assertEqual(sensor1_start.minute, 0) + self.assertEqual(sensor1_start.second, 0) + + # End = 02:01:00 + self.assertEqual(sensor1_end.hour, 2) + self.assertEqual(sensor1_end.minute, 1) + self.assertEqual(sensor1_end.second, 0) + + # Start = 21:59:00 + self.assertEqual(sensor2_start.hour, 21) + self.assertEqual(sensor2_start.minute, 59) + self.assertEqual(sensor2_start.second, 0) + + # End = 00:00:00 + self.assertEqual(sensor2_end.hour, 0) + self.assertEqual(sensor2_end.minute, 0) + self.assertEqual(sensor2_end.second, 0) def test_measure(self): """Test the history statistics sensor measure."""