How to write rule templates?

I’m using OpenHab 3.0 M3 in docker and I like to write rule templates. But where can I create one?

There is no menu in the UI. Can they be written as a file? But where must they be located?

I understand that I can publish them in the forum but where can I develop them? Also I could not find any hint in the docs.

If a rule templates is instantiated in a rule, is this a copy of the template code or a reference? I assume if I change the template code all rules based on that template will automatically be updated.

Thank you!

The UI is in work so at this point you have to create templates by hand. It’s not super hard and you have two options: YAML or JSON.

YAML

The easiest thing to do is to write it as a rule for testing. Go to the “code” tab and copy the YAML and save it to a “.yaml” file.

Then you need to modify the top part to convert it from a Rule to a Rule Template.

For example, given (I’ve removed most of the rule part for brevity):

configuration:
  script: alarm_script
  alarmTime: AlarmClock
triggers:
  ...
conditions: []
actions:
  ...

replace the “configuration” part the Rule Template information. For example,

uid: rules_tools:alarm_clock
label: Schedules a timer to run a script
description: This will trigger on an update to a DateTime Item and schedule a timer to call another script at the DateTime's state.
configDescriptions:
  - name: alarmTime
    type: TEXT
    context: item
    filterCriteria:
      - name: type
        value: DateTime
    label: Alarm Time Item
    required: true
    description: Item that holds the date and time to run the script.
  - name: script
    type: TEXT
    context: rule
    label: Script to Call
    required: true
    description: The Script or Rule to call at the alarm time.
  • Choose a unique UID. Yannick and Kai use their names as the first part. I use “rules_tools” because I’ve already established an “openhab_rules_tools” repo where I host libraries and will host my rule templates.

  • Create a meaningful label

  • Create a short description of the purpose of the template.

  • configDescriptions is where you define the properties that the user will need to set when creating a new Rule from this template.

  • Modify the triggers, conditions, and actions to use the configs. For the moment it uses ${name} where “name” is the name of the parameter to do the find and replace. However there are problems with that syntax and I don’t know if we have a solution or alternative yet.

Definitely look at the templates already posted to the Marketplace for more examples.

JSON

It’s pretty much exactly the same as the YAML only it uses JSON encoding instead of YAML. When using JSON I recommend writing the rule, querying for it in the REST API to get the JSON (or copy it straight out of the JSONDB files). And as above, replace the top part of the rule with the rule template info and modify the triggers, conditions, and actions to use the configuration parameters.

NOTE: A single field in JSON cannot extend multiple lines which means the code of Script Actions and Script Conditions have to be all on the same line. That makes working with JSON really awkward.

An example JSON formatted template might look like:

  {
    "uid":"rules_tools:mqtt_eb_online",
    "label":"ONLINE Status Publisher",
    "description":"Publishes ONLINE as a retained message to the LWT topic.",
    "configDescriptions":[
      {
        "name":"broker",
        "type":"TEXT",
        "context":"thing",
        "label":"MQTT Broker Thing",
        "description":"Select the MQTT Broker Thing used for the MQTT Event Bus",
        "required":true
      },
      {
        "name":"topicRoot",
        "type":"TEXT",
        "label":"openHAB Instance Name",
        "description":"Name of this openHAB instance, used as the root of the topic structure.",
        "required":true
      }
    ],
    "triggers": [
      {
        "id":"1",
        "label":"Broker Thing changes to ONLINE",
        "description":"",
        "configuration": {
          "thingUID":"${broker}",
          "status":"ONLINE"
        },
        "type":"core.ThingStatusChangeTrigger"
      }
    ],
    "conditions": [],
    "actions": [
      {
        "inputs": {},
        "id": "2",
        "label":"Publish ONLINE to the LWT topic as retained",
        "configuration": {
          "type":"application/javascript",
          "script":"var Log = Java.type('org.openhab.core.model.script.actions.Log');\nvar topic = '${topicRoot}/status';\nLog.logInfo('MQTT_EB', 'Publishing online message');\nvar mqtt = actions.get('mqtt', '${broker}');\nmqtt.publishMQTT(topic,'ONLINE', true);"
        },
        "type":"script.ScriptAction"
      }
    ]
  }

Again, there are a number of examples already published to the Marketplace. Learn from those.

As far as I can tell right now there is no way to write a rule template locally. You have to create the template, publish it to the Marketplace and then you can select and install it. Remember this is just released and is probably at best an alpha level feature. There is a lot of work left to do.

Ultimately I would expect one could write a JSON file in $OH_CONF/automation and I also expect a UI to be developed. But neither are supported yet.

It’s a copy. If the template changes, one needs to delete and recreate the rule from the template to pick up the changes.

Thank you for this extensive answer!
It would be very useful if the template is not a copy but more like a method invocation. This way one could write a template and reuse it for multiple use cases e.g. washing machine, dryer and dishwasher state. Changes in the logic would then only be needed in the template. Ok that is not the way they work for now. But even the current behavior helps.

You can file an issue but based on my limited understanding on how the rules engine works I don’t think that’s possible,

One may counter with what if they don’t want the changes to apply to all three but only the first two? What if the template does almost exactly what you need but it needs some slight customization for the washing machine? What if you want to wait to update the washing machine but need to apply the changes to the dryer now?

If the three truly are using the same logic, that also implies that the rule is a candidate to be modified so that the same rule instance can handle all three rather than instantiating three copies of the same rule.

There are trade offs either way. Often when there are trade offs like this, the developers error on the side of greatest flexibility.