diff --git a/custom_components/xiaomi_home/cover.py b/custom_components/xiaomi_home/cover.py
index dcc512f..08398e6 100644
--- a/custom_components/xiaomi_home/cover.py
+++ b/custom_components/xiaomi_home/cover.py
@@ -47,7 +47,7 @@ Cover entities for Xiaomi Home.
 """
 from __future__ import annotations
 import logging
-from typing import Optional
+from typing import Any, Optional
 
 from homeassistant.config_entries import ConfigEntry
 from homeassistant.core import HomeAssistant
@@ -101,7 +101,11 @@ class Cover(MIoTServiceEntity, CoverEntity):
     _prop_status_closed: Optional[list[int]]
     _prop_current_position: Optional[MIoTSpecProperty]
     _prop_target_position: Optional[MIoTSpecProperty]
+    _prop_position_value_min: Optional[int]
+    _prop_position_value_max: Optional[int]
     _prop_position_value_range: Optional[int]
+    _prop_pos_closing: bool
+    _prop_pos_opening: bool
 
     def __init__(self, miot_device: MIoTDevice,
                  entity_data: MIoTEntityData) -> None:
@@ -122,7 +126,11 @@ class Cover(MIoTServiceEntity, CoverEntity):
         self._prop_status_closed = []
         self._prop_current_position = None
         self._prop_target_position = None
+        self._prop_position_value_min = None
+        self._prop_position_value_max = None
         self._prop_position_value_range = None
+        self._prop_pos_closing = False
+        self._prop_pos_opening = False
 
         # properties
         for prop in entity_data.props:
@@ -166,6 +174,8 @@ class Cover(MIoTServiceEntity, CoverEntity):
                         'invalid current-position value_range format, %s',
                         self.entity_id)
                     continue
+                self._prop_position_value_min = prop.value_range.min_
+                self._prop_position_value_max = prop.value_range.max_
                 self._prop_position_value_range = (prop.value_range.max_ -
                                                    prop.value_range.min_)
                 self._prop_current_position = prop
@@ -175,23 +185,52 @@ class Cover(MIoTServiceEntity, CoverEntity):
                         'invalid target-position value_range format, %s',
                         self.entity_id)
                     continue
+                self._prop_position_value_min = prop.value_range.min_
+                self._prop_position_value_max = prop.value_range.max_
                 self._prop_position_value_range = (prop.value_range.max_ -
                                                    prop.value_range.min_)
                 self._attr_supported_features |= CoverEntityFeature.SET_POSITION
                 self._prop_target_position = prop
+        # For the device that has the current position property but no status
+        # property, the current position property will be used to determine the
+        # opening and the closing status.
+        if (self._prop_status is None) and (self._prop_current_position
+                                            is not None):
+            self.sub_prop_changed(self._prop_current_position,
+                                  self._position_changed_handler)
+
+    def _position_changed_handler(self, prop: MIoTSpecProperty,
+                                  ctx: Any) -> None:
+        self._prop_pos_closing = False
+        self._prop_pos_opening = False
+        self.async_write_ha_state()
 
     async def async_open_cover(self, **kwargs) -> None:
         """Open the cover."""
+        current = None if (self._prop_current_position
+                           is None) else self.get_prop_value(
+                               prop=self._prop_current_position)
+        if (current is not None) and (current < self._prop_position_value_max):
+            self._prop_pos_opening = True
+            self._prop_pos_closing = False
         await self.set_property_async(self._prop_motor_control,
                                       self._prop_motor_value_open)
 
     async def async_close_cover(self, **kwargs) -> None:
         """Close the cover."""
+        current = None if (self._prop_current_position
+                           is None) else self.get_prop_value(
+                               prop=self._prop_current_position)
+        if (current is not None) and (current > self._prop_position_value_min):
+            self._prop_pos_opening = False
+            self._prop_pos_closing = True
         await self.set_property_async(self._prop_motor_control,
                                       self._prop_motor_value_close)
 
     async def async_stop_cover(self, **kwargs) -> None:
         """Stop the cover."""
+        self._prop_pos_opening = False
+        self._prop_pos_closing = False
         await self.set_property_async(self._prop_motor_control,
                                       self._prop_motor_value_pause)
 
@@ -200,6 +239,10 @@ class Cover(MIoTServiceEntity, CoverEntity):
         pos = kwargs.get(ATTR_POSITION, None)
         if pos is None:
             return None
+        current = self.current_cover_position
+        if current is not None:
+            self._prop_pos_opening = pos > current
+            self._prop_pos_closing = pos < current
         pos = round(pos * self._prop_position_value_range / 100)
         await self.set_property_async(prop=self._prop_target_position,
                                       value=pos)
@@ -214,9 +257,11 @@ class Cover(MIoTServiceEntity, CoverEntity):
             # Assume that the current position is the same as the target
             # position when the current position is not defined in the device's
             # MIoT-Spec-V2.
-            return None if (self._prop_target_position
-                            is None) else self.get_prop_value(
-                                prop=self._prop_target_position)
+            if self._prop_target_position is None:
+                return None
+            self._prop_pos_opening = False
+            self._prop_pos_closing = False
+            return self.get_prop_value(prop=self._prop_target_position)
         pos = self.get_prop_value(prop=self._prop_current_position)
         return None if pos is None else round(pos * 100 /
                                               self._prop_position_value_range)
@@ -227,14 +272,9 @@ class Cover(MIoTServiceEntity, CoverEntity):
         if self._prop_status and self._prop_status_opening:
             return (self.get_prop_value(prop=self._prop_status)
                     in self._prop_status_opening)
-        # The status is prior to the numerical relationship of the current
-        # position and the target position when determining whether the cover
+        # The status has higher priority when determining whether the cover
         # is opening.
-        if (self._prop_target_position and
-                self.current_cover_position is not None):
-            return (self.current_cover_position
-                    < self.get_prop_value(prop=self._prop_target_position))
-        return None
+        return self._prop_pos_opening
 
     @property
     def is_closing(self) -> Optional[bool]:
@@ -242,14 +282,9 @@ class Cover(MIoTServiceEntity, CoverEntity):
         if self._prop_status and self._prop_status_closing:
             return (self.get_prop_value(prop=self._prop_status)
                     in self._prop_status_closing)
-        # The status is prior to the numerical relationship of the current
-        # position and the target position when determining whether the cover
+        # The status has higher priority when determining whether the cover
         # is closing.
-        if (self._prop_target_position and
-                self.current_cover_position is not None):
-            return (self.current_cover_position
-                    > self.get_prop_value(prop=self._prop_target_position))
-        return None
+        return self._prop_pos_closing
 
     @property
     def is_closed(self) -> Optional[bool]: