From c830734535a2951d33548d0f0afb121950db6400 Mon Sep 17 00:00:00 2001 From: Matthias Alphart Date: Sun, 23 Aug 2026 22:33:00 +0200 Subject: [PATCH] Don't restore non-KNX attributes for KNX sensors (#179932) Co-authored-by: Claude Opus 5 --- homeassistant/components/knx/sensor.py | 4 +- tests/components/knx/test_sensor.py | 64 +++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/knx/sensor.py b/homeassistant/components/knx/sensor.py index fe34dc2976fc..ba7f8b3fd9d2 100644 --- a/homeassistant/components/knx/sensor.py +++ b/homeassistant/components/knx/sensor.py @@ -181,7 +181,9 @@ class _KnxSensor(RestoreSensor, _KnxEntityBase): ) ): self._attr_native_value = last_sensor_data.native_value - self._attr_extra_state_attributes.update(last_state.attributes) + # only restore KNX specific attributes - others may have changed + if (source := last_state.attributes.get(ATTR_SOURCE)) is not None: + self._attr_extra_state_attributes[ATTR_SOURCE] = source await super().async_added_to_hass() @override diff --git a/tests/components/knx/test_sensor.py b/tests/components/knx/test_sensor.py index 3557ae8f8167..7a18bce7a19b 100644 --- a/tests/components/knx/test_sensor.py +++ b/tests/components/knx/test_sensor.py @@ -12,8 +12,19 @@ from homeassistant.components.knx.const import ( CONF_SYNC_STATE, ) from homeassistant.components.knx.schema import SensorSchema -from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass -from homeassistant.const import CONF_NAME, CONF_TYPE, STATE_UNKNOWN, Platform +from homeassistant.components.sensor import ( + ATTR_STATE_CLASS, + SensorDeviceClass, + SensorStateClass, +) +from homeassistant.const import ( + ATTR_DEVICE_CLASS, + ATTR_UNIT_OF_MEASUREMENT, + CONF_NAME, + CONF_TYPE, + STATE_UNKNOWN, + Platform, +) from homeassistant.core import HomeAssistant, State from . import KnxEntityGenerator @@ -99,6 +110,55 @@ async def test_sensor_restore(hass: HomeAssistant, knx: KNXTestKit) -> None: assert not events +async def test_sensor_restore_ignores_stale_attributes( + hass: HomeAssistant, knx: KNXTestKit +) -> None: + """Test that restoring doesn't reapply attributes the entity doesn't provide.""" + fake_state = State( + "sensor.test", + "ignored in favour of native_value", + { + ATTR_SOURCE: knx.INDIVIDUAL_ADDRESS, + ATTR_DEVICE_CLASS: SensorDeviceClass.POWER, + ATTR_STATE_CLASS: SensorStateClass.TOTAL_INCREASING, + ATTR_UNIT_OF_MEASUREMENT: "W", + }, + ) + extra_data = {"native_value": "42", "native_unit_of_measurement": None} + mock_restore_cache_with_extra_data(hass, [(fake_state, extra_data)]) + + await knx.setup_integration( + { + SensorSchema.PLATFORM: [ + { + CONF_NAME: "test", + CONF_STATE_ADDRESS: "2/2/2", + CONF_TYPE: "2byte_unsigned", # no unit or device class + CONF_SYNC_STATE: False, + }, + ] + } + ) + + knx.assert_state( + "sensor.test", + "42", + **{ATTR_SOURCE: knx.INDIVIDUAL_ADDRESS}, + device_class=None, + state_class=SensorStateClass.MEASUREMENT, + unit_of_measurement=None, + ) + # a new telegram doesn't reintroduce the stale attributes either + await knx.receive_write("2/2/2", (0x00, 0x07)) + knx.assert_state( + "sensor.test", + "7", + device_class=None, + state_class=SensorStateClass.MEASUREMENT, + unit_of_measurement=None, + ) + + async def test_last_reported( hass: HomeAssistant, knx: KNXTestKit,