Bump Python Matter Server library to 6.1.0(b0) (#118388)

This commit is contained in:
Marcel van der Veldt 2024-05-29 19:20:18 +02:00 committed by GitHub
parent 23381ff30c
commit 7136be5047
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 18 additions and 97 deletions

View File

@ -69,8 +69,8 @@ SUPPORT_FAN_MODE_DEVICES: set[tuple[int, int]] = {
(0x1209, 0x8007), (0x1209, 0x8007),
} }
SystemModeEnum = clusters.Thermostat.Enums.ThermostatSystemMode SystemModeEnum = clusters.Thermostat.Enums.SystemModeEnum
ControlSequenceEnum = clusters.Thermostat.Enums.ThermostatControlSequence ControlSequenceEnum = clusters.Thermostat.Enums.ControlSequenceOfOperationEnum
ThermostatFeature = clusters.Thermostat.Bitmaps.Feature ThermostatFeature = clusters.Thermostat.Bitmaps.Feature

View File

@ -118,7 +118,6 @@ def async_discover_entities(
attributes_to_watch=attributes_to_watch, attributes_to_watch=attributes_to_watch,
entity_description=schema.entity_description, entity_description=schema.entity_description,
entity_class=schema.entity_class, entity_class=schema.entity_class,
should_poll=schema.should_poll,
) )
# prevent re-discovery of the primary attribute if not allowed # prevent re-discovery of the primary attribute if not allowed

View File

@ -4,9 +4,7 @@ from __future__ import annotations
from abc import abstractmethod from abc import abstractmethod
from collections.abc import Callable from collections.abc import Callable
from contextlib import suppress
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime
import logging import logging
from typing import TYPE_CHECKING, Any, cast 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.helpers.util import create_attribute_path
from matter_server.common.models import EventType, ServerInfoMessage 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.device_registry import DeviceInfo
from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity import Entity, EntityDescription
from homeassistant.helpers.event import async_call_later
from .const import DOMAIN, ID_TYPE_DEVICE_ID from .const import DOMAIN, ID_TYPE_DEVICE_ID
from .helpers import get_device_id from .helpers import get_device_id
@ -30,13 +27,6 @@ if TYPE_CHECKING:
LOGGER = logging.getLogger(__name__) 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) @dataclass(frozen=True)
class MatterEntityDescription(EntityDescription): class MatterEntityDescription(EntityDescription):
@ -80,8 +70,6 @@ class MatterEntity(Entity):
identifiers={(DOMAIN, f"{ID_TYPE_DEVICE_ID}_{node_device_id}")} identifiers={(DOMAIN, f"{ID_TYPE_DEVICE_ID}_{node_device_id}")}
) )
self._attr_available = self._endpoint.node.available 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 # make sure to update the attributes once
self._update_from_device() 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 @callback
def _on_matter_event(self, event: EventType, data: Any = None) -> None: def _on_matter_event(self, event: EventType, data: Any = None) -> None:
"""Call on update from the device.""" """Call on update from the device."""
self._attr_available = self._endpoint.node.available 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._update_from_device()
self.async_write_ha_state() self.async_write_ha_state()
@ -176,9 +134,3 @@ class MatterEntity(Entity):
return create_attribute_path( return create_attribute_path(
self._endpoint.endpoint_id, attribute.cluster_id, attribute.attribute_id 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)

View File

@ -6,6 +6,6 @@
"dependencies": ["websocket_api"], "dependencies": ["websocket_api"],
"documentation": "https://www.home-assistant.io/integrations/matter", "documentation": "https://www.home-assistant.io/integrations/matter",
"iot_class": "local_push", "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."] "zeroconf": ["_matter._tcp.local.", "_matterc._udp.local."]
} }

View File

@ -51,9 +51,6 @@ class MatterEntityInfo:
# entity class to use to instantiate the entity # entity class to use to instantiate the entity
entity_class: type entity_class: type
# [optional] bool to specify if this primary value should be polled
should_poll: bool
@property @property
def primary_attribute(self) -> type[ClusterAttributeDescriptor]: def primary_attribute(self) -> type[ClusterAttributeDescriptor]:
"""Return Primary Attribute belonging to the entity.""" """Return Primary Attribute belonging to the entity."""

View File

@ -6,7 +6,7 @@ from dataclasses import dataclass
from chip.clusters import Objects as clusters from chip.clusters import Objects as clusters
from chip.clusters.Types import Nullable, NullValue 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 ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
@ -159,11 +159,10 @@ DISCOVERY_SCHEMAS = [
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
), ),
entity_class=MatterSensor, entity_class=MatterSensor,
required_attributes=(EveEnergyCluster.Attributes.Watt,), required_attributes=(EveCluster.Attributes.Watt,),
# Add OnOff Attribute as optional attribute to poll # Add OnOff Attribute as optional attribute to poll
# the primary value when the relay is toggled # the primary value when the relay is toggled
optional_attributes=(clusters.OnOff.Attributes.OnOff,), optional_attributes=(clusters.OnOff.Attributes.OnOff,),
should_poll=True,
), ),
MatterDiscoverySchema( MatterDiscoverySchema(
platform=Platform.SENSOR, platform=Platform.SENSOR,
@ -176,8 +175,7 @@ DISCOVERY_SCHEMAS = [
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
), ),
entity_class=MatterSensor, entity_class=MatterSensor,
required_attributes=(EveEnergyCluster.Attributes.Voltage,), required_attributes=(EveCluster.Attributes.Voltage,),
should_poll=True,
), ),
MatterDiscoverySchema( MatterDiscoverySchema(
platform=Platform.SENSOR, platform=Platform.SENSOR,
@ -190,8 +188,7 @@ DISCOVERY_SCHEMAS = [
state_class=SensorStateClass.TOTAL_INCREASING, state_class=SensorStateClass.TOTAL_INCREASING,
), ),
entity_class=MatterSensor, entity_class=MatterSensor,
required_attributes=(EveEnergyCluster.Attributes.WattAccumulated,), required_attributes=(EveCluster.Attributes.WattAccumulated,),
should_poll=True,
), ),
MatterDiscoverySchema( MatterDiscoverySchema(
platform=Platform.SENSOR, platform=Platform.SENSOR,
@ -204,11 +201,10 @@ DISCOVERY_SCHEMAS = [
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
), ),
entity_class=MatterSensor, entity_class=MatterSensor,
required_attributes=(EveEnergyCluster.Attributes.Current,), required_attributes=(EveCluster.Attributes.Current,),
# Add OnOff Attribute as optional attribute to poll # Add OnOff Attribute as optional attribute to poll
# the primary value when the relay is toggled # the primary value when the relay is toggled
optional_attributes=(clusters.OnOff.Attributes.OnOff,), optional_attributes=(clusters.OnOff.Attributes.OnOff,),
should_poll=True,
), ),
MatterDiscoverySchema( MatterDiscoverySchema(
platform=Platform.SENSOR, platform=Platform.SENSOR,

View File

@ -2272,7 +2272,7 @@ python-kasa[speedups]==0.6.2.1
# python-lirc==1.2.3 # python-lirc==1.2.3
# homeassistant.components.matter # homeassistant.components.matter
python-matter-server==5.10.0 python-matter-server==6.1.0b1
# homeassistant.components.xiaomi_miio # homeassistant.components.xiaomi_miio
python-miio==0.5.12 python-miio==0.5.12

View File

@ -1766,7 +1766,7 @@ python-juicenet==1.1.0
python-kasa[speedups]==0.6.2.1 python-kasa[speedups]==0.6.2.1
# homeassistant.components.matter # homeassistant.components.matter
python-matter-server==5.10.0 python-matter-server==6.1.0b1
# homeassistant.components.xiaomi_miio # homeassistant.components.xiaomi_miio
python-miio==0.5.12 python-miio==0.5.12

View File

@ -354,11 +354,11 @@
], ],
"1/29/0": [ "1/29/0": [
{ {
"type": 257, "0": 256,
"revision": 1 "1": 1
} }
], ],
"1/29/1": [3, 4, 6, 8, 29, 768, 1030], "1/29/1": [3, 4, 6, 29],
"1/29/2": [], "1/29/2": [],
"1/29/3": [], "1/29/3": [],
"1/29/65532": 0, "1/29/65532": 0,

View File

@ -354,11 +354,11 @@
], ],
"1/29/0": [ "1/29/0": [
{ {
"type": 257, "0": 256,
"revision": 1 "1": 1
} }
], ],
"1/29/1": [3, 4, 6, 8, 29, 768, 1030], "1/29/1": [3, 4, 6, 29],
"1/29/2": [], "1/29/2": [],
"1/29/3": [], "1/29/3": [],
"1/29/65532": 0, "1/29/65532": 0,

View File

@ -1,7 +1,6 @@
"""Test Matter sensors.""" """Test Matter sensors."""
from datetime import UTC, datetime, timedelta from unittest.mock import MagicMock
from unittest.mock import MagicMock, patch
from matter_server.client.models.node import MatterNode from matter_server.client.models.node import MatterNode
import pytest import pytest
@ -16,8 +15,6 @@ from .common import (
trigger_subscription_callback, trigger_subscription_callback,
) )
from tests.common import async_fire_time_changed
@pytest.fixture(name="flow_sensor_node") @pytest.fixture(name="flow_sensor_node")
async def flow_sensor_node_fixture( 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["device_class"] == "current"
assert state.attributes["friendly_name"] == "Eve Energy Plug 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 # This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True]) @pytest.mark.parametrize("expected_lingering_tasks", [True])