1. Restructured configuration: Moved config_other and console to top level 2. Added common _match_pattern function for regex pattern matching 3. Implemented Unifi Hostname bug fix in is_hostname_unknown 4. Created common get_device_hostname function to eliminate code duplication 5. Added comprehensive test scripts for all new functionality 6. Added detailed documentation for all changes
6.9 KiB
Analysis of unknown_device_patterns Checks in TasmotaManager.py
This document identifies and analyzes all places in the TasmotaManager.py script where checks against unknown_device_patterns are performed.
Summary
The script performs checks against unknown_device_patterns in 4 distinct places:
- In the
get_tasmota_devicesfunction during device discovery - In the
get_unknown_devicesfunction when identifying unknown devices for processing - In the
process_single_devicefunction when processing a single device - In the
process_devicesfunction when filtering devices for MQTT configuration
Detailed Analysis
1. In get_tasmota_devices function (lines 235-244 and 269-276)
Purpose: During device discovery, this function checks if devices match unknown patterns in two ways:
- First, it checks if the device's name or hostname as reported by UniFi matches any unknown patterns
- Second, if there's a match, it checks if the device's self-reported hostname also matches unknown patterns
Context: This is part of the initial device discovery process when scanning the network. The function sets a flag unifi_hostname_bug_detected if the UniFi-reported name matches unknown patterns but the device's self-reported hostname doesn't (indicating a possible UniFi OS bug).
Code snippet:
# Check if device name or hostname matches unknown patterns
unifi_name_matches_unknown = False
for pattern in unknown_patterns:
pattern_lower = pattern.lower()
pattern_regex = pattern_lower.replace('.', r'\.').replace('*', '.*')
if (re.match(f"^{pattern_regex}", device_name.lower()) or
re.match(f"^{pattern_regex}", device_hostname.lower())):
unifi_name_matches_unknown = True
self.logger.debug(f"Device {device_name} matches unknown device pattern: {pattern}")
break
# If the name matches unknown patterns, check the device's self-reported hostname
if unifi_name_matches_unknown and device_ip:
# ... [code to get device's self-reported hostname] ...
# Check if the self-reported hostname also matches unknown patterns
device_hostname_matches_unknown = False
for pattern in unknown_patterns:
pattern_lower = pattern.lower()
pattern_regex = pattern_lower.replace('.', r'\.').replace('*', '.*')
if re.match(f"^{pattern_regex}", device_reported_hostname.lower()):
device_hostname_matches_unknown = True
self.logger.debug(f"Device's self-reported hostname '{device_reported_hostname}' matches unknown pattern: {pattern}")
break
2. In get_unknown_devices function (lines 500-506)
Purpose: Specifically identifies devices that match unknown_device_patterns from current.json.
Context: This function is used when processing unknown devices to set them up with proper names and MQTT settings. It's called by the process_unknown_devices function, which is triggered by the --process-unknown command-line argument.
Code snippet:
for device in all_devices:
name = device.get('name', '').lower()
hostname = device.get('hostname', '').lower()
for pattern in unknown_patterns:
pattern = pattern.lower()
pattern = pattern.replace('.', r'\.').replace('*', '.*')
if re.match(f"^{pattern}", name) or re.match(f"^{pattern}", hostname):
self.logger.debug(f"Found unknown device: {name} ({hostname})")
unknown_devices.append(device)
break
3. In process_single_device function (lines 1526-1533 and 1559-1567)
Purpose: When processing a single device by IP or hostname, this function checks if it matches unknown patterns in two ways:
- First, it checks if the device's name or hostname as reported by UniFi matches any unknown patterns
- Second, if there's a match, it checks if the device's self-reported hostname also matches unknown patterns
Context: This function is used in Device mode (triggered by the --Device command-line argument) to determine if a specific device should be treated as unknown. If both the UniFi-reported name and the device's self-reported hostname match unknown patterns, the device is declared as unknown.
Code snippet:
# Initialize variables for hostname bug detection
unifi_name_matches_unknown = False
device_hostname_matches_unknown = False
for pattern in unknown_patterns:
pattern_lower = pattern.lower()
pattern_regex = pattern_lower.replace('.', r'\.').replace('*', '.*')
if (re.match(f"^{pattern_regex}", device_name.lower()) or
re.match(f"^{pattern_regex}", device_hostname.lower())):
unifi_name_matches_unknown = True
self.logger.info(f"Device {device_name} matches unknown device pattern: {pattern}")
break
# If the name matches unknown patterns, check the device's self-reported hostname
if unifi_name_matches_unknown:
# ... [code to get device's self-reported hostname] ...
# Check if the self-reported hostname also matches unknown patterns
device_hostname_matches_unknown = False
for pattern in unknown_patterns:
pattern_lower = pattern.lower()
pattern_regex = pattern_lower.replace('.', r'\.').replace('*', '.*')
if re.match(f"^{pattern_regex}", device_reported_hostname.lower()):
device_hostname_matches_unknown = True
self.logger.info(f"Device's self-reported hostname '{device_reported_hostname}' matches unknown pattern: {pattern}")
break
4. In process_devices function (lines 1760-1766)
Purpose: Filters out devices matching unknown_device_patterns during normal processing.
Context: This function is used to skip unknown devices when configuring MQTT for known devices. If a device matches an unknown_device_pattern, it's skipped unless the skip_unknown_filter parameter is True (which happens in Device mode).
Code snippet:
for device in all_devices:
name = device.get('name', '').lower()
hostname = device.get('hostname', '').lower()
is_unknown = False
for pattern in unknown_patterns:
pattern = pattern.lower()
pattern = pattern.replace('.', r'\.').replace('*', '.*')
if re.match(f"^{pattern}", name) or re.match(f"^{pattern}", hostname):
self.logger.debug(f"Skipping unknown device: {name} ({hostname})")
is_unknown = True
break
if not is_unknown:
devices.append(device)
Conclusion
The TasmotaManager.py script performs checks against unknown_device_patterns in 4 distinct places, each with a specific purpose:
- During device discovery to identify unknown devices and detect the UniFi OS hostname bug
- When specifically looking for unknown devices to process them
- When processing a single device to determine if it should be treated as unknown
- When filtering devices for MQTT configuration to skip unknown devices
These checks are an important part of the script's functionality, allowing it to handle unknown devices appropriately in different contexts.