TasmotaManager/docs/summaries/unifi_hostname_bug_fix_summary.md
2025-10-28 00:21:08 +00:00

137 lines
6.9 KiB
Markdown

# Unifi Hostname Bug Fix Summary
## Issue Description
The Unifi Hostname bug is an issue with UniFi OS where it doesn't keep track of updated hostnames. When a device's hostname is updated and the connection reset, UniFi may not pick up the new name. This can cause problems when trying to identify devices based on their hostnames.
The bug is detected when:
1. The UniFi-reported name matches an unknown_device_pattern (suggesting it's a Tasmota device)
2. The device's self-reported hostname does NOT match any unknown_device_pattern (suggesting it's actually a properly named device)
This mismatch indicates that UniFi is reporting an outdated or incorrect hostname.
## Previous Implementation
Previously, the code detected the bug in the `get_tasmota_devices` function by:
1. Checking if a device's name or hostname from UniFi matches unknown device patterns
2. If it does, checking the device's self-reported hostname by making a request to the device
3. Comparing the self-reported hostname against the same unknown device patterns
4. If the UniFi-reported name matches unknown patterns but the self-reported hostname doesn't, it sets `unifi_hostname_bug_detected = True`
However, the `is_hostname_unknown` function had a TODO comment for implementing the bug handling:
```python
# Handle Unifi Hostname bug if hostname is from Unifi OS
if from_unifi_os:
# TODO: Implement Unifi Hostname bug handling
# This would involve checking the actual device or other logic
self.logger.debug(f"Handling hostname '{hostname}' from Unifi OS (bug handling enabled)")
```
Additionally, the function would return `True` early if an IP was provided, without checking for the bug:
```python
# If IP is provided, we can skip hostname validation
if ip:
self.logger.debug(f"IP provided ({ip}), skipping hostname validation")
return True
```
## Changes Made
### 1. Fixed Early Return When IP is Provided
Changed the early return condition to only skip hostname validation if an IP is provided AND `from_unifi_os` is `False`:
```python
# If IP is provided and from_unifi_os is False, we can skip hostname validation
if ip and not from_unifi_os:
self.logger.debug(f"IP provided ({ip}) and from_unifi_os is False, skipping hostname validation")
return True
```
This ensures that when `from_unifi_os` is `True`, the function will continue to the bug handling code, even if an IP is provided.
### 2. Implemented Unifi Hostname Bug Handling
Replaced the TODO comment with actual code that:
1. Queries the device to get its self-reported hostname
2. Checks if the self-reported hostname matches any unknown patterns
3. If the UniFi-reported hostname matches unknown patterns but the self-reported hostname doesn't, it returns `False` (indicating it's not an unknown device despite what UniFi reports)
```python
# Handle Unifi Hostname bug if hostname is from Unifi OS
if from_unifi_os and ip:
self.logger.debug(f"Handling hostname '{hostname}' from Unifi OS (bug handling enabled)")
try:
# Get the device's self-reported hostname
url = f"http://{ip}/cm?cmnd=Status%205"
response = requests.get(url, timeout=5)
# Try to parse the JSON response
if response.status_code == 200:
try:
status_data = response.json()
# Extract the hostname from the response
device_reported_hostname = status_data.get('StatusNET', {}).get('Hostname', '')
if device_reported_hostname:
self.logger.debug(f"Device self-reported hostname: {device_reported_hostname}")
# Check if the self-reported hostname also matches unknown patterns
device_hostname_matches_unknown = False
for pattern in patterns:
if self._match_pattern(device_reported_hostname.lower(), pattern, match_entire_string=False):
device_hostname_matches_unknown = True
self.logger.debug(f"Device's self-reported hostname '{device_reported_hostname}' matches unknown pattern: {pattern}")
break
# If UniFi name matches unknown patterns but device's self-reported name doesn't,
# this indicates the UniFi OS hostname bug
if not device_hostname_matches_unknown:
# First check if the UniFi-reported hostname matches unknown patterns
unifi_hostname_matches_unknown = False
for pattern in patterns:
if self._match_pattern(hostname_lower, pattern, match_entire_string=False):
unifi_hostname_matches_unknown = True
break
if unifi_hostname_matches_unknown:
self.logger.info(f"UniFi OS hostname bug detected for {hostname}: self-reported hostname '{device_reported_hostname}' doesn't match unknown patterns")
return False # Not an unknown device despite what UniFi reports
except ValueError:
self.logger.debug(f"Failed to parse device response for {hostname}")
except Exception as e:
self.logger.debug(f"Error checking device's self-reported hostname for {hostname}: {str(e)}")
elif from_unifi_os:
self.logger.debug(f"Cannot check device's self-reported hostname for {hostname}: No IP address provided")
```
## Testing
A comprehensive test script `test_unifi_hostname_bug_fix.py` was created to verify the bug fix. The script tests:
1. A device affected by the Unifi Hostname bug (UniFi-reported hostname matches unknown patterns, but self-reported hostname doesn't)
2. A device not affected by the bug (both hostnames match or don't match unknown patterns)
3. Various combinations of parameters (with/without from_unifi_os, with/without IP)
4. Error handling (request exceptions, invalid JSON responses)
All tests pass, confirming that the bug fix works correctly.
## Benefits
This fix ensures that devices affected by the Unifi Hostname bug are not incorrectly identified as unknown devices. This improves the accuracy of device identification and prevents unnecessary configuration of devices that are already properly configured.
## Usage
To use the Unifi Hostname bug handling, call the `is_hostname_unknown` function with `from_unifi_os=True` and provide an IP address:
```python
# Check with Unifi Hostname bug handling
if manager.is_hostname_unknown("tasmota_device123", from_unifi_os=True, ip="192.168.1.100"):
print("This is an unknown device from Unifi OS")
else:
print("This is not an unknown device (possibly due to the Unifi Hostname bug)")
```
The function will return `False` if the device is affected by the Unifi Hostname bug (UniFi-reported hostname matches unknown patterns, but self-reported hostname doesn't).