|
|
|
@@ -39,6 +39,40 @@ HA_TO_MODE = {value: key for key, value in MODE_TO_HA.items()}
|
|
|
|
|
FAN_TO_NAME = {0: "auto", 1: "low", 2: "medium_low", 3: "medium", 4: "medium_high", 5: "high"}
|
|
|
|
|
NAME_TO_FAN = {value: key for key, value in FAN_TO_NAME.items()}
|
|
|
|
|
|
|
|
|
|
VERTICAL_SWING_TO_VALUE = {
|
|
|
|
|
SWING_OFF: 0,
|
|
|
|
|
SWING_ON: 1,
|
|
|
|
|
"fixed_upper": 2,
|
|
|
|
|
"fixed_upper_middle": 3,
|
|
|
|
|
"fixed_middle": 4,
|
|
|
|
|
"fixed_lower_middle": 5,
|
|
|
|
|
"fixed_lower": 6,
|
|
|
|
|
"swing_upper": 7,
|
|
|
|
|
"swing_upper_middle": 8,
|
|
|
|
|
"swing_middle": 9,
|
|
|
|
|
"swing_lower_middle": 10,
|
|
|
|
|
"swing_lower": 11,
|
|
|
|
|
}
|
|
|
|
|
HORIZONTAL_SWING_TO_VALUE = {
|
|
|
|
|
SWING_OFF: 0,
|
|
|
|
|
SWING_ON: 1,
|
|
|
|
|
"fixed_left": 2,
|
|
|
|
|
"fixed_left_middle": 3,
|
|
|
|
|
"fixed_middle": 4,
|
|
|
|
|
"fixed_right_middle": 5,
|
|
|
|
|
"fixed_right": 6,
|
|
|
|
|
}
|
|
|
|
|
VALUE_TO_VERTICAL_SWING = {value: mode for mode, value in VERTICAL_SWING_TO_VALUE.items()}
|
|
|
|
|
VALUE_TO_HORIZONTAL_SWING = {value: mode for mode, value in HORIZONTAL_SWING_TO_VALUE.items()}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _louver_mode(raw: Any, modes: dict[int, str]) -> str:
|
|
|
|
|
try:
|
|
|
|
|
value = int(raw)
|
|
|
|
|
except (TypeError, ValueError):
|
|
|
|
|
value = 0
|
|
|
|
|
return modes.get(value, SWING_OFF)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async def async_setup_entry(
|
|
|
|
|
hass: HomeAssistant,
|
|
|
|
@@ -132,8 +166,8 @@ class GreeControllerClimate(CoordinatorEntity[GreeControllerCoordinator], Climat
|
|
|
|
|
_attr_target_temperature_step = 1.0
|
|
|
|
|
_attr_hvac_modes = [HVACMode.OFF, HVACMode.AUTO, HVACMode.COOL, HVACMode.HEAT, HVACMode.DRY, HVACMode.FAN_ONLY]
|
|
|
|
|
_attr_fan_modes = list(NAME_TO_FAN)
|
|
|
|
|
_attr_swing_modes = [SWING_OFF, SWING_ON]
|
|
|
|
|
_attr_swing_horizontal_modes = [SWING_OFF, SWING_ON]
|
|
|
|
|
_attr_swing_modes = list(VERTICAL_SWING_TO_VALUE)
|
|
|
|
|
_attr_swing_horizontal_modes = list(HORIZONTAL_SWING_TO_VALUE)
|
|
|
|
|
_attr_supported_features = (
|
|
|
|
|
ClimateEntityFeature.TARGET_TEMPERATURE
|
|
|
|
|
| ClimateEntityFeature.FAN_MODE
|
|
|
|
@@ -200,11 +234,11 @@ class GreeControllerClimate(CoordinatorEntity[GreeControllerCoordinator], Climat
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def swing_mode(self) -> str:
|
|
|
|
|
return SWING_ON if self._device.get("swing_vertical", False) else SWING_OFF
|
|
|
|
|
return _louver_mode(self._device.get("swing_vertical", 0), VALUE_TO_VERTICAL_SWING)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def swing_horizontal_mode(self) -> str:
|
|
|
|
|
return SWING_ON if self._device.get("swing_horizontal", False) else SWING_OFF
|
|
|
|
|
return _louver_mode(self._device.get("swing_horizontal", 0), VALUE_TO_HORIZONTAL_SWING)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def extra_state_attributes(self) -> dict[str, Any]:
|
|
|
|
@@ -219,6 +253,8 @@ class GreeControllerClimate(CoordinatorEntity[GreeControllerCoordinator], Climat
|
|
|
|
|
"air": bool(device.get("air", False)),
|
|
|
|
|
"health": bool(device.get("health", False)),
|
|
|
|
|
"sleep": bool(device.get("sleep", False)),
|
|
|
|
|
"vertical_louver_position": int(device.get("swing_vertical", 0) or 0),
|
|
|
|
|
"horizontal_louver_position": int(device.get("swing_horizontal", 0) or 0),
|
|
|
|
|
"last_seen": device.get("last_seen"),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -250,10 +286,14 @@ class GreeControllerClimate(CoordinatorEntity[GreeControllerCoordinator], Climat
|
|
|
|
|
await self._command({"fan_speed": NAME_TO_FAN[fan_mode]})
|
|
|
|
|
|
|
|
|
|
async def async_set_swing_mode(self, swing_mode: str) -> None:
|
|
|
|
|
await self._command({"swing_vertical": swing_mode == SWING_ON})
|
|
|
|
|
value = VERTICAL_SWING_TO_VALUE.get(swing_mode)
|
|
|
|
|
if value is not None:
|
|
|
|
|
await self._command({"swing_vertical": value})
|
|
|
|
|
|
|
|
|
|
async def async_set_swing_horizontal_mode(self, swing_horizontal_mode: str) -> None:
|
|
|
|
|
await self._command({"swing_horizontal": swing_horizontal_mode == SWING_ON})
|
|
|
|
|
value = HORIZONTAL_SWING_TO_VALUE.get(swing_horizontal_mode)
|
|
|
|
|
if value is not None:
|
|
|
|
|
await self._command({"swing_horizontal": value})
|
|
|
|
|
|
|
|
|
|
class GreeControllerZoneClimate(CoordinatorEntity[GreeControllerCoordinator], ClimateEntity):
|
|
|
|
|
"""Full climate entity for a controller thermostat zone."""
|
|
|
|
@@ -266,8 +306,8 @@ class GreeControllerZoneClimate(CoordinatorEntity[GreeControllerCoordinator], Cl
|
|
|
|
|
_attr_target_temperature_step = 0.5
|
|
|
|
|
_attr_hvac_modes = [HVACMode.OFF, HVACMode.AUTO, HVACMode.COOL, HVACMode.HEAT]
|
|
|
|
|
_attr_preset_modes = ["auto", "comfort", "sleep", "away"]
|
|
|
|
|
_attr_swing_modes = [SWING_OFF, SWING_ON]
|
|
|
|
|
_attr_swing_horizontal_modes = [SWING_OFF, SWING_ON]
|
|
|
|
|
_attr_swing_modes = list(VERTICAL_SWING_TO_VALUE)
|
|
|
|
|
_attr_swing_horizontal_modes = list(HORIZONTAL_SWING_TO_VALUE)
|
|
|
|
|
|
|
|
|
|
def __init__(self, coordinator: GreeControllerCoordinator, zone_id: str) -> None:
|
|
|
|
|
super().__init__(coordinator)
|
|
|
|
@@ -343,11 +383,11 @@ class GreeControllerZoneClimate(CoordinatorEntity[GreeControllerCoordinator], Cl
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def swing_mode(self) -> str:
|
|
|
|
|
return SWING_ON if self._device.get("swing_vertical", False) else SWING_OFF
|
|
|
|
|
return _louver_mode(self._device.get("swing_vertical", 0), VALUE_TO_VERTICAL_SWING)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def swing_horizontal_mode(self) -> str:
|
|
|
|
|
return SWING_ON if self._device.get("swing_horizontal", False) else SWING_OFF
|
|
|
|
|
return _louver_mode(self._device.get("swing_horizontal", 0), VALUE_TO_HORIZONTAL_SWING)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def extra_state_attributes(self) -> dict[str, Any]:
|
|
|
|
@@ -378,6 +418,8 @@ class GreeControllerZoneClimate(CoordinatorEntity[GreeControllerCoordinator], Cl
|
|
|
|
|
"actual_mode": zone.get("actual_mode"),
|
|
|
|
|
"actual_setpoint": zone.get("actual_setpoint"),
|
|
|
|
|
"current_schedule": zone.get("current_schedule_name"),
|
|
|
|
|
"vertical_louver_position": int(self._device.get("swing_vertical", 0) or 0),
|
|
|
|
|
"horizontal_louver_position": int(self._device.get("swing_horizontal", 0) or 0),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
|
|
|
@@ -406,17 +448,15 @@ class GreeControllerZoneClimate(CoordinatorEntity[GreeControllerCoordinator], Cl
|
|
|
|
|
|
|
|
|
|
async def async_set_swing_mode(self, swing_mode: str) -> None:
|
|
|
|
|
device_id = str(self._zone.get("device_id") or "").strip()
|
|
|
|
|
if device_id:
|
|
|
|
|
await self.coordinator.async_device_command(
|
|
|
|
|
device_id, {"swing_vertical": swing_mode == SWING_ON}
|
|
|
|
|
)
|
|
|
|
|
value = VERTICAL_SWING_TO_VALUE.get(swing_mode)
|
|
|
|
|
if device_id and value is not None:
|
|
|
|
|
await self.coordinator.async_device_command(device_id, {"swing_vertical": value})
|
|
|
|
|
|
|
|
|
|
async def async_set_swing_horizontal_mode(self, swing_horizontal_mode: str) -> None:
|
|
|
|
|
device_id = str(self._zone.get("device_id") or "").strip()
|
|
|
|
|
if device_id:
|
|
|
|
|
await self.coordinator.async_device_command(
|
|
|
|
|
device_id, {"swing_horizontal": swing_horizontal_mode == SWING_ON}
|
|
|
|
|
)
|
|
|
|
|
value = HORIZONTAL_SWING_TO_VALUE.get(swing_horizontal_mode)
|
|
|
|
|
if device_id and value is not None:
|
|
|
|
|
await self.coordinator.async_device_command(device_id, {"swing_horizontal": value})
|
|
|
|
|
|
|
|
|
|
async def async_turn_on(self) -> None:
|
|
|
|
|
await self.coordinator.async_zone_control(self._zone_id, {"power": True})
|
|
|
|
|