diff --git a/homeassistant/components/totalconnect/__init__.py b/homeassistant/components/totalconnect/__init__.py index 76e0a09af39..bb19697b1e7 100644 --- a/homeassistant/components/totalconnect/__init__.py +++ b/homeassistant/components/totalconnect/__init__.py @@ -1,29 +1,20 @@ """The totalconnect component.""" -from datetime import timedelta -import logging - from total_connect_client.client import TotalConnectClient -from total_connect_client.exceptions import ( - AuthenticationError, - ServiceUnavailable, - TotalConnectError, -) +from total_connect_client.exceptions import AuthenticationError from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import AUTO_BYPASS, CONF_USERCODES, DOMAIN +from .coordinator import TotalConnectDataUpdateCoordinator PLATFORMS = [Platform.ALARM_CONTROL_PANEL, Platform.BINARY_SENSOR, Platform.BUTTON] CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False) -SCAN_INTERVAL = timedelta(seconds=30) -_LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: @@ -76,41 +67,3 @@ async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: client = hass.data[DOMAIN][entry.entry_id].client for location_id in client.locations: client.locations[location_id].auto_bypass_low_battery = bypass - - -class TotalConnectDataUpdateCoordinator(DataUpdateCoordinator[None]): # pylint: disable=hass-enforce-coordinator-module - """Class to fetch data from TotalConnect.""" - - config_entry: ConfigEntry - - def __init__(self, hass: HomeAssistant, client: TotalConnectClient) -> None: - """Initialize.""" - self.hass = hass - self.client = client - super().__init__( - hass, logger=_LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL - ) - - async def _async_update_data(self) -> None: - """Update data.""" - await self.hass.async_add_executor_job(self.sync_update_data) - - def sync_update_data(self) -> None: - """Fetch synchronous data from TotalConnect.""" - try: - for location_id in self.client.locations: - self.client.locations[location_id].get_panel_meta_data() - except AuthenticationError as exception: - # should only encounter if password changes during operation - raise ConfigEntryAuthFailed( - "TotalConnect authentication failed during operation." - ) from exception - except ServiceUnavailable as exception: - raise UpdateFailed( - "Error connecting to TotalConnect or the service is unavailable. " - "Check https://status.resideo.com/ for outages." - ) from exception - except TotalConnectError as exception: - raise UpdateFailed(exception) from exception - except ValueError as exception: - raise UpdateFailed("Unknown state from TotalConnect") from exception diff --git a/homeassistant/components/totalconnect/alarm_control_panel.py b/homeassistant/components/totalconnect/alarm_control_panel.py index 1de9db1d319..511a0fd6270 100644 --- a/homeassistant/components/totalconnect/alarm_control_panel.py +++ b/homeassistant/components/totalconnect/alarm_control_panel.py @@ -26,8 +26,8 @@ from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_platform from homeassistant.helpers.entity_platform import AddEntitiesCallback -from . import TotalConnectDataUpdateCoordinator from .const import DOMAIN +from .coordinator import TotalConnectDataUpdateCoordinator from .entity import TotalConnectLocationEntity SERVICE_ALARM_ARM_AWAY_INSTANT = "arm_away_instant" diff --git a/homeassistant/components/totalconnect/binary_sensor.py b/homeassistant/components/totalconnect/binary_sensor.py index 85461805124..62f84b3b69a 100644 --- a/homeassistant/components/totalconnect/binary_sensor.py +++ b/homeassistant/components/totalconnect/binary_sensor.py @@ -17,8 +17,8 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from . import TotalConnectDataUpdateCoordinator from .const import DOMAIN +from .coordinator import TotalConnectDataUpdateCoordinator from .entity import TotalConnectLocationEntity, TotalConnectZoneEntity LOW_BATTERY = "low_battery" diff --git a/homeassistant/components/totalconnect/button.py b/homeassistant/components/totalconnect/button.py index ec2d0a604c7..fc5b5e89587 100644 --- a/homeassistant/components/totalconnect/button.py +++ b/homeassistant/components/totalconnect/button.py @@ -12,8 +12,8 @@ from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from . import TotalConnectDataUpdateCoordinator from .const import DOMAIN +from .coordinator import TotalConnectDataUpdateCoordinator from .entity import TotalConnectLocationEntity, TotalConnectZoneEntity diff --git a/homeassistant/components/totalconnect/coordinator.py b/homeassistant/components/totalconnect/coordinator.py new file mode 100644 index 00000000000..9b500db1951 --- /dev/null +++ b/homeassistant/components/totalconnect/coordinator.py @@ -0,0 +1,58 @@ +"""The totalconnect component.""" + +from datetime import timedelta +import logging + +from total_connect_client.client import TotalConnectClient +from total_connect_client.exceptions import ( + AuthenticationError, + ServiceUnavailable, + TotalConnectError, +) + +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.exceptions import ConfigEntryAuthFailed +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed + +from .const import DOMAIN + +SCAN_INTERVAL = timedelta(seconds=30) +_LOGGER = logging.getLogger(__name__) + + +class TotalConnectDataUpdateCoordinator(DataUpdateCoordinator[None]): + """Class to fetch data from TotalConnect.""" + + config_entry: ConfigEntry + + def __init__(self, hass: HomeAssistant, client: TotalConnectClient) -> None: + """Initialize.""" + self.client = client + super().__init__( + hass, logger=_LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL + ) + + async def _async_update_data(self) -> None: + """Update data.""" + await self.hass.async_add_executor_job(self.sync_update_data) + + def sync_update_data(self) -> None: + """Fetch synchronous data from TotalConnect.""" + try: + for location_id in self.client.locations: + self.client.locations[location_id].get_panel_meta_data() + except AuthenticationError as exception: + # should only encounter if password changes during operation + raise ConfigEntryAuthFailed( + "TotalConnect authentication failed during operation." + ) from exception + except ServiceUnavailable as exception: + raise UpdateFailed( + "Error connecting to TotalConnect or the service is unavailable. " + "Check https://status.resideo.com/ for outages." + ) from exception + except TotalConnectError as exception: + raise UpdateFailed(exception) from exception + except ValueError as exception: + raise UpdateFailed("Unknown state from TotalConnect") from exception diff --git a/homeassistant/components/totalconnect/entity.py b/homeassistant/components/totalconnect/entity.py index a18ffc14df5..e2b619ea500 100644 --- a/homeassistant/components/totalconnect/entity.py +++ b/homeassistant/components/totalconnect/entity.py @@ -6,7 +6,8 @@ from total_connect_client.zone import TotalConnectZone from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity -from . import DOMAIN, TotalConnectDataUpdateCoordinator +from .const import DOMAIN +from .coordinator import TotalConnectDataUpdateCoordinator class TotalConnectEntity(CoordinatorEntity[TotalConnectDataUpdateCoordinator]): diff --git a/tests/components/totalconnect/test_alarm_control_panel.py b/tests/components/totalconnect/test_alarm_control_panel.py index 176fe54c34a..055d3c5b863 100644 --- a/tests/components/totalconnect/test_alarm_control_panel.py +++ b/tests/components/totalconnect/test_alarm_control_panel.py @@ -8,11 +8,12 @@ from syrupy import SnapshotAssertion from total_connect_client.exceptions import ServiceUnavailable, TotalConnectError from homeassistant.components.alarm_control_panel import DOMAIN as ALARM_DOMAIN -from homeassistant.components.totalconnect import DOMAIN, SCAN_INTERVAL from homeassistant.components.totalconnect.alarm_control_panel import ( SERVICE_ALARM_ARM_AWAY_INSTANT, SERVICE_ALARM_ARM_HOME_INSTANT, ) +from homeassistant.components.totalconnect.const import DOMAIN +from homeassistant.components.totalconnect.coordinator import SCAN_INTERVAL from homeassistant.const import ( ATTR_ENTITY_ID, SERVICE_ALARM_ARM_AWAY,