Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow changing level or tilt while blind is moving #1549

Merged

Conversation

sleiner
Copy link
Contributor

@sleiner sleiner commented May 7, 2024

Addresses #1506.

Test setup:

  • HMIP-BBL (firmware version 1.10.6)
  • RaspberryMatic 3.75.7.20240420
  • custom_homematic 53f70f7

Copy link
Contributor Author

@sleiner sleiner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SukramJ I will be offline for the rest of the week, but I wanted to get a first draft out there for you to review the overall concept.

"""Stop the device if in motion."""
await self._e_stop.send_value(value=True, collector=collector)
"""Stop the device if in motion. Use only when command_processing_lock is held."""
await self.stop(collector=collector)

def is_state_change(self, **kwargs: Any) -> bool:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be made aware of target positions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ich habe das mal versucht - so richtig glücklich war ich mit dem Ergebnis nicht. Das Problem ist, dass sowohl die einzelnen Methoden (wie open, close, open_tilt, vent, ...) als auch is_state_change unabhängig voneinander bestimmen, wie Target Level (und Target Tilt Level) abhängig von der auszuführenden Aktion zu setzen sind. Wenn hier noch eine Überprüfung von target_level und target_tilt_level dazukommt, wird es schnell sehr unübersichtlich.

Aus meiner Sicht wäre es sinnvoll, das Ableiten der Ziellevel und die Überprüfung, ob für gegebene Ziellevel ein neues Kommando gesendet werden muss, klar zu separieren. Dann kann man das Ableiten der Ziellevel auch an einer Stelle tun. Das wäre aber auch in nem eigenen PR ganz gut aufgehoben - was meinst du, @SukramJ?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hört sich gut am

hahomematic/platforms/custom/cover.py Outdated Show resolved Hide resolved
@SukramJ
Copy link
Owner

SukramJ commented May 8, 2024

Ich gehe mal davon aus, das du den Code nicht gegen ein Gerät getestet hast, das sollte aber dein Ziel sein.

Die Verwendung des Locks halte ich für unnötig, da der betroffene Codeabschnitt nur eine Ausführungszeit im Millisekunden bereich hat. Wenn der collector alle Daten gesammelt hat wird ein Befehl an die CCU gesendet, und nicht auf ein Ergebnis gewartet. Selbst wenn der Lock eine Befehlsausführung abwarten würde, sollte der Stop Befehl nicht auf eine Lockfreigabe warten müssen, sondern immer sofort ausgeführt werden.

Daher wird in #1512 statt eines Locks die command_queue (FIFO) verwendet und mit wait_for_callback innerhalb des definierten Timeouts auf ein Ergebnis gewartet. Die Ergebnisse werden in der empfangenen Reihenfolge abgearbeitet, und die Verarbeitung kann jederzeit unterbrochen werden. Würde mich freuen, wenn Du das auch testen könntest.

Egal wie es weitergeht solltest Du als nächste deine lokale Entwicklungsumgebung soweit ertüchtigen, dass Du eine Codeänderung mit HA gegen ein echtes Gerät schicken kannst.
Wenn Du dabei Hilfe brauchst, dann melde dich. Ich werde allerdings über das verlängerte Wochenende wohl nicht erreichbar sein.

@sleiner
Copy link
Contributor Author

sleiner commented May 8, 2024

Ich gehe mal davon aus, das du den Code nicht gegen ein Gerät getestet hast, das sollte aber dein Ziel sein.

Das hab ich natürlich getan (siehe PR-Beschreibung) 😉


Daher wird in #1512 statt eines Locks die command_queue (FIFO) verwendet und mit wait_for_callback innerhalb des definierten Timeouts auf ein Ergebnis gewartet. Die Ergebnisse werden in der empfangenen Reihenfolge abgearbeitet, und die Verarbeitung kann jederzeit unterbrochen werden. Würde mich freuen, wenn Du das auch testen könntest.

Das habe ich als allererstes getan. Wenn command_queue und wait_for_callback aktiv sind, tritt z.B. beim Aktivieren von Szenen diese Race Condition zuverlässig auf. Da werden halt zwei Service Calls direkt hintereinander. Das ergibt aus meiner Sicht schon Sinn, dass in der Zwischenzeit nicht asynchron ein Netzwerkrequest an die CCU rausgehen kann. Hier sind wir dann im Sub-Millisekundenbereich.

@SukramJ
Copy link
Owner

SukramJ commented May 8, 2024

Das hab ich natürlich getan (siehe PR-Beschreibung) 😉

Für mich geht das da nicht draus hervor.

Die Frage ist allerdings über welche Racecondition wir hier sprechen, und da könnte das Verständnisproblem sein.

Ich will dafür sorgen das die Befehle gegen das Gerät nacheinander, und erst nach Abschluss der Vorgängeraktion ausgeführt werden, aber auch jederzeit gestoppt werden können.

Du willst dafür sorgen, das nicht parallel an neuen Befehlen im HA Code gearbeitet wird, und so wiedersprüchliche Befehle für die CCU entstehen. Richtig?

@sleiner
Copy link
Contributor Author

sleiner commented May 8, 2024

Weil mir aufgefallen ist, dass diese Race Condition nicht offensichtlich ist, hier nochmal eine Erklärung:

Das Problem ist nicht, dass zwei Requests an die CCU sehr kurz nacheinander abgesendet werden und der zweite vom ersten überholt würde. Genau dieses Problem würde die command_queue ja lösen.

Das Problem ist, dass _set_level via _target_level und _target_tilt_level auf den command cache zugreift. Wenn also _set_level ein zweites Mal betreten wird, ohne dass der command cache schon mit den Daten des vorherigen Calls aktualisiert wurde, sind _target_level und _target_tilt_level potenziell falsch. In dem Fall sind dann die Ziellevel im zweiten Kommando tatsächlich schon falsch.

Das heißt, das lesen und aktualisieren von _target_level und _target_tilt_level muss "am Stück" passieren, das ist das, was das Lock schützen soll. Da _target_level und _target_tilt_level aus dem Command Cache kommen, und der erst beim Senden des tatsächlichen Kommandos aktualisiert wird, habe ich das Senden des Kommandos auch mit in die "gelockte" Region reingenommen. Hast Du eine Idee, wie man das noch anders oder kleinteiliger hinbekommen würde, @SukramJ?

@SukramJ
Copy link
Owner

SukramJ commented May 8, 2024

Danke für deine Erklärung.

Genau dieses Problem würde die command_queue ja lösen.

Die command_queue ist in diesem PR aber deaktiviert.

hahomematic/platforms/custom/cover.py Outdated Show resolved Hide resolved
hahomematic/platforms/custom/cover.py Outdated Show resolved Hide resolved
hahomematic/platforms/custom/cover.py Outdated Show resolved Hide resolved
hahomematic/platforms/custom/cover.py Outdated Show resolved Hide resolved
sleiner and others added 5 commits May 13, 2024 11:33
Previously, the test case would succeed even when a command queue was
being used. Since that leads to bugs on a real CCU (where the time for
sending a command is not negligible), this commit introduces a similar
communication delay to the test.

At the same time, this allows us to reduce the number of iterations that
this test needs to run in order to be reasonably sure that a race
condition is absent.
@Jack77777777
Copy link

Jack77777777 commented May 14, 2024

Wann können wir mit einem Merge und neuen Release rechnen? Würde das gerne testen.

@SukramJ
Copy link
Owner

SukramJ commented May 14, 2024

Wann können wir mit einem Merge und neuen Release rechnen?

Wenn es soweit ist.

@SukramJ
Copy link
Owner

SukramJ commented May 14, 2024

Ist sonst noch irgendwas offen?
Bei dir funktioniert mit den Geräten alles wie erwartet?

@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 92.68293% with 3 lines in your changes are missing coverage. Please review.

Project coverage is 88.47%. Comparing base (ec5d62b) to head (457f5a4).
Report is 77 commits behind head on devel.

Files Patch % Lines
hahomematic/platforms/custom/cover.py 92.68% 3 Missing ⚠️

❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@            Coverage Diff             @@
##            devel    #1549      +/-   ##
==========================================
- Coverage   90.42%   88.47%   -1.95%     
==========================================
  Files          49       52       +3     
  Lines        6037     6430     +393     
==========================================
+ Hits         5459     5689     +230     
- Misses        578      741     +163     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@SukramJ
Copy link
Owner

SukramJ commented May 14, 2024

Dann gehe ich auch davon aus das PR #1512 nicht benötigt wird. Oder?

@SukramJ
Copy link
Owner

SukramJ commented May 14, 2024

@sleiner Dann kann der PR gemerged werden?

@SukramJ SukramJ merged commit 32c8d8c into SukramJ:devel May 14, 2024
4 checks passed
@Jack77777777
Copy link

@SukramJ Jetzt müssen wir auf 1.62 warten richtig ?

@hvorragend
Copy link

hvorragend commented May 15, 2024

@SukramJ Jetzt müssen wir auf 1.62 warten richtig ?

@Jack77777777:
Freue dich nicht zu früh bzgl. meines CCA-Blueprints. Ich habe zwar in der aktuelle Version ein konfigurierbares Tilt-Delay ergänzt, aber ich kann die Positionserkennung nicht anhand des Attributes 'current_tilt_position' durchführen.
Daher weiß ich auch nicht, ob dieser PR uns dabei hilft.

@SukramJ
Copy link
Owner

SukramJ commented May 15, 2024

Geschlossene PR sind kein Diskussionsforum!

Repository owner locked as resolved and limited conversation to collaborators May 15, 2024
@SukramJ
Copy link
Owner

SukramJ commented May 15, 2024

Siehe #1506 (reply in thread)

@sleiner sleiner deleted the fix/new-blind-position-while-moving branch May 17, 2024 06:44
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants