diff --git a/homeassistant/helpers/event.py b/homeassistant/helpers/event.py index 11bfe04473a..14ba4953694 100644 --- a/homeassistant/helpers/event.py +++ b/homeassistant/helpers/event.py @@ -1514,24 +1514,19 @@ def async_track_time_interval( """Add a listener that fires repetitively at every timedelta interval.""" remove: CALLBACK_TYPE interval_listener_job: HassJob[[datetime], None] + interval_seconds = interval.total_seconds() job = HassJob( action, f"track time interval {interval}", cancel_on_shutdown=cancel_on_shutdown ) - def next_interval() -> datetime: - """Return the next interval.""" - return dt_util.utcnow() + interval - @callback def interval_listener(now: datetime) -> None: """Handle elapsed intervals.""" nonlocal remove nonlocal interval_listener_job - remove = async_track_point_in_utc_time( - hass, interval_listener_job, next_interval() - ) + remove = async_call_later(hass, interval_seconds, interval_listener_job) hass.async_run_hass_job(job, now) if name: @@ -1542,7 +1537,7 @@ def async_track_time_interval( interval_listener_job = HassJob( interval_listener, job_name, cancel_on_shutdown=cancel_on_shutdown ) - remove = async_track_point_in_utc_time(hass, interval_listener_job, next_interval()) + remove = async_call_later(hass, interval_seconds, interval_listener_job) def remove_listener() -> None: """Remove interval listener.""" diff --git a/tests/components/gardena_bluetooth/conftest.py b/tests/components/gardena_bluetooth/conftest.py index 98ae41d195b..9395d8570e6 100644 --- a/tests/components/gardena_bluetooth/conftest.py +++ b/tests/components/gardena_bluetooth/conftest.py @@ -3,7 +3,7 @@ from collections.abc import Awaitable, Callable, Generator from typing import Any from unittest.mock import AsyncMock, Mock, patch -from freezegun import freeze_time +from freezegun.api import FrozenDateTimeFactory from gardena_bluetooth.client import Client from gardena_bluetooth.const import DeviceInformation from gardena_bluetooth.exceptions import CharacteristicNotFound @@ -49,19 +49,19 @@ def mock_read_char_raw(): @pytest.fixture async def scan_step( - hass: HomeAssistant, + hass: HomeAssistant, freezer: FrozenDateTimeFactory ) -> Generator[None, None, Callable[[], Awaitable[None]]]: """Step system time forward.""" - with freeze_time("2023-01-01", tz_offset=1) as frozen_time: + freezer.move_to("2023-01-01T01:00:00Z") - async def delay(): - """Trigger delay in system.""" - frozen_time.tick(delta=SCAN_INTERVAL) - async_fire_time_changed(hass) - await hass.async_block_till_done() + async def delay(): + """Trigger delay in system.""" + freezer.tick(delta=SCAN_INTERVAL) + async_fire_time_changed(hass) + await hass.async_block_till_done() - yield delay + return delay @pytest.fixture(autouse=True) diff --git a/tests/components/modbus/conftest.py b/tests/components/modbus/conftest.py index 21c5f4ddb25..23d3ee522bb 100644 --- a/tests/components/modbus/conftest.py +++ b/tests/components/modbus/conftest.py @@ -5,11 +5,13 @@ from datetime import timedelta import logging from unittest import mock +from freezegun.api import FrozenDateTimeFactory from pymodbus.exceptions import ModbusException import pytest from homeassistant.components.modbus.const import MODBUS_DOMAIN as DOMAIN, TCP from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, CONF_SLAVE, CONF_TYPE +from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util @@ -140,26 +142,26 @@ async def mock_pymodbus_return_fixture(hass, register_words, mock_modbus): @pytest.fixture(name="mock_do_cycle") -async def mock_do_cycle_fixture(hass, mock_pymodbus_exception, mock_pymodbus_return): +async def mock_do_cycle_fixture( + hass: HomeAssistant, + freezer: FrozenDateTimeFactory, + mock_pymodbus_exception, + mock_pymodbus_return, +) -> FrozenDateTimeFactory: """Trigger update call with time_changed event.""" - now = dt_util.utcnow() + timedelta(seconds=90) - with mock.patch( - "homeassistant.helpers.event.dt_util.utcnow", return_value=now, autospec=True - ): - async_fire_time_changed(hass, now) - await hass.async_block_till_done() - return now + freezer.tick(timedelta(seconds=90)) + async_fire_time_changed(hass) + await hass.async_block_till_done() + return freezer -async def do_next_cycle(hass, now, cycle): +async def do_next_cycle( + hass: HomeAssistant, freezer: FrozenDateTimeFactory, cycle: int +) -> None: """Trigger update call with time_changed event.""" - now += timedelta(seconds=cycle) - with mock.patch( - "homeassistant.helpers.event.dt_util.utcnow", return_value=now, autospec=True - ): - async_fire_time_changed(hass, now) - await hass.async_block_till_done() - return now + freezer.tick(timedelta(seconds=cycle)) + async_fire_time_changed(hass) + await hass.async_block_till_done() @pytest.fixture(name="mock_test_state") diff --git a/tests/components/modbus/test_binary_sensor.py b/tests/components/modbus/test_binary_sensor.py index 5c4535f9f29..1e413fcc764 100644 --- a/tests/components/modbus/test_binary_sensor.py +++ b/tests/components/modbus/test_binary_sensor.py @@ -1,4 +1,5 @@ """Thetests for the Modbus sensor component.""" +from freezegun.api import FrozenDateTimeFactory import pytest from homeassistant.components.binary_sensor import DOMAIN as SENSOR_DOMAIN @@ -199,14 +200,13 @@ async def test_all_binary_sensor(hass: HomeAssistant, expected, mock_do_cycle) - ], ) async def test_lazy_error_binary_sensor( - hass: HomeAssistant, start_expect, end_expect, mock_do_cycle + hass: HomeAssistant, start_expect, end_expect, mock_do_cycle: FrozenDateTimeFactory ) -> None: """Run test for given config.""" - now = mock_do_cycle assert hass.states.get(ENTITY_ID).state == start_expect - now = await do_next_cycle(hass, now, 11) + await do_next_cycle(hass, mock_do_cycle, 11) assert hass.states.get(ENTITY_ID).state == start_expect - now = await do_next_cycle(hass, now, 11) + await do_next_cycle(hass, mock_do_cycle, 11) assert hass.states.get(ENTITY_ID).state == end_expect diff --git a/tests/components/modbus/test_climate.py b/tests/components/modbus/test_climate.py index ce43cf7c1d2..4ab78df0c81 100644 --- a/tests/components/modbus/test_climate.py +++ b/tests/components/modbus/test_climate.py @@ -1,4 +1,5 @@ """The tests for the Modbus climate component.""" +from freezegun.api import FrozenDateTimeFactory import pytest from homeassistant.components.climate import DOMAIN as CLIMATE_DOMAIN @@ -597,16 +598,15 @@ async def test_restore_state_climate( ], ) async def test_lazy_error_climate( - hass: HomeAssistant, mock_do_cycle, start_expect, end_expect + hass: HomeAssistant, mock_do_cycle: FrozenDateTimeFactory, start_expect, end_expect ) -> None: """Run test for sensor.""" hass.states.async_set(ENTITY_ID, 17) await hass.async_block_till_done() - now = mock_do_cycle assert hass.states.get(ENTITY_ID).state == start_expect - now = await do_next_cycle(hass, now, 11) + await do_next_cycle(hass, mock_do_cycle, 11) assert hass.states.get(ENTITY_ID).state == start_expect - now = await do_next_cycle(hass, now, 11) + await do_next_cycle(hass, mock_do_cycle, 11) assert hass.states.get(ENTITY_ID).state == end_expect diff --git a/tests/components/modbus/test_cover.py b/tests/components/modbus/test_cover.py index 4ec1b9d7bfc..66e4537d67e 100644 --- a/tests/components/modbus/test_cover.py +++ b/tests/components/modbus/test_cover.py @@ -1,4 +1,5 @@ """The tests for the Modbus cover component.""" +from freezegun.api import FrozenDateTimeFactory from pymodbus.exceptions import ModbusException import pytest @@ -142,14 +143,13 @@ async def test_coil_cover(hass: HomeAssistant, expected, mock_do_cycle) -> None: ], ) async def test_lazy_error_cover( - hass: HomeAssistant, start_expect, end_expect, mock_do_cycle + hass: HomeAssistant, start_expect, end_expect, mock_do_cycle: FrozenDateTimeFactory ) -> None: """Run test for given config.""" - now = mock_do_cycle assert hass.states.get(ENTITY_ID).state == start_expect - now = await do_next_cycle(hass, now, 11) + await do_next_cycle(hass, mock_do_cycle, 11) assert hass.states.get(ENTITY_ID).state == start_expect - now = await do_next_cycle(hass, now, 11) + await do_next_cycle(hass, mock_do_cycle, 11) assert hass.states.get(ENTITY_ID).state == end_expect diff --git a/tests/components/modbus/test_sensor.py b/tests/components/modbus/test_sensor.py index 8481adc0d0f..f72371ed42e 100644 --- a/tests/components/modbus/test_sensor.py +++ b/tests/components/modbus/test_sensor.py @@ -1,4 +1,5 @@ """The tests for the Modbus sensor component.""" +from freezegun.api import FrozenDateTimeFactory import pytest from homeassistant.components.modbus.const import ( @@ -928,16 +929,15 @@ async def test_wrong_unpack(hass: HomeAssistant, mock_do_cycle) -> None: ], ) async def test_lazy_error_sensor( - hass: HomeAssistant, mock_do_cycle, start_expect, end_expect + hass: HomeAssistant, mock_do_cycle: FrozenDateTimeFactory, start_expect, end_expect ) -> None: """Run test for sensor.""" hass.states.async_set(ENTITY_ID, 17) await hass.async_block_till_done() - now = mock_do_cycle assert hass.states.get(ENTITY_ID).state == start_expect - now = await do_next_cycle(hass, now, 11) + await do_next_cycle(hass, mock_do_cycle, 11) assert hass.states.get(ENTITY_ID).state == start_expect - now = await do_next_cycle(hass, now, 11) + await do_next_cycle(hass, mock_do_cycle, 11) assert hass.states.get(ENTITY_ID).state == end_expect diff --git a/tests/components/modbus/test_switch.py b/tests/components/modbus/test_switch.py index 2e2f0081eba..dce4588d606 100644 --- a/tests/components/modbus/test_switch.py +++ b/tests/components/modbus/test_switch.py @@ -2,6 +2,7 @@ from datetime import timedelta from unittest import mock +from freezegun.api import FrozenDateTimeFactory from pymodbus.exceptions import ModbusException import pytest @@ -237,14 +238,13 @@ async def test_all_switch(hass: HomeAssistant, mock_do_cycle, expected) -> None: ], ) async def test_lazy_error_switch( - hass: HomeAssistant, start_expect, end_expect, mock_do_cycle + hass: HomeAssistant, start_expect, end_expect, mock_do_cycle: FrozenDateTimeFactory ) -> None: """Run test for given config.""" - now = mock_do_cycle assert hass.states.get(ENTITY_ID).state == start_expect - now = await do_next_cycle(hass, now, 11) + await do_next_cycle(hass, mock_do_cycle, 11) assert hass.states.get(ENTITY_ID).state == start_expect - now = await do_next_cycle(hass, now, 11) + await do_next_cycle(hass, mock_do_cycle, 11) assert hass.states.get(ENTITY_ID).state == end_expect diff --git a/tests/components/unifi/test_device_tracker.py b/tests/components/unifi/test_device_tracker.py index 16432ff514e..7b939077e48 100644 --- a/tests/components/unifi/test_device_tracker.py +++ b/tests/components/unifi/test_device_tracker.py @@ -4,6 +4,7 @@ from unittest.mock import patch from aiounifi.models.message import MessageKey from aiounifi.websocket import WebsocketState +from freezegun.api import FrozenDateTimeFactory from homeassistant import config_entries from homeassistant.components.device_tracker import DOMAIN as TRACKER_DOMAIN @@ -169,6 +170,7 @@ async def test_tracked_clients( async def test_tracked_wireless_clients_event_source( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, + freezer: FrozenDateTimeFactory, mock_unifi_websocket, mock_device_registry, ) -> None: @@ -234,10 +236,9 @@ async def test_tracked_wireless_clients_event_source( assert hass.states.get("device_tracker.client").state == STATE_HOME # Change time to mark client as away - new_time = dt_util.utcnow() + controller.option_detection_time - with patch("homeassistant.util.dt.utcnow", return_value=new_time): - async_fire_time_changed(hass, new_time) - await hass.async_block_till_done() + freezer.tick(controller.option_detection_time + timedelta(seconds=1)) + async_fire_time_changed(hass) + await hass.async_block_till_done() assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME @@ -274,12 +275,11 @@ async def test_tracked_wireless_clients_event_source( assert hass.states.get("device_tracker.client").state == STATE_HOME # Change time to mark client as away - new_time = dt_util.utcnow() + controller.option_detection_time - with patch("homeassistant.util.dt.utcnow", return_value=new_time): - async_fire_time_changed(hass, new_time) - await hass.async_block_till_done() + freezer.tick(controller.option_detection_time + timedelta(seconds=1)) + async_fire_time_changed(hass) + await hass.async_block_till_done() - assert hass.states.get("device_tracker.client").state == STATE_HOME + assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME async def test_tracked_devices(