Home Assistant Unofficial Reference 2024.12.1
climate.py
Go to the documentation of this file.
1 """Support for Fujitsu HVAC devices that use the Ayla Iot platform."""
2 
3 from typing import Any
4 
5 from ayla_iot_unofficial.fujitsu_hvac import (
6  Capability,
7  FanSpeed,
8  FujitsuHVAC,
9  OpMode,
10  SwingMode,
11 )
12 
14  FAN_AUTO,
15  FAN_HIGH,
16  FAN_LOW,
17  FAN_MEDIUM,
18  SWING_BOTH,
19  SWING_HORIZONTAL,
20  SWING_OFF,
21  SWING_VERTICAL,
22  ClimateEntity,
23  ClimateEntityFeature,
24  HVACMode,
25 )
26 from homeassistant.const import ATTR_TEMPERATURE, PRECISION_HALVES, UnitOfTemperature
27 from homeassistant.core import HomeAssistant
28 from homeassistant.helpers.device_registry import DeviceInfo
29 from homeassistant.helpers.entity_platform import AddEntitiesCallback
30 from homeassistant.helpers.update_coordinator import CoordinatorEntity
31 
32 from . import FGLairConfigEntry
33 from .const import DOMAIN
34 from .coordinator import FGLairCoordinator
35 
36 HA_TO_FUJI_FAN = {
37  FAN_LOW: FanSpeed.LOW,
38  FAN_MEDIUM: FanSpeed.MEDIUM,
39  FAN_HIGH: FanSpeed.HIGH,
40  FAN_AUTO: FanSpeed.AUTO,
41 }
42 FUJI_TO_HA_FAN = {value: key for key, value in HA_TO_FUJI_FAN.items()}
43 
44 HA_TO_FUJI_HVAC = {
45  HVACMode.OFF: OpMode.OFF,
46  HVACMode.HEAT: OpMode.HEAT,
47  HVACMode.COOL: OpMode.COOL,
48  HVACMode.HEAT_COOL: OpMode.AUTO,
49  HVACMode.DRY: OpMode.DRY,
50  HVACMode.FAN_ONLY: OpMode.FAN,
51 }
52 FUJI_TO_HA_HVAC = {value: key for key, value in HA_TO_FUJI_HVAC.items()}
53 
54 HA_TO_FUJI_SWING = {
55  SWING_OFF: SwingMode.OFF,
56  SWING_VERTICAL: SwingMode.SWING_VERTICAL,
57  SWING_HORIZONTAL: SwingMode.SWING_HORIZONTAL,
58  SWING_BOTH: SwingMode.SWING_BOTH,
59 }
60 FUJI_TO_HA_SWING = {value: key for key, value in HA_TO_FUJI_SWING.items()}
61 
62 
64  hass: HomeAssistant,
65  entry: FGLairConfigEntry,
66  async_add_entities: AddEntitiesCallback,
67 ) -> None:
68  """Set up one Fujitsu HVAC device."""
70  FGLairDevice(entry.runtime_data, device)
71  for device in entry.runtime_data.data.values()
72  )
73 
74 
75 class FGLairDevice(CoordinatorEntity[FGLairCoordinator], ClimateEntity):
76  """Represent a Fujitsu HVAC device."""
77 
78  _attr_temperature_unit = UnitOfTemperature.CELSIUS
79  _attr_precision = PRECISION_HALVES
80  _attr_target_temperature_step = 0.5
81  _attr_has_entity_name = True
82  _attr_name = None
83 
84  _enable_turn_on_off_backwards_compatibility: bool = False
85 
86  def __init__(self, coordinator: FGLairCoordinator, device: FujitsuHVAC) -> None:
87  """Store the representation of the device and set the static attributes."""
88  super().__init__(coordinator, context=device.device_serial_number)
89 
90  self._attr_unique_id_attr_unique_id = device.device_serial_number
91  self._attr_device_info_attr_device_info = DeviceInfo(
92  identifiers={(DOMAIN, device.device_serial_number)},
93  name=device.device_name,
94  manufacturer="Fujitsu",
95  model=device.property_values["model_name"],
96  serial_number=device.device_serial_number,
97  sw_version=device.property_values["mcu_firmware_version"],
98  )
99 
100  self._attr_supported_features_attr_supported_features = (
101  ClimateEntityFeature.TARGET_TEMPERATURE
102  | ClimateEntityFeature.TURN_ON
103  | ClimateEntityFeature.TURN_OFF
104  )
105  if device.has_capability(Capability.OP_FAN):
106  self._attr_supported_features_attr_supported_features |= ClimateEntityFeature.FAN_MODE
107 
108  if device.has_capability(Capability.SWING_HORIZONTAL) or device.has_capability(
109  Capability.SWING_VERTICAL
110  ):
111  self._attr_supported_features_attr_supported_features |= ClimateEntityFeature.SWING_MODE
112  self._set_attr_set_attr()
113 
114  @property
115  def device(self) -> FujitsuHVAC:
116  """Return the device object from the coordinator data."""
117  return self.coordinator.data[self.coordinator_context]
118 
119  @property
120  def available(self) -> bool:
121  """Return if the device is available."""
122  return super().available and self.coordinator_context in self.coordinator.data
123 
124  async def async_set_fan_mode(self, fan_mode: str) -> None:
125  """Set Fan mode."""
126  await self.devicedevice.async_set_fan_speed(HA_TO_FUJI_FAN[fan_mode])
127  await self.coordinator.async_request_refresh()
128 
129  async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
130  """Set HVAC mode."""
131  await self.devicedevice.async_set_op_mode(HA_TO_FUJI_HVAC[hvac_mode])
132  await self.coordinator.async_request_refresh()
133 
134  async def async_set_swing_mode(self, swing_mode: str) -> None:
135  """Set swing mode."""
136  await self.devicedevice.async_set_swing_mode(HA_TO_FUJI_SWING[swing_mode])
137  await self.coordinator.async_request_refresh()
138 
139  async def async_set_temperature(self, **kwargs: Any) -> None:
140  """Set target temperature."""
141  if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
142  return
143  await self.devicedevice.async_set_set_temp(temperature)
144  await self.coordinator.async_request_refresh()
145 
146  def _set_attr(self) -> None:
147  if self.coordinator_context in self.coordinator.data:
148  self._attr_fan_mode_attr_fan_mode = FUJI_TO_HA_FAN.get(self.devicedevice.fan_speed)
149  self._attr_fan_modes_attr_fan_modes = [
150  FUJI_TO_HA_FAN[mode]
151  for mode in self.devicedevice.supported_fan_speeds
152  if mode in FUJI_TO_HA_FAN
153  ]
154  self._attr_hvac_mode_attr_hvac_mode = FUJI_TO_HA_HVAC.get(self.devicedevice.op_mode)
155  self._attr_hvac_modes_attr_hvac_modes = [
156  FUJI_TO_HA_HVAC[mode]
157  for mode in self.devicedevice.supported_op_modes
158  if mode in FUJI_TO_HA_HVAC
159  ]
160  self._attr_swing_mode_attr_swing_mode = FUJI_TO_HA_SWING.get(self.devicedevice.swing_mode)
161  self._attr_swing_modes_attr_swing_modes = [
162  FUJI_TO_HA_SWING[mode]
163  for mode in self.devicedevice.supported_swing_modes
164  if mode in FUJI_TO_HA_SWING
165  ]
166  self._attr_min_temp_attr_min_temp = self.devicedevice.temperature_range[0]
167  self._attr_max_temp_attr_max_temp = self.devicedevice.temperature_range[1]
168  self._attr_current_temperature_attr_current_temperature = self.devicedevice.sensed_temp
169  self._attr_target_temperature_attr_target_temperature = self.devicedevice.set_temp
170 
171  def _handle_coordinator_update(self) -> None:
172  self._set_attr_set_attr()
None __init__(self, FGLairCoordinator coordinator, FujitsuHVAC device)
Definition: climate.py:86
None async_setup_entry(HomeAssistant hass, FGLairConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: climate.py:67