Rule, Timer & Startup

I am currently runing OH3.2. I need to have a script, running at sytem start, which collects some IP addresses. Even when set the trigger in the rule to system level 100 it looks like, that it does not work 100%. So tried to create a timer, to delay the execution for 30s after the trigger.

The code:
createTimer(now.plusSeconds(30), [ |
logInfo(“Systemstart”, “Startlevel 100 + 30s, Aktionen beginnen”)
])

When this is part of a rule, it gives an error:
Script execution of rule with UID ‘Startup’ failed: :23:35 Expected an operand but found |
createTimer(now.plusSeconds(30), [ |
^ in at line number 23 at column number 35

The same code copied into a script runs perfectly. Any idea, what I am doing wrong?

Thomas

Can we see the whole rule? (Use ‘code’ tab)

You also might want to see this recent solution to a similar issue:

I’m going to guess you’ve selected ECMAScript for the script language but the code posted is Rules DSL and obviously won’t work.

Unless he just wants to delay his JS rule by 30s using a DSL rule. Then it should work. UI is mandatory.

complete rule:

configuration: {}
triggers:

  • id: “1”
    configuration:
    startlevel: 100
    type: core.SystemStartlevelTrigger
    conditions: []
    actions:

  • inputs: {}
    id: “2”
    configuration:
    type: application/javascript
    script: |
    createTimer(now.plusSeconds(30), [ |
    logInfo(“Systemstart”, “Startlevel 100 + 30s, Aktionen beginnen”)
    GosundSP101_STATUS5.sendCommand(“5”)
    S20Keller_STATUS5.sendCommand(“5”)
    Slampher01_STATUS5.sendCommand(“5”)
    Slampher02_STATUS5.sendCommand(“5”)
    SonoffB11_STATUS5.sendCommand(“5”)
    sonoffgbx3_STATUS5.sendCommand(“5”)
    SonoffPOWR2_STATUS5.sendCommand(“5”)
    SonoffS2001_STATUS5.sendCommand(“5”)
    AntenneR1_STATUS5.sendCommand(“5”)
    AntenneR2_STATUS5.sendCommand(“5”)

      GosundSP101_IP.state = GosundSP101_STATUS5.state
      S20Keller_IP.state = S20Keller_STATUS5.state
      Slampher01_IP.state = Slampher01_STATUS5.state
      Slampher02_IP.state = Slampher02_STATUS5.state
      Sonoff_B1_1_IP.state = SonoffB11_STATUS5.state
      sonoffgbx3_IP.state = sonoffgbx3_STATUS5.state
      SonoffPOWR2_IP.state = SonoffPOWR2_STATUS5.state
      SonoffS2001_IP.state = SonoffS2001_STATUS5.state
      AntenneR1_IP.state = AntenneR1_STATUS5.state
      AntenneR2_IP.state = AntenneR2_STATUS5.state
    
    ])
    

    type: script.ScriptAction

it is a DSL-Rule and I forgot to mention that it works in another setup running OH 3.1

No it’s not. You selected ECMAScript 5.1 when you created the Action. You either need to change that to Rules DSL or you need to change your code to be JSR223 JavaScript.

ok 1:0

I finally found the little difference, after setting up the rule again and then comparing the code. “application/javascript” and not “application/vnd.openhab.dsl.rule”.

As I have never worked with ECMAScript before, I must have just not clicked exactly on the selection. As the editor looks the same, I have never noticed that. Thanks for your help.

Thomas

one additional question: what is the appropriate time to wait after startup, until the script can run safely?

I have extended the time to 2 mins, however, after startup the items with _IP have still the value NULL. I then startet the startup script manually abt. 50 mins after startup, now the values are correct.

That is going to be totally based on your system. No one can give you a general answer to that. It depends on the hardware, other stuff that’s running at the same time, RAM, installed bindings, etc.

Thanks, does that mean, that it is generally unreliable to do certain init things with a rule triggered by start level 100?

It depends on what you want to do in such a rule, and whether that rule depends on certain Things being online.

It might be the case that something is wrong (e.g. the MQTT broker is down, Zwave controller is unplugged, etc) and no amount of waiting will be enough.

However, if the system started rule doesn’t depend on anything external or even Items being in a certain state, it will work every time.

If your rule depends on a Thing’s status, consider triggering the rule when the Thing comes online instead of a System started role. Things generally come online after the rule engine has started.

ok, thanks.

That means for initialising items from things, I need one rule per thing (which fires, when the thing goes online after startup).

For all items, which are defined OH internally (e.g. to save certain states), I can do it just at start level 100.

Correct?

You don’t necessarily need one rule out Thing. Again it depends on what your rule does and what it’s means when a Thing comes online for that rule.

The danger goes for the Item’s. It depends on what the rule does with/to the items and whether there’s any external dependencies involved. For example, if the rule expects the items to restoreOnStartup using InfluxDB but InfluxDB is down, the Items will not have been restored when the rule runs.

Again, there is no universal answer here. You have to know and understand what the dependencies are to answer that question.

again, thanks for the explanation.

What I want to achieve with the startup script is the following: I have integrated several Tasmota devices via MQTT. As these devices have an internal browser, sometime the ip address is important. Unfortunaley, OH sees the ip address only, when the Tasmota devices is bootet after OH. I have learned, that the “Status5” reads the IP address back, so the goal is, to get the address shortly after an OH reboot (which I do every night, after a system backup).

Maybe there is better approach to this.

Thomas

Trigger the rule when the MQTT broker thing changes to ONLINE.

If supported, have Tasmota publish that message as retained.

Use restoreOnStartup and assume the ip hasn’t changed unless you get that message later.

Set up static IPs for you devices so you don’t have to query for their IPs.

Thanks, I will look in that direction

I use this rule to fetch the status of my tasmota devices when OH is restarted.

configuration: {}
triggers:
  - id: "3"
    configuration:
      thingUID: mqtt:broker:d0a861377f
      status: ONLINE
    type: core.ThingStatusChangeTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      blockSource: <xml xmlns="https://developers.google.com/blockly/xml"><block
        type="mqtt_publish" id="q{vkM4L-5R)|rIn)U[3`" x="-1361" y="77"><field
        name="RETAIN">FALSE</field><value name="MESSAGE"><shadow type="text"
        id="vuC%Vj:3N?[7d]C(4ejT"><field name="TEXT">status
        5</field></shadow></value><value name="TOPIC"><shadow type="text"
        id="Teg_1ZXa.L~A3lLgOvIt"><field
        name="TEXT">cmnd/tasmotas/backlog</field></shadow></value><value
        name="BROKER"><shadow type="oh_thing" id="gw7,35,I;90JkDodD[7V"><field
        name="thingUid">mqtt:broker:d0a861377f</field></shadow></value></block></xml>
      type: application/javascript
      script: >
        var things = Java.type('org.openhab.core.model.script.actions.Things');



        things.getActions('mqtt', 'mqtt:broker:d0a861377f').publishMQTT('cmnd/tasmotas', 'status 5', 'FALSE' === 'TRUE');
    type: script.ScriptAction

On your tasmota devices the group topic should be the default “tasmotas” !

Sorry there is a typo, it should be

things.getActions('mqtt', 'mqtt:broker:d0a861377f').publishMQTT('cmnd/tasmotas/backlog', 'status 5', 'FALSE' === 'TRUE');

and off course you have to change the broker id.