[SOLVED] Help understanding rules

  • Platform information:
    • Hardware:Intel i7/8mb
    • OS: Windows 10
    • Java Runtime Environment: Zulu 8
    • openHAB version: OH2
  • Issue of the topic:
    I have been trying to teach my self Java in order to use and configure OH2. I am across sitemaps and items and as for things i just build using paper UI. I have built a few basic rules and read alot on java but thought that if i try to learn how an example rule works it may help me to understand this process further.

Below is the rule i am working on and i have added comments to it for you amazing people to verify.

Thanks for your help in advance and please feel free to let me know where i am going wrong of it there are good references i need to read.

This rule slowly dims and changes the colour of a Hue bulb over 10min.

rule “Go to sleep”
when
Item Scene_Slaapkamer changed to 9
then
//Go from from a bright orang-red to soft red (and off)
logInfo(“GoToSleep”, “Starting”, Scene_Slaapkamer.state.toString)
ColorSlaapkamer.sendCommand(“10,100,100”)
var percent = 100
var color = 10
while(percent > 0 && Scene_Slaapkamer.state == 9) {
ColorSlaapkamer.sendCommand(color.toString + “,100,” + percent.toString)
color = percent / 10
percent = percent - 5
logInfo(“GoToSleep”, color.toString, percent.toString)
Thread::sleep(30000) //takes 10 min to go off
}
if(Scene_Slaapkamer.state == 9){
SwSlaapkamer.sendCommand(OFF)
Scene_Slaapkamer.sendCommand(0)
logInfo(“GoToSleep”, "Finshed ")
}else{
logInfo(“GoToSleep”, "Aborted ")
}
end

Does the loginfo just log values for review or are they used in the code later?
Is the GoToSleep a reference to the rule name?
Where does the “Starting” and “Finshed” reference to?

To the best of my knowledge this is how i read the rule.
when item scene value changed to 9 then
log these variable to Scene_Slaapkamer.state.toString.
Send these HSB values to the HUE bulb
while these two perimeters are met then change colour and brightness by said amount which i am assuming will loop until the 30000 sec is up unless the below variable are met first thus closing the the code.

Just logging (into openhab.log)

It is just a String for the loggerName that can be used to identify the entry in the logfile.

Just a string that is used to for the log message.

(almost) correct
The while loop will run until percent >0 (and scene is 9)
It works like this: Starting from 100%, we drop -5% every 30 secs
It will take 20 steps to go down to 0%, so: 20*30secs = 10 mins

Important Note: Thread::sleep(30000) (or 30 secs) is not recommended.
another (better) way would be: createTimer(now.plusMinutes(x))

Check: (OH 1.x and OH 2.x Rules DSL only] Why have my Rules stopped running? Why Thread::sleep is a bad idea & How to use code fences

just find this don’t know if it will help.

First things first:
Use code fences when publishing code

Second, while loops and Thread:sleep inside rules are bad ideas (Especially a while loop with a Thread::sleep inside it!!)

Use this:

//// !!!!! There three variable declaration go AT THE TOP of the rules file  !!!!!
var Timer sleepTimer = null   // timer variable
var percent = 100                 //  global variable so the timer lamdba can access it
var color = 10                 //  global variable so the timer lamdba can access it

rule "Go to sleep"
when
    Item Scene_Slaapkamer changed to 9
then
    //Go from from a bright orang-red to soft red (and off)
    logInfo("GoToSleep", "Starting", Scene_Slaapkamer.state.toString)
    ColorSlaapkamer.sendCommand("10,100,100")
    percent = 100
    color = 10
    
    // No need to check if the scene number is 9 because that was the rule trigger

    if (sleepTimer === null) {                                //If there is no timer
        sleepTimer = createTimer(now(), [ |                   // then create one to start immediately
            ColorSlaapkamer.sendCommand(color.toString + ",100," + percent.toString)
            color = percent / 10
            percent = percent - 5
            logInfo("GoToSleep", color.toString, percent.toString)
            if (percent > 0) { // if the light is still ON then run the timer again in 30s
                sleepTimer.reshedule(now.plusSeconds(30))
            }
            else { // if the percent has reached 0 then we cancel the timer and turn off the light
                sleepTimer = null
                SwSlaapkamer.sendCommand(OFF)
                Scene_Slaapkamer.sendCommand(0)
                logInfo("GoToSleep", "Finshed ")
            }
        ])
    }
end
3 Likes

can we make his [SOLVED] now @Mobyn1ck

Thankyou for your help. i think i understand it much better now i have also learnt some etiquette too.

I will have more questions soon i am sure but these will be in their fences.

Case solved. (Do i need to do anything to make that happen? @adtwomey?)

1 Like

You need to tick the solution mark under the post that provided you with the solution
Like this:
hc_292

1 Like