[SOLVED] Variable and rules

Hello,
just fighting with a (I thought) simple topic but can’t find out what happens.

I have a rule-file with two rules,

  • first rule is for the case when letterbox was filled,
  • the second rule when the letterbox was cleared

In the first rule I write the time when the letterbox was filled:

...
var String Letterbox_Last_Filling = now.toString("HH':'mm' Uhr ('d'.'M'.)'")
...

(Content is i.e. 19:40 Uhr (9.2.) )

Now I thought I can use this variable in the second rule also, for testings I add:
logInfo(“letterbox.rules”, “Letterbox filling; Status Letterbox: {} (Time LastFilled: {})”,Letterbox_Full, Letterbox_Last_Filling )but message is:

" The name ‘Letterbox_Last_Filling’ cannot be resolved to an item or type"

Whats wrong?
How can i use a (String) variable in one rule file in two rules? Or not possible?

I also try to add in first line from the rule-file:

var Letterbox_Last_Filling

Its a question of scope.
Variables created inside a rule are dumped when the rule completes, and created anew next time the rule runs. “Local scope”.
openHAB Items in contrast exist outside of rules, any rule can examine or update them, and they continue to exist between rules running. “Global scope”.

Sometimes you might want to use an Item to pass values between rules running at different times. (That also allows you to use persistence to remember the value between reboots.)

But sometimes you might only want a temporary “store”. If you create a variable in a rules file, but outside of any particular rule, (do this at the top of the file), that variable will have global scope. You can alter or examine it any rule.
Or nearly - in reality it’s only global to rules within that particular rule file.
Rebooting or editing the rules file will destroy/recreate it.
You can set an initial value in the original declaration (var/val).

1 Like

So in my case, I need to use an item?
Because I need the “old” value from the variable if the rule is executed again, and if I understand you correctly (“created anew next time the rule runs”).
I thought the variable will still have the value till the variable I new defined (var Latterbox_last_Filling)…
But the variable is “NUll” when one of the rules from the rule-file will take effect?

Only if you want to

Example

var elephant = 22  //  global variable
                              // set to 22 when file loaded
                              // available to any rule in this file
                              // NOT available to rule in other files 

rule "one"
...
    elephant = 44
...

rule "two"
...
    if (elephant == 22) {
        logInfo("test", "Neither rule has run before")
    } else if (elephant == 44) {
        logInfo("test", "Rule one was last to run")
    } else if (elephant == 66) {
        logInfo("test", "Rule two was last to run")
    } else {
        logInfo("test", "Wasn't expecting that")
    }
    elephant = 66
end

Hmmm,
but in my case I can’t use variable, or?
Because it seems the setted value is lost after the rule was one time "executed, or is ther a mistake on my side?

var String Letterbox_Last_Filling
var String Letterbox_Last_Clearing

rule "Briefkasten: Einwurfklappe wurde betätigt"  // Filling
when Item Letterbox_Filling changed from CLOSED to OPEN
     or Item Switch_Socket09 changed from OFF to ON    // for testing/debugging only !!
 then
    var String Letterbox_Last_Filling = now.toString("HH':'mm' Uhr ('d'.'M'.)'")
    logInfo("letterbox.rules", "#####1 Letterbox FILLING (Time LastFill: {}; LastClear: {})",Letterbox_Last_Filling, Letterbox_Last_Clearing )
 end
  
rule "Briefkasten: Leerungsklappe wurde geöffnet"  // Clearing
when Item Letterbox_Clearing changed from 0 to 1 or Item Letterbox_Clearing changed from NULL to 1
    or Item Switch_Socket09 changed from ON to OFF    // for testing/debugging only !!
 then
    var String Letterbox_Last_Clearing = now.toString("HH':'mm' Uhr ('d'.'M'.)'")
    logInfo("letterbox.rules", "#####B Letterbox CLEARING (Time LastClear: {}; LastFill: {})",Letterbox_Last_Clearing, Letterbox_Last_Filling )
 end

LOGFILE:

2019-02-10 12:02:15.322 [vent.ItemStateChangedEvent] - Switch_Socket09 changed from OFF to ON

2019-02-10 12:02:15.340 [INFO ] [arthome.model.script.letterbox.rules] - #####1 Letterbox FILLING (Time LastFill: 12:02 Uhr (10.2.); LastClear: null)

2019-02-10 12:02:22.274 [vent.ItemStateChangedEvent] - Switch_Socket09 changed from ON to OFF

2019-02-10 12:02:22.422 [INFO ] [arthome.model.script.letterbox.rules] - #####B Letterbox CLEARING (Time LastClear: 12:02 Uhr (10.2.); LastFill: null)
var String Letterbox_Last_Filling
...

rule "Briefkasten: Einwurfklappe wurde betätigt"  // Filling
...
    var String Letterbox_Last_Filling = now.toString("HH':'mm' Uhr ('d'.'M'.)'")

You made a global variable Letterbox_Last_Filling
But inside your rule, you made a new local variable, also called Letterbox_Last_Filling
That’s allowed, the system will use the most recent one.
You set the local variable to a timestamp text.
But when this rule ends, the local variable is destroyed.
The global variable still exists, but it never got set to anything.

var String Letterbox_Last_Filling = "never used"
...

rule "Briefkasten: Einwurfklappe wurde betätigt"  // Filling
...
    Letterbox_Last_Filling = now.toString("HH':'mm' Uhr ('d'.'M'.)'")

Don’t define a new variable inside the rule by using var
Just use the existing global variable by using its name.