1
mirror of https://github.com/home-assistant/core synced 2024-09-03 08:14:07 +02:00
ha-core/homeassistant/components/sensibo/switch.py
2022-06-19 09:28:33 -05:00

147 lines
4.8 KiB
Python

"""Switch platform for Sensibo integration."""
from __future__ import annotations
from collections.abc import Callable, Mapping
from dataclasses import dataclass
from typing import Any
from pysensibo.model import SensiboDevice
from homeassistant.components.switch import (
SwitchDeviceClass,
SwitchEntity,
SwitchEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import SensiboDataUpdateCoordinator
from .entity import SensiboDeviceBaseEntity
PARALLEL_UPDATES = 0
@dataclass
class DeviceBaseEntityDescriptionMixin:
"""Mixin for required Sensibo base description keys."""
value_fn: Callable[[SensiboDevice], bool | None]
extra_fn: Callable[[SensiboDevice], dict[str, str | bool | None]]
command_on: str
command_off: str
remote_key: str
@dataclass
class SensiboDeviceSwitchEntityDescription(
SwitchEntityDescription, DeviceBaseEntityDescriptionMixin
):
"""Describes Sensibo Switch entity."""
DEVICE_SWITCH_TYPES: tuple[SensiboDeviceSwitchEntityDescription, ...] = (
SensiboDeviceSwitchEntityDescription(
key="timer_on_switch",
device_class=SwitchDeviceClass.SWITCH,
name="Timer",
icon="mdi:timer",
value_fn=lambda data: data.timer_on,
extra_fn=lambda data: {"id": data.timer_id, "turn_on": data.timer_state_on},
command_on="set_timer",
command_off="del_timer",
remote_key="timer_on",
),
)
def build_params(command: str, device_data: SensiboDevice) -> dict[str, Any] | None:
"""Build params for turning on switch."""
if command == "set_timer":
new_state = bool(device_data.ac_states["on"] is False)
params = {
"minutesFromNow": 60,
"acState": {**device_data.ac_states, "on": new_state},
}
return params
return None
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up Sensibo binary sensor platform."""
coordinator: SensiboDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
entities: list[SensiboDeviceSwitch] = []
entities.extend(
SensiboDeviceSwitch(coordinator, device_id, description)
for description in DEVICE_SWITCH_TYPES
for device_id, device_data in coordinator.data.parsed.items()
if device_data.model != "pure"
)
async_add_entities(entities)
class SensiboDeviceSwitch(SensiboDeviceBaseEntity, SwitchEntity):
"""Representation of a Sensibo Device Switch."""
entity_description: SensiboDeviceSwitchEntityDescription
def __init__(
self,
coordinator: SensiboDataUpdateCoordinator,
device_id: str,
entity_description: SensiboDeviceSwitchEntityDescription,
) -> None:
"""Initiate Sensibo Device Switch."""
super().__init__(
coordinator,
device_id,
)
self.entity_description = entity_description
self._attr_unique_id = f"{device_id}-{entity_description.key}"
self._attr_name = f"{self.device_data.name} {entity_description.name}"
@property
def is_on(self) -> bool | None:
"""Return True if entity is on."""
return self.entity_description.value_fn(self.device_data)
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the entity on."""
params = build_params(self.entity_description.command_on, self.device_data)
result = await self.async_send_command(
self.entity_description.command_on, params
)
if result["status"] == "success":
setattr(self.device_data, self.entity_description.remote_key, True)
self.async_write_ha_state()
return await self.coordinator.async_request_refresh()
raise HomeAssistantError(
f"Could not execute {self.entity_description.command_on} for device {self.name}"
)
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the entity off."""
result = await self.async_send_command(self.entity_description.command_off)
if result["status"] == "success":
setattr(self.device_data, self.entity_description.remote_key, False)
self.async_write_ha_state()
return await self.coordinator.async_request_refresh()
raise HomeAssistantError(
f"Could not execute {self.entity_description.command_off} for device {self.name}"
)
@property
def extra_state_attributes(self) -> Mapping[str, Any]:
"""Return additional attributes."""
return self.entity_description.extra_fn(self.device_data)