diff --git a/homeassistant/components/mqtt/light/schema_basic.py b/homeassistant/components/mqtt/light/schema_basic.py index d7c373bf72b..6fa6d70a665 100644 --- a/homeassistant/components/mqtt/light/schema_basic.py +++ b/homeassistant/components/mqtt/light/schema_basic.py @@ -348,17 +348,12 @@ class MqttLight( "msg_callback": brightness_received, "qos": self._config[CONF_QOS], } - self._brightness = 255 elif ( self._optimistic_brightness and last_state and last_state.attributes.get(ATTR_BRIGHTNESS) ): self._brightness = last_state.attributes.get(ATTR_BRIGHTNESS) - elif self._topic[CONF_BRIGHTNESS_COMMAND_TOPIC] is not None: - self._brightness = 255 - else: - self._brightness = None @callback @log_messages(self.hass, self.entity_id) @@ -382,15 +377,12 @@ class MqttLight( "msg_callback": rgb_received, "qos": self._config[CONF_QOS], } - self._hs = (0, 0) if ( self._optimistic_rgb and last_state and last_state.attributes.get(ATTR_HS_COLOR) ): self._hs = last_state.attributes.get(ATTR_HS_COLOR) - elif self._topic[CONF_RGB_COMMAND_TOPIC] is not None: - self._hs = (0, 0) @callback @log_messages(self.hass, self.entity_id) @@ -412,17 +404,12 @@ class MqttLight( "msg_callback": color_temp_received, "qos": self._config[CONF_QOS], } - self._color_temp = 150 if ( self._optimistic_color_temp and last_state and last_state.attributes.get(ATTR_COLOR_TEMP) ): self._color_temp = last_state.attributes.get(ATTR_COLOR_TEMP) - elif self._topic[CONF_COLOR_TEMP_COMMAND_TOPIC] is not None: - self._color_temp = 150 - else: - self._color_temp = None @callback @log_messages(self.hass, self.entity_id) @@ -444,17 +431,12 @@ class MqttLight( "msg_callback": effect_received, "qos": self._config[CONF_QOS], } - self._effect = "none" if ( self._optimistic_effect and last_state and last_state.attributes.get(ATTR_EFFECT) ): self._effect = last_state.attributes.get(ATTR_EFFECT) - elif self._topic[CONF_EFFECT_COMMAND_TOPIC] is not None: - self._effect = "none" - else: - self._effect = None @callback @log_messages(self.hass, self.entity_id) @@ -478,15 +460,12 @@ class MqttLight( "msg_callback": hs_received, "qos": self._config[CONF_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 @log_messages(self.hass, self.entity_id) @@ -510,17 +489,12 @@ class MqttLight( "msg_callback": white_value_received, "qos": self._config[CONF_QOS], } - self._white_value = 255 elif ( self._optimistic_white_value and last_state and last_state.attributes.get(ATTR_WHITE_VALUE) ): self._white_value = last_state.attributes.get(ATTR_WHITE_VALUE) - elif self._topic[CONF_WHITE_VALUE_COMMAND_TOPIC] is not None: - self._white_value = 255 - else: - self._white_value = None @callback @log_messages(self.hass, self.entity_id) @@ -541,15 +515,12 @@ class MqttLight( "msg_callback": xy_received, "qos": self._config[CONF_QOS], } - self._hs = (0, 0) if ( self._optimistic_xy and last_state and last_state.attributes.get(ATTR_HS_COLOR) ): self._hs = last_state.attributes.get(ATTR_HS_COLOR) - elif self._topic[CONF_XY_COMMAND_TOPIC] is not None: - self._hs = (0, 0) self._sub_state = await subscription.async_subscribe_topics( self.hass, self._sub_state, topics @@ -781,8 +752,9 @@ class MqttLight( and ATTR_HS_COLOR not in kwargs and self._topic[CONF_RGB_COMMAND_TOPIC] is not None ): + hs_color = self._hs if self._hs is not None else (0, 0) rgb = color_util.color_hsv_to_RGB( - self._hs[0], self._hs[1], kwargs[ATTR_BRIGHTNESS] / 255 * 100 + hs_color[0], hs_color[1], kwargs[ATTR_BRIGHTNESS] / 255 * 100 ) tpl = self._command_templates[CONF_RGB_COMMAND_TEMPLATE] if tpl: diff --git a/homeassistant/components/mqtt/light/schema_json.py b/homeassistant/components/mqtt/light/schema_json.py index 39ea550d877..bba5605348b 100644 --- a/homeassistant/components/mqtt/light/schema_json.py +++ b/homeassistant/components/mqtt/light/schema_json.py @@ -192,35 +192,6 @@ class MqttLightJson( optimistic = config[CONF_OPTIMISTIC] self._optimistic = optimistic or self._topic[CONF_STATE_TOPIC] is None - brightness = config[CONF_BRIGHTNESS] - if brightness: - self._brightness = 255 - else: - self._brightness = None - - color_temp = config[CONF_COLOR_TEMP] - if color_temp: - self._color_temp = 150 - else: - self._color_temp = None - - effect = config[CONF_EFFECT] - if effect: - self._effect = "none" - else: - self._effect = None - - white_value = config[CONF_WHITE_VALUE] - if white_value: - self._white_value = 255 - else: - self._white_value = None - - if config[CONF_HS] or config[CONF_RGB] or config[CONF_XY]: - self._hs = [0, 0] - else: - self._hs = None - self._flash_times = { key: config.get(key) for key in (CONF_FLASH_TIME_SHORT, CONF_FLASH_TIME_LONG) @@ -228,10 +199,10 @@ class MqttLightJson( self._supported_features = SUPPORT_TRANSITION | SUPPORT_FLASH self._supported_features |= config[CONF_RGB] and SUPPORT_COLOR - self._supported_features |= brightness and SUPPORT_BRIGHTNESS - self._supported_features |= color_temp and SUPPORT_COLOR_TEMP - self._supported_features |= effect and SUPPORT_EFFECT - self._supported_features |= white_value and SUPPORT_WHITE_VALUE + self._supported_features |= config[CONF_BRIGHTNESS] and SUPPORT_BRIGHTNESS + self._supported_features |= config[CONF_COLOR_TEMP] and SUPPORT_COLOR_TEMP + self._supported_features |= config[CONF_EFFECT] and SUPPORT_EFFECT + self._supported_features |= config[CONF_WHITE_VALUE] and SUPPORT_WHITE_VALUE self._supported_features |= config[CONF_XY] and SUPPORT_COLOR self._supported_features |= config[CONF_HS] and SUPPORT_COLOR @@ -250,7 +221,7 @@ class MqttLightJson( elif values["state"] == "OFF": self._state = False - if self._hs is not None: + if self._supported_features and SUPPORT_COLOR: try: red = int(values["color"]["r"]) green = int(values["color"]["g"]) @@ -282,7 +253,7 @@ class MqttLightJson( except ValueError: _LOGGER.warning("Invalid HS color value received") - if self._brightness is not None: + if self._supported_features and SUPPORT_BRIGHTNESS: try: self._brightness = int( values["brightness"] @@ -294,7 +265,7 @@ class MqttLightJson( except (TypeError, ValueError): _LOGGER.warning("Invalid brightness value received") - if self._color_temp is not None: + if self._supported_features and SUPPORT_COLOR_TEMP: try: self._color_temp = int(values["color_temp"]) except KeyError: @@ -302,13 +273,13 @@ class MqttLightJson( except ValueError: _LOGGER.warning("Invalid color temp value received") - if self._effect is not None: + if self._supported_features and SUPPORT_EFFECT: try: self._effect = values["effect"] except KeyError: pass - if self._white_value is not None: + if self._supported_features and SUPPORT_WHITE_VALUE: try: self._white_value = int(values["white_value"]) except KeyError: @@ -440,7 +411,7 @@ class MqttLightJson( if self._config[CONF_RGB]: # If there's a brightness topic set, we don't want to scale the # RGB values given using the brightness. - if self._brightness is not None: + if self._config[CONF_BRIGHTNESS]: brightness = 255 else: brightness = kwargs.get(ATTR_BRIGHTNESS, 255) @@ -473,7 +444,7 @@ class MqttLightJson( if ATTR_TRANSITION in kwargs: message["transition"] = kwargs[ATTR_TRANSITION] - if ATTR_BRIGHTNESS in kwargs and self._brightness is not None: + if ATTR_BRIGHTNESS in kwargs and self._config[CONF_BRIGHTNESS]: brightness_normalized = kwargs[ATTR_BRIGHTNESS] / DEFAULT_BRIGHTNESS_SCALE brightness_scale = self._config[CONF_BRIGHTNESS_SCALE] device_brightness = min( diff --git a/homeassistant/components/mqtt/light/schema_template.py b/homeassistant/components/mqtt/light/schema_template.py index 9c2758524a3..46a2b9f7ab7 100644 --- a/homeassistant/components/mqtt/light/schema_template.py +++ b/homeassistant/components/mqtt/light/schema_template.py @@ -185,32 +185,6 @@ class MqttLightTemplate( or self._templates[CONF_STATE_TEMPLATE] is None ) - # features - if self._templates[CONF_BRIGHTNESS_TEMPLATE] is not None: - self._brightness = 255 - else: - self._brightness = None - - if self._templates[CONF_COLOR_TEMP_TEMPLATE] is not None: - self._color_temp = 255 - else: - self._color_temp = None - - if self._templates[CONF_WHITE_VALUE_TEMPLATE] is not None: - self._white_value = 255 - else: - self._white_value = None - - if ( - self._templates[CONF_RED_TEMPLATE] is not None - and self._templates[CONF_GREEN_TEMPLATE] is not None - and self._templates[CONF_BLUE_TEMPLATE] is not None - ): - self._hs = [0, 0] - else: - self._hs = None - self._effect = None - async def _subscribe_topics(self): """(Re)Subscribe to topics.""" for tpl in self._templates.values(): @@ -233,7 +207,7 @@ class MqttLightTemplate( else: _LOGGER.warning("Invalid state value received") - if self._brightness is not None: + if self._templates[CONF_BRIGHTNESS_TEMPLATE] is not None: try: self._brightness = int( self._templates[ @@ -243,7 +217,7 @@ class MqttLightTemplate( except ValueError: _LOGGER.warning("Invalid brightness value received") - if self._color_temp is not None: + if self._templates[CONF_COLOR_TEMP_TEMPLATE] is not None: try: self._color_temp = int( self._templates[ @@ -253,7 +227,11 @@ class MqttLightTemplate( except ValueError: _LOGGER.warning("Invalid color temperature value received") - if self._hs is not None: + if ( + self._templates[CONF_RED_TEMPLATE] is not None + and self._templates[CONF_GREEN_TEMPLATE] is not None + and self._templates[CONF_BLUE_TEMPLATE] is not None + ): try: red = int( self._templates[ @@ -274,7 +252,7 @@ class MqttLightTemplate( except ValueError: _LOGGER.warning("Invalid color value received") - if self._white_value is not None: + if self._templates[CONF_COLOR_TEMP_TEMPLATE] is not None: try: self._white_value = int( self._templates[ @@ -429,7 +407,8 @@ class MqttLightTemplate( brightness = 255 else: brightness = kwargs.get( - ATTR_BRIGHTNESS, self._brightness if self._brightness else 255 + ATTR_BRIGHTNESS, + self._brightness if self._brightness is not None else 255, ) rgb = color_util.color_hsv_to_RGB( hs_color[0], hs_color[1], brightness / 255 * 100 @@ -497,15 +476,19 @@ class MqttLightTemplate( def supported_features(self): """Flag supported features.""" features = SUPPORT_FLASH | SUPPORT_TRANSITION - if self._brightness is not None: + if self._templates[CONF_BRIGHTNESS_TEMPLATE] is not None: features = features | SUPPORT_BRIGHTNESS - if self._hs is not None: + if ( + self._templates[CONF_RED_TEMPLATE] is not None + and self._templates[CONF_GREEN_TEMPLATE] is not None + and self._templates[CONF_BLUE_TEMPLATE] is not None + ): features = features | SUPPORT_COLOR if self._config.get(CONF_EFFECT_LIST) is not None: features = features | SUPPORT_EFFECT - if self._color_temp is not None: + if self._templates[CONF_COLOR_TEMP_TEMPLATE] is not None: features = features | SUPPORT_COLOR_TEMP - if self._white_value is not None: + if self._templates[CONF_WHITE_VALUE_TEMPLATE] is not None: features = features | SUPPORT_WHITE_VALUE return features diff --git a/tests/components/mqtt/test_light.py b/tests/components/mqtt/test_light.py index 30084a310fd..62291fd18b7 100644 --- a/tests/components/mqtt/test_light.py +++ b/tests/components/mqtt/test_light.py @@ -289,13 +289,13 @@ async def test_controlling_state_via_topic(hass, mqtt_mock): state = hass.states.get("light.test") assert state.state == STATE_ON - assert state.attributes.get("rgb_color") == (255, 255, 255) - assert state.attributes.get("brightness") == 255 - assert state.attributes.get("color_temp") == 150 - assert state.attributes.get("effect") == "none" - assert state.attributes.get("hs_color") == (0, 0) - assert state.attributes.get("white_value") == 255 - assert state.attributes.get("xy_color") == (0.323, 0.329) + assert state.attributes.get("rgb_color") is None + assert state.attributes.get("brightness") is None + assert state.attributes.get("color_temp") is None + assert state.attributes.get("effect") is None + assert state.attributes.get("hs_color") is None + assert state.attributes.get("white_value") is None + assert state.attributes.get("xy_color") is None async_fire_mqtt_message(hass, "test_light_rgb/status", "0") @@ -383,12 +383,17 @@ async def test_invalid_state_via_topic(hass, mqtt_mock, caplog): assert not state.attributes.get(ATTR_ASSUMED_STATE) async_fire_mqtt_message(hass, "test_light_rgb/status", "1") + async_fire_mqtt_message(hass, "test_light_rgb/rgb/status", "255,255,255") + async_fire_mqtt_message(hass, "test_light_rgb/brightness/status", "255") + async_fire_mqtt_message(hass, "test_light_rgb/color_temp/status", "153") + async_fire_mqtt_message(hass, "test_light_rgb/effect/status", "none") + async_fire_mqtt_message(hass, "test_light_rgb/white_value/status", "255") state = hass.states.get("light.test") assert state.state == STATE_ON assert state.attributes.get("rgb_color") == (255, 255, 255) assert state.attributes.get("brightness") == 255 - assert state.attributes.get("color_temp") == 150 + assert state.attributes.get("color_temp") == 153 assert state.attributes.get("effect") == "none" assert state.attributes.get("hs_color") == (0, 0) assert state.attributes.get("white_value") == 255 @@ -407,7 +412,7 @@ async def test_invalid_state_via_topic(hass, mqtt_mock, caplog): async_fire_mqtt_message(hass, "test_light_rgb/color_temp/status", "") assert "Ignoring empty color temp message" in caplog.text light_state = hass.states.get("light.test") - assert light_state.attributes["color_temp"] == 150 + assert light_state.attributes["color_temp"] == 153 async_fire_mqtt_message(hass, "test_light_rgb/effect/status", "") assert "Ignoring empty effect message" in caplog.text @@ -472,7 +477,7 @@ async def test_brightness_controlling_scale(hass, mqtt_mock): state = hass.states.get("light.test") assert state.state == STATE_ON - assert state.attributes.get("brightness") == 255 + assert state.attributes.get("brightness") is None async_fire_mqtt_message(hass, "test_scale/status", "off") @@ -558,7 +563,7 @@ async def test_white_value_controlling_scale(hass, mqtt_mock): state = hass.states.get("light.test") assert state.state == STATE_ON - assert state.attributes.get("white_value") == 255 + assert state.attributes.get("white_value") is None async_fire_mqtt_message(hass, "test_scale/status", "off") @@ -846,162 +851,6 @@ async def test_sending_mqtt_color_temp_command_with_template(hass, mqtt_mock): assert state.attributes["color_temp"] == 100 -async def test_show_brightness_if_only_command_topic(hass, mqtt_mock): - """Test the brightness if only a command topic is present.""" - config = { - light.DOMAIN: { - "platform": "mqtt", - "name": "test", - "brightness_command_topic": "test_light_rgb/brightness/set", - "command_topic": "test_light_rgb/set", - "state_topic": "test_light_rgb/status", - } - } - - assert await async_setup_component(hass, light.DOMAIN, config) - await hass.async_block_till_done() - - state = hass.states.get("light.test") - assert state.state == STATE_OFF - assert state.attributes.get("brightness") is None - - async_fire_mqtt_message(hass, "test_light_rgb/status", "ON") - - state = hass.states.get("light.test") - assert state.state == STATE_ON - assert state.attributes.get("brightness") == 255 - - -async def test_show_color_temp_only_if_command_topic(hass, mqtt_mock): - """Test the color temp only if a command topic is present.""" - config = { - light.DOMAIN: { - "platform": "mqtt", - "name": "test", - "color_temp_command_topic": "test_light_rgb/brightness/set", - "command_topic": "test_light_rgb/set", - "state_topic": "test_light_rgb/status", - } - } - - assert await async_setup_component(hass, light.DOMAIN, config) - await hass.async_block_till_done() - - state = hass.states.get("light.test") - assert state.state == STATE_OFF - assert state.attributes.get("color_temp") is None - - async_fire_mqtt_message(hass, "test_light_rgb/status", "ON") - - state = hass.states.get("light.test") - assert state.state == STATE_ON - assert state.attributes.get("color_temp") == 150 - - -async def test_show_effect_only_if_command_topic(hass, mqtt_mock): - """Test the effect only if a command topic is present.""" - config = { - light.DOMAIN: { - "platform": "mqtt", - "name": "test", - "effect_command_topic": "test_light_rgb/effect/set", - "command_topic": "test_light_rgb/set", - "state_topic": "test_light_rgb/status", - } - } - - assert await async_setup_component(hass, light.DOMAIN, config) - await hass.async_block_till_done() - - state = hass.states.get("light.test") - assert state.state == STATE_OFF - assert state.attributes.get("effect") is None - - async_fire_mqtt_message(hass, "test_light_rgb/status", "ON") - - state = hass.states.get("light.test") - assert state.state == STATE_ON - assert state.attributes.get("effect") == "none" - - -async def test_show_hs_if_only_command_topic(hass, mqtt_mock): - """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", - } - } - - assert await async_setup_component(hass, light.DOMAIN, config) - await hass.async_block_till_done() - - state = hass.states.get("light.test") - assert state.state == STATE_OFF - assert state.attributes.get("hs_color") is None - - async_fire_mqtt_message(hass, "test_light_rgb/status", "ON") - - state = hass.states.get("light.test") - assert state.state == STATE_ON - assert state.attributes.get("hs_color") == (0, 0) - - -async def test_show_white_value_if_only_command_topic(hass, mqtt_mock): - """Test the white_value if only a command topic is present.""" - config = { - light.DOMAIN: { - "platform": "mqtt", - "name": "test", - "white_value_command_topic": "test_light_rgb/white_value/set", - "command_topic": "test_light_rgb/set", - "state_topic": "test_light_rgb/status", - } - } - - assert await async_setup_component(hass, light.DOMAIN, config) - await hass.async_block_till_done() - - state = hass.states.get("light.test") - assert state.state == STATE_OFF - assert state.attributes.get("white_value") is None - - async_fire_mqtt_message(hass, "test_light_rgb/status", "ON") - - state = hass.states.get("light.test") - assert state.state == STATE_ON - assert state.attributes.get("white_value") == 255 - - -async def test_show_xy_if_only_command_topic(hass, mqtt_mock): - """Test the xy if only a command topic is present.""" - config = { - light.DOMAIN: { - "platform": "mqtt", - "name": "test", - "xy_command_topic": "test_light_rgb/xy/set", - "command_topic": "test_light_rgb/set", - "state_topic": "test_light_rgb/status", - } - } - - assert await async_setup_component(hass, light.DOMAIN, config) - await hass.async_block_till_done() - - state = hass.states.get("light.test") - assert state.state == STATE_OFF - assert state.attributes.get("xy_color") is None - - async_fire_mqtt_message(hass, "test_light_rgb/status", "ON") - - state = hass.states.get("light.test") - assert state.state == STATE_ON - assert state.attributes.get("xy_color") == (0.323, 0.329) - - async def test_on_command_first(hass, mqtt_mock): """Test on command being sent before brightness.""" config = { diff --git a/tests/components/mqtt/test_light_json.py b/tests/components/mqtt/test_light_json.py index 9a3d9abacc9..e41575968da 100644 --- a/tests/components/mqtt/test_light_json.py +++ b/tests/components/mqtt/test_light_json.py @@ -796,7 +796,7 @@ async def test_effect(hass, mqtt_mock): mqtt_mock.async_publish.reset_mock() state = hass.states.get("light.test") assert state.state == STATE_ON - assert state.attributes.get("effect") == "none" + assert state.attributes.get("effect") is None await common.async_turn_on(hass, "light.test", effect="rainbow") @@ -942,7 +942,7 @@ async def test_brightness_scale(hass, mqtt_mock): state = hass.states.get("light.test") assert state.state == STATE_ON - assert state.attributes.get("brightness") == 255 + assert state.attributes.get("brightness") is None # Turn on the light with brightness async_fire_mqtt_message( diff --git a/tests/components/mqtt/test_light_template.py b/tests/components/mqtt/test_light_template.py index 17b3332da40..6767375a50e 100644 --- a/tests/components/mqtt/test_light_template.py +++ b/tests/components/mqtt/test_light_template.py @@ -317,6 +317,14 @@ async def test_sending_mqtt_commands_and_optimistic(hass, mqtt_mock): "{{ blue|d }}", "command_off_template": "off", "effect_list": ["colorloop", "random"], + "optimistic": True, + "state_template": '{{ value.split(",")[0] }}', + "color_temp_template": '{{ value.split(",")[2] }}', + "white_value_template": '{{ value.split(",")[3] }}', + "red_template": '{{ value.split(",")[4].' 'split("-")[0] }}', + "green_template": '{{ value.split(",")[4].' 'split("-")[1] }}', + "blue_template": '{{ value.split(",")[4].' 'split("-")[2] }}', + "effect_template": '{{ value.split(",")[5] }}', "qos": 2, } }, @@ -325,7 +333,6 @@ async def test_sending_mqtt_commands_and_optimistic(hass, mqtt_mock): state = hass.states.get("light.test") assert state.state == STATE_ON - assert state.attributes.get("brightness") == 95 assert state.attributes.get("hs_color") == (100, 100) assert state.attributes.get("effect") == "random" assert state.attributes.get("color_temp") == 100 @@ -366,7 +373,6 @@ async def test_sending_mqtt_commands_and_optimistic(hass, mqtt_mock): mqtt_mock.async_publish.reset_mock() state = hass.states.get("light.test") assert state.state == STATE_ON - assert state.attributes.get("brightness") == 255 # Full brightness - no scaling of RGB values sent over MQTT await common.async_turn_on( @@ -399,7 +405,6 @@ async def test_sending_mqtt_commands_and_optimistic(hass, mqtt_mock): mqtt_mock.async_publish.reset_mock() state = hass.states.get("light.test") assert state.state == STATE_ON - assert state.attributes.get("brightness") == 128 # Half brightness - scaling of RGB values sent over MQTT await common.async_turn_on(