diff --git a/homeassistant/components/modern_forms/__init__.py b/homeassistant/components/modern_forms/__init__.py index 5b33a85578c..a190eb26837 100644 --- a/homeassistant/components/modern_forms/__init__.py +++ b/homeassistant/components/modern_forms/__init__.py @@ -3,36 +3,25 @@ from __future__ import annotations from collections.abc import Callable, Coroutine -from datetime import timedelta import logging from typing import Any, Concatenate, ParamSpec, TypeVar -from aiomodernforms import ( - ModernFormsConnectionError, - ModernFormsDevice, - ModernFormsError, -) -from aiomodernforms.models import Device as ModernFormsDeviceState +from aiomodernforms import ModernFormsConnectionError, ModernFormsError from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.update_coordinator import ( - CoordinatorEntity, - DataUpdateCoordinator, - UpdateFailed, -) +from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN +from .coordinator import ModernFormsDataUpdateCoordinator _ModernFormsDeviceEntityT = TypeVar( "_ModernFormsDeviceEntityT", bound="ModernFormsDeviceEntity" ) _P = ParamSpec("_P") -SCAN_INTERVAL = timedelta(seconds=5) PLATFORMS = [ Platform.BINARY_SENSOR, Platform.FAN, @@ -99,37 +88,6 @@ def modernforms_exception_handler( return handler -class ModernFormsDataUpdateCoordinator(DataUpdateCoordinator[ModernFormsDeviceState]): # pylint: disable=hass-enforce-coordinator-module - """Class to manage fetching Modern Forms data from single endpoint.""" - - def __init__( - self, - hass: HomeAssistant, - *, - host: str, - ) -> None: - """Initialize global Modern Forms data updater.""" - self.modern_forms = ModernFormsDevice( - host, session=async_get_clientsession(hass) - ) - - super().__init__( - hass, - _LOGGER, - name=DOMAIN, - update_interval=SCAN_INTERVAL, - ) - - async def _async_update_data(self) -> ModernFormsDevice: - """Fetch data from Modern Forms.""" - try: - return await self.modern_forms.update( - full_update=not self.last_update_success - ) - except ModernFormsError as error: - raise UpdateFailed(f"Invalid response from API: {error}") from error - - class ModernFormsDeviceEntity(CoordinatorEntity[ModernFormsDataUpdateCoordinator]): """Defines a Modern Forms device entity.""" diff --git a/homeassistant/components/modern_forms/binary_sensor.py b/homeassistant/components/modern_forms/binary_sensor.py index 0322c5e39d7..5fb0096b477 100644 --- a/homeassistant/components/modern_forms/binary_sensor.py +++ b/homeassistant/components/modern_forms/binary_sensor.py @@ -8,8 +8,9 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.util import dt as dt_util -from . import ModernFormsDataUpdateCoordinator, ModernFormsDeviceEntity +from . import ModernFormsDeviceEntity from .const import CLEAR_TIMER, DOMAIN +from .coordinator import ModernFormsDataUpdateCoordinator async def async_setup_entry( diff --git a/homeassistant/components/modern_forms/coordinator.py b/homeassistant/components/modern_forms/coordinator.py new file mode 100644 index 00000000000..ecd928aa922 --- /dev/null +++ b/homeassistant/components/modern_forms/coordinator.py @@ -0,0 +1,49 @@ +"""Coordinator for the Modern Forms integration.""" + +from __future__ import annotations + +from datetime import timedelta +import logging + +from aiomodernforms import ModernFormsDevice, ModernFormsError +from aiomodernforms.models import Device as ModernFormsDeviceState + +from homeassistant.core import HomeAssistant +from homeassistant.helpers.aiohttp_client import async_get_clientsession +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed + +from .const import DOMAIN + +SCAN_INTERVAL = timedelta(seconds=5) +_LOGGER = logging.getLogger(__name__) + + +class ModernFormsDataUpdateCoordinator(DataUpdateCoordinator[ModernFormsDeviceState]): + """Class to manage fetching Modern Forms data from single endpoint.""" + + def __init__( + self, + hass: HomeAssistant, + *, + host: str, + ) -> None: + """Initialize global Modern Forms data updater.""" + self.modern_forms = ModernFormsDevice( + host, session=async_get_clientsession(hass) + ) + + super().__init__( + hass, + _LOGGER, + name=DOMAIN, + update_interval=SCAN_INTERVAL, + ) + + async def _async_update_data(self) -> ModernFormsDevice: + """Fetch data from Modern Forms.""" + try: + return await self.modern_forms.update( + full_update=not self.last_update_success + ) + except ModernFormsError as error: + raise UpdateFailed(f"Invalid response from API: {error}") from error diff --git a/homeassistant/components/modern_forms/fan.py b/homeassistant/components/modern_forms/fan.py index b714cf04879..5f6b699fb47 100644 --- a/homeassistant/components/modern_forms/fan.py +++ b/homeassistant/components/modern_forms/fan.py @@ -18,11 +18,7 @@ from homeassistant.util.percentage import ( ) from homeassistant.util.scaling import int_states_in_range -from . import ( - ModernFormsDataUpdateCoordinator, - ModernFormsDeviceEntity, - modernforms_exception_handler, -) +from . import ModernFormsDeviceEntity, modernforms_exception_handler from .const import ( ATTR_SLEEP_TIME, CLEAR_TIMER, @@ -32,6 +28,7 @@ from .const import ( SERVICE_CLEAR_FAN_SLEEP_TIMER, SERVICE_SET_FAN_SLEEP_TIMER, ) +from .coordinator import ModernFormsDataUpdateCoordinator async def async_setup_entry( diff --git a/homeassistant/components/modern_forms/light.py b/homeassistant/components/modern_forms/light.py index 3284b96d31f..e758a50e77e 100644 --- a/homeassistant/components/modern_forms/light.py +++ b/homeassistant/components/modern_forms/light.py @@ -17,11 +17,7 @@ from homeassistant.util.percentage import ( ranged_value_to_percentage, ) -from . import ( - ModernFormsDataUpdateCoordinator, - ModernFormsDeviceEntity, - modernforms_exception_handler, -) +from . import ModernFormsDeviceEntity, modernforms_exception_handler from .const import ( ATTR_SLEEP_TIME, CLEAR_TIMER, @@ -31,6 +27,7 @@ from .const import ( SERVICE_CLEAR_LIGHT_SLEEP_TIMER, SERVICE_SET_LIGHT_SLEEP_TIMER, ) +from .coordinator import ModernFormsDataUpdateCoordinator BRIGHTNESS_RANGE = (1, 255) diff --git a/homeassistant/components/modern_forms/sensor.py b/homeassistant/components/modern_forms/sensor.py index 6a92f0fcac2..851e3092ce5 100644 --- a/homeassistant/components/modern_forms/sensor.py +++ b/homeassistant/components/modern_forms/sensor.py @@ -11,8 +11,9 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.util import dt as dt_util -from . import ModernFormsDataUpdateCoordinator, ModernFormsDeviceEntity +from . import ModernFormsDeviceEntity from .const import CLEAR_TIMER, DOMAIN +from .coordinator import ModernFormsDataUpdateCoordinator async def async_setup_entry( diff --git a/homeassistant/components/modern_forms/switch.py b/homeassistant/components/modern_forms/switch.py index d8c76d733fc..a80115c0f93 100644 --- a/homeassistant/components/modern_forms/switch.py +++ b/homeassistant/components/modern_forms/switch.py @@ -9,12 +9,9 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from . import ( - ModernFormsDataUpdateCoordinator, - ModernFormsDeviceEntity, - modernforms_exception_handler, -) +from . import ModernFormsDeviceEntity, modernforms_exception_handler from .const import DOMAIN +from .coordinator import ModernFormsDataUpdateCoordinator async def async_setup_entry( diff --git a/tests/components/modern_forms/test_config_flow.py b/tests/components/modern_forms/test_config_flow.py index 56c293b241a..4c39f83f688 100644 --- a/tests/components/modern_forms/test_config_flow.py +++ b/tests/components/modern_forms/test_config_flow.py @@ -102,7 +102,7 @@ async def test_full_zeroconf_flow_implementation( @patch( - "homeassistant.components.modern_forms.ModernFormsDevice.update", + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.update", side_effect=ModernFormsConnectionError, ) async def test_connection_error( @@ -123,7 +123,7 @@ async def test_connection_error( @patch( - "homeassistant.components.modern_forms.ModernFormsDevice.update", + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.update", side_effect=ModernFormsConnectionError, ) async def test_zeroconf_connection_error( @@ -151,7 +151,7 @@ async def test_zeroconf_connection_error( @patch( - "homeassistant.components.modern_forms.ModernFormsDevice.update", + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.update", side_effect=ModernFormsConnectionError, ) async def test_zeroconf_confirm_connection_error( diff --git a/tests/components/modern_forms/test_fan.py b/tests/components/modern_forms/test_fan.py index 82ab6407c12..a1558be981c 100644 --- a/tests/components/modern_forms/test_fan.py +++ b/tests/components/modern_forms/test_fan.py @@ -191,7 +191,9 @@ async def test_fan_error( aioclient_mock.post("http://192.168.1.123:80/mf", text="", status=400) - with patch("homeassistant.components.modern_forms.ModernFormsDevice.update"): + with patch( + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.update" + ): await hass.services.async_call( FAN_DOMAIN, SERVICE_TURN_OFF, @@ -211,9 +213,11 @@ async def test_fan_connection_error( await init_integration(hass, aioclient_mock) with ( - patch("homeassistant.components.modern_forms.ModernFormsDevice.update"), patch( - "homeassistant.components.modern_forms.ModernFormsDevice.fan", + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.update" + ), + patch( + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.fan", side_effect=ModernFormsConnectionError, ), ): diff --git a/tests/components/modern_forms/test_init.py b/tests/components/modern_forms/test_init.py index 4f146dfcea5..0fb7c1d2931 100644 --- a/tests/components/modern_forms/test_init.py +++ b/tests/components/modern_forms/test_init.py @@ -15,7 +15,7 @@ from tests.test_util.aiohttp import AiohttpClientMocker @patch( - "homeassistant.components.modern_forms.ModernFormsDevice.update", + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.update", side_effect=ModernFormsConnectionError, ) async def test_config_entry_not_ready( diff --git a/tests/components/modern_forms/test_light.py b/tests/components/modern_forms/test_light.py index 3b1cfdd90d2..0fa2a53f447 100644 --- a/tests/components/modern_forms/test_light.py +++ b/tests/components/modern_forms/test_light.py @@ -119,7 +119,9 @@ async def test_light_error( aioclient_mock.post("http://192.168.1.123:80/mf", text="", status=400) - with patch("homeassistant.components.modern_forms.ModernFormsDevice.update"): + with patch( + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.update" + ): await hass.services.async_call( LIGHT_DOMAIN, SERVICE_TURN_OFF, @@ -139,9 +141,11 @@ async def test_light_connection_error( await init_integration(hass, aioclient_mock) with ( - patch("homeassistant.components.modern_forms.ModernFormsDevice.update"), patch( - "homeassistant.components.modern_forms.ModernFormsDevice.light", + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.update" + ), + patch( + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.light", side_effect=ModernFormsConnectionError, ), ): diff --git a/tests/components/modern_forms/test_switch.py b/tests/components/modern_forms/test_switch.py index 8a2012bbd5f..d9e5443c06b 100644 --- a/tests/components/modern_forms/test_switch.py +++ b/tests/components/modern_forms/test_switch.py @@ -110,7 +110,9 @@ async def test_switch_error( aioclient_mock.clear_requests() aioclient_mock.post("http://192.168.1.123:80/mf", text="", status=400) - with patch("homeassistant.components.modern_forms.ModernFormsDevice.update"): + with patch( + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.update" + ): await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_ON, @@ -131,9 +133,11 @@ async def test_switch_connection_error( await init_integration(hass, aioclient_mock) with ( - patch("homeassistant.components.modern_forms.ModernFormsDevice.update"), patch( - "homeassistant.components.modern_forms.ModernFormsDevice.away", + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.update" + ), + patch( + "homeassistant.components.modern_forms.coordinator.ModernFormsDevice.away", side_effect=ModernFormsConnectionError, ), ):