From 965f31a9e0ccba597c0000158ed447f6b00c7fac Mon Sep 17 00:00:00 2001 From: TheJulianJES Date: Tue, 6 Feb 2024 01:12:56 +0100 Subject: [PATCH] Fix ZHA creating unnecessary "summ received" entity after upgrade (#109268) * Do not create `current_summ_received` entity until initialized once * Update zha_devices_list.py to not expect summation received entities The attribute isn't initialized for these devices in the test (which our check now expects it to be), hence we need to remove them from this list. * Update sensor tests to have initial state for current_summ_received entity The attribute needs to be initialized for it to be created which we do by plugging the attribute read. The test expects the initial state to be "unknown", but hence we plugged the attribute (to create the entity), the state is whatever we plug the attribute read as. * Update sensor tests to expect not updating current_summ_received entity if it doesn't exist --- homeassistant/components/zha/sensor.py | 20 +++++++++ tests/components/zha/test_sensor.py | 29 ++++++++++--- tests/components/zha/zha_devices_list.py | 52 ------------------------ 3 files changed, 43 insertions(+), 58 deletions(-) diff --git a/homeassistant/components/zha/sensor.py b/homeassistant/components/zha/sensor.py index 15985922ccd..929ac803b10 100644 --- a/homeassistant/components/zha/sensor.py +++ b/homeassistant/components/zha/sensor.py @@ -838,6 +838,26 @@ class SmartEnergySummationReceived(PolledSmartEnergySummation): _unique_id_suffix = "summation_received" _attr_translation_key: str = "summation_received" + @classmethod + def create_entity( + cls, + unique_id: str, + zha_device: ZHADevice, + cluster_handlers: list[ClusterHandler], + **kwargs: Any, + ) -> Self | None: + """Entity Factory. + + This attribute only started to be initialized in HA 2024.2.0, + so the entity would still be created on the first HA start after the upgrade for existing devices, + as the initialization to see if an attribute is unsupported happens later in the background. + To avoid creating a lot of unnecessary entities for existing devices, + wait until the attribute was properly initialized once for now. + """ + if cluster_handlers[0].cluster.get(cls._attribute_name) is None: + return None + return super().create_entity(unique_id, zha_device, cluster_handlers, **kwargs) + @MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_PRESSURE) # pylint: disable-next=hass-invalid-inheritance # needs fixing diff --git a/tests/components/zha/test_sensor.py b/tests/components/zha/test_sensor.py index 005e9b86e3a..4b71fd723ad 100644 --- a/tests/components/zha/test_sensor.py +++ b/tests/components/zha/test_sensor.py @@ -368,6 +368,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): "report_count", "read_plug", "unsupported_attrs", + "initial_sensor_state", ), ( ( @@ -377,6 +378,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 1, None, None, + STATE_UNKNOWN, ), ( measurement.TemperatureMeasurement.cluster_id, @@ -385,6 +387,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 1, None, None, + STATE_UNKNOWN, ), ( measurement.PressureMeasurement.cluster_id, @@ -393,6 +396,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 1, None, None, + STATE_UNKNOWN, ), ( measurement.IlluminanceMeasurement.cluster_id, @@ -401,6 +405,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 1, None, None, + STATE_UNKNOWN, ), ( smartenergy.Metering.cluster_id, @@ -415,6 +420,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): "status": 0x00, }, {"current_summ_delivered", "current_summ_received"}, + STATE_UNKNOWN, ), ( smartenergy.Metering.cluster_id, @@ -431,6 +437,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): "unit_of_measure": 0x00, }, {"instaneneous_demand", "current_summ_received"}, + STATE_UNKNOWN, ), ( smartenergy.Metering.cluster_id, @@ -445,8 +452,10 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): "status": 0x00, "summation_formatting": 0b1_0111_010, "unit_of_measure": 0x00, + "current_summ_received": 0, }, {"instaneneous_demand", "current_summ_delivered"}, + "0.0", ), ( homeautomation.ElectricalMeasurement.cluster_id, @@ -455,6 +464,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 7, {"ac_power_divisor": 1000, "ac_power_multiplier": 1}, {"apparent_power", "rms_current", "rms_voltage"}, + STATE_UNKNOWN, ), ( homeautomation.ElectricalMeasurement.cluster_id, @@ -463,6 +473,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 7, {"ac_power_divisor": 1000, "ac_power_multiplier": 1}, {"active_power", "rms_current", "rms_voltage"}, + STATE_UNKNOWN, ), ( homeautomation.ElectricalMeasurement.cluster_id, @@ -471,6 +482,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 7, {"ac_power_divisor": 1000, "ac_power_multiplier": 1}, {"active_power", "apparent_power", "rms_current", "rms_voltage"}, + STATE_UNKNOWN, ), ( homeautomation.ElectricalMeasurement.cluster_id, @@ -479,6 +491,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 7, {"ac_current_divisor": 1000, "ac_current_multiplier": 1}, {"active_power", "apparent_power", "rms_voltage"}, + STATE_UNKNOWN, ), ( homeautomation.ElectricalMeasurement.cluster_id, @@ -487,6 +500,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 7, {"ac_voltage_divisor": 10, "ac_voltage_multiplier": 1}, {"active_power", "apparent_power", "rms_current"}, + STATE_UNKNOWN, ), ( general.PowerConfiguration.cluster_id, @@ -499,6 +513,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): "battery_quantity": 3, }, None, + STATE_UNKNOWN, ), ( general.PowerConfiguration.cluster_id, @@ -511,6 +526,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): "battery_quantity": 3, }, None, + STATE_UNKNOWN, ), ( general.DeviceTemperature.cluster_id, @@ -519,6 +535,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 1, None, None, + STATE_UNKNOWN, ), ( hvac.Thermostat.cluster_id, @@ -527,6 +544,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 10, None, None, + STATE_UNKNOWN, ), ( hvac.Thermostat.cluster_id, @@ -535,6 +553,7 @@ async def async_test_pi_heating_demand(hass, cluster, entity_id): 10, None, None, + STATE_UNKNOWN, ), ), ) @@ -548,6 +567,7 @@ async def test_sensor( report_count, read_plug, unsupported_attrs, + initial_sensor_state, ) -> None: """Test ZHA sensor platform.""" @@ -582,8 +602,8 @@ async def test_sensor( # allow traffic to flow through the gateway and devices await async_enable_traffic(hass, [zha_device]) - # test that the sensor now have a state of unknown - assert hass.states.get(entity_id).state == STATE_UNKNOWN + # test that the sensor now have their correct initial state (mostly unknown) + assert hass.states.get(entity_id).state == initial_sensor_state # test sensor associated logic await test_func(hass, cluster, entity_id) @@ -826,7 +846,6 @@ async def test_electrical_measurement_init( }, { "summation_delivered", - "summation_received", }, { "instantaneous_demand", @@ -834,12 +853,11 @@ async def test_electrical_measurement_init( ), ( smartenergy.Metering.cluster_id, - {"instantaneous_demand", "current_summ_delivered", "current_summ_received"}, + {"instantaneous_demand", "current_summ_delivered"}, {}, { "instantaneous_demand", "summation_delivered", - "summation_received", }, ), ( @@ -848,7 +866,6 @@ async def test_electrical_measurement_init( { "instantaneous_demand", "summation_delivered", - "summation_received", }, {}, ), diff --git a/tests/components/zha/zha_devices_list.py b/tests/components/zha/zha_devices_list.py index 9a9535178d2..4c23244c5e0 100644 --- a/tests/components/zha/zha_devices_list.py +++ b/tests/components/zha/zha_devices_list.py @@ -243,11 +243,6 @@ DEVICES = [ DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", DEV_SIG_ENT_MAP_ID: "sensor.centralite_3210_l_summation_delivered", }, - ("sensor", "00:11:22:33:44:55:66:77-1-1794-summation_received"): { - DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], - DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", - DEV_SIG_ENT_MAP_ID: "sensor.centralite_3210_l_summation_received", - }, ("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): { DEV_SIG_CLUSTER_HANDLERS: ["basic"], DEV_SIG_ENT_MAP_CLASS: "RSSISensor", @@ -616,13 +611,6 @@ DEVICES = [ "sensor.climaxtechnology_psmp5_00_00_02_02tc_summation_delivered" ), }, - ("sensor", "00:11:22:33:44:55:66:77-1-1794-summation_received"): { - DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], - DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", - DEV_SIG_ENT_MAP_ID: ( - "sensor.climaxtechnology_psmp5_00_00_02_02tc_summation_received" - ), - }, ("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): { DEV_SIG_CLUSTER_HANDLERS: ["basic"], DEV_SIG_ENT_MAP_CLASS: "RSSISensor", @@ -1617,11 +1605,6 @@ DEVICES = [ DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", DEV_SIG_ENT_MAP_ID: "sensor.jasco_products_45852_summation_delivered", }, - ("sensor", "00:11:22:33:44:55:66:77-1-1794-summation_received"): { - DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], - DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", - DEV_SIG_ENT_MAP_ID: "sensor.jasco_products_45852_summation_received", - }, ("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): { DEV_SIG_CLUSTER_HANDLERS: ["basic"], DEV_SIG_ENT_MAP_CLASS: "RSSISensor", @@ -1682,11 +1665,6 @@ DEVICES = [ DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", DEV_SIG_ENT_MAP_ID: "sensor.jasco_products_45856_summation_delivered", }, - ("sensor", "00:11:22:33:44:55:66:77-1-1794-summation_received"): { - DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], - DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", - DEV_SIG_ENT_MAP_ID: "sensor.jasco_products_45856_summation_received", - }, ("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): { DEV_SIG_CLUSTER_HANDLERS: ["basic"], DEV_SIG_ENT_MAP_CLASS: "RSSISensor", @@ -1747,11 +1725,6 @@ DEVICES = [ DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", DEV_SIG_ENT_MAP_ID: "sensor.jasco_products_45857_summation_delivered", }, - ("sensor", "00:11:22:33:44:55:66:77-1-1794-summation_received"): { - DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], - DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", - DEV_SIG_ENT_MAP_ID: "sensor.jasco_products_45857_summation_received", - }, ("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): { DEV_SIG_CLUSTER_HANDLERS: ["basic"], DEV_SIG_ENT_MAP_CLASS: "RSSISensor", @@ -2370,11 +2343,6 @@ DEVICES = [ DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_relay_c2acn01_summation_delivered", }, - ("sensor", "00:11:22:33:44:55:66:77-1-1794-summation_received"): { - DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], - DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", - DEV_SIG_ENT_MAP_ID: "sensor.lumi_lumi_relay_c2acn01_summation_received", - }, ("sensor", "00:11:22:33:44:55:66:77-1-1794"): { DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], DEV_SIG_ENT_MAP_CLASS: "SmartEnergyMetering", @@ -4511,11 +4479,6 @@ DEVICES = [ DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", DEV_SIG_ENT_MAP_ID: "sensor.sercomm_corp_sz_esw01_summation_delivered", }, - ("sensor", "00:11:22:33:44:55:66:77-1-1794-summation_received"): { - DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], - DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", - DEV_SIG_ENT_MAP_ID: "sensor.sercomm_corp_sz_esw01_summation_received", - }, ("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): { DEV_SIG_CLUSTER_HANDLERS: ["basic"], DEV_SIG_ENT_MAP_CLASS: "RSSISensor", @@ -5362,11 +5325,6 @@ DEVICES = [ DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", DEV_SIG_ENT_MAP_ID: "sensor.sengled_e11_g13_summation_delivered", }, - ("sensor", "00:11:22:33:44:55:66:77-1-1794-summation_received"): { - DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], - DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", - DEV_SIG_ENT_MAP_ID: "sensor.sengled_e11_g13_summation_received", - }, ("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): { DEV_SIG_CLUSTER_HANDLERS: ["basic"], DEV_SIG_ENT_MAP_CLASS: "RSSISensor", @@ -5420,11 +5378,6 @@ DEVICES = [ DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", DEV_SIG_ENT_MAP_ID: "sensor.sengled_e12_n14_summation_delivered", }, - ("sensor", "00:11:22:33:44:55:66:77-1-1794-summation_received"): { - DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], - DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", - DEV_SIG_ENT_MAP_ID: "sensor.sengled_e12_n14_summation_received", - }, ("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): { DEV_SIG_CLUSTER_HANDLERS: ["basic"], DEV_SIG_ENT_MAP_CLASS: "RSSISensor", @@ -5478,11 +5431,6 @@ DEVICES = [ DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", DEV_SIG_ENT_MAP_ID: "sensor.sengled_z01_a19nae26_summation_delivered", }, - ("sensor", "00:11:22:33:44:55:66:77-1-1794-summation_received"): { - DEV_SIG_CLUSTER_HANDLERS: ["smartenergy_metering"], - DEV_SIG_ENT_MAP_CLASS: "SmartEnergySummation", - DEV_SIG_ENT_MAP_ID: "sensor.sengled_z01_a19nae26_summation_received", - }, ("sensor", "00:11:22:33:44:55:66:77-1-0-rssi"): { DEV_SIG_CLUSTER_HANDLERS: ["basic"], DEV_SIG_ENT_MAP_CLASS: "RSSISensor",