mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Switch async_track_time_interval to use async_call_later internally (#99220)
This commit is contained in:
parent
821d74e904
commit
80d2309896
@ -1514,24 +1514,19 @@ def async_track_time_interval(
|
|||||||
"""Add a listener that fires repetitively at every timedelta interval."""
|
"""Add a listener that fires repetitively at every timedelta interval."""
|
||||||
remove: CALLBACK_TYPE
|
remove: CALLBACK_TYPE
|
||||||
interval_listener_job: HassJob[[datetime], None]
|
interval_listener_job: HassJob[[datetime], None]
|
||||||
|
interval_seconds = interval.total_seconds()
|
||||||
|
|
||||||
job = HassJob(
|
job = HassJob(
|
||||||
action, f"track time interval {interval}", cancel_on_shutdown=cancel_on_shutdown
|
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
|
@callback
|
||||||
def interval_listener(now: datetime) -> None:
|
def interval_listener(now: datetime) -> None:
|
||||||
"""Handle elapsed intervals."""
|
"""Handle elapsed intervals."""
|
||||||
nonlocal remove
|
nonlocal remove
|
||||||
nonlocal interval_listener_job
|
nonlocal interval_listener_job
|
||||||
|
|
||||||
remove = async_track_point_in_utc_time(
|
remove = async_call_later(hass, interval_seconds, interval_listener_job)
|
||||||
hass, interval_listener_job, next_interval()
|
|
||||||
)
|
|
||||||
hass.async_run_hass_job(job, now)
|
hass.async_run_hass_job(job, now)
|
||||||
|
|
||||||
if name:
|
if name:
|
||||||
@ -1542,7 +1537,7 @@ def async_track_time_interval(
|
|||||||
interval_listener_job = HassJob(
|
interval_listener_job = HassJob(
|
||||||
interval_listener, job_name, cancel_on_shutdown=cancel_on_shutdown
|
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:
|
def remove_listener() -> None:
|
||||||
"""Remove interval listener."""
|
"""Remove interval listener."""
|
||||||
|
@ -3,7 +3,7 @@ from collections.abc import Awaitable, Callable, Generator
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import AsyncMock, Mock, patch
|
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.client import Client
|
||||||
from gardena_bluetooth.const import DeviceInformation
|
from gardena_bluetooth.const import DeviceInformation
|
||||||
from gardena_bluetooth.exceptions import CharacteristicNotFound
|
from gardena_bluetooth.exceptions import CharacteristicNotFound
|
||||||
@ -49,19 +49,19 @@ def mock_read_char_raw():
|
|||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def scan_step(
|
async def scan_step(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant, freezer: FrozenDateTimeFactory
|
||||||
) -> Generator[None, None, Callable[[], Awaitable[None]]]:
|
) -> Generator[None, None, Callable[[], Awaitable[None]]]:
|
||||||
"""Step system time forward."""
|
"""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():
|
async def delay():
|
||||||
"""Trigger delay in system."""
|
"""Trigger delay in system."""
|
||||||
frozen_time.tick(delta=SCAN_INTERVAL)
|
freezer.tick(delta=SCAN_INTERVAL)
|
||||||
async_fire_time_changed(hass)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
yield delay
|
return delay
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
|
@ -5,11 +5,13 @@ from datetime import timedelta
|
|||||||
import logging
|
import logging
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
from pymodbus.exceptions import ModbusException
|
from pymodbus.exceptions import ModbusException
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.modbus.const import MODBUS_DOMAIN as DOMAIN, TCP
|
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.const import CONF_HOST, CONF_NAME, CONF_PORT, CONF_SLAVE, CONF_TYPE
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
import homeassistant.util.dt as dt_util
|
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")
|
@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."""
|
"""Trigger update call with time_changed event."""
|
||||||
now = dt_util.utcnow() + timedelta(seconds=90)
|
freezer.tick(timedelta(seconds=90))
|
||||||
with mock.patch(
|
async_fire_time_changed(hass)
|
||||||
"homeassistant.helpers.event.dt_util.utcnow", return_value=now, autospec=True
|
|
||||||
):
|
|
||||||
async_fire_time_changed(hass, now)
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
return now
|
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."""
|
"""Trigger update call with time_changed event."""
|
||||||
now += timedelta(seconds=cycle)
|
freezer.tick(timedelta(seconds=cycle))
|
||||||
with mock.patch(
|
async_fire_time_changed(hass)
|
||||||
"homeassistant.helpers.event.dt_util.utcnow", return_value=now, autospec=True
|
|
||||||
):
|
|
||||||
async_fire_time_changed(hass, now)
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
return now
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="mock_test_state")
|
@pytest.fixture(name="mock_test_state")
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""Thetests for the Modbus sensor component."""
|
"""Thetests for the Modbus sensor component."""
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.binary_sensor import DOMAIN as SENSOR_DOMAIN
|
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(
|
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:
|
) -> None:
|
||||||
"""Run test for given config."""
|
"""Run test for given config."""
|
||||||
now = mock_do_cycle
|
|
||||||
assert hass.states.get(ENTITY_ID).state == start_expect
|
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
|
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
|
assert hass.states.get(ENTITY_ID).state == end_expect
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""The tests for the Modbus climate component."""
|
"""The tests for the Modbus climate component."""
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.climate import DOMAIN as CLIMATE_DOMAIN
|
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(
|
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:
|
) -> None:
|
||||||
"""Run test for sensor."""
|
"""Run test for sensor."""
|
||||||
hass.states.async_set(ENTITY_ID, 17)
|
hass.states.async_set(ENTITY_ID, 17)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
now = mock_do_cycle
|
|
||||||
assert hass.states.get(ENTITY_ID).state == start_expect
|
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
|
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
|
assert hass.states.get(ENTITY_ID).state == end_expect
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""The tests for the Modbus cover component."""
|
"""The tests for the Modbus cover component."""
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
from pymodbus.exceptions import ModbusException
|
from pymodbus.exceptions import ModbusException
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -142,14 +143,13 @@ async def test_coil_cover(hass: HomeAssistant, expected, mock_do_cycle) -> None:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_lazy_error_cover(
|
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:
|
) -> None:
|
||||||
"""Run test for given config."""
|
"""Run test for given config."""
|
||||||
now = mock_do_cycle
|
|
||||||
assert hass.states.get(ENTITY_ID).state == start_expect
|
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
|
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
|
assert hass.states.get(ENTITY_ID).state == end_expect
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
"""The tests for the Modbus sensor component."""
|
"""The tests for the Modbus sensor component."""
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.modbus.const import (
|
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(
|
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:
|
) -> None:
|
||||||
"""Run test for sensor."""
|
"""Run test for sensor."""
|
||||||
hass.states.async_set(ENTITY_ID, 17)
|
hass.states.async_set(ENTITY_ID, 17)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
now = mock_do_cycle
|
|
||||||
assert hass.states.get(ENTITY_ID).state == start_expect
|
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
|
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
|
assert hass.states.get(ENTITY_ID).state == end_expect
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
from pymodbus.exceptions import ModbusException
|
from pymodbus.exceptions import ModbusException
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -237,14 +238,13 @@ async def test_all_switch(hass: HomeAssistant, mock_do_cycle, expected) -> None:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_lazy_error_switch(
|
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:
|
) -> None:
|
||||||
"""Run test for given config."""
|
"""Run test for given config."""
|
||||||
now = mock_do_cycle
|
|
||||||
assert hass.states.get(ENTITY_ID).state == start_expect
|
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
|
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
|
assert hass.states.get(ENTITY_ID).state == end_expect
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ from unittest.mock import patch
|
|||||||
|
|
||||||
from aiounifi.models.message import MessageKey
|
from aiounifi.models.message import MessageKey
|
||||||
from aiounifi.websocket import WebsocketState
|
from aiounifi.websocket import WebsocketState
|
||||||
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.components.device_tracker import DOMAIN as TRACKER_DOMAIN
|
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(
|
async def test_tracked_wireless_clients_event_source(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
aioclient_mock: AiohttpClientMocker,
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
mock_unifi_websocket,
|
mock_unifi_websocket,
|
||||||
mock_device_registry,
|
mock_device_registry,
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -234,9 +236,8 @@ async def test_tracked_wireless_clients_event_source(
|
|||||||
assert hass.states.get("device_tracker.client").state == STATE_HOME
|
assert hass.states.get("device_tracker.client").state == STATE_HOME
|
||||||
|
|
||||||
# Change time to mark client as away
|
# Change time to mark client as away
|
||||||
new_time = dt_util.utcnow() + controller.option_detection_time
|
freezer.tick(controller.option_detection_time + timedelta(seconds=1))
|
||||||
with patch("homeassistant.util.dt.utcnow", return_value=new_time):
|
async_fire_time_changed(hass)
|
||||||
async_fire_time_changed(hass, new_time)
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert hass.states.get("device_tracker.client").state == STATE_NOT_HOME
|
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
|
assert hass.states.get("device_tracker.client").state == STATE_HOME
|
||||||
|
|
||||||
# Change time to mark client as away
|
# Change time to mark client as away
|
||||||
new_time = dt_util.utcnow() + controller.option_detection_time
|
freezer.tick(controller.option_detection_time + timedelta(seconds=1))
|
||||||
with patch("homeassistant.util.dt.utcnow", return_value=new_time):
|
async_fire_time_changed(hass)
|
||||||
async_fire_time_changed(hass, new_time)
|
|
||||||
await hass.async_block_till_done()
|
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(
|
async def test_tracked_devices(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user