You’ve encountered a file based rule on the forum or as an example in the docs for an add-on and you want to use that rule as a managed rule (i.e. in the UI). Or maybe you want to translate a rule from one language to another. This tutorial should give you the tools you need to understand and identify the parts of a rule.
How to recognize a file based rule
The general format of a file based rule is going to be different based on the language it’s written in. But overall they will all have the overall structure of:
[rule start]
[triggers]
[action]
where
[rule start]
is some symbol to indicate the start of a rule[triggers]
is a list of those events that will cause the rule to trigger[action]
is a block of code that will be executed when the rule triggers.
There can be other things that are part of the definition of a rule such as the rule UID, description, tags, etc.
Rules DSL Example
rule "My rule"
when
Member of MyGroup received command ON or
Item Foo changed to OFF
then
logInfo('test', "My rule was triggered!")
end
In the above:
[rule start]
: `rule"[triggers]:
Member of MyGroup received command ONand
Item Foo changed to OFF`[action]
:logInfo('test', "My rule was triggered!")
Everything else serves as separators or adding more information about the rule.
JS Scripting Examples
JS Scripting has two ways to create a rule.
JSRule
rules.JSRule({
name: "My rule",
description: "An example rule",
triggers: [triggers.GroupCommandTrigger('MyGroup', 'ON'),
triggers.ItemStateChangeTrigger('Foo', 'OFF')],
execute: (event) => {
console.info("My rule was triggered!");
},
tags: [],
id: "MyRule"
});
In the above:
[rule start]
:rules.JSRule({
[triggers]
:triggers: [triggers.GroupCommandTrigger('MyGroup', 'ON'),triggers.ItemStateChangeTrigger('Foo', 'OFF')],
[action]
:console.info("My rule was triggered!");
Unlike with Rules DSL, JS Scripting provides the ability to set the rule UID and add a description and tags.
Rule Builder
rules.when()
.memberOf('MyGroup').receivedCommand('ON').or().item('Foo').changed('OFF')
.then(() => { console.info("My rule was triggered!"); })
.build('My rule')
In the above:
[rule start]
:rules.when()
[triggers]
:.memberOf('MyGroup').receivedCommand('ON').or().item('Foo').changed('OFF')
[action]
:console.info("My rule was triggered!");
jRuby
rule "My rule" do
received_command MyGroup.members, command: ON
changed Foo, to: OFF
run { logger.info 'My rule was triggered!' }
end
In the above:
[rule start]
:rule
[triggers]
:received_command MyGroup.members, command: ON
andchanged Foo, to: OFF
[action]
:logger.info 'My rule was triggered!'
How to recoginze a managed rule
Managed rules will either be posted showing only the action meaning it will only include the code executed as part of the action.
If the full rule is posted it will appear as YAML with each of the parts of the rule clearly labeled. Don’t worry, you won’t be writing this YAML manually.
configuration: {}
triggers:
- id: "1"
configuration:
itemName: MyGroup
command: ON
type: core.ItemCommandTrigger
- id: "2"
configuration:
itemName: Foo
state: OFF
type: core.ItemStateChangeTrigger
conditions: []
actions:
- inputs: {}
id: "3"
configuration:
type: application/javascript
script: console.log("My rule was triggered!");
type: script.ScriptAction
If just a block of code is posted, unless otherwise indicated, that’s the rule’s [action]
.
You will notice a new section here called conditions
. This is a place you can add some checks to see whether the actions should run when it’s triggered. Not all file based rules have a concept of conditions and we will ignore that for now.
How to translate a file based rule to a managed rule
Let’s say we found the following code somewhere and we want to create it as a managed rule.
rule "My rule"
when
Member of MyGroup received command ON or
Item Foo changed to OFF
then
logInfo('test', "My rule was triggered!")
end
The first step is to identify the language of the rule. In this case the overall structure of the code and the presence of when
, then
and end
points to this being a Rules DSL rule.
- Navigate to Settings → Rules → +
Your screen may look different if you’ve not installed any rule templates. Rule templates can be installed from the marketplace and instantiated. Why write rules someone else has already written for you? But further discussion of rule templates is outside the scope of this tutorial.
- Change the Rule ID to something meaningful. Create a human friendly Label and add a Description and tags as desired.
- Click the green + next to “add trigger” and create a triggers that correspond to the triggers in the original file based rule.
-
Click the green + next to “add action”, select “Inline script” and “Rule DSL” as the language (in this case, if your original code is a different language, choose that language). Paste the “action” portion of the code into the text editior that comes up. Click “save”.
-
Click “save” or hit
ctrl-s
to save the rule.
What if there is a global variable?
Often times one will see en example code that references a variable defined outside of the rule. Usually these “global” variables are defined at the top of the file or the posted example. But with a managed rule there is no outside the rule so there is no place to define these variables.
In these cases, you need to move the global variable to the cache. If there is only one rule that uses variable, use the private cache. If more than one uses it use the shared cache. See the reference docs for the language you are using for more details.
What if the “code” is a picture of Blockly?
-
Ask the original poster to click on the code tab of the rule and paste the YAML they find there. Use code fences:
code goes here
-
Copy the YAML to the clipboard.
-
Create a new rule and fill in the UID, label, description and tags same as described above. Save the rule.
-
Click on the “code” tab and paste the contents of the clipboard and hit save. Return to the “design” tab and you can now edit the triggers and blockly code as needed.