Millisecond Rule Triggers

Hi all,

I have been testing how fast I can get rules to trigger at regular intervals. The fastest I can get a rule to trigger is every second using CRON based timer triggers as shown in the code below.

rule Example_Rule
when 
     Time cron "0/1 * * * * ?" 
then
   // Do Something  
end

I understand that executing rules based on milliseconds could cause block threads but that is what I want to test, to see how openHAB handles this strain.

Is there anyway in openHAB to get millisecond precision with rule triggers?
If there is not a way to get millisecond precision is there something preventing this and is there any plan to add this in a new release for openHAB?

It was never intended as a real time system. I can’t think of a polite way to put “you’re on a hiding to nothing” :wink:

openHAB cron triggers are handled by quartz scheduler
http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html
so you’d need that to support milliseconds.

Thanks for the link. So all openHAB timers are associated with this quartz scheduler? That does not support millisecond precision from the documentation only up to seconds.

I know cron was not supposed to be used for millisecond accuracy but is there any other openHAB solution that does not rely on cron that you know of or are all timers and rules in openHAB limited by the cron limitations of precision?

Perhaps you can explain the end result you’re trying to achieve. That might help others suggest alternative approaches.

No, because they’re not all cron triggered. It’s a last resort really, for the few times an event-driven system needs to do something by the clock.

There are delay functions in rules with arguments in milliseconds, for the occasions when you need to do A shortly before B, e.g. simulate a button press on-off, but again it is not a real time system and I wouldn’t expect accuracy sub-100mS - depending on your hosting.

If you’re just trying to stress test, trigger six rules at once and let the system sort it out, just like real life.

Hi Mark,

I am working on a project that will control and monitor smart devices in house’s and testing openHAB as a possible hub to be used within the setup. The system will be required to log values of voltage every few milliseconds to a database, I have the devices setup to monitor voltages but now it is just about how quick I can get this information to a database and how quick openHAB can act upon certain changes in the setup. For example if a voltage goes above a certain level how quick can openHAB act upon this to turn off/on a device.

The solution I am after in this post is if I can schedule jobs every few milliseconds within openHAB’s rule system or is this beyond its capabilities.

Yeah I am in the process now of setting up rules to log different item (voltage, power, current etc) to a database at the same time and try to work of the timestamps to see how much the deviation is.

Wrong system for that. I don’t think you’ll find any other home automation system that’s any good as a datalogger at that level either. You need a screwdriver for this, not a hammer.

If it’s that important, you’ll want that to be standalone local device anyway. Online “fuses” aren’t predictable enough.

Thanks for the information.

It’s ok if openHAB cant handle this but the goal is more to push it as far as it can handle and document this. Apart from CRON is there any other timer that openHAB uses to trigger rules, you mentioned delays above but from my understanding they are not used to trigger rules. Correct me if I am wrong instead they are used inside the block of code the rule executes?

Ah, its an academic thesis.

Have you read the docs? Rules are triggered by events, of which cron is only one. Generally you would be looking for external device events or UI events, you can leverage those. If you want to write some external script that fires simulated events at penHAB at 50mS intervals, you can.

Yes delays are for employment within rules. You can of course trigger a rule fires another event, and then another event after a short delay, then some other event after a further delay, etc.

That’s a rubbish measure of openHAB’s effectiveness; it’s not what its for, not what it’s good at. It’s not a datalogger.

Just an off-the cuff thought

Why not use arduino or PIC devices locally to the sensor to monitor and control the system you are monitoring and just send the data back to Openhab or whatever to store and display it over time.

Yep final year electrical engineering

Yeah I have a rule set up based upon the voltage state change that I have been testing but I need regular intervals of measurement.

Yeah I have been interfacing with the REST API through scripting to some success but I wanted to see if openHAB itself could be used so I don’t run into any threading issues and managing threads myself instead seeing if openHAB could handle this through the threads it creates for its rules.

Thats ok if thats not what its used for I am just testing it capabilities in this situation, if you have any suggestions of any other tests I am open to suggestions the more help the better.

I’m not sure to be totally honest what advantages would this have? To explain the setup I currently have is a raspberry pi 3 running openHAB 2.5.2. The data is being stored on an external MySQL server where openHAB is acting as a way to retrieve this data from devices and control these devices.

An external script is currently logging this data to the external MySQL server, querying the MySQL server and interfacing with the REST API to send commands to the devices configured in openHAB.

I wanted to see if openHAB could operate as quickly as an external script to do these operations internally within openHAB to avoid the problem of setting up my own threads and just using openHAB’s rules. There will be no need for the external scripts or reduced need.

Possibly the external script could be just used for capturing data and then only use openHAB to act upon this data example turning device on/off?

One thing you could try…

Note: I wouldn’t recommend this under any circumstances other than a test or experiment.

import java.util.concurrent.TimeUnit
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.Executors
import java.lang.Runnable
import java.util.concurrent.Future;

val Runnable doIt = [|
    logInfo("DoIt", "Do something!!")
]

var Future<?> job = null
val ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1)

rule "Start It"
when
    Item DoIt received command ON
then
    if (job === null) {
        job = scheduler.scheduleAtFixedRate(doIt, 0L, 500L, TimeUnit.MILLISECONDS);
    }
end

rule "Stop It"
when
    Item DoIt received command OFF
then
    if (job !== null) {
        job.cancel(true)
        job = null
    }
end

Edit: Replace the 500L with the interval (in milliseconds) with which you want your job to run.

Edit 2: I should add that I didn’t think I’d be able to do this in a rule, but it works (at least the rule to start the job). I haven’t tried stopping it yet (but then there’s always systemctl stop openhab2. LOL.

1 Like

Ok, I guess I’m not clear on the capability of the devices you are measuring, I was assuming dumb sensors. If they are already capable of logging data and sending it then you are right no need for additional hardware, but then how critical is the time to switch the device based on data received.

I.e if its critical the device acts in milli-seconds, (say to prevent a burn-out), then you really want that done at the sensor/switch point, thats not what OH is designed for. If you want OH to collect and monitor data, and its ok if the action to control the remote device is a couple of seconds later then sure get rid of the intermediate DB.

Its a matter of priority, logging voltages that often to make a critical decision isn’t for software its for firmware IMHO

This works and the rule executes every few milliseconds, does this constantly reserve one thread to execute the job on using that Executors.newScheduledThreadPool(1) or do threads start to build up and clog the system if this is running every few milliseconds?

Yeah I just rebooted my hub and had the rule commented out to stop it :rofl: but I could do this based upon a switch of some sort hopefully to trigger the Stop It rule.

I’m not 100% sure, but I think it will queue up the executions if the execution time of the job exceeds the execution interval.

It’s all standard java, which you can read about here.
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html

1 Like

That’s the purpose of the DoIt item. Define the item as a Switch, then send that item ON and OFF commands from the karaf console.

I guess its not as critical that the device acts in milliseconds, the data logging would be more important but it will be to a MySQL server located on another machine.

Thanks for the help, I will test it out and see how it holds up!