mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 04:07:08 +00:00
Support for Matter 1.4 Water Heater device type (#131505)
* Create water_heater.json * Update water_heater.json * Update water_heater.json * TankVolume * TankPercentage * WaterHeaterMode WaterHeaterMode * Update sensor.py * ruff-format * Update water_heater.json Attributes of WaterHeaterManagement Cluster on Endpoint 2 ClusterId 148 (0x0094) * Update test_sensor.py water_heater fixture * Update test_sensor.py * SensorDeviceClass=VOLUME_STORAGE for `TankVolume` * `BoostStateEnum` map * WaterHeaterManagementBoostState * Update sensor.py * WaterHeaterManagementEstimatedHeatRequired * Fix UnitOfEnergy * Format * Add `device_types.WaterHeater` to Climate * Strings for Tank sensors * WaterHeater icons * Update icons.json * Update strings.json * Update water_heater.json * ruff-format * Fix tests * Fix sensor.py * Fix icons * WaterHeaterManagementEstimatedHeatRequired * WaterHeaterManagementBoostState * BoostState as a binary sensor * ElectricalPowerMeasurement values * Fix tests * Create water_heater.py * Update climate.py from dev branch * Resolve conflicts * ruff-format * Add Platform.WATER_HEATER * Update water_heater.py * Update water_heater.py * Update water_heater.py * Update water_heater.py * Add WaterHeaterManagement sensors * Update tests * Add select test * Add strings * First try with water_heater * Testing current_operation * BoostState attribute * target_temperature attributes * target_temperature attribute * set_temperature and set_operation_mode * turn_on / turn_off * Trigger Boost command * Fix WaterHeaterBoostInfoStruct * Add test file * Add climate cluster to fixture * Add climate cluster to fixture * Add tests * Add ON_OFF feature * Update tests * Update tests * Translate WaterHeaterMode * Change description * Update test and snapshots * Update snapshots * Set entity name to None to make the device name be the name of the entity * Format * Update water_heater.py * Fix format * ruff-format * Import ServiceValidationError * Update homeassistant/components/matter/water_heater.py Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> * Update water_heater.py * Update test_water_heater.py * Update test_water_heater.ambr * Update test_water_heater.py * Update select.py * Update snapshots * Rename to boost_info * Set WaterHeaterMode * Update snapshots * Update snapshots * Fix for warning W7431: Argument 3 should be of type AddConfigEntryEntitiesCallback in async_setup_entry (hass-argument-type) * Update strings.json * Update strings and tests * Fix missing brace * Update tests * fix test * Updates strings * Fix async_set_temperature * Update tests * Update tests * Update homeassistant/components/matter/water_heater.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Sort strings in strings.json * Update homeassistant/components/matter/water_heater.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Remove unused line * Remove min/max target temperatures * Remove BOOST_STATE_MAP * Add comment * Remove SUPPORT_FLAGS_HEATER * Remove system_mode_value check * Update homeassistant/components/matter/water_heater.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Reformat async_set_temperature() * Update snapshots * Remove MatterWaterHeaterMode selector * Update snapshots * Rename test to test_water_heater_set_temperature * Add test_water_heater_set_operation_mode * Remove reset_mock * Update tests/components/matter/test_water_heater.py Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Add test_update_from_water_heater * Add test_water_heater_turn_on_off * Add test_water_heater_boostmode * Fix SystemMode value for STATE_HIGH_DEMAND * Add disable boost from water heater device side test * Remove unused lines * Remove unused lines * Fix test indentation * Fix water heater tests * Check for None --------- Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com> Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
4a1905a2a2
commit
4adf5ce826
@ -322,4 +322,16 @@ DISCOVERY_SCHEMAS = [
|
||||
required_attributes=(clusters.EnergyEvse.Attributes.SupplyState,),
|
||||
allow_multi=True, # also used for sensor entity
|
||||
),
|
||||
MatterDiscoverySchema(
|
||||
platform=Platform.BINARY_SENSOR,
|
||||
entity_description=MatterBinarySensorEntityDescription(
|
||||
key="WaterHeaterManagementBoostStateSensor",
|
||||
translation_key="boost_state",
|
||||
measurement_to_ha=lambda x: (
|
||||
x == clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive
|
||||
),
|
||||
),
|
||||
entity_class=MatterBinarySensor,
|
||||
required_attributes=(clusters.WaterHeaterManagement.Attributes.BoostState,),
|
||||
),
|
||||
]
|
||||
|
@ -27,6 +27,7 @@ from .switch import DISCOVERY_SCHEMAS as SWITCH_SCHEMAS
|
||||
from .update import DISCOVERY_SCHEMAS as UPDATE_SCHEMAS
|
||||
from .vacuum import DISCOVERY_SCHEMAS as VACUUM_SCHEMAS
|
||||
from .valve import DISCOVERY_SCHEMAS as VALVE_SCHEMAS
|
||||
from .water_heater import DISCOVERY_SCHEMAS as WATER_HEATER_SCHEMAS
|
||||
|
||||
DISCOVERY_SCHEMAS: dict[Platform, list[MatterDiscoverySchema]] = {
|
||||
Platform.BINARY_SENSOR: BINARY_SENSOR_SCHEMAS,
|
||||
@ -44,6 +45,7 @@ DISCOVERY_SCHEMAS: dict[Platform, list[MatterDiscoverySchema]] = {
|
||||
Platform.UPDATE: UPDATE_SCHEMAS,
|
||||
Platform.VACUUM: VACUUM_SCHEMAS,
|
||||
Platform.VALVE: VALVE_SCHEMAS,
|
||||
Platform.WATER_HEATER: WATER_HEATER_SCHEMAS,
|
||||
}
|
||||
SUPPORTED_PLATFORMS = tuple(DISCOVERY_SCHEMAS)
|
||||
|
||||
|
@ -66,6 +66,12 @@
|
||||
"operational_state": {
|
||||
"default": "mdi:play-pause"
|
||||
},
|
||||
"tank_volume": {
|
||||
"default": "mdi:water-boiler"
|
||||
},
|
||||
"tank_percentage": {
|
||||
"default": "mdi:water-boiler"
|
||||
},
|
||||
"valve_position": {
|
||||
"default": "mdi:valve"
|
||||
},
|
||||
|
@ -41,6 +41,7 @@ type SelectCluster = (
|
||||
| clusters.DishwasherMode
|
||||
| clusters.EnergyEvseMode
|
||||
| clusters.DeviceEnergyManagementMode
|
||||
| clusters.WaterHeaterMode
|
||||
)
|
||||
|
||||
|
||||
|
@ -37,6 +37,7 @@ from homeassistant.const import (
|
||||
UnitOfPower,
|
||||
UnitOfPressure,
|
||||
UnitOfTemperature,
|
||||
UnitOfVolume,
|
||||
UnitOfVolumeFlowRate,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
@ -65,7 +66,6 @@ CONTAMINATION_STATE_MAP = {
|
||||
clusters.SmokeCoAlarm.Enums.ContaminationStateEnum.kCritical: "critical",
|
||||
}
|
||||
|
||||
|
||||
OPERATIONAL_STATE_MAP = {
|
||||
# enum with known Operation state values which we can translate
|
||||
clusters.OperationalState.Enums.OperationalStateEnum.kStopped: "stopped",
|
||||
@ -77,6 +77,12 @@ OPERATIONAL_STATE_MAP = {
|
||||
clusters.RvcOperationalState.Enums.OperationalStateEnum.kDocked: "docked",
|
||||
}
|
||||
|
||||
BOOST_STATE_MAP = {
|
||||
clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive: "inactive",
|
||||
clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive: "active",
|
||||
clusters.WaterHeaterManagement.Enums.BoostStateEnum.kUnknownEnumValue: None,
|
||||
}
|
||||
|
||||
EVSE_FAULT_STATE_MAP = {
|
||||
clusters.EnergyEvse.Enums.FaultStateEnum.kNoError: "no_error",
|
||||
clusters.EnergyEvse.Enums.FaultStateEnum.kMeterFailure: "meter_failure",
|
||||
@ -996,4 +1002,44 @@ DISCOVERY_SCHEMAS = [
|
||||
entity_class=MatterSensor,
|
||||
required_attributes=(clusters.EnergyEvse.Attributes.UserMaximumChargeCurrent,),
|
||||
),
|
||||
MatterDiscoverySchema(
|
||||
platform=Platform.SENSOR,
|
||||
entity_description=MatterSensorEntityDescription(
|
||||
key="WaterHeaterManagementTankVolume",
|
||||
translation_key="tank_volume",
|
||||
device_class=SensorDeviceClass.VOLUME_STORAGE,
|
||||
native_unit_of_measurement=UnitOfVolume.LITERS,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
entity_class=MatterSensor,
|
||||
required_attributes=(clusters.WaterHeaterManagement.Attributes.TankVolume,),
|
||||
),
|
||||
MatterDiscoverySchema(
|
||||
platform=Platform.SENSOR,
|
||||
entity_description=MatterSensorEntityDescription(
|
||||
key="WaterHeaterManagementTankPercentage",
|
||||
translation_key="tank_percentage",
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
entity_class=MatterSensor,
|
||||
required_attributes=(clusters.WaterHeaterManagement.Attributes.TankPercentage,),
|
||||
),
|
||||
MatterDiscoverySchema(
|
||||
platform=Platform.SENSOR,
|
||||
entity_description=MatterSensorEntityDescription(
|
||||
key="WaterHeaterManagementEstimatedHeatRequired",
|
||||
translation_key="estimated_heat_required",
|
||||
device_class=SensorDeviceClass.ENERGY,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
native_unit_of_measurement=UnitOfEnergy.MILLIWATT_HOUR,
|
||||
suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
||||
suggested_display_precision=3,
|
||||
state_class=SensorStateClass.TOTAL,
|
||||
),
|
||||
entity_class=MatterSensor,
|
||||
required_attributes=(
|
||||
clusters.WaterHeaterManagement.Attributes.EstimatedHeatRequired,
|
||||
),
|
||||
),
|
||||
]
|
||||
|
@ -85,6 +85,9 @@
|
||||
},
|
||||
"evse_supply_charging_state": {
|
||||
"name": "Supply charging state"
|
||||
},
|
||||
"boost_state": {
|
||||
"name": "Boost state"
|
||||
}
|
||||
},
|
||||
"button": {
|
||||
@ -229,6 +232,9 @@
|
||||
},
|
||||
"laundry_washer_spin_speed": {
|
||||
"name": "Spin speed"
|
||||
},
|
||||
"water_heater_mode": {
|
||||
"name": "Water heater mode"
|
||||
}
|
||||
},
|
||||
"sensor": {
|
||||
@ -279,6 +285,15 @@
|
||||
"switch_current_position": {
|
||||
"name": "Current switch position"
|
||||
},
|
||||
"estimated_heat_required": {
|
||||
"name": "Required heating energy"
|
||||
},
|
||||
"tank_volume": {
|
||||
"name": "Tank volume"
|
||||
},
|
||||
"tank_percentage": {
|
||||
"name": "Hot water level"
|
||||
},
|
||||
"valve_position": {
|
||||
"name": "Valve position"
|
||||
},
|
||||
@ -348,6 +363,11 @@
|
||||
"valve": {
|
||||
"name": "[%key:component::valve::title%]"
|
||||
}
|
||||
},
|
||||
"water_heater": {
|
||||
"water_heater": {
|
||||
"name": "[%key:component::water_heater::title%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
|
189
homeassistant/components/matter/water_heater.py
Normal file
189
homeassistant/components/matter/water_heater.py
Normal file
@ -0,0 +1,189 @@
|
||||
"""Matter water heater platform."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, cast
|
||||
|
||||
from chip.clusters import Objects as clusters
|
||||
from matter_server.client.models import device_types
|
||||
from matter_server.common.helpers.util import create_attribute_path_from_attribute
|
||||
|
||||
from homeassistant.components.water_heater import (
|
||||
STATE_ECO,
|
||||
STATE_HIGH_DEMAND,
|
||||
STATE_OFF,
|
||||
WaterHeaterEntity,
|
||||
WaterHeaterEntityDescription,
|
||||
WaterHeaterEntityFeature,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
ATTR_TEMPERATURE,
|
||||
PRECISION_WHOLE,
|
||||
Platform,
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
|
||||
from .entity import MatterEntity
|
||||
from .helpers import get_matter
|
||||
from .models import MatterDiscoverySchema
|
||||
|
||||
TEMPERATURE_SCALING_FACTOR = 100
|
||||
|
||||
# Map HA WH system mode to Matter ThermostatRunningMode attribute of the Thermostat cluster (Heat = 4)
|
||||
WATER_HEATER_SYSTEM_MODE_MAP = {
|
||||
STATE_ECO: 4,
|
||||
STATE_HIGH_DEMAND: 4,
|
||||
STATE_OFF: 0,
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Matter WaterHeater platform from Config Entry."""
|
||||
matter = get_matter(hass)
|
||||
matter.register_platform_handler(Platform.WATER_HEATER, async_add_entities)
|
||||
|
||||
|
||||
class MatterWaterHeater(MatterEntity, WaterHeaterEntity):
|
||||
"""Representation of a Matter WaterHeater entity."""
|
||||
|
||||
_attr_current_temperature: float | None = None
|
||||
_attr_current_operation: str
|
||||
_attr_operation_list = [
|
||||
STATE_ECO,
|
||||
STATE_HIGH_DEMAND,
|
||||
STATE_OFF,
|
||||
]
|
||||
_attr_precision = PRECISION_WHOLE
|
||||
_attr_supported_features = (
|
||||
WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||
| WaterHeaterEntityFeature.ON_OFF
|
||||
| WaterHeaterEntityFeature.OPERATION_MODE
|
||||
)
|
||||
_attr_target_temperature: float | None = None
|
||||
_attr_temperature_unit = UnitOfTemperature.CELSIUS
|
||||
_platform_translation_key = "water_heater"
|
||||
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new target temperature."""
|
||||
target_temperature: float | None = kwargs.get(ATTR_TEMPERATURE)
|
||||
if (
|
||||
target_temperature is not None
|
||||
and self.target_temperature != target_temperature
|
||||
):
|
||||
matter_attribute = clusters.Thermostat.Attributes.OccupiedHeatingSetpoint
|
||||
await self.write_attribute(
|
||||
value=round(target_temperature * TEMPERATURE_SCALING_FACTOR),
|
||||
matter_attribute=matter_attribute,
|
||||
)
|
||||
|
||||
async def async_set_operation_mode(self, operation_mode: str) -> None:
|
||||
"""Set new operation mode."""
|
||||
self._attr_current_operation = operation_mode
|
||||
# Boost 1h (3600s)
|
||||
boost_info: type[
|
||||
clusters.WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct
|
||||
] = clusters.WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct(
|
||||
duration=3600
|
||||
)
|
||||
system_mode_value = WATER_HEATER_SYSTEM_MODE_MAP[operation_mode]
|
||||
await self.write_attribute(
|
||||
value=system_mode_value,
|
||||
matter_attribute=clusters.Thermostat.Attributes.SystemMode,
|
||||
)
|
||||
system_mode_path = create_attribute_path_from_attribute(
|
||||
endpoint_id=self._endpoint.endpoint_id,
|
||||
attribute=clusters.Thermostat.Attributes.SystemMode,
|
||||
)
|
||||
self._endpoint.set_attribute_value(system_mode_path, system_mode_value)
|
||||
self._update_from_device()
|
||||
# Trigger Boost command
|
||||
if operation_mode == STATE_HIGH_DEMAND:
|
||||
await self.send_device_command(
|
||||
clusters.WaterHeaterManagement.Commands.Boost(boostInfo=boost_info)
|
||||
)
|
||||
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn on water heater."""
|
||||
await self.async_set_operation_mode("eco")
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off water heater."""
|
||||
await self.async_set_operation_mode("off")
|
||||
|
||||
@callback
|
||||
def _update_from_device(self) -> None:
|
||||
"""Update from device."""
|
||||
self._attr_current_temperature = self._get_temperature_in_degrees(
|
||||
clusters.Thermostat.Attributes.LocalTemperature
|
||||
)
|
||||
self._attr_target_temperature = self._get_temperature_in_degrees(
|
||||
clusters.Thermostat.Attributes.OccupiedHeatingSetpoint
|
||||
)
|
||||
boost_state = self.get_matter_attribute_value(
|
||||
clusters.WaterHeaterManagement.Attributes.BoostState
|
||||
)
|
||||
if boost_state == clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive:
|
||||
self._attr_current_operation = STATE_HIGH_DEMAND
|
||||
else:
|
||||
self._attr_current_operation = STATE_ECO
|
||||
self._attr_temperature = cast(
|
||||
float,
|
||||
self._get_temperature_in_degrees(
|
||||
clusters.Thermostat.Attributes.OccupiedHeatingSetpoint
|
||||
),
|
||||
)
|
||||
self._attr_min_temp = cast(
|
||||
float,
|
||||
self._get_temperature_in_degrees(
|
||||
clusters.Thermostat.Attributes.AbsMinHeatSetpointLimit
|
||||
),
|
||||
)
|
||||
self._attr_max_temp = cast(
|
||||
float,
|
||||
self._get_temperature_in_degrees(
|
||||
clusters.Thermostat.Attributes.AbsMaxHeatSetpointLimit
|
||||
),
|
||||
)
|
||||
|
||||
@callback
|
||||
def _get_temperature_in_degrees(
|
||||
self, attribute: type[clusters.ClusterAttributeDescriptor]
|
||||
) -> float | None:
|
||||
"""Return the scaled temperature value for the given attribute."""
|
||||
if (value := self.get_matter_attribute_value(attribute)) is not None:
|
||||
return float(value) / TEMPERATURE_SCALING_FACTOR
|
||||
return None
|
||||
|
||||
|
||||
# Discovery schema(s) to map Matter Attributes to HA entities
|
||||
DISCOVERY_SCHEMAS = [
|
||||
MatterDiscoverySchema(
|
||||
platform=Platform.WATER_HEATER,
|
||||
entity_description=WaterHeaterEntityDescription(
|
||||
key="MatterWaterHeater",
|
||||
name=None,
|
||||
),
|
||||
entity_class=MatterWaterHeater,
|
||||
required_attributes=(
|
||||
clusters.Thermostat.Attributes.OccupiedHeatingSetpoint,
|
||||
clusters.Thermostat.Attributes.AbsMinHeatSetpointLimit,
|
||||
clusters.Thermostat.Attributes.AbsMaxHeatSetpointLimit,
|
||||
clusters.Thermostat.Attributes.LocalTemperature,
|
||||
clusters.WaterHeaterManagement.Attributes.FeatureMap,
|
||||
),
|
||||
optional_attributes=(
|
||||
clusters.WaterHeaterManagement.Attributes.HeaterTypes,
|
||||
clusters.WaterHeaterManagement.Attributes.BoostState,
|
||||
clusters.WaterHeaterManagement.Attributes.HeatDemand,
|
||||
),
|
||||
device_type=(device_types.WaterHeater,),
|
||||
allow_multi=True, # also used for sensor entity
|
||||
),
|
||||
]
|
@ -106,6 +106,7 @@ async def integration_fixture(
|
||||
"silabs_dishwasher",
|
||||
"silabs_evse_charging",
|
||||
"silabs_laundrywasher",
|
||||
"silabs_water_heater",
|
||||
"smoke_detector",
|
||||
"switch_unit",
|
||||
"temperature_sensor",
|
||||
|
534
tests/components/matter/fixtures/nodes/silabs_water_heater.json
Normal file
534
tests/components/matter/fixtures/nodes/silabs_water_heater.json
Normal file
@ -0,0 +1,534 @@
|
||||
{
|
||||
"node_id": 25,
|
||||
"date_commissioned": "2024-11-21T20:21:44.371473",
|
||||
"last_interview": "2024-11-21T20:21:44.371503",
|
||||
"interview_version": 6,
|
||||
"available": true,
|
||||
"is_bridge": false,
|
||||
"attributes": {
|
||||
"0/29/0": [
|
||||
{
|
||||
"0": 22,
|
||||
"1": 1
|
||||
}
|
||||
],
|
||||
"0/29/1": [29, 31, 40, 43, 44, 45, 48, 49, 51, 60, 62, 63],
|
||||
"0/29/2": [],
|
||||
"0/29/3": [2],
|
||||
"0/29/65532": 0,
|
||||
"0/29/65533": 2,
|
||||
"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": 3
|
||||
}
|
||||
],
|
||||
"0/31/2": 4,
|
||||
"0/31/3": 3,
|
||||
"0/31/4": 4,
|
||||
"0/31/65532": 0,
|
||||
"0/31/65533": 2,
|
||||
"0/31/65528": [],
|
||||
"0/31/65529": [],
|
||||
"0/31/65531": [0, 2, 3, 4, 65528, 65529, 65531, 65532, 65533],
|
||||
"0/40/0": 18,
|
||||
"0/40/1": "Silabs",
|
||||
"0/40/2": 65521,
|
||||
"0/40/3": "Water Heater",
|
||||
"0/40/4": 32773,
|
||||
"0/40/5": "",
|
||||
"0/40/6": "**REDACTED**",
|
||||
"0/40/7": 0,
|
||||
"0/40/8": "TEST_VERSION",
|
||||
"0/40/9": 1,
|
||||
"0/40/10": "v1.3-fix-energy-man-app-comp-2d92654525-dirty",
|
||||
"0/40/15": "",
|
||||
"0/40/18": "1868F000380F300B",
|
||||
"0/40/19": {
|
||||
"0": 3,
|
||||
"1": 3
|
||||
},
|
||||
"0/40/21": 17039360,
|
||||
"0/40/22": 1,
|
||||
"0/40/65532": 0,
|
||||
"0/40/65533": 4,
|
||||
"0/40/65528": [],
|
||||
"0/40/65529": [],
|
||||
"0/40/65531": [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 18, 19, 21, 22, 65528, 65529, 65531,
|
||||
65532, 65533
|
||||
],
|
||||
"0/43/0": "",
|
||||
"0/43/1": [
|
||||
"en-US",
|
||||
"de-DE",
|
||||
"fr-FR",
|
||||
"en-GB",
|
||||
"es-ES",
|
||||
"zh-CN",
|
||||
"it-IT",
|
||||
"ja-JP"
|
||||
],
|
||||
"0/43/65532": 0,
|
||||
"0/43/65533": 1,
|
||||
"0/43/65528": [],
|
||||
"0/43/65529": [],
|
||||
"0/43/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
|
||||
"0/44/0": 0,
|
||||
"0/44/65532": 0,
|
||||
"0/44/65533": 1,
|
||||
"0/44/65528": [],
|
||||
"0/44/65529": [],
|
||||
"0/44/65531": [0, 65528, 65529, 65531, 65532, 65533],
|
||||
"0/45/65532": 0,
|
||||
"0/45/65533": 1,
|
||||
"0/45/65528": [],
|
||||
"0/45/65529": [],
|
||||
"0/45/65531": [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": 2,
|
||||
"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": "p0jbsOzJRNw=",
|
||||
"1": true
|
||||
}
|
||||
],
|
||||
"0/49/4": true,
|
||||
"0/49/5": 0,
|
||||
"0/49/6": "p0jbsOzJRNw=",
|
||||
"0/49/7": null,
|
||||
"0/49/8": [0],
|
||||
"0/49/65532": 2,
|
||||
"0/49/65533": 2,
|
||||
"0/49/65528": [1, 5, 7],
|
||||
"0/49/65529": [0, 3, 4, 6, 8],
|
||||
"0/49/65531": [0, 1, 4, 5, 6, 7, 8, 65528, 65529, 65531, 65532, 65533],
|
||||
"0/51/0": [
|
||||
{
|
||||
"0": "MyHome",
|
||||
"1": true,
|
||||
"2": null,
|
||||
"3": null,
|
||||
"4": "0ln4A+M/qdU=",
|
||||
"5": [],
|
||||
"6": [
|
||||
"/QANuACgAAAAAAD//gCEAA==",
|
||||
"/akBUIsgAADu+RflBK+awg==",
|
||||
"/QANuACgAACOGElK6AMfiw==",
|
||||
"/oAAAAAAAADQWfgD4z+p1Q=="
|
||||
],
|
||||
"7": 4
|
||||
}
|
||||
],
|
||||
"0/51/1": 2,
|
||||
"0/51/2": 970,
|
||||
"0/51/8": true,
|
||||
"0/51/65532": 0,
|
||||
"0/51/65533": 2,
|
||||
"0/51/65528": [2],
|
||||
"0/51/65529": [0, 1],
|
||||
"0/51/65531": [0, 1, 2, 8, 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, 2],
|
||||
"0/60/65531": [0, 1, 2, 65528, 65529, 65531, 65532, 65533],
|
||||
"0/62/0": [
|
||||
{
|
||||
"1": "FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVAiQRLBgkBwEkCAEwCUEET/Kg7i1M+NQnTtjldQKCfg81STfZkuBWKlnUUolYjkKNUkOEGf/CAMckg3BH/vbbS8wbC17pWG8EvB7D6RSUfDcKNQEoARgkAgE2AwQCBAEYMAQUBAW4lb/V1fEJebN5Z4UTmE5XrEowBRRv4WHQKIysaFy3b/zkFJmrjWlt7hgwC0Cl0ZjooRQMxjnO0liVKSiIwY+sl0S34aMXNR/PAU89ZqTlHJocegee54S4ajdVZsj1LMV6YWQA3GNw61sC79aFGA==",
|
||||
"2": "FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEERIK+dKrh7jNjamMZKV9Ir5gyKBMyce881JnXvjjdrJI3B3OjB6DbhqXvpgk96gZam85WxwGWrRlJEjVl2YQu6DcKNQEpARgkAmAwBBRv4WHQKIysaFy3b/zkFJmrjWlt7jAFFLsR9bzzqpjG9Z5aOkD8b8KMO7AQGDALQAK1q01Umn5ER39/84eai6HfZDKTNsGsuLyhIfpQa6XZQXenGbFDeenDLy8zv5NOLtwu8b44Zv0IrqONItfZqOMY",
|
||||
"254": 3
|
||||
}
|
||||
],
|
||||
"0/62/1": [
|
||||
{
|
||||
"1": "BNI+NL43G+mbJrQUfyNKwd2SHwAPJT3lgk8Ru5z0mzaXqXtfF8C4nYRSBypr7WVg2dx5dzDPTQQfiwGZQhav3nY=",
|
||||
"2": 4939,
|
||||
"3": 2,
|
||||
"4": 44,
|
||||
"5": "HA_test",
|
||||
"254": 3
|
||||
}
|
||||
],
|
||||
"0/62/2": 5,
|
||||
"0/62/3": 3,
|
||||
"0/62/4": [
|
||||
"FTABAQAkAgE3AyYUyakYCSYVj6gLsxgmBP2G+CskBQA3BiYUyakYCSYVj6gLsxgkBwEkCAEwCUEEgYwxrTB+tyiEGfrRwjlXTG34MiQtJXbg5Qqd0ohdRW7MfwYY7vZiX/0h9hI8MqUralFaVPcnghAP0MSJm1YrqTcKNQEpARgkAmAwBBS3BS9aJzt+p6i28Nj+trB2Uu+vdzAFFLcFL1onO36nqLbw2P62sHZS7693GDALQIrLt7Uq3S9HEe7apdzYSR+j3BLWNXSTLWD4YbrdyYLpm6xqHDV/NPARcIp4skZdtz91WwFBDfuS4jO5aVoER1sY",
|
||||
"FTABAQAkAgE3AycUQhmZbaIbYjokFQIYJgRWZLcqJAUANwYnFEIZmW2iG2I6JBUCGCQHASQIATAJQQT2AlKGW/kOMjqayzeO0md523/fuhrhGEUU91uQpTiKo0I7wcPpKnmrwfQNPX6g0kEQl+VGaXa3e22lzfu5Tzp0Nwo1ASkBGCQCYDAEFOOMk13ScMKuT2hlaydi1yEJnhTqMAUU44yTXdJwwq5PaGVrJ2LXIQmeFOoYMAtAv2jJd1qd5miXbYesH1XrJ+vgyY0hzGuZ78N6Jw4Cb1oN1sLSpA+PNM0u7+hsEqcSvvn2eSV8EaRR+hg5YQjHDxg=",
|
||||
"FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQUARgkBwEkCAEwCUEE0j40vjcb6ZsmtBR/I0rB3ZIfAA8lPeWCTxG7nPSbNpepe18XwLidhFIHKmvtZWDZ3Hl3MM9NBB+LAZlCFq/edjcKNQEpARgkAmAwBBS7EfW886qYxvWeWjpA/G/CjDuwEDAFFLsR9bzzqpjG9Z5aOkD8b8KMO7AQGDALQIgQgt5asUGXO0ZyTWWKdjAmBSoJAzRMuD4Z+tQYZanQ3s0OItL07MU2In6uyXhjNBfjJlRqon780lhjTsm2Y+8Y"
|
||||
],
|
||||
"0/62/5": 3,
|
||||
"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": 2,
|
||||
"0/63/65528": [2, 5],
|
||||
"0/63/65529": [0, 1, 3, 4],
|
||||
"0/63/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
|
||||
"2/3/0": 0,
|
||||
"2/3/1": 0,
|
||||
"2/3/65532": 0,
|
||||
"2/3/65533": 5,
|
||||
"2/3/65528": [],
|
||||
"2/3/65529": [0],
|
||||
"2/3/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
|
||||
"2/29/0": [
|
||||
{
|
||||
"0": 1293,
|
||||
"1": 1
|
||||
},
|
||||
{
|
||||
"0": 1296,
|
||||
"1": 1
|
||||
},
|
||||
{
|
||||
"0": 1295,
|
||||
"1": 1
|
||||
}
|
||||
],
|
||||
"2/29/1": [3, 29, 144, 145, 148, 152, 156, 158, 159],
|
||||
"2/29/2": [],
|
||||
"2/29/3": [],
|
||||
"2/29/65532": 0,
|
||||
"2/29/65533": 2,
|
||||
"2/29/65528": [],
|
||||
"2/29/65529": [],
|
||||
"2/29/65531": [0, 1, 2, 3, 65528, 65529, 65531, 65532, 65533],
|
||||
"2/144/0": 0,
|
||||
"2/144/1": 3,
|
||||
"2/144/2": [
|
||||
{
|
||||
"0": 5,
|
||||
"1": true,
|
||||
"2": -50000000,
|
||||
"3": 50000000,
|
||||
"4": [
|
||||
{
|
||||
"0": -50000000,
|
||||
"1": -10000000,
|
||||
"2": 5000,
|
||||
"3": 2000,
|
||||
"4": 3000
|
||||
},
|
||||
{
|
||||
"0": -9999999,
|
||||
"1": 9999999,
|
||||
"2": 1000,
|
||||
"3": 100,
|
||||
"4": 500
|
||||
},
|
||||
{
|
||||
"0": 10000000,
|
||||
"1": 50000000,
|
||||
"2": 5000,
|
||||
"3": 2000,
|
||||
"4": 3000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"0": 2,
|
||||
"1": true,
|
||||
"2": -100000,
|
||||
"3": 100000,
|
||||
"4": [
|
||||
{
|
||||
"0": -100000,
|
||||
"1": -5000,
|
||||
"2": 5000,
|
||||
"3": 2000,
|
||||
"4": 3000
|
||||
},
|
||||
{
|
||||
"0": -4999,
|
||||
"1": 4999,
|
||||
"2": 1000,
|
||||
"3": 100,
|
||||
"4": 500
|
||||
},
|
||||
{
|
||||
"0": 5000,
|
||||
"1": 100000,
|
||||
"2": 5000,
|
||||
"3": 2000,
|
||||
"4": 3000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"0": 1,
|
||||
"1": true,
|
||||
"2": -500000,
|
||||
"3": 500000,
|
||||
"4": [
|
||||
{
|
||||
"0": -500000,
|
||||
"1": -100000,
|
||||
"2": 5000,
|
||||
"3": 2000,
|
||||
"4": 3000
|
||||
},
|
||||
{
|
||||
"0": -99999,
|
||||
"1": 99999,
|
||||
"2": 1000,
|
||||
"3": 100,
|
||||
"4": 500
|
||||
},
|
||||
{
|
||||
"0": 100000,
|
||||
"1": 500000,
|
||||
"2": 5000,
|
||||
"3": 2000,
|
||||
"4": 3000
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2/144/3": [],
|
||||
"2/144/4": 230000,
|
||||
"2/144/5": 100,
|
||||
"2/144/6": null,
|
||||
"2/144/7": null,
|
||||
"2/144/8": 23000,
|
||||
"2/144/9": null,
|
||||
"2/144/10": null,
|
||||
"2/144/11": null,
|
||||
"2/144/12": null,
|
||||
"2/144/13": null,
|
||||
"2/144/14": 50,
|
||||
"2/144/15": [
|
||||
{
|
||||
"0": 1,
|
||||
"1": 100000
|
||||
}
|
||||
],
|
||||
"2/144/16": [
|
||||
{
|
||||
"0": 1,
|
||||
"1": 100000
|
||||
}
|
||||
],
|
||||
"2/144/17": null,
|
||||
"2/144/18": null,
|
||||
"2/144/65532": 31,
|
||||
"2/144/65533": 1,
|
||||
"2/144/65528": [],
|
||||
"2/144/65529": [],
|
||||
"2/144/65531": [
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 65528,
|
||||
65529, 65531, 65532, 65533
|
||||
],
|
||||
"2/145/0": {
|
||||
"0": 14,
|
||||
"1": true,
|
||||
"2": 0,
|
||||
"3": 1000000000000000,
|
||||
"4": [
|
||||
{
|
||||
"0": 0,
|
||||
"1": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"2/145/1": null,
|
||||
"2/145/2": null,
|
||||
"2/145/3": null,
|
||||
"2/145/4": null,
|
||||
"2/145/5": {
|
||||
"0": 0,
|
||||
"1": 0,
|
||||
"2": 0,
|
||||
"3": 0
|
||||
},
|
||||
"2/145/65532": 15,
|
||||
"2/145/65533": 1,
|
||||
"2/145/65528": [],
|
||||
"2/145/65529": [],
|
||||
"2/145/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533],
|
||||
"2/148/0": 1,
|
||||
"2/148/1": 0,
|
||||
"2/148/2": 200,
|
||||
"2/148/3": 4000000,
|
||||
"2/148/4": 40,
|
||||
"2/148/5": 0,
|
||||
"2/148/65532": 3,
|
||||
"2/148/65533": 2,
|
||||
"2/148/65528": [],
|
||||
"2/148/65529": [0, 1],
|
||||
"2/148/65531": [0, 1, 2, 3, 4, 5, 65528, 65529, 65531, 65532, 65533],
|
||||
"2/152/0": 2,
|
||||
"2/152/1": false,
|
||||
"2/152/2": 1,
|
||||
"2/152/3": 1200000,
|
||||
"2/152/4": 7600000,
|
||||
"2/152/5": null,
|
||||
"2/152/6": null,
|
||||
"2/152/7": 0,
|
||||
"2/152/65532": 123,
|
||||
"2/152/65533": 4,
|
||||
"2/152/65528": [],
|
||||
"2/152/65529": [0, 1, 2, 3, 4, 5, 6, 7],
|
||||
"2/152/65531": [0, 1, 2, 3, 4, 5, 6, 7, 65528, 65529, 65531, 65532, 65533],
|
||||
"2/156/65532": 1,
|
||||
"2/156/65533": 1,
|
||||
"2/156/65528": [],
|
||||
"2/156/65529": [],
|
||||
"2/156/65531": [65528, 65529, 65531, 65532, 65533],
|
||||
"2/158/0": [
|
||||
{
|
||||
"0": "Off",
|
||||
"1": 0,
|
||||
"2": [
|
||||
{
|
||||
"1": 16384
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"0": "Manual",
|
||||
"1": 1,
|
||||
"2": [
|
||||
{
|
||||
"1": 16385
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"0": "Timed",
|
||||
"1": 2,
|
||||
"2": [
|
||||
{
|
||||
"1": 16386
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2/158/1": 1,
|
||||
"2/158/65532": 0,
|
||||
"2/158/65533": 1,
|
||||
"2/158/65528": [1],
|
||||
"2/158/65529": [0],
|
||||
"2/158/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
|
||||
"2/159/0": [
|
||||
{
|
||||
"0": "No energy management (forecast only)",
|
||||
"1": 0,
|
||||
"2": [
|
||||
{
|
||||
"1": 16384
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"0": "Device optimizes (no local or grid control)",
|
||||
"1": 1,
|
||||
"2": [
|
||||
{
|
||||
"1": 16385
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"0": "Optimized within building",
|
||||
"1": 2,
|
||||
"2": [
|
||||
{
|
||||
"1": 16386
|
||||
},
|
||||
{
|
||||
"1": 16385
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"0": "Optimized for grid",
|
||||
"1": 3,
|
||||
"2": [
|
||||
{
|
||||
"1": 16385
|
||||
},
|
||||
{
|
||||
"1": 16387
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"0": "Optimized for grid and building",
|
||||
"1": 4,
|
||||
"2": [
|
||||
{
|
||||
"1": 16386
|
||||
},
|
||||
{
|
||||
"1": 16385
|
||||
},
|
||||
{
|
||||
"1": 16387
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2/159/1": 0,
|
||||
"2/159/65532": 0,
|
||||
"2/159/65533": 2,
|
||||
"2/159/65528": [1],
|
||||
"2/159/65529": [0],
|
||||
"2/159/65531": [0, 1, 65528, 65529, 65531, 65532, 65533],
|
||||
"2/513/0": 5000,
|
||||
"2/513/3": 4000,
|
||||
"2/513/4": 6500,
|
||||
"2/513/18": 6500,
|
||||
"2/513/21": 4000,
|
||||
"2/513/22": 6500,
|
||||
"2/513/27": 2,
|
||||
"2/513/28": 4,
|
||||
"2/513/65532": 1,
|
||||
"2/513/65533": 7,
|
||||
"2/513/65528": [],
|
||||
"2/513/65529": [0],
|
||||
"2/513/65531": [0, 27, 28, 65528, 65529, 65531, 65532, 65533]
|
||||
},
|
||||
"2/513/0": 5000,
|
||||
"2/513/3": 4000,
|
||||
"2/513/4": 6500,
|
||||
"2/513/18": 6500,
|
||||
"2/513/21": 4000,
|
||||
"2/513/22": 6500,
|
||||
"2/513/27": 2,
|
||||
"2/513/28": 4,
|
||||
"2/513/65532": 1,
|
||||
"2/513/65533": 7,
|
||||
"2/513/65528": [],
|
||||
"2/513/65529": [0],
|
||||
"2/513/65531": [0, 27, 28, 65528, 65529, 65531, 65532, 65533],
|
||||
"attribute_subscriptions": []
|
||||
}
|
@ -527,6 +527,53 @@
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensors[silabs_water_heater][binary_sensor.water_heater_boost_state-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'binary_sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'binary_sensor.water_heater_boost_state',
|
||||
'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': 'Boost state',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'boost_state',
|
||||
'unique_id': '00000000000004D2-0000000000000019-MatterNodeDevice-2-WaterHeaterManagementBoostStateSensor-148-5',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensors[silabs_water_heater][binary_sensor.water_heater_boost_state-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Water Heater Boost state',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'binary_sensor.water_heater_boost_state',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_binary_sensors[smoke_detector][binary_sensor.smoke_sensor_battery_alert-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
@ -1839,6 +1839,68 @@
|
||||
'state': 'Colors',
|
||||
})
|
||||
# ---
|
||||
# name: test_selects[silabs_water_heater][select.water_heater_energy_management_mode-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'options': list([
|
||||
'No energy management (forecast only)',
|
||||
'Device optimizes (no local or grid control)',
|
||||
'Optimized within building',
|
||||
'Optimized for grid',
|
||||
'Optimized for grid and building',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'select',
|
||||
'entity_category': None,
|
||||
'entity_id': 'select.water_heater_energy_management_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': 'Energy management mode',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'device_energy_management_mode',
|
||||
'unique_id': '00000000000004D2-0000000000000019-MatterNodeDevice-2-MatterDeviceEnergyManagementMode-159-1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_selects[silabs_water_heater][select.water_heater_energy_management_mode-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Water Heater Energy management mode',
|
||||
'options': list([
|
||||
'No energy management (forecast only)',
|
||||
'Device optimizes (no local or grid control)',
|
||||
'Optimized within building',
|
||||
'Optimized for grid',
|
||||
'Optimized for grid and building',
|
||||
]),
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'select.water_heater_energy_management_mode',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'No energy management (forecast only)',
|
||||
})
|
||||
# ---
|
||||
# name: test_selects[switch_unit][select.mock_switchunit_power_on_behavior_on_startup-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
@ -3535,6 +3535,341 @@
|
||||
'state': '120.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_current-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.water_heater_current',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 2,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfElectricCurrent.AMPERE: 'A'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.CURRENT: 'current'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Current',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00000000000004D2-0000000000000019-MatterNodeDevice-2-ElectricalPowerMeasurementActiveCurrent-144-5',
|
||||
'unit_of_measurement': <UnitOfElectricCurrent.AMPERE: 'A'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_current-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'current',
|
||||
'friendly_name': 'Water Heater Current',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfElectricCurrent.AMPERE: 'A'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.water_heater_current',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '0.1',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_hot_water_level-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.water_heater_hot_water_level',
|
||||
'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': 'Hot water level',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'tank_percentage',
|
||||
'unique_id': '00000000000004D2-0000000000000019-MatterNodeDevice-2-WaterHeaterManagementTankPercentage-148-4',
|
||||
'unit_of_measurement': '%',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_hot_water_level-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Water Heater Hot water level',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': '%',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.water_heater_hot_water_level',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '40',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_power-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.water_heater_power',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 2,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfPower.WATT: 'W'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Power',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00000000000004D2-0000000000000019-MatterNodeDevice-2-ElectricalPowerMeasurementWatt-144-8',
|
||||
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_power-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'power',
|
||||
'friendly_name': 'Water Heater Power',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.water_heater_power',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '23.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_required_heating_energy-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.water_heater_required_heating_energy',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 3,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.ENERGY: 'energy'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Required heating energy',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'estimated_heat_required',
|
||||
'unique_id': '00000000000004D2-0000000000000019-MatterNodeDevice-2-WaterHeaterManagementEstimatedHeatRequired-148-3',
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_required_heating_energy-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'energy',
|
||||
'friendly_name': 'Water Heater Required heating energy',
|
||||
'state_class': <SensorStateClass.TOTAL: 'total'>,
|
||||
'unit_of_measurement': <UnitOfEnergy.KILO_WATT_HOUR: 'kWh'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.water_heater_required_heating_energy',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '4.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_tank_volume-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': None,
|
||||
'entity_id': 'sensor.water_heater_tank_volume',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.VOLUME_STORAGE: 'volume_storage'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Tank volume',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': 'tank_volume',
|
||||
'unique_id': '00000000000004D2-0000000000000019-MatterNodeDevice-2-WaterHeaterManagementTankVolume-148-2',
|
||||
'unit_of_measurement': <UnitOfVolume.LITERS: 'L'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_tank_volume-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'volume_storage',
|
||||
'friendly_name': 'Water Heater Tank volume',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfVolume.LITERS: 'L'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.water_heater_tank_volume',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '200',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_voltage-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'sensor',
|
||||
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
|
||||
'entity_id': 'sensor.water_heater_voltage',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
'sensor': dict({
|
||||
'suggested_display_precision': 0,
|
||||
}),
|
||||
'sensor.private': dict({
|
||||
'suggested_unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
|
||||
}),
|
||||
}),
|
||||
'original_device_class': <SensorDeviceClass.VOLTAGE: 'voltage'>,
|
||||
'original_icon': None,
|
||||
'original_name': 'Voltage',
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '00000000000004D2-0000000000000019-MatterNodeDevice-2-ElectricalPowerMeasurementVoltage-144-4',
|
||||
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[silabs_water_heater][sensor.water_heater_voltage-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'device_class': 'voltage',
|
||||
'friendly_name': 'Water Heater Voltage',
|
||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||
'unit_of_measurement': <UnitOfElectricPotential.VOLT: 'V'>,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'sensor.water_heater_voltage',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': '230.0',
|
||||
})
|
||||
# ---
|
||||
# name: test_sensors[smoke_detector][sensor.smoke_sensor_battery-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
69
tests/components/matter/snapshots/test_water_heater.ambr
Normal file
69
tests/components/matter/snapshots/test_water_heater.ambr
Normal file
@ -0,0 +1,69 @@
|
||||
# serializer version: 1
|
||||
# name: test_water_heaters[silabs_water_heater][water_heater.water_heater-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'max_temp': 65,
|
||||
'min_temp': 40,
|
||||
'operation_list': list([
|
||||
'eco',
|
||||
'high_demand',
|
||||
'off',
|
||||
]),
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'water_heater',
|
||||
'entity_category': None,
|
||||
'entity_id': 'water_heater.water_heater',
|
||||
'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': None,
|
||||
'platform': 'matter',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <WaterHeaterEntityFeature: 11>,
|
||||
'translation_key': None,
|
||||
'unique_id': '00000000000004D2-0000000000000019-MatterNodeDevice-2-MatterWaterHeater-513-18',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_water_heaters[silabs_water_heater][water_heater.water_heater-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_temperature': 50,
|
||||
'friendly_name': 'Water Heater',
|
||||
'max_temp': 65,
|
||||
'min_temp': 40,
|
||||
'operation_list': list([
|
||||
'eco',
|
||||
'high_demand',
|
||||
'off',
|
||||
]),
|
||||
'operation_mode': 'eco',
|
||||
'supported_features': <WaterHeaterEntityFeature: 11>,
|
||||
'target_temp_high': None,
|
||||
'target_temp_low': None,
|
||||
'temperature': 65,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'water_heater.water_heater',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'eco',
|
||||
})
|
||||
# ---
|
@ -197,3 +197,23 @@ async def test_evse_sensor(
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == "off"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["silabs_water_heater"])
|
||||
async def test_water_heater(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test water heater sensor."""
|
||||
# BoostState
|
||||
state = hass.states.get("binary_sensor.water_heater_boost_state")
|
||||
assert state
|
||||
assert state.state == "off"
|
||||
|
||||
set_node_attribute(matter_node, 2, 148, 5, 1)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get("binary_sensor.water_heater_boost_state")
|
||||
assert state
|
||||
assert state.state == "on"
|
||||
|
@ -467,3 +467,47 @@ async def test_evse_sensor(
|
||||
state = hass.states.get("sensor.evse_user_max_charge_current")
|
||||
assert state
|
||||
assert state.state == "63.0"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["silabs_water_heater"])
|
||||
async def test_water_heater(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test water heater sensor."""
|
||||
# TankVolume
|
||||
state = hass.states.get("sensor.water_heater_tank_volume")
|
||||
assert state
|
||||
assert state.state == "200"
|
||||
|
||||
set_node_attribute(matter_node, 2, 148, 2, 100)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get("sensor.water_heater_tank_volume")
|
||||
assert state
|
||||
assert state.state == "100"
|
||||
|
||||
# EstimatedHeatRequired
|
||||
state = hass.states.get("sensor.water_heater_required_heating_energy")
|
||||
assert state
|
||||
assert state.state == "4.0"
|
||||
|
||||
set_node_attribute(matter_node, 2, 148, 3, 1000000)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get("sensor.water_heater_required_heating_energy")
|
||||
assert state
|
||||
assert state.state == "1.0"
|
||||
|
||||
# TankPercentage
|
||||
state = hass.states.get("sensor.water_heater_hot_water_level")
|
||||
assert state
|
||||
assert state.state == "40"
|
||||
|
||||
set_node_attribute(matter_node, 2, 148, 4, 50)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get("sensor.water_heater_hot_water_level")
|
||||
assert state
|
||||
assert state.state == "50"
|
||||
|
246
tests/components/matter/test_water_heater.py
Normal file
246
tests/components/matter/test_water_heater.py
Normal file
@ -0,0 +1,246 @@
|
||||
"""Test Matter sensors."""
|
||||
|
||||
from unittest.mock import MagicMock, call
|
||||
|
||||
from chip.clusters import Objects as clusters
|
||||
from matter_server.client.models.node import MatterNode
|
||||
from matter_server.common.helpers.util import create_attribute_path_from_attribute
|
||||
import pytest
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.water_heater import (
|
||||
STATE_ECO,
|
||||
STATE_HIGH_DEMAND,
|
||||
STATE_OFF,
|
||||
WaterHeaterEntityFeature,
|
||||
)
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .common import (
|
||||
set_node_attribute,
|
||||
snapshot_matter_entities,
|
||||
trigger_subscription_callback,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("matter_devices")
|
||||
async def test_water_heaters(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test water heaters."""
|
||||
snapshot_matter_entities(hass, entity_registry, snapshot, Platform.WATER_HEATER)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["silabs_water_heater"])
|
||||
async def test_water_heater(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test water heater entity."""
|
||||
state = hass.states.get("water_heater.water_heater")
|
||||
assert state
|
||||
assert state.attributes["min_temp"] == 40
|
||||
assert state.attributes["max_temp"] == 65
|
||||
assert state.attributes["temperature"] == 65
|
||||
assert state.attributes["operation_list"] == ["eco", "high_demand", "off"]
|
||||
assert state.state == STATE_ECO
|
||||
|
||||
# test supported features correctly parsed
|
||||
mask = (
|
||||
WaterHeaterEntityFeature.TARGET_TEMPERATURE
|
||||
| WaterHeaterEntityFeature.ON_OFF
|
||||
| WaterHeaterEntityFeature.OPERATION_MODE
|
||||
)
|
||||
assert state.attributes["supported_features"] & mask == mask
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["silabs_water_heater"])
|
||||
async def test_water_heater_set_temperature(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test water_heater set temperature service."""
|
||||
# test single-setpoint temperature adjustment when eco mode is active
|
||||
state = hass.states.get("water_heater.water_heater")
|
||||
|
||||
assert state
|
||||
assert state.state == STATE_ECO
|
||||
await hass.services.async_call(
|
||||
"water_heater",
|
||||
"set_temperature",
|
||||
{
|
||||
"entity_id": "water_heater.water_heater",
|
||||
"temperature": 52,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert matter_client.write_attribute.call_count == 1
|
||||
assert matter_client.write_attribute.call_args == call(
|
||||
node_id=matter_node.node_id,
|
||||
attribute_path="2/513/18",
|
||||
value=5200,
|
||||
)
|
||||
matter_client.write_attribute.reset_mock()
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["silabs_water_heater"])
|
||||
@pytest.mark.parametrize(
|
||||
("operation_mode", "matter_attribute_value"),
|
||||
[(STATE_OFF, 0), (STATE_ECO, 4), (STATE_HIGH_DEMAND, 4)],
|
||||
)
|
||||
async def test_water_heater_set_operation_mode(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
operation_mode: str,
|
||||
matter_attribute_value: int,
|
||||
) -> None:
|
||||
"""Test water_heater set operation mode service."""
|
||||
state = hass.states.get("water_heater.water_heater")
|
||||
assert state
|
||||
|
||||
# test change mode to each operation_mode
|
||||
await hass.services.async_call(
|
||||
"water_heater",
|
||||
"set_operation_mode",
|
||||
{
|
||||
"entity_id": "water_heater.water_heater",
|
||||
"operation_mode": operation_mode,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert matter_client.write_attribute.call_count == 1
|
||||
assert matter_client.write_attribute.call_args == call(
|
||||
node_id=matter_node.node_id,
|
||||
attribute_path=create_attribute_path_from_attribute(
|
||||
endpoint_id=2,
|
||||
attribute=clusters.Thermostat.Attributes.SystemMode,
|
||||
),
|
||||
value=matter_attribute_value,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["silabs_water_heater"])
|
||||
async def test_water_heater_boostmode(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test water_heater set operation mode service."""
|
||||
# Boost 1h (3600s)
|
||||
boost_info: type[
|
||||
clusters.WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct
|
||||
] = clusters.WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct(duration=3600)
|
||||
state = hass.states.get("water_heater.water_heater")
|
||||
assert state
|
||||
|
||||
# enable water_heater boostmode
|
||||
await hass.services.async_call(
|
||||
"water_heater",
|
||||
"set_operation_mode",
|
||||
{
|
||||
"entity_id": "water_heater.water_heater",
|
||||
"operation_mode": STATE_HIGH_DEMAND,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert matter_client.write_attribute.call_count == 1
|
||||
assert matter_client.write_attribute.call_args == call(
|
||||
node_id=matter_node.node_id,
|
||||
attribute_path=create_attribute_path_from_attribute(
|
||||
endpoint_id=2,
|
||||
attribute=clusters.Thermostat.Attributes.SystemMode,
|
||||
),
|
||||
value=4,
|
||||
)
|
||||
assert matter_client.send_device_command.call_count == 1
|
||||
assert matter_client.send_device_command.call_args == call(
|
||||
node_id=matter_node.node_id,
|
||||
endpoint_id=2,
|
||||
command=clusters.WaterHeaterManagement.Commands.Boost(boostInfo=boost_info),
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["silabs_water_heater"])
|
||||
async def test_update_from_water_heater(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test enable boost from water heater device side."""
|
||||
entity_id = "water_heater.water_heater"
|
||||
|
||||
# confirm initial BoostState (as stored in the fixture)
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
|
||||
# confirm thermostat state is 'high_demand' by setting the BoostState to 1
|
||||
set_node_attribute(matter_node, 2, 148, 5, 1)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == STATE_HIGH_DEMAND
|
||||
|
||||
# confirm thermostat state is 'eco' by setting the BoostState to 0
|
||||
set_node_attribute(matter_node, 2, 148, 5, 0)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
state = hass.states.get(entity_id)
|
||||
assert state
|
||||
assert state.state == STATE_ECO
|
||||
|
||||
|
||||
@pytest.mark.parametrize("node_fixture", ["silabs_water_heater"])
|
||||
async def test_water_heater_turn_on_off(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
matter_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test water_heater set turn_off/turn_on."""
|
||||
state = hass.states.get("water_heater.water_heater")
|
||||
assert state
|
||||
|
||||
# turn_off water_heater
|
||||
await hass.services.async_call(
|
||||
"water_heater",
|
||||
"turn_off",
|
||||
{
|
||||
"entity_id": "water_heater.water_heater",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert matter_client.write_attribute.call_count == 1
|
||||
assert matter_client.write_attribute.call_args == call(
|
||||
node_id=matter_node.node_id,
|
||||
attribute_path=create_attribute_path_from_attribute(
|
||||
endpoint_id=2,
|
||||
attribute=clusters.Thermostat.Attributes.SystemMode,
|
||||
),
|
||||
value=0,
|
||||
)
|
||||
|
||||
matter_client.write_attribute.reset_mock()
|
||||
|
||||
# turn_on water_heater
|
||||
await hass.services.async_call(
|
||||
"water_heater",
|
||||
"turn_on",
|
||||
{
|
||||
"entity_id": "water_heater.water_heater",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert matter_client.write_attribute.call_count == 1
|
||||
assert matter_client.write_attribute.call_args == call(
|
||||
node_id=matter_node.node_id,
|
||||
attribute_path=create_attribute_path_from_attribute(
|
||||
endpoint_id=2,
|
||||
attribute=clusters.Thermostat.Attributes.SystemMode,
|
||||
),
|
||||
value=4,
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user