1 """Matter Fan platform support."""
3 from __future__
import annotations
5 from typing
import TYPE_CHECKING, Any
7 from chip.clusters
import Objects
as clusters
8 from matter_server.common.helpers.util
import create_attribute_path_from_attribute
22 from .entity
import MatterEntity
23 from .helpers
import get_matter
24 from .models
import MatterDiscoverySchema
26 FanControlFeature = clusters.FanControl.Bitmaps.Feature
27 WindBitmap = clusters.FanControl.Bitmaps.WindBitmap
28 FanModeSequenceEnum = clusters.FanControl.Enums.FanModeSequenceEnum
31 PRESET_MEDIUM =
"medium"
35 PRESET_LOW: clusters.FanControl.Enums.FanModeEnum.kLow,
36 PRESET_MEDIUM: clusters.FanControl.Enums.FanModeEnum.kMedium,
37 PRESET_HIGH: clusters.FanControl.Enums.FanModeEnum.kHigh,
38 PRESET_AUTO: clusters.FanControl.Enums.FanModeEnum.kAuto,
40 FAN_MODE_MAP_REVERSE = {v: k
for k, v
in FAN_MODE_MAP.items()}
42 PRESET_NATURAL_WIND =
"natural_wind"
43 PRESET_SLEEP_WIND =
"sleep_wind"
48 config_entry: ConfigEntry,
49 async_add_entities: AddEntitiesCallback,
51 """Set up Matter fan from Config Entry."""
53 matter.register_platform_handler(Platform.FAN, async_add_entities)
57 """Representation of a Matter fan."""
59 _last_known_preset_mode: str |
None =
None
60 _last_known_percentage: int = 0
61 _enable_turn_on_off_backwards_compatibility =
False
62 _feature_map: int |
None =
None
63 _platform_translation_key =
"fan"
67 percentage: int |
None =
None,
68 preset_mode: str |
None =
None,
71 """Turn on the fan."""
72 if percentage
is None and preset_mode
is None:
87 if percentage
is not None:
92 assert preset_mode
is not None
98 if self.
_attr_preset_mode_attr_preset_mode
in [PRESET_NATURAL_WIND, PRESET_SLEEP_WIND]:
101 node_id=self.
_endpoint_endpoint.node.node_id,
102 attribute_path=create_attribute_path_from_attribute(
104 clusters.FanControl.Attributes.FanMode,
106 value=clusters.FanControl.Enums.FanModeEnum.kOff,
110 """Set the speed of the fan, as a percentage."""
112 node_id=self.
_endpoint_endpoint.node.node_id,
113 attribute_path=create_attribute_path_from_attribute(
115 clusters.FanControl.Attributes.PercentSetting,
121 """Set new preset mode."""
123 if preset_mode
in [PRESET_NATURAL_WIND, PRESET_SLEEP_WIND]:
128 if self.
_attr_preset_mode_attr_preset_mode
in [PRESET_NATURAL_WIND, PRESET_SLEEP_WIND]:
132 node_id=self.
_endpoint_endpoint.node.node_id,
133 attribute_path=create_attribute_path_from_attribute(
135 clusters.FanControl.Attributes.FanMode,
137 value=FAN_MODE_MAP[preset_mode],
141 """Oscillate the fan."""
143 node_id=self.
_endpoint_endpoint.node.node_id,
144 attribute_path=create_attribute_path_from_attribute(
146 clusters.FanControl.Attributes.RockSetting,
149 clusters.FanControl.Attributes.RockSupport
156 """Set the direction of the fan."""
158 node_id=self.
_endpoint_endpoint.node.node_id,
159 attribute_path=create_attribute_path_from_attribute(
161 clusters.FanControl.Attributes.AirflowDirection,
163 value=clusters.FanControl.Enums.AirflowDirectionEnum.kReverse
164 if direction == DIRECTION_REVERSE
165 else clusters.FanControl.Enums.AirflowDirectionEnum.kForward,
170 if wind_mode == PRESET_NATURAL_WIND:
171 wind_setting = WindBitmap.kNaturalWind
172 elif wind_mode == PRESET_SLEEP_WIND:
173 wind_setting = WindBitmap.kSleepWind
177 node_id=self.
_endpoint_endpoint.node.node_id,
178 attribute_path=create_attribute_path_from_attribute(
180 clusters.FanControl.Attributes.WindSetting,
187 """Update from device."""
199 clusters.FanControl.Attributes.AirflowDirection
204 == clusters.FanControl.Enums.AirflowDirectionEnum.kReverse
205 else DIRECTION_FORWARD
210 clusters.FanControl.Attributes.RockSetting
217 clusters.FanControl.Attributes.PercentCurrent
221 self.
_attr_percentage_attr_percentage =
None if current_percent == 255
else current_percent
225 clusters.FanControl.Attributes.WindSetting
228 clusters.FanControl.Attributes.FanMode
230 if fan_mode == clusters.FanControl.Enums.FanModeEnum.kOff:
236 and wind_setting & WindBitmap.kNaturalWind
242 and wind_setting & WindBitmap.kSleepWind
247 clusters.FanControl.Attributes.FanMode
261 """Calculate features for HA Fan platform from Matter FeatureMap."""
272 if feature_map & FanControlFeature.kMultiSpeed:
277 if feature_map & FanControlFeature.kRocking:
291 clusters.FanControl.Attributes.FanModeSequence
294 if fan_mode_seq == FanModeSequenceEnum.kOffLowHigh:
295 preset_modes = [PRESET_LOW, PRESET_HIGH]
296 elif fan_mode_seq == FanModeSequenceEnum.kOffLowHighAuto:
297 preset_modes = [PRESET_LOW, PRESET_HIGH, PRESET_AUTO]
298 elif fan_mode_seq == FanModeSequenceEnum.kOffLowMedHigh:
299 preset_modes = [PRESET_LOW, PRESET_MEDIUM, PRESET_HIGH]
300 elif fan_mode_seq == FanModeSequenceEnum.kOffLowMedHighAuto:
301 preset_modes = [PRESET_LOW, PRESET_MEDIUM, PRESET_HIGH, PRESET_AUTO]
302 elif fan_mode_seq == FanModeSequenceEnum.kOffHighAuto:
303 preset_modes = [PRESET_HIGH, PRESET_AUTO]
304 elif fan_mode_seq == FanModeSequenceEnum.kOffHigh:
305 preset_modes = [PRESET_HIGH]
307 if feature_map & FanControlFeature.kWind:
310 clusters.FanControl.Attributes.WindSupport
313 if wind_support & WindBitmap.kNaturalWind:
314 preset_modes.append(PRESET_NATURAL_WIND)
315 if wind_support & WindBitmap.kSleepWind:
316 preset_modes.append(PRESET_SLEEP_WIND)
317 if len(preset_modes) > 0:
320 if feature_map & FanControlFeature.kAirflowDirection:
324 FanEntityFeature.TURN_OFF | FanEntityFeature.TURN_ON
329 DISCOVERY_SCHEMAS = [
331 platform=Platform.FAN,
336 entity_class=MatterFan,
338 required_attributes=(
339 clusters.FanControl.Attributes.FanMode,
340 clusters.FanControl.Attributes.PercentCurrent,
342 optional_attributes=(
343 clusters.FanControl.Attributes.SpeedSetting,
344 clusters.FanControl.Attributes.RockSetting,
345 clusters.FanControl.Attributes.WindSetting,
346 clusters.FanControl.Attributes.AirflowDirection,
347 clusters.OnOff.Attributes.OnOff,
None async_set_percentage(self, int percentage)
None async_set_preset_mode(self, str preset_mode)
Any get_matter_attribute_value(self, type[ClusterAttributeDescriptor] attribute, bool null_as_none=True)
None _calculate_features(self)
None async_set_percentage(self, int percentage)
None _set_wind_mode(self, str|None wind_mode)
None async_oscillate(self, bool oscillating)
None _update_from_device(self)
None async_set_direction(self, str direction)
None async_turn_off(self, **Any kwargs)
None async_set_preset_mode(self, str preset_mode)
None async_turn_on(self, int|None percentage=None, str|None preset_mode=None, **Any kwargs)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
MatterAdapter get_matter(HomeAssistant hass)