[SOLVED] Using Selection Item on Sitemap to set variable value for using in rules

Hi there,

In my sitemap I’ve the following item:

Frame label="Test-Button Sleep Thread" {
    Switch item=test_button
    Selection item=vDauer label="vDauer [%d min]" mappings=[2=2_Minuten,5=5_Minuten,10=10_Minuten] 
}    

The purpose is to set the value ot vDauer which I’ll use in a rule:

rule "Sleep Test"
when
    Item test_button changed to ON
then
        if (test_button.state==ON) {
            var Number vDauerms = vDauer.state as Number            
            logInfo("RULE", "--> Sleep Test an: " + vDauerms)
            Thread::sleep(vDauerms)
            logInfo("RULE", "--> Sleep Test aus")
            sendCommand(test_button, OFF)
        }
end

Unfortunately I got an error message:

Log:
[INFO ] [.eclipse.smarthome.model.script.RULE] - --> Sleep Test an: 5
[ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule ‘Sleep Test’: An error occurred during the script execution: Could not invoke method: java.lang.Thread.sleep(long) on instance: null

VScode Editor:
Type mismatch: cannot convert from Number to long

logInfo(“RULE”, "–> Sleep Test an: " + vDauerms) outputs the correct value but it obviously doesn’t in Thread:sleep

How can I get this working?

Try this instead.

Thread::sleep(vDauerms.longValue)
1 Like

If you intend to have a delay of several minutes you should use a timer
Using Threa::sleep is OK but only for short delays up to 1s or so
The reasons is that openHAB only have 5 threads to play with and if one of your rules keep a thread opened for a long time then openHAB will have one less. If your have several similar rules you system will quickly come to a halt. A timer avoid that problem.

Please note that I also changed sendCommand(test_button, OFF) to test_button.sendCommand(OFF). It is better to use the method instead of the action when the item is already known. See:

var Timer timer = null

rule "Sleep Test"
when
    Item test_button changed to ON
then
    if (test_button.state==ON) {
        var Number vDauerms = vDauer.state as Number            
        logInfo("RULE", "--> Sleep Test an: " + vDauerms)
        if (timer === null) {
            timer = createTimer(now.plusMinutes(vDauerms.intValue, [ | // Sets timer to x minutes
                logInfo("RULE", "--> Sleep Test aus")
                test_button.sendCommand(OFF)
                timer = null //reset timer
            ])
        }
    }
end

Good luck

Thanks for the hint regarding the max amount sleep threads …

I’ve tried to run your example, however it puts out the following error messages:

  • Invalid number of arguments. The method createTimer(AbstractInstant, Procedure0) is not applicable for the arguments (DateTime) - Line 11
  • Invalid number of arguments. The method plusMinutes(int) is not applicable for the arguments (int,()=>Timer) - Line 11
  • missing ‘)’ at ‘}’ - Line 16

While I agree that it’s a best practice to not use sleep for long periods, also note that it’s possible to change the number of threads allocated to rule execution. I’m currently running 30 threads.

Where can one change the number of threads?
Will it affect the performance or what is the reason for default limit of 5?

In conf/services/runtime.cfg, you can set the number of rule engine threads using this config parameter. Note that a restart is not required for the change to take effect.

org.eclipse.smarthome.threadpool:RuleEngine=NN

where NN is the number of threads.

On a low end processor, it might not be advisable to set this number too high.

3 Likes

l will have a look in the morning.

1 Like

I forgot a ) after intValue

rule "Sleep Test"
when
    Item test_button changed to ON
then
    if (test_button.state==ON) {
        var Number vDauerms = vDauer.state as Number
        logInfo("RULE", "--> Sleep Test an: " + vDauerms)
        if (timer === null) {
            timer = createTimer(now.plusMinutes(vDauerm.intValue), [ | // Sets timer to x minutes
                logInfo("RULE", "--> Sleep Test aus")
                test_button.sendCommand(OFF)
                timer = null //reset timer
            ])
        }
    }
end
2 Likes

… should be (vDauerms.intValue)

Great - It works like a charm
Thank you very much!

You’re welcome. Please mark the solution. Thanks

Does the number of rule engine thread refer to the number of rules that can concurrently fire or stay active?

I am running OH2.5.12 on a Raspberry Pi 3 B+. What is the maximum number I can use to set the number of rule engine thread? Could you please also explain how you determine this?