From cf523572294a89d3d44923aaa67d6ac28cbd940e Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Thu, 3 Feb 2022 16:49:57 +0100 Subject: [PATCH] Add MQTT light unknown state support (#65308) * Add MQTT light unknown sate support * Update homeassistant/components/mqtt/light/schema_basic.py Co-authored-by: Erik Montnemery * Update homeassistant/components/mqtt/light/schema_json.py Co-authored-by: Erik Montnemery * Update homeassistant/components/mqtt/light/schema_template.py Co-authored-by: Erik Montnemery * Update tests for default unknown state Co-authored-by: Erik Montnemery --- .../components/mqtt/light/schema_basic.py | 10 ++- .../components/mqtt/light/schema_json.py | 6 +- .../components/mqtt/light/schema_template.py | 6 +- tests/components/mqtt/test_light.py | 76 +++++++++++-------- tests/components/mqtt/test_light_json.py | 39 ++++++---- tests/components/mqtt/test_light_template.py | 42 +++++++--- 6 files changed, 116 insertions(+), 63 deletions(-) diff --git a/homeassistant/components/mqtt/light/schema_basic.py b/homeassistant/components/mqtt/light/schema_basic.py index f164abe5297..d917b379eab 100644 --- a/homeassistant/components/mqtt/light/schema_basic.py +++ b/homeassistant/components/mqtt/light/schema_basic.py @@ -109,6 +109,8 @@ CONF_WHITE_VALUE_STATE_TOPIC = "white_value_state_topic" CONF_WHITE_VALUE_TEMPLATE = "white_value_template" CONF_ON_COMMAND_TYPE = "on_command_type" +PAYLOAD_NONE = "None" + MQTT_LIGHT_ATTRIBUTES_BLOCKED = frozenset( { ATTR_COLOR_MODE, @@ -257,7 +259,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity): self._rgb_color = None self._rgbw_color = None self._rgbww_color = None - self._state = False + self._state = None self._supported_color_modes = None self._white_value = None self._xy_color = None @@ -435,9 +437,7 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity): @log_messages(self.hass, self.entity_id) def state_received(msg): """Handle new MQTT messages.""" - payload = self._value_templates[CONF_STATE_VALUE_TEMPLATE]( - msg.payload, None - ) + payload = self._value_templates[CONF_STATE_VALUE_TEMPLATE](msg.payload) if not payload: _LOGGER.debug("Ignoring empty state message from '%s'", msg.topic) return @@ -446,6 +446,8 @@ class MqttLight(MqttEntity, LightEntity, RestoreEntity): self._state = True elif payload == self._payload["off"]: self._state = False + elif payload == PAYLOAD_NONE: + self._state = None self.async_write_ha_state() if self._topic[CONF_STATE_TOPIC] is not None: diff --git a/homeassistant/components/mqtt/light/schema_json.py b/homeassistant/components/mqtt/light/schema_json.py index 2d9b8f6a388..32435948b1e 100644 --- a/homeassistant/components/mqtt/light/schema_json.py +++ b/homeassistant/components/mqtt/light/schema_json.py @@ -100,6 +100,8 @@ CONF_FLASH_TIME_SHORT = "flash_time_short" CONF_MAX_MIREDS = "max_mireds" CONF_MIN_MIREDS = "min_mireds" +PAYLOAD_NONE = "None" + def valid_color_configuration(config): """Test color_mode is not combined with deprecated config.""" @@ -179,7 +181,7 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity): def __init__(self, hass, config, config_entry, discovery_data): """Initialize MQTT JSON light.""" - self._state = False + self._state = None self._supported_features = 0 self._topic = None @@ -317,6 +319,8 @@ class MqttLightJson(MqttEntity, LightEntity, RestoreEntity): self._state = True elif values["state"] == "OFF": self._state = False + elif values["state"] is None: + self._state = None if self._supported_features and SUPPORT_COLOR and "color" in values: if values["color"] is None: diff --git a/homeassistant/components/mqtt/light/schema_template.py b/homeassistant/components/mqtt/light/schema_template.py index 736ff98f321..b7f03fd0508 100644 --- a/homeassistant/components/mqtt/light/schema_template.py +++ b/homeassistant/components/mqtt/light/schema_template.py @@ -67,6 +67,8 @@ CONF_MIN_MIREDS = "min_mireds" CONF_RED_TEMPLATE = "red_template" CONF_WHITE_VALUE_TEMPLATE = "white_value_template" +PAYLOAD_NONE = "None" + PLATFORM_SCHEMA_TEMPLATE = ( mqtt.MQTT_RW_PLATFORM_SCHEMA.extend( { @@ -109,7 +111,7 @@ class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity): def __init__(self, hass, config, config_entry, discovery_data): """Initialize a MQTT Template light.""" - self._state = False + self._state = None self._topics = None self._templates = None @@ -173,6 +175,8 @@ class MqttLightTemplate(MqttEntity, LightEntity, RestoreEntity): self._state = True elif state == STATE_OFF: self._state = False + elif state == PAYLOAD_NONE: + self._state = None else: _LOGGER.warning("Invalid state value received") diff --git a/tests/components/mqtt/test_light.py b/tests/components/mqtt/test_light.py index dcff826311b..a1f929244a0 100644 --- a/tests/components/mqtt/test_light.py +++ b/tests/components/mqtt/test_light.py @@ -177,6 +177,7 @@ from homeassistant.const import ( ATTR_SUPPORTED_FEATURES, STATE_OFF, STATE_ON, + STATE_UNKNOWN, ) import homeassistant.core as ha from homeassistant.setup import async_setup_component @@ -269,7 +270,7 @@ async def test_no_color_brightness_color_temp_hs_white_xy_if_no_topics(hass, mqt await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("rgb_color") is None assert state.attributes.get("brightness") is None assert state.attributes.get("color_temp") is None @@ -298,6 +299,16 @@ async def test_no_color_brightness_color_temp_hs_white_xy_if_no_topics(hass, mqt assert state.attributes.get(light.ATTR_COLOR_MODE) == "onoff" assert state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) == ["onoff"] + async_fire_mqtt_message(hass, "test_light_rgb/status", "OFF") + + state = hass.states.get("light.test") + assert state.state == STATE_OFF + + async_fire_mqtt_message(hass, "test_light_rgb/status", "None") + + state = hass.states.get("light.test") + assert state.state == STATE_UNKNOWN + async def test_legacy_controlling_state_via_topic(hass, mqtt_mock): """Test the controlling of the state via topic for legacy light (white_value).""" @@ -332,7 +343,7 @@ async def test_legacy_controlling_state_via_topic(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("rgb_color") is None assert state.attributes.get("brightness") is None assert state.attributes.get("color_temp") is None @@ -463,7 +474,7 @@ async def test_controlling_state_via_topic(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("rgb_color") is None assert state.attributes.get("brightness") is None assert state.attributes.get("color_temp") is None @@ -581,7 +592,7 @@ async def test_legacy_invalid_state_via_topic(hass, mqtt_mock, caplog): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("rgb_color") is None assert state.attributes.get("brightness") is None assert state.attributes.get("color_temp") is None @@ -700,7 +711,7 @@ async def test_invalid_state_via_topic(hass, mqtt_mock, caplog): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("rgb_color") is None assert state.attributes.get("rgbw_color") is None assert state.attributes.get("rgbww_color") is None @@ -823,7 +834,7 @@ async def test_brightness_controlling_scale(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("brightness") is None assert not state.attributes.get(ATTR_ASSUMED_STATE) @@ -869,7 +880,7 @@ async def test_brightness_from_rgb_controlling_scale(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("brightness") is None assert not state.attributes.get(ATTR_ASSUMED_STATE) @@ -909,7 +920,7 @@ async def test_legacy_white_value_controlling_scale(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("white_value") is None assert not state.attributes.get(ATTR_ASSUMED_STATE) @@ -969,7 +980,7 @@ async def test_legacy_controlling_state_via_topic_with_templates(hass, mqtt_mock await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("brightness") is None assert state.attributes.get("rgb_color") is None @@ -1016,6 +1027,10 @@ async def test_legacy_controlling_state_via_topic_with_templates(hass, mqtt_mock state = hass.states.get("light.test") assert state.attributes.get("xy_color") == (0.14, 0.131) + async_fire_mqtt_message(hass, "test_light_rgb/status", '{"hello": null}') + state = hass.states.get("light.test") + assert state.state == STATE_UNKNOWN + async def test_controlling_state_via_topic_with_templates(hass, mqtt_mock): """Test the setting of the state with a template.""" @@ -1058,7 +1073,7 @@ async def test_controlling_state_via_topic_with_templates(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("brightness") is None assert state.attributes.get("rgb_color") is None @@ -1456,7 +1471,7 @@ async def test_sending_mqtt_rgb_command_with_template(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", rgb_color=[255, 128, 64]) @@ -1493,7 +1508,7 @@ async def test_sending_mqtt_rgbw_command_with_template(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", rgbw_color=[255, 128, 64, 32]) @@ -1530,7 +1545,7 @@ async def test_sending_mqtt_rgbww_command_with_template(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", rgbww_color=[255, 128, 64, 32, 16]) @@ -1566,7 +1581,7 @@ async def test_sending_mqtt_color_temp_command_with_template(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", color_temp=100) @@ -1599,7 +1614,7 @@ async def test_on_command_first(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", brightness=50) @@ -1634,7 +1649,7 @@ async def test_on_command_last(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", brightness=50) @@ -1671,7 +1686,7 @@ async def test_on_command_brightness(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN # Turn on w/ no brightness - should set to max await common.async_turn_on(hass, "light.test") @@ -1727,7 +1742,7 @@ async def test_on_command_brightness_scaled(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN # Turn on w/ no brightness - should set to max await common.async_turn_on(hass, "light.test") @@ -1795,7 +1810,7 @@ async def test_legacy_on_command_rgb(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", brightness=127) @@ -1885,7 +1900,7 @@ async def test_on_command_rgb(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", brightness=127) @@ -1975,7 +1990,7 @@ async def test_on_command_rgbw(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", brightness=127) @@ -2065,7 +2080,7 @@ async def test_on_command_rgbww(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", brightness=127) @@ -2156,7 +2171,7 @@ async def test_on_command_rgb_template(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", brightness=127) @@ -2193,8 +2208,7 @@ async def test_on_command_rgbw_template(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF - + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", brightness=127) # Should get the following MQTT messages. @@ -2230,7 +2244,7 @@ async def test_on_command_rgbww_template(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", brightness=127) @@ -2279,7 +2293,7 @@ async def test_on_command_white(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("brightness") is None assert state.attributes.get("rgb_color") is None assert state.attributes.get(light.ATTR_COLOR_MODE) is None @@ -2364,7 +2378,7 @@ async def test_explicit_color_mode(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("rgb_color") is None assert state.attributes.get("brightness") is None assert state.attributes.get("color_temp") is None @@ -2505,7 +2519,7 @@ async def test_explicit_color_mode_templated(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("brightness") is None assert state.attributes.get("color_temp") is None assert state.attributes.get("hs_color") is None @@ -2591,7 +2605,7 @@ async def test_white_state_update(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("brightness") is None assert state.attributes.get("rgb_color") is None assert state.attributes.get(light.ATTR_COLOR_MODE) is None @@ -2639,7 +2653,7 @@ async def test_effect(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test", effect="rainbow") diff --git a/tests/components/mqtt/test_light_json.py b/tests/components/mqtt/test_light_json.py index baad644bf6d..2811e44618d 100644 --- a/tests/components/mqtt/test_light_json.py +++ b/tests/components/mqtt/test_light_json.py @@ -102,6 +102,7 @@ from homeassistant.const import ( ATTR_SUPPORTED_FEATURES, STATE_OFF, STATE_ON, + STATE_UNKNOWN, ) import homeassistant.core as ha from homeassistant.setup import async_setup_component @@ -268,7 +269,7 @@ async def test_no_color_brightness_color_temp_white_val_if_no_topics(hass, mqtt_ await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN expected_features = light.SUPPORT_FLASH | light.SUPPORT_TRANSITION assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == expected_features assert state.attributes.get("rgb_color") is None @@ -291,6 +292,16 @@ async def test_no_color_brightness_color_temp_white_val_if_no_topics(hass, mqtt_ assert state.attributes.get("xy_color") is None assert state.attributes.get("hs_color") is None + async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"OFF"}') + + state = hass.states.get("light.test") + assert state.state == STATE_OFF + + async_fire_mqtt_message(hass, "test_light_rgb", '{"state": null}') + + state = hass.states.get("light.test") + assert state.state == STATE_UNKNOWN + async def test_controlling_state_via_topic(hass, mqtt_mock): """Test the controlling of the state via topic.""" @@ -318,7 +329,7 @@ async def test_controlling_state_via_topic(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN expected_features = ( light.SUPPORT_BRIGHTNESS | light.SUPPORT_COLOR @@ -446,7 +457,7 @@ async def test_controlling_state_via_topic2(hass, mqtt_mock, caplog): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN expected_features = ( light.SUPPORT_BRIGHTNESS | light.SUPPORT_COLOR @@ -960,7 +971,7 @@ async def test_sending_hs_color(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN mqtt_mock.reset_mock() await common.async_turn_on( @@ -1023,7 +1034,7 @@ async def test_sending_rgb_color_no_brightness(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on( hass, "light.test", brightness=50, xy_color=[0.123, 0.123] @@ -1078,7 +1089,7 @@ async def test_sending_rgb_color_no_brightness2(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on( hass, "light.test", brightness=50, xy_color=[0.123, 0.123] @@ -1155,7 +1166,7 @@ async def test_sending_rgb_color_with_brightness(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on( hass, "light.test", brightness=50, xy_color=[0.123, 0.123] @@ -1226,7 +1237,7 @@ async def test_sending_rgb_color_with_scaled_brightness(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on( hass, "light.test", brightness=50, xy_color=[0.123, 0.123] @@ -1296,7 +1307,7 @@ async def test_sending_xy_color(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on( hass, "light.test", brightness=50, xy_color=[0.123, 0.123] @@ -1359,7 +1370,7 @@ async def test_effect(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN expected_features = ( light.SUPPORT_EFFECT | light.SUPPORT_FLASH | light.SUPPORT_TRANSITION ) @@ -1422,7 +1433,7 @@ async def test_flash_short_and_long(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN expected_features = light.SUPPORT_FLASH | light.SUPPORT_TRANSITION assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == expected_features @@ -1481,7 +1492,7 @@ async def test_transition(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN expected_features = light.SUPPORT_FLASH | light.SUPPORT_TRANSITION assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == expected_features await common.async_turn_on(hass, "light.test", transition=15) @@ -1529,7 +1540,7 @@ async def test_brightness_scale(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("brightness") is None assert not state.attributes.get(ATTR_ASSUMED_STATE) @@ -1573,7 +1584,7 @@ async def test_invalid_values(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN expected_features = ( light.SUPPORT_BRIGHTNESS | light.SUPPORT_COLOR diff --git a/tests/components/mqtt/test_light_template.py b/tests/components/mqtt/test_light_template.py index 3a8ecd357c3..45977343b95 100644 --- a/tests/components/mqtt/test_light_template.py +++ b/tests/components/mqtt/test_light_template.py @@ -40,6 +40,7 @@ from homeassistant.const import ( ATTR_SUPPORTED_FEATURES, STATE_OFF, STATE_ON, + STATE_UNKNOWN, ) import homeassistant.core as ha from homeassistant.setup import async_setup_component @@ -171,6 +172,7 @@ async def test_rgb_light(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") + assert state.state == STATE_UNKNOWN expected_features = ( light.SUPPORT_TRANSITION | light.SUPPORT_COLOR @@ -208,7 +210,7 @@ async def test_state_change_via_topic(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("rgb_color") is None assert state.attributes.get("brightness") is None assert state.attributes.get("color_temp") is None @@ -224,6 +226,16 @@ async def test_state_change_via_topic(hass, mqtt_mock): assert state.attributes.get("color_temp") is None assert state.attributes.get("white_value") is None + async_fire_mqtt_message(hass, "test_light_rgb", "off") + + state = hass.states.get("light.test") + assert state.state == STATE_OFF + + async_fire_mqtt_message(hass, "test_light_rgb", "None") + + state = hass.states.get("light.test") + assert state.state == STATE_UNKNOWN + async def test_state_brightness_color_effect_temp_white_change_via_topic( hass, mqtt_mock @@ -264,7 +276,7 @@ async def test_state_brightness_color_effect_temp_white_change_via_topic( await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("rgb_color") is None assert state.attributes.get("brightness") is None assert state.attributes.get("effect") is None @@ -283,6 +295,12 @@ async def test_state_brightness_color_effect_temp_white_change_via_topic( assert state.attributes.get("white_value") == 123 assert state.attributes.get("effect") is None + # make the light state unknown + async_fire_mqtt_message(hass, "test_light_rgb", "None") + + state = hass.states.get("light.test") + assert state.state == STATE_UNKNOWN + # turn the light off async_fire_mqtt_message(hass, "test_light_rgb", "off") @@ -514,7 +532,7 @@ async def test_sending_mqtt_commands_non_optimistic_brightness_template( await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert not state.attributes.get("brightness") assert not state.attributes.get("hs_color") assert not state.attributes.get("effect") @@ -528,7 +546,7 @@ async def test_sending_mqtt_commands_non_optimistic_brightness_template( ) mqtt_mock.async_publish.reset_mock() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN await common.async_turn_on(hass, "light.test") mqtt_mock.async_publish.assert_called_once_with( @@ -536,7 +554,7 @@ async def test_sending_mqtt_commands_non_optimistic_brightness_template( ) mqtt_mock.async_publish.reset_mock() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN # Set color_temp await common.async_turn_on(hass, "light.test", color_temp=70) @@ -545,7 +563,7 @@ async def test_sending_mqtt_commands_non_optimistic_brightness_template( ) mqtt_mock.async_publish.reset_mock() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert not state.attributes.get("color_temp") # Set full brightness @@ -555,7 +573,7 @@ async def test_sending_mqtt_commands_non_optimistic_brightness_template( ) mqtt_mock.async_publish.reset_mock() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert not state.attributes.get("brightness") # Full brightness - no scaling of RGB values sent over MQTT @@ -567,7 +585,7 @@ async def test_sending_mqtt_commands_non_optimistic_brightness_template( ) mqtt_mock.async_publish.reset_mock() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert not state.attributes.get("white_value") assert not state.attributes.get("rgb_color") @@ -628,7 +646,7 @@ async def test_effect(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 44 await common.async_turn_on(hass, "light.test") @@ -679,7 +697,7 @@ async def test_flash(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 40 await common.async_turn_on(hass, "light.test") @@ -727,7 +745,7 @@ async def test_transition(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 40 @@ -783,7 +801,7 @@ async def test_invalid_values(hass, mqtt_mock): await hass.async_block_till_done() state = hass.states.get("light.test") - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get("rgb_color") is None assert state.attributes.get("brightness") is None assert state.attributes.get("color_temp") is None