Repository: XKNX/xknx

Issue:
 cover.set_cover_position not stopping with no position_address
**Description of problem:**

Dear xknx team,

covers with **no position_address** do not longer stop when moving the slider in the ha frontpanel to a position e.g. 30%. I attached my according HA config as well as some debug log from HA. This was working in precious versions of Home Assistant for me ( version 0.111).

The **service cover.set_cover_position ist not stopping at this value**. The services cover.close_cover;  service cover.open_cover;  cover.stop_cover are working currently.

Maybe a bug to the reworked travelcalculator / cover.py? It seems to me, that there is no stop movement send to actor when the calculated position is reached.

Remark: My covers do not have a positional feedback. But this applies not only to my knx config, this reproducible to other knx hardware setup with HA as well (a friend of mine reproduces this bug with his knx covers (which have a position_address). When deleting the position address in his config, this bug occurs as well. It would be great, to have this feature back / working again! Let me know, if i can assist you reproducing this bug. 

All the best 
Jan


- [x ] using Home-Assistant knx plugin

**Version information:**
- xknx / Home-Assistant release with the issue:  0.116.4
- last working xknx / Home-Assistant release (if known): 0.111


**KNX installation:**
<!--
- Manufacturer and model of relevant actors, sensors or interfaces.

-->

**Problem-relevant `xknx.yaml` or `configuration.yaml` entries (fill out even if it seems unimportant):**
[LOG_ha.txt](https://github.com/XKNX/xknx/files/5434327/LOG_ha.txt)
[knx_cover.yaml.txt](https://github.com/XKNX/xknx/files/5434337/knx_cover.yaml.txt)
[knx.yaml.txt](https://github.com/XKNX/xknx/files/5434338/knx.yaml.txt)
![Log](https://user-images.githubusercontent.com/19536666/97102778-98466880-16a8-11eb-93fd-f1ca839db2ed.JPG)


Comments:

Patch:
diff --git a/changelog.md b/changelog.md
index b3ef0a15..5ed77445 100644
--- a/changelog.md
+++ b/changelog.md
@@ -12,6 +12,7 @@
 ### Bugfixes
 
 - HA Switch entity: keep state without state_address
+- Cover: fix `set_position` without writable position / auto_stop_if_necessary
 
 ## 0.15.2 Winter is coming
 
diff --git a/xknx/devices/cover.py b/xknx/devices/cover.py
index 4ff53c1a..7596c1e5 100644
--- a/xknx/devices/cover.py
+++ b/xknx/devices/cover.py
@@ -270,13 +270,20 @@ class Cover(Device):
 
     async def process_group_write(self, telegram):
         """Process incoming and outgoing GROUP WRITE telegram."""
+        # call after_update to account for travelcalculator changes
         if await self.updown.process(telegram):
-            if self.updown.value == RemoteValueUpDown.Direction.UP:
+            if (
+                not self.is_opening()
+                and self.updown.value == RemoteValueUpDown.Direction.UP
+            ):
                 self.travelcalculator.start_travel_up()
-            else:
+                await self.after_update()
+            elif (
+                not self.is_closing()
+                and self.updown.value == RemoteValueUpDown.Direction.DOWN
+            ):
                 self.travelcalculator.start_travel_down()
-            # call after_update to account for travelcalculator changes
-            await self.after_update()
+                await self.after_update()
         # stop from bus
         if await self.stop_.process(telegram) or await self.step.process(telegram):
             if self.is_traveling():


Test patch:
diff --git a/test/devices_tests/cover_test.py b/test/devices_tests/cover_test.py
index 16e4547c..0865454c 100644
--- a/test/devices_tests/cover_test.py
+++ b/test/devices_tests/cover_test.py
@@ -397,6 +397,10 @@ class TestCover(unittest.TestCase):
             telegram, Telegram(GroupAddress("1/2/1"), payload=DPTBinary(0))
         )
         self.assertEqual(cover.travelcalculator.travel_to_position, 50)
+        self.assertTrue(cover.is_opening())
+        # process the outgoing telegram to make sure it doesn't overwrite the target position
+        self.loop.run_until_complete(cover.process(telegram))
+        self.assertEqual(cover.travelcalculator.travel_to_position, 50)
 
     def test_position_without_position_address_down(self):
         """Test moving cover down - with no absolute positioning supported."""
@@ -416,6 +420,10 @@ class TestCover(unittest.TestCase):
             telegram, Telegram(GroupAddress("1/2/1"), payload=DPTBinary(1))
         )
         self.assertEqual(cover.travelcalculator.travel_to_position, 80)
+        self.assertTrue(cover.is_closing())
+        # process the outgoing telegram to make sure it doesn't overwrite the target position
+        self.loop.run_until_complete(cover.process(telegram))
+        self.assertEqual(cover.travelcalculator.travel_to_position, 80)
 
     def test_position_without_position_address_uninitialized_up(self):
         """Test moving uninitialized cover to absolute position - with no absolute positioning supported."""