| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- """Fan setup for our Integration."""
- import logging
- from typing import Any
- from homeassistant.components.fan import FanEntity, FanEntityFeature
- from homeassistant.core import HomeAssistant
- from homeassistant.helpers.entity_platform import AddEntitiesCallback
- from homeassistant.util.percentage import percentage_to_ranged_value
- from . import MyConfigEntry
- from .base import ExampleBaseEntity
- from .coordinator import ExampleCoordinator
- _LOGGER = logging.getLogger(__name__)
- async def async_setup_entry(
- hass: HomeAssistant,
- config_entry: MyConfigEntry,
- async_add_entities: AddEntitiesCallback,
- ):
- """Set up the Fans."""
- # This gets the data update coordinator from the config entry runtime data as specified in your __init__.py
- coordinator: ExampleCoordinator = config_entry.runtime_data.coordinator
- # ----------------------------------------------------------------------------
- # Here we are going to add our fan entity for the fan in our mock data.
- # ----------------------------------------------------------------------------
- # Fans
- fans = [
- ExampleFan(coordinator, device, "state")
- for device in coordinator.data
- if device.get("device_type") == "FAN"
- ]
- # Create the fans.
- async_add_entities(fans)
- class ExampleFan(ExampleBaseEntity, FanEntity):
- """Implementation of a fan.
- This inherits our ExampleBaseEntity to set common properties.
- See base.py for this class.
- https://developers.home-assistant.io/docs/core/entity/fan/
- """
- _attr_speed_count = 3
- _attr_supported_features = FanEntityFeature.OSCILLATE | FanEntityFeature.SET_SPEED
- _speed_parameter = "speed"
- _oscillating_parameter = "oscillating"
- @property
- def is_on(self) -> bool | None:
- """Return if the fan is on."""
- # This needs to enumerate to true or false
- return (
- self.coordinator.get_device_parameter(self.device_id, self.parameter)
- == "ON"
- )
- @property
- def oscillating(self) -> bool | None:
- """Return whether or not the fan is currently oscillating."""
- # This needs to enumerate to true or false
- return (
- self.coordinator.get_device_parameter(
- self.device_id, self._oscillating_parameter
- )
- == "ON"
- )
- @property
- def percentage(self) -> int | None:
- """Return the current speed as a percentage."""
- speed = self.coordinator.get_device_parameter(
- self.device_id, self._speed_parameter
- )
- # Need to return a percentage but our fan has speeds 0,1,2,3
- return int(self.percentage_step * speed)
- async def async_turn_on(
- self,
- percentage: int | None = None,
- preset_mode: str | None = None,
- **kwargs: Any,
- ) -> None:
- """Turn on the fan.
- A turn on command can be sent with or without a %, so we
- need to check that and turn on and set speed if requested.
- """
- await self.hass.async_add_executor_job(
- self.coordinator.api.set_data, self.device_id, self.parameter, "ON"
- )
- if percentage:
- self.async_set_fan_speed(percentage)
- # ----------------------------------------------------------------------------
- # Use async_refresh on the DataUpdateCoordinator to perform immediate update.
- # Using self.async_update or self.coordinator.async_request_refresh may delay update due
- # to trying to batch requests.
- # ----------------------------------------------------------------------------
- await self.coordinator.async_refresh()
- async def async_turn_off(self, **kwargs: Any) -> None:
- """Turn the fan off."""
- await self.hass.async_add_executor_job(
- self.coordinator.api.set_data, self.device_id, self.parameter, "OFF"
- )
- await self.coordinator.async_refresh()
- async def async_set_percentage(self, percentage: int) -> None:
- """Set the speed of the fan, as a percentage.
- Here we need to apply some logic if % is 0 to turn the fan
- off instead of setting its speed. If the fan is off, turn it on with
- the speed setting, otherwise just set the speed setting.
- """
- if percentage == 0:
- await self.async_turn_off()
- elif not self.is_on:
- await self.async_turn_on(percentage)
- else:
- await self.async_set_fan_speed(percentage)
- await self.coordinator.async_refresh()
- async def async_oscillate(self, oscillating: bool) -> None:
- """Oscillate the fan."""
- await self.hass.async_add_executor_job(
- self.coordinator.api.set_data,
- self.device_id,
- self._oscillating_parameter,
- "ON" if oscillating else "OFF",
- )
- await self.coordinator.async_refresh()
- # ----------------------------------------------------------------------------
- # Added a custom method to make our code simpler
- # ----------------------------------------------------------------------------
- async def async_set_fan_speed(self, percentage: int) -> None:
- """Set fan speed."""
- await self.hass.async_add_executor_job(
- self.coordinator.api.set_data,
- self.device_id,
- self._speed_parameter,
- percentage_to_ranged_value(1, self.speed_count, percentage),
- )
|