Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Switcher integration Switch platform."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 import logging
7 from typing import Any
8 
9 from aioswitcher.api import Command, SwitcherApi, SwitcherBaseResponse
10 from aioswitcher.device import DeviceCategory, DeviceState
11 import voluptuous as vol
12 
13 from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity
14 from homeassistant.config_entries import ConfigEntry
15 from homeassistant.core import HomeAssistant, callback
16 from homeassistant.helpers import config_validation as cv, entity_platform
17 from homeassistant.helpers.dispatcher import async_dispatcher_connect
18 from homeassistant.helpers.entity_platform import AddEntitiesCallback
19 from homeassistant.helpers.typing import VolDictType
20 
21 from .const import (
22  CONF_AUTO_OFF,
23  CONF_TIMER_MINUTES,
24  SERVICE_SET_AUTO_OFF_NAME,
25  SERVICE_TURN_ON_WITH_TIMER_NAME,
26  SIGNAL_DEVICE_ADD,
27 )
28 from .coordinator import SwitcherDataUpdateCoordinator
29 from .entity import SwitcherEntity
30 
31 _LOGGER = logging.getLogger(__name__)
32 
33 API_CONTROL_DEVICE = "control_device"
34 API_SET_AUTO_SHUTDOWN = "set_auto_shutdown"
35 
36 SERVICE_SET_AUTO_OFF_SCHEMA: VolDictType = {
37  vol.Required(CONF_AUTO_OFF): cv.time_period_str,
38 }
39 
40 SERVICE_TURN_ON_WITH_TIMER_SCHEMA: VolDictType = {
41  vol.Required(CONF_TIMER_MINUTES): vol.All(
42  cv.positive_int, vol.Range(min=1, max=150)
43  ),
44 }
45 
46 
48  hass: HomeAssistant,
49  config_entry: ConfigEntry,
50  async_add_entities: AddEntitiesCallback,
51 ) -> None:
52  """Set up Switcher switch from config entry."""
53  platform = entity_platform.async_get_current_platform()
54 
55  platform.async_register_entity_service(
56  SERVICE_SET_AUTO_OFF_NAME,
57  SERVICE_SET_AUTO_OFF_SCHEMA,
58  "async_set_auto_off_service",
59  )
60 
61  platform.async_register_entity_service(
62  SERVICE_TURN_ON_WITH_TIMER_NAME,
63  SERVICE_TURN_ON_WITH_TIMER_SCHEMA,
64  "async_turn_on_with_timer_service",
65  )
66 
67  @callback
68  def async_add_switch(coordinator: SwitcherDataUpdateCoordinator) -> None:
69  """Add switch from Switcher device."""
70  if coordinator.data.device_type.category == DeviceCategory.POWER_PLUG:
72  elif coordinator.data.device_type.category == DeviceCategory.WATER_HEATER:
74 
75  config_entry.async_on_unload(
76  async_dispatcher_connect(hass, SIGNAL_DEVICE_ADD, async_add_switch)
77  )
78 
79 
81  """Representation of a Switcher switch entity."""
82 
83  _attr_name = None
84 
85  def __init__(self, coordinator: SwitcherDataUpdateCoordinator) -> None:
86  """Initialize the entity."""
87  super().__init__(coordinator)
88  self.control_resultcontrol_result: bool | None = None
89 
90  # Entity class attributes
91  self._attr_unique_id_attr_unique_id = f"{coordinator.device_id}-{coordinator.mac_address}"
92 
93  @callback
94  def _handle_coordinator_update(self) -> None:
95  """When device updates, clear control result that overrides state."""
96  self.control_resultcontrol_result = None
97  self.async_write_ha_stateasync_write_ha_state()
98 
99  async def _async_call_api(self, api: str, *args: Any) -> None:
100  """Call Switcher API."""
101  _LOGGER.debug(
102  "Calling api for %s, api: '%s', args: %s", self.coordinator.name, api, args
103  )
104  response: SwitcherBaseResponse | None = None
105  error = None
106 
107  try:
108  async with SwitcherApi(
109  self.coordinator.data.device_type,
110  self.coordinator.data.ip_address,
111  self.coordinator.data.device_id,
112  self.coordinator.data.device_key,
113  ) as swapi:
114  response = await getattr(swapi, api)(*args)
115  except (TimeoutError, OSError, RuntimeError) as err:
116  error = repr(err)
117 
118  if error or not response or not response.successful:
119  _LOGGER.error(
120  "Call api for %s failed, api: '%s', args: %s, response/error: %s",
121  self.coordinator.name,
122  api,
123  args,
124  response or error,
125  )
126  self.coordinator.last_update_success = False
127 
128  @property
129  def is_on(self) -> bool:
130  """Return True if entity is on."""
131  if self.control_resultcontrol_result is not None:
132  return self.control_resultcontrol_result
133 
134  return bool(self.coordinator.data.device_state == DeviceState.ON)
135 
136  async def async_turn_on(self, **kwargs: Any) -> None:
137  """Turn the entity on."""
138  await self._async_call_api_async_call_api(API_CONTROL_DEVICE, Command.ON)
139  self.control_resultcontrol_result = True
140  self.async_write_ha_stateasync_write_ha_state()
141 
142  async def async_turn_off(self, **kwargs: Any) -> None:
143  """Turn the entity off."""
144  await self._async_call_api_async_call_api(API_CONTROL_DEVICE, Command.OFF)
145  self.control_resultcontrol_result = False
146  self.async_write_ha_stateasync_write_ha_state()
147 
148  async def async_set_auto_off_service(self, auto_off: timedelta) -> None:
149  """Use for handling setting device auto-off service calls."""
150  _LOGGER.warning(
151  "Service '%s' is not supported by %s",
152  SERVICE_SET_AUTO_OFF_NAME,
153  self.coordinator.name,
154  )
155 
156  async def async_turn_on_with_timer_service(self, timer_minutes: int) -> None:
157  """Use for turning device on with a timer service calls."""
158  _LOGGER.warning(
159  "Service '%s' is not supported by %s",
160  SERVICE_TURN_ON_WITH_TIMER_NAME,
161  self.coordinator.name,
162  )
163 
164 
166  """Representation of a Switcher power plug switch entity."""
167 
168  _attr_device_class = SwitchDeviceClass.OUTLET
169 
170 
172  """Representation of a Switcher water heater switch entity."""
173 
174  _attr_device_class = SwitchDeviceClass.SWITCH
175 
176  async def async_set_auto_off_service(self, auto_off: timedelta) -> None:
177  """Use for handling setting device auto-off service calls."""
178  await self._async_call_api_async_call_api(API_SET_AUTO_SHUTDOWN, auto_off)
179  self.async_write_ha_stateasync_write_ha_state()
180 
181  async def async_turn_on_with_timer_service(self, timer_minutes: int) -> None:
182  """Use for turning device on with a timer service calls."""
183  await self._async_call_api_async_call_api(API_CONTROL_DEVICE, Command.ON, timer_minutes)
184  self.control_resultcontrol_resultcontrol_result = True
185  self.async_write_ha_stateasync_write_ha_state()
None __init__(self, SwitcherDataUpdateCoordinator coordinator)
Definition: switch.py:85
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:51
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103