Wie am besten in ECMA Intervallfunktion mit Rahmenbedingungen erstellen? Timer?

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Jensemann_P
Beiträge: 162
Registriert: 26. Jul 2021 20:14
Answers: 0

Wie am besten in ECMA Intervallfunktion mit Rahmenbedingungen erstellen? Timer?

Beitrag von Jensemann_P »

Ich stehe gerade etwas auf dem Schlauch wie ich denn folgendes am elegantesten Umsetze:

Wenn der Taupunktvergleich ergibt, dass Lüften jetzt Sinn macht (Und die relative Luftfeuchtigkeit Innen unter sagen wir mal 60% liegt, darüber bei entsprechenden Werten Dauerlüftung), dann Beginne am Lüfter folgenden Ablauf

Code: Alles auswählen

1:
- 30 min Lüfter an
- 30 min Lüfter aus
- Überprüfe, ob die Rahmenbedingungen noch fürs Lüften sprechen
ja? -gehe zu 1
nein? Ende
Wichtig ist vor allem, dass dieser Vorgang die Rule in soweit entweder einfach blockiert oder neue Events abgefangen werden, dass der Intervall nicht nach jedem positiven Triggereingang wieder von vorne Beginnt. Einmal ausgelöst soll das Stumpf durchlaufen und erst nach Ende der Lüftungszeit UND der Ruhezeit entscheiden.

Zu Timern in JS habe ich folgende Variante gefunden:

Code: Alles auswählen

var ScriptExecution = Java.type("org.openhab.core.model.script.actions.ScriptExecution");
var runme = function(){ logger.info("Timer expired!"); }
var ZonedDateTime = Java.type("java.time.ZonedDateTime");
var now = ZonedDateTime.now();
var timer = SE.createTimer(now.plusSeconds(1), runme);
Wie verhält sich das? Läuft der timer los, sobald ich die letzte Zeile ausführe?
Wird eine erneute Aktivi3erung durch die Laufzeit verhindert, oder müsste ich irgendwie den Timerstate abfragen?
Müsste ich dann den Timerstate nach Ablauf von Hand auf Null (oder undefined?) stellen, oder wird der nach Ablauf automatisch geleert?
Für meine Funktion bräuchte ich dann ja schon 2 Timer und kann die expire-Variante des Items nicht benutzen.
Wäre hier nicht ein fall, in dem ein klassisches, unelegantes thread.sleep() nicht einfach nur Vorteile bringt, weil ich ja genau die "Nachteile" wie blockieren der Rule haben möchte? Oder würde mir die Laufzeit einfach x Instanzen nebeneinander setzen? Soweit ich das verstanden habe, läuft in OH3 jede Rule in einem eigenen Thread. Ab welcher Anzahl würden blockierende Threads kritisch fürs System? 3? 100? 58764?
Also, spricht etwas gegen folgenden Pseudocode-Ablauf:

Code: Alles auswählen

if (hum_rel < 60%){
        while (Alle Randbedingungen(über Items) = True)
 	     fan_on;
 	     thread.sleep(30min)
 	     fan_off;
 	     thread.sleep(30min)
        end while
}else{
    fan_on
}


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

Wie am besten in ECMA Intervallfunktion mit Rahmenbedingungen erstellen? Timer?

Beitrag von udo1toni »

Thread::sleep() ist nach wie vor nicht schön, wenn auch unter OH3 nicht mehr kritisch (unter OH2 war alles über 500 msec gefährlich)

Die einfachste Variante ist, einen Timer zu nutzen, allerdings als Schleife. Ob das in ECMA funktioniert, weiß ich nicht, denn eine notwendige Voraussetzung für einen solchen Timer ist eine globale Variable, die den Zeiger auf den Timer enthält. In der Rules DSL sähe das so aus:

Code: Alles auswählen

var Timer tZyklus = null

rule “Zyklus starten”
when
    Item Bla changed to ON
then
    if(tZyklus !== null) // Timer läuft schon, Abbruch
        return;
    tZyklus = createTimer(now.plusSeconds(1), [|
        mySwitch.sendCommand(if(mySwitch.state != ON) ON else OFF) // umschalten
        if(Randbedingung)
            tZyklus.reschedule(now.plusMinutes(30))
        else
            tZyklus = null        
    ])
end

Das ist jetzt nur eine ganz grobe Version. Solange die Randbedingung erfüllt ist, wird der Timer immer wieder neu angelegt. Jedes Mal, wenn der Timer Code ausgeführt wird, toggelt der Schalter.
Man kann die Zykluszeit auch asymmetrisch definieren, das macht man dann einfach von der Schalterstellung abhängig. Allerdings sollte man die entsprechende Zeit dann vor dem Toggle ermitteln und in einer lokalen Variablen zwischenspeichern, denn openHAB arbeitet asynchron, somit wäre das Verhalten an dieser Stelle im Code nicht deterministisch.
Man kann auch genau so gut einen Zähler mit einbauen (zweite globale Variable für den Zählerstand) und jeweils erhöhen. Timer sind eine sehr praktische Sache.

Du kannst auch einen anderen Ansatz verfolgen und ein Item mit expire Eigenschaft nutzen (die kann man als Metadaten hinzufügen). Grob gesagt wird das Item auf einen bestimmten Wert gesetzt und nach Ablauf der Zeit schaltet das Item von selbst zurück. Leider lässt sich diese Zeit nur fix konfigurieren, womit die asymmetrische Variante so nicht realisiert werden kann. Du kannst aber in einer Rule den Zustand des expire Items abfragen und daran erkennen, ob der Timer läuft (und also die Rule abbrechen). Wenn das Item von expire umgeschaltet wird, startet dann eine Rule, die den eigentlichen Code ausführt und das Expire Item wieder setzt.


Gesendet von iPad mit Tapatalk
openHAB4.3.6 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Jensemann_P
Beiträge: 162
Registriert: 26. Jul 2021 20:14
Answers: 0

Re: Wie am besten in ECMA Intervallfunktion mit Rahmenbedingungen erstellen? Timer?

Beitrag von Jensemann_P »

Hi und danke schonmal für die ausführliche Antwort.

Ich kann mir gerade nicht vorstellen wie ich 1* setzen, expire abwarten, Zeit auf off warten und erst dann wieder eingabebereit sein umsetzen könnte.

Ein Weg der mir noch einfiele wäre mit einer rule auf einen Timer zu reagieren, Minuten zahlen, nach x Minuten ausschalten, nach erreichen von y im auszustand Timer beenden.
Den Zähler dann eben in ein eigenes Item schreiben.

Ist das sinnvoll?

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

Re: Wie am besten in ECMA Intervallfunktion mit Rahmenbedingungen erstellen? Timer?

Beitrag von udo1toni »

Ich verstehe jetzt das Problem nicht. Es ist wirklich ganz einfach.

Ein Switch Item welches mit expire ergänzt wird:

Code: Alles auswählen

{
  "link": "http://openhab3:8080/rest/items/sTimer",
  "state": "NULL",
  "metadata": {
    "expire": {
      "value": "0h30m0s,command=OFF"
    }
  },
  "editable": true,
  "type": "Switch",
  "name": "sTimer",
  "label": "Expire",
  "category": "switch",
  "tags": [],
  "groupNames": []
}
}
Setzt man das Item auf ON, so wird nach 30 Minuten ein OFF Command gesendet.

Code: Alles auswählen

triggers:
  - id: "1"
    configuration:
      itemName: sTimer
      command: OFF
    type: core.ItemCommandTrigger
actions:
  - id: "2"
    configuration:
      itemName: sTimer
      state: ON
    type: core.ItemStateUpdateAction
Kommt das OFF-Command, wird das Item auf ON gesetzt. Im Beispiel habe ich einfach nur eine Item Action gesetzt. Natürlich kannst Du das in einem ECMA Script ebenfalls machen.

Um zu verhindern, dass die Rule, welche das Item initial auf ON setzt das auch tut, wenn der Timer schon gestartet wurde, setzt Du einfach eine Condition (but only if Item sTimer == OFF)
openHAB4.3.6 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Jensemann_P
Beiträge: 162
Registriert: 26. Jul 2021 20:14
Answers: 0

Re: Wie am besten in ECMA Intervallfunktion mit Rahmenbedingungen erstellen? Timer?

Beitrag von Jensemann_P »

Hmm, entweder ich raffe es gerade echt überhaupt nicht, oder wir reden immernoch aneinander vorbei.

Deine Lösung sorgt natürlich dafür, dass die 30 min ON erreicht werden und danach abgeschaltet wird. Wie erreiche ich nun aber, dass dann auch nochmals x minuten off vergehen, bis wieder ein neues initiales on aus der Rule entgegen genommen wird? Ich bräuchte ja quasi ein zweistufiges expire.

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

Re: Wie am besten in ECMA Intervallfunktion mit Rahmenbedingungen erstellen? Timer?

Beitrag von udo1toni »

dazu bruchst Du noch ein weiteres Item, welches dann entsprechend gekippt wird, aber erst nachdem das eigentliche Item schon geschaltet wurde.
openHAB4.3.6 stable in einem Debian-Container (bookworm) (Proxmox 8.4.1, LXC), mit openHABian eingerichtet

Jensemann_P
Beiträge: 162
Registriert: 26. Jul 2021 20:14
Answers: 0

Re: Wie am besten in ECMA Intervallfunktion mit Rahmenbedingungen erstellen? Timer?

Beitrag von Jensemann_P »

achsooooooo, ich schalte Item 1 an. Item 1 expire schaltet Item 2 an. Rule frägt ab ob Item1 oder Item 2 innerhalb expire liegen. So?

Antworten