1 """Support for MQTT Template lights."""
3 from __future__
import annotations
5 from collections.abc
import Callable
9 import voluptuous
as vol
22 filter_supported_color_modes,
38 from ..
import subscription
39 from ..config
import MQTT_RW_SCHEMA
40 from ..const
import CONF_COMMAND_TOPIC, CONF_STATE_TOPIC, PAYLOAD_NONE
41 from ..entity
import MqttEntity
42 from ..models
import (
48 from ..schemas
import MQTT_ENTITY_COMMON_SCHEMA
49 from .schema
import MQTT_LIGHT_SCHEMA_SCHEMA
50 from .schema_basic
import MQTT_LIGHT_ATTRIBUTES_BLOCKED
52 _LOGGER = logging.getLogger(__name__)
54 DOMAIN =
"mqtt_template"
56 DEFAULT_NAME =
"MQTT Template Light"
58 CONF_BLUE_TEMPLATE =
"blue_template"
59 CONF_BRIGHTNESS_TEMPLATE =
"brightness_template"
60 CONF_COLOR_TEMP_TEMPLATE =
"color_temp_template"
61 CONF_COMMAND_OFF_TEMPLATE =
"command_off_template"
62 CONF_COMMAND_ON_TEMPLATE =
"command_on_template"
63 CONF_EFFECT_LIST =
"effect_list"
64 CONF_EFFECT_TEMPLATE =
"effect_template"
65 CONF_GREEN_TEMPLATE =
"green_template"
66 CONF_MAX_MIREDS =
"max_mireds"
67 CONF_MIN_MIREDS =
"min_mireds"
68 CONF_RED_TEMPLATE =
"red_template"
70 COMMAND_TEMPLATES = (CONF_COMMAND_ON_TEMPLATE, CONF_COMMAND_OFF_TEMPLATE)
73 CONF_BRIGHTNESS_TEMPLATE,
74 CONF_COLOR_TEMP_TEMPLATE,
81 PLATFORM_SCHEMA_MODERN_TEMPLATE = (
82 MQTT_RW_SCHEMA.extend(
84 vol.Optional(CONF_BLUE_TEMPLATE): cv.template,
85 vol.Optional(CONF_BRIGHTNESS_TEMPLATE): cv.template,
86 vol.Optional(CONF_COLOR_TEMP_TEMPLATE): cv.template,
87 vol.Required(CONF_COMMAND_OFF_TEMPLATE): cv.template,
88 vol.Required(CONF_COMMAND_ON_TEMPLATE): cv.template,
89 vol.Optional(CONF_EFFECT_LIST): vol.All(cv.ensure_list, [cv.string]),
90 vol.Optional(CONF_EFFECT_TEMPLATE): cv.template,
91 vol.Optional(CONF_GREEN_TEMPLATE): cv.template,
92 vol.Optional(CONF_MAX_MIREDS): cv.positive_int,
93 vol.Optional(CONF_MIN_MIREDS): cv.positive_int,
94 vol.Optional(CONF_NAME): vol.Any(cv.string,
None),
95 vol.Optional(CONF_RED_TEMPLATE): cv.template,
96 vol.Optional(CONF_STATE_TEMPLATE): cv.template,
99 .extend(MQTT_ENTITY_COMMON_SCHEMA.schema)
100 .extend(MQTT_LIGHT_SCHEMA_SCHEMA.schema)
103 DISCOVERY_SCHEMA_TEMPLATE = vol.All(
104 PLATFORM_SCHEMA_MODERN_TEMPLATE.extend({}, extra=vol.REMOVE_EXTRA),
109 """Representation of a MQTT Template light."""
111 _default_name = DEFAULT_NAME
112 _entity_id_format = ENTITY_ID_FORMAT
113 _attributes_extra_blocked = MQTT_LIGHT_ATTRIBUTES_BLOCKED
115 _command_templates: dict[
116 str, Callable[[PublishPayloadType, TemplateVarsType], PublishPayloadType]
118 _value_templates: dict[str, Callable[[ReceivePayloadType], ReceivePayloadType]]
119 _fixed_color_mode: ColorMode | str |
None
120 _topics: dict[str, str |
None]
124 """Return the config schema."""
125 return DISCOVERY_SCHEMA_TEMPLATE
128 """(Re)Setup the entity."""
134 key: config.get(key)
for key
in (CONF_STATE_TOPIC, CONF_COMMAND_TOPIC)
138 for key
in COMMAND_TEMPLATES
142 config.get(key), entity=self
143 ).async_render_with_possible_json_value
144 for key
in VALUE_TEMPLATES
146 optimistic: bool = config[CONF_OPTIMISTIC]
149 or self.
_topics_topics[CONF_STATE_TOPIC]
is None
150 or CONF_STATE_TEMPLATE
not in self.
_config_config
154 color_modes = {ColorMode.ONOFF}
155 if CONF_BRIGHTNESS_TEMPLATE
in config:
156 color_modes.add(ColorMode.BRIGHTNESS)
157 if CONF_COLOR_TEMP_TEMPLATE
in config:
158 color_modes.add(ColorMode.COLOR_TEMP)
160 CONF_RED_TEMPLATE
in config
161 and CONF_GREEN_TEMPLATE
in config
162 and CONF_BLUE_TEMPLATE
in config
164 color_modes.add(ColorMode.HS)
171 features = LightEntityFeature.FLASH | LightEntityFeature.TRANSITION
172 if config.get(CONF_EFFECT_LIST)
is not None:
173 features = features | LightEntityFeature.EFFECT
177 """Update the color_mode attribute."""
185 """Handle new MQTT messages."""
186 state = self.
_value_templates_value_templates[CONF_STATE_TEMPLATE](msg.payload)
187 if state == STATE_ON:
189 elif state == STATE_OFF:
191 elif state == PAYLOAD_NONE:
194 _LOGGER.warning(
"Invalid state value received")
196 if CONF_BRIGHTNESS_TEMPLATE
in self.
_config_config:
198 if brightness :=
int(
199 self.
_value_templates_value_templates[CONF_BRIGHTNESS_TEMPLATE](msg.payload)
204 "Ignoring zero brightness value for entity %s",
209 _LOGGER.warning(
"Invalid brightness value received from %s", msg.topic)
211 if CONF_COLOR_TEMP_TEMPLATE
in self.
_config_config:
213 color_temp = self.
_value_templates_value_templates[CONF_COLOR_TEMP_TEMPLATE](
217 int(color_temp)
if color_temp !=
"None" else None
220 _LOGGER.warning(
"Invalid color temperature value received")
223 CONF_RED_TEMPLATE
in self.
_config_config
224 and CONF_GREEN_TEMPLATE
in self.
_config_config
225 and CONF_BLUE_TEMPLATE
in self.
_config_config
229 green = self.
_value_templates_value_templates[CONF_GREEN_TEMPLATE](msg.payload)
230 blue = self.
_value_templates_value_templates[CONF_BLUE_TEMPLATE](msg.payload)
231 if red ==
"None" and green ==
"None" and blue ==
"None":
239 _LOGGER.warning(
"Invalid color value received")
241 if CONF_EFFECT_TEMPLATE
in self.
_config_config:
244 effect_list := self.
_config_config[CONF_EFFECT_LIST]
245 )
and effect
in effect_list:
248 _LOGGER.warning(
"Unsupported effect value received")
252 """(Re)Subscribe to topics."""
267 """(Re)Subscribe to topics."""
268 subscription.async_subscribe_topics_internal(self.
hasshasshass, self.
_sub_state_sub_state)
272 self.
_attr_is_on_attr_is_on = last_state.state == STATE_ON
273 if last_state.attributes.get(ATTR_BRIGHTNESS):
274 self.
_attr_brightness_attr_brightness = last_state.attributes.get(ATTR_BRIGHTNESS)
275 if last_state.attributes.get(ATTR_HS_COLOR):
276 self.
_attr_hs_color_attr_hs_color = last_state.attributes.get(ATTR_HS_COLOR)
278 if last_state.attributes.get(ATTR_COLOR_TEMP):
279 self.
_attr_color_temp_attr_color_temp = last_state.attributes.get(ATTR_COLOR_TEMP)
280 if last_state.attributes.get(ATTR_EFFECT):
281 self.
_attr_effect_attr_effect = last_state.attributes.get(ATTR_EFFECT)
284 """Turn the entity on.
286 This method is a coroutine.
288 values: dict[str, Any] = {
"state":
True}
292 if ATTR_BRIGHTNESS
in kwargs:
293 values[
"brightness"] =
int(kwargs[ATTR_BRIGHTNESS])
298 if ATTR_COLOR_TEMP
in kwargs:
299 values[
"color_temp"] =
int(kwargs[ATTR_COLOR_TEMP])
306 if ATTR_HS_COLOR
in kwargs:
307 hs_color = kwargs[ATTR_HS_COLOR]
311 if CONF_BRIGHTNESS_TEMPLATE
in self.
_config_config:
314 brightness = kwargs.get(
318 rgb = color_util.color_hsv_to_RGB(
319 hs_color[0], hs_color[1], brightness / 255 * 100
321 values[
"red"] = rgb[0]
322 values[
"green"] = rgb[1]
323 values[
"blue"] = rgb[2]
324 values[
"hue"] = hs_color[0]
325 values[
"sat"] = hs_color[1]
332 if ATTR_EFFECT
in kwargs:
333 values[
"effect"] = kwargs.get(ATTR_EFFECT)
338 if ATTR_FLASH
in kwargs:
339 values[
"flash"] = kwargs.get(ATTR_FLASH)
341 if ATTR_TRANSITION
in kwargs:
342 values[
"transition"] = kwargs[ATTR_TRANSITION]
353 """Turn the entity off.
355 This method is a coroutine.
357 values: dict[str, Any] = {
"state":
False}
361 if ATTR_TRANSITION
in kwargs:
362 values[
"transition"] = kwargs[ATTR_TRANSITION]
set[ColorMode]|set[str]|None supported_color_modes(self)
tuple[float, float]|None hs_color(self)
None async_publish_with_config(self, str topic, PublishPayloadType payload)
bool add_subscription(self, str state_topic_config_key, Callable[[ReceiveMessage], None] msg_callback, set[str]|None tracked_attributes, bool disable_encoding=False)
_attr_supported_color_modes
None async_turn_on(self, **Any kwargs)
None async_turn_off(self, **Any kwargs)
None _subscribe_topics(self)
VolSchemaType config_schema()
None _prepare_subscribe_topics(self)
None _setup_from_config(self, ConfigType config)
None _state_received(self, ReceiveMessage msg)
None _update_color_mode(self)
None async_write_ha_state(self)
State|None async_get_last_state(self)
set[ColorMode] filter_supported_color_modes(Iterable[ColorMode] color_modes)