From 5e7e96c5dac39944da5280a945e3355dc1995d6f Mon Sep 17 00:00:00 2001 From: Avi Miller Date: Tue, 4 Apr 2023 13:48:32 +1000 Subject: [PATCH] Remove the LIFX sensor update coordinator (#90740) --- homeassistant/components/lifx/__init__.py | 1 - .../components/lifx/binary_sensor.py | 17 ++-- homeassistant/components/lifx/button.py | 13 ++- homeassistant/components/lifx/coordinator.py | 99 +++++++------------ homeassistant/components/lifx/entity.py | 20 +--- homeassistant/components/lifx/light.py | 4 +- homeassistant/components/lifx/select.py | 28 +++--- homeassistant/components/lifx/sensor.py | 12 +-- tests/components/lifx/__init__.py | 4 +- 9 files changed, 68 insertions(+), 130 deletions(-) diff --git a/homeassistant/components/lifx/__init__.py b/homeassistant/components/lifx/__init__.py index 1bdbc618fdf..f0c38cdfb11 100644 --- a/homeassistant/components/lifx/__init__.py +++ b/homeassistant/components/lifx/__init__.py @@ -210,7 +210,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: coordinator.async_setup() try: await coordinator.async_config_entry_first_refresh() - await coordinator.sensor_coordinator.async_config_entry_first_refresh() except ConfigEntryNotReady: connection.async_stop() raise diff --git a/homeassistant/components/lifx/binary_sensor.py b/homeassistant/components/lifx/binary_sensor.py index 1632cac3d1f..110661b1c5c 100644 --- a/homeassistant/components/lifx/binary_sensor.py +++ b/homeassistant/components/lifx/binary_sensor.py @@ -12,8 +12,8 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN, HEV_CYCLE_STATE -from .coordinator import LIFXSensorUpdateCoordinator, LIFXUpdateCoordinator -from .entity import LIFXSensorEntity +from .coordinator import LIFXUpdateCoordinator +from .entity import LIFXEntity from .util import lifx_features HEV_CYCLE_STATE_SENSOR = BinarySensorEntityDescription( @@ -32,29 +32,24 @@ async def async_setup_entry( if lifx_features(coordinator.device)["hev"]: async_add_entities( - [ - LIFXHevCycleBinarySensorEntity( - coordinator=coordinator.sensor_coordinator, - description=HEV_CYCLE_STATE_SENSOR, - ) - ] + [LIFXHevCycleBinarySensorEntity(coordinator, HEV_CYCLE_STATE_SENSOR)] ) -class LIFXHevCycleBinarySensorEntity(LIFXSensorEntity, BinarySensorEntity): +class LIFXHevCycleBinarySensorEntity(LIFXEntity, BinarySensorEntity): """LIFX HEV cycle state binary sensor.""" _attr_has_entity_name = True def __init__( self, - coordinator: LIFXSensorUpdateCoordinator, + coordinator: LIFXUpdateCoordinator, description: BinarySensorEntityDescription, ) -> None: """Initialise the sensor.""" super().__init__(coordinator) self.entity_description = description - self._attr_unique_id = f"{coordinator.parent.serial_number}_{description.key}" + self._attr_unique_id = f"{coordinator.serial_number}_{description.key}" self._async_update_attrs() @callback diff --git a/homeassistant/components/lifx/button.py b/homeassistant/components/lifx/button.py index 636f90aaf3b..b5f5373b3e8 100644 --- a/homeassistant/components/lifx/button.py +++ b/homeassistant/components/lifx/button.py @@ -12,8 +12,8 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN, IDENTIFY, RESTART -from .coordinator import LIFXSensorUpdateCoordinator, LIFXUpdateCoordinator -from .entity import LIFXSensorEntity +from .coordinator import LIFXUpdateCoordinator +from .entity import LIFXEntity RESTART_BUTTON_DESCRIPTION = ButtonEntityDescription( key=RESTART, @@ -38,22 +38,21 @@ async def async_setup_entry( domain_data = hass.data[DOMAIN] coordinator: LIFXUpdateCoordinator = domain_data[entry.entry_id] async_add_entities( - cls(coordinator.sensor_coordinator) - for cls in (LIFXRestartButton, LIFXIdentifyButton) + [LIFXRestartButton(coordinator), LIFXIdentifyButton(coordinator)] ) -class LIFXButton(LIFXSensorEntity, ButtonEntity): +class LIFXButton(LIFXEntity, ButtonEntity): """Base LIFX button.""" _attr_has_entity_name: bool = True _attr_should_poll: bool = False - def __init__(self, coordinator: LIFXSensorUpdateCoordinator) -> None: + def __init__(self, coordinator: LIFXUpdateCoordinator) -> None: """Initialise a LIFX button.""" super().__init__(coordinator) self._attr_unique_id = ( - f"{coordinator.parent.serial_number}_{self.entity_description.key}" + f"{coordinator.serial_number}_{self.entity_description.key}" ) diff --git a/homeassistant/components/lifx/coordinator.py b/homeassistant/components/lifx/coordinator.py index 038f93c1e88..293ef369806 100644 --- a/homeassistant/components/lifx/coordinator.py +++ b/homeassistant/components/lifx/coordinator.py @@ -79,7 +79,9 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]): self.device: Light = connection.device self.lock = asyncio.Lock() self.active_effect = FirmwareEffect.OFF - self.sensor_coordinator = LIFXSensorUpdateCoordinator(hass, self, title) + self._update_rssi: bool = False + self._rssi: int = 0 + self.last_used_theme: str = "" super().__init__( hass, @@ -100,6 +102,24 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]): self.device.retry_count = MESSAGE_RETRIES self.device.unregister_timeout = UNAVAILABLE_GRACE + @property + def rssi(self) -> int: + """Return stored RSSI value.""" + return self._rssi + + @property + def rssi_uom(self) -> str: + """Return the RSSI unit of measurement.""" + if AwesomeVersion(self.device.host_firmware_version) <= RSSI_DBM_FW: + return SIGNAL_STRENGTH_DECIBELS + + return SIGNAL_STRENGTH_DECIBELS_MILLIWATT + + @property + def current_infrared_brightness(self) -> str | None: + """Return the current infrared brightness as a string.""" + return infrared_brightness_value_to_option(self.device.infrared_brightness) + @property def serial_number(self) -> str: """Return the internal mac address.""" @@ -187,6 +207,9 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]): if self.device.mac_addr == TARGET_ANY: self.device.mac_addr = response.target_addr + if self._update_rssi is True: + await self.async_update_rssi() + # Update extended multizone devices if lifx_features(self.device)["extended_multizone"]: await self.async_get_extended_color_zones() @@ -196,6 +219,12 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]): await self.async_get_color_zones() await self.async_get_multizone_effect() + if lifx_features(self.device)["hev"]: + await self.async_get_hev_cycle() + + if lifx_features(self.device)["infrared"]: + await async_execute_lifx(self.device.get_infrared) + async def async_get_color_zones(self) -> None: """Get updated color information for each zone.""" zone = 0 @@ -357,64 +386,6 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]): """Return the enum value of the currently active firmware effect.""" return self.active_effect.value - -class LIFXSensorUpdateCoordinator(DataUpdateCoordinator[None]): - """DataUpdateCoordinator to gather data for a specific lifx device.""" - - def __init__( - self, - hass: HomeAssistant, - parent: LIFXUpdateCoordinator, - title: str, - ) -> None: - """Initialize DataUpdateCoordinator.""" - self.parent: LIFXUpdateCoordinator = parent - self.device: Light = parent.device - self._update_rssi: bool = False - self._rssi: int = 0 - self.last_used_theme: str = "" - - super().__init__( - hass, - _LOGGER, - name=f"{title} Sensors ({self.device.ip_addr})", - update_interval=timedelta(seconds=SENSOR_UPDATE_INTERVAL), - # Refresh immediately because the changes are not visible - request_refresh_debouncer=Debouncer( - hass, _LOGGER, cooldown=0, immediate=True - ), - ) - - @property - def rssi(self) -> int: - """Return stored RSSI value.""" - return self._rssi - - @property - def rssi_uom(self) -> str: - """Return the RSSI unit of measurement.""" - if AwesomeVersion(self.device.host_firmware_version) <= RSSI_DBM_FW: - return SIGNAL_STRENGTH_DECIBELS - - return SIGNAL_STRENGTH_DECIBELS_MILLIWATT - - @property - def current_infrared_brightness(self) -> str | None: - """Return the current infrared brightness as a string.""" - return infrared_brightness_value_to_option(self.device.infrared_brightness) - - async def _async_update_data(self) -> None: - """Fetch all device data from the api.""" - - if self._update_rssi is True: - await self.async_update_rssi() - - if lifx_features(self.device)["hev"]: - await self.async_get_hev_cycle() - - if lifx_features(self.device)["infrared"]: - await async_execute_lifx(self.device.get_infrared) - async def async_set_infrared_brightness(self, option: str) -> None: """Set infrared brightness.""" infrared_brightness = infrared_brightness_option_to_value(option) @@ -425,13 +396,13 @@ class LIFXSensorUpdateCoordinator(DataUpdateCoordinator[None]): bulb: Light = self.device if bulb.power_level: # just flash the bulb for three seconds - await self.parent.async_set_waveform_optional(value=IDENTIFY_WAVEFORM) + await self.async_set_waveform_optional(value=IDENTIFY_WAVEFORM) return # Turn the bulb on first, flash for 3 seconds, then turn off - await self.parent.async_set_power(state=True, duration=1) - await self.parent.async_set_waveform_optional(value=IDENTIFY_WAVEFORM) + await self.async_set_power(state=True, duration=1) + await self.async_set_waveform_optional(value=IDENTIFY_WAVEFORM) await asyncio.sleep(LIFX_IDENTIFY_DELAY) - await self.parent.async_set_power(state=False, duration=1) + await self.async_set_power(state=False, duration=1) def async_enable_rssi_updates(self) -> Callable[[], None]: """Enable RSSI signal strength updates.""" @@ -471,4 +442,4 @@ class LIFXSensorUpdateCoordinator(DataUpdateCoordinator[None]): """Apply the selected theme to the device.""" self.last_used_theme = theme_name theme = ThemeLibrary().get_theme(theme_name) - await ThemePainter(self.hass.loop).paint(theme, [self.parent.device]) + await ThemePainter(self.hass.loop).paint(theme, [self.device]) diff --git a/homeassistant/components/lifx/entity.py b/homeassistant/components/lifx/entity.py index 63996d60027..a86bda53cfd 100644 --- a/homeassistant/components/lifx/entity.py +++ b/homeassistant/components/lifx/entity.py @@ -8,7 +8,7 @@ from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import DOMAIN -from .coordinator import LIFXSensorUpdateCoordinator, LIFXUpdateCoordinator +from .coordinator import LIFXUpdateCoordinator class LIFXEntity(CoordinatorEntity[LIFXUpdateCoordinator]): @@ -27,21 +27,3 @@ class LIFXEntity(CoordinatorEntity[LIFXUpdateCoordinator]): sw_version=self.bulb.host_firmware_version, suggested_area=self.bulb.group, ) - - -class LIFXSensorEntity(CoordinatorEntity[LIFXSensorUpdateCoordinator]): - """Representation of a LIFX sensor entity with a sensor coordinator.""" - - def __init__(self, coordinator: LIFXSensorUpdateCoordinator) -> None: - """Initialise the sensor.""" - super().__init__(coordinator) - self.bulb = coordinator.parent.device - self._attr_device_info = DeviceInfo( - identifiers={(DOMAIN, coordinator.parent.serial_number)}, - connections={(dr.CONNECTION_NETWORK_MAC, coordinator.parent.mac_address)}, - manufacturer="LIFX", - name=coordinator.parent.label, - model=products.product_map.get(self.bulb.product, "LIFX Bulb"), - sw_version=self.bulb.host_firmware_version, - suggested_area=self.bulb.group, - ) diff --git a/homeassistant/components/lifx/light.py b/homeassistant/components/lifx/light.py index eb62cb8016e..e22baebfa81 100644 --- a/homeassistant/components/lifx/light.py +++ b/homeassistant/components/lifx/light.py @@ -274,9 +274,7 @@ class LIFXLight(LIFXEntity, LightEntity): "This device does not support setting HEV cycle state" ) - await self.coordinator.sensor_coordinator.async_set_hev_cycle_state( - power, duration or 0 - ) + await self.coordinator.async_set_hev_cycle_state(power, duration or 0) await self.update_during_transition(duration or 0) async def set_power( diff --git a/homeassistant/components/lifx/select.py b/homeassistant/components/lifx/select.py index 1b58ea04686..9ad457e0270 100644 --- a/homeassistant/components/lifx/select.py +++ b/homeassistant/components/lifx/select.py @@ -15,8 +15,8 @@ from .const import ( INFRARED_BRIGHTNESS, INFRARED_BRIGHTNESS_VALUES_MAP, ) -from .coordinator import LIFXSensorUpdateCoordinator, LIFXUpdateCoordinator -from .entity import LIFXSensorEntity +from .coordinator import LIFXUpdateCoordinator +from .entity import LIFXEntity from .util import lifx_features THEME_NAMES = [theme_name.lower() for theme_name in ThemeLibrary().themes] @@ -42,39 +42,33 @@ async def async_setup_entry( """Set up LIFX from a config entry.""" coordinator: LIFXUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] - entities: list[LIFXSensorEntity] = [] + entities: list[LIFXEntity] = [] if lifx_features(coordinator.device)["infrared"]: entities.append( - LIFXInfraredBrightnessSelectEntity( - coordinator.sensor_coordinator, description=INFRARED_BRIGHTNESS_ENTITY - ) + LIFXInfraredBrightnessSelectEntity(coordinator, INFRARED_BRIGHTNESS_ENTITY) ) if lifx_features(coordinator.device)["multizone"] is True: - entities.append( - LIFXThemeSelectEntity( - coordinator.sensor_coordinator, description=THEME_ENTITY - ) - ) + entities.append(LIFXThemeSelectEntity(coordinator, THEME_ENTITY)) async_add_entities(entities) -class LIFXInfraredBrightnessSelectEntity(LIFXSensorEntity, SelectEntity): +class LIFXInfraredBrightnessSelectEntity(LIFXEntity, SelectEntity): """LIFX Nightvision infrared brightness configuration entity.""" _attr_has_entity_name = True def __init__( self, - coordinator: LIFXSensorUpdateCoordinator, + coordinator: LIFXUpdateCoordinator, description: SelectEntityDescription, ) -> None: """Initialise the IR brightness config entity.""" super().__init__(coordinator) self.entity_description = description - self._attr_unique_id = f"{coordinator.parent.serial_number}_{description.key}" + self._attr_unique_id = f"{coordinator.serial_number}_{description.key}" self._attr_current_option = coordinator.current_infrared_brightness @callback @@ -93,21 +87,21 @@ class LIFXInfraredBrightnessSelectEntity(LIFXSensorEntity, SelectEntity): await self.coordinator.async_set_infrared_brightness(option) -class LIFXThemeSelectEntity(LIFXSensorEntity, SelectEntity): +class LIFXThemeSelectEntity(LIFXEntity, SelectEntity): """Theme entity for LIFX multizone devices.""" _attr_has_entity_name = True def __init__( self, - coordinator: LIFXSensorUpdateCoordinator, + coordinator: LIFXUpdateCoordinator, description: SelectEntityDescription, ) -> None: """Initialise the theme selection entity.""" super().__init__(coordinator) self.entity_description = description - self._attr_unique_id = f"{coordinator.parent.serial_number}_{description.key}" + self._attr_unique_id = f"{coordinator.serial_number}_{description.key}" self._attr_current_option = None @callback diff --git a/homeassistant/components/lifx/sensor.py b/homeassistant/components/lifx/sensor.py index da03b33f52a..654b5285756 100644 --- a/homeassistant/components/lifx/sensor.py +++ b/homeassistant/components/lifx/sensor.py @@ -15,8 +15,8 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import ATTR_RSSI, DOMAIN -from .coordinator import LIFXSensorUpdateCoordinator, LIFXUpdateCoordinator -from .entity import LIFXSensorEntity +from .coordinator import LIFXUpdateCoordinator +from .entity import LIFXEntity SCAN_INTERVAL = timedelta(seconds=30) @@ -35,24 +35,24 @@ async def async_setup_entry( ) -> None: """Set up LIFX sensor from config entry.""" coordinator: LIFXUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] - async_add_entities([LIFXRssiSensor(coordinator.sensor_coordinator, RSSI_SENSOR)]) + async_add_entities([LIFXRssiSensor(coordinator, RSSI_SENSOR)]) -class LIFXRssiSensor(LIFXSensorEntity, SensorEntity): +class LIFXRssiSensor(LIFXEntity, SensorEntity): """LIFX RSSI sensor.""" _attr_has_entity_name = True def __init__( self, - coordinator: LIFXSensorUpdateCoordinator, + coordinator: LIFXUpdateCoordinator, description: SensorEntityDescription, ) -> None: """Initialise the RSSI sensor.""" super().__init__(coordinator) self.entity_description = description - self._attr_unique_id = f"{coordinator.parent.serial_number}_{description.key}" + self._attr_unique_id = f"{coordinator.serial_number}_{description.key}" self._attr_native_unit_of_measurement = coordinator.rssi_uom @callback diff --git a/tests/components/lifx/__init__.py b/tests/components/lifx/__init__.py index 0278b8ec3a7..dadb57d09ad 100644 --- a/tests/components/lifx/__init__.py +++ b/tests/components/lifx/__init__.py @@ -254,7 +254,7 @@ def _patch_config_flow_try_connect( ): """Patch out discovery.""" - class MockLifxConnecton: + class MockLifxConnection: """Mock lifx discovery.""" def __init__(self, *args, **kwargs): @@ -275,7 +275,7 @@ def _patch_config_flow_try_connect( def _patcher(): with patch( "homeassistant.components.lifx.config_flow.LIFXConnection", - MockLifxConnecton, + MockLifxConnection, ): yield