1 """Support for Tasmota lights."""
3 from __future__
import annotations
7 from hatasmota
import light
as tasmota_light
8 from hatasmota.entity
import TasmotaEntity
as HATasmotaEntity, TasmotaEntityConfig
9 from hatasmota.light
import (
16 from hatasmota.models
import DiscoveryHashType
36 from .const
import DATA_REMOVE_DISCOVER_COMPONENT
37 from .discovery
import TASMOTA_DISCOVERY_ENTITY_NEW
38 from .entity
import TasmotaAvailability, TasmotaDiscoveryUpdate, TasmotaOnOffEntity
40 DEFAULT_BRIGHTNESS_MAX = 255
41 TASMOTA_BRIGHTNESS_MAX = 100
46 config_entry: ConfigEntry,
47 async_add_entities: AddEntitiesCallback,
49 """Set up Tasmota light dynamically through discovery."""
53 tasmota_entity: HATasmotaEntity, discovery_hash: DiscoveryHashType
55 """Discover and add a Tasmota light."""
57 [
TasmotaLight(tasmota_entity=tasmota_entity, discovery_hash=discovery_hash)]
60 hass.data[DATA_REMOVE_DISCOVER_COMPONENT.format(light.DOMAIN)] = (
63 TASMOTA_DISCOVERY_ENTITY_NEW.format(light.DOMAIN),
69 def clamp(value: float) -> float:
70 """Clamp value to the range 0..255."""
71 return min(
max(value, 0), 255)
75 """Scale brightness from 0..255 to 1..100."""
76 brightness_normalized = brightness / DEFAULT_BRIGHTNESS_MAX
77 device_brightness =
min(
78 round(brightness_normalized * TASMOTA_BRIGHTNESS_MAX),
79 TASMOTA_BRIGHTNESS_MAX,
82 return max(device_brightness, 1)
87 TasmotaDiscoveryUpdate,
91 """Representation of a Tasmota light."""
93 _tasmota_entity: tasmota_light.TasmotaLight
96 """Initialize Tasmota light."""
102 self.
_effect_effect: str |
None =
None
105 self.
_hs_hs: tuple[float, float] |
None =
None
114 self, update: TasmotaEntityConfig, write_state: bool =
True
116 """Handle updated discovery message."""
122 """(Re)Setup the entity."""
127 if light_type
in [LIGHT_TYPE_RGB, LIGHT_TYPE_RGBW, LIGHT_TYPE_RGBCW]:
134 if light_type == LIGHT_TYPE_RGBW:
137 if light_type
in [LIGHT_TYPE_COLDWARM, LIGHT_TYPE_RGBCW]:
149 if light_type
in [LIGHT_TYPE_RGB, LIGHT_TYPE_RGBW, LIGHT_TYPE_RGBCW]:
150 supported_features |= LightEntityFeature.EFFECT
153 supported_features |= LightEntityFeature.TRANSITION
159 """Handle state updates."""
161 if attributes := kwargs.get(
"attributes"):
162 if "brightness" in attributes:
163 brightness =
float(attributes[
"brightness"])
164 percent_bright = brightness / TASMOTA_BRIGHTNESS_MAX
166 if "color_hs" in attributes:
167 self.
_hs_hs = attributes[
"color_hs"]
168 if "color_temp" in attributes:
170 if "effect" in attributes:
172 if "white_value" in attributes:
173 white_value =
float(attributes[
"white_value"])
174 percent_white = white_value / TASMOTA_BRIGHTNESS_MAX
182 elif self.
_tasmota_entity_tasmota_entity.light_type == LIGHT_TYPE_RGBCW:
193 """Return the brightness of this light between 0..255."""
198 """Return the color mode of the light."""
203 """Return the color temperature in mired."""
208 """Return the coldest color_temp that this light supports."""
213 """Return the warmest color_temp that this light supports."""
218 """Return the current effect."""
223 """Return the list of supported effects."""
228 """Return the hs color value."""
229 if self.
_hs_hs
is None:
231 hs_color = self.
_hs_hs
232 return (hs_color[0], hs_color[1])
236 """Flag supported color modes."""
240 """Turn the entity on."""
243 attributes: dict[str, Any] = {}
245 if ATTR_HS_COLOR
in kwargs
and ColorMode.HS
in supported_color_modes:
246 hs_color = kwargs[ATTR_HS_COLOR]
247 attributes[
"color_hs"] = [hs_color[0], hs_color[1]]
249 if ATTR_WHITE
in kwargs
and ColorMode.WHITE
in supported_color_modes:
252 if ATTR_TRANSITION
in kwargs:
253 attributes[
"transition"] = kwargs[ATTR_TRANSITION]
258 if ATTR_COLOR_TEMP
in kwargs
and ColorMode.COLOR_TEMP
in supported_color_modes:
259 attributes[
"color_temp"] =
int(kwargs[ATTR_COLOR_TEMP])
261 if ATTR_EFFECT
in kwargs:
262 attributes[
"effect"] = kwargs[ATTR_EFFECT]
267 """Turn the entity off."""
268 attributes = {
"state":
"OFF"}
270 if ATTR_TRANSITION
in kwargs:
271 attributes[
"transition"] = kwargs[ATTR_TRANSITION]
None async_turn_on(self, **Any kwargs)
None __init__(self, **Any kwds)
None _setup_from_entity(self)
tuple[float, float]|None hs_color(self)
None discovery_update(self, TasmotaEntityConfig update, bool write_state=True)
set[str]|None supported_color_modes(self)
int|None brightness(self)
str|None color_mode(self)
int|None color_temp(self)
None state_updated(self, bool state, **Any kwargs)
list[str]|None effect_list(self)
None async_turn_off(self, **Any kwargs)
None async_write_ha_state(self)
bool add(self, _T matcher)
bool brightness_supported(Iterable[ColorMode|str]|None color_modes)
None async_discover(DiscoveryInfo discovery_info)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
float scale_brightness(float brightness)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)