How to disable a rule from a Blockly script?

I have some rules that disable other rules and later re-enable them. This works fine, but it has also led to quite a number of rules.

So, I would like to tidy up things a bit by using more Blockly scripts that handle this enabling and disabling of rules internally. (The advantage of this kind of setup is also that I can easily see when a rule is running, waiting to reenable a disabled rule.)

The problem is: I can’t seem to figure out how to enable/disable a rule from a Blockly script. Is it possible?

It looks like it would be possible to run a rule that disables/enables another rule, but that complicates rather than simplifies things…

How do you that in these rules? If I know that, I can tell you how this would/could be possible from blockly.

Oh, that sounds promising!

This is how I currently enable/disable rules:

The above shows the rule that enables another rule. Correspondingly, there is another rule that disables it.

Well, somewhat with a few hacks…

From 4.x on, you can use jsscripting (graalvm) which automatically provides the rules-variable and then you can use the script-block to basically call that:

image

rules.setEnabled(‘myruleid’, true);

with the current Nashorn support underneath it would be also possible but it is more complicated. It requires the “ruleManager” which is not automatically provided only in the case you use this block:

image

which adds the following code

function addFrameworkService (serviceClass) {
  var bundleContext = Java.type('org.osgi.framework.FrameworkUtil').getBundle(scriptExtension.class).getBundleContext();
  var serviceReference = bundleContext.getServiceReference(serviceClass);
  return bundleContext.getService(serviceReference);
}

var ruleManager = addFrameworkService('org.openhab.core.automation.RuleManager');

ruleManager.setEnabled(‘1_filter_map_reduce_blockly’, true);

but it would be pretty ugly to only add that block which does nothing (in fact it generates an exception as it tries to execute that isn’t thee) only to have access to the ruleManager.

Instead, what you can do is to add that whole code to a seperate script block and the enable/disable as many rules as you like:

1 Like

Thank you so much, this works just fine.

But I’m having second thoughts about moving various rules (i.e. rules that are only needed under certain circumstances) into Blockly scripts. Those thoughts don’t concern functionality but rather efficiency (and, if you wish, code aesthetics). Looking at the script below, I wonder how resource intensive this loop is when it checks the state of two items every second.

I assume that the loop that is built into the core of OH3 and which is checking for events that trigger rules is running at a much higher frequency, so checking every second is probably rather slow. So depending on how the two sloops relate to each other, I may even be saving resources compare to doing the same using two rules, but I have no clue, really.

I just have a feeling that this could be done in a more elegant way, e.g. if events could be “pushed” into the script, as it were, instead of it constantly checking.

So, to ask a question that may be relevant to also for other users: What would be some rules of thumb when implementing an event-based “trigger” in a Blockly script, i.e. a loop that waits for an event/ change of state?

The first rule is, of course: don’t check the state more often than necessary for the purpose at hand. But what else should one consider?

For example, I suppose there is no difference between the loop above and the following one (using until instead of while?

You should not use a loop but rather use triggers (see Rules - Basic | openHAB) to what for a change and then react on it.

Never use a loop with a wait …

Not sure if I’m missing something, but those triggers are not available in a Blockly script, are they?

Sure, most of the rules have triggers, here is the config screen of a blockly rule

and see Rules Blockly - Before Using | openHAB

and I highly recommend you watch the videos here: Rules Blockly | openHAB

Oh, yes, those videos are very helpful. I always watch the relevant parts when I’m stuck with a specific question. Of course, Blockly scripts can be triggered by, well, a trigger condition. But what I’m looking for here is how to wait for an event once the rule has been triggered, i.e. inside the script… I don’t think any of that is mentioned in the videos (or the documentation).

I may not understand your usecase

  • you wait for an event to trigger the blockly rule
  • and then you want to wait for another event in the rule itself?

Yes, exactly!

Then create the first rule that is triggered by the first event which enables the second rule which waits for the second event.

Oh, that strategy didn’t cross my mind at all because the task of the second rule is turned on a third rule (which the first one turned off), but yes, this would obviously work. (It sounds a bit like a state machine…)

But what is the benefit of having two rules rather than one?

After all, I started this topic because I wanted to reduce the number of rules and simplify things:

The “benefit” is that you must not wait in a rule - rules must not implement blocking behaviour but should finish as quickly possible.

If by “wait”, you mean this:

Arc-2023-02-19 at 22.58.12@2x

I understand that this is costly, which is why I asked:

If this is the same as the delay() function on Arduino, then I also understand that we want to avoid this because it blocks the entire thread (or whatever the equivalent to the main Arduino loop is here).

But we don’t need to use wait. We can also use a timer. I believe a timer is non-blocking.

So, if we use a looped timer to check for the item state from within a single rule, what would be the benefit of having two rules instead?