TasmotaManager/self_reported_hostname_locations.md
Mike Geppert 126cd39555 Major code improvements and bug fixes:
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
2025-08-08 19:04:33 -05:00

7.9 KiB

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:

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

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

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

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