I am daring to revive this thread for various reasons:
- I am trying to implement this sprinkler / irrigation approach
- Silent changes were made during the discussion
- I am also having trouble making this work
- I though there is value in it for those who want to work with the thread’s solution.
I have been abstinent form OH v1 for quite a while, and seem to have forgotten a few things.
I basically implemented the following based on this thread:
sitemap irrigation label="Irrigation" {
Frame {
Group item=gIrriAll label="Irrgiation Test" icon="water_drops"
Setpoint item=Irrigation1_1_Time|minValue=1|maxValue=30|step=1|
Setpoint item=Irrigation1_2_Time|minValue=1|maxValue=30|step=1|
Setpoint item=Irrigation1_3_Time|minValue=1|maxValue=30|step=1|
}
}
Group gIrriAll
Group gIrrigation (gIrriAll)
Group gIrrigationTime (gIrriAll)
Switch Irrigation_1 "Zone 1 valve" (gIrrigation, gIrriAll)
Switch Irrigation_2 "Zone 2 valve" (gIrrigation, gIrriAll)
Switch Irrigation_3 "Zone 3 valve" (gIrrigation, gIrriAll)
String Irrigation_Curr "Current active zone is [%s]" (gIrriAll)
Switch Irrigation_Auto "Irrigation Auto" (gIrriAll)
Switch Irrigation_Now "Irrigation Now" (gIrriAll)
Number Irrigation_1_Time "Zone 1 duration [%d mins]" (gIrrigationTime, gIrriAll)
Number Irrigation_2_Time "Zone 2 duration [%d mins]" (gIrrigationTime, gIrriAll)
Number Irrigation_3_Time "Zone 3 duration [%d mins]" (gIrrigationTime, gIrriAll)
Switch Irrigation_Allowed "Test switch to trigger cascade" (gIrriAll)
import org.openhab.core.library.types.*
import org.openhab.core.library.items.*
import org.openhab.core.types.*
import org.openhab.core.items.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.eclipse.xtext.xbase.lib.*
import org.joda.time.*
import org.openhab.library.tel.types.CallType
import java.util.Set
// ------------------------------------------------------------------------
val Timer irrigationTimer = null
// https://community.openhab.org/t/how-to-implement-timer-with-parameter/10600/7
// If you have persistence and it does not save Strings use this rule
rule "System started"
when
System started
then
logInfo("Irrigation.0", "System Start: Irrigation .")
// assumes no more than one is ON at a time
val curr = gIrrigation.members.filter[v|v.state == ON].head
logInfo("Irrigation.0", "System Start: Irrigation ..")
if(curr == null) {
Irrigation_Curr.sendCommand("None")
logInfo("Irrigation.0", "System Start: Irrigation ...")
} else {
Irrigation_Curr.sendCommand(curr.name)
logInfo("Irrigation.0", "System Start: Irrigation ....")
// retrigger the cascade rule to recreate the timer
curr.sendCommand(ON)
logInfo("Irrigation.0", "System Start: Irrigation .....")
}
// any newly created timer duration variable won't be set until intitialised
if (Irrigation_1_Time.state == Uninitialized) {
logInfo("Irrigation.0", "System Start: Irrigation initialise state: Irrigation_1_Time")
Irrigation_1_Time.postUpdate(5)
}
if (Irrigation_2_Time.state == Uninitialized) {
Irrigation_2_Time.postUpdate(5)
logInfo("Irrigation.0", "System Start: Irrigation initialise state: Irrigation_2_Time")
}
if (Irrigation_3_Time.state == Uninitialized) {
Irrigation_3_Time.postUpdate(5)
logInfo("Irrigation.0", "System Start: Irrigation initialise state: Irrigation_3_Time")
}
logInfo("Irrigation1.0", "System Start: Irrigation initialise state: done.")
// does not take into account how long it has already been running
end
rule "Start Irrigation"
when
Item Irrigation_Allowed changed to ON
then
if(Irrigation_Auto.state == ON || Irrigation_Now.state == ON){
// start with valve 1
logInfo("Irrigation.0", "Irrigation started...")
Irrigation_Curr.sendCommand(Irrigation_1.name)
Irrigation_1.sendCommand(ON)
logInfo("Irrigation.1", "... turning on {}", Irrigation_Curr.state)
}
end
rule "Irrigation switch cascade"
when
Item Irrigation_1 received command ON or
Item Irrigation_2 received command ON or
Item Irrigation_3 received command ON
then
// Get the currently running valve
val currValveName = Irrigation_Curr.state.toString
//logInfo("Irrigation.2", "... currValveName..: {}", currValveName)
val currValveSwitch = gIrrigation.members.filter[i|i.name == currValveName].head
//logInfo("Irrigation.3", "... currValveSwitch: {}", currValveSwitch.state)
val currValveNum = Integer::parseInt(currValveName.split("_").get(1))
//logInfo("Irrigation.4", "... currValveNum...: {}", currValveNum)
val currValveMins = gIrrigationTime.members.filter[t|t.name == currValveName + "_Time"].head.state as DecimalType
//logInfo("Irrigation.5", "... currValveMins..: {}", currValveMins)
// Get the next running valve in the sequence
val nextValveNum = currValveNum + 1
val nextValveName = "Irrigation_" + nextValveNum
// will be null if not found
val nextValveSwitch = gIrrigation.members.filter[i|i.name == nextValveName].head
// Create a timer to turn off curr and turn on next
irrigationTimer = createTimer(now.plusMinutes(currValveMins.intValue), [|
logInfo("Irrigation", "Turing off " + currValveName)
currValveSwitch.sendCommand(OFF)
// without the sleep commands OFF one ON the next follow too quickly
Thread::sleep(2000)
if(nextValveSwitch != null) {
logInfo("Irrigation", "Turing on " + nextValve.name)
Irrigation_Curr.sendCommand(nextValveName)
nextValveSwitch.sendCommand(ON)
} else {
logInfo("Irrigation", "Irrigation is complete")
Irrigation_Curr.sendCommand("None")
}
irrigationTimer = null
])
end
rule "Cancel Irrigation"
when
Item Irrigation_Allowed received command OFF
then
// Cancel any timers
if(irrigationTimer != null && !irrigationTimer.hasTerminated) {
irrigationTimer.cancel
}
irrigationTimer = null
// Turn off any open valves
gIrrigation.members.forEach[v | if(v.state != OFF) v.sendCommand(OFF) ]
// Update the status
Irrigation_Curr.sendCommand("None")
logInfo("Irrigation", "Irrigation stopped / ended / finished.")
end
The silent change that was made (Rich’s initial line)
// Get the next running valve in the sequence
val nextValveName = "Irrigation_" + currValveNum
should read (as reflected in my listing)
// Get the next running valve in the sequence
val nextValveName = "Irrigation_" + nextValveNum
Persistence in rrd4j.persist:
gIrriAll : strategy = everyChange, restoreOnStartup
Errors I encounter…
In start-up
[ERROR] [m.r.internal.engine.RuleEngine] - Error during the execution of startup rule 'System started': cannot invoke method public abstract java.lang.String org.openhab.core.items.Item.getName() on null
which is related to this line:
Irrigation_Curr.sendCommand(curr.name)
The next error is:
[ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule 'Irrigation switch cascade': Cannot cast org.openhab.core.types.UnDefType to org.openhab.core.library.types.DecimalType
2
related to this line:
val currValveMins = gIrrigationTime.members.filter[t|t.name == currValveName + "_Time"].head.state as DecimalType
Any hints appreciated.
[2018-03-10 Updated] incorporated all changes to make this a working solution