Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Switches for the Elexa Guardian integration."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Awaitable, Callable, Mapping
6 from dataclasses import dataclass
7 from typing import Any
8 
9 from aioguardian import Client
10 
11 from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
12 from homeassistant.config_entries import ConfigEntry
13 from homeassistant.const import EntityCategory
14 from homeassistant.core import HomeAssistant, callback
15 from homeassistant.helpers.entity_platform import AddEntitiesCallback
16 
17 from . import GuardianData
18 from .const import API_VALVE_STATUS, API_WIFI_STATUS, DOMAIN
19 from .entity import ValveControllerEntity, ValveControllerEntityDescription
20 from .util import convert_exceptions_to_homeassistant_error
21 from .valve import GuardianValveState
22 
23 ATTR_AVG_CURRENT = "average_current"
24 ATTR_CONNECTED_CLIENTS = "connected_clients"
25 ATTR_INST_CURRENT = "instantaneous_current"
26 ATTR_INST_CURRENT_DDT = "instantaneous_current_ddt"
27 ATTR_STATION_CONNECTED = "station_connected"
28 ATTR_TRAVEL_COUNT = "travel_count"
29 
30 SWITCH_KIND_ONBOARD_AP = "onboard_ap"
31 SWITCH_KIND_VALVE = "valve"
32 
33 
34 @dataclass(frozen=True, kw_only=True)
36  SwitchEntityDescription, ValveControllerEntityDescription
37 ):
38  """Describe a Guardian valve controller switch."""
39 
40  extra_state_attributes_fn: Callable[[dict[str, Any]], Mapping[str, Any]]
41  is_on_fn: Callable[[dict[str, Any]], bool]
42  off_fn: Callable[[Client], Awaitable]
43  on_fn: Callable[[Client], Awaitable]
44 
45 
46 async def _async_disable_ap(client: Client) -> None:
47  """Disable the onboard AP."""
48  async with client:
49  await client.wifi.disable_ap()
50 
51 
52 async def _async_enable_ap(client: Client) -> None:
53  """Enable the onboard AP."""
54  async with client:
55  await client.wifi.enable_ap()
56 
57 
58 async def _async_close_valve(client: Client) -> None:
59  """Close the valve."""
60  async with client:
61  await client.valve.close()
62 
63 
64 async def _async_open_valve(client: Client) -> None:
65  """Open the valve."""
66  async with client:
67  await client.valve.open()
68 
69 
70 @callback
71 def is_open(data: dict[str, Any]) -> bool:
72  """Return if the valve is opening."""
73  return data["state"] in (
74  GuardianValveState.FINISH_OPENING,
75  GuardianValveState.OPEN,
76  GuardianValveState.OPENING,
77  GuardianValveState.START_OPENING,
78  )
79 
80 
81 VALVE_CONTROLLER_DESCRIPTIONS = (
83  key=SWITCH_KIND_ONBOARD_AP,
84  translation_key="onboard_access_point",
85  entity_category=EntityCategory.CONFIG,
86  extra_state_attributes_fn=lambda data: {
87  ATTR_CONNECTED_CLIENTS: data.get("ap_clients"),
88  ATTR_STATION_CONNECTED: data["station_connected"],
89  },
90  api_category=API_WIFI_STATUS,
91  is_on_fn=lambda data: data["ap_enabled"],
92  off_fn=_async_disable_ap,
93  on_fn=_async_enable_ap,
94  ),
96  key=SWITCH_KIND_VALVE,
97  translation_key="valve_controller",
98  api_category=API_VALVE_STATUS,
99  extra_state_attributes_fn=lambda data: {
100  ATTR_AVG_CURRENT: data["average_current"],
101  ATTR_INST_CURRENT: data["instantaneous_current"],
102  ATTR_INST_CURRENT_DDT: data["instantaneous_current_ddt"],
103  ATTR_TRAVEL_COUNT: data["travel_count"],
104  },
105  is_on_fn=is_open,
106  off_fn=_async_close_valve,
107  on_fn=_async_open_valve,
108  ),
109 )
110 
111 
113  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
114 ) -> None:
115  """Set up Guardian switches based on a config entry."""
116  data: GuardianData = hass.data[DOMAIN][entry.entry_id]
117 
119  ValveControllerSwitch(entry, data, description)
120  for description in VALVE_CONTROLLER_DESCRIPTIONS
121  )
122 
123 
125  """Define a switch related to a Guardian valve controller."""
126 
127  entity_description: ValveControllerSwitchDescription
128 
129  def __init__(
130  self,
131  entry: ConfigEntry,
132  data: GuardianData,
133  description: ValveControllerSwitchDescription,
134  ) -> None:
135  """Initialize."""
136  super().__init__(entry, data.valve_controller_coordinators, description)
137 
138  self._client_client_client = data.client
139 
140  @property
141  def extra_state_attributes(self) -> Mapping[str, Any]:
142  """Return entity specific state attributes."""
143  return self.entity_descriptionentity_description.extra_state_attributes_fn(self.coordinator.data)
144 
145  @property
146  def is_on(self) -> bool:
147  """Return True if entity is on."""
148  return self.entity_descriptionentity_description.is_on_fn(self.coordinator.data)
149 
150  @convert_exceptions_to_homeassistant_error
151  async def async_turn_off(self, **kwargs: Any) -> None:
152  """Turn the switch off."""
153  await self.entity_descriptionentity_description.off_fn(self._client_client_client)
154  await self.coordinator.async_request_refresh()
155 
156  @convert_exceptions_to_homeassistant_error
157  async def async_turn_on(self, **kwargs: Any) -> None:
158  """Turn the switch on."""
159  await self.entity_descriptionentity_description.on_fn(self._client_client_client)
160  await self.coordinator.async_request_refresh()
None __init__(self, ConfigEntry entry, GuardianData data, ValveControllerSwitchDescription description)
Definition: switch.py:134
None _async_disable_ap(Client client)
Definition: switch.py:46
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:114
bool is_open(dict[str, Any] data)
Definition: switch.py:71
None _async_open_valve(Client client)
Definition: switch.py:64
None _async_close_valve(Client client)
Definition: switch.py:58
None _async_enable_ap(Client client)
Definition: switch.py:52