mirror of
https://github.com/home-assistant/core.git
synced 2026-09-28 02:18:10 -04:00
133 lines
3.7 KiB
Python
133 lines
3.7 KiB
Python
"""Support for Overkiz fans."""
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Any, cast, override
|
|
|
|
from pyoverkiz.enums import OverkizCommand, OverkizState
|
|
from pyoverkiz.enums.ui import UIWidget
|
|
|
|
from homeassistant.components.fan import (
|
|
FanEntity,
|
|
FanEntityDescription,
|
|
FanEntityFeature,
|
|
)
|
|
from homeassistant.const import Platform
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
|
|
from . import OverkizDataConfigEntry
|
|
from .entity import OverkizDescriptiveEntity
|
|
|
|
|
|
@dataclass(frozen=True, kw_only=True)
|
|
class OverkizFanDescription(FanEntityDescription):
|
|
"""Class to describe an Overkiz fan."""
|
|
|
|
percentage: OverkizState
|
|
set_percentage: OverkizCommand
|
|
|
|
|
|
FAN_DESCRIPTIONS: list[OverkizFanDescription] = [
|
|
OverkizFanDescription(
|
|
key=UIWidget.VENTILATION_INLET,
|
|
percentage=OverkizState.CORE_AIR_INPUT,
|
|
set_percentage=OverkizCommand.SET_AIR_INPUT,
|
|
),
|
|
OverkizFanDescription(
|
|
key=UIWidget.VENTILATION_OUTLET,
|
|
percentage=OverkizState.CORE_AIR_OUTPUT,
|
|
set_percentage=OverkizCommand.SET_AIR_OUTPUT,
|
|
),
|
|
OverkizFanDescription(
|
|
key=UIWidget.VENTILATION_TRANSFER,
|
|
percentage=OverkizState.CORE_AIR_TRANSFER,
|
|
set_percentage=OverkizCommand.SET_AIR_TRANSFER,
|
|
),
|
|
]
|
|
|
|
SUPPORTED_DEVICES = {description.key: description for description in FAN_DESCRIPTIONS}
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
entry: OverkizDataConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Set up the Overkiz fans from a config entry."""
|
|
data = entry.runtime_data
|
|
|
|
async_add_entities(
|
|
OverkizFan(
|
|
device.device_url,
|
|
data.coordinator,
|
|
description,
|
|
)
|
|
for device in data.platforms[Platform.FAN]
|
|
if (
|
|
description := SUPPORTED_DEVICES.get(device.widget)
|
|
or SUPPORTED_DEVICES.get(device.ui_class)
|
|
)
|
|
)
|
|
|
|
|
|
class OverkizFan(OverkizDescriptiveEntity, FanEntity):
|
|
"""Representation of an Overkiz fan."""
|
|
|
|
entity_description: OverkizFanDescription
|
|
|
|
_attr_supported_features = (
|
|
FanEntityFeature.SET_SPEED
|
|
| FanEntityFeature.TURN_ON
|
|
| FanEntityFeature.TURN_OFF
|
|
)
|
|
|
|
@property
|
|
@override
|
|
def percentage(self) -> int | None:
|
|
"""Return the current air flow level as a percentage."""
|
|
air_flow = self.device.states.get_value(self.entity_description.percentage)
|
|
|
|
if air_flow is None:
|
|
return None
|
|
|
|
return cast(int, air_flow)
|
|
|
|
@property
|
|
@override
|
|
def is_on(self) -> bool | None:
|
|
"""Return whether the fan is running."""
|
|
if (percentage := self.percentage) is None:
|
|
return None
|
|
|
|
return percentage > 0
|
|
|
|
@override
|
|
async def async_set_percentage(self, percentage: int) -> None:
|
|
"""Set the air flow level."""
|
|
if percentage == 0:
|
|
await self.async_turn_off()
|
|
return
|
|
|
|
await self.executor.async_execute_command(
|
|
self.entity_description.set_percentage, percentage
|
|
)
|
|
|
|
@override
|
|
async def async_turn_on(
|
|
self,
|
|
percentage: int | None = None,
|
|
preset_mode: str | None = None,
|
|
**kwargs: Any,
|
|
) -> None:
|
|
"""Turn the fan on."""
|
|
if percentage is not None:
|
|
await self.async_set_percentage(percentage)
|
|
return
|
|
|
|
await self.executor.async_execute_command(OverkizCommand.ON)
|
|
|
|
@override
|
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
|
"""Turn the fan off."""
|
|
await self.executor.async_execute_command(OverkizCommand.OFF)
|