AWESOME. Its working now…but way to fast. I think you wanted to show me that
plusSeconds
not plusMillis
timer.reschedule(now.plusSeconds(timeoutSecs)) // reschedule timer like a loop
Now, you need to go through the code line by line.
I advise you to save it somewhere.
The delete the rule and copy it, line by line. Don’t copy and paste.
Understand the code.
I’m on it
This is my rules for Sunrise (vice versa):
val int timeoutSecs = 9 // 9 seconds for 15 minutes
var int dimLevel = 100 // Start from 100
var Timer timer = null // Initialise timer to null
rule "Slowly Dim Down"
when
Item GPIO1 changed to ON
then
if (timer === null) { // If there is no timer
logInfo("TIMER", "Starting dimmer loop")
timer = createTimer(now.plusSeconds(0), [ | //Starts immediately
if (dimLevel == 0) { //If we have reached 0
timer = null // cancel timer
} else {
dimLevel = dimLevel - 1 // Decrease dimLevel by 1
val int pwmValue = ((dimLevel * 1024) / 100).intValue // Scale dimLevel from 0-100 to 0-1024
val commandString = "gpio pwm 1 " + pwmValue // Create command String
logInfo("LOOP Command Line: ", commandString)
executeCommandLine(commandString) // Execute command String
timer.reschedule(now.plusSeconds(timeoutSecs)) // reschedule timer like a loop
}
])
}
end
PWM signal 1024 is the lowest dimming value so I need to start with dimLevel 100.
OK I have a problem now.
The 2nd rules dont start. Just when I restart openhab it will. This are the 2 rules:
val int timeoutSecs = 9 // 9 seconds for 15 minutes
var int dimLevel = 0 // Start from 0
var Timer timer = null // Initialise timer to null
rule "Slowly Dim Up"
when
Item DUMMY changed to ON
then
if (timer === null) { // If there is no timer
logInfo("TIMER", "Starting dimmer loop")
timer = createTimer(now.plusSeconds(0), [ | //Starts immediately
if (dimLevel == 100) { //If we have reached 100
timer = null // cancel timer
} else {
dimLevel = dimLevel +1 // Increase dimLevel by 1
val int pwmValue = ((dimLevel * 1024) / 100).intValue // Scale $
val commandString = "gpio pwm 1 " + pwmValue // Create command $
logInfo("LOOP Command Line: ", commandString)
executeCommandLine(commandString) // Execute command String
timer.reschedule(now.plusSeconds(timeoutSecs)) // reschedule ti$
}
])
}
end
and
val int timeoutSecs = 9 // 9 seconds for 15 minutes
var int dimLevel = 100 // Start from 100
var Timer timer = null // Initialise timer to null
rule "Slowly Dim Up"
when
Item GPIO4 changed to ON
then
if (timer === null) { // If there is no timer
logInfo("TIMER", "Starting dimmer loop")
timer = createTimer(now.plusSeconds(0), [ | //Starts immediately
if (dimLevel == 0) { //If we have reached 0
timer = null // cancel timer
} else {
dimLevel = dimLevel -1 // Decrease dimLevel by 1
val int pwmValue = ((dimLevel * 1024) / 100).intValue // Scale $
val commandString = "gpio pwm 1 " + pwmValue // Create command $
logInfo("LOOP Command Line: ", commandString)
executeCommandLine(commandString) // Execute command String
timer.reschedule(now.plusSeconds(timeoutSecs)) // reschedule ti$
}
])
}
end
So if rule 1 got executed, rule 2 will not start and vice versa. Looks like I need a command in each rules to stop it.
Rules must have unique names. The last rule to load with the same name “wins”.
Ah damn. That was too easy
Thank you
OK I changed the name but it still doesn’t work.
It starts with “Starting dimmer loop” but doesn’t execute the “GPIO PWM” commands. When I restart openhab and trigger GPIO4 again it works fine.
Any ideas?
It’s not clear if you have also “unique-ified” the global variable names, like dimlevel
.
Okay, so it gets into a rule. Which one? Edit your logInfos somehow so that you can tell.
If it doesn’t run the loop, what does it do instead? We could add a logInfo into the “final exit” part and see if we go straight to that.
But really - assuming you have looked in openhab.log
for execution errors - we can guess it must have gone that way. How could that happen? Suspect if (dimlevel
is not giving the result we expect.
OK first thing I found in the logs is a wrong loop. “sun rise” is going down to 399 PWM and then it jumps down to 40 - 30 - 20 - 10 - 0 and this several time
2019-01-27 11:08:41.055 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 409'
2019-01-27 11:08:50.071 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 399
2019-01-27 11:08:50.079 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 399'
2019-01-27 11:14:06.002 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 40
2019-01-27 11:14:06.009 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 40'
2019-01-27 11:14:15.027 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 30
2019-01-27 11:14:15.035 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 30'
2019-01-27 11:14:24.051 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 20
2019-01-27 11:14:24.058 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 20'
2019-01-27 11:14:33.077 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 10
2019-01-27 11:14:33.085 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 10'
2019-01-27 11:14:42.106 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 0
2019-01-27 11:14:42.113 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 0'
2019-01-27 11:14:06.002 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 40
2019-01-27 11:14:06.009 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 40'
2019-01-27 11:14:15.027 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 30
2019-01-27 11:14:15.035 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 30'
2019-01-27 11:14:24.051 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 20
2019-01-27 11:14:24.058 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 20'
2019-01-27 11:14:33.077 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 10
2019-01-27 11:14:33.085 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 10'
2019-01-27 11:14:42.106 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 0
2019-01-27 11:14:42.113 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 0'
2019-01-27 11:14:06.002 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 40
2019-01-27 11:14:06.009 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 40'
2019-01-27 11:14:15.027 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 30
2019-01-27 11:14:15.035 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 30'
2019-01-27 11:14:24.051 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 20
2019-01-27 11:14:24.058 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 20'
2019-01-27 11:14:33.077 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 10
2019-01-27 11:14:33.085 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 10'
2019-01-27 11:14:42.106 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 0
2019-01-27 11:14:42.113 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 0'
2019-01-27 11:14:06.002 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 40
2019-01-27 11:14:06.009 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 40'
2019-01-27 11:14:15.027 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 30
2019-01-27 11:14:15.035 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 30'
2019-01-27 11:14:24.051 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 20
2019-01-27 11:14:24.058 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 20'
2019-01-27 11:14:33.077 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 10
2019-01-27 11:14:33.085 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 10'
2019-01-27 11:14:42.106 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 0
2019-01-27 11:14:42.113 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 0'
2019-01-27 11:14:06.002 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 40
2019-01-27 11:14:06.009 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 40'
2019-01-27 11:14:15.027 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 30
2019-01-27 11:14:15.035 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 30'
2019-01-27 11:14:24.051 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 20
2019-01-27 11:14:24.058 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 20'
2019-01-27 11:14:33.077 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 10
2019-01-27 11:14:33.085 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 10'
2019-01-27 11:14:42.106 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 0
2019-01-27 11:14:42.113 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 0'
2019-01-27 11:14:06.002 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 40
2019-01-27 11:14:06.009 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 40'
2019-01-27 11:14:15.027 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 30
2019-01-27 11:14:15.035 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 30'
2019-01-27 11:14:24.051 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 20
2019-01-27 11:14:24.058 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 20'
2019-01-27 11:14:33.077 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 10
2019-01-27 11:14:33.085 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 10'
2019-01-27 11:14:42.106 [INFO ] [ome.model.script.LOOP Command Line: ] - gpio pwm 1 0
2019-01-27 11:14:42.113 [INFO ] [lipse.smarthome.io.net.exec.ExecUtil] - executed commandLine 'gpio pwm 1 0'
Furthermore the logs yesterday for the sunset was fine. It started at pwm 0 and increased in 10th steps to 1024.
So rule sunrise -> sunset worked
sunset -> sunrise didn’t work. Needed to restart openhab to trigger it manually and then it worked with some strange errors (log above).
Here are the two rules again (may has some changes)
sunrise:
val int timeoutSecs = 9 // 9 seconds for 15 minutes
var int dimLevel = 100 // Start from 100
var Timer timer = null // Initialise timer to null
rule "Slowly Dim Up"
when
Item GPIO4 changed to ON
then
if (timer === null) { // If there is no timer
logInfo("TIMER", "Starting dimmer loop")
timer = createTimer(now.plusSeconds(0), [ | //Starts immediately
if (dimLevel == 0) { //If we have reached 0
timer = null // cancel timer
} else {
dimLevel = dimLevel -1 // Decrease dimLevel by 1
val int pwmValue = ((dimLevel * 1024) / 100).intValue // Scale dimLevel from 0-100 to 0-1024
val commandString = "gpio pwm 1 " + pwmValue // Create command String
logInfo("LOOP Command Line: ", commandString)
executeCommandLine(commandString) // Execute command String
timer.reschedule(now.plusSeconds(timeoutSecs)) // reschedule timer like a loop
}
])
}
end
Sunset
val int timeoutSecs = 9 // 9 seconds for 15 minutes
var int dimLevel = 0 // Start from 0
var Timer timer = null // Initialise timer to null
rule "Slowly Dim Down"
when
Item DUMMY changed to ON
then
if (timer === null) { // If there is no timer
logInfo("TIMER", "Starting dimmer loop")
timer = createTimer(now.plusSeconds(0), [ | //Starts immediately
if (dimLevel == 100) { //If we have reached 100
timer = null // cancel timer
} else {
dimLevel = dimLevel +1 // Increase dimLevel by 1
val int pwmValue = ((dimLevel * 1024) / 100).intValue // Scale dimLevel from 0-100 to 0-1024
val commandString = "gpio pwm 1 " + pwmValue // Create command String
logInfo("LOOP Command Line: ", commandString)
executeCommandLine(commandString) // Execute command String
timer.reschedule(now.plusSeconds(timeoutSecs)) // reschedule timer like a loop
}
])
}
end
No one an idea?
You seem to have missed the comment about global variables.
You cannot, in the same rules file, create a global variable dimlevel
which is both 100 and 0.
I would have expected this to generate errors in openhab.log
actually.
You can share the timer
and timeoutSecs
globals, but you should create them only once.
Personally, I would give timer a more unique name to avoid confusion some other time.
So I should use “dimLevel” and maybe “dimmingLevel”?
Same with timer?
It’s up to you.
Thinking about it a bit more, you’re not going to want both rules to run at the same time. Having a shared global timer
should stop that happening, so that’s probably a good thing.
I would give it a different name so that you don’t write another rule later also using ‘timer’ and get unexpected happenings.
Regarding dimlevel
- if we make sure the rules only run one at a time, you could actually use the same global variable. Only define it with var
once, of course.
But when you define it as a global, it only gets set to its initial vale when the rules file loads. When the rules run, they will alter it.
So before entering your timer loop in each rule, set the dimlevel to whatever is needed, 0 or 100
Quick question, are these two rules in separate files?
Yes, they are.
OK - I’m trying to understand it
So I don’t need a dimLevel in each rule because the level is set by the rules befor. If I use “Timer” for both timer, both timer will run in the background, right? So I could try this rules:
val int timeoutSecs = 9 // 9 seconds for 15 minutes
var int dimLevel = 100 // Start from 100
var Timer_Up timer = null // Initialise timer to null
rule "Slowly Dim Up"
when
Item GPIO4 changed to ON
then
if (timer === null) { // If there is no timer
logInfo("TIMER", "Starting dimmer loop")
timer = createTimer(now.plusSeconds(0), [ | //Starts immediately
if (dimLevel == 0) { //If we have reached 0
timer = null // cancel timer
} else {
dimLevel = dimLevel -1 // Decrease dimLevel by 1
val int pwmValue = ((dimLevel * 1024) / 100).intValue // Scale dimLevel from 0-100 to 0-1024
val commandString = "gpio pwm 1 " + pwmValue // Create command String
logInfo("LOOP Command Line: ", commandString)
executeCommandLine(commandString) // Execute command String
timer.reschedule(now.plusSeconds(timeoutSecs)) // reschedule timer like a loop
}
])
}
end
val int timeoutSecs = 9 // 9 seconds for 15 minutes
var Timer_Down timer = null // Initialise timer to null
rule "Slowly Dim Down"
when
Item DUMMY changed to ON
then
if (timer === null) { // If there is no timer
logInfo("TIMER", "Starting dimmer loop")
timer = createTimer(now.plusSeconds(0), [ | //Starts immediately
if (dimLevel == 100) { //If we have reached 100
timer = null // cancel timer
} else {
dimLevel = dimLevel +1 // Increase dimLevel by 1
val int pwmValue = ((dimLevel * 1024) / 100).intValue // Scale dimLevel from 0-100 to 0-1024
val commandString = "gpio pwm 1 " + pwmValue // Create command String
logInfo("LOOP Command Line: ", commandString)
executeCommandLine(commandString) // Execute command String
timer.reschedule(now.plusSeconds(timeoutSecs)) // reschedule timer like a loop
}
])
}
end
I’m on a good way?
Maybe if I offer a briefing on so called “global variables”
If you define a variable with var or val inside a rule, it only exists within that rule and is effectively created each time the rule runs and destroyed when it ends.
If instead you define it outside of any rule, we call it global because it can be shared by any rules in that rules file.
It’s a useful way for one rule to alter something that another rule can read later.
Or for all rules to share some common value, like a timeout.
Good practice is to define any globals at the top of your rules file, before any actual rules.
Pretty obviously, each global has to have a unique name.
If you assign an initial value,
var myGlobal = 22
that value will be given to the variable when the rules file loads.
But if any rules alter the value, it stays altered and dos not revert to that initial value (until next time you boot or edit the rules file).
So if var or val inside a rule only operate in this rule I dont need to change the name.
Wait - lets start again? Whats the different between global variable an the variable who operate only inside of one rule?
Is this global:
val int timeoutSecs = 9 // 9 seconds for 15 minutes
var int dimLevel = 100 // Start from 100
var Timer_Up timer = null // Initialise timer to null
rule "Slowly Dim Up"
and this not:
rule "Slowly Dim Up"
val int timeoutSecs = 9 // 9 seconds for 15 minutes
var int dimLevel = 100 // Start from 100
var Timer_Up timer = null // Initialise timer to null
?
You got it