165 lines
5.4 KiB
Python
165 lines
5.4 KiB
Python
from homeassistant.components.fan import (
|
|
FanEntity,
|
|
FanEntityFeature,
|
|
)
|
|
|
|
from .core.const import DOMAIN
|
|
from .core.entity import XEntity
|
|
from .core.ewelink import SIGNAL_ADD_ENTITIES, XRegistry
|
|
|
|
PARALLEL_UPDATES = 0 # fix entity_platform parallel_updates Semaphore
|
|
|
|
|
|
async def async_setup_entry(hass, config_entry, add_entities):
|
|
ewelink: XRegistry = hass.data[DOMAIN][config_entry.entry_id]
|
|
ewelink.dispatcher_connect(
|
|
SIGNAL_ADD_ENTITIES,
|
|
lambda x: add_entities([e for e in x if isinstance(e, FanEntity)]),
|
|
)
|
|
|
|
|
|
SPEED_OFF = "off"
|
|
SPEED_LOW = "low"
|
|
SPEED_MEDIUM = "medium"
|
|
SPEED_HIGH = "high"
|
|
|
|
|
|
# noinspection PyAbstractClass
|
|
class XFan(XEntity, FanEntity):
|
|
params = {"switches", "fan"}
|
|
_attr_speed_count = 3
|
|
_attr_supported_features = FanEntityFeature.SET_SPEED | FanEntityFeature.PRESET_MODE
|
|
_attr_preset_modes = [SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
|
|
|
|
def set_state(self, params: dict):
|
|
mode = None
|
|
# Cloud sends switches, LAN sends fan/speed
|
|
if "switches" in params:
|
|
s = {i["outlet"]: i["switch"] for i in params["switches"]}
|
|
if s[1] == "off":
|
|
pass
|
|
elif s[2] == "off" and s[3] == "off":
|
|
mode = SPEED_LOW
|
|
elif s[2] == "on" and s[3] == "off":
|
|
mode = SPEED_MEDIUM
|
|
elif s[2] == "off" and s[3] == "on":
|
|
mode = SPEED_HIGH
|
|
else:
|
|
if params["fan"] == "off":
|
|
pass
|
|
elif params["speed"] == 1:
|
|
mode = SPEED_LOW
|
|
elif params["speed"] == 2:
|
|
mode = SPEED_MEDIUM
|
|
elif params["speed"] == 3:
|
|
mode = SPEED_HIGH
|
|
|
|
self._attr_percentage = int(
|
|
self._attr_preset_modes.index(mode or SPEED_OFF)
|
|
/ self._attr_speed_count
|
|
* 100
|
|
)
|
|
self._attr_preset_mode = mode
|
|
|
|
async def async_set_percentage(self, percentage: int):
|
|
if percentage is None:
|
|
param = {1: "on"}
|
|
params_lan = {"fan": "on"}
|
|
elif percentage > 66:
|
|
param = {1: "on", 2: "off", 3: "on"} # high
|
|
params_lan = {"fan": "on", "speed": 3}
|
|
elif percentage > 33:
|
|
param = {1: "on", 2: "on", 3: "off"} # medium
|
|
params_lan = {"fan": "on", "speed": 2}
|
|
elif percentage > 0:
|
|
param = {1: "on", 2: "off", 3: "off"} # low
|
|
params_lan = {"fan": "on", "speed": 1}
|
|
else:
|
|
param = {1: "off"}
|
|
params_lan = {"fan": "off"}
|
|
param = [{"outlet": k, "switch": v} for k, v in param.items()]
|
|
# fan_light - iFan03 and iFan04 using new LAN API
|
|
# strip - iFan02 using old LAN API (same as cloud)
|
|
if self.device.get("localtype") != "fan_light":
|
|
params_lan = None
|
|
await self.ewelink.send(self.device, {"switches": param}, params_lan)
|
|
|
|
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
|
percentage = int(
|
|
self._attr_preset_modes.index(preset_mode) / self._attr_speed_count * 100
|
|
)
|
|
await self.async_set_percentage(percentage)
|
|
|
|
async def async_turn_on(self, percentage=None, preset_mode=None, **kwargs):
|
|
if preset_mode:
|
|
await self.async_set_preset_mode(preset_mode)
|
|
else:
|
|
await self.async_set_percentage(percentage)
|
|
|
|
async def async_turn_off(self):
|
|
await self.async_set_percentage(0)
|
|
|
|
|
|
# noinspection PyAbstractClass
|
|
class XDiffuserFan(XFan):
|
|
params = {"state", "switch"}
|
|
_attr_speed_count = 2
|
|
_attr_preset_modes = [SPEED_OFF, SPEED_LOW, SPEED_HIGH]
|
|
|
|
def set_state(self, params: dict):
|
|
if params["switch"] == "off":
|
|
self._attr_percentage = 0
|
|
self._attr_preset_mode = None
|
|
elif params["state"] == 1:
|
|
self._attr_percentage = 50
|
|
self._attr_preset_mode = SPEED_LOW
|
|
elif params["state"] == 2:
|
|
self._attr_percentage = 100
|
|
self._attr_preset_mode = SPEED_HIGH
|
|
|
|
async def async_set_percentage(self, percentage: int):
|
|
if percentage is None:
|
|
param = {"switch": "on"}
|
|
elif percentage > 50:
|
|
param = {"switch": "on", "state": 2}
|
|
elif percentage > 0:
|
|
param = {"switch": "on", "state": 1}
|
|
else:
|
|
param = {"switch": "off"}
|
|
await self.ewelink.send(self.device, param)
|
|
|
|
|
|
# noinspection PyAbstractClass
|
|
class XFanDualR3(XFan):
|
|
params = {"motorTurn"}
|
|
_attr_speed_count = 2
|
|
_attr_preset_modes = [SPEED_OFF, SPEED_LOW, SPEED_HIGH]
|
|
|
|
def set_state(self, params: dict):
|
|
if params["motorTurn"] == 0:
|
|
self._attr_percentage = 0
|
|
self._attr_preset_mode = None
|
|
elif params["motorTurn"] == 1:
|
|
self._attr_percentage = 50
|
|
self._attr_preset_mode = SPEED_LOW
|
|
elif params["motorTurn"] == 2:
|
|
self._attr_percentage = 100
|
|
self._attr_preset_mode = SPEED_HIGH
|
|
|
|
async def async_set_percentage(self, percentage: int):
|
|
if percentage is None:
|
|
param = {"motorTurn": 0}
|
|
elif percentage > 50:
|
|
param = {"motorTurn": 2}
|
|
elif percentage > 0:
|
|
param = {"motorTurn": 1}
|
|
else:
|
|
param = {"motorTurn": 0}
|
|
await self.ewelink.send(self.device, param)
|
|
|
|
|
|
# noinspection PyAbstractClass
|
|
class XToggleFan(XEntity, FanEntity):
|
|
@property
|
|
def is_on(self):
|
|
return self._attr_is_on
|