Rollladensteuerung: Alternativen zu DOIF

Begonnen von spi3845, 27 März 2017, 13:28:59

Vorheriges Thema - Nächstes Thema

spi3845

Hallo zusammen,

ich arbeite mich in DOIF ein und habe das Waschmaschinen- und Ampel-Beispiel aus https://forum.fhem.de/index.php/topic,49109.0.html und https://forum.fhem.de/index.php/topic,49109.30.html nachgebaut. Die Ampel mit drei unabhängigen DOIFs ist schon ein Gehirnverzwirner...

Zur Übung habe ich eine Rollladensteuerung mit Dummies nachgestellt. Grundsätzliche Funktionen wie Aussperrschutz funktionieren, aber einiges fehlt noch. Der Code würde dadurch aber immer komplexer. https://wiki.fhem.de/wiki/DOIF/do_always_Alternative_am_Beispiel_einer_Rollladenautomatik geht mir noch nicht weit genug...

Ich würde gerne hören, wie ihr solch ein Problem angehen würdet? Tatsächlich jede einzelne Bedingungen im DOIF abbilden? Oder mehrere DOIFs wie bei der Ampel?

Oder als Zustandsautomat im Sinne von https://wiki.fhem.de/wiki/DOIF/Mehrfachnutzung_eines_Tasters? Wobei auch diese Abbildung in einem DOIF komplex wird, da aus jedem Zustand (z.B. Rollladen unten/cmd=x) mehrere Aktionen zu beliebig anderen Zuständen führen können (z.B. Rollladen oben/cmd=y, Rolladen Lüften wenig/cmd=z, etc.), das wären dann viele Bedingungen in einem DOIF... Es gibt hier auch ein inoffzielles Modul für Zustandsautomaten: https://forum.fhem.de/index.php/topic,51796.0.html

Und hier der Beispielcode meiner Rollladensteuerung:
define timer_rollo dummy
attr timer_rollo room Test.Rollladen
attr timer_rollo setList auf zu
attr timer_rollo webCmd auf:zu
define tuer_re dummy
attr tuer_re room Test.Rollladen
attr tuer_re setList gekippt offen verschlossen
attr tuer_re webCmd gekippt:offen:verschlossen
define rollo_li dummy
attr rollo_li room Test.Rollladen
attr rollo_li setList unten oben
attr rollo_li webCmd unten:oben
define rollo_re dummy
attr rollo_re room Test.Rollladen
attr rollo_re setList unten oben irgendwo lueften_wenig lueften_viel stop
attr rollo_re webCmd unten:oben:irgendwo:lueften_wenig:lueften_viel:stop

define di_rolladensteuerung_2 DOIF ## autom. Schließen alle außer Tür-rechts, diese auf Lüften fahren, wenn gekippt\
([timer_rollo] =~ "zu" and [tuer_re] =~ "gekippt") \
(set rollo_li unten)\
(set rollo_re lueften_wenig)\
## autom. Schließen wenn Tür-rechts zu\
DOELSEIF ([timer_rollo] =~ "zu" and [tuer_re] =~ "verschlossen")\
(set rollo_li unten)\
(set rollo_re unten)\
## autom. Schließen wenn Tür-rechts offen\
DOELSEIF ([timer_rollo:"zu"] and [?tuer_re] !~ "verschlossen|gekippt")\
(set rollo_li unten)\
## autom. Lüften wenn Tür-rechts offen\
DOELSEIF ([timer_rollo] =~ "zu" and [tuer_re:"offen"] and [?rollo_re] =~ "lueften_wenig|lueften_viel|unten")\
(set rollo_re lueften_viel)\
## autom. Öffnen alle Rollos, wenn Tür-rechts gekippt oder geschlossen\
DOELSEIF ([timer_rollo:"auf"] and [tuer_re] =~ "gekippt|verschlossen") \
((set rollo_li,rollo_re oben))\
## autom. Öffnen alle Rollos, außer Tür-rechts wenn offen\
## wenn Rollladen rechts tiefer als Lüftern_wenig-Position, dann Öffnen bis Lüften_wenig,\
## sonst Rollladen rechts nicht fahren\
DOELSEIF ([timer_rollo:"auf"] and [tuer_re] !~ "gekippt|verschlossen") \
(set rollo_li oben)\
(IF ([rollo_re] !~ "lueften_wenig|unten") (set rollo_re lueften_wenig))\
## Lüften_wenig-Position\
DOELSEIF ([tuer_re:"gekippt"] and [?rollo_re] =~ "unten")\
(set rollo_re lueften_wenig)\
## Lüften_viel-Position\
DOELSEIF ([tuer_re:"offen"] and [?rollo_re] =~ "unten|lueften_wenig")\
(set rollo_re lueften_viel)\
## Schließen nach Lüften\
DOELSEIF ([tuer_re:"verschlossen"] and [?rollo_re] =~ "lueften_wenig|lueften_viel" and ([$SELF:cmd] == 7 or [$SELF:cmd] == 8))\
(set rollo_re unten)\

attr di_rolladensteuerung_2 checkall event
attr di_rolladensteuerung_2 room Test.Rollladen

Per

#1
Zitat von: spi3845 am 27 März 2017, 13:28:59Ich würde gerne hören, wie ihr solch ein Problem angehen würdet? Tatsächlich jede einzelne Bedingungen im DOIF abbilden? Oder mehrere DOIFs wie bei der Ampel?
Mein Vorgehen (im Laufe der Zeit hat diese sich erst ergeben, es existieren also noch alte Relikte :-[):
- für jeden Aktor existiert max. ein DOIF. Alles, was diesen Aktor betrifft, kommt da hinein.
- für "Zwischenergebnisse" kann es weitere DOIF geben. Entweder, weil sie im DOIF mehrfach gebraucht werden oder weil mehrere DOIF sie brauchen.
- ein DOIF kann auch mehrere Aktoren ansteuern, aber nie umgekehrt!

Nebenbei: außer den reinen Hardware-Devices verwende ich zu ~90% DOIF.

spi3845

Zitat von: Per am 27 März 2017, 14:10:58
- für jeden Aktor existiert max. ein DOIF. Alles, was diesen Aktor betrifft, kommt da hinein.
Danke - und wie sehen die DOIFs aus (die neuen, nicht die Relikte ;))? Verkettest Du alle Bedingungen einander (so wie in meinem einfachen Beispiel) oder versuchst Du (schöne :) ) Zustandsautomaten abzubilden?

Mein erster Eindruck am Beispiel der Rollladensteuerung ist, dass bei jeder neuen Anforderung ein weiterer DOELSEIF-Zweig mit vielen Bedingungen dazu kommt und das ganze irgendwann nicht mehr pflegbar wird, weil der neue DOELSEIF-Zweig vielleicht noch an der falschen Stelle gelandet ist...

Ich bin quasi auf der Suche nach der Antwort, wie man funktionierenden, übersichtlichen und gut pflegbaren DOIF-Code erstellt.

Wuppi68

versuche die ganze Problematik am besten Ereignis anstelle von Zustand gesteuert zu überdenken
Jetzt auf nem I3 und primär Homematic - kein Support für cfg Editierer

Support heißt nicht wenn die Frau zu Ihrem Mann sagt: Geh mal bitte zum Frauenarzt, ich habe Bauchschmerzen

betateilchen

Zitat von: spi3845 am 27 März 2017, 14:22:42
Ich bin quasi auf der Suche nach der Antwort, wie man funktionierenden, übersichtlichen und gut pflegbaren DOIF-Code erstellt.

Indem man ihn wegläßt. Macht die Sache sehr übersichtlich.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

spi3845

Zitat von: Wuppi68 am 27 März 2017, 14:30:19
versuche die ganze Problematik am besten Ereignis anstelle von Zustand gesteuert zu überdenken
Genau das war ja mein Ansatz in meinem Beispiel-Code. Nur führt das zu einer langen Verkettung von Bedingungen, da mehrere Ereignisse eintreten können, die abhängig verschiedener Zustände zu unterschiedlichen Ergebnissen führen. Ich hatte gehofft, es gäbe da noch irgend einen Trick, den ich in der Doku nicht gefunden habe...

spi3845

Zitat von: betateilchen am 27 März 2017, 15:24:38
Indem man ihn wegläßt. Macht die Sache sehr übersichtlich.
:D und statt dessen? Voodoo?

betateilchen

Zitat von: spi3845 am 27 März 2017, 15:34:01
und statt dessen? Voodoo?

nein, die dafür originär implementierten Möglichkeiten wie notify und echtes perl nutzen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Per

Zitat von: betateilchen am 27 März 2017, 15:43:49
nein, die dafür originär implementierten Möglichkeiten wie notify und echtes perl nutzen.
Warum nicht gleich Assembler oder gar Machinencode? Notify und Perl doch für dich auch nur "Krücken" sein, oder?

spi3845

Zitat von: betateilchen am 27 März 2017, 15:43:49
nein, die dafür originär implementierten Möglichkeiten wie notify und echtes perl nutzen.
Was kann notify was DOIF nicht kann? Das ginge doch dann in die Richtung mehrerer DOIFs parallel - so wie beim Ampel-Beispiel.

Per

Zitat von: spi3845 am 27 März 2017, 15:56:09
Was kann notify was DOIF nicht kann?
Darum geht es nicht. betateilchen ist bekennender DOIF-Hasser. Und das versucht er gern auch mal an unpassender Stelle loszuwerden. Also lass dich nicht davon beirren.

Deiner Frage nach den Automaten oder Verkettungen: wo ist da die Grenze, ich bin kein gelernter Programmierer (obwohl ich schon den Z8 mit Assembler bearbeitet habe), ich entscheide sowas eher pragmatisch von Fall zu Fall. Wenn du einen Extrem-Fall als Standard definierst, wirst du irgendwann eine Anwendung finden, bei der das andere Extrem einen Zweizeiler, deine Wahl hingegen eine halbe Seite Code erfordert (Übertreibung macht anschaulich ;)).

Beta-User

Oute mich mal auch als bekennender DOIF-Skeptiker...
Zitat von: spi3845 am 27 März 2017, 15:56:09
Was kann notify was DOIF nicht kann? Das ginge doch dann in die Richtung mehrerer DOIFs parallel - so wie beim Ampel-Beispiel.
DOIF ist ein sehr komplexes Werkzeug, das aber eben den Nachteil hat, dass man genau diese Komlexität gerne übersieht. Darauf zielt nach meinem Eindruck auf Wuppie68 ab:
Zitat von: Wuppi68 am 27 März 2017, 14:30:19
versuche die ganze Problematik am besten Ereignis anstelle von Zustand gesteuert zu überdenken

Mit einem notify (das übrigens zusammen mit at vermutlich der älteste und damit "härteste" Bestandteil von FHEM ist), reagiert man eben auf ein Ereignis und kann dann ggf. mit einfachen (perl-) if Abfragen genau die Frage nach dem aktuellen Zustand diverser (nicht-DOIF)-devices klären und daran anknüpfend dann eben genau die Reaktion auf das Ereignis auswählen, die jetzt angezeigt ist.

Sofern man Hilfsinformationen braucht, sind die nach meinen (begrenzten) Verständnis am einfachsten als userReadings bei den devices abzulegen. Das ganze ist dann nicht assembler, sondern kann recht stringenter code sein, der (als perl, klar, aber mindestens) ebenso gut zu verdauen ist als ein DOIF mit einer Vielzahl von attr., bei denen jedenfalls ich niemals verstehen werde, welche Kombination jetzt auf meinen Fall Sinn macht.

m.E. gelungenes Beispiel für perl und userreadings: Bennis globale Tür-offen-Meldung.

@betateilchen:
Bei Gelegenheit wollte ich mal eine Userreading-basierte Rolladenautomatik angehen, da gibt es leider bislang wohl nur halbgare Ansätze. Kann ich da irgendwo im Forum was finden, was mir hilft, mein (vermutlich (!) nach der commandref gebasteltes) DOIF-Konstrukt loszuwerden?

Nix für ungut,
ein weiterer DOIF-geschädigter Beta-User

PS: Wer so einen Titel wählt, braucht sich über Anworten wie meine und betateilchens nicht wundern und: Laßt das Popcorn auf der Seite, in großen Mengen ist es nicht gesund...
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

spi3845

Zitat von: Per am 27 März 2017, 16:12:02
wo ist da die Grenze, ich bin kein gelernter Programmierer (obwohl ich schon den Z8 mit Assembler bearbeitet habe), ich entscheide sowas eher pragmatisch von Fall zu Fall. Wenn du einen Extrem-Fall als Standard definierst, wirst du irgendwann eine Anwendung finden, bei der das andere Extrem einen Zweizeiler, deine Wahl hingegen eine halbe Seite Code erfordert (Übertreibung macht anschaulich ;)).
Den Eindruck einer halben Seite hatte ich nach dem Codieren des (einfachen) Rollladenbeispiels. Daher die Frage nach alternativen Ansätzen.

spi3845

Zitat von: Beta-User am 27 März 2017, 16:36:05
Mit einem notify (das übrigens zusammen mit at vermutlich der älteste und damit "härteste" Bestandteil von FHEM ist), reagiert man eben auf ein Ereignis und kann dann ggf. mit einfachen (perl-) if Abfragen genau die Frage nach dem aktuellen Zustand diverser (nicht-DOIF)-devices klären und daran anknüpfend dann eben genau die Reaktion auf das Ereignis auswählen, die jetzt angezeigt ist.
Mit einem Notify wird man ja dann bei unterschiedlichen Ereignissen nicht auskommen. Ist die Analogie dazu nicht "mehrere DOIFs"? Mir ist es am Ende egal, ob ich notify oder DOIF nutze, ich will nur die Vor-/Nachteile ausloten...

Zitat von: Beta-User am 27 März 2017, 16:36:05Das ganze ist dann nicht assembler, sondern kann recht stringenter code sein, der (als perl, klar, aber mindestens) ebenso gut zu verdauen ist als ein DOIF mit einer Vielzahl von attr., bei denen jedenfalls ich niemals verstehen werde, welche Kombination jetzt auf meinen Fall Sinn macht.
Urgh, so geht's mir auch nach dem Rollladen-Beispiel...

Zitat von: Beta-User am 27 März 2017, 16:36:05Bei Gelegenheit wollte ich mal eine Userreading-basierte Rolladenautomatik angehen, da gibt es leider bislang wohl nur halbgare Ansätze. Kann ich da irgendwo im Forum was finden, was mir hilft, mein (vermutlich (!) nach der commandref gebasteltes) DOIF-Konstrukt loszuwerden?
Da würde ich gerne mitmachen...

Zitat von: Beta-User am 27 März 2017, 16:36:05PS: Wer so einen Titel wählt, braucht sich über Anworten wie meine und betateilchens nicht wundern
Passt, ich wollte eine Diskussion, jetzt habe ich eine Diskussion.

Beta-User

Zitat von: spi3845 am 27 März 2017, 17:11:37
Mit einem Notify wird man ja dann bei unterschiedlichen Ereignissen nicht auskommen. Ist die Analogie dazu nicht "mehrere DOIFs"? Mir ist es am Ende egal, ob ich notify oder DOIF nutze, ich will nur die Vor-/Nachteile ausloten...
Kommt drauf an. Man kann für dieselbe Reaktion bei beiden Modulen (DOIF und notify) ja auswählen, auf welche Bedingungen reagiert werden soll, bei notify aber halt "nur" im Sinne von "...oder .... oder ... oder" als (alternative) Eingangsbedingungen (bei DOIF geht es auch "weiter hinten" irgendwo in einem else-Zweig). Bei Notify muß man es "hinterher" erledigen, Dinge rauszufiltern, auf die man jetzt halt doch nicht reagieren will.

Zu den Vor und Nachteilen: Mir war es bei meinen FHEM-Anfängen auch mal egal, welches Modul ich nutze, und DOIF war wirklich super-universell. Leider habe ich im Lauf der Zeit zunehmend das Gefühl, dass meine DOIF's entweder komplizierte Varianten von einfacheren Lösungen sind/waren (notify mit einfachem if hintendran, threshold, weekdaytimer) oder irgendwann nicht mehr so reagieren, wie ich das erwartete (und es vermutlich auch mal funktioniert hat). Ich halte es daher für überkomplex und daher für die Zukunft weiterhin fehleranfällig, aber das ist meine persönliche Meinung. Ich habe daher gut die Hälfte meiner DOIF's aus der ersten Phase zwischenzeitlich in andere Lösungen überführt.

notify/at ist erprobt, das wird so schnell nicht ins Wanken geraten. Und ich bin ziemlich sicher, dass daran anknüpfender guter perl-Code auch in 20 Jahren noch zuverlässig seinen Dienst tun wird und nicht das Nachpflegen irgendwelcher attr brauchen wird.

Soviel zu den Vor- und Nachteilen, die ich sehe (aber nochmal: ich kann's eigentlich nicht beurteilen, das ist reinstes Bauchgefühl).

Vermutlich wird man bei einer vernünftigen Rollandensteuerung aber nicht umhin kommen, mehrere Bausteine (notify/at,ggf. weekdaytimer mit perl bzw. alternativ DOIF) zu kombinieren. Die sollten dann aber einen klaren Zweck bzw. Auslöser haben, dann dürfte das nicht zu unübersichtlich werden.

Zitat von: spi3845 am 27 März 2017, 17:11:37
Urgh, so geht's mir auch nach dem Rollladen-Beispiel...
...eine Zeitlang habe ich geglaubt, es läge an mir, warum ich das alles nicht auf die Reihe bekomme :'(, aber dann habe ich einige threads gesehen, bei denen sich die Macher schon nicht einig waren, in welcher Kombination jetzt welche attr Snn machen und ob es eine DOELSE braucht 8). (Nur zur Klarstellung: Der Ansatz ist löblich, aber ich bin kein Programmierer und damit überfordert, und obigen Verdacht werde ich in diesem Leben nicht mehr loswerden, dafür komme ich zwischenzeitlich mit C-Code klar (DOIF goes Arduino 8)), jetzt ist dann halt perl an der Reihe).

Zitat von: spi3845 am 27 März 2017, 17:11:37
Da würde ich gerne mitmachen...
Ich bin kein Programmierer, daher wird das kein Spaß ;).
Es ist Dein Thread. Wenn es kein DOIF mehr sein soll, dann verschiebe den Beitrag und ich bin mit meinen bescheidenen Kenntnissen dabei (oder mache einen neuen auf). Ich habe HM-Hardware (Tri-State Fenstersensoren, UP-Rolladen)...
Bei Interesse kann ich gerne meine Gendanken mal zu Papier bringen, was an Elementen m.E. so zweckmäßig wäre, aber wie gesagt: Eigentlich habe ich keine Ahnung, wie man "sowas" angeht.
Zitat von: spi3845 am 27 März 2017, 17:11:37
Passt, ich wollte eine Diskussion, jetzt habe ich eine Diskussion.
Mach' das nicht zu oft, es macht keinen Sinn, die Leute hier gegeneinander aufzubringen!

Jeder hier tut, was er für gut, zielführend und richtig hält. Es ist open (source...)
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files