Lambda variable error

Hello all,
I’m having this rule works fine sometimes and sometimes logs errors, complaining about a global variable
ide error msg:

Cannot refer to the non-final variable RunFor inside a lambda expression(org.eclipse.xtext.xbase.validation.IssueCodes.invalid_mutable_variable_access)

the variables inside the createTimer closure is the highlighted for errors by vscode ide and Sometimes I’m getting errors in log view and sometimes everything works fine. any way it is still unclean code. and I hate it, especially it is repeated for 5 switches ! :sweat_smile:

var Timer myTimer01 = null
var String myCommand01 = "ON"

rule "Timer01 Switch"
when
    Item Timer01 changed
then

    if(myTimer01 !== null){
        myTimer01.cancel()
        myTimer01 = null
    }
    
    if(myTimer01 === null){

        var Number RunFor = (Timer01RunFor.state as Number).intValue()
        if(RunFor <= 0) RunFor = 5
        var Number StopFor = (Timer01StopFor.state as Number).intValue()
        if(StopFor <= 0) StopFor = 5

        myTimer01 = createTimer(now, [ |
            
            if (Timer01.state == ON) {

                if (myCommand01 == "ON") {
                    Timer01Group.members.forEach[ i | i.sendCommand(ON) ]
                    myCommand01 = "OFF"
                    myTimer01.reschedule(now.plusMinutes(RunFor))
                    
                } else if (myCommand01 == "OFF") {
                    Timer01Group.members.forEach[ i | i.sendCommand(OFF) ]
                    myCommand01 = "ON"
                    myTimer01.reschedule(now.plusMinutes(StopFor))
                }
            } else {
                Timer01Group.members.forEach[ i | i.sendCommand(OFF) ]
                myCommand01 = "ON"
                myTimer01.cancel()
                myTimer01 = null
            }
        ])
    }else{
        logInfo("Timer01", "myTimer01 !== null")
    }
end

Thanks .

It’s this
var Number RunFor = ...
“non-final” is complaining about the var type when used inside the timer code block (the lambda).
Make it a val and you’ll be fine, you don’t seem to have a need to change it after creation.

Since you want to create it with either/or values, you might find the ternary expression syntax (“shorthand-if”) useful.
zzz = if (condition) valueX else valueY

val RunFor =  if ((Timer01RunFor.state as Number) <= 0) 5 else (Timer01RunFor.state as Number).intValue
1 Like

Thanks a lot @rossko57 you are awesome :slight_smile:

Now I’m having this info, but it is much better , thanks

[INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'timers.rules', using it anyway:

Assignment to final variable

Assignment to final variable

Assignment to final variable

Assignment to final variable

Assignment to final variable

Assignment to final variable