3.5 KiB
Rule Writing Fix Summary
Issue Description
The issue was that rules were not being properly written to Tasmota devices. Specifically, when a rule containing special characters (like '#', '=', or spaces) was sent to a device, the rule would be truncated or not set correctly.
Root Cause Analysis
After examining the debug logs, I identified that the issue was due to improper URL encoding of the rule value. In the HTTP requests to the Tasmota device, special characters in the rule value were not being properly encoded, causing the rule to be truncated.
For example, in device_mode_debug.log, the rule command was logged as:
Sending rule command: http://192.168.8.155/cm?cmnd=rule1%20on button1#state=10 do power0 toggle endon
But the actual HTTP request sent was:
http://192.168.8.155:80 "GET /cm?cmnd=rule1%20on%20button1 HTTP/1.1"
Notice that the rule was truncated at the '#' character. The device's response confirmed that only "on button1" was received and stored:
Rule command response: {"Rule1":{"State":"OFF","Once":"OFF","StopOnError":"OFF","Length":10,"Free":501,"Rules":"on button1"}}
Fix Implemented
The fix was to properly URL encode the rule value using urllib.parse.quote(). This ensures that special characters like '#', '=', and spaces are properly encoded in the URL.
The fix was implemented in the configure_mqtt_settings method in TasmotaManager.py:
# Special handling for rule parameters to properly encode the URL
if param.lower().startswith('rule') and param.lower() == param and param[-1].isdigit():
# For rule commands, we need to URL encode the entire value to preserve special characters
import urllib.parse
encoded_value = urllib.parse.quote(value)
url = f"http://{ip}/cm?cmnd={param}%20{encoded_value}"
self.logger.info(f"{name}: Sending rule command: {url}")
else:
url = f"http://{ip}/cm?cmnd={param}%20{value}"
With this fix, the rule command is now properly encoded:
Sending rule command: http://192.168.8.155/cm?cmnd=rule1%20on%20button1%23state%3D10%20do%20power0%20toggle%20endon
And the device receives and stores the full rule:
Rule command response: {"Rule1":{"State":"OFF","Once":"OFF","StopOnError":"OFF","Length":42,"Free":469,"Rules":"on button1#state=10 do power0 toggle endon"}}
Testing and Verification
A test script test_rule1_encoding.py was created to verify the fix. The script:
- Defines a rule value with special characters: "on button1#state=10 do power0 toggle endon"
- Uses
urllib.parse.quote()to properly URL encode the rule value - Sends the encoded rule to the device
- Verifies that the rule was correctly set and enabled
The test script confirmed that with proper URL encoding, the full rule is successfully written to the device.
Additionally, the debug logs (device_mode_debug5.log) show that the fix is working correctly in the main application. The rule is properly encoded, sent to the device, and the device responds with the full rule text.
Conclusion
The issue with rules not being written was due to improper URL encoding of special characters in the rule value. This issue has been fixed by implementing proper URL encoding using urllib.parse.quote(). The fix has been verified by both test scripts and debug logs, and there are no remaining issues with rule writing in the current implementation.
This fix ensures that rules containing special characters are properly written to Tasmota devices, allowing for more complex rule definitions and automation.