mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 02:07:09 +00:00
Add Eve Thermo TRV Matter features (#135635)
* Add Eve Thermo Matter features * Update homeassistant/components/matter/switch.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Update homeassistant/components/matter/switch.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Update homeassistant/components/matter/switch.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Add Eve Thermo Child lock test * Update homeassistant/components/matter/switch.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Update homeassistant/components/matter/switch.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Implement thorough Child lock testing * Apply suggestions from code review --------- Co-authored-by: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Marcel van der Veldt <m.vanderveldt@outlook.com>
This commit is contained in:
parent
18ab882536
commit
ffcb4d676b
@ -61,6 +61,15 @@
|
|||||||
"battery_replacement_description": {
|
"battery_replacement_description": {
|
||||||
"default": "mdi:battery-sync-outline"
|
"default": "mdi:battery-sync-outline"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"switch": {
|
||||||
|
"child_lock": {
|
||||||
|
"default": "mdi:lock",
|
||||||
|
"state": {
|
||||||
|
"on": "mdi:lock",
|
||||||
|
"off": "mdi:lock-off"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,13 @@ from homeassistant.components.number import (
|
|||||||
NumberMode,
|
NumberMode,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import EntityCategory, Platform, UnitOfLength, UnitOfTime
|
from homeassistant.const import (
|
||||||
|
EntityCategory,
|
||||||
|
Platform,
|
||||||
|
UnitOfLength,
|
||||||
|
UnitOfTemperature,
|
||||||
|
UnitOfTime,
|
||||||
|
)
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
@ -155,4 +161,25 @@ DISCOVERY_SCHEMAS = [
|
|||||||
entity_class=MatterNumber,
|
entity_class=MatterNumber,
|
||||||
required_attributes=(custom_clusters.EveCluster.Attributes.Altitude,),
|
required_attributes=(custom_clusters.EveCluster.Attributes.Altitude,),
|
||||||
),
|
),
|
||||||
|
MatterDiscoverySchema(
|
||||||
|
platform=Platform.NUMBER,
|
||||||
|
entity_description=MatterNumberEntityDescription(
|
||||||
|
key="EveTemperatureOffset",
|
||||||
|
device_class=NumberDeviceClass.TEMPERATURE,
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
translation_key="temperature_offset",
|
||||||
|
native_max_value=25,
|
||||||
|
native_min_value=-25,
|
||||||
|
native_step=0.5,
|
||||||
|
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||||
|
measurement_to_ha=lambda x: None if x is None else x / 10,
|
||||||
|
ha_to_native_value=lambda x: round(x * 10),
|
||||||
|
mode=NumberMode.BOX,
|
||||||
|
),
|
||||||
|
entity_class=MatterNumber,
|
||||||
|
required_attributes=(
|
||||||
|
clusters.Thermostat.Attributes.LocalTemperatureCalibration,
|
||||||
|
),
|
||||||
|
vendor_id=(4874,),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
@ -254,4 +254,25 @@ DISCOVERY_SCHEMAS = [
|
|||||||
entity_class=MatterSelectEntity,
|
entity_class=MatterSelectEntity,
|
||||||
required_attributes=(clusters.SmokeCoAlarm.Attributes.SmokeSensitivityLevel,),
|
required_attributes=(clusters.SmokeCoAlarm.Attributes.SmokeSensitivityLevel,),
|
||||||
),
|
),
|
||||||
|
MatterDiscoverySchema(
|
||||||
|
platform=Platform.SELECT,
|
||||||
|
entity_description=MatterSelectEntityDescription(
|
||||||
|
key="TrvTemperatureDisplayMode",
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
translation_key="temperature_display_mode",
|
||||||
|
options=["Celsius", "Fahrenheit"],
|
||||||
|
measurement_to_ha={
|
||||||
|
0: "Celsius",
|
||||||
|
1: "Fahrenheit",
|
||||||
|
}.get,
|
||||||
|
ha_to_native_value={
|
||||||
|
"Celsius": 0,
|
||||||
|
"Fahrenheit": 1,
|
||||||
|
}.get,
|
||||||
|
),
|
||||||
|
entity_class=MatterSelectEntity,
|
||||||
|
required_attributes=(
|
||||||
|
clusters.ThermostatUserInterfaceConfiguration.Attributes.TemperatureDisplayMode,
|
||||||
|
),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
@ -161,6 +161,9 @@
|
|||||||
},
|
},
|
||||||
"altitude": {
|
"altitude": {
|
||||||
"name": "Altitude above Sea Level"
|
"name": "Altitude above Sea Level"
|
||||||
|
},
|
||||||
|
"temperature_offset": {
|
||||||
|
"name": "Temperature offset"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"light": {
|
"light": {
|
||||||
@ -196,6 +199,9 @@
|
|||||||
"toggle": "[%key:common::action::toggle%]",
|
"toggle": "[%key:common::action::toggle%]",
|
||||||
"previous": "Previous"
|
"previous": "Previous"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"temperature_display_mode": {
|
||||||
|
"name": "Temperature display mode"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sensor": {
|
"sensor": {
|
||||||
@ -256,6 +262,9 @@
|
|||||||
},
|
},
|
||||||
"power": {
|
"power": {
|
||||||
"name": "Power"
|
"name": "Power"
|
||||||
|
},
|
||||||
|
"child_lock": {
|
||||||
|
"name": "Child lock"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vacuum": {
|
"vacuum": {
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from chip.clusters import Objects as clusters
|
from chip.clusters import Objects as clusters
|
||||||
from matter_server.client.models import device_types
|
from matter_server.client.models import device_types
|
||||||
|
from matter_server.common.helpers.util import create_attribute_path_from_attribute
|
||||||
|
|
||||||
from homeassistant.components.switch import (
|
from homeassistant.components.switch import (
|
||||||
SwitchDeviceClass,
|
SwitchDeviceClass,
|
||||||
@ -13,11 +15,11 @@ from homeassistant.components.switch import (
|
|||||||
SwitchEntityDescription,
|
SwitchEntityDescription,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import EntityCategory, Platform
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from .entity import MatterEntity
|
from .entity import MatterEntity, MatterEntityDescription
|
||||||
from .helpers import get_matter
|
from .helpers import get_matter
|
||||||
from .models import MatterDiscoverySchema
|
from .models import MatterDiscoverySchema
|
||||||
|
|
||||||
@ -61,6 +63,49 @@ class MatterSwitch(MatterEntity, SwitchEntity):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class MatterNumericSwitchEntityDescription(
|
||||||
|
SwitchEntityDescription, MatterEntityDescription
|
||||||
|
):
|
||||||
|
"""Describe Matter Numeric Switch entities."""
|
||||||
|
|
||||||
|
|
||||||
|
class MatterNumericSwitch(MatterSwitch):
|
||||||
|
"""Representation of a Matter Enum Attribute as a Switch entity."""
|
||||||
|
|
||||||
|
entity_description: MatterNumericSwitchEntityDescription
|
||||||
|
|
||||||
|
async def _async_set_native_value(self, value: bool) -> None:
|
||||||
|
"""Update the current value."""
|
||||||
|
matter_attribute = self._entity_info.primary_attribute
|
||||||
|
if value_convert := self.entity_description.ha_to_native_value:
|
||||||
|
send_value = value_convert(value)
|
||||||
|
await self.matter_client.write_attribute(
|
||||||
|
node_id=self._endpoint.node.node_id,
|
||||||
|
attribute_path=create_attribute_path_from_attribute(
|
||||||
|
self._endpoint.endpoint_id,
|
||||||
|
matter_attribute,
|
||||||
|
),
|
||||||
|
value=send_value,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||||
|
"""Turn switch on."""
|
||||||
|
await self._async_set_native_value(True)
|
||||||
|
|
||||||
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
|
"""Turn switch off."""
|
||||||
|
await self._async_set_native_value(False)
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _update_from_device(self) -> None:
|
||||||
|
"""Update from device."""
|
||||||
|
value = self.get_matter_attribute_value(self._entity_info.primary_attribute)
|
||||||
|
if value_convert := self.entity_description.measurement_to_ha:
|
||||||
|
value = value_convert(value)
|
||||||
|
self._attr_is_on = value
|
||||||
|
|
||||||
|
|
||||||
# Discovery schema(s) to map Matter Attributes to HA entities
|
# Discovery schema(s) to map Matter Attributes to HA entities
|
||||||
DISCOVERY_SCHEMAS = [
|
DISCOVERY_SCHEMAS = [
|
||||||
MatterDiscoverySchema(
|
MatterDiscoverySchema(
|
||||||
@ -139,4 +184,25 @@ DISCOVERY_SCHEMAS = [
|
|||||||
device_types.Speaker,
|
device_types.Speaker,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
MatterDiscoverySchema(
|
||||||
|
platform=Platform.SWITCH,
|
||||||
|
entity_description=MatterNumericSwitchEntityDescription(
|
||||||
|
key="EveTrvChildLock",
|
||||||
|
entity_category=EntityCategory.CONFIG,
|
||||||
|
translation_key="child_lock",
|
||||||
|
measurement_to_ha={
|
||||||
|
0: False,
|
||||||
|
1: True,
|
||||||
|
}.get,
|
||||||
|
ha_to_native_value={
|
||||||
|
False: 0,
|
||||||
|
True: 1,
|
||||||
|
}.get,
|
||||||
|
),
|
||||||
|
entity_class=MatterNumericSwitch,
|
||||||
|
required_attributes=(
|
||||||
|
clusters.ThermostatUserInterfaceConfiguration.Attributes.KeypadLockout,
|
||||||
|
),
|
||||||
|
vendor_id=(4874,),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
@ -388,6 +388,63 @@
|
|||||||
'state': '1.0',
|
'state': '1.0',
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
|
# name: test_numbers[eve_thermo][number.eve_thermo_temperature_offset-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': dict({
|
||||||
|
'max': 25,
|
||||||
|
'min': -25,
|
||||||
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
|
'step': 0.5,
|
||||||
|
}),
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'number',
|
||||||
|
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||||
|
'entity_id': 'number.eve_thermo_temperature_offset',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': <NumberDeviceClass.TEMPERATURE: 'temperature'>,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Temperature offset',
|
||||||
|
'platform': 'matter',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': 'temperature_offset',
|
||||||
|
'unique_id': '00000000000004D2-0000000000000021-MatterNodeDevice-1-EveTemperatureOffset-513-16',
|
||||||
|
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_numbers[eve_thermo][number.eve_thermo_temperature_offset-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'temperature',
|
||||||
|
'friendly_name': 'Eve Thermo Temperature offset',
|
||||||
|
'max': 25,
|
||||||
|
'min': -25,
|
||||||
|
'mode': <NumberMode.BOX: 'box'>,
|
||||||
|
'step': 0.5,
|
||||||
|
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'number.eve_thermo_temperature_offset',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': '0.0',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
# name: test_numbers[eve_weather_sensor][number.eve_weather_altitude_above_sea_level-entry]
|
# name: test_numbers[eve_weather_sensor][number.eve_weather_altitude_above_sea_level-entry]
|
||||||
EntityRegistryEntrySnapshot({
|
EntityRegistryEntrySnapshot({
|
||||||
'aliases': set({
|
'aliases': set({
|
||||||
|
@ -546,6 +546,61 @@
|
|||||||
'state': 'previous',
|
'state': 'previous',
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
|
# name: test_selects[eve_thermo][select.eve_thermo_temperature_display_mode-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': dict({
|
||||||
|
'options': list([
|
||||||
|
'Celsius',
|
||||||
|
'Fahrenheit',
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'select',
|
||||||
|
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||||
|
'entity_id': 'select.eve_thermo_temperature_display_mode',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': None,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Temperature display mode',
|
||||||
|
'platform': 'matter',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': 'temperature_display_mode',
|
||||||
|
'unique_id': '00000000000004D2-0000000000000021-MatterNodeDevice-1-TrvTemperatureDisplayMode-516-0',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_selects[eve_thermo][select.eve_thermo_temperature_display_mode-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Eve Thermo Temperature display mode',
|
||||||
|
'options': list([
|
||||||
|
'Celsius',
|
||||||
|
'Fahrenheit',
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'select.eve_thermo_temperature_display_mode',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'Celsius',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
# name: test_selects[extended_color_light][select.mock_extended_color_light_lighting-entry]
|
# name: test_selects[extended_color_light][select.mock_extended_color_light_lighting-entry]
|
||||||
EntityRegistryEntrySnapshot({
|
EntityRegistryEntrySnapshot({
|
||||||
'aliases': set({
|
'aliases': set({
|
||||||
@ -1573,6 +1628,61 @@
|
|||||||
'state': 'previous',
|
'state': 'previous',
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
|
# name: test_selects[thermostat][select.longan_link_hvac_temperature_display_mode-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': dict({
|
||||||
|
'options': list([
|
||||||
|
'Celsius',
|
||||||
|
'Fahrenheit',
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'select',
|
||||||
|
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||||
|
'entity_id': 'select.longan_link_hvac_temperature_display_mode',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': None,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Temperature display mode',
|
||||||
|
'platform': 'matter',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': 'temperature_display_mode',
|
||||||
|
'unique_id': '00000000000004D2-0000000000000004-MatterNodeDevice-1-TrvTemperatureDisplayMode-516-0',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_selects[thermostat][select.longan_link_hvac_temperature_display_mode-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Longan link HVAC Temperature display mode',
|
||||||
|
'options': list([
|
||||||
|
'Celsius',
|
||||||
|
'Fahrenheit',
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'select.longan_link_hvac_temperature_display_mode',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'Celsius',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
# name: test_selects[vacuum_cleaner][select.mock_vacuum_clean_mode-entry]
|
# name: test_selects[vacuum_cleaner][select.mock_vacuum_clean_mode-entry]
|
||||||
EntityRegistryEntrySnapshot({
|
EntityRegistryEntrySnapshot({
|
||||||
'aliases': set({
|
'aliases': set({
|
||||||
|
@ -187,6 +187,52 @@
|
|||||||
'state': 'off',
|
'state': 'off',
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
|
# name: test_switches[eve_thermo][switch.eve_thermo_child_lock-entry]
|
||||||
|
EntityRegistryEntrySnapshot({
|
||||||
|
'aliases': set({
|
||||||
|
}),
|
||||||
|
'area_id': None,
|
||||||
|
'capabilities': None,
|
||||||
|
'config_entry_id': <ANY>,
|
||||||
|
'device_class': None,
|
||||||
|
'device_id': <ANY>,
|
||||||
|
'disabled_by': None,
|
||||||
|
'domain': 'switch',
|
||||||
|
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||||
|
'entity_id': 'switch.eve_thermo_child_lock',
|
||||||
|
'has_entity_name': True,
|
||||||
|
'hidden_by': None,
|
||||||
|
'icon': None,
|
||||||
|
'id': <ANY>,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'name': None,
|
||||||
|
'options': dict({
|
||||||
|
}),
|
||||||
|
'original_device_class': None,
|
||||||
|
'original_icon': None,
|
||||||
|
'original_name': 'Child lock',
|
||||||
|
'platform': 'matter',
|
||||||
|
'previous_unique_id': None,
|
||||||
|
'supported_features': 0,
|
||||||
|
'translation_key': 'child_lock',
|
||||||
|
'unique_id': '00000000000004D2-0000000000000021-MatterNodeDevice-1-EveTrvChildLock-516-1',
|
||||||
|
'unit_of_measurement': None,
|
||||||
|
})
|
||||||
|
# ---
|
||||||
|
# name: test_switches[eve_thermo][switch.eve_thermo_child_lock-state]
|
||||||
|
StateSnapshot({
|
||||||
|
'attributes': ReadOnlyDict({
|
||||||
|
'friendly_name': 'Eve Thermo Child lock',
|
||||||
|
}),
|
||||||
|
'context': <ANY>,
|
||||||
|
'entity_id': 'switch.eve_thermo_child_lock',
|
||||||
|
'last_changed': <ANY>,
|
||||||
|
'last_reported': <ANY>,
|
||||||
|
'last_updated': <ANY>,
|
||||||
|
'state': 'off',
|
||||||
|
})
|
||||||
|
# ---
|
||||||
# name: test_switches[on_off_plugin_unit][switch.mock_onoffpluginunit-entry]
|
# name: test_switches[on_off_plugin_unit][switch.mock_onoffpluginunit-entry]
|
||||||
EntityRegistryEntrySnapshot({
|
EntityRegistryEntrySnapshot({
|
||||||
'aliases': set({
|
'aliases': set({
|
||||||
|
@ -4,6 +4,7 @@ from unittest.mock import MagicMock, call
|
|||||||
|
|
||||||
from chip.clusters import Objects as clusters
|
from chip.clusters import Objects as clusters
|
||||||
from matter_server.client.models.node import MatterNode
|
from matter_server.client.models.node import MatterNode
|
||||||
|
from matter_server.common.helpers.util import create_attribute_path_from_attribute
|
||||||
import pytest
|
import pytest
|
||||||
from syrupy import SnapshotAssertion
|
from syrupy import SnapshotAssertion
|
||||||
|
|
||||||
@ -110,3 +111,57 @@ async def test_power_switch(hass: HomeAssistant, matter_node: MatterNode) -> Non
|
|||||||
assert state
|
assert state
|
||||||
assert state.state == "off"
|
assert state.state == "off"
|
||||||
assert state.attributes["friendly_name"] == "Room AirConditioner Power"
|
assert state.attributes["friendly_name"] == "Room AirConditioner Power"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("node_fixture", ["eve_thermo"])
|
||||||
|
async def test_numeric_switch(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
matter_client: MagicMock,
|
||||||
|
matter_node: MatterNode,
|
||||||
|
) -> None:
|
||||||
|
"""Test numeric switch entity is discovered and working using an Eve Thermo fixture ."""
|
||||||
|
state = hass.states.get("switch.eve_thermo_child_lock")
|
||||||
|
assert state
|
||||||
|
assert state.state == "off"
|
||||||
|
# name should be derived from description attribute
|
||||||
|
assert state.attributes["friendly_name"] == "Eve Thermo Child lock"
|
||||||
|
# test attribute changes
|
||||||
|
set_node_attribute(matter_node, 1, 516, 1, 1)
|
||||||
|
await trigger_subscription_callback(hass, matter_client)
|
||||||
|
state = hass.states.get("switch.eve_thermo_child_lock")
|
||||||
|
assert state.state == "on"
|
||||||
|
set_node_attribute(matter_node, 1, 516, 1, 0)
|
||||||
|
await trigger_subscription_callback(hass, matter_client)
|
||||||
|
state = hass.states.get("switch.eve_thermo_child_lock")
|
||||||
|
assert state.state == "off"
|
||||||
|
# test switch service
|
||||||
|
await hass.services.async_call(
|
||||||
|
"switch",
|
||||||
|
"turn_on",
|
||||||
|
{"entity_id": "switch.eve_thermo_child_lock"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert matter_client.write_attribute.call_count == 1
|
||||||
|
assert matter_client.write_attribute.call_args_list[0] == call(
|
||||||
|
node_id=matter_node.node_id,
|
||||||
|
attribute_path=create_attribute_path_from_attribute(
|
||||||
|
endpoint_id=1,
|
||||||
|
attribute=clusters.ThermostatUserInterfaceConfiguration.Attributes.KeypadLockout,
|
||||||
|
),
|
||||||
|
value=1,
|
||||||
|
)
|
||||||
|
await hass.services.async_call(
|
||||||
|
"switch",
|
||||||
|
"turn_off",
|
||||||
|
{"entity_id": "switch.eve_thermo_child_lock"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert matter_client.write_attribute.call_count == 2
|
||||||
|
assert matter_client.write_attribute.call_args_list[1] == call(
|
||||||
|
node_id=matter_node.node_id,
|
||||||
|
attribute_path=create_attribute_path_from_attribute(
|
||||||
|
endpoint_id=1,
|
||||||
|
attribute=clusters.ThermostatUserInterfaceConfiguration.Attributes.KeypadLockout,
|
||||||
|
),
|
||||||
|
value=0,
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user