Function - Final value error

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

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

Which one?! Complaints about ‘final value’ are to do with the var/val thing, passing vars into a closure (function or timer etc.)

hey thanks for the reply, I’ve resolved this using a hashmap. I’ve posted my code above.

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)

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. :slight_smile: