Hi
I’m using OH2 and trying to write my first function to avoid repeating code in my rules.
I have the following in my rules file.
import org.eclipse.xtext.xbase.lib.Functions
val logName = "Presence"
var Timer PresenceTimerChris = null
var Timer PresenceTimerVikki = null
val AwayWaitTime = 5
val Functions$Function5<GenericItem, GenericItem, GenericItem, Timer, Integer, Boolean> presenceChange= [ p, d, a, t, l |
if(d.state == ON)
{
if(t!=null)
{
logInfo(logName, "Cancel Timer")
t.cancel
t = null
}
logInfo(logName, p.label + " Home")
postUpdate(p, ON)
}
if(d.state == OFF)
{
if(t == null || t.hasTerminated)
{
logInfo(logName, "Create Timer")
t = createTimer(now.plusMinutes(l))
[|
logInfo(logName, p.label + " Away")
postUpdate(p, OFF)
postUpdate(a, now.minusMinutes(l).toString)
t = null
]
}
else
{
logInfo(logName, "Reschedule Timer")
t.reschedule(now.plusMinutes(l))
}
}
true
]
rule "Chris Presence Changed temp"
when
Item P_Chris_Mobile changed from ON to OFF or
Item P_Chris_Mobile changed from OFF to ON
then
presenceChange.apply(P_Chris, P_Chris_Mobile, P_Chris_Away, PresenceTimerChris, AwayWaitTime)
end
The error is wherever I have “t =”. It’s complaining about final value, and I’m not sure how to work around it.
Many Thanks,
Chris
chriscolden
(Chris Colden)
February 24, 2017, 10:29am
2
I’ve managed to resolve this by using HashMaps
import org.eclipse.xtext.xbase.lib.Functions
import java.util.Map
import java.util.HashMap
val logName = "Presence"
var Map<String, Timer> presenseTimers = new HashMap
val int AwayWaitTime = 5
val Functions$Function6<GenericItem, GenericItem, GenericItem, Map<String, Timer>, Integer, String, Boolean> presenceChange= [ p, d, a, t, awt, ln |
if(d.state == ON)
{
if(t.get(p.name)!=null)
{
logInfo(ln, "Cancel Timer")
t.get(p.name).cancel
t.remove(p.name)
}
logInfo(ln, p.label + " Home")
postUpdate(p, ON)
}
if(d.state == OFF)
{
if(t.get(p.name) == null || t.get(p.name).hasTerminated)
{
logInfo(ln, "Create Timer")
t.put(p.name, createTimer(now.plusMinutes(awt))
[|
logInfo(ln, p.label + " Away")
postUpdate(p, OFF)
postUpdate(a, now.minusMinutes(awt).toString)
t.remove(p.name)
])
}
else
{
logInfo(ln, "Reschedule Timer")
t.get(p.name).reschedule(now.plusMinutes(awt))
}
}
true
]
rule "Chris Presence Changed"
when
Item P_Chris_Mobile changed from ON to OFF or
Item P_Chris_Mobile changed from OFF to ON
then
presenceChange.apply(P_Chris, P_Chris_Mobile, P_Chris_Away, presenseTimers, AwayWaitTime, logName)
end
rossko57
(Rossko57)
February 24, 2017, 11:24am
3
Which one?! Complaints about ‘final value’ are to do with the var/val thing, passing vars into a closure (function or timer etc.)
Hello,
How does one access a varible outside a foreachloop for use within the loop?
Example:
var String foo = “50”
var ArrayList sl = fixture.get(“switches”) as ArrayList
sl.forEach [ ts |
logInfo(“motion_tripped”, " setting dimmer: " + ts.name)
sendCommand(ts, foo)
]
The syntax checker in the OpenHAB Designer says:
“Cannot refer to a non-final variable foo from within a closure”
Thanks!
Brian
chriscolden
(Chris Colden)
February 24, 2017, 11:26am
4
hey thanks for the reply, I’ve resolved this using a hashmap. I’ve posted my code above.
rossko57
(Rossko57)
February 24, 2017, 11:39am
5
Yes, it was just for “why”. I am surprised you didn’t need to make the hashmap a val though (which makes the map structure ‘final’, but not the content)
chriscolden
(Chris Colden)
February 24, 2017, 11:41am
6
It must be to do with the way the hashmap put is used. It must be getting the reference not the actual item. I’d be lying if I said I understood what was going on.