Callback / wait for other rule


I have a rule which fetches an image thru an API and stores is in a Image Item.

Other rules like alarm and doorbel make use of the ‘get image rule’ via sendCommand. I want the parent rule to wait for the Image to be updated.

I see two approaches:

  • Callback / wait on the ‘get image rule’
  • Create a while loop for the Image Item to be updated

I prefer the first, but havent find a way to do it. Is there a callback/wait posible with sendCommand ?

What binding do you use to fecth the image?
You can use a Thread::Sleep(time in ms)
in the rule if it takes only a few seconds
If it takes longer then maybe a timer will be better.
Can you post your items and rules, please?

Elaborate on this a bit. Do you mean that if a rule wants to get the image but another rule is currently running to get the image you want that second rule to wait its turn?

If that is the case see Design Pattern: Gate Keeper

If not, then please provide more information.

I want the image as soon as posible, therefore using a timer would be risky. Therefore a direct lock after the remote rule has executed would be preferable.

I have a rule which fetches the latest known image from the Synology Survailenace station api and places this in an Image Item.

rule "Haal laatst bekende bewegende foto op van de NAS"
    Item Synology_Haal_Image_Op received update
    if (Synology_Haal_Image_Op.state == "voordeur") {
        var String auth = sendHttpGetRequest("", 10000)
        logInfo("Synology", "Authoriseer naar Synology api" + auth)
        var String json = sendHttpGetRequest("", 10000)
        var String image = transform("JSONPATH", "$[0].imageData", json)
        Synology_Image_Voordeur.postUpdate('data:image/jpeg;base64,' + image)
        logInfo("Synology", "Snapshot van Synology gehaald en in image item gezet.")

This rule is triggered from various other rules like doorbel, alarm ext.

import java.util.concurrent.TimeUnit

rule "Als er op de deurbel wordt gedrukt, voer diverse zaken uit."
	Item MQTT_Deurbel changed to ON
	// Hue woonkamer op Alert
	sendCommand(Hue_Alert_Woonkamer, ON)
	sendCommand(Synology_Haal_Image_Op, "voordeur") {
		sendTelegramPhoto("haastrecht_openhab_bot", Synology_Image_Voordeur.state.toFullString, "Er wordt op de deurbel gedrukt, zie foto.")
		logInfo("MQTT Deurbel", "Laatste snapshot foto via telegram verstuurd.")

As you noce I’m currently using a timer, but I want to be absolutely sure it’s the last image. I’m thinking about doing a while loop until the LastUpdate time of Synology_Image_Voordeur has been updated.

But I thought, If there’s a callback on the sendCommand it would be even better.

The DP I linked to above does just what you are looking for. It locks the Rule that gets the Item so only one copy of it can execute at a given time. The example has a sleep in because the DP was written to address cases where sending commands too fast to wireless devices can cause commands to be lost. In your case you wouldn’t necessarily need the sleep.

Don’t block in rules where possible. If you have to block, is should be no longer than half a second. If you block for longer, particularly in a case like this where one Rule will be blocking waiting for another Rule to finish running that is itself long running or blocking then you will run out of execution threads. There are only 5 available meaning you can only have five rules running/blocking at a given time. Once you run out no rules will execute.

Even with the Gatekeeper DP you might run into this problem but it minimizes it because your calling Rule will not also be blocking waiting for the Image to be retrieved.

To get your callback you will need to send a command to some other Item that kicks off another Rule that deals with whatever your current Rule does once the Image is done being loaded.

1 Like

Thank you @rlkoshak for the indepth explanation. I will read into the DP.