bemade-addons/odoo_unifi_manager/models/unifi_wifi.py
2025-01-06 08:02:03 -05:00

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