Szene mit Pause erstellen

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
djd1983
Beiträge: 20
Registriert: 7. Dez 2023 09:38
Answers: 0

Szene mit Pause erstellen

Beitrag von djd1983 »

Hallo zusammen,
openHAB ist für mich Neuland und ich habe mich in der letzten Zeit mit viel Aufwand sowie "Try and Error" mit keinem bis wenig Programmierkenntnissen durch die Script- ind Widget-Thematik gedrückt. Für mein jetziges Problem scheint mir eine Nachfrage in diesem Forum unausweichlich. Danke schonmal für eure Zeit.

Mein System besteht zur Zeit aus Raspmatic und openHAB auf Raspberry. Die Raspmatic steuert u. a. 9 Rollläden an. Via openHAB kann ich dies ebenfalls bedienen.

Mein Wunsch war nun mit einem Knopfdruck alle RL im Haus hoch zufahren. Dazu habe ich ein Widget mit zwei Buttons "auf" und "Zu" zurecht gebogen Diese Buttons verweisen jewweils auf eine von mir erstellte Scene. Einmal die Scene "alle RL Hoch" und einmal die Scene "alle RL Runter". Nun möchte ich aber innerhalb einer Szene eine Pause einfügen. Zwischen jedem RL Command sollen ca. 2 oder 3 Sekunden liegen. Wie könnte ich das realieseren?

Innerhalb des Codes von der Scene kann ich den Thread::sleep befehl nicht anwenden da sonste die Meldung gemäß Dateianhang kommt.

Vielleicht könnt ihr mir weiterhelfen.

Gruß
Sepp

PS: Vielleicht noch als Nachtrag; das Widget funktioniert einwandfrei!! Es besteht lediglich die Frage nach einer einzuprogrammierenden Pause.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

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

Re: Szene mit Pause erstellen

Beitrag von udo1toni »

Herzlich willkommen im openHAB Forum!

Die unselige Geschichte mit den Szenen...

Eine Szene ist aus openHAB-Sicht ein Schnappschuss der Zustände einer festgelegten Anzahl von Kanälen.
Was Du haben willst, ist eine Ablauf Automation.

openHAB konnte ursprünglich "nur" Automation, und keine Szenen oder Zeitsteuerung, weil Automation all das uneingeschränkt kann, warum also sollte man überhaupt eine Trennung vornehmen... Aber weil andere Systeme "Szenen" beherrschen, musste openHAB auch welche bekommen.
In meinen Augen sind das Alibi-Szenen. "openHAB kann das jetzt auch!"
Spoiler: openHAB konnte das schon immer besser, nur halt unter dem Namen "Rule" und nicht "Szene".

Was Du für die Automation brauchst, ist eine Rule (oder meinetwegen zwei, eine für auf und eine für zu).

Wenn Du mit JavaScript firm bist, kannst Du die Rule so programmieren, Du kannst auch Blockly verwenden, wenn Du mehr der optische Typ bist :)
Oder Du verwendest eine der anderen Sprachen, welche von openHAB unterstützt werden.

Direkt mit an Bord ist aber nur die Rules DSL.

Thread.sleep() ist im Übrigen nicht die gute Lösung, richtig macht man das mit Timern.

Schlecht:

Code: Alles auswählen

rule "Rollläden schließen"
when
    Item RL_Alle received command ON
then
    RL_Studio_Level.sendCommand(DOWN)
    Thread.sleep(3000)
    RL_Schlafzimmer_Level.sendCommand(DOWN)
    Thread.sleep(2000)
    RL_Christopher_Level.sendCommand(DOWN)
end
Besser:

Code: Alles auswählen

// Globale Variablen zu Beginn der Datei definieren!
var Timer   tRoll = null
var Integer iRoll = 0

rule "Rollläden schließen"
when
    Item RL_Alle_Befehl received command ON
then
    if(tRoll !== null)
        return;

    iRoll = 0
    tRoll = createTimer(now, [|
        iRoll += 1
        switch(iRoll) {
            case 1: {
                RL_Studio_Level.sendCommand(DOWN)
                tRoll.reschedule(now.plusSeconds(3))
          } case 2: {
                RL_Schlafzimmer_Level.sendCommand(DOWN)
                tRoll.reschedule(now.plusSeconds("))
          } case 3: {
                RL_Christopher_Level.sendCommand(DOWN)
                tRoll = null
            }
        }
    ])
end
Noch besser: Du definierst eine Gruppe für die zu steuernden Items (bei 9 Stück lohnt das definitiv) und änderst die Namen der Items leicht ab, um eine Reihenfolge vorgeben zu können. Nennen wir die Gruppe gRL und geben den Items Namen der Form RL_n_bla - n ist eine Ziffer, die angibt, in welcher Reihenfolge die Items abgearbeitet werden, bla ist beliebiger Text, der den Regeln für Itemnamen folgt.
Gehen wird weiter davon aus, dass alle Items mit dem gleichen zeitlichen Abstand gefahren werden sollen (z.B. weil der verwendete Bus sonst überlastet wird), sieht die passende Rule so aus:

Code: Alles auswählen

// Globale Variablen zu Beginn der Datei definieren!
var Timer   tRoll = null
var Integer iRoll = 0

rule "Rollläden schließen"
when
    Item RL_Alle received command ON
then
    if(tRoll !== null)
        return;

    nRoll = 0
    tRoll = createTimer(now, [|
        iRoll += 1
        gRL.members.filter[r|r.name.split("_").get(1) = iRoll.toString].head.sendCommand(DOWN)
        if(iRoll < gRL.members.size)
           tRoll.reschedule(now.plusSeconds(3))
        else
           tRoll = null
    ])
end
Wohlgemerkt: diese Rule kümmert sich um beliebig viele Rollläden, egal ob nun einer oder 1000, solange die Itemnamen korrekt gewählt werden (also es gibt nur eindeutige n, wobei n mit 1 startet und keine Zahl ausgelassen wird; keine führenden Nullen oder andere Besonderheiten)
Alle drei Sekunden wird ein Rollladen geschlossen, bis alle Member der Gruppe gRL angesteuert wurden.

Die gleiche Rule per UI:

Code: Alles auswählen

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: RL_Alle_Befehl
    type: core.ItemCommandTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: >-
        if(sharedCache.get("tRoll"))
          return;

        sharedCache.put("iRoll",0)

        sharedCache.put("tRoll", createTimer(now, [|
          sharedCache.put("iRoll", sharedCache.get("iRoll") + 1)
          gRL.members.filter[r|r.name.split("_").get(1) = sharedCache.get("iRoll").toString].head.sendCommand(DOWN)
          if(sharedCache.get("iRoll") < gRL.members.size)
            sharedCache.get("tRoll").reschedule(now.plusSeconds(3))
          else
            sharedCache.put("tRoll", null)
          ])
        )
    type: script.ScriptAction
Die Rule ist per UI etwas aufwändiger, weil es keine globalen Variablen gibt und man stattdessen den shared Cache verwenden muss.

Ich habe die Rule auch nicht getestet :) und es ist wahrscheinlich, dass ich irgendwo einen Tippfehler drin habe... es soll hier eher darum gehen, zu zeigen, wie so etwas grundsätzlich aussieht.

Natürlich kannst Du auch die Thread.sleep() Version über die UI verwenden, wie gesagt, schlechter Stil, aber was soll's:

Code: Alles auswählen

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: RL_Alle_Befehl
    type: core.ItemCommandTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: >-
        RL_Studio_Level.sendCommand(DOWN)
        Thread.sleep(3000)
        RL_Schlafzimmer_Level.sendCommand(DOWN)
        Thread.sleep(2000)
        RL_Christopher_Level.sendCommand(DOWN)
        Thread.sleep(3000)
        RL_Zimmer4_Level.sendCommand(DOWN)
        Thread.sleep(3000)
        RL_Zimmer5_Level.sendCommand(DOWN)
        Thread.sleep(3000)
        RL_Zimmer6_Level.sendCommand(DOWN)
        Thread.sleep(3000)
        RL_Zimmer7_Level.sendCommand(DOWN)
        Thread.sleep(3000)
        RL_Zimmer8_Level.sendCommand(DOWN)
        Thread.sleep(3000)
        RL_Zimmer9_Level.sendCommand(DOWN)
    type: script.ScriptAction
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Harka
Beiträge: 489
Registriert: 30. Apr 2021 13:13
Answers: 19

Re: Szene mit Pause erstellen

Beitrag von Harka »

Sooo verkehrt finde ich die Idee mit optionalen Pausen in den Szenen gar nicht. Erinnert mich an Alexa-Routinen, welche auch für Einsteiger leicht zu bedienen sind. Kannst ja mal in GitHub ein Vorschlag einreichen.

Ich möchte noch ein alternative Vorgehensweise per Script (hier Blockly) vorschlagen. Du legst eine Liste mit den Rollos an (hier 2 Stück) und lässt diese der Reihe nach auf die gewünschte Position fahren. Es reicht sogar ein Script wenn Du die Position als "Sollwert" beim Widget hinterlegst. In der YAML-Ansicht des Widget sieht das so aus:

Code: Alles auswählen

component: oh-cell
config:
  action: rule
  actionRule: RollosForum
  actionRuleContext: "{'Sollwert': 0}"
  title: TestRollos
Alternativ kannst Du auch für jede Wunschposition ein eigenes Script erstellen und Sollwert (im Bild ausgegraut) dort hinterlegen.
ForomRollos.png
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

djd1983
Beiträge: 20
Registriert: 7. Dez 2023 09:38
Answers: 0

Re: Szene mit Pause erstellen

Beitrag von djd1983 »

Nabend,
so, durch eure gebotenen Möglichkeiten, die im Rahmen des weiteren Ausprobierens aufgekeimt sind, habe ich mir eine Lösung erarbeitet. Diese verläuft aber auf den letzten Metern irgendwie im Sande. Daher hier nochmal eine kleine Doku:

ich habe zunächst drei leere Items erstellt (RL EG, RL OG RL Haus) denen ich auch Commands in den Metadaten gegeben habe - UP, DOWN, 13 und 60. Die 13 und 60 stehen jeweils für die Prozentangaben die sich auf die Laufzeit der RL beziehen; allerdings in umgekehrte Reihenfolge von openHAB, sprich nach dem Muster von Homematic (60% ist bei mir genau die Hälfte und bei 13 % sind die Lamellen soweit geschlossen, dass im oberen Teil noch einigermaßen Licht durch kommt).

Zudem habe ich zehn Regeln (rules) erstellt.
1) RL Haus Rauf
2) RL Haus Runter
3) RL EG Rauf
4) RL EG Runter
5) RL EG 13%
6) RL EG 60%
7) RL OG Rauf
8) RL OG Runter
9) RL OG 13%
10) RL OG 60%

jede Rule hat demnach ein eigenes Script und bezieht sich auf die für die Regel zuständige Anzahl der RL.

Mechanik die ich mir als programmier unerfahrener aufgrund eurer Hilfestellungen gedacht habe wäre gewesen, dass ich über ein Widget den Command in Richtung des gwünschten leeren Item gebe. Dies klappt auch. Also Widget Button 13% gibt den Wert 87 aus und läßt ihn im Item e. g. RL EG erscheinen. Soweit so gut.
Nun steht eine Regel bereit, welche diese Wert liesst, und die Regel RL EG 13% erkennt das. Auch dieses kann ich in der Regel übersicht erkennen. Die Regel schaltet von IDLE auf RUNNING. Nun passiert aber ... nichts. Nun kann ich mir nur vorstellen, dass der Code in der Regel, sprich das Script nicht richtig verstanden wird. Daher hier mal ein Beispiel Einer Regel von mir:

Code: Alles auswählen

configuration: {}
triggers:
  - id: "1"
    configuration:
      itemName: RL_Command_EG
      command: UP
    type: core.ItemCommandTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript
      script: |-
        rule "RL_EG_Hoch"
        when
            Item RL_Command_EG received command UP
        then
            RL_Wohnzimmer_Links_Level.sendCommand(UP)
            Thread.sleep(4000)
            RL_Wohnzimmer_Rechts_Level.sendCommand(UP)
            Thread.sleep(3000)
            RL_Kuche_Links_Level.sendCommand(UP)
            Thread.sleep(2000)
            RL_Kuche_Rechts_Level.sendCommand(UP)
        end
    type: script.ScriptAction
Habt ihr ne Ahnung wo's da hakt?

Gruß Sepp

Harka
Beiträge: 489
Registriert: 30. Apr 2021 13:13
Answers: 19

Re: Szene mit Pause erstellen

Beitrag von Harka »

Hi,
Du darfst nicht RuleDSL mit JavaScript(ECMA) vertauschen. Kopiere den Code bitte in eine neue Then_Action_RunScript_RuleDSL und lösch das alte.

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

Re: Szene mit Pause erstellen

Beitrag von udo1toni »

Und wenn Du schon dabei bist... Schau Dir bitte noch mal den Code meiner Beispiele an...
Eine DSL Rule per Textdatei ist anders aufgebaut, als eine DSL Rule per UI. Die Textdatei benötigt ja einen Teil in der Ruledefinition, der den oder die Trigger angibt. Dieser Teil ist in der UI auch vorhanden, aber eben nicht Teil des Codes.
Konkret: Bitte entferne im Code alles von rule bis then (einschließlich) und noch am Ende das end.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

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

Re: Szene mit Pause erstellen

Beitrag von udo1toni »

Ach so... Die ganze Herangehensweise erscheint mir reichlich kompliziert.
djd1983 hat geschrieben: 8. Dez 2023 19:12 Prozentangaben die sich auf die Laufzeit der RL beziehen; allerdings in umgekehrte Reihenfolge von openHAB, sprich nach dem Muster von Homematic
Kannst Du natürlich machen, es ist aber falsch :) 0 % ist bei einem Rollladen "geöffnet", 100 % ist "geschlossen". Daran ändern auch verquere Definitionen verschiedener Systeme nichts, denn zum Einen gibt es andere (und vor allem professionellere) Systeme, die es korrekt machen - z.B. knx - und zum Anderen gibt es eine objektive Begründung, warum 100 % geschlossen bedeutet. Betrachtet man nämlich die Aufgabe eines Rollladens, kommt man schnell zu der Einsicht, dass ein Rollladen das exakte Gegenteil eines Dimmers ist.
Ein Dimmer, der maximal wirkt, macht maximale Helligkeit - 100 %. Wenn es im Zimmer bereits hell ist, kann ein Dimmer das Zimmer nicht verdunkeln. Ein Rollladen kann bei Dunkelheit das Zimmer nicht heller machen, er kann aber ein (durch Lichteinfall durch die Fenster) helles Zimmer abdunkeln, er ist also per Definition zu 100 % aktiv im geschlossenen Zustand.
Wie erwähnt, bei knx gibt es auch nur diese eine Definition (im Gegensatz zu anderen Systemen, die gerne mal eine Invertierung der Signale vorsehen - warum nur...)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

djd1983
Beiträge: 20
Registriert: 7. Dez 2023 09:38
Answers: 0

Re: Szene mit Pause erstellen

Beitrag von djd1983 »

Hallo Harka, hallo Udo,
ihr habt mich ans Ziel geführt. Alles funktioniert. Bin sehr zufreiden und die WunschFunktionen sind erstmal vorhanden. Danke dafür. Was die Richtigkeit der Art und Weise der Programmierung angeht; Ich denke Luft nach oben gibt es immer. :idea: Mal sehen wie das in ein paar Monaten aussieht wenn die ITems expandiert sind. :D Da werde ich bestimmt im Nachhinein an dem ein oder anderen Widget/Script noch rumschrauben.

Was die Prozentgeschicht der RL angeht...
ehrlich gesagt musste ich ein bisschen schmunzeln als ich diesen Teil deines Beitrags las. Ich konnte mich an einen anderen Thread erinnern, indem du versuchtest die "richtige Version" ebenfalls geneauso so zu verkaufen. Ich denke am Ende Ist es alles das selbe. :o ( HAT ER NICH GESAGT ...) :lol:

Letzenendes bin ich mit dem Gedanken mit Homematic so "groß geworden" und ich begründe das mit dem Anteil des Lichts den man hereinläßt. 100% viel Sonne, 0% keine Sonne. Aber dass ist eine reine Philosophiesache schätze ich mal. kaputt geht davon ja nichts.

Ich melde mich nochmal, wenn ich wieder ein paar scripte und programmiersprachen durcheinander geworfen habe. :)

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

Re: Szene mit Pause erstellen

Beitrag von udo1toni »

djd1983 hat geschrieben: 8. Dez 2023 23:36 ich begründe das mit dem Anteil des Lichts den man hereinläßt.
Wie erwähnt, bei Dunkelheit kann man kein Licht hereinlassen.

Stell Dir vor, Du hast ein Fenster OHNE Rollladen. Ah, der nicht vorhandene Rollladen hat 100 %.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten