Storen nach x-Sekunden stoppen

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Norick
Beiträge: 250
Registriert: 31. Jan 2022 06:35
Answers: 0

Re: Storen nach x-Sekunden stoppen

Beitrag von Norick »

fast aber leider noch nicht ganz :shock:
udo1toni hat geschrieben: 18. Jul 2023 18:17 Das heißt, Du legst zwei Rules an, die eine kümmert sich ausschließlich um die Positionsfahrt als solche, die andere gibt ausschließlich einen Steuerbefehl.
In der UI wird ausschließlich das Proxy Item sichtbar gemacht.
Ich denke dieser Teil wo du sagst man soll zwei Rules verwenden habe ich nicht ganz verstanden. Nun ich habe folgendes gemacht:

1) Proxy Item angelegt ohne Link zu einer Store. Dieses Item sehe ich dann auch unter den Models wieder
2) dein Proxy Item in den ordner "rules" kopiert
3) Eine neue Rule angelegt (DSL) mit dem gleichen Code wie das Proxy Item im "rule" Ordner

Code: Alles auswählen

configuration: {}
triggers: []
conditions: []
actions:
  - inputs: {}
    id: "1"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: >-
        /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"
        
        etc...

4) Nochmals eine neue Rule angelegt: Wenn ich hier unter "THEN" das Proxy Item auswähle kann ich mit "SendCommand" einen Wert angeben.

Code: Alles auswählen

configuration: {}
triggers: []
conditions: []
actions:
  - inputs: {}
    id: "1"
    configuration:
      itemName: Proxy_Store_Essen
      command: "50"
    type: core.ItemCommandAction

Aber so funktioniert es nicht ganz weil irgendwie der "Link" zum DSL Script fehlt oder?

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

Re: Storen nach x-Sekunden stoppen

Beitrag von udo1toni »

Nein. Du hast noch nicht verstanden, wie die Konfiguration von openHAB funktioniert. :)

Früher mal... wurde openHAB ausschließlich über Textdateien konfiguriert. Es gab keine UI für die Administration, nur eine UI, um eine Bedienoberfläche zur Verfügung zu stellen.

Seit openHAB2 gibt es aber zusätzlich die Möglichkeit, die Konfiguration über eine "Verwaltungs-UI" vorzunehmen. Und je weiter sich openHAB entwickelt, umso mehr Elemente werden so umgebaut, dass sie auch über die UI konfiguriert werden können.

Es gibt also zwei grundverschiedene Methoden, Rules anzulegen, entweder per Textdatei, oder per UI.
Man kann viele Rules fast unverändert so oder so anlegen, aber eben nur fast. Bei bestimmten Rules geht das überhaupt nicht. Dies hier ist so ein Fall.

Du kannst die Rule, um die Positionsfahrten zu realisieren nicht über die UI anlegen, weil sie einen Timer verwendet.

Gegeben: openHAB läuft auf einem Raspberry PI, verwendet wurde das openHABian Image. Dann gibt es eine Samba Freigabe, die vom Windows PC aus als Netzwerkfreigabe erreichbar ist. User für diese Freigabe ist openhabian mit dem Passwort openhabian (falls es nicht verändert wurde).
Damit sollte es möglich sein, schreibend auf die freigegebenen Verzeichnisse zuzugreifen.
Im Verzeichnis openHAB-conf gibt es ein Unterverzeichnis rules. In diesem Verzeichnis legst Du eine Datei an, z.B. store.rules. Wichtig ist die Endung .rules und der Speicherort, keine Unterverzeichnisse anlegen, kein anderes Verzeichnis nutzen.

ACHTUNG! Der Zeichensatz der Datei ist zwingend UTF-8, bitte für die Umbrüche NICHT <CR>+>LF> verwenden. Am einfachsten erreichst Du das über einen vernünftigen Texteditor wie Notepad++ oder (noch besser) VS Code.

In der Datei store.rules legst Du mindestens die Rule für die Positionsfahrt an:

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
Dabei ersetzt Du jedes Vorkommen von StoreControl durch das Item, welches tatsächlich den Motor des Store steuert (es sollte sich um ein Rollershutter Item handeln).
Weiterhin ersetzt Du jedes Vorkommen von MeinStore durch das Proxy Item, welches Du nutzen willst (auch dieses soll vom Typ Rollershutter sein).
Außerdem musst Du die Fahrzeiten für die Auf- und Zufahrt bestimmen und in den beiden globalen Konstanten iStoreUp und iStoreDown hinterlegen (in Millisekunden, aber keine Sorge, Du musst nicht auf eine Millisekunde genau messen. Versuche es auf eine halbe Sekunde genau auszumessen, das sollte hinreichend genau sein).

In der UI legst Du nun ein Rollershutter Widget an, mit dem Proxy Item als Steueritem. Nun solltest Du über dieses Widget den Store bedienen können, und zwar inklusive Rückmeldung der Position, sobald der Store einmal vollständig zu- und wieder aufgefahren wurde.

Und nun kannst Du eine zweite Rule anlegen, ob über die UI oder über eine Textdatei ist dann egal, die dem Proxy Item Beim gewünschten Ereignis (Temperatur ist von unter dem Grenzwert auf über dem Grenzwert gestiegen) den Befehl für die gewünschte Position sendet.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Norick
Beiträge: 250
Registriert: 31. Jan 2022 06:35
Answers: 0

Re: Storen nach x-Sekunden stoppen

Beitrag von Norick »

Ok danke für die Korrekturen, da hatte ich noch ein paar Fehler drinnen. Ich habe es jetzt so umgesetzt - denke ich zumindest - kann es aber noch nicht bedienen resp. die Store bewegt sich nicht. Ich habe es mit einem Widget auch probiert resp. auch mit einer Test-rule.

Diese sieht so aus:

Code: Alles auswählen

configuration: {}
triggers: []
conditions: []
actions:
  - inputs: {}
    id: "1"
    configuration:
      command: "50"
      itemName: Proxy_Store_Essen
    type: core.ItemCommandAction
Wenn ich diese aufrufe, dann bekomme ich im logFile das ganze File "Proxy_Store_Essen.rules" angezeigt mit folgender Fehlermeldung:

Code: Alles auswählen

Script execution of rule with UID '269cad4252' failed:
Frage: Ist es richtig das File *.rules gleich zu bennen wie das proxy-Item?

Ist das command: "50" so richtig (siehe oben)?

Was könnte es sonst noch sein?

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

Re: Storen nach x-Sekunden stoppen

Beitrag von udo1toni »

Der Name der .rules Datei ist egal, solange der Name der Datei mit .rules endet und Du nur das englische Alphabet und die arabischen Zahlen verwendest. (Unterstrich, minus und Punkt wären auch noch erlaubt, aber wozu?) Wähle die Dateinamen immer sinnvoll.
Die Endung .rules deutet es an (und das zieht sich durch ganz openHAB durch), man kann in einer .rules Datei beliebig viele Rules anlegen. Es ist also eher nicht sinnvoll, die Datei nach einem Item zu benennen.
Traditionell werden Dateinamen durchgängig klein geschrieben, das ist aber keine Pflicht. Nur muss man beim Zugriff auf die Datei beachten, dass Text.txt eine andere Datei ist als Text.TXT oder text.txt, in unixoiden Betriebssystemen sind das alles unterschiedliche Dateien.

Warum hast Du die nächsten (die "wichtigen") Informationen der Fehlermeldung nicht hierher kopiert? Es steht ja sehr eindeutig da, dass die Rule nicht ausgeführt weredn konnte, und openHAB gibt immer einen Grund an. (deshalb auch der Doppelpunkt).

Hast Du auf die Codierung der Datei geachtet? Am Ende einer Zeile nur <LF>, Zeichensatz UTF-8.
store.rules
Der erste Versuch sollte über die UI erfolgen (also z.B. mit einem Knob Widget oder einem Slider Widget, so dass man Werte von 0 bis 100 an das Proxy Item senden kann. Z.B. als Slider Card:

Code: Alles auswählen

component: oh-slider-card
config:
  item: MeinStore
  title: Store
  min: 0
  max: 100
  step: 1
  scale: true
  unit: "%"
  releaseOnly: true
releaseOnly sorgt dafür, dass der Befehl erst gesendet wird, wenn Du den Slider loslässt.
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Norick
Beiträge: 250
Registriert: 31. Jan 2022 06:35
Answers: 0

Re: Storen nach x-Sekunden stoppen

Beitrag von Norick »

ok der Fehler ist nun weg. Da hatte ich ein DSL-Script noch in der Rule drinnen. Alles gelöscht und gehofft dass es dann klappt :o
Jetzt bekomme ich folgendes:

Code: Alles auswählen

ttempting to send a state update of an item which doesn't exist: undefined
Die Frage hier ist, welches Item ist jetzt gemeint? Dass Proxy oder das StorenItem?
Die andere Frage die sich mir stellt, wie weiss OpenHab welche Rule er verwenden muss bzw. was ist der Link zum *.rules?

Mein rules File sieht jetzt so aus (gleich wie bei dir):

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 Proxy_Store_Essen received command
then
    val Integer iPos = (Proxy_Store_Essen.state as Number).intValue                  // Ermittle Ist-Position
    switch(receivedCommand) {
        case UP   : {
            Store_WohnenEssen.sendCommand(UP)                                     // Bei Aufwärts-Befehl sende UP
            bStoreDir = false                                                // Merke Fahrtrichtung
            lStoreStart = now.toInstant.toEpochMilli                         // Merke Startzeit
        }
        case DOWN : {
            Store_WohnenEssen.sendCommand(DOWN)                              // Bei Abwärts-Befehl sende DOWN
            bStoreDir = true                                                 // Merke Fahrtrichtung
            lStoreStart = now.toInstant.toEpochMilli                         // Merke Startzeit
        }
        case STOP : {
            Store_WohnenEssen.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
                                  }
            Proxy_Store_Essen.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
                Store_WohnenEssen.sendCommand(UP)                            // Starte Fahrt
            } else if(iMove > 0) {                                           // Abwärts
                iTime = iStoreDown * iMove                                   // Errechne Fahrtdauer
                Store_WohnenEssen.sendCommand(DOWN)                          // Starte Fahrt
            }
            tStore?.cancel                                                   // lösche Timer, falls vorhanden
            tStore = createTimer(now.plusNanos(iTime*10000),[                // Starte Timer für Stopp-Befehl
                Store_WohnenEssen.sendCommand(STOP)                          // Stoppe Fahrt
                Proxy_Store_Essen.postUpdate(iSoll)                   // setze neue Position
            ])
        }
    }
end
Mein StorenItem:
StorenItem.PNG

Mein Proxy:
Proxy.PNG
Da passt doch alles!?
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

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

Re: Storen nach x-Sekunden stoppen

Beitrag von udo1toni »

Norick hat geschrieben: 1. Aug 2023 10:35 Jetzt bekomme ich folgendes:
Ja, ist erklärbar. Ergänze mal bitte folgende Zeilen:

Code: Alles auswählen

            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
                                  }
            if(iPosNew < 0)   iPosNew = 0    // Diese Zeile einfügen
            if(iPosNew > 100) iPosNew = 100  // Diese Zeile einfügen
            Proxy_Store_Essen.postUpdate(iPosNew)                            // Schreibe neue Position
        }
Die Fahrtzeiten (Inhalt der beiden globalen Konstanten iStoreUp und iStoreDown) sind vermutlich zu kurz eingestellt. Bei der ersten Fahrt in eine Richtung kann es natürlich ebenfalls zu einer Grenzwertüberschreitung kommen, das verhindern die beiden Codezeilen.
Weiter unten ist das hingegen nicht möglich, da die Variable iSoll ohnehin nur Werte von 0 bis 100 annehmen kann.
Norick hat geschrieben: 1. Aug 2023 10:35 Die Frage hier ist, welches Item ist jetzt gemeint? Dass Proxy oder das StorenItem?
Das ergibt sich aus dem Kontext, das einzige Item, welches einen Status zugewiesen bekommt, ist Proxy_Store_Essen (das einzige mit .postUpdate() Methode)
Norick hat geschrieben: 1. Aug 2023 10:35 Die andere Frage die sich mir stellt, wie weiss OpenHab welche Rule er verwenden muss bzw. was ist der Link zum *.rules?

openHAB triggert die Rule durch ein Ereignis. Welches Ereignis das ist, steht im when-Teil der Rule, hier also Item Proxy_Store_Essen received command. Einen Link braucht es nicht, die Rule-Engine ist komplett Ereignis-gesteuert.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Norick
Beiträge: 250
Registriert: 31. Jan 2022 06:35
Answers: 0

Re: Storen nach x-Sekunden stoppen

Beitrag von Norick »

ok ich habe diese Zeilen eingefügt und das Widget bzw. auch eine einfache Rule manuell getriggert. Beides leider ohne Erfolg und die Store bewegt sich nicht. Im log-File sehe ich jedoch KEINEN Eintrag mehr, soweit so gut :)

Die Rule sieht so aus:

Code: Alles auswählen

configuration: {}
triggers: []
conditions: []
actions:
  - inputs: {}
    id: "1"
    configuration:
      itemName: Proxy_Store_Essen
      command: "40"
    type: core.ItemCommandAction
Ich habe geschaut ob in der ETS etwas auf dem KNX-Bus kommt wenn ich die Rule triggere. Hier kommt nichts... Mit einem physik. Taster und auch mit dem Item direkt aus Openhab kann ich die Store rauf- oder runterlassen. Das heisst dieser Teil funktioniert schon. Aber aus irgendeinem Grund findet oder triggered openhab nicht die *.rules.

Kann man hier u.U. noch eine Log-Zeile einfügen damit man einen Hinweis bekommt wo es klemmt? Oder hast du noch eine andere Idee? Noch als Ergänzung ich benutze oOH 3.4.3 (windows).

Danke

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

Re: Storen nach x-Sekunden stoppen

Beitrag von udo1toni »

Dann hilft alles nix, wir müssen ein paar Logbefehle einbauen, um zu sehen, was die Rule falsch macht :)

Beim Durchschauen des Codes während des Ergänzens der Logbefehle sind mir noch drei Fehler aufgefallen, wobei der erste vielleicht nur ein Copy & Paste Fehler ist (/ statt // in Position 1,1), der zweite aber die Ausführung der Rule als Ganzes verhindert (Rule statt rule). openHAB ist grundsätzlich case sensitive.
Fehler drei geht auf meine Kappe und verhindert das korrekte Berechnen der Position :) weil ich aus Versehen beim Berechnen der Fahrtzeit den größeren vom kleineren Wert abgezogen habe. Ich habe das hier natürlich ebenso korrigiert wie die anderen Fehler.
Weil Logging aber grundsätzlich eine gute Idee ist, hier die Rule mit vielen sinnvollen Logbefehlen:

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 Proxy_Store_Essen received command
then
    logDebug("store","Rule gestartet mit Befehl {}",receivedCommand)
    val Integer iPos = (Proxy_Store_Essen.state as Number).intValue             // Ermittle Ist-Position
    switch(receivedCommand) {
        case UP   : {
            Store_WohnenEssen.sendCommand(UP)                                   // Bei Aufwärts-Befehl sende UP
            bStoreDir = false                                                   // Merke Fahrtrichtung
            lStoreStart = now.toInstant.toEpochMilli                            // Merke Startzeit
            logDebug("store","UP erkannt, Starte Messung ({})",lStoreStart)   
        }   
        case DOWN : {
            Store_WohnenEssen.sendCommand(DOWN)                                 // Bei Abwärts-Befehl sende DOWN
            bStoreDir = true                                                    // Merke Fahrtrichtung
            lStoreStart = now.toInstant.toEpochMilli                            // Merke Startzeit
            logDebug("store","DOWN erkannt, Starte Messung ({})",lStoreStart)
        }
        case STOP : {
            logDebug("store","STOP erkannt, Berechne {} - {}",now, lStoreStart)
            Store_WohnenEssen.sendCommand(STOP)                                 // Bei Stopp-Befehl sende STOP
            val Long lDiff = now.toInstant.toEpochMilli - lStoreStart           // 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
                                  }
            if(iPosNew < 0)   iPosNew = 0                                       // Bei unterschreiten auf 0 begrenzen
            if(iPosNew > 100) iPosNew = 100                                     // Bei überschreiten auf 100 begrenzen
            logDebug("store","Diff: {} Pos: {} Pos neu: {}", lDiff, iPos, iPosNew)
            Proxy_Store_Essen.postUpdate(iPosNew)                               // Schreibe neue Position
        }
        default   : {                                                           // Befehl ist eine Zahl
                        iSoll = (receivedCommand as Number).intValue            // Bestimme Sollposition
            logDebug("store","Positionsfahrt erkannt ({} %)", iSoll)
            val Integer iMove = iSoll - iPos                                    // Bestimme Teilstrecke
            var Integer iTime = 0                                               // Initialisiere Variable
            if(iMove < 0) {                                                     // Aufwärts
                iTime = -(iStoreUp * iMove)                                     // Errechne Fahrtdauer
                Store_WohnenEssen.sendCommand(UP)                               // Starte Fahrt
            } else if(iMove > 0) {                                              // Abwärts
                iTime = iStoreDown * iMove                                      // Errechne Fahrtdauer
                Store_WohnenEssen.sendCommand(DOWN)                             // Starte Fahrt
            }
            logDebug("store","Strecke von {} % nach {} % = {} % ({} mSec)", iPos, iSoll, iMove, iTime)
            tStore?.cancel                                                      // lösche Timer, falls vorhanden
            tStore = createTimer(now.plusNanos(iTime*10000),[                   // Starte Timer für Stopp-Befehl
                Store_WohnenEssen.sendCommand(STOP)                             // Stoppe Fahrt
                Proxy_Store_Essen.postUpdate(iSoll)                             // setze neue Position
            ])
        }
    }
end
Du kannst einfach den Inhalt Deiner .rules Datei ersetzen (natürlich musst Du noch die Fahrtzeiten korrigieren, das sind glaube ich immer noch die, die ich ursprünglich mal als Beispielwerte hinterlegt habe)

Das Logging wird nun noch nicht aktiv sein, denn ich habe die Befehle alle auf DEBUG gesetzt, das Default Logging für Rules ist aber INFO, die Meldungen werden also nicht ausgegeben.
Sollten die drei kleinen Fehlerkorrekturen ausreichen, um zum Erfolg zu führen, brauchst Du nichts weiter zu tun :)
Sollte es immer noch nicht funktionieren, müsstest Du Dich lediglich mit der Karaf Konsole verbinden und das Logging auf DEBUG setzen.
Keine Sorge, Du gibst insgesamt nur vier Befehle ein, ich habe hier nur die komplette Session eingefügt...

Code: Alles auswählen

openhabian@openhabian:~$ openhab-cli console                <<< Befehl 1

Logging in as openhab
Password:                                                   <<< Das Passwort lautet    habopen

                           _   _     _     ____
   ___   ___   ___   ___  | | | |   / \   | __ )
  / _ \ / _ \ / _ \ / _ \ | |_| |  / _ \  |  _ \
 | (_) | (_) |  __/| | | ||  _  | / ___ \ | |_) )
  \___/|  __/ \___/|_| |_||_| |_|/_/   \_\|____/
       |_|       4.0.0.RC1 - Milestone Build

Use '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
To exit, use '<ctrl-d>' or 'logout'.

openhab> log:set DEBUG org.openhab.core.model.script.store  <<< Befehl 2
openhab> log:list                                           <<< Befehl 3
Logger                                             │ Level
───────────────────────────────────────────────────┼──────
ROOT                                               │ WARN
javax.jmdns                                        │ ERROR
javax.mail                                         │ ERROR
openhab.event                                      │ INFO
openhab.event.AddonEvent                           │ ERROR
openhab.event.ChannelDescriptionChangedEvent       │ ERROR
openhab.event.GroupStateUpdatedEvent               │ ERROR
openhab.event.InboxUpdatedEvent                    │ ERROR
openhab.event.ItemAddedEvent                       │ ERROR
openhab.event.ItemChannelLinkAddedEvent            │ ERROR
openhab.event.ItemChannelLinkRemovedEvent          │ ERROR
openhab.event.ItemRemovedEvent                     │ ERROR
openhab.event.ItemStateEvent                       │ ERROR
openhab.event.ItemStateUpdatedEvent                │ ERROR
openhab.event.RuleAddedEvent                       │ ERROR
openhab.event.RuleRemovedEvent                     │ ERROR
openhab.event.RuleStatusInfoEvent                  │ ERROR
openhab.event.StartlevelEvent                      │ ERROR
openhab.event.ThingAddedEvent                      │ ERROR
openhab.event.ThingRemovedEvent                    │ ERROR
openhab.event.ThingStatusInfoEvent                 │ ERROR
openhab.event.ThingUpdatedEvent                    │ ERROR
org.apache.cxf.jaxrs.sse.SseEventSinkImpl          │ ERROR
org.apache.cxf.phase.PhaseInterceptorChain         │ ERROR
org.apache.karaf.jaas.modules.audit                │ INFO
org.apache.karaf.kar.internal.KarServiceImpl       │ ERROR
org.apache.karaf.shell.ssh.SshUtils                │ ERROR
org.apache.karaf.shell.support                     │ OFF
org.apache.sshd                                    │ WARN
org.eclipse.lsp4j                                  │ OFF
org.jupnp                                          │ ERROR
org.openhab                                        │ INFO
org.openhab.core.model.script.store                │ DEBUG  <<< Ergebnis des Befehls
org.ops4j.pax.url.mvn.internal.AetherBasedResolver │ ERROR
org.ops4j.pax.web.pax-web-runtime                  │ OFF
su.litvak.chromecast.api.v2.Channel                │ ERROR
openhab> logout                                             <<< Befehl 4
openhabian@openhabian:~$
Anschließend sollte es bei jedem Triggern der Rule Ausgaben in der Logdatei geben, die dann hilfreich beim Eingrenzen weiterer Fehler wären. Um das Logging elegant wieder loszuwerden, reicht es, statt

Code: Alles auswählen

openhab> log:set DEBUG org.openhab.core.model.script.store
den Befehl

Code: Alles auswählen

openhab> log:set DEFAULT org.openhab.core.model.script.store
zu senden.
Einstellungen zum Logging wirken unmittelbar und sind persistent, d.h. Du muss openHAB nicht neu starten, aber wenn Du es mal neu startest, bleiben alle Einstellungen erhalten.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Norick
Beiträge: 250
Registriert: 31. Jan 2022 06:35
Answers: 0

Re: Storen nach x-Sekunden stoppen

Beitrag von Norick »

Oha, da hast du Recht. Das fehlende "\" hat dazu geführt dass das Script nicht ausgeführt wurde. Hier jetzt mit deinen Anpassungen und das Logfile mit den Debug Einträgen:

Code: Alles auswählen

[DEBUG] [org.openhab.core.model.script.store ] - Rule gestartet mit Befehl 40
[DEBUG] [org.openhab.core.model.script.store ] - Positionsfahrt erkannt (40 %)
[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'ProxyStoreEssen-1' failed: An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.IntegerExtensions.operator_lessThan(int,int) on instance: null in ProxyStoreEssen
Ein Teil scheint schon zu funktionieren, resp. die Rule wird jetzt zumindest aufgerufen. Was genau das Problem ist habe ich nicht ganz kapiert. Ich bin mir sicher du weisst mehr dazu.. :roll:

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

Re: Storen nach x-Sekunden stoppen

Beitrag von udo1toni »

Das Problem wird sein, dass das Proxy Item noch keinen Status hat...

Ändere bitte die Rule vorne ab:

Code: Alles auswählen

    logDebug("store","Rule gestartet mit Befehl {}",receivedCommand)
    var Integer iPos = 0
    if(Proxy_Store_Essen.state instanceof Number)
        iPos = (Proxy_Store_Essen.state as Number).intValue                     // Ermittle Ist-Position
Nun wird iPos mit 0 vorbelegt und der Staus von Proxy_Store_Essen nur dann verwendet, wenn es sich um eine gültige Zahl handelt.
Natürlich wird das zu Beginn eventuell nicht stimmen, aber spätestens wenn der Store einmal vollständig geschlossen und geöffnet wurde, sollte es wie geplant arbeiten.

Die Codezeile kann ohne Probleme drin bleiben, ist sogar besser in dieser Form :)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten