openHAB version: 2.5M2 installed from repository with apt
Issue of the topic: Device not responding to command when several commands sent in one rule
I have a Sonoff RF Bridge that has been flashed with Tasmota Firmware
I have several decorative lighting fixtures with EL CHEAPO rf switches bought from Ali Express
I configured the RF Bridge as a Generic MQTT device
It has 3 channels,
one saves received messages to a Text Item
The other two are linked to Switch items
It works pretty well.
I have a rule
rule "Sparkley Darkley Jars OFF"
when
Time cron "0 0 23 * * ?"
then
logInfo("SonoffRFBridge", "Sparkley Darkies turned off")
SonoffRFBridge_SparkleyDarkleyJar01.sendCommand(OFF)
SonoffRFBridge_SparkleyDarkleyJar2.sendCommand(OFF)
end
When the rule fires, the commands are sent successfully
When I monitor MQTT, both commands are sent and the Sonoff Bridge reports the expected response.
Only The first fixture turns off. The second fixture remains on.
Manually toggling the switches in Paper UI, iOS client, Homekit Bridge works fine.
I have the same issue when creating an automation in Homekit.
My initial attempt using a wait(1) inbetween the sendCommand(OFF) seems to hang and the second command is not seen in MQTT.
There is no command wait() in openHAB, instead (only as a first test!) use Thread::sleep(1000) (this is 1000 Milliseconds)
so the rule looks like
rule "Sparkley Darkley Jars OFF"
when
Time cron "0 0 23 * * ?"
then
logInfo("SonoffRFBridge", "Sparkley Darkies turned off")
SonoffRFBridge_SparkleyDarkleyJar01.sendCommand(OFF)
Thread::sleep(1000)
SonoffRFBridge_SparkleyDarkleyJar2.sendCommand(OFF)
end
As this rule will only trigger once a day, Thread::sleep() would be ok with such a big value. A better solution would be to use a timer to wait, but in this case it might be a little overengineered…
This works as expected.
Whether the issue is in the Sonoff RF Bridge or the EL CHEAPO rf switches is out of scope of OpenHAB.
Thank you very much.
A Thread method reference may be over engineered, but as a work-around it’s good enough.
Thanks
Oh no, Thread::sleep() is the only way to wait in a rule. A timer would be more complex:
var Timer tTimer = null // define global vars at the top of the file
rule "rule with timed sleep"
when
Time cron "0 0 23 * * ?"
then
tTimer?.cancel // kill any existing timer
logInfo("SonoffRFBridge", "Sparkley Darkies turned off")
SonoffRFBridge_SparkleyDarkleyJar01.sendCommand(OFF)
tTimer = createTimer(now.plusSeconds(1), [|
SonoffRFBridge_SparkleyDarkleyJar2.sendCommand(OFF)
])
end
The difference is, Thread::sleep() will pause the Thread (and the Thread keeps occupied) where the Timer code will be scheduled. the Rule will end immediately, and the timer is executed at the scheduled time.