Tasmota: IF/ELSE Rules Parsing Problem

Created on 27 Dec 2019  路  8Comments  路  Source: arendst/Tasmota

PROBLEM DESCRIPTION

Self-compiled with Gipod. I created a user_config_override.h with two lines:

#define USE_EXPRESSION
#define SUPPORT_IF_STATEMENT

When a rule uses a Command that assigns a value, the IF/ELSE rules parser is not recognizing the ELSE/ENDIF clauses and is assigning the entire statement as part of the value it passes to the command. For example:

ON Power2#State DO IF (%value%==0) Delay 20;Var2 0 ELSE Delay 20;Var2 1;Event LEDmd=1 ENDIF ENDON

When the (%value%==0) condition is TRUE, Var2 is assigned the literal string value 0 ELSE Delay 20.

On the ELSE clause (if I apply the workaround noted below), the value LEDmd=1 ENDIF is passed to the Event in the triggered rule.

I tried explicitly using the Backlog statement on each command "thread" but this had no impact on the problem. I removed the Backlogs to make room in the rule set buffers (I plan on adding more rules later).

REQUESTED INFORMATION

_Make sure your have performed every step and checked the applicable boxes before submitting your issue. Thank you!_

  • [x] Read the Contributing Guide and Policy and the Code of Conduct
  • [x] Searched the problem in issues
  • [x] Searched the problem in the docs
  • [x] Searched the problem in the forum
  • [x] Searched the problem in the chat
  • [x] Device used (e.g., Sonoff Basic): _____
  • [x] Tasmota binary firmware version number used: 8.1.0.1

    • [ ] Pre-compiled

    • [x] Self-compiled

    • [x] IDE / Compiler used: Gitpod

  • [x] Flashing tools used: OTA File Upload
  • [x] Provide the output of command: Backlog Template; Module; GPIO 255:
{"NAME":"GD-30W","GPIO":[0,107,0,108,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
{"GPIO0":{"0":"None"},"GPIO1":{"107":"Tuya Tx"},"GPIO2":{"0":"None"},"GPIO3":{"108":"Tuya Rx"},"GPIO4":{"0":"None"},"GPIO5":{"0":"None"},"GPIO9":{"0":"None"},"GPIO10":{"0":"None"},"GPIO12":{"0":"None"},"GPIO13":{"0":"None"},"GPIO14":{"0":"None"},"GPIO15":{"0":"None"},"GPIO16":{"0":"None"}}
  • [x] If using rules, provide the output of this command: Backlog Rule1; Rule2; Rule3:
{"Rule1":"ON","Once":"OFF","StopOnError":"OFF","Free":89,"Rules":"ON Rules#Timer=1 DO Event aDiff=1 ENDON ON MQTT#Connected DO Backlog SerialSend5 55AA0001000000;Event LEDmd=1;Dimmer 50;TuyaSend3 108,99baddFFFF6464;Event aOff=0;Event aDiff=1 ENDON ON Time#Initialized DO Backlog Var2 0;Var3 0;Var4 0;Var5 0;Event ckTim ENDON ON Time#Minute=%Mem2% DO Event ckTim ENDON ON Time#Minute=%Mem1% DO Event ckTim ENDON ON Event#ckTim DO Backlog Var5 0; Event ckMng=%Time%; Event ckNt=%Time% ENDON"}
{"Rule2":"ON","Once":"OFF","StopOnError":"OFF","Free":101,"Rules":"ON Event#ckMng DO IF (%value%<%Mem1%) Var5 0 ELSE Var5 1 ENDIF ENDON ON Event#ckNt>=%Mem2% DO Var5 0 ENDON ON Var5#State DO Event aDiff=%value% ENDON ON Event#aDiff DO IF (%value%==0) PulseTime1 0; RuleTimer1 0 ELSEIF (%Var4%==0) PulseTime1 175; RuleTimer1 300; Power1 %Var5% ENDIF ENDON ON Event#LEDmd DO TuyaSend4 110,%value% ENDON ON Event#OFF DO Backlog Var2 0;Var5 0;Power1 0;Power2 0; Event aDiff=0 ENDON"}
{"Rule3":"ON","Once":"OFF","StopOnError":"OFF","Free":190,"Rules":"ON Power2#State DO IF (%value%!=0) Delay 20;Var2 1;Event LEDmd=1;SetOption0 ELSE Delay 20;Var2 0;SetOption0 ENDIF ENDON ON Power3#State DO Var3 %value% ENDON ON Power4#State DO IF (%value%==1) Var4 1;Power1 0 ELSE Var4 0 ENDIF ENDON ON Power1#State DO IF (%value%==0) Power2 %Var2% ELSE Delay 20;Power3 %Var3% ENDIF ENDON"}
  • [x] Provide the output of this command: Status 0:
STATUS {"Status":{"Module":0,"FriendlyName":["Diffuser","Diffuser Light","Diffuser Mist","Diffuser Error",""],"Topic":"diffuser","ButtonTopic":"0","Power":19,"PowerOnState":3,"LedState":1,"LedMask":"FFFF","SaveData":1,"SaveState":0,"SwitchTopic":"0","SwitchMode":[0,0,0,0,0,0,0,0],"ButtonRetain":0,"SwitchRetain":0,"SensorRetain":0,"PowerRetain":0}}
STATUS1 {"StatusPRM":{"Baudrate":9600,"GroupTopic":"tasmotas","OtaUrl":"http://thehackbox.org/tasmota/tasmota.bin","RestartReason":"Software/System restart","Uptime":"0T18:12:14","StartupUTC":"2019-12-26T19:52:42","Sleep":50,"CfgHolder":4617,"BootCount":5,"SaveCount":22,"SaveAddress":"F5000"}}
STATUS2 {"StatusFWR":{"Version":"8.1.0.1(tasmota)","BuildDateTime":"2019-12-25T17:01:25","Boot":31,"Core":"2_6_1","SDK":"2.2.2-dev(38a443e)","Hardware":"ESP8266EX","CR":"361/699"}}
STATUS3 {"StatusLOG":{"SerialLog":0,"WebLog":2,"MqttLog":0,"SysLog":0,"LogHost":"","LogPort":514,"SSId":["mySSID",""],"TelePeriod":300,"Resolution":"558180C0","SetOption":["00C08108","2805C8000100060000005A00000000000000","008000C8","00000000"]}}
STATUS4 {"StatusMEM":{"ProgramSize":574,"Free":428,"Heap":24,"ProgramFlashSize":1024,"FlashSize":1024,"FlashChipId":"1440C8","FlashMode":0,"Features":["00000809","8FDAE397","043683A1","22B617CD","01001BC0","00007881"],"Drivers":"1,2,3,4,5,6,7,8,9,10,12,16,18,19,20,21,22,24,26,29","Sensors":"1,2,3,4,5,6,7,8,9,10,14,15,17,18,20,22,26,34"}}
STATUS5 {"StatusNET":{"Hostname":"diffuser-hostID","IPAddress":"192.168.1.63","Gateway":"192.168.1.1","Subnetmask":"255.255.255.0","DNSServer":"192.168.1.1","Mac":"myMAC","Webserver":2,"WifiConfig":4}}
STATUS6 {"StatusMQT":{"MqttHost":"myHost","MqttPort":1883,"MqttClientMask":"DVES_%06X","MqttClient":"DVES_hostID","MqttUser":"myUserID","MqttCount":2,"MAX_PACKET_SIZE":1000,"KEEPALIVE":30}}
STATUS7 {"StatusTIM":{"UTC":"Fri Dec 27 14:04:56 2019","Local":"Fri Dec 27 09:04:56 2019","StartDST":"Sun Mar 10 02:00:00 2019","EndDST":"Sun Nov 03 02:00:00 2019","Timezone":99,"Sunrise":"07:33","Sunset":"17:22"}}
STATUS10 {"StatusSNS":{"Time":"2019-12-27T09:04:56"}}
STATUS11 {"StatusSTS":{"Time":"2019-12-27T09:04:56","Uptime":"0T18:12:14","UptimeSec":65534,"Heap":24,"SleepMode":"Dynamic","Sleep":10,"LoadAvg":99,"MqttCount":2,"POWER1":"ON","POWER2":"ON","POWER3":"OFF","POWER4":"OFF","POWER5":"ON","Dimmer":100,"Fade":"OFF","Speed":1,"LedTable":"ON","Wifi":{"AP":1,"SSId":"mySSID","BSSId":"myBSSID","Channel":6,"RSSI":66,"Signal":-67,"LinkCount":2,"Downtime":"0T00:00:10"}}}
  • [ ] Provide the output of the Console log output when you experience your issue; if applicable:
    _(Please use_ weblog 4 _for more debug information)_
N/A

TO REPRODUCE

See description above

EXPECTED BEHAVIOUR

The commands are parsed properly

SCREENSHOTS

N/A

ADDITIONAL CONTEXT

To work around the issue, I added an innocuous command after the assignment command to introduce a semicolon (;) so the parser would recognize the end of the command properly.

ON Power2#State DO IF (%value%==0) Delay 20;Var2 0;SetOption0 ELSE Delay 20;Var2 1;Event LEDmd=1;SetOption0 ENDIF ENDON

(Please, remember to close the issue when the problem has been addressed)

bug fixed

All 8 comments

Let me check...

I've never used the IF/ELSE functionality but...

if you want to execute both delay 20 followed by var2 0 as far as I know you always need to use backlog to execute more than one command.

So in your original rule:

ON Power2#State DO IF (%value%==0) Delay 20;Var2 0 ELSE Delay 20;Var2 1;Event LEDmd=1 ENDIF ENDON

it should at least contain some backlog commands like:

ON Power2#State DO IF (%value%==0) backlog Delay 20;Var2 0 ELSE backlog Delay 20;Var2 1;Event LEDmd=1 ENDIF ENDON

If I use this rule it seems to work fine:

16:34:02 CMD: power2 2
16:34:02 SRC: Serial
16:34:02 CMD: Group 0, Index 2, Command "POWER", Data "2"
16:34:02 MQT: stat/wemos4/POWER2 = {"POWER2":"ON"}
16:34:02 MQT: stat/wemos4/POWER2 = ON
16:34:02 RUL: POWER2#STATE performs "IF (1==0) backlog Delay 20;Var2 0 ELSE backlog Delay 20;Var2 1;Event LEDmd=1 ENDIF"
16:34:02 SRC: Rule
16:34:02 CMD: Group 0, Index 1, Command "IF", Data "(1==0) backlog Delay 20[1E]Var2 0 ELSE backlog Delay 20[1E]Var2 1[1E]Event LEDmd=1 ENDIF"
16:34:02 MQT: stat/wemos4/IF = {"If":"Done"}
16:34:03 SRC: Backlog
16:34:03 CMD: Group 0, Index 1, Command "DELAY", Data "20"
16:34:03 MQT: stat/wemos4/DELAY = {"Delay":20}
16:34:05 SRC: Backlog
16:34:05 CMD: Group 0, Index 2, Command "VAR", Data "1"
16:34:05 MQT: stat/wemos4/VAR = {"Var2":"1"}
16:34:05 SRC: Backlog
16:34:05 CMD: Group 0, Index 1, Command "EVENT", Data "LEDmd=1"
16:34:05 MQT: stat/wemos4/EVENT = {"Event":"Done"}
16:34:05 CFG: Saved to flash at F9, Count 647, Bytes 4096
16:34:33 CMD: power2 2
16:34:33 SRC: Serial
16:34:33 CMD: Group 0, Index 2, Command "POWER", Data "2"
16:34:33 MQT: stat/wemos4/POWER2 = {"POWER2":"OFF"}
16:34:33 MQT: stat/wemos4/POWER2 = OFF
16:34:33 RUL: POWER2#STATE performs "IF (0==0) backlog Delay 20;Var2 0 ELSE backlog Delay 20;Var2 1;Event LEDmd=1 ENDIF"
16:34:33 SRC: Rule
16:34:33 CMD: Group 0, Index 1, Command "IF", Data "(0==0) backlog Delay 20[1E]Var2 0 ELSE backlog Delay 20[1E]Var2 1[1E]Event LEDmd=1 ENDIF"
16:34:33 MQT: stat/wemos4/IF = {"If":"Done"}
16:34:33 SRC: Backlog
16:34:33 CMD: Group 0, Index 1, Command "DELAY", Data "20"
16:34:33 MQT: stat/wemos4/DELAY = {"Delay":20}
16:34:35 SRC: Backlog
16:34:35 CMD: Group 0, Index 2, Command "VAR", Data "0"
16:34:35 MQT: stat/wemos4/VAR = {"Var2":"0"}
16:34:36 CFG: Saved to flash at F8, Count 648, Bytes 4096

Unless I miss something?

With the IF/ELSE feature, @laurentdong made the Backlog implicit. You can specify it but it is not necessary (I'm saving a few rule set bytes by removing it). In my case, I tried it with and without explicitly specifying the Backlog but the results were the same... for me. The parser didn't see the ELSE or the ENDIF.

I'll grab the latest development and compile and upload again. Perhaps something else was "introduced" which is now "rolled back" through other code updates. I'll update in a few minutes.

I think I remember some wise guy (Adrian) inserted a backlog in front of a rule if there is no backlog cmnd in the rule. That is what happens here. If there is no backlog command in the rule the rule is executed with a superseded backlog command before the IF. This is bound to fail as you see. Laurents code is not even executed.

I'll have to find where Adrian did it and find another solution.

Indeed line 441 is a breaking change as sson as an Event is in the rule; it adds the backlog resulting in your experience. Without an event in the rule it works fine.

As a workaround I think I change Adrian's code line to include a test for IF and if so do not change to backlog.

Hold on.

Give it a try.

I'm off as the year comes to a close here. Happy New Year.

Works at me end. Thanks Theo.

Happy New Year! 馃巻 馃嵕

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Vujagig picture Vujagig  路  3Comments

abzman picture abzman  路  3Comments

Joeyhza picture Joeyhza  路  3Comments

TylerDurden23 picture TylerDurden23  路  3Comments

ximonline picture ximonline  路  3Comments