Add remaining Matter Operational State sensor discovery schemas (#136741)

This commit is contained in:
Marcel van der Veldt 2025-01-29 09:16:30 +01:00 committed by GitHub
parent 447096b295
commit 609eb00a26
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 144 additions and 3 deletions

View File

@ -72,6 +72,9 @@ OPERATIONAL_STATE_MAP = {
clusters.OperationalState.Enums.OperationalStateEnum.kRunning: "running",
clusters.OperationalState.Enums.OperationalStateEnum.kPaused: "paused",
clusters.OperationalState.Enums.OperationalStateEnum.kError: "error",
clusters.RvcOperationalState.Enums.OperationalStateEnum.kSeekingCharger: "seeking_charger",
clusters.RvcOperationalState.Enums.OperationalStateEnum.kCharging: "charging",
clusters.RvcOperationalState.Enums.OperationalStateEnum.kDocked: "docked",
}
@ -98,6 +101,18 @@ class MatterListSensorEntityDescription(MatterSensorEntityDescription):
list_attribute: type[ClusterAttributeDescriptor]
@dataclass(frozen=True, kw_only=True)
class MatterOperationalStateSensorEntityDescription(MatterSensorEntityDescription):
"""Describe Matter sensor entities from Matter OperationalState objects."""
# list attribute: the attribute descriptor to get the list of values (= list of structs)
# needs to be set for handling OperationalState not on the OperationalState cluster, but
# on one of its derived clusters (e.g. RvcOperationalState)
state_list_attribute: type[ClusterAttributeDescriptor] = (
clusters.OperationalState.Attributes.OperationalStateList
)
class MatterSensor(MatterEntity, SensorEntity):
"""Representation of a Matter sensor."""
@ -147,6 +162,7 @@ class MatterDraftElectricalMeasurementSensor(MatterEntity, SensorEntity):
class MatterOperationalStateSensor(MatterSensor):
"""Representation of a sensor for Matter Operational State."""
entity_description: MatterOperationalStateSensorEntityDescription
states_map: dict[int, str]
@callback
@ -157,10 +173,11 @@ class MatterOperationalStateSensor(MatterSensor):
# therefore it is not possible to provide a fixed list of options
# or to provide a mapping to a translateable string for all options
operational_state_list = self.get_matter_attribute_value(
clusters.OperationalState.Attributes.OperationalStateList
self.entity_description.state_list_attribute
)
if TYPE_CHECKING:
operational_state_list = cast(
# cast to the generic OperationalStateStruct type just to help typing
list[clusters.OperationalState.Structs.OperationalStateStruct],
operational_state_list,
)
@ -782,7 +799,7 @@ DISCOVERY_SCHEMAS = [
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterSensorEntityDescription(
entity_description=MatterOperationalStateSensorEntityDescription(
key="OperationalState",
device_class=SensorDeviceClass.ENUM,
translation_key="operational_state",
@ -806,6 +823,32 @@ DISCOVERY_SCHEMAS = [
clusters.OperationalState.Attributes.PhaseList,
),
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterListSensorEntityDescription(
key="RvcOperationalStateCurrentPhase",
translation_key="current_phase",
list_attribute=clusters.RvcOperationalState.Attributes.PhaseList,
),
entity_class=MatterListSensor,
required_attributes=(
clusters.RvcOperationalState.Attributes.CurrentPhase,
clusters.RvcOperationalState.Attributes.PhaseList,
),
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterListSensorEntityDescription(
key="OvenCavityOperationalStateCurrentPhase",
translation_key="current_phase",
list_attribute=clusters.OvenCavityOperationalState.Attributes.PhaseList,
),
entity_class=MatterListSensor,
required_attributes=(
clusters.OvenCavityOperationalState.Attributes.CurrentPhase,
clusters.OvenCavityOperationalState.Attributes.PhaseList,
),
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterSensorEntityDescription(
@ -820,4 +863,33 @@ DISCOVERY_SCHEMAS = [
device_type=(device_types.Thermostat,),
allow_multi=True, # also used for climate entity
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterOperationalStateSensorEntityDescription(
key="RvcOperationalState",
device_class=SensorDeviceClass.ENUM,
translation_key="operational_state",
state_list_attribute=clusters.RvcOperationalState.Attributes.OperationalStateList,
),
entity_class=MatterOperationalStateSensor,
required_attributes=(
clusters.RvcOperationalState.Attributes.OperationalState,
clusters.RvcOperationalState.Attributes.OperationalStateList,
),
allow_multi=True, # also used for vacuum entity
),
MatterDiscoverySchema(
platform=Platform.SENSOR,
entity_description=MatterOperationalStateSensorEntityDescription(
key="OvenCavityOperationalState",
device_class=SensorDeviceClass.ENUM,
translation_key="operational_state",
state_list_attribute=clusters.OvenCavityOperationalState.Attributes.OperationalStateList,
),
entity_class=MatterOperationalStateSensor,
required_attributes=(
clusters.OvenCavityOperationalState.Attributes.OperationalState,
clusters.OvenCavityOperationalState.Attributes.OperationalStateList,
),
),
]

View File

@ -246,7 +246,10 @@
"stopped": "Stopped",
"running": "Running",
"paused": "[%key:common::state::paused%]",
"error": "Error"
"error": "Error",
"seeking_charger": "Seeking charger",
"charging": "Charging",
"docked": "Docked"
}
},
"switch_current_position": {

View File

@ -3412,6 +3412,72 @@
'state': '28.3',
})
# ---
# name: test_sensors[vacuum_cleaner][sensor.mock_vacuum_operational_state-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'stopped',
'running',
'paused',
'error',
'seeking_charger',
'charging',
'docked',
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.mock_vacuum_operational_state',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Operational state',
'platform': 'matter',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'operational_state',
'unique_id': '00000000000004D2-0000000000000042-MatterNodeDevice-1-RvcOperationalState-97-4',
'unit_of_measurement': None,
})
# ---
# name: test_sensors[vacuum_cleaner][sensor.mock_vacuum_operational_state-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Mock Vacuum Operational state',
'options': list([
'stopped',
'running',
'paused',
'error',
'seeking_charger',
'charging',
'docked',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.mock_vacuum_operational_state',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_sensors[yandex_smart_socket][sensor.yndx_00540_current-entry]
EntityRegistryEntrySnapshot({
'aliases': set({