diff --git a/homeassistant/components/matter/climate.py b/homeassistant/components/matter/climate.py index 163d2c23dcb..69a961ebf90 100644 --- a/homeassistant/components/matter/climate.py +++ b/homeassistant/components/matter/climate.py @@ -69,8 +69,8 @@ SUPPORT_FAN_MODE_DEVICES: set[tuple[int, int]] = { (0x1209, 0x8007), } -SystemModeEnum = clusters.Thermostat.Enums.ThermostatSystemMode -ControlSequenceEnum = clusters.Thermostat.Enums.ThermostatControlSequence +SystemModeEnum = clusters.Thermostat.Enums.SystemModeEnum +ControlSequenceEnum = clusters.Thermostat.Enums.ControlSequenceOfOperationEnum ThermostatFeature = clusters.Thermostat.Bitmaps.Feature diff --git a/homeassistant/components/matter/discovery.py b/homeassistant/components/matter/discovery.py index bc922ffffef..e898150e5ed 100644 --- a/homeassistant/components/matter/discovery.py +++ b/homeassistant/components/matter/discovery.py @@ -118,7 +118,6 @@ def async_discover_entities( attributes_to_watch=attributes_to_watch, entity_description=schema.entity_description, entity_class=schema.entity_class, - should_poll=schema.should_poll, ) # prevent re-discovery of the primary attribute if not allowed diff --git a/homeassistant/components/matter/entity.py b/homeassistant/components/matter/entity.py index a47147e874a..ded1e1a2d39 100644 --- a/homeassistant/components/matter/entity.py +++ b/homeassistant/components/matter/entity.py @@ -4,9 +4,7 @@ from __future__ import annotations from abc import abstractmethod from collections.abc import Callable -from contextlib import suppress from dataclasses import dataclass -from datetime import datetime import logging from typing import TYPE_CHECKING, Any, cast @@ -14,10 +12,9 @@ from chip.clusters.Objects import ClusterAttributeDescriptor, NullValue from matter_server.common.helpers.util import create_attribute_path from matter_server.common.models import EventType, ServerInfoMessage -from homeassistant.core import CALLBACK_TYPE, callback +from homeassistant.core import callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity, EntityDescription -from homeassistant.helpers.event import async_call_later from .const import DOMAIN, ID_TYPE_DEVICE_ID from .helpers import get_device_id @@ -30,13 +27,6 @@ if TYPE_CHECKING: LOGGER = logging.getLogger(__name__) -# For some manually polled values (e.g. custom clusters) we perform -# an additional poll as soon as a secondary value changes. -# For example update the energy consumption meter when a relay is toggled -# of an energy metering powerplug. The below constant defined the delay after -# which we poll the primary value (debounced). -EXTRA_POLL_DELAY = 3.0 - @dataclass(frozen=True) class MatterEntityDescription(EntityDescription): @@ -80,8 +70,6 @@ class MatterEntity(Entity): identifiers={(DOMAIN, f"{ID_TYPE_DEVICE_ID}_{node_device_id}")} ) self._attr_available = self._endpoint.node.available - self._attr_should_poll = entity_info.should_poll - self._extra_poll_timer_unsub: CALLBACK_TYPE | None = None # make sure to update the attributes once self._update_from_device() @@ -116,40 +104,10 @@ class MatterEntity(Entity): ) ) - async def async_will_remove_from_hass(self) -> None: - """Run when entity will be removed from hass.""" - if self._extra_poll_timer_unsub: - self._extra_poll_timer_unsub() - for unsub in self._unsubscribes: - with suppress(ValueError): - # suppress ValueError to prevent race conditions - unsub() - - async def async_update(self) -> None: - """Call when the entity needs to be updated.""" - if not self._endpoint.node.available: - # skip poll when the node is not (yet) available - return - # manually poll/refresh the primary value - await self.matter_client.refresh_attribute( - self._endpoint.node.node_id, - self.get_matter_attribute_path(self._entity_info.primary_attribute), - ) - self._update_from_device() - @callback def _on_matter_event(self, event: EventType, data: Any = None) -> None: """Call on update from the device.""" self._attr_available = self._endpoint.node.available - if self._attr_should_poll: - # secondary attribute updated of a polled primary value - # enforce poll of the primary value a few seconds later - if self._extra_poll_timer_unsub: - self._extra_poll_timer_unsub() - self._extra_poll_timer_unsub = async_call_later( - self.hass, EXTRA_POLL_DELAY, self._do_extra_poll - ) - return self._update_from_device() self.async_write_ha_state() @@ -176,9 +134,3 @@ class MatterEntity(Entity): return create_attribute_path( self._endpoint.endpoint_id, attribute.cluster_id, attribute.attribute_id ) - - @callback - def _do_extra_poll(self, called_at: datetime) -> None: - """Perform (extra) poll of primary value.""" - # scheduling the regulat update is enough to perform a poll/refresh - self.async_schedule_update_ha_state(True) diff --git a/homeassistant/components/matter/manifest.json b/homeassistant/components/matter/manifest.json index 20988e387fe..d3ad4348950 100644 --- a/homeassistant/components/matter/manifest.json +++ b/homeassistant/components/matter/manifest.json @@ -6,6 +6,6 @@ "dependencies": ["websocket_api"], "documentation": "https://www.home-assistant.io/integrations/matter", "iot_class": "local_push", - "requirements": ["python-matter-server==5.10.0"], + "requirements": ["python-matter-server==6.1.0b1"], "zeroconf": ["_matter._tcp.local.", "_matterc._udp.local."] } diff --git a/homeassistant/components/matter/models.py b/homeassistant/components/matter/models.py index c10219d8a33..c77d6b42dcd 100644 --- a/homeassistant/components/matter/models.py +++ b/homeassistant/components/matter/models.py @@ -51,9 +51,6 @@ class MatterEntityInfo: # entity class to use to instantiate the entity entity_class: type - # [optional] bool to specify if this primary value should be polled - should_poll: bool - @property def primary_attribute(self) -> type[ClusterAttributeDescriptor]: """Return Primary Attribute belonging to the entity.""" diff --git a/homeassistant/components/matter/sensor.py b/homeassistant/components/matter/sensor.py index 6f1bd1d142b..ff5848ef54e 100644 --- a/homeassistant/components/matter/sensor.py +++ b/homeassistant/components/matter/sensor.py @@ -6,7 +6,7 @@ from dataclasses import dataclass from chip.clusters import Objects as clusters from chip.clusters.Types import Nullable, NullValue -from matter_server.client.models.clusters import EveEnergyCluster +from matter_server.common.custom_clusters import EveCluster from homeassistant.components.sensor import ( SensorDeviceClass, @@ -159,11 +159,10 @@ DISCOVERY_SCHEMAS = [ state_class=SensorStateClass.MEASUREMENT, ), entity_class=MatterSensor, - required_attributes=(EveEnergyCluster.Attributes.Watt,), + required_attributes=(EveCluster.Attributes.Watt,), # Add OnOff Attribute as optional attribute to poll # the primary value when the relay is toggled optional_attributes=(clusters.OnOff.Attributes.OnOff,), - should_poll=True, ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -176,8 +175,7 @@ DISCOVERY_SCHEMAS = [ state_class=SensorStateClass.MEASUREMENT, ), entity_class=MatterSensor, - required_attributes=(EveEnergyCluster.Attributes.Voltage,), - should_poll=True, + required_attributes=(EveCluster.Attributes.Voltage,), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -190,8 +188,7 @@ DISCOVERY_SCHEMAS = [ state_class=SensorStateClass.TOTAL_INCREASING, ), entity_class=MatterSensor, - required_attributes=(EveEnergyCluster.Attributes.WattAccumulated,), - should_poll=True, + required_attributes=(EveCluster.Attributes.WattAccumulated,), ), MatterDiscoverySchema( platform=Platform.SENSOR, @@ -204,11 +201,10 @@ DISCOVERY_SCHEMAS = [ state_class=SensorStateClass.MEASUREMENT, ), entity_class=MatterSensor, - required_attributes=(EveEnergyCluster.Attributes.Current,), + required_attributes=(EveCluster.Attributes.Current,), # Add OnOff Attribute as optional attribute to poll # the primary value when the relay is toggled optional_attributes=(clusters.OnOff.Attributes.OnOff,), - should_poll=True, ), MatterDiscoverySchema( platform=Platform.SENSOR, diff --git a/requirements_all.txt b/requirements_all.txt index b9916d9a14d..da62c93dd3c 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -2272,7 +2272,7 @@ python-kasa[speedups]==0.6.2.1 # python-lirc==1.2.3 # homeassistant.components.matter -python-matter-server==5.10.0 +python-matter-server==6.1.0b1 # homeassistant.components.xiaomi_miio python-miio==0.5.12 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index d375d72a0c8..a233d7515a1 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1766,7 +1766,7 @@ python-juicenet==1.1.0 python-kasa[speedups]==0.6.2.1 # homeassistant.components.matter -python-matter-server==5.10.0 +python-matter-server==6.1.0b1 # homeassistant.components.xiaomi_miio python-miio==0.5.12 diff --git a/tests/components/matter/fixtures/nodes/onoff-light-alt-name.json b/tests/components/matter/fixtures/nodes/onoff-light-alt-name.json index 3f6e83ca460..46575640adf 100644 --- a/tests/components/matter/fixtures/nodes/onoff-light-alt-name.json +++ b/tests/components/matter/fixtures/nodes/onoff-light-alt-name.json @@ -354,11 +354,11 @@ ], "1/29/0": [ { - "type": 257, - "revision": 1 + "0": 256, + "1": 1 } ], - "1/29/1": [3, 4, 6, 8, 29, 768, 1030], + "1/29/1": [3, 4, 6, 29], "1/29/2": [], "1/29/3": [], "1/29/65532": 0, diff --git a/tests/components/matter/fixtures/nodes/onoff-light-no-name.json b/tests/components/matter/fixtures/nodes/onoff-light-no-name.json index 18cb68c8926..a6c73564af0 100644 --- a/tests/components/matter/fixtures/nodes/onoff-light-no-name.json +++ b/tests/components/matter/fixtures/nodes/onoff-light-no-name.json @@ -354,11 +354,11 @@ ], "1/29/0": [ { - "type": 257, - "revision": 1 + "0": 256, + "1": 1 } ], - "1/29/1": [3, 4, 6, 8, 29, 768, 1030], + "1/29/1": [3, 4, 6, 29], "1/29/2": [], "1/29/3": [], "1/29/65532": 0, diff --git a/tests/components/matter/test_sensor.py b/tests/components/matter/test_sensor.py index c8af0647d31..4ee6180ad77 100644 --- a/tests/components/matter/test_sensor.py +++ b/tests/components/matter/test_sensor.py @@ -1,7 +1,6 @@ """Test Matter sensors.""" -from datetime import UTC, datetime, timedelta -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock from matter_server.client.models.node import MatterNode import pytest @@ -16,8 +15,6 @@ from .common import ( trigger_subscription_callback, ) -from tests.common import async_fire_time_changed - @pytest.fixture(name="flow_sensor_node") async def flow_sensor_node_fixture( @@ -280,26 +277,6 @@ async def test_eve_energy_sensors( assert state.attributes["device_class"] == "current" assert state.attributes["friendly_name"] == "Eve Energy Plug Current" - # test if the sensor gets polled on interval - eve_energy_plug_node.update_attribute("1/319486977/319422472", 237.0) - async_fire_time_changed(hass, datetime.now(UTC) + timedelta(seconds=31)) - await hass.async_block_till_done() - entity_id = "sensor.eve_energy_plug_voltage" - state = hass.states.get(entity_id) - assert state - assert state.state == "237.0" - - # test extra poll triggered when secondary value (switch state) changes - set_node_attribute(eve_energy_plug_node, 1, 6, 0, True) - eve_energy_plug_node.update_attribute("1/319486977/319422474", 5.0) - with patch("homeassistant.components.matter.entity.EXTRA_POLL_DELAY", 0.0): - await trigger_subscription_callback(hass, matter_client) - await hass.async_block_till_done() - entity_id = "sensor.eve_energy_plug_power" - state = hass.states.get(entity_id) - assert state - assert state.state == "5.0" - # This tests needs to be adjusted to remove lingering tasks @pytest.mark.parametrize("expected_lingering_tasks", [True])