From db0c5bbbea733ba2514e00598a5bb8bb60f86233 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Sun, 8 Oct 2023 20:57:14 +0200 Subject: [PATCH] Fix mqtt sensor or binary_sensor state not saved after expiry (#101670) Fix mqtt sensor state not saved after expire --- homeassistant/components/mqtt/binary_sensor.py | 2 +- homeassistant/components/mqtt/sensor.py | 4 +++- tests/components/mqtt/test_binary_sensor.py | 13 ++++++++++++- tests/components/mqtt/test_sensor.py | 13 ++++++++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/mqtt/binary_sensor.py b/homeassistant/components/mqtt/binary_sensor.py index c0f4cc7786e..7eb444b046a 100644 --- a/homeassistant/components/mqtt/binary_sensor.py +++ b/homeassistant/components/mqtt/binary_sensor.py @@ -180,7 +180,7 @@ class MqttBinarySensor(MqttEntity, BinarySensorEntity, RestoreEntity): @callback @log_messages(self.hass, self.entity_id) - @write_state_on_attr_change(self, {"_attr_is_on"}) + @write_state_on_attr_change(self, {"_attr_is_on", "_expired"}) def state_message_received(msg: ReceiveMessage) -> None: """Handle a new received MQTT state message.""" # auto-expire enabled? diff --git a/homeassistant/components/mqtt/sensor.py b/homeassistant/components/mqtt/sensor.py index 05db22a8e62..0f73b93f1de 100644 --- a/homeassistant/components/mqtt/sensor.py +++ b/homeassistant/components/mqtt/sensor.py @@ -277,7 +277,9 @@ class MqttSensor(MqttEntity, RestoreSensor): ) @callback - @write_state_on_attr_change(self, {"_attr_native_value", "_attr_last_reset"}) + @write_state_on_attr_change( + self, {"_attr_native_value", "_attr_last_reset", "_expired"} + ) @log_messages(self.hass, self.entity_id) def message_received(msg: ReceiveMessage) -> None: """Handle new MQTT messages.""" diff --git a/tests/components/mqtt/test_binary_sensor.py b/tests/components/mqtt/test_binary_sensor.py index ea9c8072290..e7a4c9ab1aa 100644 --- a/tests/components/mqtt/test_binary_sensor.py +++ b/tests/components/mqtt/test_binary_sensor.py @@ -123,7 +123,6 @@ async def test_setting_sensor_value_expires_availability_topic( "name": "test", "state_topic": "test-topic", "expire_after": 4, - "force_update": True, } } } @@ -200,6 +199,18 @@ async def expires_helper(hass: HomeAssistant) -> None: state = hass.states.get("binary_sensor.test") assert state.state == STATE_UNAVAILABLE + # Send the last message again + # Time jump 0.5s + now += timedelta(seconds=0.5) + freezer.move_to(now) + async_fire_time_changed(hass, now) + async_fire_mqtt_message(hass, "test-topic", "OFF") + await hass.async_block_till_done() + + # Value was updated correctly. + state = hass.states.get("binary_sensor.test") + assert state.state == STATE_OFF + async def test_expiration_on_discovery_and_discovery_update_of_binary_sensor( hass: HomeAssistant, diff --git a/tests/components/mqtt/test_sensor.py b/tests/components/mqtt/test_sensor.py index bc75492a03e..06967b7f8a8 100644 --- a/tests/components/mqtt/test_sensor.py +++ b/tests/components/mqtt/test_sensor.py @@ -339,7 +339,6 @@ async def test_setting_sensor_value_expires_availability_topic( "state_topic": "test-topic", "unit_of_measurement": "fav unit", "expire_after": "4", - "force_update": True, } } } @@ -413,6 +412,18 @@ async def expires_helper(hass: HomeAssistant) -> None: state = hass.states.get("sensor.test") assert state.state == STATE_UNAVAILABLE + # Send the last message again + # Time jump 0.5s + now += timedelta(seconds=0.5) + freezer.move_to(now) + async_fire_time_changed(hass, now) + async_fire_mqtt_message(hass, "test-topic", "101") + await hass.async_block_till_done() + + # Value was updated correctly. + state = hass.states.get("sensor.test") + assert state.state == "101" + @pytest.mark.parametrize( "hass_config",