Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Support for LCN switches."""
2 
3 from collections.abc import Iterable
4 from functools import partial
5 from typing import Any
6 
7 import pypck
8 
9 from homeassistant.components.switch import DOMAIN as DOMAIN_SWITCH, SwitchEntity
10 from homeassistant.config_entries import ConfigEntry
11 from homeassistant.const import CONF_DOMAIN, CONF_ENTITIES
12 from homeassistant.core import HomeAssistant
13 from homeassistant.helpers.entity_platform import AddEntitiesCallback
14 from homeassistant.helpers.typing import ConfigType
15 
16 from .const import (
17  ADD_ENTITIES_CALLBACKS,
18  CONF_DOMAIN_DATA,
19  CONF_OUTPUT,
20  DOMAIN,
21  OUTPUT_PORTS,
22  RELAY_PORTS,
23  SETPOINTS,
24 )
25 from .entity import LcnEntity
26 from .helpers import InputType
27 
28 PARALLEL_UPDATES = 0
29 
30 
32  config_entry: ConfigEntry,
33  async_add_entities: AddEntitiesCallback,
34  entity_configs: Iterable[ConfigType],
35 ) -> None:
36  """Add entities for this domain."""
37  entities: list[
38  LcnOutputSwitch | LcnRelaySwitch | LcnRegulatorLockSwitch | LcnKeyLockSwitch
39  ] = []
40  for entity_config in entity_configs:
41  if entity_config[CONF_DOMAIN_DATA][CONF_OUTPUT] in OUTPUT_PORTS:
42  entities.append(LcnOutputSwitch(entity_config, config_entry))
43  elif entity_config[CONF_DOMAIN_DATA][CONF_OUTPUT] in RELAY_PORTS:
44  entities.append(LcnRelaySwitch(entity_config, config_entry))
45  elif entity_config[CONF_DOMAIN_DATA][CONF_OUTPUT] in SETPOINTS:
46  entities.append(LcnRegulatorLockSwitch(entity_config, config_entry))
47  else: # in KEYS
48  entities.append(LcnKeyLockSwitch(entity_config, config_entry))
49 
50  async_add_entities(entities)
51 
52 
54  hass: HomeAssistant,
55  config_entry: ConfigEntry,
56  async_add_entities: AddEntitiesCallback,
57 ) -> None:
58  """Set up LCN switch entities from a config entry."""
59  add_entities = partial(
60  add_lcn_switch_entities,
61  config_entry,
62  async_add_entities,
63  )
64 
65  hass.data[DOMAIN][config_entry.entry_id][ADD_ENTITIES_CALLBACKS].update(
66  {DOMAIN_SWITCH: add_entities}
67  )
68 
70  (
71  entity_config
72  for entity_config in config_entry.data[CONF_ENTITIES]
73  if entity_config[CONF_DOMAIN] == DOMAIN_SWITCH
74  ),
75  )
76 
77 
78 class LcnOutputSwitch(LcnEntity, SwitchEntity):
79  """Representation of a LCN switch for output ports."""
80 
81  _attr_is_on = False
82 
83  def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
84  """Initialize the LCN switch."""
85  super().__init__(config, config_entry)
86 
87  self.outputoutput = pypck.lcn_defs.OutputPort[config[CONF_DOMAIN_DATA][CONF_OUTPUT]]
88 
89  async def async_added_to_hass(self) -> None:
90  """Run when entity about to be added to hass."""
91  await super().async_added_to_hass()
92  if not self.device_connectiondevice_connection.is_group:
93  await self.device_connectiondevice_connection.activate_status_request_handler(self.outputoutput)
94 
95  async def async_will_remove_from_hass(self) -> None:
96  """Run when entity will be removed from hass."""
97  await super().async_will_remove_from_hass()
98  if not self.device_connectiondevice_connection.is_group:
99  await self.device_connectiondevice_connection.cancel_status_request_handler(self.outputoutput)
100 
101  async def async_turn_on(self, **kwargs: Any) -> None:
102  """Turn the entity on."""
103  if not await self.device_connectiondevice_connection.dim_output(self.outputoutput.value, 100, 0):
104  return
105  self._attr_is_on_attr_is_on_attr_is_on = True
106  self.async_write_ha_stateasync_write_ha_state()
107 
108  async def async_turn_off(self, **kwargs: Any) -> None:
109  """Turn the entity off."""
110  if not await self.device_connectiondevice_connection.dim_output(self.outputoutput.value, 0, 0):
111  return
112  self._attr_is_on_attr_is_on_attr_is_on = False
113  self.async_write_ha_stateasync_write_ha_state()
114 
115  def input_received(self, input_obj: InputType) -> None:
116  """Set switch state when LCN input object (command) is received."""
117  if (
118  not isinstance(input_obj, pypck.inputs.ModStatusOutput)
119  or input_obj.get_output_id() != self.outputoutput.value
120  ):
121  return
122 
123  self._attr_is_on_attr_is_on_attr_is_on = input_obj.get_percent() > 0
124  self.async_write_ha_stateasync_write_ha_state()
125 
126 
127 class LcnRelaySwitch(LcnEntity, SwitchEntity):
128  """Representation of a LCN switch for relay ports."""
129 
130  _attr_is_on = False
131 
132  def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
133  """Initialize the LCN switch."""
134  super().__init__(config, config_entry)
135 
136  self.outputoutput = pypck.lcn_defs.RelayPort[config[CONF_DOMAIN_DATA][CONF_OUTPUT]]
137 
138  async def async_added_to_hass(self) -> None:
139  """Run when entity about to be added to hass."""
140  await super().async_added_to_hass()
141  if not self.device_connectiondevice_connection.is_group:
142  await self.device_connectiondevice_connection.activate_status_request_handler(self.outputoutput)
143 
144  async def async_will_remove_from_hass(self) -> None:
145  """Run when entity will be removed from hass."""
146  await super().async_will_remove_from_hass()
147  if not self.device_connectiondevice_connection.is_group:
148  await self.device_connectiondevice_connection.cancel_status_request_handler(self.outputoutput)
149 
150  async def async_turn_on(self, **kwargs: Any) -> None:
151  """Turn the entity on."""
152  states = [pypck.lcn_defs.RelayStateModifier.NOCHANGE] * 8
153  states[self.outputoutput.value] = pypck.lcn_defs.RelayStateModifier.ON
154  if not await self.device_connectiondevice_connection.control_relays(states):
155  return
156  self._attr_is_on_attr_is_on_attr_is_on = True
157  self.async_write_ha_stateasync_write_ha_state()
158 
159  async def async_turn_off(self, **kwargs: Any) -> None:
160  """Turn the entity off."""
161  states = [pypck.lcn_defs.RelayStateModifier.NOCHANGE] * 8
162  states[self.outputoutput.value] = pypck.lcn_defs.RelayStateModifier.OFF
163  if not await self.device_connectiondevice_connection.control_relays(states):
164  return
165  self._attr_is_on_attr_is_on_attr_is_on = False
166  self.async_write_ha_stateasync_write_ha_state()
167 
168  def input_received(self, input_obj: InputType) -> None:
169  """Set switch state when LCN input object (command) is received."""
170  if not isinstance(input_obj, pypck.inputs.ModStatusRelays):
171  return
172 
173  self._attr_is_on_attr_is_on_attr_is_on = input_obj.get_state(self.outputoutput.value)
174  self.async_write_ha_stateasync_write_ha_state()
175 
176 
177 class LcnRegulatorLockSwitch(LcnEntity, SwitchEntity):
178  """Representation of a LCN switch for regulator locks."""
179 
180  _attr_is_on = False
181 
182  def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
183  """Initialize the LCN switch."""
184  super().__init__(config, config_entry)
185 
186  self.setpoint_variablesetpoint_variable = pypck.lcn_defs.Var[
187  config[CONF_DOMAIN_DATA][CONF_OUTPUT]
188  ]
189  self.reg_idreg_id = pypck.lcn_defs.Var.to_set_point_id(self.setpoint_variablesetpoint_variable)
190 
191  async def async_added_to_hass(self) -> None:
192  """Run when entity about to be added to hass."""
193  await super().async_added_to_hass()
194  if not self.device_connectiondevice_connection.is_group:
195  await self.device_connectiondevice_connection.activate_status_request_handler(
196  self.setpoint_variablesetpoint_variable
197  )
198 
199  async def async_will_remove_from_hass(self) -> None:
200  """Run when entity will be removed from hass."""
201  await super().async_will_remove_from_hass()
202  if not self.device_connectiondevice_connection.is_group:
203  await self.device_connectiondevice_connection.cancel_status_request_handler(
204  self.setpoint_variablesetpoint_variable
205  )
206 
207  async def async_turn_on(self, **kwargs: Any) -> None:
208  """Turn the entity on."""
209  if not await self.device_connectiondevice_connection.lock_regulator(self.reg_idreg_id, True):
210  return
211  self._attr_is_on_attr_is_on_attr_is_on = True
212  self.async_write_ha_stateasync_write_ha_state()
213 
214  async def async_turn_off(self, **kwargs: Any) -> None:
215  """Turn the entity off."""
216  if not await self.device_connectiondevice_connection.lock_regulator(self.reg_idreg_id, False):
217  return
218  self._attr_is_on_attr_is_on_attr_is_on = False
219  self.async_write_ha_stateasync_write_ha_state()
220 
221  def input_received(self, input_obj: InputType) -> None:
222  """Set switch state when LCN input object (command) is received."""
223  if (
224  not isinstance(input_obj, pypck.inputs.ModStatusVar)
225  or input_obj.get_var() != self.setpoint_variablesetpoint_variable
226  ):
227  return
228 
229  self._attr_is_on_attr_is_on_attr_is_on = input_obj.get_value().is_locked_regulator()
230  self.async_write_ha_stateasync_write_ha_state()
231 
232 
233 class LcnKeyLockSwitch(LcnEntity, SwitchEntity):
234  """Representation of a LCN switch for key locks."""
235 
236  _attr_is_on = False
237 
238  def __init__(self, config: ConfigType, config_entry: ConfigEntry) -> None:
239  """Initialize the LCN switch."""
240  super().__init__(config, config_entry)
241 
242  self.keykey = pypck.lcn_defs.Key[config[CONF_DOMAIN_DATA][CONF_OUTPUT]]
243  self.table_idtable_id = ord(self.keykey.name[0]) - 65
244  self.key_idkey_id = int(self.keykey.name[1]) - 1
245 
246  async def async_added_to_hass(self) -> None:
247  """Run when entity about to be added to hass."""
248  await super().async_added_to_hass()
249  if not self.device_connectiondevice_connection.is_group:
250  await self.device_connectiondevice_connection.activate_status_request_handler(self.keykey)
251 
252  async def async_will_remove_from_hass(self) -> None:
253  """Run when entity will be removed from hass."""
254  await super().async_will_remove_from_hass()
255  if not self.device_connectiondevice_connection.is_group:
256  await self.device_connectiondevice_connection.cancel_status_request_handler(self.keykey)
257 
258  async def async_turn_on(self, **kwargs: Any) -> None:
259  """Turn the entity on."""
260  states = [pypck.lcn_defs.KeyLockStateModifier.NOCHANGE] * 8
261  states[self.key_idkey_id] = pypck.lcn_defs.KeyLockStateModifier.ON
262 
263  if not await self.device_connectiondevice_connection.lock_keys(self.table_idtable_id, states):
264  return
265 
266  self._attr_is_on_attr_is_on_attr_is_on = True
267  self.async_write_ha_stateasync_write_ha_state()
268 
269  async def async_turn_off(self, **kwargs: Any) -> None:
270  """Turn the entity off."""
271  states = [pypck.lcn_defs.KeyLockStateModifier.NOCHANGE] * 8
272  states[self.key_idkey_id] = pypck.lcn_defs.KeyLockStateModifier.OFF
273 
274  if not await self.device_connectiondevice_connection.lock_keys(self.table_idtable_id, states):
275  return
276 
277  self._attr_is_on_attr_is_on_attr_is_on = False
278  self.async_write_ha_stateasync_write_ha_state()
279 
280  def input_received(self, input_obj: InputType) -> None:
281  """Set switch state when LCN input object (command) is received."""
282  if (
283  not isinstance(input_obj, pypck.inputs.ModStatusKeyLocks)
284  or self.keykey not in pypck.lcn_defs.Key
285  ):
286  return
287 
288  self._attr_is_on_attr_is_on_attr_is_on = input_obj.get_state(self.table_idtable_id, self.key_idkey_id)
289  self.async_write_ha_stateasync_write_ha_state()
None input_received(self, InputType input_obj)
Definition: switch.py:280
None __init__(self, ConfigType config, ConfigEntry config_entry)
Definition: switch.py:238
None input_received(self, InputType input_obj)
Definition: switch.py:115
None __init__(self, ConfigType config, ConfigEntry config_entry)
Definition: switch.py:83
None input_received(self, InputType input_obj)
Definition: switch.py:221
None __init__(self, ConfigType config, ConfigEntry config_entry)
Definition: switch.py:182
None input_received(self, InputType input_obj)
Definition: switch.py:168
None __init__(self, ConfigType config, ConfigEntry config_entry)
Definition: switch.py:132
None add_entities(AsusWrtRouter router, AddEntitiesCallback async_add_entities, set[str] tracked)
IssData update(pyiss.ISS iss)
Definition: __init__.py:33
None add_lcn_switch_entities(ConfigEntry config_entry, AddEntitiesCallback async_add_entities, Iterable[ConfigType] entity_configs)
Definition: switch.py:35
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:57