Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion homeassistant/components/matter/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,10 @@ def _calculate_features(
return
self._feature_map = feature_map
self._attr_supported_features = FanEntityFeature(0)
# PercentSetting is always a mandatory attribute of the FanControl cluster,
# so percentage-based speed control is always available.
self._attr_supported_features |= FanEntityFeature.SET_SPEED
if feature_map & FanControlFeature.kMultiSpeed:
self._attr_supported_features |= FanEntityFeature.SET_SPEED
self._attr_speed_count = int(
self.get_matter_attribute_value(clusters.FanControl.Attributes.SpeedMax)
)
Comment on lines 255 to 265
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Expand Down
18 changes: 12 additions & 6 deletions tests/components/matter/snapshots/test_fan.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': <FanEntityFeature: 56>,
'supported_features': <FanEntityFeature: 57>,
'translation_key': 'fan',
'unique_id': '00000000000004D2-0000000000000004-MatterNodeDevice-1-MatterFan-514-0',
'unit_of_measurement': None,
Expand All @@ -47,14 +47,16 @@
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Longan link HVAC',
'percentage': 0,
'percentage_step': 1.0,
'preset_mode': None,
'preset_modes': list([
'low',
'medium',
'high',
'auto',
]),
'supported_features': <FanEntityFeature: 56>,
'supported_features': <FanEntityFeature: 57>,
}),
'context': <ANY>,
'entity_id': 'fan.longan_link_hvac',
Expand Down Expand Up @@ -174,7 +176,7 @@
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': <FanEntityFeature: 56>,
'supported_features': <FanEntityFeature: 57>,
'translation_key': 'fan',
'unique_id': '00000000000004D2-0000000000000049-MatterNodeDevice-1-MatterFan-514-0',
'unit_of_measurement': None,
Expand All @@ -184,13 +186,15 @@
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Mock Extractor hood',
'percentage': 0,
'percentage_step': 1.0,
'preset_mode': None,
'preset_modes': list([
'low',
'medium',
'high',
]),
'supported_features': <FanEntityFeature: 56>,
'supported_features': <FanEntityFeature: 57>,
}),
'context': <ANY>,
'entity_id': 'fan.mock_extractor_hood',
Expand Down Expand Up @@ -450,7 +454,7 @@
'platform': 'matter',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': <FanEntityFeature: 56>,
'supported_features': <FanEntityFeature: 57>,
'translation_key': 'fan',
'unique_id': '00000000000004D2-0000000000000072-MatterNodeDevice-1-MatterFan-514-0',
'unit_of_measurement': None,
Expand All @@ -460,13 +464,15 @@
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'SL-RangeHood',
'percentage': 0,
'percentage_step': 1.0,
'preset_mode': None,
'preset_modes': list([
'low',
'medium',
'high',
]),
'supported_features': <FanEntityFeature: 56>,
'supported_features': <FanEntityFeature: 57>,
}),
'context': <ANY>,
'entity_id': 'fan.sl_rangehood',
Expand Down
32 changes: 32 additions & 0 deletions tests/components/matter/test_fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
DOMAIN as FAN_DOMAIN,
SERVICE_OSCILLATE,
SERVICE_SET_DIRECTION,
SERVICE_SET_PERCENTAGE,
FanEntityFeature,
)
Comment thread
lboue marked this conversation as resolved.
from homeassistant.const import (
Expand Down Expand Up @@ -441,3 +442,34 @@ async def test_fan_features(
state = hass.states.get(entity_id)
assert state
assert state.attributes["preset_modes"] == preset_modes


@pytest.mark.parametrize("node_fixture", ["silabs_range_hood"])
async def test_fan_set_percentage_without_multispeed(
hass: HomeAssistant,
matter_client: MagicMock,
matter_node: MatterNode,
) -> None:
"""Test percentage control on a fan without the MultiSpeed feature.

PercentSetting is mandatory in the FanControl cluster regardless of features,
so SET_SPEED must be available and write to PercentSetting (attribute 0x0002).
"""
entity_id = "fan.sl_rangehood"
state = hass.states.get(entity_id)
assert state
assert state.attributes["supported_features"] & FanEntityFeature.SET_SPEED
assert state.attributes["percentage_step"] == 1.0

await hass.services.async_call(
FAN_DOMAIN,
SERVICE_SET_PERCENTAGE,
{ATTR_ENTITY_ID: entity_id, ATTR_PERCENTAGE: 75},
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="1/514/2",
value=75,
)
Loading