Add select entity to Overkiz integration (#62916)

This commit is contained in:
Mick Vleeshouwer 2022-01-13 14:35:44 -08:00 committed by GitHub
parent c3c14563e5
commit 5e3bfabfcf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 173 additions and 0 deletions

View File

@ -818,6 +818,7 @@ omit =
homeassistant/components/overkiz/lock.py homeassistant/components/overkiz/lock.py
homeassistant/components/overkiz/number.py homeassistant/components/overkiz/number.py
homeassistant/components/overkiz/scene.py homeassistant/components/overkiz/scene.py
homeassistant/components/overkiz/select.py
homeassistant/components/overkiz/sensor.py homeassistant/components/overkiz/sensor.py
homeassistant/components/ovo_energy/__init__.py homeassistant/components/ovo_energy/__init__.py
homeassistant/components/ovo_energy/const.py homeassistant/components/ovo_energy/const.py

View File

@ -1,9 +1,12 @@
"""Parent class for every Overkiz device.""" """Parent class for every Overkiz device."""
from __future__ import annotations from __future__ import annotations
from enum import unique
from pyoverkiz.enums import OverkizAttribute, OverkizState from pyoverkiz.enums import OverkizAttribute, OverkizState
from pyoverkiz.models import Device from pyoverkiz.models import Device
from homeassistant.backports.enum import StrEnum
from homeassistant.helpers.entity import DeviceInfo, EntityDescription from homeassistant.helpers.entity import DeviceInfo, EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
@ -95,3 +98,12 @@ class OverkizDescriptiveEntity(OverkizEntity):
self.entity_description = description self.entity_description = description
self._attr_name = f"{super().name} {self.entity_description.name}" self._attr_name = f"{super().name} {self.entity_description.name}"
self._attr_unique_id = f"{super().unique_id}-{self.entity_description.key}" self._attr_unique_id = f"{super().unique_id}-{self.entity_description.key}"
# Used by translations of state and select sensors
@unique
class OverkizDeviceClass(StrEnum):
"""Device class for Overkiz specific devices."""
OPEN_CLOSED_PEDESTRIAN = "overkiz__open_closed_pedestrian"
MEMORIZED_SIMPLE_VOLUME = "overkiz__memorized_simple_volume"

View File

@ -0,0 +1,134 @@
"""Support for Overkiz select."""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState
from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import HomeAssistantOverkizData
from .const import DOMAIN, IGNORED_OVERKIZ_DEVICES
from .entity import OverkizDescriptiveEntity, OverkizDeviceClass
@dataclass
class OverkizSelectDescriptionMixin:
"""Define an entity description mixin for select entities."""
options: list[str | OverkizCommandParam]
select_option: Callable[[str, Callable[..., Awaitable[None]]], Awaitable[None]]
@dataclass
class OverkizSelectDescription(SelectEntityDescription, OverkizSelectDescriptionMixin):
"""Class to describe an Overkiz select entity."""
def _select_option_open_closed_pedestrian(
option: str, execute_command: Callable[..., Awaitable[None]]
) -> Awaitable[None]:
"""Change the selected option for Open/Closed/Pedestrian."""
return execute_command(
{
OverkizCommandParam.CLOSED: OverkizCommand.CLOSE,
OverkizCommandParam.OPEN: OverkizCommand.OPEN,
OverkizCommandParam.PEDESTRIAN: OverkizCommand.SET_PEDESTRIAN_POSITION,
}[OverkizCommandParam(option)],
None,
)
def _select_option_memorized_simple_volume(
option: str, execute_command: Callable[..., Awaitable[None]]
) -> Awaitable[None]:
"""Change the selected option for Memorized Simple Volume."""
return execute_command(OverkizCommand.SET_MEMORIZED_SIMPLE_VOLUME, option)
SELECT_DESCRIPTIONS: list[OverkizSelectDescription] = [
OverkizSelectDescription(
key=OverkizState.CORE_OPEN_CLOSED_PEDESTRIAN,
name="Position",
icon="mdi:content-save-cog",
options=[
OverkizCommandParam.OPEN,
OverkizCommandParam.PEDESTRIAN,
OverkizCommandParam.CLOSED,
],
select_option=_select_option_open_closed_pedestrian,
device_class=OverkizDeviceClass.OPEN_CLOSED_PEDESTRIAN,
),
OverkizSelectDescription(
key=OverkizState.IO_MEMORIZED_SIMPLE_VOLUME,
name="Memorized Simple Volume",
icon="mdi:volume-high",
options=[OverkizCommandParam.STANDARD, OverkizCommandParam.HIGHEST],
select_option=_select_option_memorized_simple_volume,
entity_category=EntityCategory.CONFIG,
device_class=OverkizDeviceClass.MEMORIZED_SIMPLE_VOLUME,
),
]
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Overkiz select from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]
entities: list[OverkizSelect] = []
key_supported_states = {
description.key: description for description in SELECT_DESCRIPTIONS
}
for device in data.coordinator.data.values():
if (
device.widget in IGNORED_OVERKIZ_DEVICES
or device.ui_class in IGNORED_OVERKIZ_DEVICES
):
continue
for state in device.definition.states:
if description := key_supported_states.get(state.qualified_name):
entities.append(
OverkizSelect(
device.device_url,
data.coordinator,
description,
)
)
async_add_entities(entities)
class OverkizSelect(OverkizDescriptiveEntity, SelectEntity):
"""Representation of an Overkiz Select entity."""
entity_description: OverkizSelectDescription
@property
def current_option(self) -> str | None:
"""Return the selected entity option to represent the entity state."""
if state := self.device.states.get(self.entity_description.key):
return str(state.value)
return None
@property
def options(self) -> list[str]:
"""Return a set of selectable options."""
return self.entity_description.options
async def async_select_option(self, option: str) -> None:
"""Change the selected option."""
await self.entity_description.select_option(
option, self.executor.async_execute_command
)

View File

@ -0,0 +1,13 @@
{
"state": {
"overkiz__open_closed_pedestrian": {
"open": "Open",
"pedestrian": "Pedestrian",
"closed": "Closed"
},
"overkiz__memorized_simple_volume": {
"highest": "Highest",
"standard": "Standard"
}
}
}

View File

@ -0,0 +1,13 @@
{
"state": {
"overkiz__memorized_simple_volume": {
"highest": "Highest",
"standard": "Standard"
},
"overkiz__open_closed_pedestrian": {
"closed": "Closed",
"open": "Open",
"pedestrian": "Pedestrian"
}
}
}