Seite 1 von 2

Openhab und Prozedur? [gelöst]

Verfasst: 12. Feb 2019 06:44
von fkempter
Hallo

wie und wo kann ich die Prozedur erstellen?
Ähnlich so:

Code: Alles auswählen

rule "Check IoT Online"
when
    Time cron "* 0 * * * ?" or
    Item groupWindows changed or
    Item ggroupDoors changed 
then
	call AufrufProz(itemWindow01)
	call AufrufProz(itemWindow02)
	call AufrufProz(itemWindow03)
	..
end


//----- Beispiel Prozedur ------
AufrufProz(procItem) {
	if procItem.state == NULL {
	  procItem.postUpdate("OFFLINE")
	  ..
    }
}


Re: Openhab und Prozedur?

Verfasst: 12. Feb 2019 09:21
von mamoel
Soweit ich weiß geht das nur über "Lambdas".

Schau mal hier oder hier.

Re: Openhab und Prozedur?

Verfasst: 12. Feb 2019 09:36
von peter-pan

Re: Openhab und Prozedur?

Verfasst: 12. Feb 2019 10:06
von seppy
Hi,
ich glaube peter-pan's Lösung passt, aber Du hast die nervige Einschränkung, dass an Scripte keine Parameter übergeben werden können. Das müsstest Du über Proxy Items lösen.
Die Lambda Funktionen können unter Umständen auch helfen. Was ist denn Dein Ziel?

Grüße,
Seppy

Re: Openhab und Prozedur?

Verfasst: 12. Feb 2019 11:40
von peter-pan
..eine weitere Möglichkeit wäre z.B. vielleicht noch executeCommandline () oder das exec-Binding.

Code: Alles auswählen

var String result = executeCommandLine("/etc/openhab2/test.sh", 60000)
Ausserdem könntest du noch in den Transformations schauen, da gibt es auch noch Möglichkeiten.
transform.jpg

Re: Openhab und Prozedur?

Verfasst: 12. Feb 2019 12:45
von mamoel
Ich denke mal dem Threadersteller ging es eher darum, duplizierten Code innerhalb der rules zu vermeiden. Es kommt ja bei komplexeren Installationen häufig vor, dass man in seinen Regeln gewisse Teilaufgaben gerne in separate Methoden/Funktionen auslagern möchte, da man sie dann an mehreren Stellen wiederverwenden kann.
Bei ioBroker mit JavaScript war das ganz normal. In den typischen openHAB-rules habe ich das bisher nicht gesehen.

Re: Openhab und Prozedur?

Verfasst: 12. Feb 2019 15:56
von udo1toni
Im konkreten Fall wäre es das einfachste, die Gruppe zu verwenden. Aber es fehlen noch ein paar Randinformationen. Nehmen wir mal an, wir haben folgende Items:

Code: Alles auswählen

Group gWindows
String Window1 (gWindows)
String Window2 (gWindows)
String Window3 (gWindows)
Die Rule soll regelmäßig kontrollieren, ob der Status NULL ist und entsprechend reagieren:

Code: Alles auswählen

rule "check gWindows"
when
    Member of gWindows changed
then
    if(triggeringItem.state == NULL) triggeringItem.postUpdate("OFFLINE")
end
Fertig! Egal, welches Item WindowN seinen Status auf NULL ändert, es wird exakt dieses Item auf OFFLINE gesetzt.
Nun soll die Rule zusätzlich auf Zeit triggern. Damit steht dann kein triggeringItem zur Verfügung:

Code: Alles auswählen

rule "check gWindows"
when
    Time cron "0 0 * * * ?" // zur vollen Stunde
    Member of gWindows changed
then
    if(triggeringItem !== null)
        if(triggeringItem.state == NULL) triggeringItem.postUpdate("OFFLINE")
    else
        gWindows.members.forEach[m|
            if(m.state == NULL) m.postUpdate("OFFLINE")
        ]
end
Fertig! Nun unterscheidet die Rule zwischen den zwei Triggern und setzt entweder konkret genau das Item, welches getriggert hat (unter der Voraussetzung, dass es NULL ist), oder, falls die Rule auf Zeit getriggert hat, durchläuft es die gesamte Gruppe und schaut sich jedes einzelne Item an.
da braucht es keine Prozeduren und keine Lambdas!
Da noch eine weitere Group als Trigger vorgesehen ist, könnte es theoretisch notwendig sein, noch eine weitere Unterscheidung zu treffen. Je nach Gruppenbeschaffenheit könnte man z.B. so:

Code: Alles auswählen

if(gWindows.members.filter[m|m.name == triggeringItem.name].size == 0)
prüfen, ob das TriggeringItem aus der ersten oder der zweiten Gruppe stammt.

Es mag Fälle geben, wo ein Lambda als Funktionsersatz tatsächlich die bessere Wahl ist, aber die Gruppen und die zugehörigen Funktionen sind extrem mächtig, der Code ist im Zweifel sehr schlank und (wenn man ein wenig über die Worte nachdenkt) sogar leicht verständlich.

Re: Openhab und Prozedur?

Verfasst: 12. Feb 2019 18:00
von fkempter
mamoel hat geschrieben: 12. Feb 2019 12:45 Ich denke mal dem Threadersteller ging es eher darum, duplizierten Code innerhalb der rules zu vermeiden. Es kommt ja bei komplexeren Installationen häufig vor, dass man in seinen Regeln gewisse Teilaufgaben gerne in separate Methoden/Funktionen auslagern möchte, da man sie dann an mehreren Stellen wiederverwenden kann.
Bei ioBroker mit JavaScript war das ganz normal. In den typischen openHAB-rules habe ich das bisher nicht gesehen.
Ganz genau die Prozedur checkt einige Dinge und der Code wird dann releativ lang, aber für jedes Item wäre es derselbe Code.
Über einer Prozedur wird es wesnetlich übersichtlicher und auch Wartungsfreundlicher.
SG Franz

Re: Openhab und Prozedur?

Verfasst: 12. Feb 2019 18:06
von fkempter
udo1toni hat geschrieben: 12. Feb 2019 15:56 Im konkreten Fall wäre es das einfachste, die Gruppe zu verwenden. Aber es fehlen noch ein paar Randinformationen. Nehmen wir mal an, wir haben folgende Items:
Group gWindows
String Window1 (gWindows)
String Window2 (gWindows)
.....
Hi Udo,

Die Schleife

Code: Alles auswählen

        gWindows.members.forEach[m|
            if(m.state == NULL) m.postUpdate("OFFLINE")
        ]
schaut viel versprechend aus.
In die Schleife kann ich dann meinen ganzen überigen Code platzieren.
Ich werde es austesten und geb hier dan Bescheid.
SG Franz

Re: Openhab und Prozedur?

Verfasst: 13. Feb 2019 06:20
von fkempter
Gut zu wissen das mit der Schleife. Vielen Dank!
Diese Funktion kann ich noch öfters verwenden.

Nun habe ich noch ein Problem. Ich möchte das Icon unabhängig vom .state Inhalt ändern
IoT-Status.jpg
Die folgende Rule prüft ob ein IoT Device gerade Online,Invisible(Sleepmodus) bzw Offline=>3Tage nicht mehr aktiv
Die IoT String-Items habe mehrere Informationen mit Pipe getrennt: "O_5.1|85 |AlarmMelder03||2019-02-13T05:50:12Z"
CharNum 1 = I=Online; O=Offline
Ich habe hier im Code als Dummyfunktion(funktioniert natürlich nicht) derweil m.ChangeIcoto verwendet.
Gibt es so eine ähnliche Funktion?

Code: Alles auswählen

rule "Check IoT Online"
when
	Time cron "* 0 * * ?" or //jeden Stunde
    	Member of gIoT_Status changed 
then
        gIoT_Status.members.forEach[m| {
  		    logInfo("--fk check state: ", m.state.toString)
            var String tmp_State =   m.state.toString
            if (tmp_State == NULL || tmp_State.length() < 25 ) {    //prüfe ob ein State überhaupt vorhanden
                m.ChangeIconto("OFFLINE")
            } else {                                                //wenn State vorhanden prüfe den String
                var String DateIot = tmp_State.substring(tmp_State.length()-20,tmp_State.length()) 
                if (tmp_State.substring(0,1) == "I") m.ChangeIconto("ONLINE")
                else if (DateIot < now.minusDays(3).toString) m.ChangeIconto("OFFLINE")
                     else m.ChangeIconto("INVISIBLE")
                
            } 
		} ]
end