Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

SmartHomer
Beiträge: 51
Registriert: 17. Mai 2018 09:26
Answers: 0

Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Beitrag von SmartHomer »

Hallo,

ich habe folgendes Problem. Ich möchte gerne Variablen welche ich in der .rules Datei deklariere an Items übergeben, um den Wert der Variablen in der Sitemap anzuzeigen. Wie muss ich hierfür vorgehen?

Vielen Dank!

hr3
Beiträge: 210
Registriert: 23. Mai 2017 21:41
Answers: 0

Re: Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Beitrag von hr3 »

sendCommand bzw. postUpdate
Aber sag doch etwas konkreter, welcher Daten-Typ in der Variablen gespeichert werden soll und wie du das Item definiert hast.
Was hast du schon und was funktioniert/nicht?

SmartHomer
Beiträge: 51
Registriert: 17. Mai 2018 09:26
Answers: 0

Re: Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Beitrag von SmartHomer »

Ich möchte gerne eine Variable definieren zur Berechnung für die Prognose der elektrischen Leistung einer Photovoltaik Anlage. Diese Variable habe ich in der .rules Datei folgendermaßen definiert:

var Number Prognose_PV_Leistung = Strahlungsintensitaet_Sonne*Gesamtflaeche_PV_Module*Wirkungsgrad_PV_Anlage*cos_thetta*(1-Bewoelkungsgrad)

Ebenfalls habe ich die Variablen zur Berechnung für die Variable Prognose_PV_Leistung definiert:

var Number Strahlungsintensitaet_Sonne = 1000 // [W/m²]
var Number Gesamtflaeche_PV_Module = 20 // [m²]
var Number Wirkungsgrad_PV_Anlage = 0.15 // [%]
var Number cos_thetta = 0.93 // [dimensionslos]
var Number Bewoelkungsgrad = 0.75 // [%]

Nun möchte ich den Wert der Variablen vom Type Number Prognose_PV_Leistung in der Sitemap anzeigen lassen. Ich weiß nicht wie ich die rule definieren muss mit dem sendCommand bzw. postUpdate damit ich den Variablen Wert an ein Item übergeben um dieses Item dann in der Sitemap anzuzeigen.

hr3
Beiträge: 210
Registriert: 23. Mai 2017 21:41
Answers: 0

Re: Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Beitrag von hr3 »

Im Moment sind alle Werte für die Formel Konstanten. Ich denke das ist für den ersten Test und denn werden Strahlungsintensitaet_Sonne und/oder Bewoelkungsgrad variabel. Deswegen auch erst einmal als "when System started", ist dann durch einen anderen Trigger zu ersetzen. https://docs.openhab.org/configuration/rules-dsl.html

Code: Alles auswählen

val Breitengrad = 0.85 // [Gradmaß]
val Azimutabweichung = 0.79 // [Bogenmaß]
val Gesamtflaeche_PV_Module = 20 // [m²]
val Wirkungsgrad_PV_Anlage = 0.15 // [%]
val Strahlungsintensitaet_Sonne = 1000 // [W/m²]
val Bewoelkungsgrad = 0.75 // [%]
val cos_thetta = 0.93 // [dimensionslos]

rule "System started"
when
  System started
then
  var Number Prognose_PV_Leistung = Strahlungsintensitaet_Sonne*Gesamtflaeche_PV_Module*Wirkungsgrad_PV_Anlage*cos_thetta*(1-Bewoelkungsgrad)
//logInfo("Prognose_PV_Leistung",Prognose_PV_Leistung.toString)
  numItem.postUpdate(Prognose_PV_Leistung)
end

SmartHomer
Beiträge: 51
Registriert: 17. Mai 2018 09:26
Answers: 0

Re: Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Beitrag von SmartHomer »

Wenn ich den Code so übernehme zeigt er mir im Smart Home Designer die Fehlermeldung zu numItem "The method or field numItem is undefined"

Wo muss ich diese definieren. Ich möchte sozusagen die Variable Prognose_PV_Leistung an eine Art dummy Item ausgeben.

Was ist der Unterschied zwischen var und val?

Was ist die Funktion dieser Zeile: logInfo("Prognose_PV_Leistung",Prognose_PV_Leistung.toString)?

Sorry ich bin noch relativ unvertraut in diesem Themengebiet.

hr3
Beiträge: 210
Registriert: 23. Mai 2017 21:41
Answers: 0

Re: Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Beitrag von hr3 »

Sag doch bitte gleich, dass du ganz am Anfang stehst mit deinem Kenntnisstand.
Ich mag es nicht, wenn ich mit einer konkreten Frage geködert werde und mich dann zurück zu Adam und Eva hangeln darf.
Deswegen, hier mein letzter Hinweise und der Tipp, erst einmal viel viel lesen.
var/val https://docs.openhab.org/configuration/rules-dsl.html
loginfo https://docs.openhab.org/administration/logging.html

x.items

Code: Alles auswählen

Number numItem "numItem[%s]"
x.sitemap

Code: Alles auswählen

sitemap tmp label="tmp" {
	Frame{
		Default item=numItem
	}
}

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

Re: Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Beitrag von udo1toni »

Ich springe hier mal bei, um ein wenig Licht ins Dunkel zu bringen. :)

Die UI von openHAB ist dazu gedacht, Items bzw. deren Status anzuzeigen und/oder zu manipulieren (also Schalter AN/AUS).
Deshalb kann openHAB bis auf wenige Ausnahmen auch nichts anderes in eine UI einbetten.
Die Ausnahmen sind Webview, Mapview, Image, Video und Chart, wobei auch diese Elemente ihre Steuerinformationenen gewöhnlich aus Items beziehen.

Du musst also zwingend ein Item verwenden, wenn Du irgendeinen Zahlenwert oder gesteuerten Text anzeigen lassen möchtest.
Glücklicherweise muss man bei der Definition eines Items kein Binding oder auch Channels angeben. Es reicht also ein ungebundenes Item vom passenden Typ, um den errechneten Wert anzuzeigen.

var/val: var steht für Variable, also ein Platzhalter, dessen konkreter Wert (das, was darin gespeichert ist) variabel, also veränderbar ist. Der Gegensatz dazu ist val, das steht für Value, also ein Wert. Dieser Wert ist aber zur Laufzeit nicht änderbar, einmal festgelegt, bleibt er so, wie er ist, er ist also konstant.

Code: Alles auswählen

var int iMyInterger = 5
val int cMyInteger = 5

rule "Testrule"
    when
        Time cron "0 0 18 * * ?"  // einmal täglich 18 Uhr
    then
        iMyInteger = iMyInteger + 1  // klappt, da variabel
        cMyInteger = cMyInteger + 1  // Fehler, da konstant
end
Gemein wird es dann, wenn ich innerhalb einer Rule ein val einsetze. Auch hier darf der Wert nicht mehr verändert werden. Wenn die Rule aber beendet wird, wird auch die Konstante wieder aus dem Speicher entfernt. Beim nächsten Aufruf der Rule darf der Konstanten also erneut einmalig ein Wert zugewiesen werden. Der Unterschied besteht vor allem darin, wie der Speicher für Variablen und Konstanten verwaltet wird.

Code: Alles auswählen

logInfo("Prognose_PV_Leistung",Prognose_PV_Leistung.toString)
logInfo() ist eine Action, die im Logging einen Eintrag der Stufe INFO erzeugt. Es gibt auch logDebug(), logError() und logWarn().
Der Witz einer solchen Zeile, und warum es dafür vier verschiedene Actions gibt, ist, dass man das Logging während der Laufzeit von openHAB steuern kann, und zwar extrem kleinteilig. Der erste Parameter von logInfo() ist der Loggername (genauer der letzte Teil des Loggernamens). Wenn man das Logging für diesen Loggernamen auf WARN setzt, wird logInfo() keine Ausgabe mehr erzeugen, logWarn() aber weiterhin. Wenn man das Logging auf DEBUG setzt, werden zusätzlich auch logDebug() Anweisungen eine Ausgabe erzeugen.
Es ist also sinnvoll, solche logInfo() Actions überall da einzusetzen, wo man gerne recht genaue Informationen haben möchte, was gerade in der Rule abgeht. Wenn die Verarbeitung der Rule ungewöhnliche Randbedingungen vorfindet, bietet sich ein logWarn() an, wenn ein krasser Fehler auftritt, ein logError(). Wenn man eine sehr umfangreiche Rule schreibt, kann es auch sinnvoll sein, an weiteren Stellen z.B. Zwischenergebnisse mit logDebug() ausgeben zu lassen. Man lässt dann das Logging auf INFO oder auf WARN, nur wenn es Probleme gibt, dreht man das Logging auf und bekommt dann zusätzliche Informationen.
Das Logging von Karaf (das ist die von openHAB eingesetzte OSGI-Schicht) ist extrem mächtig, man kann z.B. auch bestimmte Logs in separate Dateien laufen lassen, default landet alles erstmal in openhab.log, bis auf Events, die landen in events.log

Der zweite Parameter ist die eigentliche Information, die geloggt werden soll. Die zitierte Zeile ist nicht so ganz korrekt, denn der Loggername wird hier für Klartext missbraucht. Da dieser Klartext auch noch recht lang ist, wird die automatische Formatierung des log Files hier zerstörerisch wirken. Korrekt sähe das eher so aus:

Code: Alles auswählen

logInfo("pvCalc","Prognose_PV_Leistung: {} Wh",Prognose_PV_Leistung)
Diese Zeile bewirkt eine Logzeile in dieser Form:

Code: Alles auswählen

2018-05-17 16:28:39.482 [INFO] [.e.model.script.pvCalc] Prognose_PV_Leistung: 45321.12345 Wh
Für erste Schritte mit openHAB2 empfehle ich dringend, openHAB2 frisch zu installieren und dann die Demo auszuwählen. Dabei wird automatisch eine Konfiguration eingespielt, die zum einen einige Dinge zeigt, die so möglich sind, zum anderen kann man sich die Konfigurationsdateien prima anschauen und so verstehen, die openHAB tickt. Ich nutze openHAB seit Version 1.0 und habe es exakt so gemacht. Ich habe erst nach praktisch kompletter Inbetriebnahme erste Fragen gehabt, z.B. weil ich einen Zeitstempel aus der Persistence auslesen wollte (was bisher zumindest mit erheblichem Aufwand verbunden war), aber für die Grundfunktionen musste ich nicht mal groß im Wiki stöbern, das ergab sich alles praktisch von selbst aus der Demo.

Weiterhin möchte ich empfehlen, für ein Produktivsystem eine zweite openHAB Instanz separat einzurichten. Dabei kann man im Hinterkopf behalten, dass openHAB hervorragend auf kleinen Systemen läuft. Es reicht also z.B. auch eine kleine virtuelle Maschine, auf der dann freilich z.B. Debian werkeln muss - extra ein Windows dafür hochzuziehen ist albern ;) Falls Du aber noch eine ältere Gurke dastehen hast, die eh nur zustaubt, kann auch auf dieser eine Instanz laufen. Auf dem einen System kannst Du dann nach Herzenslust testen, auf dem anderen läuft das, was bisher für gut befunden wurde.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

SmartHomer
Beiträge: 51
Registriert: 17. Mai 2018 09:26
Answers: 0

Re: Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Beitrag von SmartHomer »

Super Vielen Dank für die Infos. Hat mir sehr geholfen.
Ich habe noch eine weitere Frage, wie kann ich ein Item aus einer .items Datei in einer .rules Datei aufrufen. Zum besseren Verständnis ein konkretes Beispiel: Ich möchte den Wert des Bewölkungsgrads welchen ich über openweathermap abfrage an die Variable "Bewoelkungsgrad" vom Typ Number in die .rules Datei übergeben. Was für eine Möglichkeit gibt es hier?

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

Re: Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Beitrag von udo1toni »

Gegeben ist ein Item:

Code: Alles auswählen

Number nBewoelkung "Bewölkungsgrad [%s]" {...}
In einer Rule ausgelesen:

Code: Alles auswählen

rule "Bewölkung geändert"
    when
        Item nBewoelkung changed
    then
        var Number Bewoelkung
        if (nBewoelkung.state instanceof Number) {
            Bewoelkung = (nBewoelkung.state as Number)
            logInfo ("wolken","Bewölkungsgrad: {}",Bewoelkung)
        }
end
Eine Variable innerhalb einer Rule lohnt sich aber nur, wenn man Berechnungen darin speichert, die man im weiteren Verlauf der Rule weiter verwendet oder auch verändert, um später irgendwas mit dem Ergebnis anzufangen. Oft ist es eleganter, direkt den Status des Items zu verwenden:

Code: Alles auswählen

rule "Bewölkung geändert"
    when
        Item nBewoelkung changed
    then
        if (nBewoelkung.state instanceof Number)
            logInfo ("wolken","Bewölkungsgrad: {}",nBewoelkung.state)
end
Man beachte, dass man auf das Type Casting verzichten kann.

Wenn die Variable global definiert ist, gilt Ähnliches. Man muss sich vorher genau überlegen, ob man den konkreten Wert tatsächlich nur innerhalb der Rules benötigt, die sich in dem .rules File befinden, und ob es egal ist, was bei einem Neustart von openHAB mit dem Wert passiert.
In dem Zusammenhang sollte man auch daran denken, dass global definierte Variablen und Konstanten beim Neuladen eines *.rules Files ebenfalls neu initialisiert werden. Es reicht schon ein touch auf Dateiebene, um das auszulösen!
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

SmartHomer
Beiträge: 51
Registriert: 17. Mai 2018 09:26
Answers: 0

Re: Variablen in Datei .rules an Items übergeben und in der sitemap anzeigen

Beitrag von SmartHomer »

Ok ich habe es nur teilweise verstanden.

Ich möchte mit folgender Formel die aktuelle Photovoltaik Leistung berechnen:

Prognose_PV_Leistung = Strahlungsintensitaet_Sonne*Gesamtflaeche_PV_Module*Wirkungsgrad_PV_Anlage*cos_thetta*(1-Bewoelkungsgrad)

Dabei unterscheide ich zwischen Konstanten und Variablen.

Konstanten:
  • Gesamtflaeche_PV_Module
  • Wirkungsgrad_PV_Anlage
Variablen:
  • Strahlungsintensitaet_Sonne
  • cos_thetta
  • Bewoelkungsgrad
Die Konstanten habe ich in der .rules Datei außerhalb der Regeln definiert:

Code: Alles auswählen

val Number Gesamtflaeche_PV_Module = 20				// [m²]
val Number Wirkungsgrad_PV_Anlage = 0.15			// [%]
Die Variablen habe ich auch in der .rules Datei außerhalb der Regeln definiert:

Code: Alles auswählen

var Number Strahlungsintensitaet_Sonne	 		// [W/m²]
var Number Bewoelkungsgrad						//  = 0.75 [%]
val Number cos_thetta = 0.93						// [dimensionslos]
Folgende Regeln habe ich bestimmt:

Code: Alles auswählen

rule "System started"
when
  System started
then
  var Number Prognose_PV_Leistung = Strahlungsintensitaet_Sonne*Gesamtflaeche_PV_Module*Wirkungsgrad_PV_Anlage*cos_thetta*(1-Bewoelkungsgrad)
  logInfo("pvCalc","Prognose_PV_Leistung: {} W",Prognose_PV_Leistung)
  numItem.postUpdate(Prognose_PV_Leistung)
 end

rule "Sonnenstrahlung geändert"
when
	Item Total_Radiation changed
then
	if (Total_Radiation.state instanceof Number) {
		Strahlungsintensitaet_Sonne = {Total_Radiation.state as Number}
	}
	logInfo ("Sonnenstrahlung","Sonnenstrahlung_Lorch: {}",Total_Radiation) 
end

rule "Bewölkung geändert"
when
	Item Bewoelkungsgrad_Lorch changed
then
	if (Bewoelkungsgrad_Lorch.state instanceof Number) {
		Bewoelkungsgrad = {Bewoelkungsgrad_Lorch.state as Number}
	}
	logInfo ("Wolken","Bewölkungsgrad: {}",Bewoelkungsgrad_Lorch) 
end
Die drei Variablen möchte ich aus einer .Items Datei für die Formel verwenden. Wenn sich der Wert beispielsweise Sonnenstrahlung oder Bewölkung ändert der neue Wert berechnet wird und diesen über eine .sitemap Datei anzeigen lassen. Letztendlich will ich den Wert oder Status des Items an die Variable in der .rules Datei übergeben, sodass die aktuelle erzeugte Leistung berechnet wird.

Antworten