Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Platform for Kostal Plenticore switches."""
2 
3 from __future__ import annotations
4 
5 from dataclasses import dataclass
6 from datetime import timedelta
7 import logging
8 from typing import Any
9 
10 from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
11 from homeassistant.config_entries import ConfigEntry
12 from homeassistant.const import EntityCategory
13 from homeassistant.core import HomeAssistant
14 from homeassistant.helpers.device_registry import DeviceInfo
15 from homeassistant.helpers.entity_platform import AddEntitiesCallback
16 from homeassistant.helpers.update_coordinator import CoordinatorEntity
17 
18 from .const import DOMAIN
19 from .coordinator import SettingDataUpdateCoordinator
20 
21 _LOGGER = logging.getLogger(__name__)
22 
23 
24 @dataclass(frozen=True, kw_only=True)
26  """A class that describes plenticore switch entities."""
27 
28  module_id: str
29  is_on: str
30  on_value: str
31  on_label: str
32  off_value: str
33  off_label: str
34 
35 
36 SWITCH_SETTINGS_DATA = [
38  module_id="devices:local",
39  key="Battery:Strategy",
40  name="Battery Strategy",
41  is_on="1",
42  on_value="1",
43  on_label="Automatic",
44  off_value="2",
45  off_label="Automatic economical",
46  ),
47 ]
48 
49 
51  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
52 ) -> None:
53  """Add kostal plenticore Switch."""
54  plenticore = hass.data[DOMAIN][entry.entry_id]
55 
56  entities = []
57 
58  available_settings_data = await plenticore.client.get_settings()
59  settings_data_update_coordinator = SettingDataUpdateCoordinator(
60  hass,
61  _LOGGER,
62  "Settings Data",
63  timedelta(seconds=30),
64  plenticore,
65  )
66  for description in SWITCH_SETTINGS_DATA:
67  if (
68  description.module_id not in available_settings_data
69  or description.key
70  not in (
71  setting.id for setting in available_settings_data[description.module_id]
72  )
73  ):
74  _LOGGER.debug(
75  "Skipping non existing setting data %s/%s",
76  description.module_id,
77  description.key,
78  )
79  continue
80 
81  entities.append(
83  settings_data_update_coordinator,
84  description,
85  entry.entry_id,
86  entry.title,
87  plenticore.device_info,
88  )
89  )
90 
91  async_add_entities(entities)
92 
93 
95  CoordinatorEntity[SettingDataUpdateCoordinator], SwitchEntity
96 ):
97  """Representation of a Plenticore Switch."""
98 
99  _attr_entity_category = EntityCategory.CONFIG
100  entity_description: PlenticoreSwitchEntityDescription
101 
102  def __init__(
103  self,
104  coordinator: SettingDataUpdateCoordinator,
105  description: PlenticoreSwitchEntityDescription,
106  entry_id: str,
107  platform_name: str,
108  device_info: DeviceInfo,
109  ) -> None:
110  """Create a new Switch Entity for Plenticore process data."""
111  super().__init__(coordinator)
112  self.entity_descriptionentity_description = description
113  self.platform_nameplatform_name = platform_name
114  self.module_idmodule_id = description.module_id
115  self.data_iddata_id = description.key
116  self._name_name = description.name
117  self._is_on_is_on = description.is_on
118  self._attr_name_attr_name = f"{platform_name} {description.name}"
119  self.on_valueon_value = description.on_value
120  self.on_labelon_label = description.on_label
121  self.off_valueoff_value = description.off_value
122  self.off_labeloff_label = description.off_label
123  self._attr_unique_id_attr_unique_id = f"{entry_id}_{description.module_id}_{description.key}"
124 
125  self._attr_device_info_attr_device_info = device_info
126 
127  @property
128  def available(self) -> bool:
129  """Return if entity is available."""
130  return (
131  super().available
132  and self.coordinator.data is not None
133  and self.module_idmodule_id in self.coordinator.data
134  and self.data_iddata_id in self.coordinator.data[self.module_idmodule_id]
135  )
136 
137  async def async_added_to_hass(self) -> None:
138  """Register this entity on the Update Coordinator."""
139  await super().async_added_to_hass()
140  self.async_on_removeasync_on_remove(
141  self.coordinator.start_fetch_data(self.module_idmodule_id, self.data_iddata_id)
142  )
143 
144  async def async_will_remove_from_hass(self) -> None:
145  """Unregister this entity from the Update Coordinator."""
146  self.coordinator.stop_fetch_data(self.module_idmodule_id, self.data_iddata_id)
147  await super().async_will_remove_from_hass()
148 
149  async def async_turn_on(self, **kwargs: Any) -> None:
150  """Turn device on."""
151  if await self.coordinator.async_write_data(
152  self.module_idmodule_id, {self.data_iddata_id: self.on_valueon_value}
153  ):
154  self.coordinator.name = f"{self.platform_name} {self._name} {self.on_label}"
155  await self.coordinator.async_request_refresh()
156 
157  async def async_turn_off(self, **kwargs: Any) -> None:
158  """Turn device off."""
159  if await self.coordinator.async_write_data(
160  self.module_idmodule_id, {self.data_iddata_id: self.off_valueoff_value}
161  ):
162  self.coordinator.name = (
163  f"{self.platform_name} {self._name} {self.off_label}"
164  )
165  await self.coordinator.async_request_refresh()
166 
167  @property
168  def is_on(self) -> bool:
169  """Return true if device is on."""
170  if self.coordinator.data[self.module_idmodule_id][self.data_iddata_id] == self._is_on_is_on:
171  self.coordinator.name = f"{self.platform_name} {self._name} {self.on_label}"
172  else:
173  self.coordinator.name = (
174  f"{self.platform_name} {self._name} {self.off_label}"
175  )
176  return bool(self.coordinator.data[self.module_idmodule_id][self.data_iddata_id] == self._is_on_is_on)
None __init__(self, SettingDataUpdateCoordinator coordinator, PlenticoreSwitchEntityDescription description, str entry_id, str platform_name, DeviceInfo device_info)
Definition: switch.py:109
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:52