postUpdate from a var not working

I have a rule that should save a configs old state so it could be places back later.

rule "vrijedag automatisering"

when

        Item vandaag_thuis received command

then

        var Number rev_old
        var Number rzr_old
        var Number rzl_old
        var Number zbw_old

        if(vandaag_thuis.state == ON){
                //Eerste oude status opslaan zodat dit later teruggezet kan worden
                rev_old = autoRev.state as DecimalType
                rzr_old = autoRzr.state as DecimalType
                rzl_old = autoRzl.state as DecimalType
                zbw_old = autoZbw.state as DecimalType
                logInfo(logName, "De rev_old status is nu: " + rev_old)
                //Status nu veranderen
                autoRev.postUpdate("4")
                autoRzr.postUpdate("4")
                autoRzl.postUpdate("4")
                autoZbw.postUpdate("3")
                logInfo(logName, "De autoRev-status -if- is nu: " + autoRev.state)

        }
        else{
                autoRev.postUpdate(rev_old)
                autoRzr.postUpdate(rzr_old)
                autoRzl.postUpdate(rzl_old)
                autoZbw.postUpdate(zbw_old)
                logInfo(logName, "de autoRev-status -else- is nu: " + autoRev.state)
        }

end

All auto*** items are of the Number type.

When the rule runs, the initial status (when the ON is triggered) is saved correctly. However, when the if-statement is false, de old status is not restored. No error in the logs.

What is my issue here?

rev_old is empty if vandaag_thuis.state != ON. try:

rule "vrijedag automatisering"
when
        Item vandaag_thuis received command
then
        //Eerste oude status opslaan zodat dit later teruggezet kan worden
        var Number rev_old = autoRev.state as DecimalType
        var Number rzr_old = autoRzr.state as DecimalType
        var Number rzl_old = autoRzl.state as DecimalType
        var Number zbw_old = autoZbw.state as DecimalType

        if(vandaag_thuis.state == ON){
                logInfo(logName, "De rev_old status is nu: " + rev_old)
                //Status nu veranderen
                autoRev.postUpdate("4")
                autoRzr.postUpdate("4")
                autoRzl.postUpdate("4")
                autoZbw.postUpdate("3")
                logInfo(logName, "De autoRev-status -if- is nu: " + autoRev.state)

        }
        else{
                autoRev.postUpdate(rev_old)
                autoRzr.postUpdate(rzr_old)
                autoRzl.postUpdate(rzl_old)
                autoZbw.postUpdate(zbw_old)
                logInfo(logName, "de autoRev-status -else- is nu: " + autoRev.state)
        }

end

Edit: I think I understand what you want to do now. Search the forum for previousState, as in item.previousState, to find your solution. No need to save the old state then, just let the persistence service do that job for you. Else, if you want to save the old state for future use, create dummy items to save that previous state.

Variable values are only available in your rules, when the rules run. When the rule is finished, your variables are lost. So you cannot ‘save’ your variables when vandaag_thuis.state == ON, and retrieve those same values when the vandaag_thuis item changes to OFF.

The trick here is to declare your storage variables with var, like rev_old outside of any rule, at the beginning of your rules file.
You don’t have to give them a value at that time, but you can if you wish.

That makes them “global” - any rule in this file can see and alter them.
They are not created anew when rules tun, they are not discarded when rules exit.

Don’t use DecimalType :wink:

Why updating an Item to the current state?

rule "vrijedag automatisering"
when
    Item vandaag_thuis received command
then
    //Eerste oude status opslaan zodat dit later teruggezet kan worden
    if(vandaag_thuis.state == ON){
        logInfo(logName, "De rev_old status is nu: {}",autoRev.state)
        //Status nu veranderen
        autoRev.postUpdate(4)
        autoRzr.postUpdate(4)
        autoRzl.postUpdate(4)
        autoZbw.postUpdate(3)
        logInfo(logName, "De autoRev-status -if- is nu: 4")
    } else{
        autoRev.postUpdate(autoRev.state as Number)
        autoRzr.postUpdate(autoRzr.state as Number)
        autoRzl.postUpdate(autoRzl.state as Number)
        autoZbw.postUpdate(autoZbw.state as Number)
        logInfo(logName, "de autoRev-status -else- is nu: {}",autoRev.state)
    }
end

But be aware that there is no guarantee that any of the items state is of type Number at all. This could possibly cause a null pointer exception. If you have default values, you can prevent this:

rule "vrijedag automatisering"
when
    Item vandaag_thuis received command
then
    var Number nAutoRev = 4
    var Number nAutoRzr = 4
    var Number nAutoRzl = 4
    var Number nAutoZbw = 3
    if(vandaag_thuis.state != ON) {
        if(autoRev.state instanceof Number) nAutoRev = autoRev.state as Number
        if(autoRzr.state instanceof Number) nAutoRzr = autoRzr.state as Number
        if(autoRzl.state instanceof Number) nAutoRzl = autoRzl.state as Number
        if(autoZbw.state instanceof Number) nAutoZbw = autoZbw.state as Number
    }
    if(vandaag_thuis.state == ON)
        logInfo(logName, "De rev_old status is nu: {}",autoRev.state)
    autoRev.postUpdate(nAutoRev)
    autoRzr.postUpdate(nAutoRzr)
    autoRzl.postUpdate(nAutoRzl)
    autoZbw.postUpdate(nAutoZbw)
    logInfo(logName, "de autoRev-status -else- is nu: {}",nAutoRev)
end

@duiffie I new there had to be something and it was just what @rossko57 said. Use a global variable. The dummy item would work as well just a the persistence (nice one btw, didn’t think of that at all!)

@Udo_Hartmann Will delete the DecimalType. If you look closely, it is not updating to the current state (although it could do) and neither is it an Item. It is a method of temporary storing the state till ‘vandaag_thuis’ is switched off again.

The Items concerned only take numbers and are controlled by numbers. It’s like a ranking system. The lower, the more automated. You set the numbers in the sitemap.

Thank all for the quick replies!

Ah, I missed that point. Obviously, then you have to define the var in global context.

Do you know about persistence? Take a look…
items:

Group gAuto
Number autoRev (gAuto)
Number autoRzr (gAuto)
Number autoRzl (gAuto)
Number autoZbw (gAuto)

rrd4j.persist:

Strategies {
    everyMinute : "0 * * * * ?"
    default = everyChange, everyMinute
}
Items {
    gAuto* // this will persist all members of gAuto, but not gAuto itself
}

rule:

var nTimestamp

rule "set and restore"
when
    Item vandaag_thuis received command
then
    if(receivedCommand == ON) {
        nTimestamp = now
        autoRev.postUpdate("4")
        autoRzr.postUpdate("4")
        autoRzl.postUpdate("4")
        autoZbw.postUpdate("3")
    } else {
        gAuto.members.forEach[i |
            i.postUpdate(i.historicState(nTimestamp,"rrd4j").state as Number)
        ]
    }
end

You could also use an Item to store the timestamp. Please be aware that (like your rule) if sending the ON command twice in a row, there will be no old value anymore.

You have to install rrd4j persistence to use it :slight_smile: and of course you could use other persistence services, too, but imho rrd4j will fit best.