Using openHAB for complex time requirement

Let’s say you have a script that downloads live stock reports but it has to be during market hours only. It has to be only during Monday-Friday, and between market open at 8:30 a.m. and market close at 3:00 p.m. During these hours and days, we want to run the update script every three minutes. Based on the API limits of the stock data provider, it is critical that the script be called only during these dates and times.

Here is the rule to be run with the exec binding:

rule "StockUpdate"
when
Time cron "0 0/3 * * * ?"
then
    if (now.getDayOfWeek <= 5){
        if (new LocalTime().getLocalMillis() >= new LocalTime(08, 28, 0, 0).getLocalMillis()) {
            if (new LocalTime().getLocalMillis() <= new LocalTime(15, 10, 0, 0).getLocalMillis()) {
                executeCommandLine("/etc/openhab2/scripts/markets2.sh")
                logInfo("stocks", "completed bash script test.")
            }
        }
    }
end

Now let’s examine the above script. The trigger is cron which is set to check rule conditions every three minutes.

We are then going to do a series of nested if statements, all of which must be true to get to our actual script execution.

First, we need to make sure it is a weekday. So as long as the day of the week is not 6 or 7, then we are ok.
Next, we want to start running by 8:30 each morning, so we will set to start at 8:28 each weekday.
Next, we want to stop shortly after the close. It takes five to ten minutes for final prices to settle, so we will use 15:10 in military time.

If all these conditions are met, the script executes! While it may be possible to approximate this using only cron, this approach is far more accurate, easier to do, and more elegant.

1 Like

I don’t see how that is more accurate and easier than…

rule "StockUpdate"
when
Time cron "0 30/3 8 MON-FRI * ?"
Time cron "0 0/3 9-14 MON-FRI * ?"
then
    executeCommandLine("/etc/openhab2/scripts/markets2.sh")
    logInfo("stocks", "completed bash script test.")
end
1 Like

Do you mean:

rule "StockUpdate"
when
Time cron "0 30/3 8 1-5 * ?"
Time cron "0 0/3 9-15 1-5 * ?"
then
    executeCommandLine("/etc/openhab2/scripts/markets2.sh")
    logInfo("stocks", "completed bash script test.")
end

Either way they are non-standard cron expressions, at least according to:
Cronmaker:
http://www.cronmaker.com/
Crontab.guru
https://crontab.guru/#0_30/3_8_MON-FRI_?
https://crontab.guru/#0_30/3_8_1-5
_?

I have not tested these expressions in OH. Do they work?
I was running this script on another machine with cron and to get the start and end times, it was a long and convoluted expression and less precise:
1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,49,52,55,58 8,9,10,11,12,13,14,15 * * 1,2,3,4,5
With OH and cron, using the rule this way was far simpler, more precise (8:28-15:10), and more understandable.

openHAB uses Quartz, not standard cron. Standard cron doesn’t support seconds. The first field is seconds.

Use https://www.freeformatter.com/cron-expression-generator-quartz.html for a cron generator for openHAB.

//             Seconds | Minutes | Hours | Day of Month | Month | Day of Week | Year
    Time cron "0         30/3      8       ?              *       MON-FRI       *"  or // At second :00, every 3 minutes starting at minute :30, at 08am, every day between Monday and Friday, every month
    Time cron "0         0/3       9-14    ?              *       MON-FRI       *"     // At second :00, every 3 minutes starting at minute :00, every hour between 09am and 14pm, every day between Monday and Friday, every month

With Quartz you can get as precise as a second.

The first cron expression will run the Rule at 08:30, 08:33, 08:36 and so on until 08:57.

The second cron expression will run the Rule at 09:00, 09:33 and so on until 14:57.

If you want it to run at exactly 15:00 you will need to add one more cron expression:

    Time cron "0 0 15 ? * MON-FRI *"

Even with regular cron, this expression does not need to be this long and complicated.

I disagree. A rule like the above posted is excessively long, complex, and error prone. It’s slightly more straight forward only insofar as you don’t understand the cron syntax and were using the wrong cron builders.

The above cron expressions will be just as accurate as the rule, easier to do if you are aware of the correct cron builder, and much more elegant.

Elegant: pleasingly ingenious and simple.

1 Like

Thanks Rich! I thought cron in the code actually meant cron.

Here is the new script with the better code. It starts at 8:28 and goes until close to 1500 hours. Then it specifically runs at 1502 and again at 1505:

rule "StockUpdate"
when
Time cron "0 28/3 8 ? * MON-FRI *" or
Time cron "0 0/3 9-14 ? * MON-FRI *" or
Time cron "0 2 15 ? * MON-FRI *" or
Time cron "0 5 15 ? * MON-FRI *"
then
    executeCommandLine("/etc/openhab2/scripts/markets2.sh")
    logInfo("stocks", "executed bash script for financial markets update.")
end