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