Seite 1 von 6

Storen nach x-Sekunden stoppen

Verfasst: 13. Jun 2023 06:46
von Norick
Ich versuche gerade eine neue Rule zu schreiben um die Storen auf einer Position x zu stoppen. Ich habe diese per UI implementiert und funktioniert wenn der Trigger ausgelöst wird. Leider kann man hier nur angeben ob die Store nach unten oder ganz noch oben gehen soll.

Was ich möchte ist jedoch die Store auf einer Position x zu stoppen, d.h. nach einer Zeit t. Kann mir bitte jemand sagen wie ich einen solchen Timer direkt in die UI eingeben kann?

Re: Storen nach x-Sekunden stoppen

Verfasst: 13. Jun 2023 20:01
von udo1toni
Was Du brauchst,m ist ein Proxy Item und etwas Intelligenz im Hintergrund :)

In die UI kommt ein Rollershutter Widget, welches mit einem Rollershutter ITem gekoppelt ist. Das Item kennt die Befehle UP/DOWN//STOP und 0 - 100. Außerdem kennt des den Status 0 - 100.
0 wird "ganz oben", 100 wird "ganz unten".

Nun brauchst Du noch eine Rule, welche aus der aktuellen Position und der Fahrzeit in der vorgegebenen Richtung errechnet, wann der Antrieb gestoppt werden muss.
Du musst also in zwei Variablen speichern, wie lange der Stor für eine Abwärtsfahrt benötigt und wie lange der Stor für eine Aufwärtsfahrt benötigt. Anschließend kannst Du von jeder vorgegebenen Position aus berechnen, wie lange die Fahrt zu einer anderen Position dauert, etwa so:

Code: Alles auswählen

/Globale Variablen und Konstanten immer vor der ersten Rule definieren!
val Integer iStoreUp    = 29500 // 29,5 Sekunden aufwärts
val Integer iStoreDown  = 27300 // 27,3 Sekunden  abwärts
var Timer   tStore      = null  // Timer für Positionsfahrt
var Long    lStoreStart = null  // Startzeit für UP/DOWN Fahrt
var Boolean bStoreDir   = false // Richtung (false = UP)
var Integer iSoll       = null  // Sollposition
Rule "drive store"
when
    Item MeinStore received command
then
    val Integer iPos = (MeinStore.state as Number).intValue                  // Ermittle Ist-Position
    switch(receivedCommand) {
        case UP   : {
            StoreControl.sendCommand(UP)                                     // Bei Aufwärts-Befehl sende UP
            bStoreDir = false                                                // Merke Fahrtrichtung
            lStoreStart = now.toInstant.toEpochMilli                         // Merke Startzeit
        }
        case DOWN : {
            StoreControl.sendCommand(DOWN)                                   // Bei Abwärts-Befehl sende DOWN
            bStoreDir = true                                                 // Merke Fahrtrichtung
            lStoreStart = now.toInstant.toEpochMilli                         // Merke Startzeit
        }
        case STOP : {
            StoreControl.sendCommand(STOP)                                   // Bei Stopp-Befehl sende STOP
            val Long lDiff = lStoreStart - now.toInstant.toEpochMilli        // Errechne Fahrtzeit
            val Integer iPosNew = if(bStoreDir) {                            // Abhängig von der Fahrtrichtung
                                      iPos - (lDiff/iStoreUp*100).intValue   // Bestimme neue Position
                                  } else {
                                      iPos + (lDiff/iStoreDown*100).intValue // Bestimme neue Position
                                  }
            MeinStore.postUpdate(iPosNew)                                    // Schreibe neue Position
        }
        default   : {                                                        // Befehl ist eine Zahl
                        iSoll = (receivedCommand as Number).intValue         // Bestimme Sollposition
            val Integer iMove = iSoll - iPos                                 // Bestimme Teilstrecke
            var Integer iTime = 0                                            // Initialisiere Variable
            if(iMove < 0) {                                                  // Aufwärts
                iTime = -(iStoreUp * iMove)                                  // Errechne Fahrtdauer
                StoreControl.sendCommand(UP)                                 // Starte Fahrt
            } else if(iMove > 0) {                                           // Abwärts
                iTime = iStoreDown * iMove                                   // Errechne Fahrtdauer
                StoreControl.sendCommand(DOWN)                               // Starte Fahrt
            }
            tStore?.cancel                                                   // lösche Timer, falls vorhanden
            tStore = createTimer(now.plusNanos(iTime*10000),[                // Starte Timer für Stopp-Befehl
                StoreControl.sendCommand(STOP)                               // Stoppe Fahrt
                MeinStore.postUpdate(iSoll)                                  // setze neue Position
            ])
        }
    }
end
Das Format, ist hier das für rules-Dateien im Ordner $OPENHAB_CONF/rules, die Rule könnte man notfalls auch über die UI anlegen (dann müsste man die Konstanten halt lokal definieren und auf die Timer Variable verzichten). Allerdings braucht es auch noch die Position des Store, das übernimmt die Rule ebenfalls, nur wird man hier vermutlich nicht ohne globale Variablen auskommen (jedenfalls nicht ohne weiteres)

Wie man sehen kann, ist so eine Steuerung nicht trivial, und sei sie auch noch so einfach.
Ich nutze für elektrische Rollläden 2-Kanal-Schalter von Sonoff, die ich mit Tasmoata geflasht habe. Tasmota bietet Shutter-Support, dort ist also alles drin, was man benötigt. Die Ansteuerung erfolgt dann mit den Kommandos UP/DOWN/STOP und 0 - 100, die Rückmeldung kommt als Zahl 0 - 100, also exakt so, wie openHAB das erwartet (vorausgesetzt, man parametriert alles korrekt...)

Re: Storen nach x-Sekunden stoppen

Verfasst: 15. Jun 2023 06:57
von Norick
Vielen Dank für die Antwort. Ja, scheint wirklich nicht trivial zu sein.

Du schreibst man benötigt dazu ein "Rollershutter Widget" welches mit dem Item gekoppelt ist. Was meinst du damit genau? Benötigt es nicht nur die Rule die du gezeigt hast?

In meinem Fall ist es so, dass die Storen soweit funktionieren und ich eigentlich "Nur" die Storen nach einer Zeit x stoppen möchte in einer Rule. Ginge dies u.U. nicht einfacher mit einem Timer welcher die Store nach der Zeit x stoppt?


Oder gäbe es die Möglichkeit ein Rollershutte-Widget zu benutzen welches die Fähigkeit hat den Storen in einer Position x zu stoppen, mit einer Rule zu verknüpfen? Wenn ja, wäre dies u.U. noch einfacher die Frage ist nur wie ich ein Widget mit der rule dann verbinde.

Re: Storen nach x-Sekunden stoppen

Verfasst: 15. Jun 2023 17:05
von udo1toni
Du kannst machen was Du willst.
Ein Store ist ja am Ende des Tages nichts anderes als eine Jalousie oder ein Rollladen, er wird mit Motor angetrieben, er hat eine offene Stellung und eine geschlossene Stellung, zwischen beiden Positionen vergeht eine Fahrzeit X, weshalb man die Steuerung in % erledigt, wobei 1 % logischerweise 1/100 X entspricht. Du kannst Dich mit dem Taschenrechner hinstellen und ausrechnen, dass Du für die halbe Wegstrecke 17,3 Sekunden benötigst und dann diese Zeit über die UI eingeben, damit ein Timer die Fahrt nach 17,3 Sekunden stoppt. Oder Du nutzt eine Rule, welche sich um alle Aspekte der Steuerung kümmert.
Und was macht die Rule? Sie bestimmt anhand der aktuellen Position (!) und der Sollposition (beides als Anteil der Wegstrecke, nicht als Anzahl Sekunden), wie lange der Motor in welche Richtung laufen muss, um von der aktuellen Position auf die Sollposition zu kommen.
In der Konsequenz braucht die Rule zwingend einige Informationen, als da wären: Fahrtdauer für eine Gesamtstrecke (und zwar je Richtung, insbesondere wenn der Store von oben nach unten bewegt wird, weil der Motor dann unterschiedlich viel Kraft für die beiden Richtungen braucht)
sowie die aktuelle Position, und als Befehl die neue Sollposition.

Es mag ja sein, dass Deine Store "soweit funktionieren", aber es reicht nun mal nicht, einen Motor ein- und auszuschalten, es gibt einfach ein paar Dinge drum herum, die berechnet werden müssen, damit das Ganze einfach funktioniert.
Und um all diese Dinge kümmert sich die Rule oben (weitgehend). Die Rule verwendet ebenfalls einen Timer zur Steuerung :)
Solltest Du statt einem Item zum Steuern der Fahrtrichtung z.B. zwei Items brauchen, lässt sich die Rule einfach anpassen, aber nur Du weißt, wie Du Deine Store ansteuerst, diesen Teil hast Du nicht erläutert.

Ein Rollladen wird immer über ein Rollershutter Item abgebildet. Ein Rollershutter Item kann über die Befehl UP/DOWN/STOP den Shutter in die gewünschte Richtung bewegen, sowie über die Angabe 0 - 100 Positionsfahrten steuern. Moderne Steuerungen nehmen dabei direkt die Befehle 0 - 100 entgegen und der Anwender muss sich um gar nichts kümmern, Deine Store können das nicht, also musst Du die entsprechende Logik selbst einbauen.

Ein Rollershutter Widget bietet Dir die entsprechenden Schaltflächen zur Steuerung an und wird mit dem Rollershutter Item verknüpft. Das ist nicht so schwer...

Re: Storen nach x-Sekunden stoppen

Verfasst: 17. Jun 2023 07:44
von Norick
so wie ich das verstehe wird dann diese Rule automatisch verwendet wenn ich über ein Storen Widget die Store bewege - richtig?

Wie kann ich aber der Store mitteilen, dass diese nach x-Sekunden stoppt (so war ja eigentlich meine Frage)? Zum Beispiel wenn die Temperatur t erreicht ist soll die Store runterfahren für x Sekunden.

Re: Storen nach x-Sekunden stoppen

Verfasst: 17. Jun 2023 09:16
von udo1toni
Gar nicht. Stattdessen sagst Du in der Rule, dass der Store auf 60 % fahren soll.

Natürlich kannst Du den Store auch stur über Zeit fahren, dann nutzt Du ein kleines Detail aus der Rule oben, das ist der Timer...

Code: Alles auswählen

...
storeDown.sendCommand(ON)
createTimer(now.plusSeconds(13),[
    storeStop.sendCommand(ON)
])
Dies wäre Code, um den Store über mehrere Items anzusteuern, eines für runter, eines für rauf, eines für Stop. In dem Fall wären die Items vermutlich "Taster", die z.B. mit einer Fernbedienung verdrahtet sind und jeweils einen Impuls an die Fernbedienung senden.

Re: Storen nach x-Sekunden stoppen

Verfasst: 18. Jun 2023 08:14
von Norick
Ok jetzt verstehe ich das Ganze besser was du meinst. Wenn ich jetzt eine neue Rule über das UI anlege kann ich als Item eine Store auswählen. Danach sehe ich unter "Then" das "send a command to" resp. weiter unter stehen dann die drei Commands zur Auswahl (UP, DOWN, STOP). Hier gibt es jedoch auch noch das Feld "Command to send" welches leer ist.

Frage:
Wie kann ich jetzt in dieser Rule der Store sagen sie soll auf 60 % fahren?

Re: Storen nach x-Sekunden stoppen

Verfasst: 18. Jun 2023 09:42
von udo1toni
Unter der Voraussetzung, dass Du eine(n) Rollladen/Store/Jalousie mit einem Rollershutter Item ansteuerst und das Gerät Positionsfahrten unterstützt, gibst Du in der Rule einfach den Zielwert an (statt UP/DOWN/STOP über die Radiobuttons zu wählen).

Allerdings ist es meiner Erfahrung meist so, dass man nicht eine einzelne Verdunkelung steuern möchte, sondern mehrere, oft genug auf unterschiedliche Positionen. Natürlich kannst Du beliebig viele Actions zu einer Rule hinzufügen, aber irgendwann wird die UI dann halt lächerlich.

Re: Storen nach x-Sekunden stoppen

Verfasst: 21. Jun 2023 06:50
von Norick
Meine Store unterstützt dies, ja. Ich habe jetzt in der Rule einfach "60" eingetragen ohne UP/DOWN/STOP. Die Rule sieht jetzt so aus:

Code: Alles auswählen

configuration: {}
triggers: []
conditions: []
actions:
  - inputs: {}
    id: "1"
    configuration:
      command: "60"
      itemName: KNX_Device_Storen_Essen_Wohnen_Essen
    type: core.ItemCommandAction
Aber wenn ich die Rule teste, in diesem Fall noch ohne Trigger, geht nichts. Ebenfalls habe ich deine Rule in dem lokalen Ordner mit der Endung .rules abgelegt bzw. eine Fehlermeldung bekomme ich keine angezeigt im log-File.

Re: Storen nach x-Sekunden stoppen

Verfasst: 21. Jun 2023 20:13
von udo1toni
Warum hast Du das denn nicht von Anfang an gesagt? Wenn Deine Store (eigentlich ja die Aktoren) Positionsfahrten unterstützen, brauchst Du keine Rules dafür (es sei denn, Du möchtest halt aus einer Rule heraus eine Position anfahren).

Stattdessen legst Du einfach ein Wigdet an, mit dem Du die gewünschte Höhe angibst, in %
In der Sitemap z.B.

Code: Alles auswählen

Switch item=KNX_Device_Storen_Essen_Wohnen_Essen mappings=[0="Auf",30="30",60="60",100="Zu"]
fertig.
Du erhältst vier Knöpfe mit der Beschriftung Auf, 30, 60 und Zu. Und bei Druck auf die Knöpfe passiert dann genau das.

Du kannst auch einen Slider verwenden, um die gewünschte Höhe zu wählen.
Wobei sich mir der Sinn dahinter nicht erschließt - es gibt allgemein vielleicht zwei gewünschte Positionen eines Rollladens - abgesehen von Auf und Zu - natürlich pro Laden individuell. Ich habe in meinem Wohnzimmer sieben Fenster, zwei nach Osten, fünf nach Süden, für die Beschattung gibt es jeweils eine Position, aber wenn ich den Fernseher anmache, sollen die Läden ein Stück runter, weil die Fenster im Bild sichtbar sind. Das war es dann aber auch.
Die Positionen selbst sind natürlich ganz bestimmte Positionen, die sollen auch auf 1 % genau angefahren werden (und das geschieht auch).

Das Gleiche geht auch über die anderen UI, Du musst lediglich dafür sorgen, dass die gewünschte Höhe als Befehl gesendet wird.