- Platform information:
- Hardware: AMD Phenom II X4, 12GB Ram
- OS: Ubuntu 16.04
- Java Runtime Environment: Oracle Java 1.8.0_151
- openHAB version: 2.2.0 stable
Dear all,
I tried to write a rule today with a topic that I thought was quite easy. But actually it drives me nuts. I cancelled several approaches because each of them became a little complex in my opinion. So I was not sure if this is the right way or if there is a best practice for this. Maybe the rule experts among you have some hints.
Here’s the situation:
- I have a Number item without binding ->
sWzHelligkeit_State
- This item represents the status (3 different states possible) of the light level in a room
- There are 2 thresholds used to calculate the state out of a light sensor value
With the following items and rule this works fine
Number sWzHelligkeit { <some binding for lux sensor> }
Number sWzHelligkeit_State
Number sWzHelligkeit_Treshold1
Number sWzHelligkeit_Treshold2
rule "WzHelligkeitStatus"
when
Item sWzHelligkeit changed
then
val newValue = sWzHelligkeit.state as Number
val currState = sWzHelligkeit_State.state as Number
val threshold1 = sWzHelligkeit_Threshold1.state as Number
val threshold2 = sWzHelligkeit_Threshold2.state as Number
var newState
if (newValue < threshold2) { newState = 2 }
if (newValue > threshold2 && newValue < threshold1) { newState = 1 }
if (newValue > threshold1) { newState = 0 }
if (newState != currState) {
sWzHelligkeit_State.sendCommand(newState)
}
end
And now comes the headache
I want to expand this rule with a time delay to filter some short light peaks hitting the sensor (e.g. a car light)
- Only update the state item if sensor value is in the defined area for let’s say 30 sec
- if sensor value shows just a short peak -> do nothing
1. attempt -> timer:
- Start a timer instead of updating the state item
if (newState != currState) {
timerVar = createTimer(now.plusSeconds(30)) [|]
sWzHelligkeit_State.sendCommand(newState)
]
}
- Here I ran into issues with the variable scope ->
newState
is defined in the rule what leads to errors - Does it make sense to define the var
newState
as global in the ruiles file? - Or use a proxy item?
- And what’s about cancelling the timer when the sensor value drops back to where it came from?
2. attempt -> sleep:
- Use
Thread::sleep
before updating the state item - And then? Check all conditions again? (Copy&Paste same code?)
- Or calculate average or minimum with persistence?
if (newState != currState) {
Thread::sleep(30000)
// What to do here?
sWzHelligkeit_State.sendCommand(newState)
}
I think with a little bit more tweaking both attempts can do the thing. Just wanted to check what’s your solution for this. Maybe I’m missing something that makes it less complicated and/or w/o additional proxy items.
Looking forward to your suggestions.
Greetings
Sebastian