Просмотр исходного кода

Fix cover state stuck on opening/closing when motor settles near target (#5483)

For covers without a reliable action dp, _current_state resolves a mid
position by comparing the set position with the current position, but
required them to be exactly equal. Motors that settle a percent or two
off their target (e.g. Zemismart ZM25R2) never satisfy the comparison,
so the state falls through to the last control command and reports
opening/closing indefinitely (or unknown once the control dp returns to
stop), even though the cover is stationary.

Allow a small tolerance (2%) in the comparison, matching the intent of
the existing comment ("around the set position").
Peter Rojs 4 дней назад
Родитель
Сommit
72dc0cb4d0
2 измененных файлов с 7 добавлено и 1 удалено
  1. 1 1
      custom_components/tuya_local/cover.py
  2. 6 0
      tests/test_cover.py

+ 1 - 1
custom_components/tuya_local/cover.py

@@ -153,7 +153,7 @@ class TuyaLocalCover(TuyaLocalEntity, CoverEntity):
             and self._position_dp
         ):
             setpos = self._position_dp.get_value(self._device)
-            if setpos == pos:
+            if setpos is not None and abs(setpos - pos) <= 2:
                 # if the current position is around the set position,
                 # which is not closed, then we want is_closed to return
                 # false, so HA gets the full state from position.

+ 6 - 0
tests/test_cover.py

@@ -350,6 +350,12 @@ class TestCurrentState:
         cover._position_dp.get_value.return_value = 50
         assert cover._current_state == "opened"
 
+    def test_mid_position_near_setpos_is_opened(self):
+        cover = _make_cover(action=False, currentpos=True, position=True)
+        cover._currentpos_dp.get_value.return_value = 49
+        cover._position_dp.get_value.return_value = 50
+        assert cover._current_state == "opened"
+
     def test_mid_position_with_open_cmd_is_opening(self):
         cover = _make_cover(action=False, currentpos=True, position=True, control=True)
         cover._currentpos_dp.get_value.return_value = 50