From 9ade8002ac2fde685fe647772835621b92a36fb0 Mon Sep 17 00:00:00 2001 From: Konstantin Belyalov Date: Tue, 5 Sep 2017 16:01:03 -0700 Subject: [PATCH] Add new config variable to MQTT light (#9304) * Add new config variable to MQTT light * Address reviewer's issues: refactor template render part. * Update mqtt.py --- 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 038cacd300e..ac72a7052f1 100644 --- a/homeassistant/components/light/mqtt.py +++ b/homeassistant/components/light/mqtt.py @@ -39,6 +39,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_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 @@ PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({ 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 @@ class MqttLight(Light): if ATTR_RGB_COLOR in kwargs and \ self._topic[CONF_RGB_COMMAND_TOPIC] is not None: + tpl = self._templates[CONF_RGB_COMMAND_TEMPLATE] + if tpl: + colors = {'red', 'green', 'blue'} + 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], - '{},{},{}'.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 97375aa6b13..e111fc3aa49 100644 --- a/tests/components/light/test_mqtt.py +++ b/tests/components/light/test_mqtt.py @@ -123,6 +123,20 @@ light: 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 @@ class TestLightMQTT(unittest.TestCase): 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: {