Inserting delays in commands during a rule

Hi

Yet again the Drools engine syntax has floored me.

I've got a simple rule running that monitors my doorbell button.

Using the WebTTS app from Google Play I can get OpenRemote to make my phone (or other Android device) to 'Speak' or play a chime.

Everything works well, until I try to cascade commands to a single device.

Speech commands can be sent consecutively and the app will stack them.

However if I send a MP3 play command, followed by a "say" command, they both play together.

I will ask the writer of the app to offer a stack feature for files, but is it possible to simply put a delay in the command stack within a rule?

this works :-

{code}
    if (isActive)
    {
// execute.command("TextToSpeech_Kristi-param", "There is someone at the front door"); // Uncomment to send command
        execute.command("Stu_S7-Play-param", "doorbell/Doorbell-sound-tubular-chimes.mp3");
        execute.command("Stu_S7-door", ""); // Uncomment to send command
        execute.command("TextToSpeech_Stu_S7-param", "Rush to the door and open it quickly"); // Uncomment to send command
{/code}

but this crashes my rules :frowning:

{code}
    if (isActive)
    {
// execute.command("TextToSpeech_Kristi-param", "There is someone at the front door"); // Uncomment to send command
        execute.command("Stu_S7-Play-param", "doorbell/Doorbell-sound-tubular-chimes.mp3");
  timer (int: 5s)
        execute.command("Stu_S7-door", ""); // Uncomment to send command
        execute.command("TextToSpeech_Stu_S7-param", "Rush to the door and open it quickly"); // Uncomment to send command
{/code}

many thanks

Stuart

You can use:

TimeUnit.MILLISECONDS.sleep(5000);

for 5s delay.

Kind regards,

Michal

Thanks Michal

I'll drop it in and let you know what happens.

Cheers :slight_smile:

Thanks for the help Michal,

I dropped it into the sequence and it worked like a charm.

The only problem is that the sequence is still playing by the time I get to the door :wink:

So I've just removed the delay and the sound file.

Hi

I am new to rules. I am trying to setup a simple rule where in if the switch status is “ON”, wait 5 secs and then issue a command to turn it off. This is what i have so far but it is giving an error. I tried using the TimeUnit.MILLISECONDS.sleep(5000); before and after the “then” statement but neither seems to work. i am sure i am doing something very obviously wrong. Any help will be greatly appreciated.

in both cases the error seems to be related to the sleep statement

Below is what i have in the rules area in the designer:

package org.openremote.controller.protocol

global org.openremote.controller.statuscache.CommandFacade execute;
global org.openremote.controller.statuscache.SwitchFacade switches;

rule “turn off switch” when

Event( source == “SwitchSensor”, value == “on” )
TimeUnit.MILLISECONDS.sleep(5000);
then

execute.command( “remotec command off” );

end

Hi

I'm certainly no expert, but give this a try...

{Code}
package org.openremote.controller.protocol;

global org.openremote.controller.statuscache.CommandFacade execute;

import java.util.*;
import java.util.regex.*;

rule "Turn switch off"
when
    $evt:Event(source matches "SwitchSendor", $source : source) // NOTE SENSOR NAME IS WHAT IS BEING COMPARED HERE
then
    String buttonStatus = $evt.getValue().toString();
    boolean isActive = buttonStatus != null && buttonStatus.equalsIgnoreCase("On");

    System.out.println("Switch Status Change '" + $source + "': " + buttonStatus);

    // EXECUTE ANY COMMANDS BY USING THEIR NAME AND VALUE TO SET
    // ADD ADDITIONAL COMMANDS AS REQUIRED

    if (isActive)
    {
// execute.command("remotec command off" ); // Uncomment to send command

TimeUnit.MILLISECONDS.sleep(5000);

       execute.command("remotec command off" );
    
    }
    else
    {
// execute.command("something else", ""); // Uncomment to send command

// execute.command("command that requires a variable", "OFF");
    }
end

{/Code}

Hi,

the rule should read:

rule “turn off switch”

timer (int: 5s)

when

Event( source == “SwitchSensor”, value == “on” )
then

execute.command( “remotec command off” );

end

thanks! that worked

Hi

I've just just a slightly modified version of this lovely rule to stop my Android app drawing down another Gig of data in the background :frowning:

I've put a webview element in a client's design to view a choice of their CCTV camera feeds.

Using an in memory command to select the camera URL, a web view uses the sensor to get the URL.

The only problem was that the app keeps pulling down the data until the app is completely closed :frowning:

Bang goes a gig of data in a very short time.

So...

This little rule sets the in memory value to null after 20 seconds.

rule "Clear CCTV URL"
timer (int: 20s)
when
Event( source == "CCTV_URL")
then

execute.command( "CCTV_Front", "null" );

end

Hi Michael

trying to see how i can enhance this application - is there a way to insert a delay between pressing of a button and executing the associated command? to explain the requirement better, after i press the button to open the garage door, i want delay of 5 mins before it actually open the garage door- i.e. executes the command to the Remotec switch to close and the associated rule you helped with below to close it?

Thanks

For short delays (up to a second) you can try to use TimeUnit.MILLISECONDS.sleep() function, but it has disadvantage that it stops the rules engine thread for this time and other rules cannot be evaluated in parallel. The correct way of doing this would be

declare DelayCommand
    command : String
end

rule "Crate command"
when
   Event("your button press event")
then
   insert(new DelayCommand("your actual door open command"));
end

rule "Expression timer"
    timer(int: 5m) // This can be made dynamic in a new Drools version in controller 2.5 with timer(expr: $d, $p)
                   // where $d, $p can be set in the when part
when
    $d: DelayCommand( $c : command )
then 
  execute.command($c);
  retract($d);
end 

thanks for you reply Michael and please forgive my ignorance with but how do i find out what is the event tied to “your button press event”? I have included my config files- if you point me in the right direction i would greatly appreciate

ui_state.xml (13.8 KB)

panel.xml (4.33 KB)

controller.xml (11.3 KB)

building_modeler.xml (26.4 KB)

You don’t have it yet. What you need to do is define in-memory virtual command with ‘on’ command. This one you will link with a button on your UI. Then you need to define second in-memory virtual command with command ‘status’ and the same address as the first one. Then you create sensor “your button press event”, type custom, and link it with the second defined command. Also, you will need to modify slightly the rule:

rule "Crate command"
when
   Event("your button press event", value=="on")
then
   insert(new DelayCommand("your actual door open command"));
   execute.command("your second in-memory virtual command name", "off");
end

HI

any idea why add a second rule as below breaks my first rule (seems like the controller goes in to a pause mode or something). With just the first rule, it has been working great. When i add the second rule, the Remotec switch stay ON and neither of the rules seem to get executed

package org.openremote.controller.protocol

global org.openremote.controller.statuscache.CommandFacade execute;

global org.openremote.controller.statuscache.SwitchFacade switches;

rule “turn off switch”

timer (int: 2s)

when

Event( source == “SwitchSensor”, value == “on” )

then

execute.command( “remotec command off” );

end

// for auto turn ON/OFF Dimmer when door opens/closes

rule "turn on gdoor light”

when

Event( source == “Garage door sensor”, value == “255” )

then

execute.command( “MONOPRICE_DIMMER_ON” );

end

rule "turn off gdoor light”

when

Event( source == “Garage door sensor”, value == “0” )

then

execute.command( “MONOPRICE_DIMMER_OFF” );

end

You can look into logs/boot.log file to see if the rule file is free of syntax errors. If your example is pure copy paste then you have a mix of " and ” characters, which are not the same. Only the first ones are allowed.

Thanks for your reply Michal. there are a bunch of errors in the boot log file with regards to the rules- i cant really tell what the source of the error is though. I have attached the boot log file. may be you can see something obvious that i am missing. Does it not like spaces in the sensor names?

boot.log (28.7 KB)

Michal has already spotted a potential problem for you.

[quote]

If your example is pure copy paste then you have a mix of " and ” characters, which are not the same. Only the first ones are allowed.

[/quote]

Thanks guys would have never guessed. I started writing the rule on a noted on MAC which probably added those different type of quotes. For anyone else who runs in to similar, issue this link explains it well. After i read it, what Michal stated made complete sense.

http://in.relation.to/2009/11/21/be-aware-of-using-doublequotes-when-writing-drools-decision-tables/