Skip to content

Commit

Permalink
Add switch entity to Overkiz integration (#64000)
Browse files Browse the repository at this point in the history
  • Loading branch information
iMicknl committed Jan 17, 2022
1 parent 57bd8a7 commit 313ad2e
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 1 deletion.
1 change: 1 addition & 0 deletions .coveragerc
Expand Up @@ -823,6 +823,7 @@ omit =
homeassistant/components/overkiz/scene.py
homeassistant/components/overkiz/select.py
homeassistant/components/overkiz/sensor.py
homeassistant/components/overkiz/switch.py
homeassistant/components/ovo_energy/__init__.py
homeassistant/components/ovo_energy/const.py
homeassistant/components/ovo_energy/sensor.py
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/overkiz/const.py
Expand Up @@ -25,6 +25,7 @@
Platform.NUMBER,
Platform.SCENE,
Platform.SENSOR,
Platform.SWITCH,
]

IGNORED_OVERKIZ_DEVICES: list[UIClass | UIWidget] = [
Expand All @@ -35,5 +36,10 @@
# Used to map the Somfy widget and ui_class to the Home Assistant platform
OVERKIZ_DEVICE_TO_PLATFORM: dict[UIClass | UIWidget, Platform] = {
UIClass.DOOR_LOCK: Platform.LOCK,
UIWidget.DOMESTIC_HOT_WATER_TANK: Platform.SWITCH, # widgetName, uiClass is WaterHeatingSystem (not supported)
UIClass.LIGHT: Platform.LIGHT,
UIClass.ON_OFF: Platform.SWITCH,
UIWidget.RTD_INDOOR_SIREN: Platform.SWITCH, # widgetName, uiClass is Siren (not supported)
UIWidget.RTD_OUTDOOR_SIREN: Platform.SWITCH, # widgetName, uiClass is Siren (not supported)
UIClass.SWIMMING_POOL: Platform.SWITCH,
}
4 changes: 3 additions & 1 deletion homeassistant/components/overkiz/entity.py
Expand Up @@ -96,9 +96,11 @@ def __init__(
"""Initialize the device."""
super().__init__(device_url, coordinator)
self.entity_description = description
self._attr_name = f"{super().name} {self.entity_description.name}"
self._attr_unique_id = f"{super().unique_id}-{self.entity_description.key}"

if self.entity_description.name:
self._attr_name = f"{super().name} {self.entity_description.name}"


# Used by translations of state and select sensors
@unique
Expand Down
138 changes: 138 additions & 0 deletions homeassistant/components/overkiz/switch.py
@@ -0,0 +1,138 @@
"""Support for Overkiz switches."""
from __future__ import annotations

from collections.abc import Awaitable, Callable
from dataclasses import dataclass
from typing import Any

from pyoverkiz.enums import OverkizCommand, OverkizCommandParam, OverkizState
from pyoverkiz.enums.ui import UIClass, UIWidget
from pyoverkiz.types import StateType as OverkizStateType

from homeassistant.components.switch import (
SwitchDeviceClass,
SwitchEntity,
SwitchEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from . import HomeAssistantOverkizData
from .const import DOMAIN
from .entity import OverkizDescriptiveEntity


@dataclass
class OverkizSwitchDescriptionMixin:
"""Define an entity description mixin for switch entities."""

turn_on: Callable[[Callable[..., Awaitable[None]]], Awaitable[None]]
turn_off: Callable[[Callable[..., Awaitable[None]]], Awaitable[None]]
is_on: Callable[[Callable[[str], OverkizStateType]], bool]


@dataclass
class OverkizSwitchDescription(SwitchEntityDescription, OverkizSwitchDescriptionMixin):
"""Class to describe an Overkiz switch."""


SWITCH_DESCRIPTIONS: list[OverkizSwitchDescription] = [
OverkizSwitchDescription(
key=UIWidget.DOMESTIC_HOT_WATER_TANK,
turn_on=lambda execute_command: execute_command(
OverkizCommand.SET_FORCE_HEATING, OverkizCommandParam.ON
),
turn_off=lambda execute_command: execute_command(
OverkizCommand.SET_FORCE_HEATING, OverkizCommandParam.OFF
),
is_on=lambda select_state: (
select_state(OverkizState.IO_FORCE_HEATING) == OverkizCommandParam.ON
),
icon="mdi:water-boiler",
),
OverkizSwitchDescription(
key=UIClass.ON_OFF,
turn_on=lambda execute_command: execute_command(OverkizCommand.ON),
turn_off=lambda execute_command: execute_command(OverkizCommand.OFF),
is_on=lambda select_state: (
select_state(OverkizState.CORE_ON_OFF) == OverkizCommandParam.ON
),
device_class=SwitchDeviceClass.OUTLET,
),
OverkizSwitchDescription(
key=UIClass.SWIMMING_POOL,
turn_on=lambda execute_command: execute_command(OverkizCommand.ON),
turn_off=lambda execute_command: execute_command(OverkizCommand.OFF),
is_on=lambda select_state: (
select_state(OverkizState.CORE_ON_OFF) == OverkizCommandParam.ON
),
icon="mdi:pool",
),
OverkizSwitchDescription(
key=UIWidget.RTD_INDOOR_SIREN,
turn_on=lambda execute_command: execute_command(OverkizCommand.ON),
turn_off=lambda execute_command: execute_command(OverkizCommand.OFF),
is_on=lambda select_state: (
select_state(OverkizState.CORE_ON_OFF) == OverkizCommandParam.ON
),
icon="mdi:bell",
),
OverkizSwitchDescription(
key=UIWidget.RTD_OUTDOOR_SIREN,
turn_on=lambda execute_command: execute_command(OverkizCommand.ON),
turn_off=lambda execute_command: execute_command(OverkizCommand.OFF),
is_on=lambda select_state: (
select_state(OverkizState.CORE_ON_OFF) == OverkizCommandParam.ON
),
icon="mdi:bell",
),
]

SUPPORTED_DEVICES = {
description.key: description for description in SWITCH_DESCRIPTIONS
}


async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Overkiz switch from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]
entities: list[OverkizSwitch] = []

for device in data.platforms[Platform.SWITCH]:
if description := SUPPORTED_DEVICES.get(device.widget) or SUPPORTED_DEVICES.get(
device.ui_class
):
entities.append(
OverkizSwitch(
device.device_url,
data.coordinator,
description,
)
)

async_add_entities(entities)


class OverkizSwitch(OverkizDescriptiveEntity, SwitchEntity):
"""Representation of an Overkiz Switch."""

entity_description: OverkizSwitchDescription

@property
def is_on(self) -> bool:
"""Return True if entity is on."""
return self.entity_description.is_on(self.executor.select_state)

async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the entity on."""
await self.entity_description.turn_on(self.executor.async_execute_command)

async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off."""
await self.entity_description.turn_off(self.executor.async_execute_command)

0 comments on commit 313ad2e

Please sign in to comment.