Home Assistant Unofficial Reference 2024.12.1
fan.py
Go to the documentation of this file.
1 """Fan definition for Intellifire."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Awaitable, Callable
6 from dataclasses import dataclass
7 import math
8 from typing import Any
9 
10 from intellifire4py.control import IntelliFireController
11 from intellifire4py.model import IntelliFirePollData
12 
13 from homeassistant.components.fan import (
14  FanEntity,
15  FanEntityDescription,
16  FanEntityFeature,
17 )
18 from homeassistant.config_entries import ConfigEntry
19 from homeassistant.core import HomeAssistant
20 from homeassistant.helpers.entity_platform import AddEntitiesCallback
22  percentage_to_ranged_value,
23  ranged_value_to_percentage,
24 )
25 
26 from .const import DOMAIN, LOGGER
27 from .coordinator import IntellifireDataUpdateCoordinator
28 from .entity import IntellifireEntity
29 
30 
31 @dataclass(frozen=True)
33  """Required keys for fan entity."""
34 
35  set_fn: Callable[[IntelliFireController, int], Awaitable]
36  value_fn: Callable[[IntelliFirePollData], int]
37  speed_range: tuple[int, int]
38 
39 
40 @dataclass(frozen=True)
42  FanEntityDescription, IntellifireFanRequiredKeysMixin
43 ):
44  """Describes a fan entity."""
45 
46 
47 INTELLIFIRE_FANS: tuple[IntellifireFanEntityDescription, ...] = (
49  key="fan",
50  translation_key="fan",
51  set_fn=lambda control_api, speed: control_api.set_fan_speed(speed=speed),
52  value_fn=lambda data: data.fanspeed,
53  speed_range=(1, 4),
54  ),
55 )
56 
57 
59  hass: HomeAssistant,
60  entry: ConfigEntry,
61  async_add_entities: AddEntitiesCallback,
62 ) -> None:
63  """Set up the fans."""
64  coordinator: IntellifireDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
65 
66  if coordinator.data.has_fan:
68  IntellifireFan(coordinator=coordinator, description=description)
69  for description in INTELLIFIRE_FANS
70  )
71  return
72  LOGGER.debug("Disabling Fan - IntelliFire device does not appear to have one")
73 
74 
76  """Fan entity for the fireplace."""
77 
78  entity_description: IntellifireFanEntityDescription
79  _attr_supported_features = (
80  FanEntityFeature.SET_SPEED
81  | FanEntityFeature.TURN_OFF
82  | FanEntityFeature.TURN_ON
83  )
84  _enable_turn_on_off_backwards_compatibility = False
85 
86  @property
87  def is_on(self) -> bool:
88  """Return on or off."""
89  return self.entity_descriptionentity_description.value_fn(self.coordinator.read_api.data) >= 1
90 
91  @property
92  def percentage(self) -> int | None:
93  """Return fan percentage."""
95  self.entity_descriptionentity_description.speed_range,
96  self.coordinator.read_api.data.fanspeed,
97  )
98 
99  @property
100  def speed_count(self) -> int:
101  """Count of supported speeds."""
102  return self.entity_descriptionentity_description.speed_range[1]
103 
104  async def async_set_percentage(self, percentage: int) -> None:
105  """Set the speed percentage of the fan."""
106  # Calculate percentage steps
107  LOGGER.debug("Setting Fan Speed %s", percentage)
108 
109  int_value = math.ceil(
110  percentage_to_ranged_value(self.entity_descriptionentity_description.speed_range, percentage)
111  )
112  await self.entity_descriptionentity_description.set_fn(self.coordinator.control_api, int_value)
113  await self.coordinator.async_request_refresh()
114 
115  async def async_turn_on(
116  self,
117  percentage: int | None = None,
118  preset_mode: str | None = None,
119  **kwargs: Any,
120  ) -> None:
121  """Turn on the fan."""
122  if percentage:
123  int_value = math.ceil(
125  self.entity_descriptionentity_description.speed_range, percentage
126  )
127  )
128  else:
129  int_value = 1
130  await self.entity_descriptionentity_description.set_fn(self.coordinator.control_api, int_value)
131  await self.coordinator.async_request_refresh()
132 
133  async def async_turn_off(self, **kwargs: Any) -> None:
134  """Turn off the fan."""
135  await self.entity_descriptionentity_description.set_fn(self.coordinator.control_api, 0)
136  await self.coordinator.async_request_refresh()
None async_set_percentage(self, int percentage)
Definition: fan.py:104
None async_turn_on(self, int|None percentage=None, str|None preset_mode=None, **Any kwargs)
Definition: fan.py:120
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: fan.py:62
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