Ja aber nein

Das ist ja der Punkt... Du misst hinter der Entnahme durch die Powerstation. entsprechend wäre es besser so:
Einfach:
gemessene Leistung negativ (Maximum z.B. -100 W) -> nächsthöhere Ladestufe
gemessene Leistung positiv (Minimum + 1 W) -> nächstniedrigere Ladestufe
Dabei muss das (negative) Maximum so gewählt werden, dass der Sprung auf die nächsthöhere Ladestufe keinesfalls zu einem Überschreiten des Minimums von + 1 W führt.
aufwändiger:
Du weißt, wie viel Leistung Powerstation exakt entnimmt, wenn sie auf Ladestufe 1, 2 bzw. 3 lädt.
Weiterhin kennst Du den Ladestand. Es gibt nämlich vermutlich auch für die Leistungsaufnahme in den Stufen eine Abhängigkeit vom Ladestand, oder die höheren Ladestufen werden ab einem bestimmten Ladestand ignoriert. das wäre auf jeden Fall noch zu klären.
Entsprechend errechnest Du anhand der gemessenen Leistung unter Berücksichtigung der aktuellen Entnahme, ob Du die Stufe wechseln musst, und wenn ja, auf welche Stufe du wechseln musst.
Falls Du die aktuelle Leistungsaufnahme aus der Powerstation auslesen kannst, wäre das die elegante Lösung:
Code: Alles auswählen
var Timer tPowerstation = null
rule "Powerstation Ladestufe"
when
Item Verbrauch changed or
Item Ladeleistung changed
then
if(tPowerstation !== null) // Timer läuft bereits
return;
var Number nVerbrauch = 0.0
if(Verbrauch.state instanceof Number)
nVerbrauch = (Verbrauch.state as Number).floatValue // negativ -> Überschuss
var Number nLadeleistung = 0.0
if(Ladeleistung.state instanceof Number)
nLadeleistung = (Ladeleistung.state as Number).floatValue // positiv -> bereits bezogener Überschuss
val Number nExcess = nVerbrauch - nLadeleistung
val Integer iSoll = transform("SCALE","ladestufe.scale",nExcess)
if(LadestufeIst.state.toString != iSoll.toString) {
LadestufeIst.sendCommand(iSoll)
tPowerstation = createTimer(now.plusMinutes(1),[
tPowerstation = null
])
}
end
Und dazu passend die Datei
ladestufe.scale:
Also die zur Verfügung stehende Leistung ergibt sich aus dem gemessenen Überschuss plus der aktuell entnommenen Leistung. Und über die SCALE Transformation wird dann die Stufe 0 bis 3 gewählt.
Natürlich wird die Ladestufe nur bei Bedarf umgeschaltet und entsprechend die Totzeit (über den Timer) ebenfalls nur bei einer Änderung der Ladestufe gestartet. Die Abfrage des Zustands über den String vermeidet den Aufwand mit instanceof Number, hier geht es ja nur um "gleich oder nicht", das geht gut über den String.
Eine Mittelung des aktuellen Überschusses ist sicher auch machbar, dann musst Du allerdings die Persistence befragen (elegante Lösung) oder die Messwerte ständig selbst mitteln (igitt), also ungefähr so:
Code: Alles auswählen
var Number nVerbrauch = 0.0
if(Verbrauch.averageSince(now.minusMinutes(1)) instanceof Number)
nVerbrauch = (Verbrauch.averageSince(now.minusMinutes(1)) as Number).floatValue // negativ -> Überschuss
Das Hauptproblem dabei kann im Zusammenhang mit der verwendeten Persistence selbst auftreten, da muss man halt genau hinschauen... z.B. rrd4j erlaubt maximal einen Messwert pro 10 Sekunden, wenn da mehr rein kommt, wird averageSince vermutlich verfälschte Ergebnisse liefern.
Den Ladezustand musst Du aber so oder so auch berücksichtigen, nicht dass die Powerstätion das nicht selbst machen würde, aber Du willst ja nicht ständig unnötigerweise Befehle senden, die ohnehin nicht befolgt werden, weil die Powerstation schon am Ladeschluss angekommen ist.
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet