From 04fc3a1f25e387103ee8a6e86f6dc3b037787428 Mon Sep 17 00:00:00 2001 From: Patrik Lindgren <21142447+ggravlingen@users.noreply.github.com> Date: Tue, 5 Apr 2022 14:00:45 +0200 Subject: [PATCH] Cleanup constants in Tradfri integration (#69125) Co-authored-by: Martin Hjelmare --- homeassistant/components/tradfri/__init__.py | 43 +++++++++--------- .../components/tradfri/base_class.py | 7 +-- .../components/tradfri/config_flow.py | 12 ++--- homeassistant/components/tradfri/const.py | 44 +++---------------- .../components/tradfri/coordinator.py | 9 ++-- homeassistant/components/tradfri/cover.py | 11 +---- homeassistant/components/tradfri/fan.py | 13 ++---- homeassistant/components/tradfri/light.py | 41 ++++++++--------- homeassistant/components/tradfri/sensor.py | 11 ++--- tests/components/tradfri/test_init.py | 12 ++--- 10 files changed, 70 insertions(+), 133 deletions(-) diff --git a/homeassistant/components/tradfri/__init__.py b/homeassistant/components/tradfri/__init__.py index 26637f500ac..e4d13568e6d 100644 --- a/homeassistant/components/tradfri/__init__.py +++ b/homeassistant/components/tradfri/__init__.py @@ -2,7 +2,6 @@ from __future__ import annotations from datetime import datetime, timedelta -import logging from typing import Any from pytradfri import Gateway, RequestError @@ -11,7 +10,7 @@ from pytradfri.command import Command from pytradfri.device import Device from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_HOST, EVENT_HOMEASSISTANT_STOP +from homeassistant.const import CONF_HOST, EVENT_HOMEASSISTANT_STOP, Platform from homeassistant.core import Event, HomeAssistant, callback from homeassistant.exceptions import ConfigEntryNotReady import homeassistant.helpers.config_validation as cv @@ -23,28 +22,28 @@ from homeassistant.helpers.dispatcher import ( from homeassistant.helpers.event import async_track_time_interval from .const import ( - ATTR_TRADFRI_GATEWAY, - ATTR_TRADFRI_GATEWAY_MODEL, - ATTR_TRADFRI_MANUFACTURER, CONF_GATEWAY_ID, CONF_IDENTITY, CONF_KEY, COORDINATOR, COORDINATOR_LIST, DOMAIN, + FACTORY, KEY_API, - PLATFORMS, - SIGNAL_GW, - TIMEOUT_API, + LOGGER, ) from .coordinator import TradfriDeviceDataUpdateCoordinator -_LOGGER = logging.getLogger(__name__) - -FACTORY = "tradfri_factory" -LISTENERS = "tradfri_listeners" - CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False) +PLATFORMS = [ + Platform.COVER, + Platform.FAN, + Platform.LIGHT, + Platform.SENSOR, + Platform.SWITCH, +] +SIGNAL_GW = "tradfri.gw_status" +TIMEOUT_API = 30 async def async_setup_entry( @@ -54,7 +53,6 @@ async def async_setup_entry( """Create a gateway.""" tradfri_data: dict[str, Any] = {} hass.data.setdefault(DOMAIN, {})[entry.entry_id] = tradfri_data - listeners = tradfri_data[LISTENERS] = [] factory = await APIFactory.init( entry.data[CONF_HOST], @@ -68,7 +66,9 @@ async def async_setup_entry( await factory.shutdown() # Setup listeners - listeners.append(hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, on_hass_stop)) + entry.async_on_unload( + hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, on_hass_stop) + ) api = factory.request gateway = Gateway() @@ -89,10 +89,10 @@ async def async_setup_entry( config_entry_id=entry.entry_id, connections=set(), identifiers={(DOMAIN, entry.data[CONF_GATEWAY_ID])}, - manufacturer=ATTR_TRADFRI_MANUFACTURER, - name=ATTR_TRADFRI_GATEWAY, + manufacturer="IKEA of Sweden", + name="Gateway", # They just have 1 gateway model. Type is not exposed yet. - model=ATTR_TRADFRI_GATEWAY_MODEL, + model="E1526", sw_version=gateway_info.firmware_version, ) @@ -126,12 +126,12 @@ async def async_setup_entry( try: await api(gateway.get_gateway_info()) except RequestError: - _LOGGER.error("Keep-alive failed") + LOGGER.error("Keep-alive failed") gw_status = False async_dispatcher_send(hass, SIGNAL_GW, gw_status) - listeners.append( + entry.async_on_unload( async_track_time_interval(hass, async_keep_alive, timedelta(seconds=60)) ) @@ -147,9 +147,6 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: tradfri_data = hass.data[DOMAIN].pop(entry.entry_id) factory = tradfri_data[FACTORY] await factory.shutdown() - # unsubscribe listeners - for listener in tradfri_data[LISTENERS]: - listener() return unload_ok diff --git a/homeassistant/components/tradfri/base_class.py b/homeassistant/components/tradfri/base_class.py index 727e611dca4..bd1968dfd15 100644 --- a/homeassistant/components/tradfri/base_class.py +++ b/homeassistant/components/tradfri/base_class.py @@ -4,7 +4,6 @@ from __future__ import annotations from abc import abstractmethod from collections.abc import Callable from functools import wraps -import logging from typing import Any, cast from pytradfri.command import Command @@ -15,11 +14,9 @@ from homeassistant.core import callback from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DOMAIN +from .const import DOMAIN, LOGGER from .coordinator import TradfriDeviceDataUpdateCoordinator -_LOGGER = logging.getLogger(__name__) - def handle_error( func: Callable[[Command | list[Command]], Any] @@ -32,7 +29,7 @@ def handle_error( try: await func(command) except RequestError as err: - _LOGGER.error("Unable to execute command %s: %s", command, err) + LOGGER.error("Unable to execute command %s: %s", command, err) return wrapper diff --git a/homeassistant/components/tradfri/config_flow.py b/homeassistant/components/tradfri/config_flow.py index d39eef864be..940c53c2df2 100644 --- a/homeassistant/components/tradfri/config_flow.py +++ b/homeassistant/components/tradfri/config_flow.py @@ -16,14 +16,10 @@ from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResult -from .const import ( - CONF_GATEWAY_ID, - CONF_IDENTITY, - CONF_IMPORT_GROUPS, - CONF_KEY, - DOMAIN, - KEY_SECURITY_CODE, -) +from .const import CONF_GATEWAY_ID, CONF_IDENTITY, CONF_KEY, DOMAIN + +CONF_IMPORT_GROUPS = "import_groups" +KEY_SECURITY_CODE = "security_code" class AuthError(Exception): diff --git a/homeassistant/components/tradfri/const.py b/homeassistant/components/tradfri/const.py index d3f04f4e2c4..23b97efedd5 100644 --- a/homeassistant/components/tradfri/const.py +++ b/homeassistant/components/tradfri/const.py @@ -1,45 +1,13 @@ """Consts used by Tradfri.""" -from typing import Final +import logging -from homeassistant.components.light import SUPPORT_TRANSITION -from homeassistant.const import ( # noqa: F401 pylint: disable=unused-import - CONF_HOST, - Platform, -) +LOGGER = logging.getLogger(__package__) -ATTR_AUTO = "Auto" -ATTR_DIMMER = "dimmer" -ATTR_HUE = "hue" -ATTR_SAT = "saturation" -ATTR_TRADFRI_GATEWAY = "Gateway" -ATTR_TRADFRI_GATEWAY_MODEL = "E1526" -ATTR_TRADFRI_MANUFACTURER = "IKEA of Sweden" -ATTR_TRANSITION_TIME = "transition_time" -ATTR_MODEL = "model" -CONF_IDENTITY = "identity" -CONF_IMPORT_GROUPS = "import_groups" CONF_GATEWAY_ID = "gateway_id" +CONF_IDENTITY = "identity" CONF_KEY = "key" - -DOMAIN = "tradfri" -KEY_API = "tradfri_api" -DEVICES = "tradfri_devices" -SIGNAL_GW = "tradfri.gw_status" -KEY_SECURITY_CODE = "security_code" -SUPPORTED_LIGHT_FEATURES = SUPPORT_TRANSITION -PLATFORMS = [ - Platform.COVER, - Platform.FAN, - Platform.LIGHT, - Platform.SENSOR, - Platform.SWITCH, -] -TIMEOUT_API = 30 -ATTR_MAX_FAN_STEPS = 49 - -SCAN_INTERVAL = 60 # Interval for updating the coordinator - COORDINATOR = "coordinator" COORDINATOR_LIST = "coordinator_list" - -ATTR_FILTER_LIFE_REMAINING: Final = "filter_life_remaining" +DOMAIN = "tradfri" +FACTORY = "tradfri_factory" +KEY_API = "tradfri_api" diff --git a/homeassistant/components/tradfri/coordinator.py b/homeassistant/components/tradfri/coordinator.py index 8aed96d344f..0d90b4ee28c 100644 --- a/homeassistant/components/tradfri/coordinator.py +++ b/homeassistant/components/tradfri/coordinator.py @@ -3,7 +3,6 @@ from __future__ import annotations from collections.abc import Callable from datetime import timedelta -import logging from typing import Any from pytradfri.command import Command @@ -13,9 +12,9 @@ from pytradfri.error import RequestError from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed -from .const import SCAN_INTERVAL +from .const import LOGGER -_LOGGER = logging.getLogger(__name__) +SCAN_INTERVAL = 60 # Interval for updating the coordinator class TradfriDeviceDataUpdateCoordinator(DataUpdateCoordinator[Device]): @@ -35,7 +34,7 @@ class TradfriDeviceDataUpdateCoordinator(DataUpdateCoordinator[Device]): super().__init__( hass, - _LOGGER, + LOGGER, name=f"Update coordinator for {device}", update_interval=timedelta(seconds=SCAN_INTERVAL), ) @@ -62,7 +61,7 @@ class TradfriDeviceDataUpdateCoordinator(DataUpdateCoordinator[Device]): # Store exception so that it gets raised in _async_update_data self._exception = exc - _LOGGER.debug( + LOGGER.debug( "Observation failed for %s, trying again", self.device, exc_info=exc ) # Change interval so we get a swift refresh diff --git a/homeassistant/components/tradfri/cover.py b/homeassistant/components/tradfri/cover.py index d4c3063f35d..976a48906fc 100644 --- a/homeassistant/components/tradfri/cover.py +++ b/homeassistant/components/tradfri/cover.py @@ -12,14 +12,7 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .base_class import TradfriBaseEntity -from .const import ( - ATTR_MODEL, - CONF_GATEWAY_ID, - COORDINATOR, - COORDINATOR_LIST, - DOMAIN, - KEY_API, -) +from .const import CONF_GATEWAY_ID, COORDINATOR, COORDINATOR_LIST, DOMAIN, KEY_API from .coordinator import TradfriDeviceDataUpdateCoordinator @@ -70,7 +63,7 @@ class TradfriCover(TradfriBaseEntity, CoverEntity): @property def extra_state_attributes(self) -> dict[str, str] | None: """Return the state attributes.""" - return {ATTR_MODEL: self._device.device_info.model_number} + return {"model": self._device.device_info.model_number} @property def current_cover_position(self) -> int | None: diff --git a/homeassistant/components/tradfri/fan.py b/homeassistant/components/tradfri/fan.py index ed478025405..5c5688edd4c 100644 --- a/homeassistant/components/tradfri/fan.py +++ b/homeassistant/components/tradfri/fan.py @@ -17,17 +17,12 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .base_class import TradfriBaseEntity -from .const import ( - ATTR_AUTO, - ATTR_MAX_FAN_STEPS, - CONF_GATEWAY_ID, - COORDINATOR, - COORDINATOR_LIST, - DOMAIN, - KEY_API, -) +from .const import CONF_GATEWAY_ID, COORDINATOR, COORDINATOR_LIST, DOMAIN, KEY_API from .coordinator import TradfriDeviceDataUpdateCoordinator +ATTR_AUTO = "Auto" +ATTR_MAX_FAN_STEPS = 49 + def _from_fan_percentage(percentage: int) -> int: """Convert percent to a value that the Tradfri API understands.""" diff --git a/homeassistant/components/tradfri/light.py b/homeassistant/components/tradfri/light.py index 506343d3d4d..99c4350c9b8 100644 --- a/homeassistant/components/tradfri/light.py +++ b/homeassistant/components/tradfri/light.py @@ -14,6 +14,7 @@ from homeassistant.components.light import ( SUPPORT_BRIGHTNESS, SUPPORT_COLOR, SUPPORT_COLOR_TEMP, + SUPPORT_TRANSITION, LightEntity, ) from homeassistant.config_entries import ConfigEntry @@ -22,20 +23,11 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback import homeassistant.util.color as color_util from .base_class import TradfriBaseEntity -from .const import ( - ATTR_DIMMER, - ATTR_HUE, - ATTR_SAT, - ATTR_TRANSITION_TIME, - CONF_GATEWAY_ID, - COORDINATOR, - COORDINATOR_LIST, - DOMAIN, - KEY_API, - SUPPORTED_LIGHT_FEATURES, -) +from .const import CONF_GATEWAY_ID, COORDINATOR, COORDINATOR_LIST, DOMAIN, KEY_API from .coordinator import TradfriDeviceDataUpdateCoordinator +SUPPORTED_LIGHT_FEATURES = SUPPORT_TRANSITION + async def async_setup_entry( hass: HomeAssistant, @@ -142,8 +134,11 @@ class TradfriLight(TradfriBaseEntity, LightEntity): if ATTR_TRANSITION in kwargs: transition_time = int(kwargs[ATTR_TRANSITION]) * 10 - dimmer_data = {ATTR_DIMMER: 0, ATTR_TRANSITION_TIME: transition_time} - await self._api(self._device_control.set_dimmer(**dimmer_data)) + await self._api( + self._device_control.set_dimmer( + dimmer=0, transition_time=transition_time + ) + ) else: await self._api(self._device_control.set_state(False)) @@ -160,8 +155,8 @@ class TradfriLight(TradfriBaseEntity, LightEntity): brightness = kwargs[ATTR_BRIGHTNESS] brightness = min(brightness, 254) dimmer_data = { - ATTR_DIMMER: brightness, - ATTR_TRANSITION_TIME: transition_time, + "dimmer": brightness, + "transition_time": transition_time, } dimmer_command = self._device_control.set_dimmer(**dimmer_data) transition_time = None @@ -175,9 +170,9 @@ class TradfriLight(TradfriBaseEntity, LightEntity): kwargs[ATTR_HS_COLOR][1] * (self._device_control.max_saturation / 100) ) color_data = { - ATTR_HUE: hue, - ATTR_SAT: sat, - ATTR_TRANSITION_TIME: transition_time, + "hue": hue, + "saturation": sat, + "transition_time": transition_time, } color_command = self._device_control.set_hsb(**color_data) transition_time = None @@ -195,7 +190,7 @@ class TradfriLight(TradfriBaseEntity, LightEntity): temp = self.min_mireds temp_data = { ATTR_COLOR_TEMP: temp, - ATTR_TRANSITION_TIME: transition_time, + "transition_time": transition_time, } temp_command = self._device_control.set_color_temp(**temp_data) transition_time = None @@ -207,9 +202,9 @@ class TradfriLight(TradfriBaseEntity, LightEntity): hue = int(hs_color[0] * (self._device_control.max_hue / 360)) sat = int(hs_color[1] * (self._device_control.max_saturation / 100)) color_data = { - ATTR_HUE: hue, - ATTR_SAT: sat, - ATTR_TRANSITION_TIME: transition_time, + "hue": hue, + "saturation": sat, + "transition_time": transition_time, } color_command = self._device_control.set_hsb(**color_data) transition_time = None diff --git a/homeassistant/components/tradfri/sensor.py b/homeassistant/components/tradfri/sensor.py index 1654b780124..ebd90333292 100644 --- a/homeassistant/components/tradfri/sensor.py +++ b/homeassistant/components/tradfri/sensor.py @@ -3,7 +3,6 @@ from __future__ import annotations from collections.abc import Callable from dataclasses import dataclass -import logging from typing import Any, cast from pytradfri.command import Command @@ -28,17 +27,15 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .base_class import TradfriBaseEntity from .const import ( - ATTR_FILTER_LIFE_REMAINING, CONF_GATEWAY_ID, COORDINATOR, COORDINATOR_LIST, DOMAIN, KEY_API, + LOGGER, ) from .coordinator import TradfriDeviceDataUpdateCoordinator -_LOGGER = logging.getLogger(__name__) - @dataclass class TradfriSensorEntityDescriptionMixin: @@ -91,7 +88,7 @@ SENSOR_DESCRIPTIONS_FAN: tuple[TradfriSensorEntityDescription, ...] = ( value=_get_air_quality, ), TradfriSensorEntityDescription( - key=ATTR_FILTER_LIFE_REMAINING, + key="filter_life_remaining", name="filter time left", state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=TIME_HOURS, @@ -116,14 +113,14 @@ def _migrate_old_unique_ids(hass: HomeAssistant, old_unique_id: str, key: str) - try: ent_reg.async_update_entity(entity_id, new_unique_id=new_unique_id) except ValueError: - _LOGGER.warning( + LOGGER.warning( "Skip migration of id [%s] to [%s] because it already exists", old_unique_id, new_unique_id, ) return - _LOGGER.debug( + LOGGER.debug( "Migrating unique_id from [%s] to [%s]", old_unique_id, new_unique_id, diff --git a/tests/components/tradfri/test_init.py b/tests/components/tradfri/test_init.py index 9d8cf60b2bf..7bcf43f6c27 100644 --- a/tests/components/tradfri/test_init.py +++ b/tests/components/tradfri/test_init.py @@ -37,9 +37,9 @@ async def test_entry_setup_unload(hass, mock_api_factory): assert dev_entry.identifiers == { (tradfri.DOMAIN, entry.data[tradfri.CONF_GATEWAY_ID]) } - assert dev_entry.manufacturer == tradfri.ATTR_TRADFRI_MANUFACTURER - assert dev_entry.name == tradfri.ATTR_TRADFRI_GATEWAY - assert dev_entry.model == tradfri.ATTR_TRADFRI_GATEWAY_MODEL + assert dev_entry.manufacturer == "IKEA of Sweden" + assert dev_entry.name == "Gateway" + assert dev_entry.model == "E1526" with patch.object( hass.config_entries, "async_forward_entry_unload", return_value=True @@ -85,6 +85,6 @@ async def test_remove_stale_devices(hass, mock_api_factory): assert dev_entry.identifiers == { (tradfri.DOMAIN, entry.data[tradfri.CONF_GATEWAY_ID]) } - assert dev_entry.manufacturer == tradfri.ATTR_TRADFRI_MANUFACTURER - assert dev_entry.name == tradfri.ATTR_TRADFRI_GATEWAY - assert dev_entry.model == tradfri.ATTR_TRADFRI_GATEWAY_MODEL + assert dev_entry.manufacturer == "IKEA of Sweden" + assert dev_entry.name == "Gateway" + assert dev_entry.model == "E1526"