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:
emontnemery 2018-10-08 15:36:57 +02:00 committed by Paulus Schoutsen
parent 9290f245bf
commit 42fb886d71
3 changed files with 133 additions and 7 deletions

View file

@ -137,6 +137,21 @@ light:
payload_on: "on"
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
from unittest import mock
@ -180,7 +195,7 @@ class TestLightMQTT(unittest.TestCase):
})
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."""
with assert_setup_component(1, 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('brightness'))
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('xy_color'))
@ -208,6 +224,7 @@ class TestLightMQTT(unittest.TestCase):
self.assertIsNone(state.attributes.get('rgb_color'))
self.assertIsNone(state.attributes.get('brightness'))
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('xy_color'))
@ -226,6 +243,8 @@ class TestLightMQTT(unittest.TestCase):
'color_temp_command_topic': 'test_light_rgb/color_temp/set',
'effect_state_topic': 'test_light_rgb/effect/status',
'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_command_topic': 'test_light_rgb/white_value/set',
'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('color_temp'))
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('xy_color'))
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(150, state.attributes.get('color_temp'))
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((0.323, 0.329), state.attributes.get('xy_color'))
@ -309,6 +330,14 @@ class TestLightMQTT(unittest.TestCase):
self.assertEqual((255, 255, 255),
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',
'0.675,0.322')
self.hass.block_till_done()
@ -412,7 +441,7 @@ class TestLightMQTT(unittest.TestCase):
light_state.attributes['white_value'])
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: {
'platform': 'mqtt',
'name': 'test',
@ -422,11 +451,13 @@ class TestLightMQTT(unittest.TestCase):
'rgb_command_topic': 'test_light_rgb/rgb/set',
'color_temp_command_topic': 'test_light_rgb/color_temp/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',
'xy_command_topic': 'test_light_rgb/xy/set',
'brightness_state_topic': 'test_light_rgb/brightness/status',
'color_temp_state_topic': 'test_light_rgb/color_temp/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',
'white_value_state_topic': 'test_light_rgb/white_value/status',
'xy_state_topic': 'test_light_rgb/xy/status',
@ -434,6 +465,7 @@ class TestLightMQTT(unittest.TestCase):
'brightness_value_template': '{{ value_json.hello }}',
'color_temp_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(",") }}',
'white_value_template': '{{ value_json.hello }}',
'xy_value_template': '{{ value_json.hello | join(",") }}',
@ -459,17 +491,28 @@ class TestLightMQTT(unittest.TestCase):
'{"hello": "rainbow"}')
fire_mqtt_message(self.hass, 'test_light_rgb/white_value/status',
'{"hello": "75"}')
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(STATE_ON, state.state)
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('rainbow', state.attributes.get('effect'))
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'))
def test_sending_mqtt_commands_and_optimistic(self):
@ -482,6 +525,7 @@ class TestLightMQTT(unittest.TestCase):
'rgb_command_topic': 'test_light_rgb/rgb/set',
'color_temp_command_topic': 'test_light_rgb/color_temp/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',
'xy_command_topic': 'test_light_rgb/xy/set',
'effect_list': ['colorloop', 'random'],
@ -529,6 +573,8 @@ class TestLightMQTT(unittest.TestCase):
self.mock_publish.reset_mock()
common.turn_on(self.hass, 'light.test',
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],
white_value=80)
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/rgb/set', '255,128,0', 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/xy/set', '0.14,0.131', 2, False),
], any_order=True)
@ -545,6 +592,7 @@ class TestLightMQTT(unittest.TestCase):
self.assertEqual(STATE_ON, state.state)
self.assertEqual((255, 128, 0), state.attributes['rgb_color'])
self.assertEqual(50, state.attributes['brightness'])
self.assertEqual((30.118, 100), state.attributes['hs_color'])
self.assertEqual(80, state.attributes['white_value'])
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('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):
"""Test the white_value if only a command topic is present."""
config = {light.DOMAIN: {