# Places That Look for Device Self-Reported Hostname This document identifies all places in the TasmotaManager codebase that look for device self-reported hostnames. ## 1. `is_hostname_unknown` Function (Lines 260-362) **Purpose**: Checks if a hostname matches any pattern in unknown_device_patterns, with special handling for the Unifi Hostname bug. **How it retrieves self-reported hostname**: - Makes an HTTP request to the device using `http://{ip}/cm?cmnd=Status%205` (line 315) - Extracts the hostname from the response using `status_data.get('StatusNET', {}).get('Hostname', '')` (line 323) - Compares the self-reported hostname against unknown patterns (lines 328-334) - If the UniFi-reported hostname matches unknown patterns but the self-reported hostname doesn't, it detects the UniFi OS hostname bug (lines 336-348) **Code snippet**: ```python # 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 ``` ## 2. `get_tasmota_devices` Method (Lines 480-537) **Purpose**: Part of the device discovery process when scanning the network. Checks for the UniFi OS hostname bug. **How it retrieves self-reported hostname**: - Makes an HTTP request to the device using `http://{device_ip}/cm?cmnd=Status%205` (line 501) - Extracts the hostname from the response using `status_data.get('StatusNET', {}).get('Hostname', '')` (line 509) - Checks if the self-reported hostname also matches unknown patterns (lines 514-527) - If the UniFi-reported name matches unknown patterns but the device's self-reported name doesn't, it sets the `unifi_hostname_bug_detected` flag to `True` (lines 529-533) **Code snippet**: ```python # Get the device's self-reported hostname url = f"http://{device_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 unknown_patterns: # ... pattern matching code ... if re.match(regex_pattern, 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 ``` ## 3. `process_single_device` Method (Lines 1780-1841) **Purpose**: Processes a single device by hostname or IP address. Checks the device's self-reported hostname before declaring it as unknown. **How it retrieves self-reported hostname**: - Makes an HTTP request to the device using `http://{device_ip}/cm?cmnd=Status%205` (line 1791) - Extracts the hostname from the response using `status_data.get('StatusNET', {}).get('Hostname', '')` (line 1799) - Checks if the self-reported hostname also matches unknown patterns (lines 1804-1817) - Makes a decision based on whether both the UniFi-reported and self-reported hostnames match unknown patterns: - If both match, the device is declared as unknown (lines 1820-1822) - If the UniFi-reported hostname matches but the self-reported hostname doesn't, the device is NOT declared as unknown, and it's considered a possible UniFi OS bug (lines 1823-1825) - If no self-reported hostname is found or there's an error, it falls back to using the UniFi-reported name (lines 1826-1841) **Code snippet**: ```python # Get the device's self-reported hostname url = f"http://{device_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.info(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 unknown_patterns: # ... pattern matching code ... if re.match(regex_pattern, 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 # Only declare as unknown if both UniFi-reported and self-reported hostnames match unknown patterns if device_hostname_matches_unknown: is_unknown = True self.logger.info("Device declared as unknown: both UniFi-reported and self-reported hostnames match unknown patterns") else: is_unknown = False self.logger.info("Device NOT declared as unknown: self-reported hostname doesn't match unknown patterns (possible UniFi OS bug)") ``` ## 4. Device Details Collection (Lines 2068-2092) **Purpose**: Collects general device information, including the hostname, as part of checking device details and updating settings if needed. **How it retrieves hostname information**: - Makes an HTTP request to the device using `http://{ip}/cm?cmnd=Status%205` (line 2069) - Extracts the hostname from the response using `network_data.get("StatusNET", {}).get("Hostname", "Unknown")` (line 2092) - Stores the hostname in a device_detail dictionary **Code snippet**: ```python # Get Status 5 for network info url_network = f"http://{ip}/cm?cmnd=Status%205" response = requests.get(url_network, timeout=5) network_data = response.json() # ... other code ... device_detail = { # ... other fields ... "hostname": network_data.get("StatusNET", {}).get("Hostname", "Unknown"), # ... other fields ... } ``` ## Summary The TasmotaManager codebase looks for device self-reported hostnames in four main places: 1. **`is_hostname_unknown` Function**: Specifically handles the Unifi Hostname bug by checking if the self-reported hostname matches unknown patterns. 2. **`get_tasmota_devices` Method**: Checks for the UniFi OS hostname bug during device discovery. 3. **`process_single_device` Method**: Checks the device's self-reported hostname before declaring it as unknown when processing a single device. 4. **Device Details Collection**: Retrieves the hostname as part of gathering general device information. The first three locations specifically deal with the Unifi Hostname bug, where UniFi OS might not keep track of updated hostnames. By checking the device's self-reported hostname, the code can determine if the device actually has a real hostname that UniFi is not showing correctly.