1 """Support for Bond fans."""
3 from __future__
import annotations
9 from aiohttp.client_exceptions
import ClientResponseError
10 from bond_async
import Action, DeviceType, Direction
11 import voluptuous
as vol
24 percentage_to_ranged_value,
25 ranged_value_to_percentage,
29 from .
import BondConfigEntry
30 from .const
import SERVICE_SET_FAN_SPEED_TRACKED_STATE
31 from .entity
import BondEntity
32 from .models
import BondData
33 from .utils
import BondDevice
35 _LOGGER = logging.getLogger(__name__)
37 PRESET_MODE_BREEZE =
"Breeze"
42 entry: BondConfigEntry,
43 async_add_entities: AddEntitiesCallback,
45 """Set up Bond fan devices."""
46 data = entry.runtime_data
47 platform = entity_platform.async_get_current_platform()
48 platform.async_register_entity_service(
49 SERVICE_SET_FAN_SPEED_TRACKED_STATE,
50 {vol.Required(
"speed"): vol.All(vol.Number(scale=0), vol.Range(0, 100))},
51 "async_set_speed_belief",
56 for device
in data.hub.devices
57 if DeviceType.is_fan(device.type)
62 """Representation of a Bond fan."""
64 def __init__(self, data: BondData, device: BondDevice) ->
None:
65 """Create HA entity representing Bond fan."""
66 self.
_power_power: bool |
None =
None
67 self.
_speed_speed: int |
None =
None
70 if self.
_device_device.has_action(Action.BREEZE_ON):
72 features = FanEntityFeature.TURN_OFF | FanEntityFeature.TURN_ON
73 if self.
_device_device.supports_speed():
74 features |= FanEntityFeature.SET_SPEED
75 if self.
_device_device.supports_direction():
76 features |= FanEntityFeature.DIRECTION
77 if self.
_device_device.has_action(Action.BREEZE_ON):
78 features |= FanEntityFeature.PRESET_MODE
82 state = self.
_device_device.state
83 self.
_power_power = state.get(
"power")
84 self.
_speed_speed = state.get(
"speed")
86 breeze = state.get(
"breeze", [0, 0, 0])
91 """Return the range of speeds."""
92 return (1, self.
_device_device.props.get(
"max_speed", 3))
96 """Return the current speed percentage for the fan."""
105 """Return the number of speeds the fan supports."""
110 """Return fan rotation direction."""
112 if self.
_direction_direction == Direction.FORWARD:
113 direction = DIRECTION_FORWARD
114 elif self.
_direction_direction == Direction.REVERSE:
115 direction = DIRECTION_REVERSE
120 """Set the desired speed for the fan."""
121 _LOGGER.debug(
"async_set_percentage called with percentage %s", percentage)
127 bond_speed = math.ceil(
131 "async_set_percentage converted percentage %s to bond speed %s",
136 await self.
_bond_bond.action(self.
_device_id_device_id, Action.set_speed(bond_speed))
139 """Set the believed state to on or off."""
141 await self.
_bond_bond.action(
142 self.
_device_id_device_id, Action.set_power_state_belief(power_state)
144 except ClientResponseError
as ex:
146 "The bond API returned an error calling set_power_state_belief for"
147 f
" {self.entity_id}. Code: {ex.status} Message: {ex.message}"
151 """Set the believed speed for the fan."""
152 _LOGGER.debug(
"async_set_speed_belief called with percentage %s", speed)
161 "async_set_percentage converted percentage %s to bond speed %s",
166 await self.
_bond_bond.action(
167 self.
_device_id_device_id, Action.set_speed_belief(bond_speed)
169 except ClientResponseError
as ex:
171 "The bond API returned an error calling set_speed_belief for"
172 f
" {self.entity_id}. Code: {ex.code} Message: {ex.message}"
177 percentage: int |
None =
None,
178 preset_mode: str |
None =
None,
181 """Turn on the fan."""
182 _LOGGER.debug(
"Fan async_turn_on called with percentage %s", percentage)
184 if preset_mode
is not None:
186 elif percentage
is not None:
189 await self.
_bond_bond.action(self.
_device_id_device_id, Action.turn_on())
192 """Set the preset mode of the fan."""
193 await self.
_bond_bond.action(self.
_device_id_device_id, Action(Action.BREEZE_ON))
196 """Turn the fan off."""
198 await self.
_bond_bond.action(self.
_device_id_device_id, Action(Action.BREEZE_OFF))
199 await self.
_bond_bond.action(self.
_device_id_device_id, Action.turn_off())
202 """Set fan rotation direction."""
204 Direction.REVERSE
if direction == DIRECTION_REVERSE
else Direction.FORWARD
206 await self.
_bond_bond.action(self.
_device_id_device_id, Action.set_direction(bond_direction))
None async_set_speed_belief(self, int speed)
None __init__(self, BondData data, BondDevice device)
str|None current_direction(self)
tuple[int, int] _speed_range(self)
None async_set_direction(self, str direction)
None async_set_percentage(self, int percentage)
None async_set_power_belief(self, bool power_state)
None async_turn_on(self, int|None percentage=None, str|None preset_mode=None, **Any kwargs)
None async_turn_off(self, **Any kwargs)
None async_set_preset_mode(self, str preset_mode)
str|None preset_mode(self)
None async_set_percentage(self, int percentage)
None async_set_preset_mode(self, str preset_mode)
None async_turn_off(self, **Any kwargs)
None async_setup_entry(HomeAssistant hass, BondConfigEntry entry, AddEntitiesCallback async_add_entities)
float percentage_to_ranged_value(tuple[float, float] low_high_range, float percentage)
int ranged_value_to_percentage(tuple[float, float] low_high_range, float value)
int int_states_in_range(tuple[float, float] low_high_range)