mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Improve MQTT JSON light to allow non-ambiguous states (#45522)
This commit is contained in:
parent
aea8636c7e
commit
411c0a9685
@ -175,6 +175,43 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
|
|||||||
self._supported_features |= config[CONF_XY] and SUPPORT_COLOR
|
self._supported_features |= config[CONF_XY] and SUPPORT_COLOR
|
||||||
self._supported_features |= config[CONF_HS] 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):
|
async def _subscribe_topics(self):
|
||||||
"""(Re)Subscribe to topics."""
|
"""(Re)Subscribe to topics."""
|
||||||
last_state = await self.async_get_last_state()
|
last_state = await self.async_get_last_state()
|
||||||
@ -190,37 +227,11 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
|
|||||||
elif values["state"] == "OFF":
|
elif values["state"] == "OFF":
|
||||||
self._state = False
|
self._state = False
|
||||||
|
|
||||||
if self._supported_features and SUPPORT_COLOR:
|
if self._supported_features and SUPPORT_COLOR and "color" in values:
|
||||||
try:
|
if values["color"] is None:
|
||||||
red = int(values["color"]["r"])
|
self._hs = None
|
||||||
green = int(values["color"]["g"])
|
else:
|
||||||
blue = int(values["color"]["b"])
|
self._hs = self._parse_color(values)
|
||||||
|
|
||||||
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_BRIGHTNESS:
|
if self._supported_features and SUPPORT_BRIGHTNESS:
|
||||||
try:
|
try:
|
||||||
@ -236,7 +247,10 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity):
|
|||||||
|
|
||||||
if self._supported_features and SUPPORT_COLOR_TEMP:
|
if self._supported_features and SUPPORT_COLOR_TEMP:
|
||||||
try:
|
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:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -295,11 +295,21 @@ async def test_controlling_state_via_topic(hass, mqtt_mock):
|
|||||||
light_state = hass.states.get("light.test")
|
light_state = hass.states.get("light.test")
|
||||||
assert light_state.attributes.get("hs_color") == (180.0, 50.0)
|
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}')
|
async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"ON", "color_temp":155}')
|
||||||
|
|
||||||
light_state = hass.states.get("light.test")
|
light_state = hass.states.get("light.test")
|
||||||
assert light_state.attributes.get("color_temp") == 155
|
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(
|
async_fire_mqtt_message(
|
||||||
hass, "test_light_rgb", '{"state":"ON", "effect":"colorloop"}'
|
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("white_value") == 255
|
||||||
assert state.attributes.get("color_temp") == 100
|
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
|
# Bad HS color values
|
||||||
async_fire_mqtt_message(
|
async_fire_mqtt_message(
|
||||||
hass,
|
hass,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user