wie Rule nur 1x ausführen ?

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Benutzeravatar
Steinspiel
Beiträge: 394
Registriert: 28. Dez 2019 08:49
Answers: 2

wie Rule nur 1x ausführen ?

Beitrag von Steinspiel »

Moin,

Habe nicht das richtige zu meinem Problem finden können, deshalb meine Frage hier:

Mein Bewegungsmelder (Bew_Sens_Presence) löst irgendwann zwischen 15:00 und 17:00 Uhr aus und schaltet zwei Lampen ("Flur2_Dimmen" und "oben_Dimmen") ein und nicht wieder aus. Das Ausschalten erfolgt dann ja nach Bedarf per Sprachbefehl. Nun soll sich die Lampe bis 17:00 Uhr aber nicht noch ein zweites mal per Bewegungsmelder einschalten...!

Nach dem was ich gelesen habe, kann man wohl einen Zähler integrieren, der die Schaltvorgänge mitzählt und dann die Regel abbricht, sollte die gewünschte Anzahl Durchläufen erreicht sein. Nur wie?

Ich glaube so ein Zähler ist ziemlich nützlich, auch für andere Aufgaben. Könnte mir jemand zeigen wie das geht?

einen schönen Abend noch,

Code: Alles auswählen

var Timer tBewegung = null                                                              // Timervariable global definieren

rule "ein_mal"

when
        Item Bew_Sens_Presence changed to ON                                            // Bewegung erkannt
        
then

        if(Flur2_an_aus.state == ON) {                                                  // Abfrage ob Flur2 schon an ist, wenn ja ABBRUCH
                return;
        }

        if(OffsetBewegungsmelder.state == 1)                                            // Offset nach "1" abgefragt   (wg. richtigen Schaltzeitpunkt)  

        {
                sendCommand(Flur2_Dimmen, 80)                                            // Flurlampe 2 auf 80% Dimmen, Ein, keine AUS Schaltung
                sendCommand(oben_Dimmen, 100)                                            // Kueche auf 100 % Dimmen, Ein          


        }
end
bis dann, Steinspiel

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

Re: wie Rule nur 1x ausführen ?

Beitrag von udo1toni »

Na ja, Du musst halt eine Variable dazu definieren. Natürlich brauchst Du eine weitere Rule, die die Variable vor 15 Uhr zurücksetzt.

Code: Alles auswählen

var Timer tBewegung = null                  // Timervariable global definieren
var Number nCount = 0

rule "ein_mal"

when
    Item Bew_Sens_Presence changed to ON    // Bewegung erkannt
then
    if(Flur2_an_aus.state == ON)            // Abfrage ob Flur2 schon an ist, wenn ja ABBRUCH
        return;
    if(OffsetBewegungsmelder.state == 1) {  // Offset nach "1" abgefragt   (wg. richtigen Schaltzeitpunkt)  
        if(nCount > 0)                      // nCount schon hochgezählt
            return;
        sendCommand(Flur2_Dimmen, 80)       // Flurlampe 2 auf 80% Dimmen, Ein, keine AUS Schaltung
        sendCommand(oben_Dimmen, 100)       // Kueche auf 100 % Dimmen, Ein          
        nCount = nCount + 1                 // hochzählen
    }
end
Warum Deine Rules nicht so besonders toll sind, habe ich im anderen Thread ja schon erklärt ;)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
Steinspiel
Beiträge: 394
Registriert: 28. Dez 2019 08:49
Answers: 2

Re: wie Rule nur 1x ausführen ?

Beitrag von Steinspiel »

Moin
udo1toni hat geschrieben: 15. Jan 2020 22:42 Na ja, Du musst halt eine Variable dazu definieren. Natürlich brauchst Du eine weitere Rule, die die Variable vor 15 Uhr zurücksetzt.
Das mit der Counter Variablen hat gut funktioniert, Danke.
Das zurücksetzen des Counters vor 14:00 Uhr habe ich so gelöst

Code: Alles auswählen

rule "Counter zuruecksetzen"

when         Time cron "50 59 13 ? * * *"                                     // Zeitschaltpunkt Counter zurücksetzen 13:59:50 Uhr
then         nCount = nCount - 1                                              // Counter -1 = 0
                logInfo("Counter","Counter ist wieder 0.")
end
Es funktioniert auf jeden Fall. :-)

Was nicht funktioniert ist mein "logInfo" wenn der Counter hochgezählt ist. Setze ich ihn *vor* das "return;" bekomme ich in VS Code eine Fehlermeldung.

Code: Alles auswählen

            
if(nCount > 0)                                                  // nCount schon hochgezählt
logInfo("Counter","Licht war schon 1 x an.")
return;
und danach nutzt es mir ja nicht viel... Muss ich das anders definieren?
Warum Deine Rules nicht so besonders toll sind, habe ich im anderen Thread ja schon erklärt ;)
Das hat getroffen! ;-(

Habe mir das alles noch einmal angesehen und mich gewundert das ich das in meinem "Rules Wahn" irgendwie ignoriert hatte!
Klein, kompackt und läuft, selbst mit dem hinzugefügten Counter! Darauf werde ich aufbauen, nochmals Danke!

Wegen der zig tausend Log Einträge die "meine" Offset Version immer erzeugte, fragte ich mich sowieso: es sind ja alles Schreibzugriffe auf die SD Card im Raspberry und nagen die nicht mit der Zeit an der Lebensdauer der Karte oder ist das zu vernachlässigen weil es wie bei einer "richtigen" HDD auch (fast) egal ist?
bis dann, Steinspiel

Benutzeravatar
peter-pan
Beiträge: 2564
Registriert: 28. Nov 2018 12:03
Answers: 25
Wohnort: Schwäbisch Gmünd

Re: wie Rule nur 1x ausführen ?

Beitrag von peter-pan »

....probier's mal so:

Code: Alles auswählen

if(nCount > 0){             // nCount schon hochgezählt
logInfo("Counter","Licht war schon 1 x an.")
return;
}


... mit geschweiften Klammern, weil's kein Einzeiler mehr ist ;)
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

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

Re: wie Rule nur 1x ausführen ?

Beitrag von udo1toni »

Steinspiel hat geschrieben: 16. Jan 2020 18:14 Habe mir das alles noch einmal angesehen und mich gewundert das ich das in meinem "Rules Wahn" irgendwie ignoriert hatte!
Klein, kompackt und läuft, selbst mit dem hinzugefügten Counter! Darauf werde ich aufbauen, nochmals Danke!
Mach Dir nichts draus, jeder fängt mal klein an :)
Wegen der zig tausend Log Einträge die "meine" Offset Version immer erzeugte, fragte ich mich sowieso: es sind ja alles Schreibzugriffe auf die SD Card im Raspberry und nagen die nicht mit der Zeit an der Lebensdauer der Karte oder ist das zu vernachlässigen weil es wie bei einer "richtigen" HDD auch (fast) egal ist?
Leider ist das nicht zu vernachlässigen.
Wenn Du openHABian für die Installation verwendest, dieses bringt ein Tool namens ZRAM mit, damit werden logs und temporäre Dateien in einer RAM Disk gespeichert. Das funktioniert natürlich nur, wenn man auch genug RAM hat, also ab RaspberryPi3 (1GB) sollte das kein Problem sein.
Zu beachten ist, dass bei Spannungsausfall alle Daten im RAM verloren gehen. Wenn der Pi regulär heruntergefahren wird, schreibt das Tool hingegen alle Daten noch auf das Speichermedium der Wahl, aber halt in einem Rutsch.

SD-Karten und USB-Sticks unterscheiden sich übrigens erheblich von SolidStateDisks, weil dort ein anderer Controller zum Einsatz kommt. Die SSD bringt mehr Speicher mit, als sie nominell hat. Wenn Zellen ausfallen, werden Ausweichbereiche zugewiesen, der Controller sorgt außerdem mit wear leveling dafür, dass die Speicherzellen "gleichmäßig" abgenutzt werden. Es gibt einzelne USB Sticks, die das auch bieten, die sind aber erheblich teurer (bei gleicher Speichergröße) als gewöhnliche USB Sticks.

Unter dem Strich ist ZRAM sicherlich eine gute Variante, am besten in Verbindung mit einer USV für den Raspberry inklusive automatischem Shutdown wenn der Akkustand kritisch wird.
Huckepackplatinen gibt es dafür schon für einige zehn Euro (so ab 22EUR bis 40EUR) plus Akku natürlich, der aber vergleichsweise klein ausfallen kann (rein rechnerisch sollten 5 Li-Mignonzellen mit je 700mAh den Pi etwa 20 Minuten am Leben halten können).

Von meiner Seite ist das aber alles Theorie, da ich openHAB virtualisiert betreibe. ;)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
Steinspiel
Beiträge: 394
Registriert: 28. Dez 2019 08:49
Answers: 2

Re: wie Rule nur 1x ausführen ?

Beitrag von Steinspiel »

peter-pan hat geschrieben: 16. Jan 2020 18:29 ... mit geschweiften Klammern, weil's kein Einzeiler mehr ist ;)
Funktioniert! ;-)

Sag mal, kann man so einen "Counter" auslesen? Ich meine, wenn ich den nicht auf Null zurücksetze, könnte man doch ablesen wie viele Schaltvorgänge es gab, oder?
bis dann, Steinspiel

Benutzeravatar
Steinspiel
Beiträge: 394
Registriert: 28. Dez 2019 08:49
Answers: 2

Re: wie Rule nur 1x ausführen ?

Beitrag von Steinspiel »

udo1toni hat geschrieben: 16. Jan 2020 19:51 Unter dem Strich ist ZRAM sicherlich eine gute Variante,
[...]
Von meiner Seite ist das aber alles Theorie, da ich openHAB virtualisiert betreibe. ;)
Moin,

Ich habe ZRAM erst einmal aktiviert. Das ging ja Problemlos...
Alles läuft wie gewohnt und ich merke keinen Unterschied. Da es mir aber an Wissen fehlt wüsste ich auch nicht wie ich herausfinden kann was jetzt anders als vorher sein muss. "free -m" zeigt mir zwar benutzten und freien Speicher an, aber eine RAM Disk im Sinne von einem LW wie unter Windows, kann ich da nicht erkennen... ;-)

Ich habe ja mal irgendwann vor (wenn wirklich alles läuft), mich mit Persistence zu befassen. Was meinst Du, sollte man das mit einer SD Card als Datenträger lieber sein lassen?
Überhaupt, von welchen Zeitraum reden wir bis so eine SD mit 24/7 openHAB drauf ihren Geist aufgibt, 6 Monate, ein Jahr...? Kann ja sein das es da Erfahrungswerte gibt...

schönen Abend noch....
bis dann, Steinspiel

Benutzeravatar
Steinspiel
Beiträge: 394
Registriert: 28. Dez 2019 08:49
Answers: 2

Re: wie Rule nur 1x ausführen ?

Beitrag von Steinspiel »

ERGÄNZUNG zu ZRAM

mit "lsblk" sieht man "Laufwerke" die "zram0" 1 und 2 heißen, mit je um die 500 MB größe in /opt/zram...
Also da ist zumindest was... ;-)
bis dann, Steinspiel

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

Re: wie Rule nur 1x ausführen ?

Beitrag von udo1toni »

Im Zweifel wirst Du mit mount sehen, dass /tmp und /var/log/ nicht am gewohnten Platz gemountet sind. (gut, dafür musst Du natürlich wissen, wo sie normalerweise zu finden sind...)
Der Zeitraum, in dem mit einem Ausfall zu rechnen ist, hängt sehr stark von verschiedenen Faktoren ab (auch von der verwendeten Karte, hauptsächlich aber natürlich von der Menge der Schreibvorgänge und damit von der Auslastung des Systems). Wie erwähnt setze ich für openHAB keinen Pi ein, aber die Berichte schwanken von Jahren bis zu wenigen Wochen (ohne Optimierungen).

Wenn Du eine Variable nutzt, kannst Du die natürlich auch auswerten. Wenn es Dir darum geht, die Zahl anzuzeigen, bietet es sich natürlich an, gleich ein ungebundenes Number Item zu verwenden. Ungebunden heißt, dass das Item keinen {} Teil in der Definition hat.

Dann sieht die Rule etwas anders aus:

Code: Alles auswählen

var Timer tBewegung = null                  // Timervariable global definieren

rule "ein_mal"

when
    Item Bew_Sens_Presence changed to ON    // Bewegung erkannt
then
    var Number nCount = 0                   // Variable initialisieren
    if(Counter.state instanceof Number)     // Falls Item eine gültige Zahl beinhaltet
        nCount = Counter.state as Number    // Variable mit Wert füllen
    if(Flur2_an_aus.state == ON)            // Abfrage ob Flur2 schon an ist, wenn ja ABBRUCH
        return;
    if(OffsetBewegungsmelder.state == 1) {  // Offset nach "1" abgefragt   (wg. richtigen Schaltzeitpunkt)  
        if(nCount > 0)                      // nCount schon hochgezählt
            return;
        sendCommand(Flur2_Dimmen, 80)       // Flurlampe 2 auf 80% Dimmen, Ein, keine AUS Schaltung
        sendCommand(oben_Dimmen, 100)       // Kueche auf 100 % Dimmen, Ein          
        nCount = nCount + 1                 // hochzählen
        logInfo("count","Schon {} mal eingeschaltet",nCount)
    }
    Counter.postUpdate(nCount)              // Item mit Variable füllen
end
Nun muss die Variable nicht global definiert werden, denn der Wert wird aus dem Item gelesen und ins Item geschrieben. Natürlich muss das Item als Item angelegt sein. Falls die Variable keine Zahl enthält, wird der Counter mit 0 initialisiert (deshalb der Umweg über die Variable)

Natürlich ist das nur sinnvoll, wenn die Abbruchbedingung if(nCount > 0) return; nicht mehr aktiv ist, sonst wird der Counter ja nur zwischen 0 und 1 wechseln.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Benutzeravatar
peter-pan
Beiträge: 2564
Registriert: 28. Nov 2018 12:03
Answers: 25
Wohnort: Schwäbisch Gmünd

Re: wie Rule nur 1x ausführen ?

Beitrag von peter-pan »

... ich hab jetzt nicht deine ganzen Rules und was du damit machst angeschaut, aber Udo hat ja da schon einiges optimiert.

Für den Fall, dass du nur wissen willst, wie viel mal die Rule aufgerufen wird (und auch nicht abspeichern willst), kannst du evtl. mal folgendes probieren:

Code: Alles auswählen

if(nCount > 0){             // nCount schon hochgezählt
 nCount=nCount + 1
 logInfo("Counter","Licht war schon {} x an.", nCount)
return;
}
D.h.: Der Counter wird halt so lange hochgezählt, bis deine andere Regel ihn wieder auf 0 setzt.

Zu ZRAM kann ich noch nicht viel sagen, da ich im Moment dabei bin das mal auf einem "Test-RasPi" auszuprobieren. Aber wie Udo schon ausgeführt hat gibt es natürlich das Für und Wieder abzuwägen (SD-Karten-Crash,Stromausfall, USV, etc.).

Ich "spiele" seit ungefähr 1 1/2 Jahren mit OH2 und hatte (klopf auf Holz) noch nie einen SD-Karten-Crash. Ich habe aber 2 Ersatzkarten, auf die ein per "Win32Diskmanger" erstelltes Image wieder zurück geschrieben werden können, und die dann auch funktionieren (getestet).

Mein Tipp hierzu ist einfach den Event-Logger von Info auf Warn zu stellen. Es ist zwar schön zu sehen, wenn die Temperatur von 22,5 Grad auf 22,6 Grad steigt (ich übertreibe etwas), aber ich nehme mal an, dass du nicht den ganzen Tag am PC sitzt und zuschaust was der Logger sagt, dazu hast eigentlich deine Oberfläche (Basic, Classic, Habpanel), die zeigt alles schön an. Das brauchst du doch höchstens zum Testen.

Gehe einfach in die Console (openhab-cli console) und ändere das Log-Verhalten deine Events:

Code: Alles auswählen

openhab> log:set warn smarthome.event
openhab> log:list | grep -i smarthome.event
smarthome.event                                    x WARN
smarthome.event.InboxUpdatedEvent                  x ERROR
smarthome.event.ItemAddedEvent                     x ERROR
smarthome.event.ItemRemovedEvent                   x ERROR
smarthome.event.ItemStateEvent                     x ERROR
smarthome.event.ThingAddedEvent                    x ERROR
smarthome.event.ThingRemovedEvent                  x ERROR
smarthome.event.ThingStatusInfoEvent               x ERROR
openhab>
Dann hast gleich mal zig-hunderte( oder -tausende) Schreibvorgänge am Tag weniger. Und zum Testen ist der Logger genauso schnell wieder auf Info gesetzt und wieder zurück.
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.1.1 openhabian

Antworten