No spaces in trigger

Michael Ingraham 2019-08-25 23:47:32 -04:00
parent 61e8ce6f70
commit 036320f2d4
1 changed files with 73 additions and 100 deletions

173
Rules.md

@ -1,65 +1,53 @@
Tasmota provides a Rule function heavily inspired by the ESP Easy implementation. Rules expand the functionality of Tasmota with flexible and user configurable rules while maintaining a small memory footprint. Automation solutions can be implemented without having to add dedicated code or use external solutions. Tasmota provides a Rule feature heavily inspired by the _ESPEasy_ implementation. Rules expand the functionality of Tasmota with flexible and user configurable logic while maintaining a small memory footprint. Automation solutions can be implemented without having to add dedicated code or use external solutions.
- [Rule Syntax](#rule-syntax) - [Rule Syntax](#rule-syntax)
- [Trigger](#Rule-trigger) - [Trigger](#Rule-trigger)
- [Command](#Rule-command) - [Command](#Rule-command)
- [Variables](#Rule-variables) - [Variables](#Rule-variables)
- [Rule Cookbook](Rule-Cookbook) - [Rule Cookbook](Rule-Cookbook) (_Sample rules_)
<a id="top"></a> <a id="top"></a>
## Introduction ## Introduction
Rules perform actions based on triggers (f.e. switch state change, temperature threshold, events like system boot, a defined timer elapsing, custom defined events, etc). They are stored in flash and therefore will survive a reboot. Rules perform actions based on triggers (e.g., switch state change, temperature threshold, events like system boot, a defined timer elapsing, custom defined events, etc.) They are stored in flash and therefore will survive a reboot.
>Most pre-compiled binaries have the Rules feature enabled (the exception being sonoff-minimal.bin and sonoff-classic.bin [builds](Builds)). >Most pre-compiled binaries ([builds](Builds)) have the Rules feature enabled. The exception being `sonoff-minimal.bin` and `sonoff-classic.bin`. *If you are compiling your own firmware, in order to use rules, include `#define USE_RULES` in `user_config_override.h`.*
*If you are compiling your own firmware, `define USE_RULES` has to be enabled in `user_config_override.h` in order to use rules.*
**Currently no "IF" directive or nested rules are supported.**
## Rule Syntax ## Rule Syntax
**"IF/ELSE" statements, combining triggers with AND/OR, and nested rules are not supported.**
Every rule needs to follow this syntax: Every rule needs to follow this syntax:
`on <trigger> do <command> endon` `ON <trigger> DO <command> [ENDON | BREAK]`
- **`ON`** - marks the beginning of a rule definition
- **`<trigger>`** - what condition needs to occur for the rule to execute
- **`DO`** - what <command> the rule is to perform if the `<trigger>` condition is met
- **`ENDON`** - marks the end of a rule. It can be followed by another rule.
- **`BREAK`** - marks the end of a rule. `BREAK` will stop the execution of the remaining rules that follow this rule within the rule set. If a rule that ends with `BREAK` is triggered, the following rules in that rule set will not be executed. This allows the rules to somewhat simulate an "IF/ELSE" statement.
**`on`** marks the start of a new rule. Rule sets are defined by using the [`Rule<x>`](Commands#rule) command. After defining a rule set, you have to enable it (turn it on) using `Rule<x> 1`. Similarly you can disable the rule set using `Rule<x> 0`.
See [Commands](Commands#Rules) for a complete list of rules related commands.
There are three separate rule sets called `Rule1`, `Rule2` and `Rule3`. Each rule set can contain as many rules as can fit within the 511 character limit. Whenever a rule set is enabled all the rules in it will be active.
**`<trigger>`** is what needs to occur for the rule to execute the `<command>` Rules inside a rule set `Rule<x>` are concatenated and entered as a single statement.
`Rule<x> ON <trigger1> DO <command> ENDON ON <trigger2> DO <command> ENDON ...`
**`do`** is the separator between the `<trigger>` and `<command>` Spaces after `ON`, around `DO`, and before `ENDON` or `BREAK` are mandatory. A rule is **not** case sensitive.
**`endon`** marks the end of that rule. It can be followed by another rule.
Alternatively you can end the rule with `break`.<br>
**`break`** will stop the execution for all the triggers that follow this rule inside the rule set. If a trigger that ends with `break` occurs, the following triggers of that rule set will not be executed. This allows the rules to somewhat simulate an "IF THEN ELSE" statement.
Rule sets are defined by using the [`Rule<x>`](Commands#rule) command. After defining one you have to enable the rule set (turn it on) using `Rule<x> 1`. Similarly you can disable the rule set using `Rule<x> 0`.
> See [Commands](Commands#Rules) for a complete list of rules related commands.
There are 3 separate rule sets called `Rule1`, `Rule2` and `Rule3`. Each rule set can contain as many rules as can fit within the 511 character limit. Whenever a rule set is enabled all the rules in it will be active.
Rules inside a rule set can be concatenated and have to be in one line:
```on <trigger1> do <command> endon on <trigger2> do <command> endon ...```
Spaces after `on`, around `do` and before `endon` or `break` are mandatory. A rule is **not** case sensitive.
Example of defining rule set:
```
Rule1 on <trigger1> do <command> break on <trigger2> do <command> endon
```
### Rule Trigger ### Rule Trigger
A rule trigger can consist of: A rule trigger can consist of:
``` - `[TriggerName]#[ValueName]`
[TriggerName]#[ValueName] - `[TriggerName]#[ValueName][comparison][value]`
[TriggerName]#[ValueName][comparison][value] - `[SensorName]#[ValueName]`
[SensorName]#[ValueName] - `[SensorName]#[ValueName][comparison][value]`
[SensorName]#[ValueName][comparison][value] - `Tele-[SensorName]#[ValueName]`
Tele-[SensorName]#[ValueName]
```
Comparison operators are: A rule's trigger clause **must _not_ contain spaces**.
Comparison operators:
|Operator|Function| |Operator|Function|
|:-:|:--| |:-:|:--|
@ -72,17 +60,17 @@ Comparison operators are:
|`<=`| lesser than or equal to| |`<=`| lesser than or equal to|
|`\|`| used for [modulo operation](https://en.wikipedia.org/wiki/Modulo_operation) with remainder = 0 (exact division)| |`\|`| used for [modulo operation](https://en.wikipedia.org/wiki/Modulo_operation) with remainder = 0 (exact division)|
Some of available triggers: Some of available triggers:
Trigger | When it occurs | Trigger | When it occurs |
------------------|-------------| ------------------|----------------|
Analog#A0div10 | when the `A0` input changes by more than 1% it provides a value between 0 and 100 Analog#A0div10 | when the `A0` input changes by more than 1% it provides a value between 0 and 100
Button2#State | when a button changes state:<br>`0` = OFF<BR>`1` = ON<BR>`2` = TOGGLE<BR>`3` = HOLD Button2#State | when a button changes state:<br>`0` = OFF<BR>`1` = ON<BR>`2` = TOGGLE<BR>`3` = HOLD
Clock#Timer=3 | when global `Timer3` is activated Clock#Timer=3 | when global `Timer3` is activated
Dimmer#Boot | occurs after Tasmota starts<a id="ADC0"></a> Dimmer#Boot | occurs after Tasmota starts<a id="ADC0"></a>
Dimmer#State | when the value for Dimmer is changed Dimmer#State | when the value for Dimmer is changed
Event#User | when command `Event User` is executed. You can define your own event values and trigger them with the `Event`](commands#event) command. Event#eventName | when command `Event eventName` is executed. You can define your own event values and trigger them with the [`Event`](commands#event) command.
Mem<x>#State | when the value for Mem\<x\> is changed Mem<x>#State | when the value for Mem\<x> is changed
Http#Initialized Http#Initialized
Mqtt#Connected | when MQTT is connected Mqtt#Connected | when MQTT is connected
Mqtt#Disconnected | when MQTT is disconnected Mqtt#Disconnected | when MQTT is disconnected
@ -92,7 +80,7 @@ Rules#Timer=1 | when countdown `RuleTimer1` expires
Switch1#Boot | occurs after Tasmota starts Switch1#Boot | occurs after Tasmota starts
Switch1#State | when a switch changes state:<br>`0` = OFF<BR>`1` = ON<BR>`2` = TOGGLE<BR>`3` = HOLD<BR>(`SwitchTopic 0` must be set for this to trigger) Switch1#State | when a switch changes state:<br>`0` = OFF<BR>`1` = ON<BR>`2` = TOGGLE<BR>`3` = HOLD<BR>(`SwitchTopic 0` must be set for this to trigger)
System#Boot | occurs once after MQTT is initialized. Due to the command execution order it cannot occur earlier than that. System#Boot | occurs once after MQTT is initialized. Due to the command execution order it cannot occur earlier than that.
System#Save | executed just before a planned restart System#Save | executed just before a planned restart
Time#Initialized | once when NTP is initialized and time is in sync Time#Initialized | once when NTP is initialized and time is in sync
Time#Initialized>120 | once, 120 seconds after NTP is initialized and time is in sync Time#Initialized>120 | once, 120 seconds after NTP is initialized and time is in sync
Time#Minute | every minute Time#Minute | every minute
@ -103,24 +91,28 @@ Var\<x>#State | when the value for Var\<x> is changed
Wifi#Connected | when Wi-Fi is connected Wifi#Connected | when Wi-Fi is connected
Wifi#Disconnected | when Wi-Fi is disconnected Wifi#Disconnected | when Wi-Fi is disconnected
Connected sensors can be a trigger in the form as they are represented in the `TelePeriod` or `Status 8` JSON message. Connected sensors can be a trigger in the form as they are represented in the `TelePeriod` and `Status 8` JSON payloads.
To trigger only at TelePeriod time, prefix the sensor with the word `Tele-`.
Trigger | When it occurs | Trigger | When it occurs |
------------------|-------------| ------------------|----------------|
|Tele-AM2301#Temperature|triggers on the TelePeriod time for the sensor AM2301| |DS18B20#Temperature| whenever the temperature of sensor DS18B20 changes|
|DS18B20#Temperature<20| whenever the temperature of sensor DS18B20 is below 20 degrees| |DS18B20#Temperature<20| whenever the temperature of sensor DS18B20 is below 20 degrees|
|AM2301-12#Humidity==55.5| whenever the humidity of sensor AM2301-12 equals 55.5%| |AM2301-12#Humidity==55.5| whenever the humidity of sensor AM2301-12 equals 55.5%|
|INA219#Current>0.100| whenever the current drawn is more than 0.1A| |INA219#Current>0.100| whenever the current drawn is more than 0.1A|
|Energy#Power>100| whenever the power used is more than 100W| |Energy#Power>100| whenever the power used is more than 100W|
Hardware and software serial interface, RF or IR are also supported based on their [JSON](JSON-Status-Responses) status message: To trigger only at TelePeriod time, prefix the sensor with the word `Tele-`.
Trigger | When it occurs | Trigger | When it occurs |
------------------|-------------| ------------------|----------------|
|SerialReceived#Data=\<string\>| whenever \<string\> is received via hardware serial| |Tele-AM2301#Temperature|sensor AM2301 Temperature value when the TelePeriod JSON payload is output|
|SSerialReceived#Data=\<string\>| whenever \<string\> is received via software serial|
Hardware and software serial interface, RF, or IR are also supported based on their [JSON](JSON-Status-Responses) status message:
Trigger | When it occurs |
------------------|----------------|
|SerialReceived#Data=\<string>| whenever \<string> is received via hardware serial|
|SSerialReceived#Data=\<string>| whenever \<string> is received via software serial|
|IrReceived#Data=801| whenever an IR signal for a RC5 remote control button 1 is received| |IrReceived#Data=801| whenever an IR signal for a RC5 remote control button 1 is received|
|IrReceived#Data=0x00FF9867|whenever an IR signal with hex code 0x00FF9867 is received| |IrReceived#Data=0x00FF9867|whenever an IR signal with hex code 0x00FF9867 is received|
|RfReceived#RfKey=4| whenever the [RF Bridge](Sonoff-RF-Bridge-433) receives a recognized RfKey 4 signal |RfReceived#RfKey=4| whenever the [RF Bridge](Sonoff-RF-Bridge-433) receives a recognized RfKey 4 signal
@ -129,32 +121,27 @@ Trigger | When it occurs |
### Rule Command ### Rule Command
A rule command can be any command listed in the [Commands list](Commands). That command `<parameter>` can be replaced with `%value%` which will use the value of the trigger. A rule command can be any command listed in the [Commands list](Commands). The command's `<parameter>` can be replaced with `%value%` which will use the value of the trigger.
```on Switch1#State do Power %value% endon``` `ON Switch1#State DO Power %value% ENDON`
To accomplish a rule with one trigger but several commands, you need to use `Backlog`: To accomplish a rule with one trigger but several commands, you need to use `Backlog`:
`ON <trigger> DO Backlog <command1>; <command2>; <command3> ENDON`
```on [trigger] do backlog [command1]; [command2]; [command3] endon``` **Appending a rule onto an existing rule set**
**Appending a rule onto an existing rule set**
Use the `+` character to append a new rule to the rule set. For example: Use the `+` character to append a new rule to the rule set. For example:
&nbsp;&nbsp;&nbsp;&nbsp;Existing Rule1: `on Rules#Timer=1 do Mem2 %time% endon` &nbsp;&nbsp;&nbsp;&nbsp;Existing Rule1: `ON Rules#Timer=1 DO Mem2 %time% ENDON`
&nbsp;&nbsp;&nbsp;&nbsp;Rule to append: `on button1#state do POWER TOGGLE endon` &nbsp;&nbsp;&nbsp;&nbsp;Rule to append: `ON button1#state DO POWER TOGGLE ENDON`
&nbsp;&nbsp;&nbsp;&nbsp;Command: `Rule1 + on button1#state do POWER TOGGLE endon` &nbsp;&nbsp;&nbsp;&nbsp;Command: `Rule1 + ON button1#state DO POWER TOGGLE ENDON`
&nbsp;&nbsp;&nbsp;&nbsp;Resulting Rule1: `on Rules#Timer=1 do Mem2 %time% endon on button1#state do POWER TOGGLE endon` &nbsp;&nbsp;&nbsp;&nbsp;Resulting Rule1: `ON Rules#Timer=1 DO Mem2 %time% ENDON ON button1#state DO POWER TOGGLE ENDON`
### Rule Variables ### Rule Variables
There are 10 available variables (double precision reals) in Tasmota, `Var1` through `Var5` and `Mem1` through `Mem5`. All `Var` will be empty strings when the program starts. The value of all `Mem` persists after a reboot. There are ten available variables (double precision reals) in Tasmota, `Var1..Var5` and `Mem1..Mem5`. All `Var` will be empty strings when the program starts. The value of all `Mem` persists after a reboot. They provide a means to store the trigger `%value%` to be used in any rule.
They provide a means to store the trigger `%value%` to be used in any rule.
The value of a `Var<x>` and `Mem<x>` can be: The value of a `Var<x>` and `Mem<x>` can be:
- any number - any number
@ -167,32 +154,18 @@ The value of a `Var<x>` and `Mem<x>` can be:
- %sunrise% - %sunrise%
- %sunset% - %sunset%
To set the value for `Var<x>` and `Mem<x>` use the command To set the value for `Var<x>` and `Mem<x>` use the command
``` - `Var<x> <value>`
Var<x> <value> - `Mem<x> <value>`
Mem<x> <value>
```
The `<value>` can also be the value of a trigger of that rule.
`on AM2301#Temperature do var2 %value% endon` The `<value>` can also be the value of the trigger of the rule.
<br> - Set Var2 to the temperature of the AM2301 sensor - `ON AM2301#Temperature DO Var2 %value% ENDON`
Sets Var2 to the temperature of the sensor AM2301 - Set Var4 to Var2's value - `ON Event#temp DO Var4 %Var2% ENDON`
- Set Mem2 to the current time (minutes elapsed since midnight) - `ON Rules#Timer=1 DO Mem2 %time% ENDON`
`on Event#temp do var4 %var2% endon` - After a Wi-Fi reconnect event, publish a payload containing timestamps of when Wi-Fi was disconnected in *From:* and when Wi-Fi re-connected in *To:* to `stat/topic/BLACKOUT`.
<br> ```
Sets Var4 to Var2's value Rule1
ON wifi#disconnected DO Var1 %timestamp% ENDON
`on Rules#Timer=1 do Mem2 %time% endon` ON wifi#connected DO Var2 %timestamp% ENDON
<br> ON mqtt#connected DO Publish stat/topic/BLACKOUT {"From":"%Var1%","To":"%Var2%"} ENDON
Sets Mem2 to the current time (minutes elapsed since midnight) ```
`on wifi#disconnected do var1 %timestamp% endon on wifi#connected do var2 %timestamp% endon on mqtt#connected do publish stat/topic/BLACKOUT {"From":"%var1%","To":"%var2%"} endon`
<br>
After a Wi-Fi reconnect event publish to stat/topic/BLACKOUT a payload containing timestamps of when the Wi-Fi disconnected in *From:* and when the Wi-Fi connected in *To:*.
&nbsp;
&nbsp;
**For examples of various rules see the [Rule Cookbook](Rule-Cookbook).**
[Back To Top](#top)