Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Support for WeMo switches."""
2 
3 from __future__ import annotations
4 
5 from datetime import datetime, timedelta
6 from typing import Any
7 
8 from pywemo import CoffeeMaker, Insight, Maker, StandbyState, Switch
9 
10 from homeassistant.components.switch import SwitchEntity
11 from homeassistant.config_entries import ConfigEntry
12 from homeassistant.const import STATE_OFF, STATE_ON, STATE_STANDBY, STATE_UNKNOWN
13 from homeassistant.core import HomeAssistant
14 from homeassistant.helpers.entity_platform import AddEntitiesCallback
15 
16 from . import async_wemo_dispatcher_connect
17 from .coordinator import DeviceCoordinator
18 from .entity import WemoBinaryStateEntity
19 
20 SCAN_INTERVAL = timedelta(seconds=10)
21 PARALLEL_UPDATES = 0
22 
23 ATTR_COFFEMAKER_MODE = "coffeemaker_mode"
24 ATTR_CURRENT_STATE_DETAIL = "state_detail"
25 ATTR_ON_LATEST_TIME = "on_latest_time"
26 ATTR_ON_TODAY_TIME = "on_today_time"
27 ATTR_ON_TOTAL_TIME = "on_total_time"
28 ATTR_POWER_THRESHOLD = "power_threshold_w"
29 ATTR_SENSOR_STATE = "sensor_state"
30 ATTR_SWITCH_MODE = "switch_mode"
31 
32 MAKER_SWITCH_MOMENTARY = "momentary"
33 MAKER_SWITCH_TOGGLE = "toggle"
34 
35 
37  hass: HomeAssistant,
38  _config_entry: ConfigEntry,
39  async_add_entities: AddEntitiesCallback,
40 ) -> None:
41  """Set up WeMo switches."""
42 
43  async def _discovered_wemo(coordinator: DeviceCoordinator) -> None:
44  """Handle a discovered Wemo device."""
45  async_add_entities([WemoSwitch(coordinator)])
46 
47  await async_wemo_dispatcher_connect(hass, _discovered_wemo)
48 
49 
51  """Representation of a WeMo switch."""
52 
53  # All wemo devices used with WemoSwitch are subclasses of Switch.
54  wemo: Switch
55 
56  @property
57  def extra_state_attributes(self) -> dict[str, Any]:
58  """Return the state attributes of the device."""
59  attr: dict[str, Any] = {}
60  if isinstance(self.wemowemowemo, Maker):
61  # Is the maker sensor on or off.
62  if self.wemowemowemo.has_sensor:
63  # Note a state of 1 matches the WeMo app 'not triggered'!
64  if self.wemowemowemo.sensor_state:
65  attr[ATTR_SENSOR_STATE] = STATE_OFF
66  else:
67  attr[ATTR_SENSOR_STATE] = STATE_ON
68 
69  # Is the maker switch configured as toggle(0) or momentary (1).
70  if self.wemowemowemo.switch_mode:
71  attr[ATTR_SWITCH_MODE] = MAKER_SWITCH_MOMENTARY
72  else:
73  attr[ATTR_SWITCH_MODE] = MAKER_SWITCH_TOGGLE
74 
75  if isinstance(self.wemowemowemo, (Insight, CoffeeMaker)):
76  attr[ATTR_CURRENT_STATE_DETAIL] = self.detail_statedetail_state
77 
78  if isinstance(self.wemowemowemo, Insight):
79  attr[ATTR_ON_LATEST_TIME] = self.as_uptimeas_uptime(self.wemowemowemo.on_for)
80  attr[ATTR_ON_TODAY_TIME] = self.as_uptimeas_uptime(self.wemowemowemo.today_on_time)
81  attr[ATTR_ON_TOTAL_TIME] = self.as_uptimeas_uptime(self.wemowemowemo.total_on_time)
82  attr[ATTR_POWER_THRESHOLD] = self.wemowemowemo.threshold_power_watts
83 
84  if isinstance(self.wemowemowemo, CoffeeMaker):
85  attr[ATTR_COFFEMAKER_MODE] = self.wemowemowemo.mode
86 
87  return attr
88 
89  @staticmethod
90  def as_uptime(_seconds: int) -> str:
91  """Format seconds into uptime string in the format: 00d 00h 00m 00s."""
92  uptime = datetime(1, 1, 1) + timedelta(seconds=_seconds)
93  return (
94  f"{uptime.day - 1:0>2d}d {uptime.hour:0>2d}h "
95  f"{uptime.minute:0>2d}m {uptime.second:0>2d}s"
96  )
97 
98  @property
99  def detail_state(self) -> str:
100  """Return the state of the device."""
101  if isinstance(self.wemowemowemo, CoffeeMaker):
102  return self.wemowemowemo.mode_string
103  if isinstance(self.wemowemowemo, Insight):
104  standby_state = self.wemowemowemo.standby_state
105  if standby_state == StandbyState.ON:
106  return STATE_ON
107  if standby_state == StandbyState.OFF:
108  return STATE_OFF
109  if standby_state == StandbyState.STANDBY:
110  return STATE_STANDBY
111  return STATE_UNKNOWN
112  # Unreachable code statement.
113  raise RuntimeError
114 
115  @property
116  def icon(self) -> str | None:
117  """Return the icon of device based on its type."""
118  if isinstance(self.wemowemowemo, CoffeeMaker):
119  return "mdi:coffee"
120  return None
121 
122  def turn_on(self, **kwargs: Any) -> None:
123  """Turn the switch on."""
124  with self._wemo_call_wrapper_wemo_call_wrapper("turn on"):
125  self.wemowemowemo.on()
126 
127  def turn_off(self, **kwargs: Any) -> None:
128  """Turn the switch off."""
129  with self._wemo_call_wrapper_wemo_call_wrapper("turn off"):
130  self.wemowemowemo.off()
Generator[None] _wemo_call_wrapper(self, str message)
Definition: entity.py:68
dict[str, Any] extra_state_attributes(self)
Definition: switch.py:57
None async_setup_entry(HomeAssistant hass, ConfigEntry _config_entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:40
None async_wemo_dispatcher_connect(HomeAssistant hass, DispatchCallback dispatch)
Definition: __init__.py:159