-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Matter TemperatureNumber feature from TemperatureControl cluster #128838
base: dev
Are you sure you want to change the base?
Changes from all commits
5010f44
ab9c7a0
3dcfd71
41615a0
3713603
be1cd73
1bc8a01
ae7d853
008b5b9
ded711e
d7aee69
70887f9
b857efe
46c18ea
a9af663
22a4c18
2acd72e
43ef56c
564821d
7a68c68
d5c4f1b
68bf4df
ddca2d4
e1c332d
f0b6716
8297fd4
35183bc
fefe07a
bbee0ed
d2d4f39
59d1391
ad5de14
08fa381
3e59c9b
08c9b4d
b8432cb
72684c2
f26de81
b449484
8d0441b
0876e57
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -157,6 +157,7 @@ | |
SystemModeEnum = clusters.Thermostat.Enums.SystemModeEnum | ||
ControlSequenceEnum = clusters.Thermostat.Enums.ControlSequenceOfOperationEnum | ||
ThermostatFeature = clusters.Thermostat.Bitmaps.Feature | ||
TemperatureControlFeature = clusters.TemperatureControl.Bitmaps.Feature | ||
|
||
|
||
class ThermostatRunningState(IntEnum): | ||
|
@@ -420,6 +421,91 @@ def _get_temperature_in_degrees( | |
return None | ||
|
||
|
||
class MatterTemperatureControlClimate(MatterEntity, ClimateEntity): | ||
"""Representation of a climate entity from the Matter TemperatureControl cluster.""" | ||
|
||
_attr_temperature_unit: str = UnitOfTemperature.CELSIUS | ||
_attr_hvac_mode: HVACMode = HVACMode.HEAT_COOL | ||
_attr_hvac_modes: list[HVACMode] = [HVACMode.HEAT_COOL] | ||
_attr_target_temperature_step: float | None | ||
_feature_map: int | None = None | ||
|
||
_platform_translation_key = "thermostat" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the thing I'm in doubt about. We could choose to define a translation key for "Temperature Control" instead of the default Thermostat label. What do you think ? |
||
|
||
async def async_set_temperature(self, **kwargs: Any) -> None: | ||
"""Set new target temperature.""" | ||
target_hvac_mode: HVACMode | None = kwargs.get(ATTR_HVAC_MODE) | ||
target_temperature: float | None = kwargs.get(ATTR_TEMPERATURE) | ||
|
||
if target_hvac_mode is not None: | ||
await self.async_set_hvac_mode(target_hvac_mode) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add a small test case where the mode is also set in the set temperature |
||
|
||
if target_temperature is not None: | ||
# single setpoint control | ||
if self.target_temperature != target_temperature: | ||
await self.matter_client.send_device_command( | ||
node_id=self._endpoint.node.node_id, | ||
endpoint_id=self._endpoint.endpoint_id, | ||
command=clusters.TemperatureControl.Commands.SetTemperature( | ||
targetTemperature=int( | ||
target_temperature * TEMPERATURE_SCALING_FACTOR | ||
) | ||
), | ||
) | ||
return | ||
|
||
@callback | ||
def _update_from_device(self) -> None: | ||
"""Update from device.""" | ||
self._calculate_features() | ||
self._attr_hvac_action = None | ||
# update target_temperature | ||
self._attr_target_temperature = self._get_temperature_in_degrees( | ||
clusters.TemperatureControl.Attributes.TemperatureSetpoint | ||
) | ||
# update min_temp | ||
attribute = clusters.TemperatureControl.Attributes.MinTemperature | ||
if (value := self._get_temperature_in_degrees(attribute)) is not None: | ||
self._attr_min_temp = value | ||
# update max_temp | ||
attribute = clusters.TemperatureControl.Attributes.MaxTemperature | ||
if (value := self._get_temperature_in_degrees(attribute)) is not None: | ||
self._attr_max_temp = value | ||
|
||
@callback | ||
def _calculate_features( | ||
self, | ||
) -> None: | ||
"""Calculate features for HA Thermostat platform from Matter FeatureMap.""" | ||
feature_map = int( | ||
self.get_matter_attribute_value( | ||
clusters.TemperatureControl.Attributes.FeatureMap | ||
) | ||
) | ||
# NOTE: the featuremap can dynamically change, so we need to update the | ||
# supported features if the featuremap changes. | ||
# work out supported features and presets from matter featuremap | ||
if self._feature_map == feature_map: | ||
return | ||
self._feature_map = feature_map | ||
lboue marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self._attr_hvac_modes: list[HVACMode] = [HVACMode.HEAT_COOL] | ||
if feature_map & TemperatureControlFeature.kTemperatureNumber: | ||
self._attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE | ||
if feature_map & TemperatureControlFeature.kTemperatureStep: | ||
self._attr_target_temperature_step = self._get_temperature_in_degrees( | ||
clusters.TemperatureControl.Attributes.Step | ||
) | ||
|
||
@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): | ||
return float(value) / TEMPERATURE_SCALING_FACTOR | ||
return None | ||
|
||
|
||
# Discovery schema(s) to map Matter Attributes to HA entities | ||
DISCOVERY_SCHEMAS = [ | ||
MatterDiscoverySchema( | ||
|
@@ -446,4 +532,19 @@ def _get_temperature_in_degrees( | |
), | ||
device_type=(device_types.Thermostat, device_types.RoomAirConditioner), | ||
), | ||
MatterDiscoverySchema( | ||
platform=Platform.CLIMATE, | ||
entity_description=ClimateEntityDescription( | ||
key="MatterTemperatureControl", | ||
name=None, | ||
), | ||
entity_class=MatterTemperatureControlClimate, | ||
required_attributes=( | ||
clusters.TemperatureControl.Attributes.TemperatureSetpoint, | ||
clusters.TemperatureControl.Attributes.FeatureMap, | ||
lboue marked this conversation as resolved.
Show resolved
Hide resolved
|
||
clusters.TemperatureControl.Attributes.MinTemperature, | ||
clusters.TemperatureControl.Attributes.MaxTemperature, | ||
), | ||
optional_attributes=(clusters.TemperatureControl.Attributes.Step,), | ||
), | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is already defined in the base model, no need to repeat here