135 lines
5.2 KiB
Python
135 lines
5.2 KiB
Python
|
from homeassistant.components.cover import CoverDeviceClass, CoverEntity
|
||
|
|
||
|
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, CoverEntity)]),
|
||
|
)
|
||
|
|
||
|
|
||
|
# noinspection PyUnresolvedReferences
|
||
|
DEVICE_CLASSES = {cls.value: cls for cls in CoverDeviceClass}
|
||
|
|
||
|
|
||
|
# noinspection PyAbstractClass
|
||
|
class XCover(XEntity, CoverEntity):
|
||
|
params = {"switch", "setclose"}
|
||
|
|
||
|
def __init__(self, ewelink: XRegistry, device: dict):
|
||
|
XEntity.__init__(self, ewelink, device)
|
||
|
self._attr_device_class = DEVICE_CLASSES.get(device.get("device_class"))
|
||
|
|
||
|
def set_state(self, params: dict):
|
||
|
# => command to cover from mobile app
|
||
|
if len(params) == 1:
|
||
|
if "switch" in params:
|
||
|
# device receive command - on=open/off=close/pause=stop
|
||
|
self._attr_is_opening = params["switch"] == "on"
|
||
|
self._attr_is_closing = params["switch"] == "off"
|
||
|
elif "setclose" in params:
|
||
|
# device receive command - mode to position
|
||
|
pos = 100 - params["setclose"]
|
||
|
self._attr_is_closing = pos < self.current_cover_position
|
||
|
self._attr_is_opening = pos > self.current_cover_position
|
||
|
|
||
|
# BINTHEN BCM Series payload:
|
||
|
# {"sequence":"1652428259464","setclose":38}
|
||
|
# KingArt KING-Q4 payloads:
|
||
|
# {"switch":"off","setclose":21} or {"switch":"on","setclose":0}
|
||
|
elif "setclose" in params:
|
||
|
# the device has finished the action
|
||
|
# reversed position: HA closed at 0, eWeLink closed at 100
|
||
|
self._attr_current_cover_position = 100 - params["setclose"]
|
||
|
self._attr_is_closed = self.current_cover_position == 0
|
||
|
self._attr_is_closing = False
|
||
|
self._attr_is_opening = False
|
||
|
|
||
|
async def async_stop_cover(self, **kwargs):
|
||
|
params = {"switch": "pause"}
|
||
|
self.set_state(params)
|
||
|
self._async_write_ha_state()
|
||
|
await self.ewelink.send(self.device, params, query_cloud=False)
|
||
|
|
||
|
async def async_open_cover(self, **kwargs):
|
||
|
params = {"switch": "on"}
|
||
|
self.set_state(params)
|
||
|
self._async_write_ha_state()
|
||
|
await self.ewelink.send(self.device, params, query_cloud=False)
|
||
|
|
||
|
async def async_close_cover(self, **kwargs):
|
||
|
params = {"switch": "off"}
|
||
|
self.set_state(params)
|
||
|
self._async_write_ha_state()
|
||
|
await self.ewelink.send(self.device, params, query_cloud=False)
|
||
|
|
||
|
async def async_set_cover_position(self, position: int, **kwargs):
|
||
|
params = {"setclose": 100 - position}
|
||
|
self.set_state(params)
|
||
|
self._async_write_ha_state()
|
||
|
await self.ewelink.send(self.device, params, query_cloud=False)
|
||
|
|
||
|
|
||
|
# noinspection PyAbstractClass
|
||
|
class XCoverDualR3(XCover):
|
||
|
params = {"currLocation", "motorTurn"}
|
||
|
|
||
|
def set_state(self, params: dict):
|
||
|
if "currLocation" in params:
|
||
|
# 0 - closed, 100 - opened
|
||
|
self._attr_current_cover_position = params["currLocation"]
|
||
|
self._attr_is_closed = self._attr_current_cover_position == 0
|
||
|
|
||
|
if "motorTurn" in params:
|
||
|
if params["motorTurn"] == 0: # stop
|
||
|
self._attr_is_opening = False
|
||
|
self._attr_is_closing = False
|
||
|
elif params["motorTurn"] == 1:
|
||
|
self._attr_is_opening = True
|
||
|
self._attr_is_closing = False
|
||
|
elif params["motorTurn"] == 2:
|
||
|
self._attr_is_opening = False
|
||
|
self._attr_is_closing = True
|
||
|
|
||
|
async def async_stop_cover(self, **kwargs):
|
||
|
await self.ewelink.send(self.device, {"motorTurn": 0})
|
||
|
|
||
|
async def async_open_cover(self, **kwargs):
|
||
|
await self.ewelink.send(self.device, {"motorTurn": 1})
|
||
|
|
||
|
async def async_close_cover(self, **kwargs):
|
||
|
await self.ewelink.send(self.device, {"motorTurn": 2})
|
||
|
|
||
|
async def async_set_cover_position(self, position: int, **kwargs):
|
||
|
await self.ewelink.send(self.device, {"location": position})
|
||
|
|
||
|
|
||
|
# noinspection PyAbstractClass
|
||
|
class XZigbeeCover(XCover):
|
||
|
params = {"curPercent", "curtainAction"}
|
||
|
|
||
|
def set_state(self, params: dict):
|
||
|
if "curPercent" in params:
|
||
|
# reversed position: HA closed at 0, eWeLink closed at 100
|
||
|
self._attr_current_cover_position = 100 - params["curPercent"]
|
||
|
self._attr_is_closed = self._attr_current_cover_position == 0
|
||
|
|
||
|
async def async_stop_cover(self, **kwargs):
|
||
|
await self.ewelink.send(self.device, {"curtainAction": "pause"})
|
||
|
|
||
|
async def async_open_cover(self, **kwargs):
|
||
|
await self.ewelink.send(self.device, {"curtainAction": "open"})
|
||
|
|
||
|
async def async_close_cover(self, **kwargs):
|
||
|
await self.ewelink.send(self.device, {"curtainAction": "close"})
|
||
|
|
||
|
async def async_set_cover_position(self, position: int, **kwargs):
|
||
|
await self.ewelink.send(self.device, {"openPercent": 100 - position})
|