TasmotaManager/is_device_excluded_implementation.py
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

68 lines
3.4 KiB
Python

def is_device_excluded(self, device_name: str, hostname: str = '', patterns: list = None, log_level: str = 'debug') -> bool:
"""Check if a device name or hostname matches any pattern in exclude_patterns.
This function provides a centralized way to check if a device should be excluded
based on its name or hostname matching any of the exclude_patterns defined in the
configuration. It uses case-insensitive matching and supports glob patterns (with *)
in the patterns list.
Args:
device_name: The device name to check against exclude_patterns
hostname: The device hostname to check against exclude_patterns (optional)
patterns: Optional list of patterns to check against. If not provided,
patterns will be loaded from the configuration.
log_level: The logging level to use ('debug', 'info', 'warning', 'error'). Default is 'debug'.
Returns:
bool: True if the device should be excluded (name or hostname matches any pattern),
False otherwise
Examples:
# Check if a device should be excluded based on patterns in the config
if manager.is_device_excluded("homeassistant", "homeassistant.local"):
print("This device should be excluded")
# Check against a specific list of patterns
custom_patterns = ["^homeassistant*", "^.*sonos.*"]
if manager.is_device_excluded("sonos-speaker", "sonos.local", custom_patterns, log_level='info'):
print("This device matches a custom exclude pattern")
"""
# If no patterns provided, get them from the configuration
if patterns is None:
patterns = []
network_filters = self.config['unifi'].get('network_filter', {})
for network in network_filters.values():
patterns.extend(network.get('exclude_patterns', []))
# Convert device_name and hostname to lowercase for case-insensitive matching
name = device_name.lower() if device_name else ''
hostname_lower = hostname.lower() if hostname else ''
# Set up logging based on the specified level
log_func = getattr(self.logger, log_level)
# Check if device name or hostname matches any pattern
for pattern in patterns:
pattern_lower = pattern.lower()
# Convert glob pattern to regex pattern
pattern_regex = pattern_lower.replace('.', r'\.').replace('*', '.*')
# Check if pattern already starts with ^
if pattern_regex.startswith('^'):
regex_pattern = f"{pattern_regex}$"
# Special case for patterns like ^.*something.* which should match anywhere in the string
if pattern_regex.startswith('^.*'):
if (re.search(regex_pattern, name) or
(hostname_lower and re.search(regex_pattern, hostname_lower))):
log_func(f"Excluding device due to pattern '{pattern}': {device_name} ({hostname})")
return True
continue
else:
regex_pattern = f"^{pattern_regex}$"
# For normal patterns, use re.match which anchors at the beginning of the string
if (re.match(regex_pattern, name) or
(hostname_lower and re.match(regex_pattern, hostname_lower))):
log_func(f"Excluding device due to pattern '{pattern}': {device_name} ({hostname})")
return True
return False