Add support for HS color to mqtt light (#16958)
* Add support for HS color to mqtt light * Warn if hs state update is invalid
This commit is contained in:
parent
9290f245bf
commit
42fb886d71
3 changed files with 133 additions and 7 deletions
|
@ -15,7 +15,7 @@ from homeassistant.components.light import (
|
||||||
ATTR_WHITE_VALUE, Light, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP,
|
ATTR_WHITE_VALUE, Light, SUPPORT_BRIGHTNESS, SUPPORT_COLOR_TEMP,
|
||||||
SUPPORT_EFFECT, SUPPORT_COLOR, SUPPORT_WHITE_VALUE)
|
SUPPORT_EFFECT, SUPPORT_COLOR, SUPPORT_WHITE_VALUE)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_BRIGHTNESS, CONF_COLOR_TEMP, CONF_EFFECT, CONF_NAME,
|
CONF_BRIGHTNESS, CONF_COLOR_TEMP, CONF_EFFECT, CONF_HS, CONF_NAME,
|
||||||
CONF_OPTIMISTIC, CONF_PAYLOAD_OFF, CONF_PAYLOAD_ON, STATE_ON,
|
CONF_OPTIMISTIC, CONF_PAYLOAD_OFF, CONF_PAYLOAD_ON, STATE_ON,
|
||||||
CONF_RGB, CONF_STATE, CONF_VALUE_TEMPLATE, CONF_WHITE_VALUE, CONF_XY)
|
CONF_RGB, CONF_STATE, CONF_VALUE_TEMPLATE, CONF_WHITE_VALUE, CONF_XY)
|
||||||
from homeassistant.components.mqtt import (
|
from homeassistant.components.mqtt import (
|
||||||
|
@ -44,6 +44,9 @@ CONF_EFFECT_COMMAND_TOPIC = 'effect_command_topic'
|
||||||
CONF_EFFECT_LIST = 'effect_list'
|
CONF_EFFECT_LIST = 'effect_list'
|
||||||
CONF_EFFECT_STATE_TOPIC = 'effect_state_topic'
|
CONF_EFFECT_STATE_TOPIC = 'effect_state_topic'
|
||||||
CONF_EFFECT_VALUE_TEMPLATE = 'effect_value_template'
|
CONF_EFFECT_VALUE_TEMPLATE = 'effect_value_template'
|
||||||
|
CONF_HS_COMMAND_TOPIC = 'hs_command_topic'
|
||||||
|
CONF_HS_STATE_TOPIC = 'hs_state_topic'
|
||||||
|
CONF_HS_VALUE_TEMPLATE = 'hs_value_template'
|
||||||
CONF_RGB_COMMAND_TEMPLATE = 'rgb_command_template'
|
CONF_RGB_COMMAND_TEMPLATE = 'rgb_command_template'
|
||||||
CONF_RGB_COMMAND_TOPIC = 'rgb_command_topic'
|
CONF_RGB_COMMAND_TOPIC = 'rgb_command_topic'
|
||||||
CONF_RGB_STATE_TOPIC = 'rgb_state_topic'
|
CONF_RGB_STATE_TOPIC = 'rgb_state_topic'
|
||||||
|
@ -82,6 +85,9 @@ PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
|
||||||
vol.Optional(CONF_EFFECT_LIST): vol.All(cv.ensure_list, [cv.string]),
|
vol.Optional(CONF_EFFECT_LIST): vol.All(cv.ensure_list, [cv.string]),
|
||||||
vol.Optional(CONF_EFFECT_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
vol.Optional(CONF_EFFECT_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||||
vol.Optional(CONF_EFFECT_VALUE_TEMPLATE): cv.template,
|
vol.Optional(CONF_EFFECT_VALUE_TEMPLATE): cv.template,
|
||||||
|
vol.Optional(CONF_HS_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||||
|
vol.Optional(CONF_HS_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||||
|
vol.Optional(CONF_HS_VALUE_TEMPLATE): cv.template,
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||||
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
vol.Optional(CONF_UNIQUE_ID): cv.string,
|
||||||
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
|
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
|
||||||
|
@ -143,6 +149,8 @@ async def _async_setup_entity(hass, config, async_add_entities,
|
||||||
CONF_COMMAND_TOPIC,
|
CONF_COMMAND_TOPIC,
|
||||||
CONF_EFFECT_COMMAND_TOPIC,
|
CONF_EFFECT_COMMAND_TOPIC,
|
||||||
CONF_EFFECT_STATE_TOPIC,
|
CONF_EFFECT_STATE_TOPIC,
|
||||||
|
CONF_HS_COMMAND_TOPIC,
|
||||||
|
CONF_HS_STATE_TOPIC,
|
||||||
CONF_RGB_COMMAND_TOPIC,
|
CONF_RGB_COMMAND_TOPIC,
|
||||||
CONF_RGB_STATE_TOPIC,
|
CONF_RGB_STATE_TOPIC,
|
||||||
CONF_STATE_TOPIC,
|
CONF_STATE_TOPIC,
|
||||||
|
@ -156,6 +164,7 @@ async def _async_setup_entity(hass, config, async_add_entities,
|
||||||
CONF_BRIGHTNESS: config.get(CONF_BRIGHTNESS_VALUE_TEMPLATE),
|
CONF_BRIGHTNESS: config.get(CONF_BRIGHTNESS_VALUE_TEMPLATE),
|
||||||
CONF_COLOR_TEMP: config.get(CONF_COLOR_TEMP_VALUE_TEMPLATE),
|
CONF_COLOR_TEMP: config.get(CONF_COLOR_TEMP_VALUE_TEMPLATE),
|
||||||
CONF_EFFECT: config.get(CONF_EFFECT_VALUE_TEMPLATE),
|
CONF_EFFECT: config.get(CONF_EFFECT_VALUE_TEMPLATE),
|
||||||
|
CONF_HS: config.get(CONF_HS_VALUE_TEMPLATE),
|
||||||
CONF_RGB: config.get(CONF_RGB_VALUE_TEMPLATE),
|
CONF_RGB: config.get(CONF_RGB_VALUE_TEMPLATE),
|
||||||
CONF_RGB_COMMAND_TEMPLATE: config.get(CONF_RGB_COMMAND_TEMPLATE),
|
CONF_RGB_COMMAND_TEMPLATE: config.get(CONF_RGB_COMMAND_TEMPLATE),
|
||||||
CONF_STATE: config.get(CONF_STATE_VALUE_TEMPLATE),
|
CONF_STATE: config.get(CONF_STATE_VALUE_TEMPLATE),
|
||||||
|
@ -207,6 +216,8 @@ class MqttLight(MqttAvailability, MqttDiscoveryUpdate, Light):
|
||||||
optimistic or topic[CONF_COLOR_TEMP_STATE_TOPIC] is None)
|
optimistic or topic[CONF_COLOR_TEMP_STATE_TOPIC] is None)
|
||||||
self._optimistic_effect = (
|
self._optimistic_effect = (
|
||||||
optimistic or topic[CONF_EFFECT_STATE_TOPIC] is None)
|
optimistic or topic[CONF_EFFECT_STATE_TOPIC] is None)
|
||||||
|
self._optimistic_hs = \
|
||||||
|
optimistic or topic[CONF_HS_STATE_TOPIC] is None
|
||||||
self._optimistic_white_value = (
|
self._optimistic_white_value = (
|
||||||
optimistic or topic[CONF_WHITE_VALUE_STATE_TOPIC] is None)
|
optimistic or topic[CONF_WHITE_VALUE_STATE_TOPIC] is None)
|
||||||
self._optimistic_xy = \
|
self._optimistic_xy = \
|
||||||
|
@ -232,6 +243,8 @@ class MqttLight(MqttAvailability, MqttDiscoveryUpdate, Light):
|
||||||
self._supported_features |= (
|
self._supported_features |= (
|
||||||
topic[CONF_EFFECT_COMMAND_TOPIC] is not None and
|
topic[CONF_EFFECT_COMMAND_TOPIC] is not None and
|
||||||
SUPPORT_EFFECT)
|
SUPPORT_EFFECT)
|
||||||
|
self._supported_features |= (
|
||||||
|
topic[CONF_HS_COMMAND_TOPIC] is not None and SUPPORT_COLOR)
|
||||||
self._supported_features |= (
|
self._supported_features |= (
|
||||||
topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None and
|
topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None and
|
||||||
SUPPORT_WHITE_VALUE)
|
SUPPORT_WHITE_VALUE)
|
||||||
|
@ -374,6 +387,33 @@ class MqttLight(MqttAvailability, MqttDiscoveryUpdate, Light):
|
||||||
else:
|
else:
|
||||||
self._effect = None
|
self._effect = None
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def hs_received(topic, payload, qos):
|
||||||
|
"""Handle new MQTT messages for hs color."""
|
||||||
|
payload = templates[CONF_HS](payload)
|
||||||
|
if not payload:
|
||||||
|
_LOGGER.debug("Ignoring empty hs message from '%s'", topic)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
hs_color = [float(val) for val in payload.split(',', 2)]
|
||||||
|
self._hs = hs_color
|
||||||
|
self.async_schedule_update_ha_state()
|
||||||
|
except ValueError:
|
||||||
|
_LOGGER.debug("Failed to parse hs state update: '%s'",
|
||||||
|
payload)
|
||||||
|
|
||||||
|
if self._topic[CONF_HS_STATE_TOPIC] is not None:
|
||||||
|
await mqtt.async_subscribe(
|
||||||
|
self.hass, self._topic[CONF_HS_STATE_TOPIC], hs_received,
|
||||||
|
self._qos)
|
||||||
|
self._hs = (0, 0)
|
||||||
|
if self._optimistic_hs and last_state\
|
||||||
|
and last_state.attributes.get(ATTR_HS_COLOR):
|
||||||
|
self._hs = last_state.attributes.get(ATTR_HS_COLOR)
|
||||||
|
elif self._topic[CONF_HS_COMMAND_TOPIC] is not None:
|
||||||
|
self._hs = (0, 0)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def white_value_received(topic, payload, qos):
|
def white_value_received(topic, payload, qos):
|
||||||
"""Handle new MQTT messages for white value."""
|
"""Handle new MQTT messages for white value."""
|
||||||
|
@ -403,7 +443,7 @@ class MqttLight(MqttAvailability, MqttDiscoveryUpdate, Light):
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def xy_received(topic, payload, qos):
|
def xy_received(topic, payload, qos):
|
||||||
"""Handle new MQTT messages for color."""
|
"""Handle new MQTT messages for xy color."""
|
||||||
payload = templates[CONF_XY](payload)
|
payload = templates[CONF_XY](payload)
|
||||||
if not payload:
|
if not payload:
|
||||||
_LOGGER.debug("Ignoring empty xy-color message from '%s'",
|
_LOGGER.debug("Ignoring empty xy-color message from '%s'",
|
||||||
|
@ -539,6 +579,19 @@ class MqttLight(MqttAvailability, MqttDiscoveryUpdate, Light):
|
||||||
self._hs = kwargs[ATTR_HS_COLOR]
|
self._hs = kwargs[ATTR_HS_COLOR]
|
||||||
should_update = True
|
should_update = True
|
||||||
|
|
||||||
|
if ATTR_HS_COLOR in kwargs and \
|
||||||
|
self._topic[CONF_HS_COMMAND_TOPIC] is not None:
|
||||||
|
|
||||||
|
hs_color = kwargs[ATTR_HS_COLOR]
|
||||||
|
mqtt.async_publish(
|
||||||
|
self.hass, self._topic[CONF_HS_COMMAND_TOPIC],
|
||||||
|
'{},{}'.format(*hs_color), self._qos,
|
||||||
|
self._retain)
|
||||||
|
|
||||||
|
if self._optimistic_hs:
|
||||||
|
self._hs = kwargs[ATTR_HS_COLOR]
|
||||||
|
should_update = True
|
||||||
|
|
||||||
if ATTR_HS_COLOR in kwargs and \
|
if ATTR_HS_COLOR in kwargs and \
|
||||||
self._topic[CONF_XY_COMMAND_TOPIC] is not None:
|
self._topic[CONF_XY_COMMAND_TOPIC] is not None:
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ CONF_FRIENDLY_NAME_TEMPLATE = 'friendly_name_template'
|
||||||
CONF_HEADERS = 'headers'
|
CONF_HEADERS = 'headers'
|
||||||
CONF_HOST = 'host'
|
CONF_HOST = 'host'
|
||||||
CONF_HOSTS = 'hosts'
|
CONF_HOSTS = 'hosts'
|
||||||
|
CONF_HS = 'hs'
|
||||||
CONF_ICON = 'icon'
|
CONF_ICON = 'icon'
|
||||||
CONF_ICON_TEMPLATE = 'icon_template'
|
CONF_ICON_TEMPLATE = 'icon_template'
|
||||||
CONF_INCLUDE = 'include'
|
CONF_INCLUDE = 'include'
|
||||||
|
|
|
@ -137,6 +137,21 @@ light:
|
||||||
payload_on: "on"
|
payload_on: "on"
|
||||||
payload_off: "off"
|
payload_off: "off"
|
||||||
|
|
||||||
|
Configuration for HS Version with brightness:
|
||||||
|
|
||||||
|
light:
|
||||||
|
platform: mqtt
|
||||||
|
name: "Office Light HS"
|
||||||
|
state_topic: "office/hs1/light/status"
|
||||||
|
command_topic: "office/hs1/light/switch"
|
||||||
|
brightness_state_topic: "office/hs1/brightness/status"
|
||||||
|
brightness_command_topic: "office/hs1/brightness/set"
|
||||||
|
hs_state_topic: "office/hs1/hs/status"
|
||||||
|
hs_command_topic: "office/hs1/hs/set"
|
||||||
|
qos: 0
|
||||||
|
payload_on: "on"
|
||||||
|
payload_off: "off"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import unittest
|
import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
@ -180,7 +195,7 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
})
|
})
|
||||||
self.assertIsNone(self.hass.states.get('light.test'))
|
self.assertIsNone(self.hass.states.get('light.test'))
|
||||||
|
|
||||||
def test_no_color_brightness_color_temp_white_xy_if_no_topics(self):
|
def test_no_color_brightness_color_temp_hs_white_xy_if_no_topics(self):
|
||||||
"""Test if there is no color and brightness if no topic."""
|
"""Test if there is no color and brightness if no topic."""
|
||||||
with assert_setup_component(1, light.DOMAIN):
|
with assert_setup_component(1, light.DOMAIN):
|
||||||
assert setup_component(self.hass, light.DOMAIN, {
|
assert setup_component(self.hass, light.DOMAIN, {
|
||||||
|
@ -197,6 +212,7 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
self.assertIsNone(state.attributes.get('rgb_color'))
|
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||||
self.assertIsNone(state.attributes.get('brightness'))
|
self.assertIsNone(state.attributes.get('brightness'))
|
||||||
self.assertIsNone(state.attributes.get('color_temp'))
|
self.assertIsNone(state.attributes.get('color_temp'))
|
||||||
|
self.assertIsNone(state.attributes.get('hs_color'))
|
||||||
self.assertIsNone(state.attributes.get('white_value'))
|
self.assertIsNone(state.attributes.get('white_value'))
|
||||||
self.assertIsNone(state.attributes.get('xy_color'))
|
self.assertIsNone(state.attributes.get('xy_color'))
|
||||||
|
|
||||||
|
@ -208,6 +224,7 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
self.assertIsNone(state.attributes.get('rgb_color'))
|
self.assertIsNone(state.attributes.get('rgb_color'))
|
||||||
self.assertIsNone(state.attributes.get('brightness'))
|
self.assertIsNone(state.attributes.get('brightness'))
|
||||||
self.assertIsNone(state.attributes.get('color_temp'))
|
self.assertIsNone(state.attributes.get('color_temp'))
|
||||||
|
self.assertIsNone(state.attributes.get('hs_color'))
|
||||||
self.assertIsNone(state.attributes.get('white_value'))
|
self.assertIsNone(state.attributes.get('white_value'))
|
||||||
self.assertIsNone(state.attributes.get('xy_color'))
|
self.assertIsNone(state.attributes.get('xy_color'))
|
||||||
|
|
||||||
|
@ -226,6 +243,8 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
|
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
|
||||||
'effect_state_topic': 'test_light_rgb/effect/status',
|
'effect_state_topic': 'test_light_rgb/effect/status',
|
||||||
'effect_command_topic': 'test_light_rgb/effect/set',
|
'effect_command_topic': 'test_light_rgb/effect/set',
|
||||||
|
'hs_state_topic': 'test_light_rgb/hs/status',
|
||||||
|
'hs_command_topic': 'test_light_rgb/hs/set',
|
||||||
'white_value_state_topic': 'test_light_rgb/white_value/status',
|
'white_value_state_topic': 'test_light_rgb/white_value/status',
|
||||||
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
||||||
'xy_state_topic': 'test_light_rgb/xy/status',
|
'xy_state_topic': 'test_light_rgb/xy/status',
|
||||||
|
@ -244,6 +263,7 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
self.assertIsNone(state.attributes.get('brightness'))
|
self.assertIsNone(state.attributes.get('brightness'))
|
||||||
self.assertIsNone(state.attributes.get('color_temp'))
|
self.assertIsNone(state.attributes.get('color_temp'))
|
||||||
self.assertIsNone(state.attributes.get('effect'))
|
self.assertIsNone(state.attributes.get('effect'))
|
||||||
|
self.assertIsNone(state.attributes.get('hs_color'))
|
||||||
self.assertIsNone(state.attributes.get('white_value'))
|
self.assertIsNone(state.attributes.get('white_value'))
|
||||||
self.assertIsNone(state.attributes.get('xy_color'))
|
self.assertIsNone(state.attributes.get('xy_color'))
|
||||||
self.assertFalse(state.attributes.get(ATTR_ASSUMED_STATE))
|
self.assertFalse(state.attributes.get(ATTR_ASSUMED_STATE))
|
||||||
|
@ -257,6 +277,7 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
self.assertEqual(255, state.attributes.get('brightness'))
|
self.assertEqual(255, state.attributes.get('brightness'))
|
||||||
self.assertEqual(150, state.attributes.get('color_temp'))
|
self.assertEqual(150, state.attributes.get('color_temp'))
|
||||||
self.assertEqual('none', state.attributes.get('effect'))
|
self.assertEqual('none', state.attributes.get('effect'))
|
||||||
|
self.assertEqual((0, 0), state.attributes.get('hs_color'))
|
||||||
self.assertEqual(255, state.attributes.get('white_value'))
|
self.assertEqual(255, state.attributes.get('white_value'))
|
||||||
self.assertEqual((0.323, 0.329), state.attributes.get('xy_color'))
|
self.assertEqual((0.323, 0.329), state.attributes.get('xy_color'))
|
||||||
|
|
||||||
|
@ -309,6 +330,14 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
self.assertEqual((255, 255, 255),
|
self.assertEqual((255, 255, 255),
|
||||||
light_state.attributes.get('rgb_color'))
|
light_state.attributes.get('rgb_color'))
|
||||||
|
|
||||||
|
fire_mqtt_message(self.hass, 'test_light_rgb/hs/status',
|
||||||
|
'200,50')
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
light_state = self.hass.states.get('light.test')
|
||||||
|
self.assertEqual((200, 50),
|
||||||
|
light_state.attributes.get('hs_color'))
|
||||||
|
|
||||||
fire_mqtt_message(self.hass, 'test_light_rgb/xy/status',
|
fire_mqtt_message(self.hass, 'test_light_rgb/xy/status',
|
||||||
'0.675,0.322')
|
'0.675,0.322')
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
|
@ -412,7 +441,7 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
light_state.attributes['white_value'])
|
light_state.attributes['white_value'])
|
||||||
|
|
||||||
def test_controlling_state_via_topic_with_templates(self):
|
def test_controlling_state_via_topic_with_templates(self):
|
||||||
"""Test the setting og the state with a template."""
|
"""Test the setting of the state with a template."""
|
||||||
config = {light.DOMAIN: {
|
config = {light.DOMAIN: {
|
||||||
'platform': 'mqtt',
|
'platform': 'mqtt',
|
||||||
'name': 'test',
|
'name': 'test',
|
||||||
|
@ -422,11 +451,13 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
'rgb_command_topic': 'test_light_rgb/rgb/set',
|
'rgb_command_topic': 'test_light_rgb/rgb/set',
|
||||||
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
|
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
|
||||||
'effect_command_topic': 'test_light_rgb/effect/set',
|
'effect_command_topic': 'test_light_rgb/effect/set',
|
||||||
|
'hs_command_topic': 'test_light_rgb/hs/set',
|
||||||
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
||||||
'xy_command_topic': 'test_light_rgb/xy/set',
|
'xy_command_topic': 'test_light_rgb/xy/set',
|
||||||
'brightness_state_topic': 'test_light_rgb/brightness/status',
|
'brightness_state_topic': 'test_light_rgb/brightness/status',
|
||||||
'color_temp_state_topic': 'test_light_rgb/color_temp/status',
|
'color_temp_state_topic': 'test_light_rgb/color_temp/status',
|
||||||
'effect_state_topic': 'test_light_rgb/effect/status',
|
'effect_state_topic': 'test_light_rgb/effect/status',
|
||||||
|
'hs_state_topic': 'test_light_rgb/hs/status',
|
||||||
'rgb_state_topic': 'test_light_rgb/rgb/status',
|
'rgb_state_topic': 'test_light_rgb/rgb/status',
|
||||||
'white_value_state_topic': 'test_light_rgb/white_value/status',
|
'white_value_state_topic': 'test_light_rgb/white_value/status',
|
||||||
'xy_state_topic': 'test_light_rgb/xy/status',
|
'xy_state_topic': 'test_light_rgb/xy/status',
|
||||||
|
@ -434,6 +465,7 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
'brightness_value_template': '{{ value_json.hello }}',
|
'brightness_value_template': '{{ value_json.hello }}',
|
||||||
'color_temp_value_template': '{{ value_json.hello }}',
|
'color_temp_value_template': '{{ value_json.hello }}',
|
||||||
'effect_value_template': '{{ value_json.hello }}',
|
'effect_value_template': '{{ value_json.hello }}',
|
||||||
|
'hs_value_template': '{{ value_json.hello | join(",") }}',
|
||||||
'rgb_value_template': '{{ value_json.hello | join(",") }}',
|
'rgb_value_template': '{{ value_json.hello | join(",") }}',
|
||||||
'white_value_template': '{{ value_json.hello }}',
|
'white_value_template': '{{ value_json.hello }}',
|
||||||
'xy_value_template': '{{ value_json.hello | join(",") }}',
|
'xy_value_template': '{{ value_json.hello | join(",") }}',
|
||||||
|
@ -459,17 +491,28 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
'{"hello": "rainbow"}')
|
'{"hello": "rainbow"}')
|
||||||
fire_mqtt_message(self.hass, 'test_light_rgb/white_value/status',
|
fire_mqtt_message(self.hass, 'test_light_rgb/white_value/status',
|
||||||
'{"hello": "75"}')
|
'{"hello": "75"}')
|
||||||
fire_mqtt_message(self.hass, 'test_light_rgb/xy/status',
|
|
||||||
'{"hello": [0.123,0.123]}')
|
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
|
|
||||||
state = self.hass.states.get('light.test')
|
state = self.hass.states.get('light.test')
|
||||||
self.assertEqual(STATE_ON, state.state)
|
self.assertEqual(STATE_ON, state.state)
|
||||||
self.assertEqual(50, state.attributes.get('brightness'))
|
self.assertEqual(50, state.attributes.get('brightness'))
|
||||||
self.assertEqual((0, 123, 255), state.attributes.get('rgb_color'))
|
self.assertEqual((84, 169, 255), state.attributes.get('rgb_color'))
|
||||||
self.assertEqual(300, state.attributes.get('color_temp'))
|
self.assertEqual(300, state.attributes.get('color_temp'))
|
||||||
self.assertEqual('rainbow', state.attributes.get('effect'))
|
self.assertEqual('rainbow', state.attributes.get('effect'))
|
||||||
self.assertEqual(75, state.attributes.get('white_value'))
|
self.assertEqual(75, state.attributes.get('white_value'))
|
||||||
|
|
||||||
|
fire_mqtt_message(self.hass, 'test_light_rgb/hs/status',
|
||||||
|
'{"hello": [100,50]}')
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get('light.test')
|
||||||
|
self.assertEqual((100, 50), state.attributes.get('hs_color'))
|
||||||
|
|
||||||
|
fire_mqtt_message(self.hass, 'test_light_rgb/xy/status',
|
||||||
|
'{"hello": [0.123,0.123]}')
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get('light.test')
|
||||||
self.assertEqual((0.14, 0.131), state.attributes.get('xy_color'))
|
self.assertEqual((0.14, 0.131), state.attributes.get('xy_color'))
|
||||||
|
|
||||||
def test_sending_mqtt_commands_and_optimistic(self):
|
def test_sending_mqtt_commands_and_optimistic(self):
|
||||||
|
@ -482,6 +525,7 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
'rgb_command_topic': 'test_light_rgb/rgb/set',
|
'rgb_command_topic': 'test_light_rgb/rgb/set',
|
||||||
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
|
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
|
||||||
'effect_command_topic': 'test_light_rgb/effect/set',
|
'effect_command_topic': 'test_light_rgb/effect/set',
|
||||||
|
'hs_command_topic': 'test_light_rgb/hs/set',
|
||||||
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
'white_value_command_topic': 'test_light_rgb/white_value/set',
|
||||||
'xy_command_topic': 'test_light_rgb/xy/set',
|
'xy_command_topic': 'test_light_rgb/xy/set',
|
||||||
'effect_list': ['colorloop', 'random'],
|
'effect_list': ['colorloop', 'random'],
|
||||||
|
@ -529,6 +573,8 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
self.mock_publish.reset_mock()
|
self.mock_publish.reset_mock()
|
||||||
common.turn_on(self.hass, 'light.test',
|
common.turn_on(self.hass, 'light.test',
|
||||||
brightness=50, xy_color=[0.123, 0.123])
|
brightness=50, xy_color=[0.123, 0.123])
|
||||||
|
common.turn_on(self.hass, 'light.test',
|
||||||
|
brightness=50, hs_color=[359, 78])
|
||||||
common.turn_on(self.hass, 'light.test', rgb_color=[255, 128, 0],
|
common.turn_on(self.hass, 'light.test', rgb_color=[255, 128, 0],
|
||||||
white_value=80)
|
white_value=80)
|
||||||
self.hass.block_till_done()
|
self.hass.block_till_done()
|
||||||
|
@ -537,6 +583,7 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
mock.call('test_light_rgb/set', 'on', 2, False),
|
mock.call('test_light_rgb/set', 'on', 2, False),
|
||||||
mock.call('test_light_rgb/rgb/set', '255,128,0', 2, False),
|
mock.call('test_light_rgb/rgb/set', '255,128,0', 2, False),
|
||||||
mock.call('test_light_rgb/brightness/set', 50, 2, False),
|
mock.call('test_light_rgb/brightness/set', 50, 2, False),
|
||||||
|
mock.call('test_light_rgb/hs/set', '359.0,78.0', 2, False),
|
||||||
mock.call('test_light_rgb/white_value/set', 80, 2, False),
|
mock.call('test_light_rgb/white_value/set', 80, 2, False),
|
||||||
mock.call('test_light_rgb/xy/set', '0.14,0.131', 2, False),
|
mock.call('test_light_rgb/xy/set', '0.14,0.131', 2, False),
|
||||||
], any_order=True)
|
], any_order=True)
|
||||||
|
@ -545,6 +592,7 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
self.assertEqual(STATE_ON, state.state)
|
self.assertEqual(STATE_ON, state.state)
|
||||||
self.assertEqual((255, 128, 0), state.attributes['rgb_color'])
|
self.assertEqual((255, 128, 0), state.attributes['rgb_color'])
|
||||||
self.assertEqual(50, state.attributes['brightness'])
|
self.assertEqual(50, state.attributes['brightness'])
|
||||||
|
self.assertEqual((30.118, 100), state.attributes['hs_color'])
|
||||||
self.assertEqual(80, state.attributes['white_value'])
|
self.assertEqual(80, state.attributes['white_value'])
|
||||||
self.assertEqual((0.611, 0.375), state.attributes['xy_color'])
|
self.assertEqual((0.611, 0.375), state.attributes['xy_color'])
|
||||||
|
|
||||||
|
@ -652,6 +700,30 @@ class TestLightMQTT(unittest.TestCase):
|
||||||
self.assertEqual(STATE_ON, state.state)
|
self.assertEqual(STATE_ON, state.state)
|
||||||
self.assertEqual('none', state.attributes.get('effect'))
|
self.assertEqual('none', state.attributes.get('effect'))
|
||||||
|
|
||||||
|
def test_show_hs_if_only_command_topic(self):
|
||||||
|
"""Test the hs if only a command topic is present."""
|
||||||
|
config = {light.DOMAIN: {
|
||||||
|
'platform': 'mqtt',
|
||||||
|
'name': 'test',
|
||||||
|
'hs_command_topic': 'test_light_rgb/hs/set',
|
||||||
|
'command_topic': 'test_light_rgb/set',
|
||||||
|
'state_topic': 'test_light_rgb/status',
|
||||||
|
}}
|
||||||
|
|
||||||
|
with assert_setup_component(1, light.DOMAIN):
|
||||||
|
assert setup_component(self.hass, light.DOMAIN, config)
|
||||||
|
|
||||||
|
state = self.hass.states.get('light.test')
|
||||||
|
self.assertEqual(STATE_OFF, state.state)
|
||||||
|
self.assertIsNone(state.attributes.get('hs_color'))
|
||||||
|
|
||||||
|
fire_mqtt_message(self.hass, 'test_light_rgb/status', 'ON')
|
||||||
|
self.hass.block_till_done()
|
||||||
|
|
||||||
|
state = self.hass.states.get('light.test')
|
||||||
|
self.assertEqual(STATE_ON, state.state)
|
||||||
|
self.assertEqual((0, 0), state.attributes.get('hs_color'))
|
||||||
|
|
||||||
def test_show_white_value_if_only_command_topic(self):
|
def test_show_white_value_if_only_command_topic(self):
|
||||||
"""Test the white_value if only a command topic is present."""
|
"""Test the white_value if only a command topic is present."""
|
||||||
config = {light.DOMAIN: {
|
config = {light.DOMAIN: {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue