Regel für Poolsteuerung

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Antworten
Maxwell
Beiträge: 3
Registriert: 28. Jul 2024 16:39
Answers: 0

Regel für Poolsteuerung

Beitrag von Maxwell »

Hallo Zusammen,

ich bin momentan dabei eine Rule für eine Poolsteuerung zu erstellen. Hier habe ich von einem Github Projekt abgekupfert und die
Rule nach meiner Anlage angepasst.
Problem ist nur das ich laufend folgenden fehler erhalte:

Code: Alles auswählen

Script execution of rule with UID 'Poolsteuerung-2' failed: An error occurred during the script execution: index=2, size=2 in Poolsteuerung
Habe schon alles was mir in den Sinn gekommen wäre versucht;
Es muss am Zweiten Teil der rule liegen ... aber ich komme nicht drauf

Code: Alles auswählen

import org.joda.time.LocalTime

var Number POOL_MODE_AUTO = 0.0
var Number POOL_MODE_MANU = 1.0

//------------------------------------------------------------------------
// Init virtual Items
//------------------------------------------------------------------------
rule "Init virtual Items"
when
	System started
then
	createTimer(now.plusSeconds(180)) [ | // let persistance finish restoring a few seconds
		logDebug("pool.rules", "Rule: Init virtual Items ...")


		if (Setting_Time_Pool_Valve_Start_H.state == NULL) {
			Setting_Time_Pool_Valve_Start_H.postUpdate(11)
		}
		if (Setting_Time_Pool_Valve_Start_M.state == NULL ) {
			Setting_Time_Pool_Valve_Start_M.postUpdate(30)
		}

		if (Setting_Time_Pool_Valve_Stop_H.state == NULL) {
			Setting_Time_Pool_Valve_Stop_H.postUpdate(18)
		}
		if (Setting_Time_Pool_Valve_Stop_M.state == NULL) {
			Setting_Time_Pool_Valve_Stop_M.postUpdate(30)
		}

		if(Pooltemperatur.state == NULL) {
			Pooltemperatur.postUpdate(0)
		}

		if(Switch_Pump.state == NULL) {
			Switch_Pump.sendCommand(OFF)
		}

		if(Pool_Mode.state == NULL) {
			Pool_Mode.sendCommand(POOL_MODE_AUTO)
		}
	]
end

//------------------------------------------------------------------------
// Zeitsteuerung der Poolpumpe
//------------------------------------------------------------------------
rule "Poolpumpe: Zeitsteuerung"
when
		//every Minute
		Time cron "0 * * * * ?" or
		Item Pool_Mode changed
then
		logDebug("pool.rules", "Rule: Poolpumpe Steuern ...")

		if (Pool_Mode.state == POOL_MODE_AUTO) {
			//AUTOMATIC
			logDebug("pool.rules", "     AUTOMATIC")

			var Number sollStundeStart = (Setting_Time_Pool_Valve_Start_H.state as DecimalType).intValue
			var Number sollMinuteStart = (Setting_Time_Pool_Valve_Start_M.state as DecimalType).intValue
			val LocalTime startTime = new LocalTime(sollStundeStart.intValue, sollMinuteStart.intValue)

			var Number sollStundeStop = (Setting_Time_Pool_Valve_Stop_H.state as DecimalType).intValue
			var Number sollMinuteStop = (Setting_Time_Pool_Valve_Stop_M.state as DecimalType).intValue
  		val LocalTime endTime = new LocalTime(sollStundeStop.intValue, sollMinuteStop.intValue)

  		if (now.toLocalTime().isAfter(startTime) && now.toLocalTime().isBefore(endTime)) {

				if (Switch_Pump.state == OFF) {
					logInfo("pool.rules", "Rule: Poolpumpe einschalten ...")
					Switch_Pump.sendCommand(ON);
				}
  		} else	{

				if (Switch_Pump.state == ON) {
					logInfo("pool.rules", "Rule: Poolpumpe & Solar ausschalten ...")
					Switch_Pump.sendCommand(OFF);
				}
			}

		} else if (Pool_Mode.state == POOL_MODE_MANU) {
			logDebug("pool.rules", "     MANUELL")

		}	else {
				logError("pool.rules", "UNDEFINED Pool_Mode: " + Pool_Mode.state )
		}
end

Mit Hilfe der Rule soll es möglich sein einen Zeitbereich für die Laufzeit der Poolpumpe auf der Sitemap zu definieren.

Vielen Dank im Voraus für euere Hilfe

Gruß der Neue :-)

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

Re: Regel für Poolsteuerung

Beitrag von udo1toni »

Herzlich willkommen im openHAB Forum!

Welche Version von openHAB nutzt Du?
Falls Du openHAB ab Version 3.0 benutzt, ist schon der erste Import falsch, da openHAB ab Version 3 ausschließlich JavaTime unterstützt.

Weitere Tipps sind ebenfalls stark abhängig von der Version, die Du nutzt :)
openHAB4.3.2 stable in einem Debian-Container (bookworm) (Proxmox 8.3.3, LXC), mit openHABian eingerichtet

Maxwell
Beiträge: 3
Registriert: 28. Jul 2024 16:39
Answers: 0

Re: Regel für Poolsteuerung

Beitrag von Maxwell »

Hallo,

vielen Dank für deine Antwort. Ich nutze Openhab 3.4.4 !
Welche möglichkeiten habe ich ? Warscheinlich ist der Code wie in der Rule dann so nicht mehr möglich.

ich habe den import auf

import java.time.LocalTime

geändert. Fehler ist noch da aber der erste Punkt sollte schon begradigt sein :-)

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

Re: Regel für Poolsteuerung

Beitrag von udo1toni »

Ich bin mir nicht sicher, ob java.time.LocalTime als Import überhaupt notwendig ist, aber "meine" Herangehensweise wäre ohnehin eine andere.

Zunächst einmal möchte ich Dir raten, ein Update auf OH4.2 durchzuführen, von OH3.4.4 aus sollte das ohne großen Stress vonstatten gehen. Vorteil: openHAB4 bietet bessere Möglichkeiten bezüglich der Zeiteinstellung.

Meine Lösung sähe so aus:

Zwei Items für die Zeit:

Code: Alles auswählen

DateTime poolStart "Startzeit" <time> {stateDescription=""[pattern="%tH:%tM"]}
DateTime poolStopp "Stoppzeit" <time> {stateDescription=""[pattern="%tH:%tM"]}
Sitemap:

Code: Alles auswählen

Input item=poolStart inputHint="time"
Input item=poolStopp inputHint="time"
Die Zeit wird hier einfach über die Tastatur als Zahlenwert eingegeben. Wahlweise könnte man noch ein paar extra Rules bauen, um die Zeit mittels +/- Knöpfen einzugeben.

Mehrere simple Rules:

Code: Alles auswählen

val Integer POOL_MODE_AUTO = 0
val Integer POOL_MODE_MANU = 1

rule "Init virtual Items"
when
    System started
then
    createTimer(now.plusSeconds(30)) [ |
        logDebug("pool", "Init virtual Items ...")
        if(!(poolStart.state instanceof DateTimeType))
            poolStart.postUpdate(new DateTimeType(now.withHour(11).withMinute(30)))
        if(!(poolStopp.state instanceof DateTimeType))
            poolStopp.postUpdate(new DateTimeType(now.withHour(18).withMinute(30)))
        if(!(Pooltemperatur.state instanceof Number))
            Pooltemperatur.postUpdate(0)
        if(!(Switch_Pump.state instanceof OnOffType))
            Switch_Pump.sendCommand(OFF)
        if(!(Pool_Mode.state instanceof Number))
            Pool_Mode.postUpdate(POOL_MODE_AUTO)
    ]
end

rule "Poolpumpe Start"
when
    Time is poolStart timeOnly
then
    if((Pool_Mode.state as Number).intValue != POOL_MODE_AUTO) return;

    if(Switch_Pump.state != ON) {
        logInfo("pool", "Poolpumpe einschalten ...")
        Switch_Pump.sendCommand(ON)
    }
end

rule "Poolpumpe Stopp"
when
    Time is poolStopp timeOnly
then
    if((Pool_Mode.state as Number).intValue != POOL_MODE_AUTO) return;

    if(Switch_Pump.state != OFF) {
        logInfo("pool", "Poolpumpe ausschalten ...")
        Switch_Pump.sendCommand(OFF)
    }
end
Da es nur Automatik und Manuell gibt, könnte man das Number Item Pool_Mode auch locker als Switch Item bauen (poolAuto ON/OFF), dann kann man sich den Quatsch mit den globalen Konstanten sparen. Sinnvoll wäre das nur, wenn es mehr als zwei erlaubte Werte gibt.

Der Trigger Time is <DateTimeItem> [timeOnly] steht auch in openHAB 3 zur Verfügung, ich bin mir aber nicht sicher, ob es in openHAB3.4.4 bereits das Input Widget gibt.

Dann müsste man für die Eingabe des Start- und Stoppzeitpunkts einen Umweg über Button Widgets gehen:
Items:

Code: Alles auswählen

Number setPoolStart "Startzeit[]" <time>
Number setPoolStopp "Stoppzeit[]" <time>
Sitemap:

Code: Alles auswählen

Text item=poolStart
Text item=poolStopp
Switch item=setPoolStart mappings=[1="-1h",2="-5min,3="+5min",4="+1h"]
Switch item=setPoolStopp mappings=[1="-1h",2="-5min,3="+5min",4="+1h"]
Rules:

Code: Alles auswählen

rule "set start"
when
    Item setPoolStart received update
then
    val myTime = (poolStart.state as DateTimeType).getZonedDateTime
    var int iMinuteOfDay = myTime.getMinute + myTime.getHour
    switch((newState as Number).intValue) {
        case 1: {iMinuteOfDay -= 60}
        case 2: {iMinuteOfDay -= 5}
        case 3: {iMinuteOfDay += 5}
        case 4: {iMinuteOfDay += 60}
    }
    if(iMinuteOfDay < 0) iMinuteOfDay = 0
    if(iMinuteOfDay > 1439) iMinuteOfDay = 1439
    val iHour = (iMinuteOfDay / 60).intValue
    val iMinute = iMinuteOfDay - iHour * 60
    poolStart.postUpdate(new DateTimeType(now.withHour(iHour).withMinute(iMinute)))
end

rule "set stopp"
when
    Item setPoolStopp received update
then
    val myTime = (poolStopp.state as DateTimeType).getZonedDateTime
    var int iMinuteOfDay = myTime.getMinute + myTime.getHour
    switch((newState as Number).intValue) {
        case 1: {iMinuteOfDay -= 60}
        case 2: {iMinuteOfDay -= 5}
        case 3: {iMinuteOfDay += 5}
        case 4: {iMinuteOfDay += 60}
    }
    if(iMinuteOfDay < 0) iMinuteOfDay = 0
    if(iMinuteOfDay > 1439) iMinuteOfDay = 1439
    val iHour = (iMinuteOfDay / 60).intValue
    val iMinute = iMinuteOfDay - iHour * 60
    poolStopp.postUpdate(new DateTimeType(now.withHour(iHour).withMinute(iMinute)))
end
Diese Rules sind aber - wie erwähnt - nur dann notwendig, wenn das Input Widget noch nicht zur Verfügung steht und Du nicht auf OH4.2 updaten willst.

Es gibt noch zig andere Möglichkeiten, das umzusetzen, aber die Variante oben wäre die einfachste (und in meinen Augen sinnvolle).
openHAB4.3.2 stable in einem Debian-Container (bookworm) (Proxmox 8.3.3, LXC), mit openHABian eingerichtet

Maxwell
Beiträge: 3
Registriert: 28. Jul 2024 16:39
Answers: 0

Re: Regel für Poolsteuerung

Beitrag von Maxwell »

Hallo,

vielen Dank für deine ausführliche Antwort. Durch solche Menschen wie dich lebt das Forum erst richtig !!!

Ich habe Openhabian auf Proxmox laufen und schon mal was in richtung Update versucht aber bin daran gescheitert.
Nun gibt es noch ein zwei drei kleine Projekte die ich umsetzen möchte bevor ich das ganze System auf einen anderen LXC Container umziehe.
In der Aktuellen installation sind noch viele kleine überreste von alten versuchen übrig geblieben die sollen
nicht mit übernommen werden, deswegen würde ich nur ungern ein Update fahren.

Zu meinem eigentlichen Problem:

Ich habe gestern noch etwas rumprobiert und mir Java Localtime workarounds im Internet durchgelesen.
Mit folgendem Code funktionierte es dann komischerweise auf Anhieb:

Code: Alles auswählen


			var Number sollStundeStart = (Setting_Time_Pool_Valve_Start_H.state as DecimalType).intValue
			var Number sollMinuteStart = (Setting_Time_Pool_Valve_Start_M.state as DecimalType).intValue
			val LocalTime startZeit = LocalTime.of(sollStundeStart.intValue, sollMinuteStart.intValue)

			var Number sollStundeStop = (Setting_Time_Pool_Valve_Stop_H.state as DecimalType).intValue
			var Number sollMinuteStop = (Setting_Time_Pool_Valve_Stop_M.state as DecimalType).intValue
    		        val LocalTime endZeit = LocalTime.of(sollStundeStop.intValue, sollMinuteStop.intValue)
    		        
Vielleicht kann damit jmd der ähnliches vor hat etwas damit anfangen.

Das mit der Globalen Variable 0 und 1 hat der "Macher" dieser Rule so angelegt weil es noch einen 3 "Heizbetrieb" gibt welchen ich NOCH
nicht realisiert habe. Diese möglichkeit möchte ich mir jedoch gleich vorab noch offenhalten.

Ich werde in einem extra LXC Container mal deine Variante testen und meine Erfahrungen teilen...

Vielen Dank nochmal für deine schnelle Hilfe !

Antworten