Home Assistant Unofficial Reference 2024.12.1
entity.py
Go to the documentation of this file.
1 """Support for Magic Home lights."""
2 
3 from __future__ import annotations
4 
5 from abc import abstractmethod
6 from typing import Any
7 
8 from flux_led.aiodevice import AIOWifiLedBulb
9 
10 from homeassistant import config_entries
11 from homeassistant.const import (
12  ATTR_CONNECTIONS,
13  ATTR_HW_VERSION,
14  ATTR_IDENTIFIERS,
15  ATTR_MANUFACTURER,
16  ATTR_MODEL,
17  ATTR_NAME,
18  ATTR_SW_VERSION,
19  CONF_MODEL,
20  CONF_NAME,
21 )
22 from homeassistant.core import callback
23 from homeassistant.helpers import device_registry as dr
24 from homeassistant.helpers.device_registry import DeviceInfo
25 from homeassistant.helpers.dispatcher import async_dispatcher_connect
26 from homeassistant.helpers.entity import Entity
27 from homeassistant.helpers.update_coordinator import CoordinatorEntity
28 
29 from .const import CONF_MINOR_VERSION, DOMAIN, SIGNAL_STATE_UPDATED
30 from .coordinator import FluxLedUpdateCoordinator
31 
32 
34  device: AIOWifiLedBulb, entry: config_entries.ConfigEntry
35 ) -> DeviceInfo:
36  version_num = device.version_num
37  if minor_version := entry.data.get(CONF_MINOR_VERSION):
38  sw_version = version_num + int(hex(minor_version)[2:]) / 100
39  sw_version_str = f"{sw_version:0.2f}"
40  else:
41  sw_version_str = str(device.version_num)
42  device_info: DeviceInfo = {
43  ATTR_IDENTIFIERS: {(DOMAIN, entry.entry_id)},
44  ATTR_MANUFACTURER: "Zengge",
45  ATTR_MODEL: device.model,
46  ATTR_NAME: entry.data.get(CONF_NAME, entry.title),
47  ATTR_SW_VERSION: sw_version_str,
48  }
49  if hw_model := entry.data.get(CONF_MODEL):
50  device_info[ATTR_HW_VERSION] = hw_model
51  if entry.unique_id:
52  device_info[ATTR_CONNECTIONS] = {(dr.CONNECTION_NETWORK_MAC, entry.unique_id)}
53  return device_info
54 
55 
57  """Representation of a Flux entity without a coordinator."""
58 
59  _attr_has_entity_name = True
60  _attr_should_poll = False
61 
62  def __init__(
63  self,
64  device: AIOWifiLedBulb,
66  ) -> None:
67  """Initialize the light."""
68  self._device: AIOWifiLedBulb = device
69  self.entryentry = entry
70  self._attr_device_info_attr_device_info = _async_device_info(self._device, entry)
71 
72 
73 class FluxEntity(CoordinatorEntity[FluxLedUpdateCoordinator]):
74  """Representation of a Flux entity with a coordinator."""
75 
76  _attr_has_entity_name = True
77 
78  def __init__(
79  self,
80  coordinator: FluxLedUpdateCoordinator,
81  base_unique_id: str,
82  key: str | None,
83  ) -> None:
84  """Initialize the light."""
85  super().__init__(coordinator)
86  self._device: AIOWifiLedBulb = coordinator.device
87  self._responding_responding = True
88  if key:
89  self._attr_unique_id_attr_unique_id = f"{base_unique_id}_{key}"
90  else:
91  self._attr_unique_id_attr_unique_id = base_unique_id
92  self._attr_device_info_attr_device_info = _async_device_info(self._device, coordinator.entry)
93 
94  async def _async_ensure_device_on(self) -> None:
95  """Turn the device on if it needs to be turned on before a command."""
96  if self._device.requires_turn_on and not self._device.is_on:
97  await self._device.async_turn_on()
98 
99  @property
100  def extra_state_attributes(self) -> dict[str, str]:
101  """Return the attributes."""
102  return {"ip_address": self._device.ipaddr}
103 
104  @callback
105  def _handle_coordinator_update(self) -> None:
106  """Handle updated data from the coordinator."""
107  if self.coordinator.last_update_success != self._responding_responding:
108  self.async_write_ha_state()
109  self._responding_responding = self.coordinator.last_update_success
110 
111  async def async_added_to_hass(self) -> None:
112  """Handle entity which will be added."""
113  self.async_on_remove(
115  self.hasshass,
116  SIGNAL_STATE_UPDATED.format(self._device.ipaddr),
117  self.async_write_ha_state,
118  )
119  )
120  await super().async_added_to_hass()
121 
122 
124  """Representation of a Flux entity that supports on/off."""
125 
126  @property
127  def is_on(self) -> bool:
128  """Return true if device is on."""
129  return self._device.is_on
130 
131  async def async_turn_on(self, **kwargs: Any) -> None:
132  """Turn the specified device on."""
133  await self._async_turn_on_async_turn_on(**kwargs)
134  self.async_write_ha_state()
135  await self.coordinator.async_request_refresh()
136 
137  @abstractmethod
138  async def _async_turn_on(self, **kwargs: Any) -> None:
139  """Turn the specified device on."""
140 
141  async def async_turn_off(self, **kwargs: Any) -> None:
142  """Turn the specified device off."""
143  await self._device.async_turn_off()
144  self.async_write_ha_state()
145  await self.coordinator.async_request_refresh()
None __init__(self, AIOWifiLedBulb device, config_entries.ConfigEntry entry)
Definition: entity.py:66
None __init__(self, FluxLedUpdateCoordinator coordinator, str base_unique_id, str|None key)
Definition: entity.py:83
None async_turn_on(self, **Any kwargs)
Definition: light.py:280
DeviceInfo _async_device_info(AIOWifiLedBulb device, config_entries.ConfigEntry entry)
Definition: entity.py:35
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103