Extended Motion Sensor Rule: any Suggestions?

They are basic because they are posted with the intent that you will add to them and combine them with other posted examples.

Better to use

createTimer(now.plusMillis(500), [ | gLicht_Flur_Helligkeit.sendCommand(Par_Sollhelligkeit)])

over the Thread::sleep.

There are many approaches to avoid duplicated code. See Design Pattern: DRY, How Not to Repeat Yourself in Rules DSL. In particular, look at the Associated Items design pattern that let’s you access related Items based on their name. For example, replace all your copy and paste per room with:

    sendCommand("gLicht_"+Raum_Name+"_Farbtemerature", Par_Farbtemerature)
    sendCommand("gLicht_"+Raum_Name+"_Helligkeit", Par_Sollhelligkeit)

ReentrantLocks are super dangerous to use in Rules DSL. I cannot recommend their use under any circumstances.

Because you are almost certainly going to have other Rules that care about the time of day, it’s far better to code this as presented in the DP linked to above and put it in it’s own Rule and put the result into an Item. Then this Rule just needs to check the Item. It’s more efficient and easier to maintain.

See Associated Items DP (linked to in the DRY DP above) for how to name and easily extract the room name from the triggering Item. It also shows how to both sendCommand/postUpdate (examples above) and retrieve the state of an Item for which you’ve constructed it’s name.

These too could be put into Items and use Associated Items to get them by name. For something similar see Design Pattern: State Machine Driven Groups.

If you must use a lock, and you should go to great lengths to avoid it, at least put the code in a try/catch/finally so you have at least a chance that the lock get’s unlocked in case there is an error. In this case, use a HashTable instead of a HashMap. HashTable is thread safe and implements the locking for you. It’s safe to use library code that manages it’s own locks. In Rules DSL, certain errors can occur that never return to the Rule leaving your locks locked forever.

You can shorten the code that cancels and removes the timer to:

timers?.cancel
timers.put(Raum_Name, null)

Putting a null value removes the key so the remove is redundant.

But you don’t have to cancel and remove the Timer. Just reschedule it.

2 Likes