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.
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.
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.
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 and of course you could use other persistence services, too, but imho rrd4j will fit best.