I’m not so sure that as this is implemented this would work very well even if persistence were able to keep up, which won’t ever be the case.
I’m also very concerned about that 5 second sleep. You only get five Rule threads. That means only five Rules can run at the same time. With that set of log statements you would have the following take place:
- Rule triggers 1253.76, sleeps for five seconds
- Rule triggers 3399.6800000000003 sleeps for five seconds
- Rule triggers 5591.04 sleeps for five seconds
- Rule triggers 4590.08 sleeps for five seconds
- Rule triggers 2570.2400000000002 sleeps for five seconds
- Rule can’t trigger for 1475.84 because all five threads are in use, waits to trigger
- Rule can’t trigger for 558.72 because all five threads are in use, waits to trigger
- about 4.5 seconds later the first Rule completes, second to last Rule triggers
- about 4.5 seconds later the second Rule completes, last Rule triggers
I don’t think that is desired behavior.
OH is not a real time system and the order of processing of events and the timeliness of that processing is not guaranteed when events occur this close together. I could definitely see MySQL or the add-on dropping all values until it remains the same for at least half a second. If the value is changing that fast, it is unlikely that you would want to save any but the last value to persistence as that’s the value most likely to have meaning.
So, you will not be able to achieve what you are after using persistence.
Looking at the values it looks like the voltage ramps up and then drops. It also looks like it raises by at least 1000 at each reading when you press the button. So why not just look to see if the current state is greater than 1000 more than the previous state and add a debounce?
var Timer Klingel_timer = null
rule "Klingel_Info"
when
Item Klingel_Spannung changed
then
if(Klingel_timer != null) return; // if there is a timer, we've already detected the press so ignore the event
if(Klingel_Spannung.state as Number >= (previousState as Number) + 1000){
sendNotification("xxx@msn.com","Ding Dong")
// Choose an appropriate debounce time (i.e. amount of time to ignore changes)
Klingel_Spannung = createTimer(now.plusSeconds(5), [ | Klingel_Spannung = null]) // the Timer doesn't need to do anything
}
end
The first time the voltage changes by 1000 or more we send the notification and create a Timer for five seconds. For the next five seconds we ignore all the changes to the voltage Item. Then the first time after the Timer expires that the voltage changes by 1000 or more we do it all again.