Improve MQTT JSON light to allow non-ambiguous states (#45522)

This commit is contained in:
Erik Montnemery 2021-02-02 09:36:00 +01:00 committed by GitHub
parent aea8636c7e
commit 411c0a9685
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 32 deletions

View File

@ -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:

View File

@ -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,