Skip to content

Commit

Permalink
Remove the LIFX sensor update coordinator
Browse files Browse the repository at this point in the history
Signed-off-by: Avi Miller <me@dje.li>
  • Loading branch information
Djelibeybi committed Apr 3, 2023
1 parent 59511cc commit 4ebf6ba
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 130 deletions.
1 change: 0 additions & 1 deletion homeassistant/components/lifx/__init__.py
Expand Up @@ -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
Expand Down
17 changes: 6 additions & 11 deletions homeassistant/components/lifx/binary_sensor.py
Expand Up @@ -12,8 +12,8 @@
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(
Expand All @@ -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
Expand Down
13 changes: 6 additions & 7 deletions homeassistant/components/lifx/button.py
Expand Up @@ -12,8 +12,8 @@
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,
Expand All @@ -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}"
)


Expand Down
99 changes: 35 additions & 64 deletions homeassistant/components/lifx/coordinator.py
Expand Up @@ -79,7 +79,9 @@ def __init__(
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,
Expand All @@ -100,6 +102,24 @@ def async_setup(self) -> 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."""
Expand Down Expand Up @@ -187,6 +207,9 @@ async def _async_update_data(self) -> 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()
Expand All @@ -196,6 +219,12 @@ async def _async_update_data(self) -> 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
Expand Down Expand Up @@ -357,64 +386,6 @@ def async_get_active_effect(self) -> int:
"""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)
Expand All @@ -425,13 +396,13 @@ async def async_identify_bulb(self) -> 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."""
Expand Down Expand Up @@ -471,4 +442,4 @@ async def async_apply_theme(self, theme_name: str) -> 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])
20 changes: 1 addition & 19 deletions homeassistant/components/lifx/entity.py
Expand Up @@ -8,7 +8,7 @@
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import DOMAIN
from .coordinator import LIFXSensorUpdateCoordinator, LIFXUpdateCoordinator
from .coordinator import LIFXUpdateCoordinator


class LIFXEntity(CoordinatorEntity[LIFXUpdateCoordinator]):
Expand All @@ -27,21 +27,3 @@ def __init__(self, coordinator: LIFXUpdateCoordinator) -> None:
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,
)
4 changes: 1 addition & 3 deletions homeassistant/components/lifx/light.py
Expand Up @@ -274,9 +274,7 @@ async def set_hev_cycle_state(
"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(
Expand Down
28 changes: 11 additions & 17 deletions homeassistant/components/lifx/select.py
Expand Up @@ -15,8 +15,8 @@
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]
Expand All @@ -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
Expand All @@ -93,21 +87,21 @@ async def async_select_option(self, option: str) -> None:
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
Expand Down

0 comments on commit 4ebf6ba

Please sign in to comment.