mirror of https://github.com/home-assistant/core
174 lines
6.1 KiB
Python
174 lines
6.1 KiB
Python
"""Support for Fujitsu HVAC devices that use the Ayla Iot platform."""
|
|
|
|
from typing import Any
|
|
|
|
from ayla_iot_unofficial.fujitsu_hvac import (
|
|
Capability,
|
|
FanSpeed,
|
|
FujitsuHVAC,
|
|
OpMode,
|
|
SwingMode,
|
|
)
|
|
|
|
from homeassistant.components.climate import (
|
|
FAN_AUTO,
|
|
FAN_HIGH,
|
|
FAN_LOW,
|
|
FAN_MEDIUM,
|
|
SWING_BOTH,
|
|
SWING_HORIZONTAL,
|
|
SWING_OFF,
|
|
SWING_VERTICAL,
|
|
ClimateEntity,
|
|
ClimateEntityFeature,
|
|
HVACMode,
|
|
)
|
|
from homeassistant.const import ATTR_TEMPERATURE, PRECISION_HALVES, UnitOfTemperature
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.device_registry import DeviceInfo
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|
|
|
from . import FGLairConfigEntry
|
|
from .const import DOMAIN
|
|
from .coordinator import FGLairCoordinator
|
|
|
|
HA_TO_FUJI_FAN = {
|
|
FAN_LOW: FanSpeed.LOW,
|
|
FAN_MEDIUM: FanSpeed.MEDIUM,
|
|
FAN_HIGH: FanSpeed.HIGH,
|
|
FAN_AUTO: FanSpeed.AUTO,
|
|
}
|
|
FUJI_TO_HA_FAN = {value: key for key, value in HA_TO_FUJI_FAN.items()}
|
|
|
|
HA_TO_FUJI_HVAC = {
|
|
HVACMode.OFF: OpMode.OFF,
|
|
HVACMode.HEAT: OpMode.HEAT,
|
|
HVACMode.COOL: OpMode.COOL,
|
|
HVACMode.HEAT_COOL: OpMode.AUTO,
|
|
HVACMode.DRY: OpMode.DRY,
|
|
HVACMode.FAN_ONLY: OpMode.FAN,
|
|
}
|
|
FUJI_TO_HA_HVAC = {value: key for key, value in HA_TO_FUJI_HVAC.items()}
|
|
|
|
HA_TO_FUJI_SWING = {
|
|
SWING_OFF: SwingMode.OFF,
|
|
SWING_VERTICAL: SwingMode.SWING_VERTICAL,
|
|
SWING_HORIZONTAL: SwingMode.SWING_HORIZONTAL,
|
|
SWING_BOTH: SwingMode.SWING_BOTH,
|
|
}
|
|
FUJI_TO_HA_SWING = {value: key for key, value in HA_TO_FUJI_SWING.items()}
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
entry: FGLairConfigEntry,
|
|
async_add_entities: AddEntitiesCallback,
|
|
) -> None:
|
|
"""Set up one Fujitsu HVAC device."""
|
|
async_add_entities(
|
|
FGLairDevice(entry.runtime_data, device)
|
|
for device in entry.runtime_data.data.values()
|
|
)
|
|
|
|
|
|
class FGLairDevice(CoordinatorEntity[FGLairCoordinator], ClimateEntity):
|
|
"""Represent a Fujitsu HVAC device."""
|
|
|
|
_attr_temperature_unit = UnitOfTemperature.CELSIUS
|
|
_attr_precision = PRECISION_HALVES
|
|
_attr_target_temperature_step = 0.5
|
|
_attr_has_entity_name = True
|
|
_attr_name = None
|
|
|
|
_enable_turn_on_off_backwards_compatibility: bool = False
|
|
|
|
def __init__(self, coordinator: FGLairCoordinator, device: FujitsuHVAC) -> None:
|
|
"""Store the representation of the device and set the static attributes."""
|
|
super().__init__(coordinator, context=device.device_serial_number)
|
|
|
|
self._attr_unique_id = device.device_serial_number
|
|
self._attr_device_info = DeviceInfo(
|
|
identifiers={(DOMAIN, device.device_serial_number)},
|
|
name=device.device_name,
|
|
manufacturer="Fujitsu",
|
|
model=device.property_values["model_name"],
|
|
serial_number=device.device_serial_number,
|
|
sw_version=device.property_values["mcu_firmware_version"],
|
|
)
|
|
|
|
self._attr_supported_features = (
|
|
ClimateEntityFeature.TARGET_TEMPERATURE
|
|
| ClimateEntityFeature.TURN_ON
|
|
| ClimateEntityFeature.TURN_OFF
|
|
)
|
|
if device.has_capability(Capability.OP_FAN):
|
|
self._attr_supported_features |= ClimateEntityFeature.FAN_MODE
|
|
|
|
if device.has_capability(Capability.SWING_HORIZONTAL) or device.has_capability(
|
|
Capability.SWING_VERTICAL
|
|
):
|
|
self._attr_supported_features |= ClimateEntityFeature.SWING_MODE
|
|
self._set_attr()
|
|
|
|
@property
|
|
def device(self) -> FujitsuHVAC:
|
|
"""Return the device object from the coordinator data."""
|
|
return self.coordinator.data[self.coordinator_context]
|
|
|
|
@property
|
|
def available(self) -> bool:
|
|
"""Return if the device is available."""
|
|
return super().available and self.coordinator_context in self.coordinator.data
|
|
|
|
async def async_set_fan_mode(self, fan_mode: str) -> None:
|
|
"""Set Fan mode."""
|
|
await self.device.async_set_fan_speed(HA_TO_FUJI_FAN[fan_mode])
|
|
await self.coordinator.async_request_refresh()
|
|
|
|
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
|
"""Set HVAC mode."""
|
|
await self.device.async_set_op_mode(HA_TO_FUJI_HVAC[hvac_mode])
|
|
await self.coordinator.async_request_refresh()
|
|
|
|
async def async_set_swing_mode(self, swing_mode: str) -> None:
|
|
"""Set swing mode."""
|
|
await self.device.async_set_swing_mode(HA_TO_FUJI_SWING[swing_mode])
|
|
await self.coordinator.async_request_refresh()
|
|
|
|
async def async_set_temperature(self, **kwargs: Any) -> None:
|
|
"""Set target temperature."""
|
|
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
|
|
return
|
|
await self.device.async_set_set_temp(temperature)
|
|
await self.coordinator.async_request_refresh()
|
|
|
|
def _set_attr(self) -> None:
|
|
if self.coordinator_context in self.coordinator.data:
|
|
self._attr_fan_mode = FUJI_TO_HA_FAN.get(self.device.fan_speed)
|
|
self._attr_fan_modes = [
|
|
FUJI_TO_HA_FAN[mode]
|
|
for mode in self.device.supported_fan_speeds
|
|
if mode in FUJI_TO_HA_FAN
|
|
]
|
|
self._attr_hvac_mode = FUJI_TO_HA_HVAC.get(self.device.op_mode)
|
|
self._attr_hvac_modes = [
|
|
FUJI_TO_HA_HVAC[mode]
|
|
for mode in self.device.supported_op_modes
|
|
if mode in FUJI_TO_HA_HVAC
|
|
]
|
|
self._attr_swing_mode = FUJI_TO_HA_SWING.get(self.device.swing_mode)
|
|
self._attr_swing_modes = [
|
|
FUJI_TO_HA_SWING[mode]
|
|
for mode in self.device.supported_swing_modes
|
|
if mode in FUJI_TO_HA_SWING
|
|
]
|
|
self._attr_min_temp = self.device.temperature_range[0]
|
|
self._attr_max_temp = self.device.temperature_range[1]
|
|
self._attr_current_temperature = self.device.sensed_temp
|
|
self._attr_target_temperature = self.device.set_temp
|
|
|
|
def _handle_coordinator_update(self) -> None:
|
|
self._set_attr()
|
|
super()._handle_coordinator_update()
|