Ankündigung

Einklappen
Keine Ankündigung bisher.

System started, Einlesen von KNX und Rules

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    System started, Einlesen von KNX und Rules

    Hallo zusammen,

    mit ein paar Rules bestimme ich die Betriebsminuten von einzelnen SwitchItems einer Gruppe.

    Mein Problem ist derzeit der OH-Start.

    Während OH nicht läuft, kann sich der Status eines SwitchItems ändern. Beim OH-Startup werden die GAs vom KNX-Bus eingelesen. Die SwitchItems ändern sich von NULL auf ON oder OFF. Leider feuert das keine Rules, in meinen Augen ein großer Design-Fehler.

    Damit bleiben die "Member of ... received update"-Rules, die die Betriebsminuten berechnen, wirkungslos.

    Um einen potentiellen Statuswechsel mitzubekommen, bleibt mir wohl nichts anderes übrig, durch alle Items durchzugehen, die vom KNX-Bus eingelesen wurden, und ein Item.postUpdate(Item.state) durchzuführen.

    Oder gibt es eine andere Lösung?

    Wenn nein:

    Es scheint so zu sein, dass "System started" erst dann triggert, nachdem alle KNX-GAs gelesen wurden. Ist das definitiv so? Ich habe leider nichts darüber gefunden, was alles bereits geschehen ist, wenn "System started" triggert.

    Und gibt es eine Möglichkeit, herauszubekommen, welche Items mit einem Channel verbunden sind, der vom KNX-Bus eingelesen wird? Ich würde gerne eine weitere, letztlich redundante Gruppe vermeiden.
    openHAB 4.2

    #2
    Zitat von Tokamak Beitrag anzeigen
    mit ein paar Rules bestimme ich die Betriebsminuten von einzelnen SwitchItems einer Gruppe.
    Soweit ok.
    Mein Problem ist derzeit der OH-Start.
    Du kannst eine Betriebszeit nur dann berechnen, wenn openHAB auch läuft.
    Während OH nicht läuft, kann sich der Status eines SwitchItems ändern.
    und zwar mehrfach. Heißt, es kann sein, dass ein Switch beim Shutdown eingeschaltet war, unmittelbar danach abgeschaltet wurde und unmittelbar vor dem Start von openHAB wieder eingeschaltet wurde. Du kannst unmöglich berechnen, ob das Item ein- oder ausgeschaltet war.
    Beim OH-Startup werden die GAs vom KNX-Bus eingelesen. Die SwitchItems ändern sich von NULL auf ON oder OFF. Leider feuert das keine Rules, in meinen Augen ein großer Design-Fehler.
    Wie kommst Du darauf, dass damit Rules nicht ausgelöst werden? changed sollte definitiv getriggert werden.
    Es scheint so zu sein, dass "System started" erst dann triggert, nachdem alle KNX-GAs gelesen wurden. Ist das definitiv so?
    Nein, das ist definitiv nicht so. System started triggert exakt dann, wenn die *.rules Datei eingelesen wurde (also beim Start von openHAB und wenn die Dateiüberwachung eine Änderung des Änderungszeitpunkts festgestellt hat.)
    Ich habe leider nichts darüber gefunden, was alles bereits geschehen ist, wenn "System started" triggert.
    openHAB arbeitet komplett asynchron, es gibt keinerlei Gewissheit, welche Teile von openHAB bereits laufen und welche noch nicht, wenn irgendein Teil von openHAB gerade beginnt zu arbeiten.

    openHAB sollte nicht herunter gefahren werden (außer zu Wartungszwecken), aber wenn das passiert muss einem schon klar sein, dass solche Berechnungen zwangsläufig falsche Ergebnisse liefern werden.

    Kommentar


      #3
      Zitat von udo1toni Beitrag anzeigen
      und zwar mehrfach. Heißt, es kann sein, dass ein Switch beim Shutdown eingeschaltet war, unmittelbar danach abgeschaltet wurde und unmittelbar vor dem Start von openHAB wieder eingeschaltet wurde. Du kannst unmöglich berechnen, ob das Item ein- oder ausgeschaltet war.
      Selbstverständlich. Dennoch kann ich versuchen, den "Schaden" zu minimieren, um zumindest den letzten, ggf. geänderten Status zu berückcksichtigen.

      Wie kommst Du darauf, dass damit Rules nicht ausgelöst werden? changed sollte definitiv getriggert werden.
      Weil ich es ausprobiert habe. Es wird nichts gefeuert, weder hier noch da.
      Z.B. ist die Gruppe
      Code:
      Group:Number:SUM gFenster "Geschlossene Fenster [%d]"
      die alle Reed-Kontakte umfasst, ein Proxy zum NumberItem OffeneFenster, das mit der langweiligen Rule
      Code:
      rule "OffeneFenster"
      when
          Item gFenster changed then
           OffeneFenster.postUpdate(gFenster.members.size-(gFenster.state as Number))
      end
      aktualisiert wird.
      Obwohl alle Reed-Kontakt-GAs zum Start eingelesen werden und sich dabei gFenster ständig ändert, ist OffeneFenster nach System started NULL.

      Daher muss ich wohl ich wie oben beschrieben über postUpdate() tätig werden. Dummweise habe ich bisher keine Möglichkeit gefunden, über die Registries und sonstige Objekte an die gleichen Informationen zu kommen. Weder ist es mir gelungen, die "ga"s zu einem Channel noch die Items, die mit einem Channel verknüpft sind, zu bestimmen.
      Derzeit arbeite ich daran, über GET /rest/things an die Items zu kommen, die an KNX-Channels hängen und dort eine "ga" mit "<" haben, doch macht mir die Implementierung von JSONPATH das Leben schwer, da keine Arrays zurückgegeben werdn können.


      openHAB sollte nicht herunter gefahren werden (außer zu Wartungszwecken), aber wenn das passiert muss einem schon klar sein, dass solche Berechnungen zwangsläufig falsche Ergebnisse liefern werden.
      Auch klar. Ich setze seit über 10 Jahren einen HS3 ein, den ich aber nun durch OH ablösen will, um auch andere Bindings hinzuzuziehen. Meine Implementierung benötigt noch ein paar Wochen, bevor ich den HS3 absschalten kann.
      Ich programmiere lieber, als Logiken zusammenzuklicken. Ich muss aber zugeben, dass das eine oder andere beim HS besser gelöst ist.

      openHAB 4.2

      Kommentar


        #4
        Ich bin mit dem HS nie warm geworden, obwohl das Modell mit den Logikmodulen schon ganz nett ist (ich hab für meine Tore da auch mal was extrem Spezielles zusammengebaut)

        Aber was Du da schreibst, scheint mir eher der verzweifelte Versuch zu sein, keinesfalls die in openHAB integrierten Mechanismen zu verwenden. Beispiel:
        Fensterkontakte sollten bei geschlossenem Fenster auch CLOSED melden. Nun reicht eine Gruppe
        Code:
        Group:Contact:OR(CLOSED,OPEN) gGroup "Geschlossene Fenster [%d]"
        geöffnete Fenster lassen sich durch umdrehen der Logik ebenso ausgeben:
        Code:
        Group:Contact:OR(OPEN,CLOSED) gGroup "Geöffnete Fenster [%d]"
        .
        Sobald mindestens einer der Kontakte nicht geschlossen ist, meldet die Gruppe OPEN und im Label steht die Anzahl der geöffneten Kontakte.

        Will man in einer Rule auf die Zahl zugreifen, ist auch das kein Problem:
        Code:
        rule "geöffnete Fenster"
        when
            Member of gGroup changed
        then
            val Number nOpen = gGroup.members.filter[i|i.state == OPEN].size
            val Number nClosed = gGroup.members.filter[i|i.state == CLOSED].size
            val Number nAnzahl = gGroup.members.size
            logInfo("fensterkontakte","{} Fenster von {} sind geöffnet, {} Fenster sind geschlossen.",nOpen,nAnzahl,nClosed)
        end
        Das Summieren über OR im Label geht natürlich nur, wenn der Kontakt nicht zusätzlich noch die Stellung "gekippt" signalisieren kann.
        In einer Rule lässt sich das aber bequem auch mit String Items oder Number Items abwickeln - dann natürlich mit Strings statt States.

        Mit System started kann man auch eine Rule bauen, die prüft, ob die Items schon initialisiert wurden:
        Code:
        var Timer tSystemstart = null
        rule "Systemstart"
        when
            System started
        then
            if(tSystemstart === null)
                tSystemstart = createTimer(now.plusSeconds(1), [ |
                    if(gMygroup.members.filter[i | i.state == NULL].size > 0)
                        tSystemstart.reschedule(now.plusSeconds(1))
                    else {
                        // alle Items haben einen gültigen Wert -> Berechnung auslösen
                    }
                ])
        end
        Die Rule startet, sobald die Rule geladen wurde. Die Rule legt einen Timer an, der einmal pro Sekunde prüft, ob alle Items der angegebenen Gruppe schon einen definierten Status haben. Sobald das der Fall ist, kann der Timer abschließend etwas tun (was auch immer).

        Kommentar


          #5
          Solche Initialisierungs-Routinen habe ich schon. Das nutze ich z.B., um sicherzustellen, dass mit RestoreOnSetup alles geladen wurde.

          Das mit dem Fenster ist doch nur symbolisch. Ich habe auch andere Proxies.

          Ich weiß um den Unterschied zwischen Contact und Switch. Solange aber HS und OH parallel werkeln, werde ich nichts in der ETS umkonfigurieren, um nicht auch noch laufende HS-Logiken ändern zu müssen, die ich noch nicht ersetzt habe - allen voran der QuadClient.

          Daher hat das auch alles nichts mit Verzweiflung zu tun.

          Dein vorhergehendes Posting hat mich letztlich auf die rettende Idee gebracht, einen definierten Ausgangspunkt herstellen zu können.

          Bisher sind die Items immer initialisiert worden, bevor System started war, auch, wenn das so nicht festgelegt ist. Erst nach System started sind die Rules scharf.

          Leider gibt es keine Möglichkeit, wie im HS eine Read-Request abzusetzen. Mit schärferen Waffen geht es allerdings doch.

          Nun habe ich eine einfache Rule, die nach System started das KNX-IP-Interface via PUT /rest/things/knx:ip:bridge/enable "false" offline und sofort wieder mittels "true" online nimmt.

          Alle KNX-Things lesen daraufhin the Channel mit <-GAs wieder ein.

          Darauf reagieren nun meine Rules, und alles ist wie gewünscht.

          Super wäre es, wenn ich in der Bridge konfigurieren könnte, dass sie offline starten soll. Dann würde ich sie erst nach System started online nehmen.
          openHAB 4.2

          Kommentar


            #6
            Zitat von Tokamak Beitrag anzeigen
            Solche Initialisierungs-Routinen habe ich schon. Das nutze ich z.B., um sicherzustellen, dass mit RestoreOnSetup alles geladen wurde.
            Ich gehe mal davon aus, dass Du RestoreOnStartup meinst. Warum glaubst Du, das sicherstellen zu müssen?
            Das mit dem Fenster ist doch nur symbolisch. Ich habe auch andere Proxies.

            Ich weiß um den Unterschied zwischen Contact und Switch. Solange aber HS und OH parallel werkeln, werde ich nichts in der ETS umkonfigurieren, um nicht auch noch laufende HS-Logiken ändern zu müssen, die ich noch nicht ersetzt habe - allen voran der QuadClient.
            Um ein Bit in openHAB zu nutzen, musst Du auf knx-Seite gar nichts ändern. Ein Bit ist ein Bit.
            Bisher sind die Items immer initialisiert worden, bevor System started war, auch, wenn das so nicht festgelegt ist. Erst nach System started sind die Rules scharf.
            System started (wie oben erwähnt) ist der Trigger, der zum Zeitpunkt, zu dem die Rules eingelesen worden sind auslöst.
            Leider gibt es keine Möglichkeit, wie im HS eine Read-Request abzusetzen. Mit schärferen Waffen geht es allerdings doch.
            Da openHAB beim Start alle als lesbar definierten GA ausliest, sollte keine Notwendigkeit bestehen, weitere Read Requests zu senden.
            Allerdings kann man mit dem knx2 Binding sehr wohl auch (zyklisch) Read Requests senden - für den Fall, dass man knx Devices einsetzt, welche weder zyklisch noch bei Wertänderung senden können, sondern ausschließlich auf Anforderung. Das ging sogar schon mit knx1, war aber nicht gut dokumentiert.

            Kommentar


              #7
              Zitat von udo1toni Beitrag anzeigen
              Ich gehe mal davon aus, dass Du RestoreOnStartup meinst. Warum glaubst Du, das sicherstellen zu müssen?
              Um zu unterscheiden, on ein Item mit Strategie everyChange+restoreOnStartup und Wert NULL nach dem Systemstart deswegen NULL ist, weil es noch nie gesetzt und daher nie gespeichert wurde, oder NULL, weil es noch nicht geladen wurde, setze ich mir ein Flag, wenn ich relativ sicher bin, dass das Laden abgeschlossen ist.

              Um ein Bit in openHAB zu nutzen, musst Du auf knx-Seite gar nichts ändern. Ein Bit ist ein Bit.
              Ein 0 ist bei einem SwitchItem ein OFF, bei einem ContactItem ein CLOSED. Meine Reed-Sensoren senden 1, wenn das Fenster geschlossen ist. Das wäre bei einem Contact ein OPEN. Daher nutze ich lieber ein SwitchItem.

              Da openHAB beim Start alle als lesbar definierten GA ausliest, sollte keine Notwendigkeit bestehen, weitere Read Requests zu senden.
              Will ich auch gar nicht, wenn denn die eingelesenen GAs Rules triggern würden. Das tun sie aber erst nach System started, und daher will ich das einmalige Einlesen auf die Zeit nach dem System started verschieben. Danach kann ich mit dem normalen KNX-Busverkehr arbeiten, ohne weitere Read-Reqeusts abzusetzen.
              Mit dem Trick, mit dem Enablen der KNX-Bridge das Einlesen der KNX-Things zu triggern, erreiche ich das nun. Schöner wäre es, wenn ich konfigurieren könnte, dass die Things erst nach dem Systemstart initialisiert werden sollen.

              Das habe ich im übrigen auch beim HS so gemacht. Das Flag "Beim Start abfragen" habe ich nicht gesetzt, weil das Einlesen parallel zur Intialisierung der Logiken erfolgte und so zu unverhersagbaren Seiteneffekten geführt hatte.
              Daher habe ich nach dem Systemstart mit mehreren Sequenzen alle GAs eingelesen, die mich interessiert haben. So war ich sicher, (fast) alles mitzubekommen, was sich während der Downtime getan hat, und damit die gleichen Logiken auszulösen, die auch während der Laufzeit abgearbeitet worden wären.
              Das hat meine Implementierung in der Startphase viel berechenbarer gemacht.


              openHAB 4.2

              Kommentar


                #8
                Zitat von Tokamak Beitrag anzeigen
                Will ich auch gar nicht, wenn denn die eingelesenen GAs Rules triggern würden. Das tun sie aber erst nach System started,
                Der Punkt ist, dass die Rules zu dem Zeitpunkt noch nicht geladen sind. Ergo weiß openHAB nichts von Triggern, die stehen ja in den Rules.
                Aber so langsam verstehe ich Dein Problem

                Der Workaround, die Bridge kurz OFFLINE zu schalten ist auf jeden Fall nett, auch wenn Du Dir zu Recht wünschst, dass openHAB das von sich aus steuerbar machen sollte.

                Kommentar

                Lädt...
                X