diff --git a/homeassistant/const.py b/homeassistant/const.py index c01a435ca85..4dcc171d35c 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -168,6 +168,7 @@ EVENT_SERVICE_REGISTERED = 'service_registered' EVENT_SERVICE_REMOVED = 'service_removed' EVENT_LOGBOOK_ENTRY = 'logbook_entry' EVENT_THEMES_UPDATED = 'themes_updated' +EVENT_TIMER_OUT_OF_SYNC = 'timer_out_of_sync' # #### DEVICE CLASSES #### DEVICE_CLASS_BATTERY = 'battery' @@ -216,6 +217,7 @@ ATTR_CREDENTIALS = 'credentials' ATTR_NOW = 'now' ATTR_DATE = 'date' ATTR_TIME = 'time' +ATTR_SECONDS = 'seconds' # Contains domain, service for a SERVICE_CALL event ATTR_DOMAIN = 'domain' diff --git a/homeassistant/core.py b/homeassistant/core.py index d1f811502e0..1754a8b5014 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -29,11 +29,11 @@ from voluptuous.humanize import humanize_error from homeassistant.const import ( ATTR_DOMAIN, ATTR_FRIENDLY_NAME, ATTR_NOW, ATTR_SERVICE, - ATTR_SERVICE_CALL_ID, ATTR_SERVICE_DATA, EVENT_CALL_SERVICE, + ATTR_SERVICE_CALL_ID, ATTR_SERVICE_DATA, ATTR_SECONDS, EVENT_CALL_SERVICE, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP, + EVENT_HOMEASSISTANT_CLOSE, EVENT_SERVICE_REMOVED, EVENT_SERVICE_EXECUTED, EVENT_SERVICE_REGISTERED, EVENT_STATE_CHANGED, - EVENT_TIME_CHANGED, MATCH_ALL, EVENT_HOMEASSISTANT_CLOSE, - EVENT_SERVICE_REMOVED, __version__) + EVENT_TIME_CHANGED, EVENT_TIMER_OUT_OF_SYNC, MATCH_ALL, __version__) from homeassistant import loader from homeassistant.exceptions import ( HomeAssistantError, InvalidEntityFormatError, InvalidStateError) @@ -1297,8 +1297,11 @@ def _async_create_timer(hass: HomeAssistant) -> None: hass.bus.async_fire(EVENT_TIME_CHANGED, {ATTR_NOW: now}) - if monotonic() > target + 1: - _LOGGER.error('Timer got out of sync. Resetting') + # If we are more than a second late, a tick was missed + late = monotonic() - target + if late > 1: + hass.bus.async_fire(EVENT_TIMER_OUT_OF_SYNC, + {ATTR_SECONDS: late}) schedule_tick(now) diff --git a/tests/test_core.py b/tests/test_core.py index d88257abfb4..7ab624447c5 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -19,9 +19,9 @@ import homeassistant.util.dt as dt_util from homeassistant.util.unit_system import (METRIC_SYSTEM) from homeassistant.const import ( __version__, EVENT_STATE_CHANGED, ATTR_FRIENDLY_NAME, CONF_UNIT_SYSTEM, - ATTR_NOW, EVENT_TIME_CHANGED, EVENT_HOMEASSISTANT_STOP, - EVENT_HOMEASSISTANT_CLOSE, EVENT_SERVICE_REGISTERED, EVENT_SERVICE_REMOVED, - EVENT_SERVICE_EXECUTED) + ATTR_NOW, EVENT_TIME_CHANGED, EVENT_TIMER_OUT_OF_SYNC, ATTR_SECONDS, + EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_CLOSE, + EVENT_SERVICE_REGISTERED, EVENT_SERVICE_REMOVED, EVENT_SERVICE_EXECUTED) from tests.common import get_test_home_assistant, async_mock_service @@ -916,12 +916,13 @@ def test_timer_out_of_sync(mock_monotonic, loop): delay, callback, target = hass.loop.call_later.mock_calls[0][1] - with patch.object(ha, '_LOGGER', MagicMock()) as mock_logger, \ - patch('homeassistant.core.dt_util.utcnow', - return_value=datetime(2018, 12, 31, 3, 4, 8, 200000)): + with patch('homeassistant.core.dt_util.utcnow', + return_value=datetime(2018, 12, 31, 3, 4, 8, 200000)): callback(target) - assert len(mock_logger.error.mock_calls) == 1 + event_type, event_data = hass.bus.async_fire.mock_calls[1][1] + assert event_type == EVENT_TIMER_OUT_OF_SYNC + assert abs(event_data[ATTR_SECONDS] - 2.433333) < 0.001 assert len(funcs) == 2 fire_time_event, stop_timer = funcs