Add MQTT humidifier unknown state support (#65302)

* Add MQTT humidifier unknown state support

* Update homeassistant/components/mqtt/humidifier.py

Co-authored-by: Erik Montnemery <erik@montnemery.com>

* Fix tests for changed default optimistic state

Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
Jan Bouwhuis 2022-02-03 16:49:09 +01:00 committed by GitHub
parent 711bd7169e
commit 2d011821ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 9 deletions

View File

@ -66,6 +66,8 @@ DEFAULT_PAYLOAD_ON = "ON"
DEFAULT_PAYLOAD_OFF = "OFF"
DEFAULT_PAYLOAD_RESET = "None"
PAYLOAD_NONE = "None"
MQTT_HUMIDIFIER_ATTRIBUTES_BLOCKED = frozenset(
{
humidifier.ATTR_HUMIDITY,
@ -187,7 +189,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
def __init__(self, hass, config, config_entry, discovery_data):
"""Initialize the MQTT humidifier."""
self._state = False
self._state = None
self._target_humidity = None
self._mode = None
self._supported_features = 0
@ -283,6 +285,8 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
self._state = True
elif payload == self._payload["STATE_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:
@ -392,7 +396,7 @@ class MqttHumidifier(MqttEntity, HumidifierEntity):
return self._available_modes
@property
def is_on(self):
def is_on(self) -> bool | None:
"""Return true if device is on."""
return self._state

View File

@ -28,6 +28,7 @@ from homeassistant.const import (
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
STATE_UNKNOWN,
)
from homeassistant.setup import async_setup_component
@ -157,7 +158,7 @@ async def test_controlling_state_via_topic(hass, mqtt_mock, caplog):
await hass.async_block_till_done()
state = hass.states.get("humidifier.test")
assert state.state == STATE_OFF
assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE)
async_fire_mqtt_message(hass, "state-topic", "StAtE_On")
@ -220,6 +221,10 @@ async def test_controlling_state_via_topic(hass, mqtt_mock, caplog):
state = hass.states.get("humidifier.test")
assert state.attributes.get(humidifier.ATTR_HUMIDITY) is None
async_fire_mqtt_message(hass, "state-topic", "None")
state = hass.states.get("humidifier.test")
assert state.state == STATE_UNKNOWN
async def test_controlling_state_via_topic_and_json_message(hass, mqtt_mock, caplog):
"""Test the controlling state via topic and JSON message."""
@ -250,7 +255,7 @@ async def test_controlling_state_via_topic_and_json_message(hass, mqtt_mock, cap
await hass.async_block_till_done()
state = hass.states.get("humidifier.test")
assert state.state == STATE_OFF
assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE)
async_fire_mqtt_message(hass, "state-topic", '{"val":"ON"}')
@ -301,6 +306,10 @@ async def test_controlling_state_via_topic_and_json_message(hass, mqtt_mock, cap
assert "Ignoring empty mode from" in caplog.text
caplog.clear()
async_fire_mqtt_message(hass, "state-topic", '{"val": null}')
state = hass.states.get("humidifier.test")
assert state.state == STATE_UNKNOWN
async def test_controlling_state_via_topic_and_json_message_shared_topic(
hass, mqtt_mock, caplog
@ -333,7 +342,7 @@ async def test_controlling_state_via_topic_and_json_message_shared_topic(
await hass.async_block_till_done()
state = hass.states.get("humidifier.test")
assert state.state == STATE_OFF
assert state.state == STATE_UNKNOWN
assert not state.attributes.get(ATTR_ASSUMED_STATE)
async_fire_mqtt_message(
@ -404,7 +413,7 @@ async def test_sending_mqtt_commands_and_optimistic(hass, mqtt_mock, caplog):
await hass.async_block_till_done()
state = hass.states.get("humidifier.test")
assert state.state == STATE_OFF
assert state.state == STATE_UNKNOWN
assert state.attributes.get(ATTR_ASSUMED_STATE)
await async_turn_on(hass, "humidifier.test")
@ -498,7 +507,7 @@ async def test_sending_mqtt_command_templates_(hass, mqtt_mock, caplog):
await hass.async_block_till_done()
state = hass.states.get("humidifier.test")
assert state.state == STATE_OFF
assert state.state == STATE_UNKNOWN
assert state.attributes.get(ATTR_ASSUMED_STATE)
await async_turn_on(hass, "humidifier.test")
@ -593,7 +602,7 @@ async def test_sending_mqtt_commands_and_explicit_optimistic(hass, mqtt_mock, ca
await hass.async_block_till_done()
state = hass.states.get("humidifier.test")
assert state.state == STATE_OFF
assert state.state == STATE_UNKNOWN
assert state.attributes.get(ATTR_ASSUMED_STATE)
await async_turn_on(hass, "humidifier.test")
@ -731,7 +740,7 @@ async def test_attributes(hass, mqtt_mock, caplog):
await hass.async_block_till_done()
state = hass.states.get("humidifier.test")
assert state.state == STATE_OFF
assert state.state == STATE_UNKNOWN
assert state.attributes.get(humidifier.ATTR_AVAILABLE_MODES) == [
"eco",
"baby",