(SOLVED) Uninitialized var

Put all the lights into a Group. I’ll call it Lights. Then

rule "Set lights to OFF"
when
    System started
then
    createTimer(now.plusSeconds(30), [ | Lights.sendCommand(OFF) ])
end

The Timer should help to avoid that parallel loading problem.

But the question is why must they be OFF? Why not leave them as they are and only turn some ON or OFF if an automation event was missed (e.g. the time of day changed)? If you use retained messages for the commands, then when OH comes up it will immediately know what state the lights are supposed to be in if they are online. If they are offline then the lights will become that state when they come back online.

Like I described, just use a retained message when you command the light and the light will return to that state when it comes back online (e.g. in a power outage).

There is no such thing as “querying” in MQTT. There are either unretained messages in which case the client needs to be connected to receive the message, or retained messages in which case the client will receive the last published message even if it wasn’t connected when the message was sent.

So you want them to return to the last state they were commanded to from OH. That is exactly what a retained message would do.

Again, retained messages would solve this.

See Loop of flashing light inside a timer - #2 by rlkoshak

It’s not unreasonable, you are just going about achieving it the hard way.

This really isn’t OH’s job. Use the capabilities of MQTT to your advantage.

But even if it were OH’s job, you are still going about it the hard way. Another simple approach would be:

  • put all the lights into one Group, we’ll call it Lights
  • configure Lights* to be persisted on everyChange and restoreOnStartup
  • run a simple Rule at startup to sendCommand to the lights with the restored state from the database
rule "Restore lights"
when
    System started
then
    createTimer[now.plusSeconds(30) | Lights.members.forEach[ light | light.sendCommand(light.state) ]
end

To restore a light to it’s previously commanded state when it comes online (assuming you don’t use retained messages) you would need to get some sort of message to indicate that it has come online. You could look for the LWT message and then use the first message after that to indicate it has come back online to then sendCommand the Item’s current state in OH. Again, using Persistence the rule would look something like (using Design Pattern: Associated Items):

import org.eclipse.smarthome.model.script.ScriptServiceUtil

rule "Came back online?"
when
    Item Member of Lights changed
then
    val lwt = ScriptService.getItemRegistry.getItem(triggeringItem.name+"_LWT")
    hist = triggeringItem.previousState(true).getTimeStamp()
    if(lwt.lastUpdate.isAfter(hist)) triggeringItem.sendCommand(hist.state)
end

If the previous state of the Light that is different from the current state is before the most recent LWT message, this is the first message after the LWT so send the last state of the light back to the light.

NOTE: I just typed in these Rules, they likely contain errors.

That is something your device needs to implement and publish a message. There isn’t anything you can do from OH. MQTT doesn’t work that way.

If you have a Rule triggered with a changed trigger, then there will be a variable called previousState. This variable does not require Persistence.

It’s a long time bug that hasn’t been fixed.

It wouldn’t be bad but I think this entire approach to do what you are after is not the best way to achieve what you are after so I’m questioning whether it’s worth dealing with this particular problem in the first place.