From edb28be964d9cff29b1a82660873ab20cc499040 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Sun, 24 Sep 2023 12:52:13 +0200 Subject: [PATCH] Avoid redundant calls to async_write_ha_state in mqtt device_tracker (#100767) Avoid redundant calls to async_ha_write_state --- .../components/mqtt/device_tracker.py | 6 +-- tests/components/mqtt/test_device_tracker.py | 37 +++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/mqtt/device_tracker.py b/homeassistant/components/mqtt/device_tracker.py index 67355d9bca5..f99eab4d58f 100644 --- a/homeassistant/components/mqtt/device_tracker.py +++ b/homeassistant/components/mqtt/device_tracker.py @@ -36,9 +36,10 @@ from .mixins import ( MQTT_ENTITY_COMMON_SCHEMA, MqttEntity, async_setup_entry_helper, + write_state_on_attr_change, ) from .models import MqttValueTemplate, ReceiveMessage, ReceivePayloadType -from .util import get_mqtt_data, valid_subscribe_topic +from .util import valid_subscribe_topic CONF_PAYLOAD_HOME = "payload_home" CONF_PAYLOAD_NOT_HOME = "payload_not_home" @@ -135,6 +136,7 @@ class MqttDeviceTracker(MqttEntity, TrackerEntity): @callback @log_messages(self.hass, self.entity_id) + @write_state_on_attr_change(self, {"_location_name"}) def message_received(msg: ReceiveMessage) -> None: """Handle new MQTT messages.""" payload: ReceivePayloadType = self._value_template(msg.payload) @@ -148,8 +150,6 @@ class MqttDeviceTracker(MqttEntity, TrackerEntity): assert isinstance(msg.payload, str) self._location_name = msg.payload - get_mqtt_data(self.hass).state_write_requests.write_state_request(self) - state_topic: str | None = self._config.get(CONF_STATE_TOPIC) if state_topic is None: return diff --git a/tests/components/mqtt/test_device_tracker.py b/tests/components/mqtt/test_device_tracker.py index 8485e5578fe..204b149e479 100644 --- a/tests/components/mqtt/test_device_tracker.py +++ b/tests/components/mqtt/test_device_tracker.py @@ -13,8 +13,10 @@ from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.setup import async_setup_component from .test_common import ( + help_custom_config, help_test_reloadable, help_test_setting_blocked_attribute_via_mqtt_json_message, + help_test_skipped_async_ha_write_state, ) from tests.common import async_fire_mqtt_message @@ -636,3 +638,38 @@ async def test_reloadable( domain = device_tracker.DOMAIN config = DEFAULT_CONFIG await help_test_reloadable(hass, mqtt_client_mock, domain, config) + + +@pytest.mark.parametrize( + "hass_config", + [ + help_custom_config( + device_tracker.DOMAIN, + DEFAULT_CONFIG, + ( + { + "availability_topic": "availability-topic", + "json_attributes_topic": "json-attributes-topic", + }, + ), + ) + ], +) +@pytest.mark.parametrize( + ("topic", "payload1", "payload2"), + [ + ("test-topic", "home", "work"), + ("availability-topic", "online", "offline"), + ("json-attributes-topic", '{"attr1": "val1"}', '{"attr1": "val2"}'), + ], +) +async def test_skipped_async_ha_write_state( + hass: HomeAssistant, + mqtt_mock_entry: MqttMockHAClientGenerator, + topic: str, + payload1: str, + payload2: str, +) -> None: + """Test a write state command is only called when there is change.""" + await mqtt_mock_entry() + await help_test_skipped_async_ha_write_state(hass, topic, payload1, payload2)