Also, das wichtigste hier im Forum wäre, Code, den Du postest, auch als Code zu markieren (ich habe das mal nachgeholt...)
Nun zu Deinem Code:
Gleich der erste Fehler passiert in der allerersten Zeile noch vor der Rule.
Du definierst unnötigerweise eine globale Variable und weist ihr einen Wert zu, den Du aus einem Item gewinnst. Das wird gleich aus mehreren Gründen schief gehen.
Grund eins: die Definition ist statisch, sie wird nur einmalig ausgeführt, und zwar, wenn die Datei geladen wird. Die Variable bekommt dabei den Wert zugewiesen, nicht etwa eine Funktion.
Grund zwei: Beim Laden der Rule ist die Chance bei etwa 95 %, dass der Status des Items NULL ist. NULL ist allerdings kein Bestandteil des Datentyps Number, es wird deshalb eine NullPointer Exception geben.
Und weiter geht es mit Zeile zwei
Dort weist Du der Timer Variablen den Wert
Null zu. Diesen Wert gibt es allerdings nicht. Entweder Du hast ein Item, das kann den Status
NULL annehmen, oder Du hast eine Variable, die kann den Wert
null zugewiesen bekommen.
Der Rest der Rule würde vermutlich funktionieren, aber die Herangehensweise ist unnötig kompliziert. Optimiert und korrigiert sähe die Rule bei mir so aus:
Code: Alles auswählen
var Timer tCharge = null // Timer Variable global definieren
rule "PV Laden"
when
Item PV_Laden_Amp_max changed
then
if(!(newState instanceof Number)) // Falls kein gülter Zahlenwert
return; // breche Rule ab
var Integer iAmpere = (newState as Number).intValue // Verfügbare Ladeleistung in Ampere ermitteln
if(iAmpere >= 6) { // falls iAmpere mindestens 6
tCharge?.cancel // breche Timer ab, falls vorhanden
tCharge = null // setze tCharge auf null
} else if(tCharge === null) // falls iAmpere kleiner 6 UND kein Timer vorhanden
tCharge = createTimer(now.plusMinutes(2), [ | // Erzeuge Abschalttimer
Wallbox_Forcestate.sendCommand(OFF)
tCharge = null
])
if(iAmpere > 16) iAmpere = 16 // falls über 16, setze 16
if(iAmpere < 6) iAmpere = 6 // falls unter 6, setze 6
Wallbox_Max_Amp.sendCommand(iAmpere) // Ladeleistung an Wallbox senden
end
Der Name der Rule kann beliebige Zeichen aus dem UTF-8 Zeichensatz enthalten, also z.B. Leerzeichen oder auch Umlaute.
Er entspricht da einem Label. Naturgemäß darf aber jeder Name nur einmal benutzt werden, in der Hinsicht ist er eher mit einer UID vergleichbar
Der Trigger
changed ist hier vollkommen ausreichend
und mit diesem Trigger kommt eine implizite Variable, welche etwas Tipparbeit spart (
newState enthält den aktuellen Status des Items, welches die Rule mit
changed getriggert hat. Eine weitere implizite Variable wäre
previousState, welche den Status
vor dem
changed Ereignis enthält. Die spielt hier aber keine Rolle, nur der Vollständigkeit halber...)
Der erste Schritt innerhalb des Rule Codes ist, zu prüfen, ob überhaupt eine gültige Zahl im Status vorliegt. Ist das nicht der Fall, bricht die Rule ab, denn sie kann keine qualifizierte Entscheidung treffen.
Falls die Rule nicht abgebrochen wird, wird im nächsten Schritt aus dem aktuellen Status der Ganzzahlwert ermittelt (dieser ist hinreichend für den restlichen Code).
Weiter geht es mit der Steuerung des Timers. Grund für die vertauschte Reihenfolge ist das Einsparen einer Variable
Liegt der Wert bei oder über 6, so kann ein eventuell laufender Timer abgebrochen und die Timer Variable genullt werden.
Liegt der Wert unter 6, so gilt es zu beachten, ob der Timer bereits läuft. Ist das der Fall, so darf der Timer nicht erzeugt werden, sonst werden mehrere Timer erzeugt, von denen nur der zuletzt angelegte Timer noch gestoppt werden kann (weil ja immer wieder die selbe Timer Variable verwendet wird.) Ist noch kein Timer vorhanden, wird er angelegt und gestartet. (Zu beachten: der Timer wird vom Scheduler verwaltet und hat nichts mit der Rule zu tun)
Zum Abschluss wird der ermittelte Wert mit Ober- und Untergrenze abgeglichen (wie gesagt, das muss nach dem Vergleich für den Timer geschehen, weil sonst die Untergrenze den Vergleich vermasselt...)
Der Wert, der nun sicher ein Integer Wert zwischen 6 und 16 ist, wird an die Wallbox gesendet. Fertig...
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet