Home Assistant Unofficial Reference 2024.12.1
fan.py
Go to the documentation of this file.
1 """Support for ISY fans."""
2 
3 from __future__ import annotations
4 
5 import math
6 from typing import Any
7 
8 from pyisy.constants import ISY_VALUE_UNKNOWN, PROTO_INSTEON
9 
10 from homeassistant.components.fan import FanEntity, FanEntityFeature
11 from homeassistant.config_entries import ConfigEntry
12 from homeassistant.const import Platform
13 from homeassistant.core import HomeAssistant
14 from homeassistant.helpers.device_registry import DeviceInfo
15 from homeassistant.helpers.entity_platform import AddEntitiesCallback
17  percentage_to_ranged_value,
18  ranged_value_to_percentage,
19 )
20 from homeassistant.util.scaling import int_states_in_range
21 
22 from .const import _LOGGER, DOMAIN
23 from .entity import ISYNodeEntity, ISYProgramEntity
24 from .models import IsyData
25 
26 SPEED_RANGE = (1, 255) # off is not included
27 
28 
30  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
31 ) -> None:
32  """Set up the ISY fan platform."""
33  isy_data: IsyData = hass.data[DOMAIN][entry.entry_id]
34  devices: dict[str, DeviceInfo] = isy_data.devices
35  entities: list[ISYFanEntity | ISYFanProgramEntity] = [
36  ISYFanEntity(node, devices.get(node.primary_node))
37  for node in isy_data.nodes[Platform.FAN]
38  ]
39 
40  entities.extend(
41  ISYFanProgramEntity(name, status, actions)
42  for name, status, actions in isy_data.programs[Platform.FAN]
43  )
44 
45  async_add_entities(entities)
46 
47 
49  """Representation of an ISY fan device."""
50 
51  _attr_supported_features = (
52  FanEntityFeature.SET_SPEED
53  | FanEntityFeature.TURN_OFF
54  | FanEntityFeature.TURN_ON
55  )
56  _enable_turn_on_off_backwards_compatibility = False
57 
58  @property
59  def percentage(self) -> int | None:
60  """Return the current speed percentage."""
61  if self._node_node.status == ISY_VALUE_UNKNOWN:
62  return None
63  return ranged_value_to_percentage(SPEED_RANGE, self._node_node.status)
64 
65  @property
66  def speed_count(self) -> int:
67  """Return the number of speeds the fan supports."""
68  if self._node_node.protocol == PROTO_INSTEON:
69  return 3
70  return int_states_in_range(SPEED_RANGE)
71 
72  @property
73  def is_on(self) -> bool | None:
74  """Get if the fan is on."""
75  if self._node_node.status == ISY_VALUE_UNKNOWN:
76  return None
77  return bool(self._node_node.status != 0)
78 
79  async def async_set_percentage(self, percentage: int) -> None:
80  """Set node to speed percentage for the ISY fan device."""
81  if percentage == 0:
82  await self._node_node.turn_off()
83  return
84 
85  isy_speed = math.ceil(percentage_to_ranged_value(SPEED_RANGE, percentage))
86 
87  await self._node_node.turn_on(val=isy_speed)
88 
89  async def async_turn_on(
90  self,
91  percentage: int | None = None,
92  preset_mode: str | None = None,
93  **kwargs: Any,
94  ) -> None:
95  """Send the turn on command to the ISY fan device."""
96  await self.async_set_percentageasync_set_percentageasync_set_percentage(percentage or 67)
97 
98  async def async_turn_off(self, **kwargs: Any) -> None:
99  """Send the turn off command to the ISY fan device."""
100  await self._node_node.turn_off()
101 
102 
104  """Representation of an ISY fan program."""
105 
106  @property
107  def percentage(self) -> int | None:
108  """Return the current speed percentage."""
109  if self._node_node.status == ISY_VALUE_UNKNOWN:
110  return None
111  return ranged_value_to_percentage(SPEED_RANGE, self._node_node.status)
112 
113  @property
114  def speed_count(self) -> int:
115  """Return the number of speeds the fan supports."""
116  return int_states_in_range(SPEED_RANGE)
117 
118  @property
119  def is_on(self) -> bool:
120  """Get if the fan is on."""
121  return bool(self._node_node.status != 0)
122 
123  async def async_turn_off(self, **kwargs: Any) -> None:
124  """Send the turn on command to ISY fan program."""
125  if not await self._actions_actions.run_then():
126  _LOGGER.error("Unable to turn off the fan")
127 
128  async def async_turn_on(
129  self,
130  percentage: int | None = None,
131  preset_mode: str | None = None,
132  **kwargs: Any,
133  ) -> None:
134  """Send the turn off command to ISY fan program."""
135  if not await self._actions_actions.run_else():
136  _LOGGER.error("Unable to turn on the fan")
None turn_on(self, int|None percentage=None, str|None preset_mode=None, **Any kwargs)
Definition: __init__.py:416
None async_set_percentage(self, int percentage)
Definition: __init__.py:340
None async_turn_on(self, int|None percentage=None, str|None preset_mode=None, **Any kwargs)
Definition: fan.py:94
None async_turn_off(self, **Any kwargs)
Definition: fan.py:98
None async_set_percentage(self, int percentage)
Definition: fan.py:79
None async_turn_on(self, int|None percentage=None, str|None preset_mode=None, **Any kwargs)
Definition: fan.py:133
None turn_off(self, **Any kwargs)
Definition: entity.py:1705
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: fan.py:31
float percentage_to_ranged_value(tuple[float, float] low_high_range, float percentage)
Definition: percentage.py:81
int ranged_value_to_percentage(tuple[float, float] low_high_range, float value)
Definition: percentage.py:64
int int_states_in_range(tuple[float, float] low_high_range)
Definition: scaling.py:61