Rules with а while loop & Thread::sleep - how to do it right?

Hi.
I have a “Soft Awake” cron rule, it works, but when its running i see a gap in my graphs.
OH 1.8.3

var int Dimmer = 1
Light_Bed_DIM.sendCommand(Dimmer)
Thread::sleep(60000) 
while ( (Dimmer = Dimmer + 1) <= 100 ) {
	if (Light_SoftAwake.state == ON && Light_SoftAwakeCancel.state == OFF) {
		Light_Bed_DIM.sendCommand(Dimmer)
		Thread::sleep(10000)
	}
}
... another dimmer next

May be another way for this rule is exists?

What triggers this rule? What is being charted?

It doesn’t make sense that the Sleep would be preventing your persistence from running. Is it just those two Items or all Items? It is hard to tell with the other Items on the chart.

You could implement this using my Recursive Timers Design Pattern.

It would look something like (using Timers instead of the Expire binding):

import org.eclipse.xtext.xbase.lib.Functions
import java.util.Map

val Map<String, Timer> timers = newHashMap

val Functions$Function3<DimmerItem, Map<String, Timer>, Functions$Function3, Timer> createDimmerTimer = 
[dimmer, timers, createDimmerTimer |

    // create a timer for 10 seconds
    createTimer(now.plusSeconds(10), [|

        // Reset the Timer to null in the map
        timers.put(door.name, null)

        // reschedule the timer if needed
        val Number curr = dimmer.state as Number
        if(Light_SoftAwake.state == ON && Light_SoftAwakeCancel.state == OFF &&  curr < 100){
            curr = curr + 1
            dimmer.sendCommand(curr)
            timers.put(dimmer.name, dimmerTimer.apply(dimmer, timers, createDimmerTimer))
        }
    ]
]

rule "Soft Awake"
when
    // Some event
then
    timers.put(LightBed_DIM, timers, createDoorTimer)
end

This is not what I would call a clean solution, but it will eliminate the Thread::sleeps and presumably fix those gaps.

But it would be a lot more satisfying to know why those gaps are there in the first place.

The theory of operation above is there is a lambda that returns a Timer. We store this Timer ina Map (see the link to the design pattern to understand why). When the Timer goes off, it checks to see if it is supposed to increment the Dimmer. If so it increments the Dimmer and then creates a new Timer by recursively calling the lambda again. Once it reaches a state where it should no longer be incrementing the Dimmer (Light_SoftAwake.state != ON || Light_SoftAwakeCancel.state == ON || current Dimmer value == 100) the Timer no longer gets recreated and dies away.

Cron triggers this rule Time cron "0 */5 2-9 * * ?".
Temperatures of my heating system is charted. All sensors is using MQTT.
Gap on all charts, all items.
I cheked logs - all cron based rules stops for this time (i dont use ReentrantLock in this rule).

I need more time to understand your approach with lambdas.:slight_smile:
Expire Binding is great, i start using it right now.

Thank you rlkoshak.

It is very very odd that everything stops loading at this time. the Thread::sleep should have not impact on those at all. Have you run any further tests to verify that it is indeed the Thread::sleep that is causing the problem? I’m a little skeptical that it is but if it is this needs to be filed as a bug.