DOIF-Dimmen mit EnOcean Taster und HUEDevice

Begonnen von dafosy, 02 April 2021, 16:21:27

Vorheriges Thema - Nächstes Thema

dafosy

Hallo Community,
als Lösung eines DOIF-Dimmers mit EnOcean-Schaltern und HUEDevices habe ich aktuell folgende Lösung:


1. Zielstellung:


Mit einem EnOcean Taster soll ein dimmbares HUEDevice-Lichtsystem gesteuert werden.

1) Ein einfacher Klick oben, schaltet das Licht in geringster Stufe ein.
2) Ein Doppelklick auf den Einschalter schaltet das Licht auf höchster Stufe ein.
3) Das Gedrückt-Halten des Einschalters dimmt das Licht heller.
4) Das Gedrückt-Halten des Ausschalters dimmt das Licht dunkler - mit Dimmbegrenzung, d.h. das Licht dimmt nicht dunkler als die unterste Stufe
5) Ein einfacher Klick auf den Ausschalter, schaltet das Licht aus.

2. Vorausgesetzt:
Eingerichtet ist das HUEDevice-Lichtsystem - in meinem Fall das HUEDevice9 und der EnOcean-Schalter ist auch registriert.

3. Copy&Paste:
Was muss im Code geändert werden, wenn ihr das folgende bei euch Anwenden wollt:

2x Sequence mit eurem EnOcean-Taster
2x Dummys mit eurer Bezeichnung
3x DOIFs mit entsprechenden Änderungen des HUEDevices, der Dummybezeichnungen und der entsprechenden Sequencen


--- 4.1 Anlegen der Sequence Eventhandler ---

Als erstes lege ich mittels Sequence Eventhandler. Dieser bewirkt die Erzeugung eines Events durch Drücken des EnOcean Tasters und nimmt konkret Bezug unf den konkreten EnOcean-Schalter:

Als erstes der Tastendruck für das Einschalten:
defmod SZ_ON_seq sequence EnO_FEEFAXXX:B0 0.5 EnO_FEEFAXXX:buttons:.released

--> attr SZ_ON_seq room 07_SchlafZ
--> attr SZ_ON_seq triggerPartial 1


Das erste Attribut weist die SZ_ON_seq dem Raum "SchlafZ" zu - der Ordnung in der Seitenleiste wegen.
Das zweite Attribut setzt bei kurzem Tastendruch das Event "trigger" und bei einem Tastendruck länger als 0,5 Sekunden das Attribut "Partial_1".

Gleiches machen wir mit der Ausschalt-Taste:
defmod SZ_OFF_seq sequence EnO_FEEFAXXX:BI 0.5 EnO_FEEFAXXX:buttons:.released

--> attr SZ_OFF_seq room 07_SchlafZ
--> attr SZ_OFF_seq triggerPartial 1


--- 4.2 Anlegen zweier Dummys, der später die Anzahl der Tastenklicks bzw. den AUS-Status zählen ---


defmod SchlafZ_Klicks_Dummy dummy
set SchlafZ_Klicks_Dummy 0


attr SchlafZ_Klicks_Dummy room 07_SchlafZ ... der Ordnung wegen

defmod SchlafZ_AUS_Dummy dummy
set SchlafZ_AUS_Dummy 0


attr SchlafZ_AUS_Dummy room 07_SchlafZ ... der Ordnung wegen

--- 5.0 nun der etwas umfangreicher DOIF-Bereich ---


Zuerst der DOIF, der die Anzahl der
5.1 EinschaltKlicks zählt und zwar, wenn der EnOcean-Schalter betätigt wird.

defmod SchlafZ_Klickanzahl_DOIF DOIF ( [EnO_FEEFAXXX:buttons] eq "pressed" and [EnO_FEEFAXXX:state] eq "B0" )
(set SchlafZ_Klicks_Dummy  {([SchlafZ_Klicks_Dummy]+1)})
DOELSEIF
([SchlafZ_AUS_Dummy:state] eq 1)
(set HUEDevice9 pct 25)
(set HUEDevice9 off)
(set SchlafZ_AUS_Dummy 0)


attr SchlafZ_Klickanzahl_DOIF room 07_SchlafZ
attr wait 0:0,1,0
attr do always

Hintergrund für den zweiten Eintrag ist eine Anomalie in der Haupt-Licht-DOIF weiter unten - die entsprechende Stelle habe ich unten auch nochmal erläutert. Wenn ich ausschalte, möchte ich, dass das Licht erst runterdimmt und dann ausschaltet. Hintergrund: wenn nachts ein Bewegungsmelder anspricht, will ich nicht volle Pulle die Augen weggebrannt bekommen, wenn vorher die Lampen ggf. auf 100% standen.


Es folgt ein DOIF um die
5.2 Klicks wieder zu Nullen. Und zwar dann, wenn sich der Wert des Dummys ändert, 0,7 Sekunden warten, um dann den Dummy wieder auf 0 zu setzen. 0,7 Sekunden warten, damit Zeit für ein Doppelklick bleibt.

defmod SchlafZ_Klicks_Nullen_DOIF DOIF ([SchlafZ_Klicks_Dummy:state]>0) (set SchlafZ_Klicks_Dummy 0)

attr SchlafZ_Klicks_Nullen_DOIF room 07_SchlafZ
attr SchlafZ_Klicks_Nullen_DOIF wait 0.7

--- 5.3 Nun kommt der Schlüssel-DOIF ---


defmod SchlafZ_Licht_DOIF DOIF
([SchlafZ_Klicks_Dummy:state] eq 1 and [SZ_ON_seq:"^trigger$"]) 
(set HUEDevice9 on)             
(set SchlafZ_Klicks_Dummy 0) 

DOELSEIF 
([SchlafZ_Klicks_Dummy:state] eq 2 and [SZ_ON_seq:"^trigger$"])   
(set HUEDevice9 pct 100)   
(set SchlafZ_Klicks_Dummy 0) 

DOELSEIF ([SZ_OFF_seq:"^trigger$"] and [HUEDevice10:pct]>0) 
(set SchlafZ_AUS_Dummy 1)                                           

DOELSEIF ([SZ_ON_seq:"^partial_1$"])
(set HUEDevice9 dimUp)
(set SchlafZ_Klicks_Dummy 0)   

DOELSEIF ([SZ_OFF_seq:"^partial_1$"])
(set HUEDevice9 dimDown)
(set SchlafZ_Klicks_Dummy 0)   

DOELSEIF ([EnO_FEEFAXXX:"^buttons:.released$"])   
(set SchlafZ_Klicks_Dummy 0)

DOELSEIF ([SchlafZ_Klicks_Dummy] eq 2)
(set SchlafZ_Klicks_Dummy 0) 

DOELSEIF
([HUEDevice9:pct]<25 and [HUEDevice9:pct]>=5)
(set HUEDevice9 pct 25)
(set SchlafZ_Klicks_Dummy 0)

DOELSEIF
([HUEDevice9:pct]>0 and [HUEDevice9:pct]<5)
(set HUEDevice9 off)
(set SchlafZ_Klicks_Dummy 0)

DOELSEIF
([HUEDevice9:pct]>98 )
(set SchlafZ_Klicks_Dummy 0)


---

attr do always
wait 0,0.6:0,0.6:0:0,0.6:0,0.6:0.6:0.6:0,0.6:0,0.6:0,0.6:0,6
attr repeatsame 5
attr repeatcmd 0:0:0:0.5:0.5:0:0


Zur Erklärung:

1.) ([SchlafZ_Klicks_Dummy:state] eq 1 and [SZ_ON_seq:"^trigger$"]) 
Der Schalter wird einmal gedrückt und meldet den Sequence-Event-Status: "trigger", dadurch wird das Licht eingeschaltet und zwar auf der letzten bekannten Helligkeitsposition.
Anschließend wird der Dummy-Klick-Zähler auf 0 gesetzt, um für die nächste Tasterbetätigung wieder in der Ausgangsposition zu sein.

2.) ([SchlafZ_Klicks_Dummy:state] eq 2 and [SZ_ON_seq:"^trigger$"])
Das ist der Doppelklick auf den Einschalt-Taster. Durch das zweimalige Drücken des Tasters wird der Dummy-Klickzähler "SchlafZ_Klicks_Dummy" auf 2 hochgezählt und bedeutet in unserem Fall, dass das Licht volle Kraft einschalten soll. Da das passiert, kann der Dummy-Klick-Zähler anschließend auf 0 gesetzt werden, um beim nächsten Mal wieder in der Ausgangsposition zu sein.

3.) ([SZ_OFF_seq:"^trigger$"] and [HUEDevice10:pct]>0)
Damit sollen die HUEDevices ausgeschaltet werden und zwar nur, wenn diese auch "on" sind.

Hier gibt es ja noch die folgende Besonderheit: wenn ich das HUEDevice Lichtsystem ausschalten möchte, dann soll erst auf Minimum gedimmt werden und erst dann der Ausschaltbefehl "off" folgen. Hinergrund ist die parallele Verwendung eines Bewegungsmelders. Würde vor dem Ausschalten nicht gedimmt werden, dann würde beim nächsten Einschaltvorgang das Leuchtmittel erst mit der zuletzt bekannten Leuchtstärke starten - auch wenn beim Einschalten unmittelbar bspw. eine Helligkeitsregelung mit "pct 25" folgen würde. Das ist Mist, wenn du nachts nur mal pinkeln gehen willst. Also: erst dimmen, dann ausschalten.
Allerdings gab es beim programmieren hier Probleme. Die Befehlsfolge

...
DOELSEIF ([SZ_OFF_seq:"^trigger$"] and [HUEDevice10:pct]>0 )
(set HUEDevice9 pct 25)
(set HUEDevice9 off)
...


klappte einfach nicht. Sicherlich dadurch bedingt, dass meine DOIF-Anweisung (hier der 6. Anstrich) mit ([EnO_FEEFAXXX:"^buttons:.released$"]) den DOIF-Eintrag abbrechen lässt. Allerdings ist dieser DOIF-Eintrag wichtig - siehe weiter unten.

4.) ([SZ_ON_seq:"^partial_1$"])
Hier wird das Licht hochgedimmt, wenn der EIN-Taster gedrückt wird.

5.) ([SZ_OFF_seq:"^partial_1$"])
Hier wird das Licht runtergedimmt, wenn der AUS-Taster gedrückt wird. Begrenzt durch DOELSEIF Nr. 8 im folgenden.

6.) ([EnO_FEEFAXXX:"^buttons:.released$"])
DOIF bricht einen Befehlsblock ab, wenn ein neues Event eintritt. In dem Fall also, wenn beim Dimmen (Taste gedrückt halten) die Taste los gelassen wird, gibt es ein neues Event. Wenn der Eintrag hier fehlen würde, dann würde zwar das neue Event eintreten, der Befehlsblock des jeweiligen Dimmens (heller oder dunkler ... hier DOIFELSE 4+5) nicht unterbrochen werden - also trotz loslassen des Tasters, würde das Licht sich weiter in die entsprechende Richtung dimmen.

7.) ([SchlafZ_Klicks_Dummy] eq 2)
Ich glaube diese DOIF brauche ich, damit sich der SchlaZ_Klicks_Dummy nach dem Doppelklick wieder nullst. Ich habe zwar die oben bereits erwähnte SchlafZ_Klicks_Nullen_DOIF, aber diese greift nicht beim Doppelklick. Ich mutmaße, dass dies daran liegt, dass eine anderes Event ausgelöst wird nach dem Doppelklick und die SchlafZ_Klicks_Nullen_DOIF dadurch abbricht. Hier wäre Forumsberatung hilfreich.
 
8.) ([HUEDevice9:pct]<25 and [HUEDevice9:pct]>=5)
Diese DOIFELSE-Anweisung ist dafür da, dass das Licht beim runterdimmen nicht unter die pct-Helligkeitsstufe 25 fällt, denn dann würde es ausgehen und man will ja nur dimmen und die Lampen nicht ausschalten. Das größer/gleich 5 an Ende hat die Bewandnis, dass manchmal das HUEDevice trotz ausschaltens auf den PCT-Wert 4 fällt und nicht 0. Für diesen Fall dann die nächste DOIFELSE:

9.) ([HUEDevice9:pct]>0 and [HUEDevice9:pct]<5)
Manchmal hatte ich den Fall, dass trotz dem Ausschalten der Lampen die Helligkeitsstufe 2,3,4 angezeigt wird, obwohl die HUEDevices nicht mehr leuchten und eigentlich auch off gestellt wurden. Dennoch fühle ich mich besser, wenn das HUEDevice auch off meldet.

10.) ([HUEDevice10:pct]>98)
Der Vollständigkeit halber bricht diese DOIF die dimUp-Routine aus 4 ab. An sicht nicht notwendig.


Beim Attribut wait habe ich jeweils 0,6 Sekunden gewählt, bevor ich die "SchlafZ_Klicks_Dummy" wieder auf 0 setze, damit Zeit gegeben ist, um den Doppelklick auch registrieren zu können.
Die Attribute repeatcmd und repeatsame benötige ich fürs Dimmen bzw. dem Gedrückt-Halten des Tasters. Die genaue Funktion kann ich leider nicht genau erklären. Wenn ich diese aber weglasse, klappt es nicht. ;)

--- Ausschalten des HUEDevice ---
Wie unter dem 3. Anstrich gesehen, lässt dieser DOIF einen Dummy ansteigen. (set SchlafZ_AUS_Dummy 1)
Dieser Dummy-Anstieg führt oben in der ersten DOIF-Beschreibung, der Klickanzahlzähler berücksichtigt - Punkt 5.1.



bekannte Probleme:
in den DOIF-Anweisungen kann oft nur ein set-Befehl stehen, da oft während des Ausführens ein anderes Event eintritt und somit die entsprechende DOIF-Sektion abbricht. Das führt zu Problemen, wenn bspw. mehrere HUEDevices gedimmt/ geschaltet werden sollen. Gerne sind Lösungen in dem Bereich erwünscht.