Add Switcher Lights support (#129494)

* switcher lights integration

* fix based on requested changes

* Update light.py

* switcher fix based on requested changes

* fix linting

* fix linting

* Update light.py

* Update light.py

* Update homeassistant/components/switcher_kis/light.py

* Update light.py

---------

Co-authored-by: Shay Levy <levyshay1@gmail.com>
This commit is contained in:
YogevBokobza 2024-11-07 22:06:34 +02:00 committed by GitHub
parent 8cae8edc55
commit dac6271e01
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 104 additions and 19 deletions

View File

@ -35,16 +35,20 @@ async def async_setup_entry(
def async_add_light(coordinator: SwitcherDataUpdateCoordinator) -> None:
"""Add light from Switcher device."""
entities: list[LightEntity] = []
if (
coordinator.data.device_type.category
== DeviceCategory.SINGLE_SHUTTER_DUAL_LIGHT
):
entities.extend(SwitcherDualLightEntity(coordinator, i) for i in range(2))
if (
coordinator.data.device_type.category
== DeviceCategory.DUAL_SHUTTER_SINGLE_LIGHT
if coordinator.data.device_type.category in (
DeviceCategory.SINGLE_SHUTTER_DUAL_LIGHT,
DeviceCategory.DUAL_SHUTTER_SINGLE_LIGHT,
DeviceCategory.LIGHT,
):
number_of_lights = len(cast(SwitcherLight, coordinator.data).light)
if number_of_lights == 1:
entities.append(SwitcherSingleLightEntity(coordinator, 0))
else:
entities.extend(
SwitcherMultiLightEntity(coordinator, i)
for i in range(number_of_lights)
)
async_add_entities(entities)
config_entry.async_on_unload(
@ -133,8 +137,8 @@ class SwitcherSingleLightEntity(SwitcherBaseLightEntity):
self._attr_unique_id = f"{coordinator.device_id}-{coordinator.mac_address}"
class SwitcherDualLightEntity(SwitcherBaseLightEntity):
"""Representation of a Switcher dual light entity."""
class SwitcherMultiLightEntity(SwitcherBaseLightEntity):
"""Representation of a Switcher multiple light entity."""
_attr_translation_key = "light"

View File

@ -5,6 +5,7 @@ from aioswitcher.device import (
DeviceType,
ShutterDirection,
SwitcherDualShutterSingleLight,
SwitcherLight,
SwitcherPowerPlug,
SwitcherShutter,
SwitcherSingleShutterDualLight,
@ -23,18 +24,27 @@ DUMMY_DEVICE_ID3 = "bada77"
DUMMY_DEVICE_ID4 = "bbd164"
DUMMY_DEVICE_ID5 = "bcdb64"
DUMMY_DEVICE_ID6 = "bcdc64"
DUMMY_DEVICE_ID7 = "bcdd64"
DUMMY_DEVICE_ID8 = "bcde64"
DUMMY_DEVICE_ID9 = "bcdf64"
DUMMY_DEVICE_KEY1 = "18"
DUMMY_DEVICE_KEY2 = "01"
DUMMY_DEVICE_KEY3 = "12"
DUMMY_DEVICE_KEY4 = "07"
DUMMY_DEVICE_KEY5 = "15"
DUMMY_DEVICE_KEY6 = "16"
DUMMY_DEVICE_KEY7 = "17"
DUMMY_DEVICE_KEY8 = "18"
DUMMY_DEVICE_KEY9 = "19"
DUMMY_DEVICE_NAME1 = "Plug 23BC"
DUMMY_DEVICE_NAME2 = "Heater FE12"
DUMMY_DEVICE_NAME3 = "Breeze AB39"
DUMMY_DEVICE_NAME4 = "Runner DD77"
DUMMY_DEVICE_NAME5 = "RunnerS11 6CF5"
DUMMY_DEVICE_NAME6 = "RunnerS12 A9BE"
DUMMY_DEVICE_NAME7 = "Light 36BB"
DUMMY_DEVICE_NAME8 = "Light 36CB"
DUMMY_DEVICE_NAME9 = "Light 36DB"
DUMMY_DEVICE_PASSWORD = "12345678"
DUMMY_ELECTRIC_CURRENT1 = 0.5
DUMMY_ELECTRIC_CURRENT2 = 12.8
@ -44,18 +54,27 @@ DUMMY_IP_ADDRESS3 = "192.168.100.159"
DUMMY_IP_ADDRESS4 = "192.168.100.160"
DUMMY_IP_ADDRESS5 = "192.168.100.161"
DUMMY_IP_ADDRESS6 = "192.168.100.162"
DUMMY_IP_ADDRESS7 = "192.168.100.163"
DUMMY_IP_ADDRESS8 = "192.168.100.164"
DUMMY_IP_ADDRESS9 = "192.168.100.165"
DUMMY_MAC_ADDRESS1 = "A1:B2:C3:45:67:D8"
DUMMY_MAC_ADDRESS2 = "A1:B2:C3:45:67:D9"
DUMMY_MAC_ADDRESS3 = "A1:B2:C3:45:67:DA"
DUMMY_MAC_ADDRESS4 = "A1:B2:C3:45:67:DB"
DUMMY_MAC_ADDRESS5 = "A1:B2:C3:45:67:DC"
DUMMY_MAC_ADDRESS6 = "A1:B2:C3:45:67:DD"
DUMMY_MAC_ADDRESS7 = "A1:B2:C3:45:67:DE"
DUMMY_MAC_ADDRESS8 = "A1:B2:C3:45:67:DF"
DUMMY_MAC_ADDRESS9 = "A1:B2:C3:45:67:DG"
DUMMY_TOKEN_NEEDED1 = False
DUMMY_TOKEN_NEEDED2 = False
DUMMY_TOKEN_NEEDED3 = False
DUMMY_TOKEN_NEEDED4 = False
DUMMY_TOKEN_NEEDED5 = True
DUMMY_TOKEN_NEEDED6 = True
DUMMY_TOKEN_NEEDED7 = True
DUMMY_TOKEN_NEEDED8 = True
DUMMY_TOKEN_NEEDED9 = True
DUMMY_PHONE_ID = "1234"
DUMMY_POWER_CONSUMPTION1 = 100
DUMMY_POWER_CONSUMPTION2 = 2780
@ -75,6 +94,7 @@ DUMMY_USERNAME = "email"
DUMMY_TOKEN = "zvVvd7JxtN7CgvkD1Psujw=="
DUMMY_LIGHT = [DeviceState.ON]
DUMMY_LIGHT_2 = [DeviceState.ON, DeviceState.ON]
DUMMY_LIGHT_3 = [DeviceState.ON, DeviceState.ON, DeviceState.ON]
DUMMY_PLUG_DEVICE = SwitcherPowerPlug(
DeviceType.POWER_PLUG,
@ -162,4 +182,40 @@ DUMMY_THERMOSTAT_DEVICE = SwitcherThermostat(
DUMMY_REMOTE_ID,
)
DUMMY_LIGHT_DEVICE = SwitcherLight(
DeviceType.LIGHT_SL01,
DeviceState.ON,
DUMMY_DEVICE_ID7,
DUMMY_DEVICE_KEY7,
DUMMY_IP_ADDRESS7,
DUMMY_MAC_ADDRESS7,
DUMMY_DEVICE_NAME7,
DUMMY_TOKEN_NEEDED7,
DUMMY_LIGHT,
)
DUMMY_DUAL_LIGHT_DEVICE = SwitcherLight(
DeviceType.LIGHT_SL02,
DeviceState.ON,
DUMMY_DEVICE_ID8,
DUMMY_DEVICE_KEY8,
DUMMY_IP_ADDRESS8,
DUMMY_MAC_ADDRESS8,
DUMMY_DEVICE_NAME8,
DUMMY_TOKEN_NEEDED8,
DUMMY_LIGHT_2,
)
DUMMY_TRIPLE_LIGHT_DEVICE = SwitcherLight(
DeviceType.LIGHT_SL03,
DeviceState.ON,
DUMMY_DEVICE_ID9,
DUMMY_DEVICE_KEY9,
DUMMY_IP_ADDRESS9,
DUMMY_MAC_ADDRESS9,
DUMMY_DEVICE_NAME9,
DUMMY_TOKEN_NEEDED9,
DUMMY_LIGHT_3,
)
DUMMY_SWITCHER_DEVICES = [DUMMY_PLUG_DEVICE, DUMMY_WATER_HEATER_DEVICE]

View File

@ -21,26 +21,43 @@ from homeassistant.util import slugify
from . import init_integration
from .consts import (
DUMMY_DUAL_LIGHT_DEVICE as DEVICE4,
DUMMY_DUAL_SHUTTER_SINGLE_LIGHT_DEVICE as DEVICE2,
DUMMY_LIGHT_DEVICE as DEVICE3,
DUMMY_SINGLE_SHUTTER_DUAL_LIGHT_DEVICE as DEVICE,
DUMMY_TOKEN as TOKEN,
DUMMY_TRIPLE_LIGHT_DEVICE as DEVICE5,
DUMMY_USERNAME as USERNAME,
)
ENTITY_ID = f"{LIGHT_DOMAIN}.{slugify(DEVICE.name)}_light_1"
ENTITY_ID2 = f"{LIGHT_DOMAIN}.{slugify(DEVICE.name)}_light_2"
ENTITY_ID3 = f"{LIGHT_DOMAIN}.{slugify(DEVICE2.name)}"
ENTITY_ID_2 = f"{LIGHT_DOMAIN}.{slugify(DEVICE.name)}_light_2"
ENTITY_ID2 = f"{LIGHT_DOMAIN}.{slugify(DEVICE2.name)}"
ENTITY_ID3 = f"{LIGHT_DOMAIN}.{slugify(DEVICE3.name)}"
ENTITY_ID4 = f"{LIGHT_DOMAIN}.{slugify(DEVICE4.name)}_light_1"
ENTITY_ID4_2 = f"{LIGHT_DOMAIN}.{slugify(DEVICE4.name)}_light_2"
ENTITY_ID5 = f"{LIGHT_DOMAIN}.{slugify(DEVICE5.name)}_light_1"
ENTITY_ID5_2 = f"{LIGHT_DOMAIN}.{slugify(DEVICE5.name)}_light_2"
ENTITY_ID5_3 = f"{LIGHT_DOMAIN}.{slugify(DEVICE5.name)}_light_3"
@pytest.mark.parametrize(
("device", "entity_id", "light_id", "device_state"),
[
(DEVICE, ENTITY_ID, 0, [DeviceState.OFF, DeviceState.ON]),
(DEVICE, ENTITY_ID2, 1, [DeviceState.ON, DeviceState.OFF]),
(DEVICE2, ENTITY_ID3, 0, [DeviceState.OFF]),
(DEVICE, ENTITY_ID_2, 1, [DeviceState.ON, DeviceState.OFF]),
(DEVICE2, ENTITY_ID2, 0, [DeviceState.OFF]),
(DEVICE3, ENTITY_ID3, 0, [DeviceState.OFF]),
(DEVICE4, ENTITY_ID4, 0, [DeviceState.OFF, DeviceState.ON]),
(DEVICE4, ENTITY_ID4_2, 1, [DeviceState.ON, DeviceState.OFF]),
(DEVICE5, ENTITY_ID5, 0, [DeviceState.OFF, DeviceState.ON, DeviceState.ON]),
(DEVICE5, ENTITY_ID5_2, 1, [DeviceState.ON, DeviceState.OFF, DeviceState.ON]),
(DEVICE5, ENTITY_ID5_3, 2, [DeviceState.ON, DeviceState.ON, DeviceState.OFF]),
],
)
@pytest.mark.parametrize("mock_bridge", [[DEVICE, DEVICE2]], indirect=True)
@pytest.mark.parametrize(
"mock_bridge", [[DEVICE, DEVICE2, DEVICE3, DEVICE4, DEVICE5]], indirect=True
)
async def test_light(
hass: HomeAssistant,
mock_bridge,
@ -98,11 +115,19 @@ async def test_light(
("device", "entity_id", "light_id", "device_state"),
[
(DEVICE, ENTITY_ID, 0, [DeviceState.OFF, DeviceState.ON]),
(DEVICE, ENTITY_ID2, 1, [DeviceState.ON, DeviceState.OFF]),
(DEVICE2, ENTITY_ID3, 0, [DeviceState.OFF]),
(DEVICE, ENTITY_ID_2, 1, [DeviceState.ON, DeviceState.OFF]),
(DEVICE2, ENTITY_ID2, 0, [DeviceState.OFF]),
(DEVICE3, ENTITY_ID3, 0, [DeviceState.OFF]),
(DEVICE4, ENTITY_ID4, 0, [DeviceState.OFF, DeviceState.ON]),
(DEVICE4, ENTITY_ID4_2, 1, [DeviceState.ON, DeviceState.OFF]),
(DEVICE5, ENTITY_ID5, 0, [DeviceState.OFF, DeviceState.ON, DeviceState.ON]),
(DEVICE5, ENTITY_ID5_2, 1, [DeviceState.ON, DeviceState.OFF, DeviceState.ON]),
(DEVICE5, ENTITY_ID5_3, 2, [DeviceState.ON, DeviceState.ON, DeviceState.OFF]),
],
)
@pytest.mark.parametrize("mock_bridge", [[DEVICE]], indirect=True)
@pytest.mark.parametrize(
"mock_bridge", [[DEVICE, DEVICE2, DEVICE3, DEVICE4, DEVICE5]], indirect=True
)
async def test_light_control_fail(
hass: HomeAssistant,
mock_bridge,