Skip to content

Commit

Permalink
Do not allow mqtt lights to set brightness to zero (home-assistant#91296
Browse files Browse the repository at this point in the history
)

* Do not allow mqtt lights to set brightness to zero

* Loglevel to debug

* Typo
  • Loading branch information
jbouwh authored Apr 14, 2023
1 parent 025e179 commit fc8c5f1
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 8 deletions.
4 changes: 4 additions & 0 deletions homeassistant/components/mqtt/light/schema_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,10 @@ def brightness_received(msg: ReceiveMessage) -> None:
return

device_value = float(payload)
if device_value == 0:
_LOGGER.debug("Ignoring zero brightness from '%s'", msg.topic)
return

percent_bright = device_value / self._config[CONF_BRIGHTNESS_SCALE]
self._attr_brightness = min(round(percent_bright * 255), 255)

Expand Down
17 changes: 12 additions & 5 deletions homeassistant/components/mqtt/light/schema_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,11 +378,18 @@ def state_received(msg: ReceiveMessage) -> None:

if brightness_supported(self.supported_color_modes):
try:
self._attr_brightness = int(
values["brightness"] # type: ignore[operator]
/ float(self._config[CONF_BRIGHTNESS_SCALE])
* 255
)
if brightness := values["brightness"]:
self._attr_brightness = int(
brightness # type: ignore[operator]
/ float(self._config[CONF_BRIGHTNESS_SCALE])
* 255
)
else:
_LOGGER.debug(
"Ignoring zero brightness value for entity %s",
self.entity_id,
)

except KeyError:
pass
except (TypeError, ValueError):
Expand Down
15 changes: 12 additions & 3 deletions homeassistant/components/mqtt/light/schema_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,20 @@ def state_received(msg: ReceiveMessage) -> None:

if CONF_BRIGHTNESS_TEMPLATE in self._config:
try:
self._attr_brightness = int(
if brightness := int(
self._value_templates[CONF_BRIGHTNESS_TEMPLATE](msg.payload)
)
):
self._attr_brightness = brightness
else:
_LOGGER.debug(
"Ignoring zero brightness value for entity %s",
self.entity_id,
)

except ValueError:
_LOGGER.warning("Invalid brightness value received")
_LOGGER.warning(
"Invalid brightness value received from %s", msg.topic
)

if CONF_COLOR_TEMP_TEMPLATE in self._config:
try:
Expand Down
13 changes: 13 additions & 0 deletions tests/components/mqtt/test_light.py
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,19 @@ async def test_controlling_state_via_topic_with_templates(
assert state.attributes.get(light.ATTR_COLOR_MODE) == "xy"
assert state.attributes.get(light.ATTR_SUPPORTED_COLOR_MODES) == color_modes

async_fire_mqtt_message(hass, "test_light_rgb/brightness/status", '{"hello": 100}')
state = hass.states.get("light.test")
assert state.attributes.get("brightness") == 100

async_fire_mqtt_message(hass, "test_light_rgb/brightness/status", '{"hello": 50}')
state = hass.states.get("light.test")
assert state.attributes.get("brightness") == 50

# test zero brightness received is ignored
async_fire_mqtt_message(hass, "test_light_rgb/brightness/status", '{"hello": 0}')
state = hass.states.get("light.test")
assert state.attributes.get("brightness") == 50


@pytest.mark.parametrize(
"hass_config",
Expand Down
31 changes: 31 additions & 0 deletions tests/components/mqtt/test_light_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,37 @@ async def test_controlling_state_via_topic(
light_state = hass.states.get("light.test")
assert light_state.attributes.get("effect") == "colorloop"

async_fire_mqtt_message(
hass,
"test_light_rgb",
'{"state":"ON",'
'"color":{"r":255,"g":255,"b":255},'
'"brightness":128,'
'"color_temp":155,'
'"effect":"colorloop"}',
)
light_state = hass.states.get("light.test")
assert light_state.state == STATE_ON
assert light_state.attributes.get("brightness") == 128

async_fire_mqtt_message(
hass,
"test_light_rgb",
'{"state":"OFF","brightness":0}',
)
light_state = hass.states.get("light.test")
assert light_state.state == STATE_OFF
assert light_state.attributes.get("brightness") is None

# test previous zero brightness received was ignored and brightness is restored
async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"ON"}')
light_state = hass.states.get("light.test")
assert light_state.attributes.get("brightness") == 128

async_fire_mqtt_message(hass, "test_light_rgb", '{"state":"ON","brightness":0}')
light_state = hass.states.get("light.test")
assert light_state.attributes.get("brightness") == 128


@pytest.mark.parametrize(
"hass_config",
Expand Down
6 changes: 6 additions & 0 deletions tests/components/mqtt/test_light_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,12 @@ async def test_state_brightness_color_effect_temp_change_via_topic(
light_state = hass.states.get("light.test")
assert light_state.attributes["brightness"] == 100

# ignore a zero brightness
async_fire_mqtt_message(hass, "test_light_rgb", "on,0")

light_state = hass.states.get("light.test")
assert light_state.attributes["brightness"] == 100

# change the color temp
async_fire_mqtt_message(hass, "test_light_rgb", "on,,195")

Expand Down

0 comments on commit fc8c5f1

Please sign in to comment.