Add hs_command_template and xy_command_template to mqtt light default schema (#84988)

* Add mqtt light hs_command_template

* Add mqtt light xy_command_template
pull/85059/head
Sándor Oroszi 2023-01-03 12:58:00 +01:00 committed by GitHub
parent e7e1a7d46e
commit a0d41e1d97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 8 deletions

View File

@ -78,6 +78,7 @@ ABBREVIATIONS = {
"hold_stat_tpl": "hold_state_template",
"hold_stat_t": "hold_state_topic",
"hs_cmd_t": "hs_command_topic",
"hs_cmd_tpl": "hs_command_template",
"hs_stat_t": "hs_state_topic",
"hs_val_tpl": "hs_value_template",
"ic": "icon",
@ -250,6 +251,7 @@ ABBREVIATIONS = {
"whit_val_stat_t": "white_value_state_topic",
"whit_val_tpl": "white_value_template",
"xy_cmd_t": "xy_command_topic",
"xy_cmd_tpl": "xy_command_template",
"xy_stat_t": "xy_state_topic",
"xy_val_tpl": "xy_value_template",
"l_ver_t": "latest_version_topic",

View File

@ -88,6 +88,7 @@ CONF_EFFECT_COMMAND_TOPIC = "effect_command_topic"
CONF_EFFECT_LIST = "effect_list"
CONF_EFFECT_STATE_TOPIC = "effect_state_topic"
CONF_EFFECT_VALUE_TEMPLATE = "effect_value_template"
CONF_HS_COMMAND_TEMPLATE = "hs_command_template"
CONF_HS_COMMAND_TOPIC = "hs_command_topic"
CONF_HS_STATE_TOPIC = "hs_state_topic"
CONF_HS_VALUE_TEMPLATE = "hs_value_template"
@ -105,6 +106,7 @@ CONF_RGBWW_COMMAND_TEMPLATE = "rgbww_command_template"
CONF_RGBWW_COMMAND_TOPIC = "rgbww_command_topic"
CONF_RGBWW_STATE_TOPIC = "rgbww_state_topic"
CONF_RGBWW_VALUE_TEMPLATE = "rgbww_value_template"
CONF_XY_COMMAND_TEMPLATE = "xy_command_template"
CONF_XY_COMMAND_TOPIC = "xy_command_topic"
CONF_XY_STATE_TOPIC = "xy_state_topic"
CONF_XY_VALUE_TEMPLATE = "xy_value_template"
@ -147,9 +149,11 @@ COMMAND_TEMPLATE_KEYS = [
CONF_BRIGHTNESS_COMMAND_TEMPLATE,
CONF_COLOR_TEMP_COMMAND_TEMPLATE,
CONF_EFFECT_COMMAND_TEMPLATE,
CONF_HS_COMMAND_TEMPLATE,
CONF_RGB_COMMAND_TEMPLATE,
CONF_RGBW_COMMAND_TEMPLATE,
CONF_RGBWW_COMMAND_TEMPLATE,
CONF_XY_COMMAND_TEMPLATE,
]
VALUE_TEMPLATE_KEYS = [
CONF_BRIGHTNESS_VALUE_TEMPLATE,
@ -185,6 +189,7 @@ _PLATFORM_SCHEMA_BASE = (
vol.Optional(CONF_EFFECT_LIST): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_EFFECT_STATE_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_EFFECT_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_HS_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_HS_COMMAND_TOPIC): valid_publish_topic,
vol.Optional(CONF_HS_STATE_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_HS_VALUE_TEMPLATE): cv.template,
@ -213,6 +218,7 @@ _PLATFORM_SCHEMA_BASE = (
vol.Optional(CONF_WHITE_SCALE, default=DEFAULT_WHITE_SCALE): vol.All(
vol.Coerce(int), vol.Range(min=1)
),
vol.Optional(CONF_XY_COMMAND_TEMPLATE): cv.template,
vol.Optional(CONF_XY_COMMAND_TOPIC): valid_publish_topic,
vol.Optional(CONF_XY_STATE_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_XY_VALUE_TEMPLATE): cv.template,
@ -763,7 +769,11 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
hs_color: str | None = kwargs.get(ATTR_HS_COLOR)
if hs_color and self._topic[CONF_HS_COMMAND_TOPIC] is not None:
await publish(CONF_HS_COMMAND_TOPIC, f"{hs_color[0]},{hs_color[1]}")
device_hs_payload = self._command_templates[CONF_HS_COMMAND_TEMPLATE](
f"{hs_color[0]},{hs_color[1]}",
{"hue": hs_color[0], "sat": hs_color[1]},
)
await publish(CONF_HS_COMMAND_TOPIC, device_hs_payload)
should_update |= set_optimistic(ATTR_HS_COLOR, hs_color, ColorMode.HS)
rgb: tuple[int, int, int] | None
@ -797,7 +807,11 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity):
if (xy_color := kwargs.get(ATTR_XY_COLOR)) and self._topic[
CONF_XY_COMMAND_TOPIC
] is not None:
await publish(CONF_XY_COMMAND_TOPIC, f"{xy_color[0]},{xy_color[1]}")
device_xy_payload = self._command_templates[CONF_XY_COMMAND_TEMPLATE](
f"{xy_color[0]},{xy_color[1]}",
{"x": xy_color[0], "y": xy_color[1]},
)
await publish(CONF_XY_COMMAND_TOPIC, device_xy_payload)
should_update |= set_optimistic(ATTR_XY_COLOR, xy_color, ColorMode.XY)
if (

View File

@ -2861,18 +2861,18 @@ async def test_max_mireds(hass, mqtt_mock_entry_with_yaml_config):
"hs_command_topic",
{"rgb_color": [255, 128, 0]},
"30.118,100.0",
None,
None,
None,
"hs_command_template",
"hue",
b"3",
),
(
light.SERVICE_TURN_ON,
"xy_command_topic",
{"hs_color": [30.118, 100.0]},
"0.611,0.375",
None,
None,
None,
"xy_command_template",
"x * 10",
b"6",
),
(
light.SERVICE_TURN_OFF,
@ -3113,6 +3113,78 @@ async def test_sending_mqtt_effect_command_with_template(
assert state.attributes.get("effect") == "colorloop"
async def test_sending_mqtt_hs_command_with_template(
hass, mqtt_mock_entry_with_yaml_config
):
"""Test the sending of HS Color command with template."""
config = {
light.DOMAIN: {
"name": "test",
"command_topic": "test_light_hs/set",
"hs_command_topic": "test_light_hs/hs_color/set",
"hs_command_template": '{"hue": {{ hue | int }}, "sat": {{ sat | int}}}',
"qos": 0,
}
}
assert await async_setup_component(hass, mqtt.DOMAIN, {mqtt.DOMAIN: config})
await hass.async_block_till_done()
mqtt_mock = await mqtt_mock_entry_with_yaml_config()
state = hass.states.get("light.test")
assert state.state == STATE_UNKNOWN
await common.async_turn_on(hass, "light.test", hs_color=(30, 100))
mqtt_mock.async_publish.assert_has_calls(
[
call("test_light_hs/set", "ON", 0, False),
call("test_light_hs/hs_color/set", '{"hue": 30, "sat": 100}', 0, False),
],
any_order=True,
)
state = hass.states.get("light.test")
assert state.state == STATE_ON
assert state.attributes["hs_color"] == (30, 100)
async def test_sending_mqtt_xy_command_with_template(
hass, mqtt_mock_entry_with_yaml_config
):
"""Test the sending of XY Color command with template."""
config = {
light.DOMAIN: {
"name": "test",
"command_topic": "test_light_xy/set",
"xy_command_topic": "test_light_xy/xy_color/set",
"xy_command_template": '{"Color": "{{ (x * 65536) | round | int }},{{ (y * 65536) | round | int }}"}',
"qos": 0,
}
}
assert await async_setup_component(hass, mqtt.DOMAIN, {mqtt.DOMAIN: config})
await hass.async_block_till_done()
mqtt_mock = await mqtt_mock_entry_with_yaml_config()
state = hass.states.get("light.test")
assert state.state == STATE_UNKNOWN
await common.async_turn_on(hass, "light.test", xy_color=(0.151, 0.343))
mqtt_mock.async_publish.assert_has_calls(
[
call("test_light_xy/set", "ON", 0, False),
call("test_light_xy/xy_color/set", '{"Color": "9896,22479"}', 0, False),
],
any_order=True,
)
state = hass.states.get("light.test")
assert state.state == STATE_ON
assert state.attributes["xy_color"] == (0.151, 0.343)
async def test_setup_manual_entity_from_yaml(hass):
"""Test setup manual configured MQTT entity."""
platform = light.DOMAIN