diff --git a/custom_components/sonoff/core/devices.py b/custom_components/sonoff/core/devices.py index b98cac0f..4ffb2aeb 100644 --- a/custom_components/sonoff/core/devices.py +++ b/custom_components/sonoff/core/devices.py @@ -21,7 +21,7 @@ from ..binary_sensor import XBinarySensor, XWiFiDoor, XZigbeeMotion from ..climate import XClimateNS, XClimateTH, XThermostat from ..core.entity import XEntity -from ..cover import XCover, XCoverDualR3, XZigbeeCover +from ..cover import XCover, XCoverDualR3, XZigbeeCover, XCover91 from ..fan import XDiffuserFan, XFan, XToggleFan, XFanDualR3 from ..light import ( XDiffuserLight, @@ -55,7 +55,6 @@ XEnergySensorPOWR3, XEnergyTotal, XT5Action, - XButton91, ) from ..switch import ( XSwitch, @@ -212,7 +211,7 @@ def spec(cls, base: str = None, enabled: bool = None, **kwargs) -> type: 82: SPEC_2CH, 83: SPEC_3CH, 84: SPEC_4CH, - 91: [XButton91], + 91: [XCover91], 102: [XWiFiDoor, XWiFiDoorBattery, RSSI], # Sonoff DW2 Door/Window sensor 103: [XLightB02, RSSI], # Sonoff B02 CCT bulb 104: [XLightB05B, RSSI], # Sonoff B05-B RGB+CCT color bulb diff --git a/custom_components/sonoff/cover.py b/custom_components/sonoff/cover.py index 91607547..1d0f8414 100644 --- a/custom_components/sonoff/cover.py +++ b/custom_components/sonoff/cover.py @@ -132,3 +132,31 @@ async def async_close_cover(self, **kwargs): async def async_set_cover_position(self, position: int, **kwargs): await self.ewelink.send(self.device, {"openPercent": 100 - position}) + + +# https://github.com/AlexxIT/SonoffLAN/issues/1304 +class XCover91(XEntity, CoverEntity): + param = "op" + + _attr_is_closed = None # unknown state + + def set_state(self, params: dict): + if v := params.get(self.param): + if v == 1: + self._attr_is_opening = True + self._attr_is_closing = False + elif v == 2: + self._attr_is_opening = False + self._attr_is_closing = False + elif v == 3: + self._attr_is_opening = False + self._attr_is_closing = True + + async def async_stop_cover(self, **kwargs): + await self.ewelink.send(self.device, {self.param: 2}) + + async def async_open_cover(self, **kwargs): + await self.ewelink.send(self.device, {self.param: 1}) + + async def async_close_cover(self, **kwargs): + await self.ewelink.send(self.device, {self.param: 3}) diff --git a/custom_components/sonoff/sensor.py b/custom_components/sonoff/sensor.py index 09bb61fd..a1b64fa6 100644 --- a/custom_components/sonoff/sensor.py +++ b/custom_components/sonoff/sensor.py @@ -347,15 +347,6 @@ def set_state(self, params: dict): asyncio.create_task(self.clear_state()) -class XButton91(XEventSesor): - params = {"op"} - - def set_state(self, params: dict): - button = params["op"] - self._attr_native_value = f"button_{button}" - asyncio.create_task(self.clear_state()) - - class XUnknown(XEntity, SensorEntity): _attr_device_class = SensorDeviceClass.TIMESTAMP diff --git a/tests/test_entity.py b/tests/test_entity.py index 50353350..9c45ce8f 100644 --- a/tests/test_entity.py +++ b/tests/test_entity.py @@ -26,7 +26,7 @@ SIGNAL_CONNECTED, SIGNAL_UPDATE, ) -from custom_components.sonoff.cover import XCover, XCoverDualR3, XZigbeeCover +from custom_components.sonoff.cover import XCover, XCoverDualR3, XZigbeeCover, XCover91 from custom_components.sonoff.fan import XFan from custom_components.sonoff.light import ( UIID22_MODES, @@ -47,7 +47,6 @@ XUnknown, XEnergySensorDualR3, XT5Action, - XButton91, XEnergyTotal, ) from custom_components.sonoff.switch import ( @@ -1658,11 +1657,11 @@ def test_t5(): def test_91(): entities = get_entitites({"extra": {"uiid": 91}, "params": {"op": 1}}) - action: XButton91 = entities[0] - assert action.state == "" + cover: XCover91 = entities[0] + assert cover.state == "opening" - action.internal_update({"op": 2}) - assert action.state == "button_2" + cover.internal_update({"op": 2}) + assert cover.state is None def test_powr3():