Ankündigung

Einklappen
Keine Ankündigung bisher.

Komplexere Rules?

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

    Komplexere Rules?

    Hallo alle,

    nachdem ich nun etwas Erfahrung mit einfacheren Regeln habe, würde ich gerne auch komplexere schreiben.

    Konkret geht es mir darum, je nach PV-Produktion verschiedene Verbraucher zu- oder abzuschalten, wobei jeder Verbraucher aber selber auch noch ein eigenes komplexes Regelwerk hat.

    Beispiel: "lasse die Lüftung normal auf 2 laufen. Stelle sie auf 3, wenn genug Strom da ist. So lange, wie sie tags auf 3 gelaufen ist, soll sie danach nachts auf 1 laufen. Wenn es draußen sehr heiß ist, lasse die Lüftung tagsüber nicht laufen, dafür aber nachts auf 3, wenn es abgekühlt hat."

    Auf diese Weise würde ich gerne verschiedene Verbraucher einbinden und nach Priorität ordnen.

    Müsste ich das zB in Java schreiben, würde ich mir verschiedene Klassen und Methoden basteln, um das ganze Gerüst halbwegs konfigurier- und wartbar zu halten. Wenn ich es aber richtig verstanden habe, darf ich in Rules weder Klassen noch Methoden anlegen, oder? Gibt es andere Möglichkeiten, wie ich den Code übersichtlich halten kann, oder müsste ich alles in eine große Regel schreiben?

    Viele Grüße,

    Marcus.

    #2
    Hallo Marcus,

    die Rules sind meiner Meinung nach kein Glanzpunkt von openHAB. Da Skripte für komplexere Regeln auch nicht taugen, bleibt Dir nur noch die Möglichkeit, Lambda-Expressions zu verwenden, um den Code zu strukturieren. Schaut man sich die Definition einer solchen Lambda-Expression an, wird aber auch schnell klar, dass es sich hier eher um einen Workaround handelt.

    Und um noch ein bisschen weiter auszuholen: Xtext ist in meinen Augen das falsche Mittel für Rules. Im Eclipse-Universum bekommt man mit Xtext zwar sehr schnell eine DSL mitsamt Editor und sonstigem Schnick-Schnack zusammen, aber für die konkrete Aufgabenstellung "Rules" ist man auch sehr schnell an den Grenzen.

    In openHAB 2 soll das wohl besser werden: https://www.eclipse.org/forums/index.php/t/860533/

    Gruß,
    Martin

    Kommentar


      #3
      Gerade das genannte Beispiel wird wohl nicht ohne weiteres über eine wie auch immer geartete UI abzuhandeln sein. Im zitierten Thread werden ja auzch ganz klar Grenzen des Ansatzes erläutert.

      Ich als kompletter Autodidakt (Baujahr 1970, ja, der Commodore C64) muss sagen, ja, die Lernkurve mit Xtext ist steil, zumal es keine vernünftige Dokumentation gibt (damit meine ich eine Dokumentation, die auch auf die Besonderheiten mit openHAB eingeht und gleichzeitig einen kompletten Überblick über Xtext gibt).
      Trotzdem habe ich bei mir schon einiges an Rules rumliegen, die über ein einfaches "wenn das dann dies" hinausgehen.
      Es kommt natürlich darauf an, was alles an Templates auftauchen wird, aber vermutlich wird wieder viel selbst entwickeln angesagt sein, um spezielle Probleme zu lösen - die dann auch nicht ohne weiteres von anderen wieder verwendet werden können. Und da will ich eine Programmiersprache zur Verfügung haben, bei der ich mit möglichst wenig Texteingaben möglichst viel erreichen kann.

      Bei Xtext nervt mich das ständige Typecasting, zumal ich keinen blassen Schimmer habe, was ich da tue, aber die Lösung kann auch nicht sein, 1087 Zeichen für ein
      Code:
      wenn Corridor_MotionDetector ON und Corridor_Brightness < 30 dann Corridor_Light ON
      zu benötigen. Immerhin, wenn das Template schon existiert, wird es etwas weniger, nämlich 339 Zeichen. Interessant ist das aber nur, weil sich die Eingabe der Zeichen auf Klicken in der UI reduziert. Wenn ich das von Hand tippen muss, verfluche ich denjenigen, der sich so etwas ausgedacht hat.

      Mein Wunsch ist eine objektorientierte Sprache für die eigentlichen Module, die Schnittstelle zum System kann dann gerne so gestaltet sein, dass ich das von mir programmierte Modul über die UI mit In-Out versehen kann.

      Als Beispiel möchte ich (nur um mal über den Tellerrand zu schauen) den HS nennen. Leider ist da das Programmieren eines Moduls total krank, raus kommt aber ein Block, den man im grafischen Editor einfach an die gewünschte Stelle schiebt, Ein- und Ausgänge mit den gewünschten Punkten verbindet und gut ist.

      Kommentar


        #4
        Ich hab mir auch schon gedanken gemacht:

        Theoretisch könnte man ein phyton skript, c++ programm oder sonstiges Aufrufen übergibt Parameter z.B executeCommandLine("maechtigesCProgramm arg1 arg2"). Den String kannst du ja in den Rules selber zusammenbauen. Rückgabewert musste leider per RestAPI setzen und den String dann entsprechend verarbeiten.


        Kommentar


          #5
          Hallo!

          Herzlichen Dank für Eure Kommentare! Wenn sie auch keine konkrete Lösung aufzeigen, so haben sie mir doch sehr geholfen insofern, dass ich jetzt weiß, dass ich nichts wesentliches übersehen / falsch verstanden habe. Dann schau ich jetzt mal, wie ich weiterkomme - vielleicht bau ich mir komplexere Items in Java, oder ich bau mir eine JavaScript-Anbindung. Python wäre sicher auch eine Alternative, aber da ich Python selber im Moment leider noch nicht kann, würden mir da Ergebnisse zu lange dauern.

          udo1toni, tja - 1970 und C64. Eine Kombination, die mir durchaus bekannt ist! :-)

          Marcus.

          Kommentar


            #6
            Hallo nochmal,

            hab jetzt ein bisschen experimentiert, und der JavaScript-Ansatz scheint eine recht einfach einzubindende Variante zu sein.

            Beispiel folgende Rule:

            import javax.script.*
            var Invocable engine=null

            rule "SkriptTest"
            when
            Time cron "0/5 * * * * ?"
            then
            if (engine==null) {
            engine=new ScriptEngineManager().getEngineByName("JavaScript" ) as Invocable
            val java.io.File skript=new java.io.File("configurations/rules/test.js")
            (engine as ScriptEngine).eval(new java.io.FileReader(skript))
            var version=engine.invokeFunction("version")
            logInfo("Test.rule","JavaScript geladen: {}",version)
            }
            var ping=engine.invokeFunction("ping")
            logInfo("Test.rule","Ping: {}",ping)
            end

            ... zusammen mit folgendem JavaScript in test.js:


            var zaehler=0;

            function version() {
            return "Rule-JavaScript 0.1";
            }

            function ping() {
            zaehler++;
            return zaehler;
            }


            ... beweist, dass es grundsätzlich funktioniert, und dass auch Zustand zwischen zwei Regel-Aufrufen erhalten bleibt. Damit sind ja quasi alle Grundvoraussetzungen erfüllt!

            Marcus.

            Kommentar


              #7
              ... und da xtend mehrzeilige String-Literale ohne großen Aufwand akzeptiert, kann man sogar das Skript auch gleich in der Rule ablegen:

              val String skript='
              var zaehler=0;

              function version() {
              return "Rule-JavaScript 0.1";
              }

              function ping() {
              zaehler++;
              return zaehler;
              }
              '

              So kann ich nun also doch Funktionen und Klassen direkt in Rule-Files definieren :-)

              Kommentar

              Lädt...
              X