117 lines
4.2 KiB
Python
117 lines
4.2 KiB
Python
from odoo import models, fields, api
|
|
from datetime import datetime
|
|
import logging
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
class Wifi(models.Model):
|
|
_name = 'unifi.wifi'
|
|
_description = 'Unifi WiFi Network'
|
|
|
|
name = fields.Char(string='WiFi Name (SSID)', required=True)
|
|
unifi_id = fields.Char(string='UniFi ID', readonly=True)
|
|
last_sync = fields.Datetime(string='Last Synchronization', readonly=True)
|
|
|
|
security_mode = fields.Selection(
|
|
[('open', 'Open'), ('wpa', 'WPA/WPA2 Personal'), ('wpa3', 'WPA3')],
|
|
string='Security Mode',
|
|
required=True,
|
|
default='wpa'
|
|
)
|
|
|
|
password = fields.Char(
|
|
string='WiFi Password',
|
|
help="Password for the WiFi network (if applicable)."
|
|
)
|
|
|
|
vlan_id = fields.Many2one(
|
|
comodel_name='unifi.network',
|
|
string='VLAN'
|
|
)
|
|
|
|
description = fields.Text(
|
|
string='Description'
|
|
)
|
|
|
|
ctrl_id = fields.Many2one(
|
|
'unifi.ctrl',
|
|
string='Controller',
|
|
required=True,
|
|
help="Controller where this rule is applied."
|
|
)
|
|
|
|
@api.model
|
|
def sync_from_controller(self, client, controller_id):
|
|
"""Synchronize WiFi networks from UniFi Controller."""
|
|
try:
|
|
_logger.info(f"Starting WiFi sync for controller {controller_id}")
|
|
wifi_configs = client.get_wifis()
|
|
synced_ids = []
|
|
|
|
for wifi in wifi_configs:
|
|
# Map security mode
|
|
security = wifi.get('security', '').lower()
|
|
if 'wpa3' in security:
|
|
security_mode = 'wpa3'
|
|
elif 'wpa' in security:
|
|
security_mode = 'wpa'
|
|
else:
|
|
security_mode = 'open'
|
|
|
|
values = {
|
|
'name': wifi.get('name', ''),
|
|
'unifi_id': wifi.get('_id', ''),
|
|
'security_mode': security_mode,
|
|
'password': wifi.get('x_passphrase', ''), # Note: This might be encrypted
|
|
'description': wifi.get('name_combine', '') or wifi.get('name', ''),
|
|
'last_sync': fields.Datetime.now(),
|
|
'ctrl_id': controller_id,
|
|
}
|
|
|
|
# Try to find VLAN if specified
|
|
vlan_id = wifi.get('vlan_id')
|
|
if vlan_id:
|
|
network = self.env['unifi.network'].search([
|
|
('ctrl_id', '=', controller_id),
|
|
('vlan', '=', vlan_id)
|
|
], limit=1)
|
|
if network:
|
|
values['vlan_id'] = network.id
|
|
|
|
# Update existing or create new
|
|
existing = self.search([
|
|
('unifi_id', '=', values['unifi_id']),
|
|
('ctrl_id', '=', controller_id)
|
|
])
|
|
|
|
if existing:
|
|
_logger.info(f"Updating existing WiFi network: {values['name']}")
|
|
existing.write(values)
|
|
else:
|
|
_logger.info(f"Creating new WiFi network: {values['name']}")
|
|
self.create(values)
|
|
|
|
synced_ids.append(values['unifi_id'])
|
|
|
|
# Disable WiFi networks that no longer exist in the controller
|
|
outdated = self.search([
|
|
('ctrl_id', '=', controller_id),
|
|
('unifi_id', 'not in', synced_ids)
|
|
])
|
|
if outdated:
|
|
_logger.info(f"Disabling {len(outdated)} outdated WiFi networks")
|
|
outdated.unlink()
|
|
|
|
_logger.info("WiFi synchronization completed successfully")
|
|
|
|
except Exception as e:
|
|
_logger.error(f"Error during WiFi synchronization: {str(e)}")
|
|
raise api.UserError(f"Failed to sync WiFi networks: {str(e)}")
|
|
|
|
def sync_to_controller(self):
|
|
"""Synchronize WiFi network to UniFi Controller."""
|
|
self.ensure_one()
|
|
client = self.ctrl_id.get_client()
|
|
# Implementation of pushing changes to UniFi
|
|
# This would need to be implemented based on UniFi's API
|
|
pass
|