Rolladensteuerung über GPIO

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
hanshanf
Beiträge: 2
Registriert: 14. Nov 2019 10:49
Answers: 0

Rolladensteuerung über GPIO

Beitrag von hanshanf »

Hallo,

ich bin dieses Jahr von FHEM auf OpenHab umgestiegen. Bisher habe ich meine Homematic-Automatisierung in Openhab abgebildet und bin sehr happy mit dem neuen System.
Aktuell kämpfe ich mit der Umsetzung meiner Astro-abhängigen Rolledensteuerung, und komme irgendwie nicht weiter.

Aufbauzustand:
Da ich Rolladenmotoren mit einem mir nicht bekannten Rolling-Code verwende (Jarolift) , muss ich die Steuerung über eine Fernbedienung (Up,Stop, Down und Kanal-Wahl Taster (hat 4 Kanäle)), die über GPIO am Raspi hängt, ansteuern. Das Funktioniert alles schon (war unter FHEM aktiv).

Dieser Aufbauzustand bedingt eine Eigenheiten, da dies kein intelligentes System ist:
-ich muss den zuletzt ausgeführten Kanal (z.B. Kanal 1 - Rolladen Ost) irgendwo speichern, damit ich diesen in einer nächsten Rule verwenden kann. Ich dachte hier an die Speicherung in einem eigenen Item.

Ich habe nun folgende Item- und Rules Datei geschrieben. Leider funktioniert das so noch nicht. Ich habe schon viel gelesen, aber bestimmt gibt es hier noch div. Syntax-Fehler oder Logikfehler. Bestimmt habe ich mein Vorhaben auch kompliziert umgesetzt und es gibt einen "einfacheren" Weg. Ich würde mich sehr über Anregungen dazu freuen.

Im nächsten Schritt möchte ich dann eine direkte Ansteuerung der einzelnen Kanäle umsetzte, dies aber erst im zweiten Step.
Hier also mal die zwei Dateien die ich beschrieben habe:
Zusatz-Info zur Fernbedieung:
Die Fernbedienung wechselt den Kanal bei jedem einmaligen Druck einen Kanal weiter. Sprich beim Systemstart Default Alle 4 Kanäle zusammen aktiviert, beim nächsten Tastendruck Kanal 1 aktiviert, nächster Tastendruck Kanal 2 aktiviert, ..., nach dem 4. Kanal folgt wieder "alle Kanäle aktiviert"
Ich habe noch eine Init-Datei (System Started - Rule) die das Kanal-Item beim Start mit dem Wert 0 belegt (Ausgangszustand)

Items:

Code: Alles auswählen

Switch Rolladen_Up "Rolladen Up" { gpio="pin:19 activelow:yes initialValue:low" }
Switch Rolladen_Stop "Rolladen Stop" { gpio="pin:13 activelow:yes initialValue:low" }
Switch Rolladen_Down "Rolladen Down" { gpio="pin:6 activelow:yes initialValue:low" }                                                                                
Number Rolladen_Channel_Ist "Kanal [%s]"  
Rules:

Code: Alles auswählen

rule "Rolladenautomatik"                                                        
var Timer tDelay = null                                                       
var Number rolladen_channel_ist_var = Rolladen_Channel_Ist                     
when                                                                            
                Channel 'astro:sun:091d0939:set#event' triggered START                                           
then                                                                            
                val rolladen_channel_soll_wz_ez = 1                                             //Rolladen Ost auf Kanal 1 der Fernbedienung
                if (rolladen_channel_ist_var !== rolladen_channel_soll_wz_ez)   
                {                                                               
                while(rolladen_channel_ist_var !== rolladen_channel_soll_wz_ez) 
                Rolladen_Channel.sendCommand(ON)                                
                Thread::sleep(300)                                              
                Rolladen_Channel.sendCommand(OFF)                               
                rolladen_channel_ist_var = rolladen_channel_ist_var + 1         
                               if (rolladen_channel_ist_var = 5)                
                               {                                                
                               rolladen_channel_ist_var = 0                     
                               }                                                
                }                                                               
                                                                                
                Rolladen_Down.sendCommand(ON)                                   
                Thread::sleep(300)                                              
                Rolladen_Down.sendCommand(OFF)                                  
                tDelay?.cancel                                                
                tDelay = createTimer(now.plusSeconds(10))                     
                Rolladen_Stop.sendCommand(ON)                                   
                Thread::sleep(300)                                              
                Rolladen_Stop.sendCommand(OFF)                                  
                Rolladen_Channel_Ist.postUpdate(Rolladen_channel_soll_wz_ez)    
end
EDIT: Code-Tags gesetzt

Benutzeravatar
udo1toni
Beiträge: 15248
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Rolladensteuerung über GPIO

Beitrag von udo1toni »

Hallo und willkommen,

ich habe mir mal die Freiheit genommen, die Code-Tags zu ergänzen - das macht den Code lesbarer.

Zuerst mal zu den offensichtlichen Fehlern:
Globale Variablen (tDelay und rolladen_channel_ist_var) müssen außerhalb von Rules definiert werden, ganz zu Beginn der Datei, in der sie verwendet werden.
Eine Wertzuweisung außerhalb einer Rule muss absolut sein (rolladen_channel_ist_var darf nur eine Zahl zugewiesen werden)
Wenn man den Status eines Items verwenden will, so braucht es die Eigenschaft .state des Items (Wertzuweisung zu Beginn)
Ein Vergleich mit !== ist nur bei bestimmten Vergleichswerten zulässig, !== bedeutet "nicht identisch", im Gegensatz zu !=, was "nicht gleich" bedeutet. Der Vergleich auf identisch kommt eigentlich nur bei null zum tragen, null verweist auf eine bestimmte Speicherzelle, der Vergleich testet, ob beide Seiten auf die selbe Speicherstelle verweisen und somit der Wert identisch ist.
while() wirkt nur auf den nächsten Befehl. Soll das nicht so sein, muss der zu wiederholende Codeblock mit geschweiften Klammern umgeben sein.
Ein Timer (tDelay) benötigt ein Lambda (einen Code Block), welcher bei Ablauf des Timers ausgeführt wird.

Code: Alles auswählen

// Globale Variablen werden zu Beginn der Datei definiert

var Timer tDelay = null                                    // ein Timer
var Number rolladen_channel_ist_var = 0                    // default Wert


rule "Rolladenautomatik"
when
    Channel 'astro:sun:091d0939:set#event' triggered START
then
    rolladen_channel_ist_var = Rolladen_Channel_Ist.state
    val rolladen_channel_soll_wz_ez = 1                                // Rolladen Ost auf Kanal 1 der Fernbedienung

    while(rolladen_channel_ist_var != rolladen_channel_soll_wz_ez) {
        Rolladen_Channel.sendCommand(ON)
        Thread::sleep(300)
        Rolladen_Channel.sendCommand(OFF)
        rolladen_channel_ist_var = rolladen_channel_ist_var + 1
        if (rolladen_channel_ist_var > 4) rolladen_channel_ist_var = 0
    }
    Rolladen_Channel_Ist.postUpdate(Rolladen_channel_soll_wz_ez)

    Rolladen_Down.sendCommand(ON)
    Thread::sleep(300)
    Rolladen_Down.sendCommand(OFF)
    tDelay?.cancel
    tDelay = createTimer(now.plusSeconds(10), [|
        Rolladen_Stop.sendCommand(ON)
        Thread::sleep(300)
        Rolladen_Stop.sendCommand(OFF)
    ])
end
So sähe der Code erst mal korrekt aus. Ob er allerdings funktioniert, kann ich nicht versprechen.
Erster Einwand: nach dem OFF für den Channel-Switch müsste noch ein weiteres Thread::sleep(300) kommen, denn die Abarbeitung der Befehle bis zum erneuten Durchlaufen der while Schleife brauchen vermutlich nur 1 bis 2 Millisekunden, zu wenig Zeit für die Fernbedienung...
Zweiter Einwand: openHAB arbeitet asynchron. Du sendest ein ON und 300 Millisekunden später ein OFF. Das bedeutet aber nicht, dass der entsprechende Ausgang auch 300 Millisekunden lang ON ist, allenfalls besteht eine gewisse Chance, dass das so passiert.

Da Du ohnehin Relaiskontakte des Pi steuerst, möchte ich vorschlagen, hier Funktionen auszulagern, sprich, Du bastelst ein Script, welches die GPIOs mit den entsprechenden Zeiten ansteuert, sobald es einen entsprechenden Befehl bekommt.
Gehe ich recht in der Annahme, dass die Fernbedienung anzeigt, auf welchem Kanal sie sendet? Dann könntest Du mit relativ geringem Aufwand eine echte Rückmeldung implementieren, welcher Kanal der Fernbedienung tatsächlich ausgewählt ist (vier GPIOs als Input...) - das sollte dann ebenfalls im externen Script vorgehalten werden. Dann kann eine openHAB Rule an das Script den Befehl "Fahre Kanal 3 runter" und "stoppe Kanal 3" senden, was wesentlich zuverlässiger funktionieren dürfte.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

hanshanf
Beiträge: 2
Registriert: 14. Nov 2019 10:49
Answers: 0

Re: Rolladensteuerung über GPIO

Beitrag von hanshanf »

WoW!!!
Danke für die schnelle Hilfe. Ich bin begeistert.
Habe nun an den Channel GPIO eine LED angeschlossen.
Sie geht auch an. Allerdings geht sie nicht mehr aus.
Das verstehe ich irgendwie nicht, da der OFF-Befehl ja eigentlich gesendet wird. Ich habe auch mal mit einem längeren Thread experimentiert, aber damit hat es nichts zu tun.
Hängt es evtl. mit einer falschen Definition des items zusammen?
Switch Rolladen_Channel "Rolladen Kanal" { gpio="pin:5 activelow:yes initialValue:low" }

Bezüglich Script.
Setzt man da auf .py oder .sh ? Hat eines von beiden Vorteile/Nachteile oder ist das einfach Geschmacksache?

Benutzeravatar
udo1toni
Beiträge: 15248
Registriert: 11. Apr 2018 18:05
Answers: 242
Wohnort: Darmstadt

Re: Rolladensteuerung über GPIO

Beitrag von udo1toni »

Kannst Du denn den GPIO über das Item normal schalten (also ohne Rule, mit einem Schalter über die UI)?

Wie Du externe Scripte programmierst, bleibt Dir überlassen, nimm das, womit Du am besten zurecht kommst. Manchmal reicht ein einfaches bash Script, um ein Problem zu lösen, manchmal möchte man auf vordefinierte Funktionen zugreifen (z.B. um die GPIO direkt zu kontrollieren), dann ist natürlich eine "echte" Programmiersprache Pflicht.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten