Fix MQTT FullTopic with URL-encoded leading space
- Devices had FullTopic starting with %20 (URL-encoded space) - This breaks MQTT topic publishing with invalid leading space - Now detects %20 prefix and forces update even if normalized values match - Properly URL-encodes all MQTT setting values when sending - FullTopic %prefix%/%topic%/ now encoded as %25prefix%25%2F%25topic%25%2F - Fixes MQTT topics showing as '%20stat/device/...' instead of 'stat/device/...'
This commit is contained in:
parent
12ebdbf3e9
commit
be95930cd1
@ -226,6 +226,9 @@ class ConfigurationManager:
|
||||
|
||||
self.logger.debug(f"{device_name}: Raw FullTopic from device: '{current_full_topic}'")
|
||||
|
||||
# Check if device has URL-encoded spaces at the beginning (broken state)
|
||||
has_leading_encoded_space = current_full_topic.startswith('%20')
|
||||
|
||||
# Normalize: remove any URL-encoded spaces from the beginning of current value
|
||||
# This handles the case where the device returns '%20%prefix%' instead of '%prefix%'
|
||||
while current_full_topic.startswith('%20'):
|
||||
@ -236,7 +239,10 @@ class ConfigurationManager:
|
||||
|
||||
self.logger.debug(f"{device_name}: Comparing FullTopic: current='{current_full_topic}' vs expected='{mqtt_full_topic_normalized}'")
|
||||
|
||||
if current_full_topic != mqtt_full_topic_normalized:
|
||||
# Update if values don't match OR if device had leading encoded space (needs fixing)
|
||||
if current_full_topic != mqtt_full_topic_normalized or has_leading_encoded_space:
|
||||
if has_leading_encoded_space:
|
||||
self.logger.info(f"{device_name}: FullTopic has invalid leading space, will fix")
|
||||
updates_needed.append(('FullTopic', mqtt_full_topic_normalized))
|
||||
|
||||
# Handle NoRetain (SetOption62)
|
||||
@ -255,7 +261,13 @@ class ConfigurationManager:
|
||||
|
||||
failed_updates = []
|
||||
for setting_name, setting_value in updates_needed:
|
||||
command = f"{setting_name}%20{setting_value}"
|
||||
# URL encode the value, especially important for FullTopic which contains % and /
|
||||
from urllib.parse import quote
|
||||
# Convert value to string and URL encode it
|
||||
encoded_value = quote(str(setting_value), safe='')
|
||||
command = f"{setting_name}%20{encoded_value}"
|
||||
|
||||
self.logger.debug(f"{device_name}: Sending command: {command}")
|
||||
|
||||
result, success = retry_command(
|
||||
lambda: send_tasmota_command(device_ip, command, timeout=5, logger=self.logger),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user