mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 23:27:37 +00:00
Add support for LIFX 26"x13" Ceiling (#148459)
Signed-off-by: Avi Miller <me@dje.li>
This commit is contained in:
parent
87aecf0ed9
commit
ec5991bc68
@ -70,6 +70,7 @@ INFRARED_BRIGHTNESS_VALUES_MAP = {
|
||||
}
|
||||
|
||||
LIFX_CEILING_PRODUCT_IDS = {176, 177, 201, 202}
|
||||
LIFX_128ZONE_CEILING_PRODUCT_IDS = {201, 202}
|
||||
|
||||
_LOGGER = logging.getLogger(__package__)
|
||||
|
||||
|
@ -41,6 +41,7 @@ from .const import (
|
||||
DEFAULT_ATTEMPTS,
|
||||
DOMAIN,
|
||||
IDENTIFY_WAVEFORM,
|
||||
LIFX_128ZONE_CEILING_PRODUCT_IDS,
|
||||
MAX_ATTEMPTS_PER_UPDATE_REQUEST_MESSAGE,
|
||||
MAX_UPDATE_TIME,
|
||||
MESSAGE_RETRIES,
|
||||
@ -183,6 +184,11 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]):
|
||||
"""Return true if this is a matrix device."""
|
||||
return bool(lifx_features(self.device)["matrix"])
|
||||
|
||||
@cached_property
|
||||
def is_128zone_matrix(self) -> bool:
|
||||
"""Return true if this is a 128-zone matrix device."""
|
||||
return bool(self.device.product in LIFX_128ZONE_CEILING_PRODUCT_IDS)
|
||||
|
||||
async def diagnostics(self) -> dict[str, Any]:
|
||||
"""Return diagnostic information about the device."""
|
||||
features = lifx_features(self.device)
|
||||
@ -216,6 +222,16 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]):
|
||||
"last_result": self.device.last_hev_cycle_result,
|
||||
}
|
||||
|
||||
if features["matrix"] is True:
|
||||
device_data["matrix"] = {
|
||||
"effect": self.device.effect,
|
||||
"chain": self.device.chain,
|
||||
"chain_length": self.device.chain_length,
|
||||
"tile_devices": self.device.tile_devices,
|
||||
"tile_devices_count": self.device.tile_devices_count,
|
||||
"tile_device_width": self.device.tile_device_width,
|
||||
}
|
||||
|
||||
if features["infrared"] is True:
|
||||
device_data["infrared"] = {"brightness": self.device.infrared_brightness}
|
||||
|
||||
@ -291,6 +307,37 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]):
|
||||
|
||||
return calls
|
||||
|
||||
@callback
|
||||
def _async_build_get64_update_requests(self) -> list[Callable]:
|
||||
"""Build one or more get64 update requests."""
|
||||
if self.device.tile_device_width == 0:
|
||||
return []
|
||||
|
||||
calls: list[Callable] = []
|
||||
calls.append(
|
||||
partial(
|
||||
self.device.get64,
|
||||
tile_index=0,
|
||||
length=1,
|
||||
x=0,
|
||||
y=0,
|
||||
width=self.device.tile_device_width,
|
||||
)
|
||||
)
|
||||
if self.is_128zone_matrix:
|
||||
# For 128-zone ceiling devices, we need another get64 request for the next set of zones
|
||||
calls.append(
|
||||
partial(
|
||||
self.device.get64,
|
||||
tile_index=0,
|
||||
length=1,
|
||||
x=0,
|
||||
y=4,
|
||||
width=self.device.tile_device_width,
|
||||
)
|
||||
)
|
||||
return calls
|
||||
|
||||
async def _async_update_data(self) -> None:
|
||||
"""Fetch all device data from the api."""
|
||||
device = self.device
|
||||
@ -312,9 +359,9 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]):
|
||||
[
|
||||
self.device.get_tile_effect,
|
||||
self.device.get_device_chain,
|
||||
self.device.get64,
|
||||
]
|
||||
)
|
||||
methods.extend(self._async_build_get64_update_requests())
|
||||
if self.is_extended_multizone:
|
||||
methods.append(self.device.get_extended_color_zones)
|
||||
elif self.is_legacy_multizone:
|
||||
@ -339,6 +386,7 @@ class LIFXUpdateCoordinator(DataUpdateCoordinator[None]):
|
||||
|
||||
if self.is_matrix or self.is_extended_multizone or self.is_legacy_multizone:
|
||||
self.active_effect = FirmwareEffect[self.device.effect.get("effect", "OFF")]
|
||||
|
||||
if self.is_legacy_multizone and num_zones != self.get_number_of_zones():
|
||||
# The number of zones has changed so we need
|
||||
# to update the zones again. This happens rarely.
|
||||
|
@ -199,6 +199,17 @@ def _mocked_ceiling() -> Light:
|
||||
return bulb
|
||||
|
||||
|
||||
def _mocked_128zone_ceiling() -> Light:
|
||||
bulb = _mocked_bulb()
|
||||
bulb.product = 201 # LIFX 26"x13" Ceiling
|
||||
bulb.effect = {"effect": "OFF"}
|
||||
bulb.get_tile_effect = MockLifxCommand(bulb)
|
||||
bulb.set_tile_effect = MockLifxCommand(bulb)
|
||||
bulb.get64 = MockLifxCommand(bulb)
|
||||
bulb.get_device_chain = MockLifxCommand(bulb)
|
||||
return bulb
|
||||
|
||||
|
||||
def _mocked_bulb_old_firmware() -> Light:
|
||||
bulb = _mocked_bulb()
|
||||
bulb.host_firmware_version = "2.77"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -12,7 +12,9 @@ from . import (
|
||||
IP_ADDRESS,
|
||||
SERIAL,
|
||||
MockLifxCommand,
|
||||
_mocked_128zone_ceiling,
|
||||
_mocked_bulb,
|
||||
_mocked_ceiling,
|
||||
_mocked_clean_bulb,
|
||||
_mocked_infrared_bulb,
|
||||
_mocked_light_strip,
|
||||
@ -209,3 +211,101 @@ async def test_multizone_bulb_diagnostics(
|
||||
|
||||
diag = await get_diagnostics_for_config_entry(hass, hass_client, config_entry)
|
||||
assert diag == snapshot
|
||||
|
||||
|
||||
async def test_matrix_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test diagnostics for a standard bulb."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=lifx.DOMAIN,
|
||||
title=DEFAULT_ENTRY_TITLE,
|
||||
data={CONF_HOST: IP_ADDRESS},
|
||||
unique_id=SERIAL,
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
bulb = _mocked_ceiling()
|
||||
bulb.effect = {"effect": "OFF"}
|
||||
bulb.tile_devices_count = 1
|
||||
bulb.tile_device_width = 8
|
||||
bulb.tile_devices = [
|
||||
{
|
||||
"accel_meas_x": 0,
|
||||
"accel_meas_y": 0,
|
||||
"accel_meas_z": 2000,
|
||||
"user_x": 0.0,
|
||||
"user_y": 0.0,
|
||||
"width": 8,
|
||||
"height": 8,
|
||||
"supported_frame_buffers": 5,
|
||||
"device_version_vendor": 1,
|
||||
"device_version_product": 176,
|
||||
"firmware_build": 1729829374000000000,
|
||||
"firmware_version_minor": 10,
|
||||
"firmware_version_major": 4,
|
||||
}
|
||||
]
|
||||
bulb.chain = {0: [(0, 0, 0, 3500)] * 64}
|
||||
bulb.chain_length = 1
|
||||
|
||||
with (
|
||||
_patch_discovery(device=bulb),
|
||||
_patch_config_flow_try_connect(device=bulb),
|
||||
_patch_device(device=bulb),
|
||||
):
|
||||
await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
diag = await get_diagnostics_for_config_entry(hass, hass_client, config_entry)
|
||||
assert diag == snapshot
|
||||
|
||||
|
||||
async def test_128zone_matrix_diagnostics(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test diagnostics for a standard bulb."""
|
||||
config_entry = MockConfigEntry(
|
||||
domain=lifx.DOMAIN,
|
||||
title=DEFAULT_ENTRY_TITLE,
|
||||
data={CONF_HOST: IP_ADDRESS},
|
||||
unique_id=SERIAL,
|
||||
)
|
||||
config_entry.add_to_hass(hass)
|
||||
bulb = _mocked_128zone_ceiling()
|
||||
bulb.effect = {"effect": "OFF"}
|
||||
bulb.tile_devices_count = 1
|
||||
bulb.tile_device_width = 16
|
||||
bulb.tile_devices = [
|
||||
{
|
||||
"accel_meas_x": 0,
|
||||
"accel_meas_y": 0,
|
||||
"accel_meas_z": 2000,
|
||||
"user_x": 0.0,
|
||||
"user_y": 0.0,
|
||||
"width": 8,
|
||||
"height": 16,
|
||||
"supported_frame_buffers": 5,
|
||||
"device_version_vendor": 1,
|
||||
"device_version_product": 201,
|
||||
"firmware_build": 1729829374000000000,
|
||||
"firmware_version_minor": 10,
|
||||
"firmware_version_major": 4,
|
||||
}
|
||||
]
|
||||
bulb.chain = {0: [(0, 0, 0, 3500)] * 128}
|
||||
bulb.chain_length = 1
|
||||
|
||||
with (
|
||||
_patch_discovery(device=bulb),
|
||||
_patch_config_flow_try_connect(device=bulb),
|
||||
_patch_device(device=bulb),
|
||||
):
|
||||
await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
diag = await get_diagnostics_for_config_entry(hass, hass_client, config_entry)
|
||||
assert diag == snapshot
|
||||
|
Loading…
x
Reference in New Issue
Block a user