diff --git a/Rules.md b/Rules.md index e9ae5878..3908fc65 100644 --- a/Rules.md +++ b/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) - [Trigger](#Rule-trigger) - [Command](#Rule-command) - [Variables](#Rule-variables) -- [Rule Cookbook](Rule-Cookbook) +- [Rule Cookbook](Rule-Cookbook) (_Sample rules_) + ## 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)). -*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.** +>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`.* ## Rule Syntax +**"IF/ELSE" statements, combining triggers with AND/OR, and nested rules are not supported.** + Every rule needs to follow this syntax: -`on do endon` +`ON DO [ENDON | BREAK]` +- **`ON`** - marks the beginning of a rule definition +- **``** - what condition needs to occur for the rule to execute +- **`DO`** - what the rule is to perform if the `` 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`](Commands#rule) command. After defining a rule set, you have to enable it (turn it on) using `Rule 1`. Similarly you can disable the rule set using `Rule 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. -**``** is what needs to occur for the rule to execute the `` +Rules inside a rule set `Rule` are concatenated and entered as a single statement. +`Rule ON DO ENDON ON DO ENDON ...` -**`do`** is the separator between the `` and `` - -**`endon`** marks the end of that rule. It can be followed by another rule. - -Alternatively you can end the rule with `break`.
-**`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`](Commands#rule) command. After defining one you have to enable the rule set (turn it on) using `Rule 1`. Similarly you can disable the rule set using `Rule 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 do endon on do 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 do break on do endon -``` +Spaces after `ON`, around `DO`, and before `ENDON` or `BREAK` are mandatory. A rule is **not** case sensitive. ### Rule Trigger -A rule trigger can consist of: -``` -[TriggerName]#[ValueName] -[TriggerName]#[ValueName][comparison][value] -[SensorName]#[ValueName] -[SensorName]#[ValueName][comparison][value] -Tele-[SensorName]#[ValueName] -``` +A rule trigger can consist of: +- `[TriggerName]#[ValueName]` +- `[TriggerName]#[ValueName][comparison][value]` +- `[SensorName]#[ValueName]` +- `[SensorName]#[ValueName][comparison][value]` +- `Tele-[SensorName]#[ValueName]` -Comparison operators are: +A rule's trigger clause **must _not_ contain spaces**. + +Comparison operators: |Operator|Function| |:-:|:--| @@ -72,17 +60,17 @@ Comparison operators are: |`<=`| lesser than or equal to| |`\|`| 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 | -------------------|-------------| +------------------|----------------| 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:
`0` = OFF
`1` = ON
`2` = TOGGLE
`3` = HOLD Clock#Timer=3 | when global `Timer3` is activated -Dimmer#Boot | occurs after Tasmota starts +Dimmer#Boot | occurs after Tasmota starts 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. -Mem#State | when the value for Mem\ is changed +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#State | when the value for Mem\ is changed Http#Initialized Mqtt#Connected | when MQTT is connected Mqtt#Disconnected | when MQTT is disconnected @@ -92,7 +80,7 @@ Rules#Timer=1 | when countdown `RuleTimer1` expires Switch1#Boot | occurs after Tasmota starts Switch1#State | when a switch changes state:
`0` = OFF
`1` = ON
`2` = TOGGLE
`3` = HOLD
(`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#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>120 | once, 120 seconds after NTP is initialized and time is in sync Time#Minute | every minute @@ -103,24 +91,28 @@ Var\#State | when the value for Var\ is changed Wifi#Connected | when Wi-Fi is connected 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. - -To trigger only at TelePeriod time, prefix the sensor with the word `Tele-`. +Connected sensors can be a trigger in the form as they are represented in the `TelePeriod` and `Status 8` JSON payloads. 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| |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| |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 | -------------------|-------------| -|SerialReceived#Data=\| whenever \ is received via hardware serial| -|SSerialReceived#Data=\| whenever \ is received via software serial| +------------------|----------------| +|Tele-AM2301#Temperature|sensor AM2301 Temperature value when the TelePeriod JSON payload is output| + +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=\| whenever \ is received via hardware serial| +|SSerialReceived#Data=\| whenever \ is received via software serial| |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| |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 -A rule command can be any command listed in the [Commands list](Commands). That command `` 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 `` 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 DO Backlog ; ; 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: -    Existing Rule1: `on Rules#Timer=1 do Mem2 %time% endon` +    Existing Rule1: `ON Rules#Timer=1 DO Mem2 %time% ENDON` -    Rule to append: `on button1#state do POWER TOGGLE endon` +    Rule to append: `ON button1#state DO POWER TOGGLE ENDON` -    Command: `Rule1 + on button1#state do POWER TOGGLE endon` +    Command: `Rule1 + ON button1#state DO POWER TOGGLE ENDON` -    Resulting Rule1: `on Rules#Timer=1 do Mem2 %time% endon on button1#state do POWER TOGGLE endon` +    Resulting Rule1: `ON Rules#Timer=1 DO Mem2 %time% ENDON ON button1#state DO POWER TOGGLE ENDON` ### 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. - -They provide a means to store the trigger `%value%` to be used in any rule. +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. The value of a `Var` and `Mem` can be: - any number @@ -167,32 +154,18 @@ The value of a `Var` and `Mem` can be: - %sunrise% - %sunset% -To set the value for `Var` and `Mem` use the command -``` -Var -Mem -``` -The `` can also be the value of a trigger of that rule. +To set the value for `Var` and `Mem` use the command +- `Var ` +- `Mem ` -`on AM2301#Temperature do var2 %value% endon` -
-Sets Var2 to the temperature of the sensor AM2301 - -`on Event#temp do var4 %var2% endon` -
-Sets Var4 to Var2's value - -`on Rules#Timer=1 do Mem2 %time% 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` -
-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:*. - -  -  - -**For examples of various rules see the [Rule Cookbook](Rule-Cookbook).** - -[Back To Top](#top) \ No newline at end of file +The `` can also be the value of the trigger of the rule. +- Set Var2 to the temperature of the AM2301 sensor - `ON AM2301#Temperature DO Var2 %value% ENDON` +- 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` +- 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`. + ``` + Rule1 + 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 + ```