forked from home-assistant/core
/
switch.py
146 lines (116 loc) · 4.78 KB
/
switch.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
"""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)