Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Support for Xiaomi Aqara binary sensors."""
2 
3 import logging
4 from typing import Any
5 
6 from homeassistant.components.switch import SwitchEntity
7 from homeassistant.config_entries import ConfigEntry
8 from homeassistant.core import HomeAssistant
9 from homeassistant.helpers.entity_platform import AddEntitiesCallback
10 
11 from .const import DOMAIN, GATEWAYS_KEY
12 from .entity import XiaomiDevice
13 
14 _LOGGER = logging.getLogger(__name__)
15 
16 # Load power in watts (W)
17 ATTR_LOAD_POWER = "load_power"
18 
19 # Total (lifetime) power consumption in watts
20 ATTR_POWER_CONSUMED = "power_consumed"
21 ATTR_IN_USE = "in_use"
22 
23 LOAD_POWER = "load_power"
24 POWER_CONSUMED = "power_consumed"
25 ENERGY_CONSUMED = "energy_consumed"
26 IN_USE = "inuse"
27 
28 
30  hass: HomeAssistant,
31  config_entry: ConfigEntry,
32  async_add_entities: AddEntitiesCallback,
33 ) -> None:
34  """Perform the setup for Xiaomi devices."""
35  entities = []
36  gateway = hass.data[DOMAIN][GATEWAYS_KEY][config_entry.entry_id]
37  for device in gateway.devices["switch"]:
38  model = device["model"]
39  if model == "plug":
40  if "proto" not in device or int(device["proto"][0:1]) == 1:
41  data_key = "status"
42  else:
43  data_key = "channel_0"
44  entities.append(
46  device, "Plug", data_key, True, gateway, config_entry
47  )
48  )
49  elif model in (
50  "ctrl_neutral1",
51  "ctrl_neutral1.aq1",
52  "switch_b1lacn02",
53  "switch.b1lacn02",
54  ):
55  entities.append(
57  device, "Wall Switch", "channel_0", False, gateway, config_entry
58  )
59  )
60  elif model in (
61  "ctrl_ln1",
62  "ctrl_ln1.aq1",
63  "switch_b1nacn02",
64  "switch.b1nacn02",
65  ):
66  entities.append(
68  device, "Wall Switch LN", "channel_0", False, gateway, config_entry
69  )
70  )
71  elif model in (
72  "ctrl_neutral2",
73  "ctrl_neutral2.aq1",
74  "switch_b2lacn02",
75  "switch.b2lacn02",
76  ):
77  entities.append(
79  device,
80  "Wall Switch Left",
81  "channel_0",
82  False,
83  gateway,
84  config_entry,
85  )
86  )
87  entities.append(
89  device,
90  "Wall Switch Right",
91  "channel_1",
92  False,
93  gateway,
94  config_entry,
95  )
96  )
97  elif model in (
98  "ctrl_ln2",
99  "ctrl_ln2.aq1",
100  "switch_b2nacn02",
101  "switch.b2nacn02",
102  ):
103  entities.append(
105  device,
106  "Wall Switch LN Left",
107  "channel_0",
108  False,
109  gateway,
110  config_entry,
111  )
112  )
113  entities.append(
115  device,
116  "Wall Switch LN Right",
117  "channel_1",
118  False,
119  gateway,
120  config_entry,
121  )
122  )
123  elif model in ("86plug", "ctrl_86plug", "ctrl_86plug.aq1"):
124  if "proto" not in device or int(device["proto"][0:1]) == 1:
125  data_key = "status"
126  else:
127  data_key = "channel_0"
128  entities.append(
130  device, "Wall Plug", data_key, True, gateway, config_entry
131  )
132  )
133  async_add_entities(entities)
134 
135 
137  """Representation of a XiaomiPlug."""
138 
139  def __init__(
140  self,
141  device,
142  name,
143  data_key,
144  supports_power_consumption,
145  xiaomi_hub,
146  config_entry,
147  ):
148  """Initialize the XiaomiPlug."""
149  self._data_key_data_key = data_key
150  self._in_use_in_use = None
151  self._load_power_load_power = None
152  self._power_consumed_power_consumed = None
153  self._supports_power_consumption_supports_power_consumption = supports_power_consumption
154  # Polling needed for Zigbee plug only.
155  self._attr_should_poll_attr_should_poll_attr_should_poll = supports_power_consumption
156  super().__init__(device, name, xiaomi_hub, config_entry)
157 
158  @property
159  def icon(self):
160  """Return the icon to use in the frontend, if any."""
161  if self._data_key_data_key == "status":
162  return "mdi:power-plug"
163  return "mdi:power-socket"
164 
165  @property
166  def is_on(self):
167  """Return true if it is on."""
168  return self._state_state_state
169 
170  @property
172  """Return the state attributes."""
173  if self._supports_power_consumption_supports_power_consumption:
174  attrs = {
175  ATTR_IN_USE: self._in_use_in_use,
176  ATTR_LOAD_POWER: self._load_power_load_power,
177  ATTR_POWER_CONSUMED: self._power_consumed_power_consumed,
178  }
179  else:
180  attrs = {}
181  attrs.update(super().extra_state_attributes)
182  return attrs
183 
184  def turn_on(self, **kwargs: Any) -> None:
185  """Turn the switch on."""
186  if self._write_to_hub_write_to_hub(self._sid_sid, **{self._data_key_data_key: "on"}):
187  self._state_state_state = True
188  self.schedule_update_ha_stateschedule_update_ha_state()
189 
190  def turn_off(self, **kwargs: Any) -> None:
191  """Turn the switch off."""
192  if self._write_to_hub_write_to_hub(self._sid_sid, **{self._data_key_data_key: "off"}):
193  self._state_state_state = False
194  self.schedule_update_ha_stateschedule_update_ha_state()
195 
196  def parse_data(self, data, raw_data):
197  """Parse data sent by gateway."""
198  if IN_USE in data:
199  self._in_use_in_use = int(data[IN_USE])
200  if not self._in_use_in_use:
201  self._load_power_load_power = 0
202 
203  for key in (POWER_CONSUMED, ENERGY_CONSUMED):
204  if key in data:
205  self._power_consumed_power_consumed = round(float(data[key]), 2)
206  break
207 
208  if LOAD_POWER in data:
209  self._load_power_load_power = round(float(data[LOAD_POWER]), 2)
210 
211  value = data.get(self._data_key_data_key)
212  if value not in ["on", "off"]:
213  return False
214 
215  state = value == "on"
216  if self._state_state_state == state:
217  return False
218  self._state_state_state = state
219  return True
220 
221  def update(self) -> None:
222  """Get data from hub."""
223  _LOGGER.debug("Update data from hub: %s", self._name_name)
224  self._get_from_hub_get_from_hub(self._sid_sid)
def __init__(self, device, name, data_key, supports_power_consumption, xiaomi_hub, config_entry)
Definition: switch.py:147
None schedule_update_ha_state(self, bool force_refresh=False)
Definition: entity.py:1244
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:33