Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """Component to interface with switches that can be controlled remotely."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 from enum import StrEnum
7 from functools import partial
8 import logging
9 
10 from propcache import cached_property
11 import voluptuous as vol
12 
13 from homeassistant.config_entries import ConfigEntry
14 from homeassistant.const import (
15  SERVICE_TOGGLE,
16  SERVICE_TURN_OFF,
17  SERVICE_TURN_ON,
18  STATE_ON,
19 )
20 from homeassistant.core import HomeAssistant
21 from homeassistant.helpers import config_validation as cv
23  DeprecatedConstantEnum,
24  all_with_deprecated_constants,
25  check_if_deprecated_constant,
26  dir_with_deprecated_constants,
27 )
28 from homeassistant.helpers.entity import ToggleEntity, ToggleEntityDescription
29 from homeassistant.helpers.entity_component import EntityComponent
30 from homeassistant.helpers.typing import ConfigType
31 from homeassistant.loader import bind_hass
32 from homeassistant.util.hass_dict import HassKey
33 
34 from .const import DOMAIN
35 
36 _LOGGER = logging.getLogger(__name__)
37 
38 DATA_COMPONENT: HassKey[EntityComponent[SwitchEntity]] = HassKey(DOMAIN)
39 ENTITY_ID_FORMAT = DOMAIN + ".{}"
40 PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA
41 PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE
42 SCAN_INTERVAL = timedelta(seconds=30)
43 
44 MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
45 
46 
47 class SwitchDeviceClass(StrEnum):
48  """Device class for switches."""
49 
50  OUTLET = "outlet"
51  SWITCH = "switch"
52 
53 
54 DEVICE_CLASSES_SCHEMA = vol.All(vol.Lower, vol.Coerce(SwitchDeviceClass))
55 
56 # DEVICE_CLASS* below are deprecated as of 2021.12
57 # use the SwitchDeviceClass enum instead.
58 DEVICE_CLASSES = [cls.value for cls in SwitchDeviceClass]
59 _DEPRECATED_DEVICE_CLASS_OUTLET = DeprecatedConstantEnum(
60  SwitchDeviceClass.OUTLET, "2025.1"
61 )
62 _DEPRECATED_DEVICE_CLASS_SWITCH = DeprecatedConstantEnum(
63  SwitchDeviceClass.SWITCH, "2025.1"
64 )
65 
66 # mypy: disallow-any-generics
67 
68 
69 @bind_hass
70 def is_on(hass: HomeAssistant, entity_id: str) -> bool:
71  """Return if the switch is on based on the statemachine.
72 
73  Async friendly.
74  """
75  return hass.states.is_state(entity_id, STATE_ON)
76 
77 
78 async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
79  """Track states and offer events for switches."""
80  component = hass.data[DATA_COMPONENT] = EntityComponent[SwitchEntity](
81  _LOGGER, DOMAIN, hass, SCAN_INTERVAL
82  )
83  await component.async_setup(config)
84 
85  component.async_register_entity_service(SERVICE_TURN_OFF, None, "async_turn_off")
86  component.async_register_entity_service(SERVICE_TURN_ON, None, "async_turn_on")
87  component.async_register_entity_service(SERVICE_TOGGLE, None, "async_toggle")
88 
89  return True
90 
91 
92 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
93  """Set up a config entry."""
94  return await hass.data[DATA_COMPONENT].async_setup_entry(entry)
95 
96 
97 async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
98  """Unload a config entry."""
99  return await hass.data[DATA_COMPONENT].async_unload_entry(entry)
100 
101 
102 class SwitchEntityDescription(ToggleEntityDescription, frozen_or_thawed=True):
103  """A class that describes switch entities."""
104 
105  device_class: SwitchDeviceClass | None = None
106 
107 
108 CACHED_PROPERTIES_WITH_ATTR_ = {
109  "device_class",
110 }
111 
112 
113 class SwitchEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
114  """Base class for switch entities."""
115 
116  entity_description: SwitchEntityDescription
117  _attr_device_class: SwitchDeviceClass | None
118 
119  @cached_property
120  def device_class(self) -> SwitchDeviceClass | None:
121  """Return the class of this entity."""
122  if hasattr(self, "_attr_device_class"):
123  return self._attr_device_class
124  if hasattr(self, "entity_description"):
125  return self.entity_description.device_class
126  return None
127 
128 
129 # These can be removed if no deprecated constant are in this module anymore
130 __getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
131 __dir__ = partial(
132  dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
133 )
134 __all__ = all_with_deprecated_constants(globals())
SwitchDeviceClass|None device_class(self)
Definition: __init__.py:120
bool is_on(HomeAssistant hass, str entity_id)
Definition: __init__.py:70
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:92
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
Definition: __init__.py:97
bool async_setup(HomeAssistant hass, ConfigType config)
Definition: __init__.py:78
list[str] all_with_deprecated_constants(dict[str, Any] module_globals)
Definition: deprecation.py:356