Motion Blinds opening closing (#68837)

This commit is contained in:
starkillerOG 2022-04-03 17:21:53 +02:00 committed by GitHub
parent 0558be0ab2
commit 2bb71cf6bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,4 +1,5 @@
"""Support for Motion Blinds using their WLAN API.""" """Support for Motion Blinds using their WLAN API."""
from enum import IntEnum
import logging import logging
from motionblinds import DEVICE_TYPES_WIFI, BlindType from motionblinds import DEVICE_TYPES_WIFI, BlindType
@ -38,6 +39,14 @@ from .const import (
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
class State(IntEnum):
"""Moving status of the blind."""
Closing = -1
Not_Moving = 0
Opening = 1
POSITION_DEVICE_MAP = { POSITION_DEVICE_MAP = {
BlindType.RollerBlind: CoverDeviceClass.SHADE, BlindType.RollerBlind: CoverDeviceClass.SHADE,
BlindType.RomanBlind: CoverDeviceClass.SHADE, BlindType.RomanBlind: CoverDeviceClass.SHADE,
@ -168,6 +177,7 @@ class MotionPositionDevice(CoordinatorEntity, CoverEntity):
self._blind = blind self._blind = blind
self._api_lock = coordinator.api_lock self._api_lock = coordinator.api_lock
self._moving = State.Not_Moving
self._requesting_position = False self._requesting_position = False
self._previous_positions = [] self._previous_positions = []
@ -224,6 +234,27 @@ class MotionPositionDevice(CoordinatorEntity, CoverEntity):
return None return None
return self._blind.position == 100 return self._blind.position == 100
@property
def is_opening(self):
"""Return if the cover is opening or not."""
if self.is_closed is None:
return None
return self._moving == State.Opening
@property
def is_closing(self):
"""Return if the cover is closing or not."""
if self.is_closed is None:
return None
return self._moving == State.Closing
def _set_moving_state(self, new_position, old_position):
"""Set the moving status for a position move."""
if new_position > old_position:
self._moving = State.Closing
else:
self._moving = State.Opening
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Subscribe to multicast pushes and register signal handler.""" """Subscribe to multicast pushes and register signal handler."""
self._blind.Register_callback(self.unique_id, self.schedule_update_ha_state) self._blind.Register_callback(self.unique_id, self.schedule_update_ha_state)
@ -244,8 +275,6 @@ class MotionPositionDevice(CoordinatorEntity, CoverEntity):
async with self._api_lock: async with self._api_lock:
await self.hass.async_add_executor_job(self._blind.Update_trigger) await self.hass.async_add_executor_job(self._blind.Update_trigger)
self.async_write_ha_state()
if len(self._previous_positions) < 2 or not all( if len(self._previous_positions) < 2 or not all(
self.current_cover_position == prev_position self.current_cover_position == prev_position
for prev_position in self._previous_positions for prev_position in self._previous_positions
@ -255,9 +284,12 @@ class MotionPositionDevice(CoordinatorEntity, CoverEntity):
self.hass, UPDATE_INTERVAL_MOVING, self.async_scheduled_update_request self.hass, UPDATE_INTERVAL_MOVING, self.async_scheduled_update_request
) )
else: else:
self._moving = State.Not_Moving
self._previous_positions = [] self._previous_positions = []
self._requesting_position = False self._requesting_position = False
self.async_write_ha_state()
async def async_request_position_till_stop(self): async def async_request_position_till_stop(self):
"""Request the position of the blind every UPDATE_INTERVAL_MOVING seconds until it stops moving.""" """Request the position of the blind every UPDATE_INTERVAL_MOVING seconds until it stops moving."""
self._previous_positions = [] self._previous_positions = []
@ -265,6 +297,7 @@ class MotionPositionDevice(CoordinatorEntity, CoverEntity):
return return
self._requesting_position = True self._requesting_position = True
self.async_write_ha_state()
async_call_later( async_call_later(
self.hass, UPDATE_INTERVAL_MOVING, self.async_scheduled_update_request self.hass, UPDATE_INTERVAL_MOVING, self.async_scheduled_update_request
) )
@ -273,12 +306,14 @@ class MotionPositionDevice(CoordinatorEntity, CoverEntity):
"""Open the cover.""" """Open the cover."""
async with self._api_lock: async with self._api_lock:
await self.hass.async_add_executor_job(self._blind.Open) await self.hass.async_add_executor_job(self._blind.Open)
self._moving = State.Opening
await self.async_request_position_till_stop() await self.async_request_position_till_stop()
async def async_close_cover(self, **kwargs): async def async_close_cover(self, **kwargs):
"""Close cover.""" """Close cover."""
async with self._api_lock: async with self._api_lock:
await self.hass.async_add_executor_job(self._blind.Close) await self.hass.async_add_executor_job(self._blind.Close)
self._moving = State.Closing
await self.async_request_position_till_stop() await self.async_request_position_till_stop()
async def async_set_cover_position(self, **kwargs): async def async_set_cover_position(self, **kwargs):
@ -288,21 +323,19 @@ class MotionPositionDevice(CoordinatorEntity, CoverEntity):
await self.hass.async_add_executor_job( await self.hass.async_add_executor_job(
self._blind.Set_position, 100 - position self._blind.Set_position, 100 - position
) )
self._set_moving_state(position, self._blind.position)
await self.async_request_position_till_stop() await self.async_request_position_till_stop()
async def async_set_absolute_position(self, **kwargs): async def async_set_absolute_position(self, **kwargs):
"""Move the cover to a specific absolute position (see TDBU).""" """Move the cover to a specific absolute position (see TDBU)."""
position = kwargs[ATTR_ABSOLUTE_POSITION] await self.async_set_cover_position(**kwargs)
async with self._api_lock:
await self.hass.async_add_executor_job(
self._blind.Set_position, 100 - position
)
await self.async_request_position_till_stop()
async def async_stop_cover(self, **kwargs): async def async_stop_cover(self, **kwargs):
"""Stop the cover.""" """Stop the cover."""
async with self._api_lock: async with self._api_lock:
await self.hass.async_add_executor_job(self._blind.Stop) await self.hass.async_add_executor_job(self._blind.Stop)
self._moving = State.Not_Moving
self.async_write_ha_state()
class MotionTiltDevice(MotionPositionDevice): class MotionTiltDevice(MotionPositionDevice):
@ -339,6 +372,8 @@ class MotionTiltDevice(MotionPositionDevice):
"""Stop the cover.""" """Stop the cover."""
async with self._api_lock: async with self._api_lock:
await self.hass.async_add_executor_job(self._blind.Stop) await self.hass.async_add_executor_job(self._blind.Stop)
self._moving = State.Not_Moving
self.async_write_ha_state()
class MotionTDBUDevice(MotionPositionDevice): class MotionTDBUDevice(MotionPositionDevice):
@ -394,12 +429,14 @@ class MotionTDBUDevice(MotionPositionDevice):
"""Open the cover.""" """Open the cover."""
async with self._api_lock: async with self._api_lock:
await self.hass.async_add_executor_job(self._blind.Open, self._motor_key) await self.hass.async_add_executor_job(self._blind.Open, self._motor_key)
self._moving = State.Opening
await self.async_request_position_till_stop() await self.async_request_position_till_stop()
async def async_close_cover(self, **kwargs): async def async_close_cover(self, **kwargs):
"""Close cover.""" """Close cover."""
async with self._api_lock: async with self._api_lock:
await self.hass.async_add_executor_job(self._blind.Close, self._motor_key) await self.hass.async_add_executor_job(self._blind.Close, self._motor_key)
self._moving = State.Closing
await self.async_request_position_till_stop() await self.async_request_position_till_stop()
async def async_set_cover_position(self, **kwargs): async def async_set_cover_position(self, **kwargs):
@ -409,6 +446,7 @@ class MotionTDBUDevice(MotionPositionDevice):
await self.hass.async_add_executor_job( await self.hass.async_add_executor_job(
self._blind.Set_scaled_position, 100 - position, self._motor_key self._blind.Set_scaled_position, 100 - position, self._motor_key
) )
self._set_moving_state(position, self._blind.scaled_position[self._motor_key])
await self.async_request_position_till_stop() await self.async_request_position_till_stop()
async def async_set_absolute_position(self, **kwargs): async def async_set_absolute_position(self, **kwargs):
@ -420,10 +458,12 @@ class MotionTDBUDevice(MotionPositionDevice):
await self.hass.async_add_executor_job( await self.hass.async_add_executor_job(
self._blind.Set_position, 100 - position, self._motor_key, target_width self._blind.Set_position, 100 - position, self._motor_key, target_width
) )
self._set_moving_state(position, self._blind.position[self._motor_key])
await self.async_request_position_till_stop() await self.async_request_position_till_stop()
async def async_stop_cover(self, **kwargs): async def async_stop_cover(self, **kwargs):
"""Stop the cover.""" """Stop the cover."""
async with self._api_lock: async with self._api_lock:
await self.hass.async_add_executor_job(self._blind.Stop, self._motor_key) await self.hass.async_add_executor_job(self._blind.Stop, self._motor_key)
self._moving = State.Not_Moving
self.async_write_ha_state()