diff --git a/homeassistant/components/mqtt/light/schema_json.py b/homeassistant/components/mqtt/light/schema_json.py index c6622578a6f..489b424f4eb 100644 --- a/homeassistant/components/mqtt/light/schema_json.py +++ b/homeassistant/components/mqtt/light/schema_json.py @@ -175,6 +175,43 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity): self._supported_features |= config[CONF_XY] and SUPPORT_COLOR self._supported_features |= config[CONF_HS] and SUPPORT_COLOR + def _parse_color(self, values): + try: + red = int(values["color"]["r"]) + green = int(values["color"]["g"]) + blue = int(values["color"]["b"]) + + return color_util.color_RGB_to_hs(red, green, blue) + except KeyError: + pass + except ValueError: + _LOGGER.warning("Invalid RGB color value received") + return self._hs + + try: + x_color = float(values["color"]["x"]) + y_color = float(values["color"]["y"]) + + return color_util.color_xy_to_hs(x_color, y_color) + except KeyError: + pass + except ValueError: + _LOGGER.warning("Invalid XY color value received") + return self._hs + + try: + hue = float(values["color"]["h"]) + saturation = float(values["color"]["s"]) + + return (hue, saturation) + except KeyError: + pass + except ValueError: + _LOGGER.warning("Invalid HS color value received") + return self._hs + + return self._hs + async def _subscribe_topics(self): """(Re)Subscribe to topics.""" last_state = await self.async_get_last_state() @@ -190,37 +227,11 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity): elif values["state"] == "OFF": self._state = False - if self._supported_features and SUPPORT_COLOR: - try: - red = int(values["color"]["r"]) - green = int(values["color"]["g"]) - blue = int(values["color"]["b"]) - - self._hs = color_util.color_RGB_to_hs(red, green, blue) - except KeyError: - pass - except ValueError: - _LOGGER.warning("Invalid RGB color value received") - - try: - x_color = float(values["color"]["x"]) - y_color = float(values["color"]["y"]) - - self._hs = color_util.color_xy_to_hs(x_color, y_color) - except KeyError: - pass - except ValueError: - _LOGGER.warning("Invalid XY color value received") - - try: - hue = float(values["color"]["h"]) - saturation = float(values["color"]["s"]) - - self._hs = (hue, saturation) - except KeyError: - pass - except ValueError: - _LOGGER.warning("Invalid HS color value received") + if self._supported_features and SUPPORT_COLOR and "color" in values: + if values["color"] is None: + self._hs = None + else: + self._hs = self._parse_color(values) if self._supported_features and SUPPORT_BRIGHTNESS: try: @@ -236,7 +247,10 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity): if self._supported_features and SUPPORT_COLOR_TEMP: try: - self._color_temp = int(values["color_temp"]) + if values["color_temp"] is None: + self._color_temp = None + else: + self._color_temp = int(values["color_temp"]) except KeyError: pass except ValueError: diff --git a/tests/components/mqtt/test_light_json.py b/tests/components/mqtt/test_light_json.py index 1c9eed0e404..022df109f38 100644 --- a/tests/components/mqtt/test_light_json.py +++ b/tests/components/mqtt/test_light_json.py @@ -295,11 +295,21 @@ async def test_controlling_state_via_topic(hass, mqtt_mock): light_state = hass.states.get("light.test") assert light_state.attributes.get("hs_color") == (180.0, 50.0) + async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"ON", "color":null}') + + light_state = hass.states.get("light.test") + assert "hs_color" not in light_state.attributes + async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"ON", "color_temp":155}') light_state = hass.states.get("light.test") assert light_state.attributes.get("color_temp") == 155 + async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"ON", "color_temp":null}') + + light_state = hass.states.get("light.test") + assert "color_temp" not in light_state.attributes + async_fire_mqtt_message( hass, "test_light_rgb", '{"state":"ON", "effect":"colorloop"}' ) @@ -1004,6 +1014,18 @@ async def test_invalid_values(hass, mqtt_mock): assert state.attributes.get("white_value") == 255 assert state.attributes.get("color_temp") == 100 + # Empty color value + async_fire_mqtt_message( + hass, + "test_light_rgb", + '{"state":"ON",' '"color":{}}', + ) + + # Color should not have changed + state = hass.states.get("light.test") + assert state.state == STATE_ON + assert state.attributes.get("rgb_color") == (255, 255, 255) + # Bad HS color values async_fire_mqtt_message( hass,