1 """Support for Xiaomi Yeelight WiFi color bulb."""
3 from __future__
import annotations
8 from yeelight
import BulbException
9 from yeelight.aio
import KEY_CONNECTED, AsyncBulb
18 ACTIVE_MODE_NIGHTLIGHT,
21 UPDATE_REQUEST_PROPERTIES,
23 from .scanner
import YeelightScanner
25 _LOGGER = logging.getLogger(__name__)
30 """Generate a more human readable model."""
31 return model.replace(
"_",
" ").title()
36 """Generate a more human readable id."""
37 return hex(
int(id_, 16))
if id_
else "None"
42 """Generate a more human readable name."""
43 return f
"{async_format_model(model)} {async_format_id(id_)}"
48 """Generate name from capabilities."""
50 return f
"Yeelight {model_id}"
54 """Check if a push update needs the bg_power workaround.
56 Some devices will push the incorrect state for bg_power.
58 To work around this any time we are pushed an update
59 with bg_power, we force poll state which will be correct.
61 return "bg_power" in data
65 """Represents single Yeelight device."""
68 self, hass: HomeAssistant, host: str, config: dict[str, Any], bulb: AsyncBulb
70 """Initialize device."""
79 self.
_name_name: str |
None =
None
83 """Return bulb device."""
88 """Return the name of the device if any."""
89 return self.
_name_name
93 """Return device config."""
98 """Return hostname."""
99 return self.
_host_host
103 """Return true is device is available."""
108 """Set unavailable on api call failure due to a network issue."""
113 """Return configured/autodetected device model."""
118 """Return the firmware version."""
123 """Return the unique ID of the device."""
128 """Return true / false if nightlight is supported.
130 Uses brightness as it appears to be supported in both ceiling and other lights.
136 """Return true / false if nightlight is currently enabled."""
149 """Return true / false if color flow is currently running."""
154 return self.
bulbbulb.last_properties.get(
"active_mode")
158 return self.
bulbbulb.last_properties.get(
"flowing")
162 return self.
bulbbulb.last_properties.get(
"nl_br")
166 """Return bulb type."""
173 """Read new properties from the device."""
175 await self.
bulbbulb.async_get_properties(UPDATE_REQUEST_PROPERTIES)
179 except TimeoutError
as ex:
181 "timed out while trying to update device %s, %s: %s",
186 except OSError
as ex:
189 "Unable to update device %s, %s: %s", self.
_host_host, self.
namename, ex
192 except BulbException
as ex:
194 "Unable to update device %s, %s: %s", self.
_host_host, self.
namename, ex
198 """Fetch capabilities and setup name if available."""
199 scanner = YeelightScanner.async_get(self.
_hass_hass)
203 if name := self.
_config_config.
get(CONF_NAME):
210 self.
_name_name = f
"Yeelight {async_format_model_id(self.model, id_)}"
215 """Update device properties and send data updated signal."""
223 """Call a forced update."""
228 """Update push from device."""
229 _LOGGER.debug(
"Received callback: %s", data)
231 self.
_available_available = data.get(KEY_CONNECTED,
True)
233 not was_available
and self.
_available_available
def _async_forced_update(self, _now)
def async_mark_unavailable(self)
def _async_update_properties(self)
bool is_nightlight_supported(self)
bool is_color_flow_enabled(self)
def async_update_callback(self, data)
bool is_nightlight_enabled(self)
def async_update(self, force=False)
None __init__(self, HomeAssistant hass, str host, dict[str, Any] config, AsyncBulb bulb)
def _nightlight_brightness(self)
web.Response get(self, web.Request request, str config_key)
str _async_unique_name(dict capabilities)
str async_format_id(str|None id_)
str async_format_model_id(str model, str|None id_)
str async_format_model(str model)
def update_needs_bg_power_workaround(data)
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)
CALLBACK_TYPE async_call_later(HomeAssistant hass, float|timedelta delay, HassJob[[datetime], Coroutine[Any, Any, None]|None]|Callable[[datetime], Coroutine[Any, Any, None]|None] action)