From a05bcabb6b40e1fb9eab6d04d0f000914daaa020 Mon Sep 17 00:00:00 2001 From: Konstantin Belyalov Date: Mon, 4 Sep 2017 23:29:53 -0700 Subject: [PATCH 1/3] Add new config variable to MQTT light --- homeassistant/components/light/mqtt.py | 14 ++++++-- tests/components/light/test_mqtt.py | 46 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/light/mqtt.py b/homeassistant/components/light/mqtt.py index 038cacd300ee0..dd276024aa367 100644 --- a/homeassistant/components/light/mqtt.py +++ b/homeassistant/components/light/mqtt.py @@ -39,6 +39,7 @@ CONF_EFFECT_LIST = 'effect_list' CONF_EFFECT_STATE_TOPIC = 'effect_state_topic' CONF_EFFECT_VALUE_TEMPLATE = 'effect_value_template' +CONF_RGB_COMMAND_TEMPLATE = 'rgb_command_template' CONF_RGB_COMMAND_TOPIC = 'rgb_command_topic' CONF_RGB_STATE_TOPIC = 'rgb_state_topic' CONF_RGB_VALUE_TEMPLATE = 'rgb_value_template' @@ -75,6 +76,7 @@ vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean, vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string, vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string, + vol.Optional(CONF_RGB_COMMAND_TEMPLATE): cv.template, vol.Optional(CONF_RGB_COMMAND_TOPIC): mqtt.valid_publish_topic, vol.Optional(CONF_RGB_STATE_TOPIC): mqtt.valid_subscribe_topic, vol.Optional(CONF_RGB_VALUE_TEMPLATE): cv.template, @@ -125,6 +127,7 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): CONF_COLOR_TEMP: config.get(CONF_COLOR_TEMP_VALUE_TEMPLATE), CONF_EFFECT: config.get(CONF_EFFECT_VALUE_TEMPLATE), CONF_RGB: config.get(CONF_RGB_VALUE_TEMPLATE), + CONF_RGB_COMMAND_TEMPLATE: config.get(CONF_RGB_COMMAND_TEMPLATE), CONF_STATE: config.get(CONF_STATE_VALUE_TEMPLATE), CONF_WHITE_VALUE: config.get(CONF_WHITE_VALUE_TEMPLATE), CONF_XY: config.get(CONF_XY_VALUE_TEMPLATE), @@ -397,10 +400,17 @@ def async_turn_on(self, **kwargs): if ATTR_RGB_COLOR in kwargs and \ self._topic[CONF_RGB_COMMAND_TOPIC] is not None: + rgb_color_str = '{},{},{}'.format(*kwargs[ATTR_RGB_COLOR]) + tpl = self._templates[CONF_RGB_COMMAND_TEMPLATE] + if tpl is not None: + colors = {'red', 'green', 'blue'} + env = {} + for key, val in zip(colors, kwargs[ATTR_RGB_COLOR]): + env[key] = val + rgb_color_str = tpl.async_render(env) mqtt.async_publish( self.hass, self._topic[CONF_RGB_COMMAND_TOPIC], - '{},{},{}'.format(*kwargs[ATTR_RGB_COLOR]), self._qos, - self._retain) + rgb_color_str, self._qos, self._retain) if self._optimistic_rgb: self._rgb = kwargs[ATTR_RGB_COLOR] diff --git a/tests/components/light/test_mqtt.py b/tests/components/light/test_mqtt.py index 97375aa6b13d3..e111fc3aa491f 100644 --- a/tests/components/light/test_mqtt.py +++ b/tests/components/light/test_mqtt.py @@ -123,6 +123,20 @@ payload_on: "on" payload_off: "off" +config for RGB Version with RGB command template: + +light: + platform: mqtt + name: "Office Light RGB" + state_topic: "office/rgb1/light/status" + command_topic: "office/rgb1/light/switch" + rgb_state_topic: "office/rgb1/rgb/status" + rgb_command_topic: "office/rgb1/rgb/set" + rgb_command_template: "{{ '#%02x%02x%02x' | format(red, green, blue)}}" + qos: 0 + payload_on: "on" + payload_off: "off" + """ import unittest from unittest import mock @@ -512,6 +526,38 @@ def test_sending_mqtt_commands_and_optimistic(self): \ self.assertEqual(80, state.attributes['white_value']) self.assertEqual((0.123, 0.123), state.attributes['xy_color']) + def test_sending_mqtt_rgb_command_with_template(self): + """Test the sending of RGB command with template.""" + config = {light.DOMAIN: { + 'platform': 'mqtt', + 'name': 'test', + 'command_topic': 'test_light_rgb/set', + 'rgb_command_topic': 'test_light_rgb/rgb/set', + 'rgb_command_template': '{{ "#%02x%02x%02x" | ' + 'format(red, green, blue)}}', + 'payload_on': 'on', + 'payload_off': 'off', + 'qos': 0 + }} + + 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) + + light.turn_on(self.hass, 'light.test', rgb_color=[255, 255, 255]) + self.hass.block_till_done() + + self.mock_publish().async_publish.assert_has_calls([ + mock.call('test_light_rgb/set', 'on', 0, False), + mock.call('test_light_rgb/rgb/set', '#ffffff', 0, False), + ], any_order=True) + + state = self.hass.states.get('light.test') + self.assertEqual(STATE_ON, state.state) + self.assertEqual((255, 255, 255), state.attributes['rgb_color']) + def test_show_brightness_if_only_command_topic(self): """Test the brightness if only a command topic is present.""" config = {light.DOMAIN: { From 5a4d07c96e9cce3864988255ff1fa76ea5b13e80 Mon Sep 17 00:00:00 2001 From: Konstantin Belyalov Date: Tue, 5 Sep 2017 07:49:45 -0700 Subject: [PATCH 2/3] Address reviewer's issues: refactor template render part. --- homeassistant/components/light/mqtt.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/light/mqtt.py b/homeassistant/components/light/mqtt.py index dd276024aa367..a4a98e1a3d43a 100644 --- a/homeassistant/components/light/mqtt.py +++ b/homeassistant/components/light/mqtt.py @@ -400,14 +400,14 @@ def async_turn_on(self, **kwargs): if ATTR_RGB_COLOR in kwargs and \ self._topic[CONF_RGB_COMMAND_TOPIC] is not None: - rgb_color_str = '{},{},{}'.format(*kwargs[ATTR_RGB_COLOR]) tpl = self._templates[CONF_RGB_COMMAND_TEMPLATE] if tpl is not None: colors = {'red', 'green', 'blue'} - env = {} - for key, val in zip(colors, kwargs[ATTR_RGB_COLOR]): - env[key] = val - rgb_color_str = tpl.async_render(env) + variables = {key: val for key, val in + zip(colors, kwargs[ATTR_RGB_COLOR])} + rgb_color_str = tpl.async_render(variables) + else: + rgb_color_str = '{},{},{}'.format(*kwargs[ATTR_RGB_COLOR]) mqtt.async_publish( self.hass, self._topic[CONF_RGB_COMMAND_TOPIC], rgb_color_str, self._qos, self._retain) From 3c90e164186dba58b8d7cbe2812bcc629e837199 Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Wed, 6 Sep 2017 00:25:54 +0200 Subject: [PATCH 3/3] Update mqtt.py --- homeassistant/components/light/mqtt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/light/mqtt.py b/homeassistant/components/light/mqtt.py index a4a98e1a3d43a..ac72a7052f11b 100644 --- a/homeassistant/components/light/mqtt.py +++ b/homeassistant/components/light/mqtt.py @@ -401,7 +401,7 @@ def async_turn_on(self, **kwargs): self._topic[CONF_RGB_COMMAND_TOPIC] is not None: tpl = self._templates[CONF_RGB_COMMAND_TEMPLATE] - if tpl is not None: + if tpl: colors = {'red', 'green', 'blue'} variables = {key: val for key, val in zip(colors, kwargs[ATTR_RGB_COLOR])}