Source code for unifi_controller_api.models.device

"""
Models for UniFi devices and related objects.
"""

from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional


[docs] @dataclass class LLDPEntry: """ LLDP (Link Layer Discovery Protocol) information entry for a device port. Contains information about connected neighbors discovered via LLDP. """ chassis_descr: Optional[str] = None chassis_id: Optional[str] = None chassis_id_subtype: Optional[str] = None local_port_idx: Optional[int] = None local_port_name: Optional[str] = None port_descr: Optional[str] = None port_id: Optional[str] = None power_allocated: Optional[int] = None power_requested: Optional[int] = None is_wired: Optional[bool] = None
[docs] @dataclass class UnifiDevice: """ Represents a UniFi network device. This class models a device managed by a UniFi controller, such as an access point, switch, gateway, or other UniFi device. """ # Basic device identification mac: str name: Optional[str] = None ip: Optional[str] = None model: Optional[str] = None type: Optional[str] = None # Model and hardware information serial: Optional[str] = None model_in_lts: Optional[bool] = None model_in_eol: Optional[bool] = None model_incompatible: Optional[bool] = None manufacturer_id: Optional[str] = None board_rev: Optional[int] = None architecture: Optional[str] = None # UniFi controller identification _id: Optional[str] = None device_id: Optional[str] = None hash_id: Optional[str] = None site_id: Optional[str] = None anon_id: Optional[str] = None # Status information version: Optional[str] = None adopted: Optional[bool] = None last_seen: Optional[int] = None disconnected_at: Optional[int] = None uptime: Optional[int] = None state: Optional[int] = None disconnection_reason: Optional[str] = None connected_at: Optional[int] = None provisioned_at: Optional[int] = None upgrade_state: Optional[str] = None unsupported_reason: Optional[str] = None # Network information connect_request_ip: Optional[str] = None inform_ip: Optional[str] = None inform_url: Optional[str] = None gateway_mac: Optional[str] = None internet: Optional[bool] = None # Site information site_name: Optional[str] = None unifi_id: Optional[str] = None # Statistics fields with special mapping user_num_sta: Optional[int] = field(default=None, metadata={"unifi_api_field": "user-num_sta"}) user_wlan_num_sta: Optional[int] = field(default=None, metadata={"unifi_api_field": "user-wlan-num_sta"}) guest_num_sta: Optional[int] = field(default=None, metadata={"unifi_api_field": "guest-num_sta"}) guest_wlan_num_sta: Optional[int] = field(default=None, metadata={"unifi_api_field": "guest-wlan-num_sta"}) rx_bytes_r: Optional[int] = field(default=None, metadata={"unifi_api_field": "rx_bytes-r"}) tx_bytes_r: Optional[int] = field(default=None, metadata={"unifi_api_field": "tx_bytes-r"}) # Table data and capabilities port_table: Optional[List[Dict[str, Any]]] = None radio_table: Optional[List[Dict[str, Any]]] = None radio_table_stats: Optional[List[Dict[str, Any]]] = None vap_table: Optional[List[Dict[str, Any]]] = None ethernet_table: Optional[List[Dict[str, Any]]] = None uplink_table: Optional[List[Dict[str, Any]]] = None antenna_table: Optional[List[Dict[str, Any]]] = None scan_radio_table: Optional[List[Dict[str, Any]]] = None countrycode_table: Optional[List[Dict[str, Any]]] = None vwire_table: Optional[List[Dict[str, Any]]] = None config_network: Optional[Dict[str, Any]] = None lldp_info: List[LLDPEntry] = field(default_factory=list) lldp_table: List[Dict[str, Any]] = field(default_factory=list, repr=False) fw_caps: Optional[int] = None hw_caps: Optional[int] = None wifi_caps: Optional[int] = None switch_caps: Optional[int] = None sys_error_caps: Optional[int] = None # Device features and settings in_gateway_mode: Optional[bool] = None vwireEnabled: Optional[bool] = None has_speaker: Optional[bool] = None has_eth1: Optional[bool] = None has_fan: Optional[bool] = None has_temperature: Optional[bool] = None outdoor_mode_override: Optional[bool] = None lcm_brightness_override: Optional[int] = None lcm_idle_timeout_override: Optional[int] = None led_override: Optional[bool] = None led_override_color: Optional[str] = None led_override_color_brightness: Optional[int] = None atf_enabled: Optional[bool] = None mesh_sta_vap_enabled: Optional[bool] = None dot1x_portctrl_enabled: Optional[bool] = None wlangroup_id_ng: Optional[str] = None fixed_ap_available: Optional[bool] = None two_phase_adopt: Optional[bool] = None # System information cfgversion: Optional[str] = None kernel_version: Optional[str] = None country_code: Optional[str] = None syslog_key: Optional[str] = None required_version: Optional[str] = None setup_id: Optional[str] = None license_state: Optional[str] = None # Security and authentication x_has_ssh_hostkey: Optional[bool] = None x_fingerprint: Optional[str] = None x_vwirekey: Optional[str] = None x_authkey: Optional[str] = None x_aes_gcm: Optional[bool] = None # Additional tracking fields upgrade_to_firmware: Optional[str] = None uplink: Optional[Dict[str, Any]] = None start_disconnected_millis: Optional[int] = None start_connected_millis: Optional[int] = None startup_timestamp: Optional[int] = None unsupported: Optional[bool] = None disabled: Optional[bool] = None # Optional display fields model_name: Optional[str] = None # Store any additional fields that aren't explicitly defined _extra_fields: Dict[str, Any] = field(default_factory=dict, repr=False)
[docs] def __post_init__(self): """ Process object initialization. - Convert lldp_table to lldp_info if present - Ensure nested LLDP entries are properly typed """ # Handle lldp_table to lldp_info conversion automatically if self.lldp_table and not self.lldp_info: self.lldp_info = [LLDPEntry(**entry) if isinstance(entry, dict) else entry for entry in self.lldp_table] self.lldp_table = [] # Clear after conversion to avoid duplication # Ensure lldp_info contains proper LLDPEntry objects elif self.lldp_info and isinstance(self.lldp_info, list): if not all(isinstance(entry, LLDPEntry) for entry in self.lldp_info): self.lldp_info = [LLDPEntry(**entry) if isinstance(entry, dict) else entry for entry in self.lldp_info]
[docs] def to_dict(self) -> Dict[str, Any]: """ Convert the UnifiDevice to a dictionary. Returns: Dictionary representation of the device with all fields. """ # Start with the standard fields result = {k: v for k, v in self.__dict__.items() if not k.startswith('_')} # Convert LLDP entries to dictionaries if result.get('lldp_info'): result['lldp_info'] = [entry.__dict__ for entry in self.lldp_info] # Add any extra fields if hasattr(self, '_extra_fields'): result.update(self._extra_fields) return result