Add Pressure and Altitude discovery schemas for Matter Eve Weather device (#125690)

* Update number.py to add EveWeatherAltitude attribute

* Update sensor.py to add EveCluster Pressure Attribute

* Update strings.json

* Create eve-weather-sensor.json

* Update test_sensor.py

* Update eve-weather-sensor.json

* Update test_sensor.py

Pressure
AttributeId: 319422484 (0x00130a0014) - Value type: float32

* Update test_sensor.py

* Update test_sensor.py

* Update test_sensor.py

* Update manifest.json

Bump to python-matter-server==6.5.0

* Update requirements_all.txt

Bump requirements to python-matter-server 6.5.0

* Update requirements_test_all.txt

Bump requirements to python-matter-server 6.5.0

* Update test_sensor.py

* Update test_sensor.py

* Update sensor.py

* Update sensor.py

* Update test_sensor.py

* Update sensor.py

* Update test_sensor.py

* Update test_sensor.py

* Update test_sensor.py

* fix test fixture

* Update requirements_all.txt

* Update requirements_test_all.txt

* Update manifest.json

* fix tests

* Update test_sensor.py

* add device class

---------

Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
This commit is contained in:
Ludovic BOUÉ 2024-09-24 17:59:58 +02:00 committed by GitHub
parent a66e287903
commit 31a1ad8409
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 455 additions and 22 deletions

View File

@ -5,15 +5,17 @@ from __future__ import annotations
from dataclasses import dataclass
from chip.clusters import Objects as clusters
from matter_server.common import custom_clusters
from matter_server.common.helpers.util import create_attribute_path_from_attribute
from homeassistant.components.number import (
NumberDeviceClass,
NumberEntity,
NumberEntityDescription,
NumberMode,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory, Platform, UnitOfTime
from homeassistant.const import EntityCategory, Platform, UnitOfLength, UnitOfTime
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -137,4 +139,20 @@ DISCOVERY_SCHEMAS = [
entity_class=MatterNumber,
required_attributes=(clusters.LevelControl.Attributes.OnOffTransitionTime,),
),
MatterDiscoverySchema(
platform=Platform.NUMBER,
entity_description=MatterNumberEntityDescription(
key="EveWeatherAltitude",
device_class=NumberDeviceClass.DISTANCE,
entity_category=EntityCategory.CONFIG,
translation_key="altitude",
native_max_value=9000,
native_min_value=0,
native_unit_of_measurement=UnitOfLength.METERS,
native_step=1,
mode=NumberMode.BOX,
),
entity_class=MatterNumber,
required_attributes=(custom_clusters.EveCluster.Attributes.Altitude,),
),
]

View File

@ -242,6 +242,18 @@ DISCOVERY_SCHEMAS = [
entity_class=MatterSensor,
required_attributes=(EveCluster.Attributes.ValvePosition,),
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterSensorEntityDescription(
key="EveWeatherPressure",
device_class=SensorDeviceClass.PRESSURE,
native_unit_of_measurement=UnitOfPressure.HPA,
suggested_display_precision=1,
state_class=SensorStateClass.MEASUREMENT,
),
entity_class=MatterSensor,
required_attributes=(EveCluster.Attributes.Pressure,),
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterSensorEntityDescription(

View File

@ -119,6 +119,9 @@
},
"on_off_transition_time": {
"name": "On/Off transition time"
},
"altitude": {
"name": "Altitude above Sea Level"
}
},
"light": {

View File

@ -0,0 +1,322 @@
{
"node_id": 29,
"date_commissioned": "2024-09-10T13:34:48.252332",
"last_interview": "2024-09-10T13:34:48.252334",
"interview_version": 6,
"available": true,
"is_bridge": false,
"attributes": {
"0/29/0": [
{
"0": 22,
"1": 1
}
],
"0/29/1": [29, 31, 40, 42, 47, 48, 49, 51, 53, 60, 62, 63],
"0/29/2": [41],
"0/29/3": [1, 2],
"0/29/65532": 0,
"0/29/65533": 1,
"0/29/65528": [],
"0/29/65529": [],
"0/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"0/31/0": [
{
"1": 5,
"2": 2,
"3": [112233],
"4": null,
"254": 4
}
],
"0/31/1": [],
"0/31/2": 4,
"0/31/3": 3,
"0/31/4": 4,
"0/31/65532": 0,
"0/31/65533": 1,
"0/31/65528": [],
"0/31/65529": [],
"0/31/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"0/40/0": 1,
"0/40/1": "Eve Systems",
"0/40/2": 4874,
"0/40/3": "Eve Weather",
"0/40/4": 87,
"0/40/5": "",
"0/40/6": "**REDACTED**",
"0/40/7": 1,
"0/40/8": "1.1",
"0/40/9": 7143,
"0/40/10": "3.3.0",
"0/40/15": "**REDACTED**",
"0/40/18": "**REDACTED**",
"0/40/19": {
"0": 3,
"1": 3
},
"0/40/65532": 0,
"0/40/65533": 1,
"0/40/65528": [],
"0/40/65529": [],
"0/40/65531": [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 18, 19, 65528, 65529, 65531, 65532,
65533
],
"0/42/0": [],
"0/42/1": true,
"0/42/2": 1,
"0/42/3": null,
"0/42/65532": 0,
"0/42/65533": 1,
"0/42/65528": [],
"0/42/65529": [0],
"0/42/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"0/47/0": 1,
"0/47/1": 0,
"0/47/2": "Battery",
"0/47/11": 2956,
"0/47/12": 200,
"0/47/14": 0,
"0/47/15": false,
"0/47/16": 2,
"0/47/18": [],
"0/47/19": "",
"0/47/25": 1,
"0/47/65532": 10,
"0/47/65533": 1,
"0/47/65528": [],
"0/47/65529": [],
"0/47/65531": [
0, 1, 2, 11, 12, 14, 15, 16, 18, 19, 25, 65528, 65529, 65531, 65532, 65533
],
"0/48/0": 0,
"0/48/1": {
"0": 60,
"1": 900
},
"0/48/2": 0,
"0/48/3": 0,
"0/48/4": true,
"0/48/65532": 0,
"0/48/65533": 1,
"0/48/65528": [1, 3, 5],
"0/48/65529": [0, 2, 4],
"0/48/65531": [0, 1, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
"0/49/0": 1,
"0/49/1": [],
"0/49/2": 10,
"0/49/3": 20,
"0/49/4": true,
"0/49/5": 0,
"0/49/6": "**REDACTED**",
"0/49/7": null,
"0/49/65532": 2,
"0/49/65533": 1,
"0/49/65528": [1, 5, 7],
"0/49/65529": [0, 3, 4, 6, 8],
"0/49/65531": [0, 1, 2, 3, 4, 5, 6, 7, 65528, 65529, 65531, 65532, 65533],
"0/51/0": [],
"0/51/1": 1,
"0/51/2": 3416207,
"0/51/3": 948,
"0/51/5": [],
"0/51/6": [],
"0/51/7": [],
"0/51/8": false,
"0/51/65532": 0,
"0/51/65533": 1,
"0/51/65528": [],
"0/51/65529": [0],
"0/51/65531": [0, 1, 2, 3, 5, 6, 7, 8, 65528, 65529, 65531, 65532, 65533],
"0/53/0": 25,
"0/53/1": 2,
"0/53/2": "**REDACTED**",
"0/53/3": 4660,
"0/53/4": 12054125955590472924,
"0/53/5": "**REDACTED**",
"0/53/6": 0,
"0/53/7": [],
"0/53/8": [],
"0/53/9": 867525816,
"0/53/10": 68,
"0/53/11": 127,
"0/53/12": 197,
"0/53/13": 17,
"0/53/14": 244,
"0/53/15": 243,
"0/53/16": 0,
"0/53/17": 0,
"0/53/18": 334,
"0/53/19": 6,
"0/53/20": 0,
"0/53/21": 221,
"0/53/22": 1814103,
"0/53/23": 1812208,
"0/53/24": 1895,
"0/53/25": 1812220,
"0/53/26": 1806871,
"0/53/27": 1895,
"0/53/28": 144123,
"0/53/29": 1670020,
"0/53/30": 0,
"0/53/31": 0,
"0/53/32": 0,
"0/53/33": 515245,
"0/53/34": 1061,
"0/53/35": 0,
"0/53/36": 25,
"0/53/37": 0,
"0/53/38": 0,
"0/53/39": 310675,
"0/53/40": 180775,
"0/53/41": 783,
"0/53/42": 171240,
"0/53/43": 0,
"0/53/44": 4,
"0/53/45": 0,
"0/53/46": 0,
"0/53/47": 0,
"0/53/48": 110041,
"0/53/49": 10200,
"0/53/50": 818,
"0/53/51": 11698,
"0/53/52": 0,
"0/53/53": 114,
"0/53/54": 6189,
"0/53/55": 371,
"0/53/59": {
"0": 672,
"1": 8335
},
"0/53/60": "AB//4A==",
"0/53/61": {
"0": true,
"1": false,
"2": true,
"3": true,
"4": true,
"5": true,
"6": false,
"7": true,
"8": true,
"9": true,
"10": true,
"11": true
},
"0/53/62": [0, 0, 0, 0],
"0/53/65532": 15,
"0/53/65533": 1,
"0/53/65528": [],
"0/53/65529": [0],
"0/53/65531": [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 59,
60, 61, 62, 65528, 65529, 65531, 65532, 65533
],
"0/60/0": 0,
"0/60/1": null,
"0/60/2": null,
"0/60/65532": 0,
"0/60/65533": 1,
"0/60/65528": [],
"0/60/65529": [0, 1, 2],
"0/60/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"0/62/0": [],
"0/62/1": [],
"0/62/2": 5,
"0/62/3": 4,
"0/62/4": [],
"0/62/5": 4,
"0/62/65532": 0,
"0/62/65533": 1,
"0/62/65528": [1, 3, 5, 8],
"0/62/65529": [0, 2, 4, 6, 7, 9, 10, 11],
"0/62/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533],
"0/63/0": [],
"0/63/1": [],
"0/63/2": 4,
"0/63/3": 3,
"0/63/65532": 0,
"0/63/65533": 1,
"0/63/65528": [2, 5],
"0/63/65529": [0, 1, 3, 4],
"0/63/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"1/3/0": 0,
"1/3/1": 4,
"1/3/65532": 0,
"1/3/65533": 4,
"1/3/65528": [],
"1/3/65529": [0],
"1/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"1/29/0": [
{
"0": 770,
"1": 2
}
],
"1/29/1": [3, 29, 1026, 319486977],
"1/29/2": [],
"1/29/3": [],
"1/29/65532": 0,
"1/29/65533": 1,
"1/29/65528": [],
"1/29/65529": [],
"1/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"1/1026/0": 1603,
"1/1026/1": -4000,
"1/1026/2": 8500,
"1/1026/65532": 0,
"1/1026/65533": 4,
"1/1026/65528": [],
"1/1026/65529": [],
"1/1026/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
"1/319486977/319422464": "AAFXCwIAAAMC/xsEDFNWNDNMMUEwMzg2MJwBAP8EAQJsNPkBAR0BACUE9griHksEfgeAA1EBAA==",
"1/319486977/319422466": "Ps00AOODMwBqe48sBgECAgIDAicBLwEjAlAPABAABwAA6gERAAEA",
"1/319486977/319422467": "EiMTAACLYy0AH74Fwx88JwQOEiQTAADjZS0AH7wFzB87JwQOEiUTAAA7aC0AH7oF1B86JwQOEiYTAACTai0AH7kF5x86JwQOEicTAADrbC0AH7sF8B85JwQOEigTAABDby0AH7wFAiA4JwQOEikTAACbcS0AH7sFFCA3JwQOEioTAADzcy0AH7EFMiA1JwQOEisTAABLdi0AH6gFVyA0JwQOEiwTAACjeC0AH6gFaiAzJwQOEi0TAAD7ei0AH6YFfCAyJwQOEi4TAABTfS0AH6YFgCAzJwQOEi8TAACrfy0AH6MFhyA0JwQOEjATAAADgi0AH58FnSA1JwQOEjETAABbhC0AH58FtSA1JwQOEjITAACzhi0AH5wFwSA0JwQOEjMTAAALiS0AH5cF1SA0JwQOEjQTAABjiy0AH58F3yA0JwIGEjUTAAC7jS0AH6EF7yA0JwIGEjYTAAATkC0AH60F+yAzJwIGEjcTAABrki0AH68FAiEyJwIGEjgTAADDlC0AH7kFACEyJwIGEjkTAAAbly0AH8QF7SAyJwIGEjoTAABzmS0AH9QF1SAzJwIGEjsTAADLmy0AH98FvyAzJwIG",
"1/319486977/319422482": 13420,
"1/319486977/319422483": 40.0,
"1/319486977/319422484": 1008.5,
"1/319486977/319422485": 6,
"1/319486977/319422486": 0,
"1/319486977/65533": 1,
"1/319486977/65528": [],
"1/319486977/65529": [],
"1/319486977/65531": [
65528, 65529, 65531, 319422464, 319422465, 319422466, 319422467,
319422468, 319422469, 319422482, 319422483, 319422484, 319422485,
319422486, 65533
],
"2/3/0": 0,
"2/3/1": 4,
"2/3/65532": 0,
"2/3/65533": 4,
"2/3/65528": [],
"2/3/65529": [0],
"2/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
"2/29/0": [
{
"0": 775,
"1": 2
}
],
"2/29/1": [3, 29, 1029],
"2/29/2": [],
"2/29/3": [],
"2/29/65532": 0,
"2/29/65533": 1,
"2/29/65528": [],
"2/29/65529": [],
"2/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
"2/1029/0": 8066,
"2/1029/1": 0,
"2/1029/2": 10000,
"2/1029/65532": 0,
"2/1029/65533": 3,
"2/1029/65528": [],
"2/1029/65529": [],
"2/1029/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533]
},
"attribute_subscriptions": []
}

View File

@ -1,8 +1,10 @@
"""Test Matter number entities."""
from unittest.mock import MagicMock
from unittest.mock import MagicMock, call
from matter_server.client.models.node import MatterNode
from matter_server.common import custom_clusters
from matter_server.common.helpers.util import create_attribute_path_from_attribute
import pytest
from homeassistant.core import HomeAssistant
@ -24,6 +26,16 @@ async def dimmable_light_node_fixture(
)
@pytest.fixture(name="eve_weather_sensor_node")
async def eve_weather_sensor_node_fixture(
hass: HomeAssistant, matter_client: MagicMock
) -> MatterNode:
"""Fixture for a Eve Weather sensor node."""
return await setup_integration_with_node_fixture(
hass, "eve-weather-sensor", matter_client
)
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
async def test_level_control_config_entities(
@ -54,3 +66,41 @@ async def test_level_control_config_entities(
state = hass.states.get("number.mock_dimmable_light_on_level")
assert state
assert state.state == "20"
async def test_eve_weather_sensor_altitude(
hass: HomeAssistant,
matter_client: MagicMock,
eve_weather_sensor_node: MatterNode,
) -> None:
"""Test weather sensor created from (Eve) custom cluster."""
# pressure sensor on Eve custom cluster
state = hass.states.get("number.eve_weather_altitude_above_sea_level")
assert state
assert state.state == "40.0"
set_node_attribute(eve_weather_sensor_node, 1, 319486977, 319422483, 800)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get("number.eve_weather_altitude_above_sea_level")
assert state
assert state.state == "800.0"
# test set value
await hass.services.async_call(
"number",
"set_value",
{
"entity_id": "number.eve_weather_altitude_above_sea_level",
"value": 500,
},
blocking=True,
)
assert matter_client.write_attribute.call_count == 1
assert matter_client.write_attribute.call_args_list[0] == call(
node_id=eve_weather_sensor_node.node_id,
attribute_path=create_attribute_path_from_attribute(
endpoint_id=1,
attribute=custom_clusters.EveCluster.Attributes.Altitude,
),
value=500,
)

View File

@ -92,6 +92,16 @@ async def eve_energy_plug_patched_node_fixture(
)
@pytest.fixture(name="eve_weather_sensor_node")
async def eve_weather_sensor_node_fixture(
hass: HomeAssistant, matter_client: MagicMock
) -> MatterNode:
"""Fixture for a Eve Weather sensor node."""
return await setup_integration_with_node_fixture(
hass, "eve-weather-sensor", matter_client
)
@pytest.fixture(name="air_quality_sensor_node")
async def air_quality_sensor_node_fixture(
hass: HomeAssistant, matter_client: MagicMock
@ -192,26 +202,6 @@ async def test_light_sensor(
assert state.state == "2.0"
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
async def test_pressure_sensor(
hass: HomeAssistant,
matter_client: MagicMock,
pressure_sensor_node: MatterNode,
) -> None:
"""Test pressure sensor."""
state = hass.states.get("sensor.mock_pressure_sensor_pressure")
assert state
assert state.state == "0.0"
set_node_attribute(pressure_sensor_node, 1, 1027, 0, 1010)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get("sensor.mock_pressure_sensor_pressure")
assert state
assert state.state == "101.0"
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
async def test_temperature_sensor(
@ -413,6 +403,44 @@ async def test_eve_thermo_sensor(
assert state.state == "0"
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
async def test_pressure_sensor(
hass: HomeAssistant,
matter_client: MagicMock,
pressure_sensor_node: MatterNode,
) -> None:
"""Test pressure sensor."""
state = hass.states.get("sensor.mock_pressure_sensor_pressure")
assert state
assert state.state == "0.0"
set_node_attribute(pressure_sensor_node, 1, 1027, 0, 1010)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get("sensor.mock_pressure_sensor_pressure")
assert state
assert state.state == "101.0"
async def test_eve_weather_sensor_custom_cluster(
hass: HomeAssistant,
matter_client: MagicMock,
eve_weather_sensor_node: MatterNode,
) -> None:
"""Test weather sensor created from (Eve) custom cluster."""
# pressure sensor on Eve custom cluster
state = hass.states.get("sensor.eve_weather_pressure")
assert state
assert state.state == "1008.5"
set_node_attribute(eve_weather_sensor_node, 1, 319486977, 319422484, 800)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get("sensor.eve_weather_pressure")
assert state
assert state.state == "800.0"
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
async def test_air_quality_sensor(