This commit is contained in:
Mateusz Gruszczyński
2026-08-24 16:12:31 +02:00
parent 83f744e2cb
commit 66a5d6e5e9
22 changed files with 686 additions and 103 deletions
@@ -16,6 +16,17 @@ from .const import DOMAIN
from .coordinator import GreeControllerCoordinator
DEVICE_FEATURE_SWITCHES = [
("light", "supports_light", "Panel light"),
("quiet", "supports_quiet", "Quiet"),
("turbo", "supports_turbo", "Turbo"),
("xfan", "supports_xfan", "X-FAN"),
("air", "supports_air", "Air"),
("health", "supports_health", "Health"),
("sleep", "supports_sleep", "Sleep"),
]
async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
@@ -23,11 +34,15 @@ async def async_setup_entry(
) -> None:
"""Create one enabled switch per controller zone."""
runtime: GreeControllerRuntimeData = entry.runtime_data
entities = [
entities: list[SwitchEntity] = [
GreeControllerZoneEnabledSwitch(runtime.coordinator, str(zone["zone_id"]))
for zone in runtime.coordinator.plan.get("zones", [])
if zone.get("zone_id")
]
for device_id, device in runtime.coordinator.data.items():
for field, support_field, name in DEVICE_FEATURE_SWITCHES:
if device.get(support_field) is True:
entities.append(GreeControllerDeviceFeatureSwitch(runtime.coordinator, device_id, field, support_field, name))
async_add_entities(entities)
@@ -75,3 +90,61 @@ class GreeControllerZoneEnabledSwitch(CoordinatorEntity[GreeControllerCoordinato
async def async_turn_off(self, **kwargs: Any) -> None:
await self.coordinator.client.zone_control(self._zone_id, {"enabled": False})
await self.coordinator.async_request_refresh()
class GreeControllerDeviceFeatureSwitch(CoordinatorEntity[GreeControllerCoordinator], SwitchEntity):
"""Optional GREE unit feature exposed only when the controller detected it."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: GreeControllerCoordinator,
device_id: str,
field: str,
support_field: str,
name: str,
) -> None:
super().__init__(coordinator)
self._device_id = device_id
self._field = field
self._support_field = support_field
self._attr_name = name
self._attr_unique_id = f"{device_id}-{field}"
@property
def _device(self) -> dict[str, Any]:
return self.coordinator.data.get(self._device_id, {})
@property
def available(self) -> bool:
return (
super().available
and bool(self._device.get("online", False))
and self._device.get(self._support_field) is True
)
@property
def is_on(self) -> bool:
return bool(self._device.get(self._field, False))
@property
def device_info(self) -> DeviceInfo:
device = self._device
return DeviceInfo(
identifiers={(DOMAIN, self._device_id)},
name=str(device.get("name") or self._device_id),
manufacturer="GREE",
model=str(device.get("model") or "GREE HVAC"),
sw_version=str(device.get("firmware") or "") or None,
)
async def _set(self, value: bool) -> None:
await self.coordinator.client.command(self._device_id, {self._field: value})
await self.coordinator.async_request_refresh()
async def async_turn_on(self, **kwargs: Any) -> None:
await self._set(True)
async def async_turn_off(self, **kwargs: Any) -> None:
await self._set(False)