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

6.9 KiB

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:

# 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:

# 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:

# 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)
# 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:

# 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).