Add YoLink MultiOutlet support (#82622)

This commit is contained in:
Matrix 2022-11-29 21:10:38 +08:00 committed by GitHub
parent 412c12b992
commit f0b979556c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 78 additions and 14 deletions

View file

@ -6,6 +6,7 @@ from dataclasses import dataclass
from typing import Any
from yolink.device import YoLinkDevice
from yolink.outlet_request_builder import OutletRequestBuilder
from homeassistant.components.switch import (
SwitchDeviceClass,
@ -19,6 +20,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import (
ATTR_COORDINATORS,
ATTR_DEVICE_MANIPULATOR,
ATTR_DEVICE_MULTI_OUTLET,
ATTR_DEVICE_OUTLET,
ATTR_DEVICE_SWITCH,
DOMAIN,
@ -32,8 +34,7 @@ class YoLinkSwitchEntityDescription(SwitchEntityDescription):
"""YoLink SwitchEntityDescription."""
exists_fn: Callable[[YoLinkDevice], bool] = lambda _: True
value: Callable[[Any], bool | None] = lambda _: None
state_key: str = "state"
plug_index: int | None = None
DEVICE_TYPES: tuple[YoLinkSwitchEntityDescription, ...] = (
@ -41,26 +42,63 @@ DEVICE_TYPES: tuple[YoLinkSwitchEntityDescription, ...] = (
key="outlet_state",
device_class=SwitchDeviceClass.OUTLET,
name="State",
value=lambda value: value == "open" if value is not None else None,
exists_fn=lambda device: device.device_type == ATTR_DEVICE_OUTLET,
),
YoLinkSwitchEntityDescription(
key="manipulator_state",
name="State",
icon="mdi:pipe",
value=lambda value: value == "open" if value is not None else None,
exists_fn=lambda device: device.device_type == ATTR_DEVICE_MANIPULATOR,
),
YoLinkSwitchEntityDescription(
key="switch_state",
name="State",
device_class=SwitchDeviceClass.SWITCH,
value=lambda value: value == "open" if value is not None else None,
exists_fn=lambda device: device.device_type == ATTR_DEVICE_SWITCH,
),
YoLinkSwitchEntityDescription(
key="multi_outlet_usb_ports",
name="UsbPorts",
device_class=SwitchDeviceClass.OUTLET,
exists_fn=lambda device: device.device_type == ATTR_DEVICE_MULTI_OUTLET,
plug_index=0,
),
YoLinkSwitchEntityDescription(
key="multi_outlet_plug_1",
name="Plug1",
device_class=SwitchDeviceClass.OUTLET,
exists_fn=lambda device: device.device_type == ATTR_DEVICE_MULTI_OUTLET,
plug_index=1,
),
YoLinkSwitchEntityDescription(
key="multi_outlet_plug_2",
name="Plug2",
device_class=SwitchDeviceClass.OUTLET,
exists_fn=lambda device: device.device_type == ATTR_DEVICE_MULTI_OUTLET,
plug_index=2,
),
YoLinkSwitchEntityDescription(
key="multi_outlet_plug_3",
name="Plug3",
device_class=SwitchDeviceClass.OUTLET,
exists_fn=lambda device: device.device_type == ATTR_DEVICE_MULTI_OUTLET,
plug_index=3,
),
YoLinkSwitchEntityDescription(
key="multi_outlet_plug_4",
name="Plug4",
device_class=SwitchDeviceClass.OUTLET,
exists_fn=lambda device: device.device_type == ATTR_DEVICE_MULTI_OUTLET,
plug_index=4,
),
)
DEVICE_TYPE = [ATTR_DEVICE_MANIPULATOR, ATTR_DEVICE_OUTLET, ATTR_DEVICE_SWITCH]
DEVICE_TYPE = [
ATTR_DEVICE_MANIPULATOR,
ATTR_DEVICE_MULTI_OUTLET,
ATTR_DEVICE_OUTLET,
ATTR_DEVICE_SWITCH,
]
async def async_setup_entry(
@ -108,18 +146,30 @@ class YoLinkSwitchEntity(YoLinkEntity, SwitchEntity):
f"{coordinator.device.device_name} ({self.entity_description.name})"
)
def _get_state(
self, state_value: str | list[str] | None, plug_index: int | None
) -> bool | None:
"""Parse state value."""
if isinstance(state_value, list) and plug_index is not None:
return state_value[plug_index] == "open"
return state_value == "open" if state_value is not None else None
@callback
def update_entity_state(self, state: dict[str, Any]) -> None:
def update_entity_state(self, state: dict[str, str | list[str]]) -> None:
"""Update HA Entity State."""
self._attr_is_on = self.entity_description.value(
state.get(self.entity_description.state_key)
self._attr_is_on = self._get_state(
state.get("state"), self.entity_description.plug_index
)
self.async_write_ha_state()
async def call_state_change(self, state: str) -> None:
"""Call setState api to change switch state."""
await self.call_device_api("setState", {"state": state})
self._attr_is_on = self.entity_description.value(state)
await self.call_device(
OutletRequestBuilder.set_state_request(
state, self.entity_description.plug_index
)
)
self._attr_is_on = self._get_state(state, self.entity_description.plug_index)
self.async_write_ha_state()
async def async_turn_on(self, **kwargs: Any) -> None: