Startup order of bundles and rules

Regarding the documentation of issue #1914 documentation the bundles should be loaded at startup level 10 and the rules at startup level 40 (and if “system started” rules are used, level 50).

But I still have some errors in my log when starting the OpenHAB 4.1.1 (docker) process. The 1st error comes from the telegram and the 2nd from the frigate bundle.

2024-01-22 08:46:59.194 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘meile-55’ failed: ‘sendTelegram’ is not a member of ‘org.openhab.core.thing.binding.ThingActions’; line 42, column 3, length 33 in meile

2024-01-22 08:47:31.965 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘meile-57’ failed: ‘TriggerEvent’ is not a member of ‘org.openhab.core.thing.binding.ThingActions’; line 2205, column 20, length 96 in meile

It looks like the bundles are not already loaded when the (DSL) rules are loaded and parsed. It’s not a real problem, because the rules will work later on but I try to understand why it happens and it would be nice to keep the logging clean without unnecessary errors/warnings to be able to make it easy to identify real problems.

If you look at the startup levels, Things are not initialized until start level 80. Both of these errors come from rules attempting to use an Action from a Thing that hasn’t been initialized yet. It’s not enough that the bundle be loaded, the Thing needs to be initialized and ONLINE too.

If these rules are triggered with a system started change to a system runlevel of 80 or greater. If these rules are not triggered with a system started or system runlevel trigger, you can use Delay Start [4.0.0.0;4.9.9.9] to disable those rules until a configured amount of time after runlevel 100 is reached, or Thing Status Reporting [4.0.0.0;4.9.9.9] to disable/enable the rules until the Things become ONLINE.

Wow, your rule has over 2200 lines?

Check for the thing status before calling the action should do the trick.

Jruby code:

thing = things["telegram:xxx:xxx"]
thing.send_telegram(...) if thing.online?

Will that work if the Thing doesn’t exist yet?

Depending on the system there can be seconds or more between runlevel 40 and runlevel 80.

It’s grown to this size over the course of 3 years and I still haven’t found time to split it…

I’ll give it a try!

These are really valuable tips to adjust startup handling! I’ll try them!

Are these openhab_rules_tools only available in JavaScript or is it possible to use them in DSL also?

Rules DSL does not support libraries.

But there is nothing about the rule templates linked to above that makes it so you have to stop using Rules DSL. But they are written in JS Scripting so you need to have JS Scripting and openhab_rules_tools installed to use them.

Maybe now is the right time to migrate my rules from DSL to JS - I’ve been putting this off for a while…

I have the feeling that new developments tend to only take place in JS. Even though DSL is (still) supported, it no longer seems to be the primary rule language to rely on for long-term projects.

Are there any features which JS may be missing but DSL provides (even in very rare cases) or can JS fully be used to replace DSL completely?

Blockly, jRuby, and HABApp all have very active development ongoing.

It was always a little awkward to work in and with implementation of Blockly it is no longer the easiest to pick up for non-programmer users. It’s also challenging to change and keep up with new features.

There is a lot that Rules DSL cannot do that JS Scripting can but there is nothing that can be done in Rules DSL that cannot be done in JS Scripting. This is also true of Blockly and jRuby. HABApp runs as a separate process so I think you need a work around to access Rule Actions.

Ok, thanks!

Even if I’m not a big fan of JavaScript, it seems that it’s the best option here (I’m more the Java guy - I know about Java rules addon but it’s not part of OH, so I don’t want to use it). Now, since OH using the solid and fast ECMAScript implementation from GraalVM and not longer the one based on Nashorn/Rhino, I think it’s a good choice.
Now I have a lot of work in front of me to port everything. I think I can migrate in steps while running DSL and JS rules in parallel.

Oops for that, one tiny adjustment is needed. if thing.online?if thing&.online?

i.e.:

thing = things["telegram:xxx:xxx"]
thing.send_telegram(...) if thing&.online?

JRuby has a built in “startup delay” feature, e.g.

rule "Do this on startup" do
  on_load delay: 1.minute
  run do 
    # do stuff here after 1 minute after the script is loaded
  end
end

Alternatively, there’s also a delay feature for any trigger

rule "send telegram 30 seconds after motion sensor" do
  changed Motion_Sensor, to: ON

  delay 30.seconds # This is not the same as sleep. It creates a wait timer for you
  run do
    # do something
  end

  # You can do more if needed
  delay 5.seconds
  run do
    # do another thing 5 seconds after the above execution block
  end
end

Or, one can trigger based on something changing to a certain state and staying in that state for a given amount of time

telegram_id = "telegram:xxx:xxx"
rule "send a telegram when thing has been online for 5 seconds" do
  changed things[telegram_id], to: :online, for: 5.seconds
  run do
    things[telegram_id].send_telegram(xxxx)
  end
end

All these without manually creating a timer yourself.

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.