31 Commits

Author SHA1 Message Date
iv3jdv ca7547adcf fix(ui): hide Telegram buttons for unauthenticated users 2026-04-27 18:23:08 +02:00
iv3jdv 817eda7d03 feat(mqtt): make subscription topics configurable via config.json 2026-04-27 17:57:51 +02:00
iv3jdv 56cd9d5323 feat(ui): add dynamic hotspot/repeater badge based on duplex mode 2026-04-27 17:28:06 +02:00
iv3jdv 47f1490701 update readme 2026-04-27 16:53:39 +02:00
iv3jdv 33dac9c8e4 Delete fleet_console.log.1 2026-04-27 15:54:40 +02:00
iv3jdv 6cdfbedf9e update .gitignore 2026-04-27 15:16:29 +02:00
iv3jdv e4d1e3eca4 feat(ui): implement dynamic profile buttons and global override 2026-04-27 14:36:42 +02:00
iv3jdv ad961dedc2 update timeout 2026-04-27 01:09:44 +02:00
iv3jdv 289b6d5f59 fix: resolve blue TX line freeze and add smart hang-time 2026-04-27 01:04:26 +02:00
iv3jdv 8881f6630f update credits 2026-04-26 23:58:19 +02:00
iv3jdv 0a7f7f718e feat: implement dynamic Callsign and Radio ID from MQTT General topic
- Node names and IDs are now automatically updated using MMDVMHost/General data
- Added fallback to clients.json values if node is offline or data is missing
- Improved UI with dynamic badge coloring and high-contrast text for IDs
2026-04-26 23:37:43 +02:00
iv3jdv 2685ee0212 feat: add location and coordinates to node cards 2026-04-26 22:46:04 +02:00
iv3jdv 8f48bfaa5a feat: add real-time TX/RX frequency display to node cards 2026-04-26 21:57:24 +02:00
iv3jdv 2a722a7ae6 update README.md 2026-04-26 20:11:28 +02:00
iv3jdv cd3960b110 update README.md 2026-04-26 19:37:35 +02:00
iv3jdv bc7f7fe345 update README.md 2026-04-26 19:31:26 +02:00
iv3jdv 7ba28dd02a Fix: mismatch 2026-04-26 18:28:02 +02:00
iv3jdv d2feb67cef update index.html 2026-04-26 18:22:16 +02:00
iv3jdv 69749411cd update index.html 2026-04-26 18:04:05 +02:00
iv3jdv 364ada37c4 update index.html 2026-04-26 17:51:37 +02:00
iv3jdv 89148d446e update index.html 2026-04-26 17:46:52 +02:00
iv3jdv 8865fe85ab update index.html 2026-04-26 17:41:09 +02:00
iv3jdv 2e0d3f4a6e update index.html 2026-04-26 17:35:02 +02:00
iv3jdv e8e4cce689 Fix: Download ID 2026-04-26 16:39:04 +02:00
iv3jdv 5ca7adc1f2 Update systemd/fleet-control.service 2026-04-26 15:51:49 +02:00
iv3jdv a147162736 Update README.md 2026-04-26 15:51:28 +02:00
iv3jdv 0c4b1e45be Update README.md 2026-04-26 15:45:56 +02:00
iv3jdv de3e8fc68c Delete README.md.old 2026-04-26 15:29:02 +02:00
iv3jdv 2be89da897 Update systemd/fleet-control.service 2026-04-26 15:28:49 +02:00
iv3jdv acd445a479 Update install.txt 2026-04-26 15:28:06 +02:00
iv3jdv 71a1cd32c3 Update install.txt 2026-04-26 15:26:58 +02:00
8 changed files with 527 additions and 678 deletions
+1
View File
@@ -20,6 +20,7 @@ telemetry_cache.json
# Ignora log di sistema eventuali # Ignora log di sistema eventuali
*.log *.log
*.log.*
# Ignora le configurazioni reali dell'agente remoto # Ignora le configurazioni reali dell'agente remoto
*.ini *.ini
+42 -22
View File
@@ -4,12 +4,14 @@
--- ---
![Dashboard Screenshot](images/dashboard.png)
<a name="english"></a> <a name="english"></a>
## 🇬🇧 English ## 🇬🇧 English
**Fleet Control Console** is a professional, real-time command and control (C2) dashboard designed for amateur radio repeater networks (MMDVM). This repository contains the **Server (Central Hub)** component, which provides a centralized web interface to monitor and manage a fleet of remote digital voice nodes (DMR, NXDN, YSF, P25). **Fleet Control Console** is a professional, real-time command and control (C2) dashboard designed for amateur radio repeater networks (MMDVM). This repository contains the **Server (Central Hub)** component, which provides a centralized web interface to monitor and manage a fleet of remote digital voice nodes (DMR, NXDN, YSF, P25).
> ️ **Note:** This is the Central Server repository. To monitor remote repeaters, you must install the [Fleet Control Agent](link_al_repo_agent_qui) on each node. > ️ **Note:** This is the Central Server repository. To monitor remote repeaters, you must install the [Fleet Control Agent](https://git.arifvg.it/iv3jdv/fleet-control-agent.git) on each node.
### 🏗️ Architecture & Technology Stack ### 🏗️ Architecture & Technology Stack
The server acts as the brain of the network: The server acts as the brain of the network:
@@ -31,6 +33,10 @@ The server acts as the brain of the network:
* A critical system daemon crashes (Auto-healing failed). * A critical system daemon crashes (Auto-healing failed).
* Works securely even when the web app is closed or in the background. * Works securely even when the web app is closed or in the background.
### ⚠️ Security Requirement: HTTPS
Please note that **Web Push Notifications** and the **Service Worker** require a secure connection to function. For security reasons, modern browsers only enable these features over **HTTPS**. If you are accessing the console via HTTP (outside of `localhost`), the "Push" button and notification registration will not work. We recommend using a reverse proxy (like Nginx, Caddy, or Traefik) with an SSL certificate.
**Pro Tip:** You can use Let's Encrypt to get a free SSL certificate for your domain.
#### 🛠️ Advanced Remote Control & Maintenance #### 🛠️ Advanced Remote Control & Maintenance
* **Remote .INI Editor:** Edit daemon configuration files (e.g., MMDVMHost.ini) directly from the web interface without SSH access. * **Remote .INI Editor:** Edit daemon configuration files (e.g., MMDVMHost.ini) directly from the web interface without SSH access.
* **Service Management:** Start, Stop, or Restart remote system daemons with a single click. * **Service Management:** Start, Stop, or Restart remote system daemons with a single click.
@@ -49,17 +55,22 @@ The server acts as the brain of the network:
### 🚀 Installation Guide ### 🚀 Installation Guide
#### 1. System Pre-requisites (Critical) #### 0. Root Privileges
Before installing Python dependencies, install the necessary system compilers and pip/venv tools. On Debian/Ubuntu: All installation steps must be executed as the `root` user. Before starting, elevate your privileges by running:
```bash ```bash
sudo apt update apt update
sudo apt install build-essential python3-dev libssl-dev libffi-dev python3-pip python3-venv apt install build-essential python3-dev libssl-dev libffi-dev python3-pip python3-venv
```
#### 1. Clone Repository
Clone the repository into the /opt directory to ensure all systemd paths work correctly:
```bash
git clone https://tuo-gitea.com/utente/fleet-control-server.git /opt/fleet-control-server
cd /opt/fleet-control-server
``` ```
#### 2. Virtual Environment Setup (Recommended) #### 2. Virtual Environment Setup (Recommended)
To prevent conflicts with OS packages (PEP 668), create an isolated environment: To prevent conflicts with OS packages (PEP 668), create an isolated environment:
```bash ```bash
cd /opt/web-control-server cd /opt/fleet-control-server
python3 -m venv venv python3 -m venv venv
source venv/bin/activate source venv/bin/activate
pip install --upgrade pip setuptools wheel pip install --upgrade pip setuptools wheel
@@ -75,10 +86,10 @@ pip install -r requirements.txt
#### 4. Running as a Service #### 4. Running as a Service
To run the server continuously in production using Gunicorn: To run the server continuously in production using Gunicorn:
```bash ```bash
sudo cp fleet-control.service /etc/systemd/system/ cp fleet-console.service /etc/systemd/system/
sudo systemctl daemon-reload systemctl daemon-reload
sudo systemctl enable fleet-control systemctl enable fleet-console
sudo systemctl start fleet-control systemctl start fleet-console
``` ```
*(Ensure the `.service` file points to the `gunicorn` executable inside your `venv`)*. *(Ensure the `.service` file points to the `gunicorn` executable inside your `venv`)*.
@@ -89,7 +100,7 @@ sudo systemctl start fleet-control
**Fleet Control Console** è una dashboard di comando e controllo (C2) professionale in tempo reale, progettata per le reti di ripetitori radioamatoriali (MMDVM). Questo repository contiene il **Server (Central Hub)**, che fornisce un'interfaccia web centralizzata per monitorare e gestire una flotta di nodi digitali remoti (DMR, NXDN, YSF, P25). **Fleet Control Console** è una dashboard di comando e controllo (C2) professionale in tempo reale, progettata per le reti di ripetitori radioamatoriali (MMDVM). Questo repository contiene il **Server (Central Hub)**, che fornisce un'interfaccia web centralizzata per monitorare e gestire una flotta di nodi digitali remoti (DMR, NXDN, YSF, P25).
> ️ **Nota:** Questo è il repository del Server Centrale. Per monitorare i ripetitori, devi installare il [Fleet Control Agent](link_al_repo_agent_qui) su ciascun nodo remoto. > ️ **Nota:** Questo è il repository del Server Centrale. Per monitorare i ripetitori, devi installare il [Fleet Control Agent](https://git.arifvg.it/iv3jdv/fleet-control-agent.git) su ciascun nodo remoto.
### 🏗️ Architettura e Tecnologie ### 🏗️ Architettura e Tecnologie
Il server agisce da cervello della rete: Il server agisce da cervello della rete:
@@ -111,6 +122,10 @@ Il server agisce da cervello della rete:
* Un demone di sistema remoto si blocca (fallimento auto-healing). * Un demone di sistema remoto si blocca (fallimento auto-healing).
* Funzionano in modo sicuro anche quando la web app è chiusa o in background. * Funzionano in modo sicuro anche quando la web app è chiusa o in background.
### ⚠️ Sicurezza Richiesta: HTTPS
Si prega di notare che le **Notifiche Web Push** e il **Service Worker** richiedono una connessione sicura per funzionare. Per motivi di sicurezza, i browser moderni abilitano queste funzionalità solo su **HTTPS**. Se accedi alla console via HTTP (al di fuori di `localhost`), il tasto "Push" e la registrazione delle notifiche non saranno attivi. Si consiglia l'uso di un reverse proxy (come Nginx, Caddy o Traefik) con certificato SSL.
**Suggerimento:** Puoi usare Let's Encrypt per ottenere un certificato SSL gratuito per il tuo dominio.
#### 🛠️ Controllo Remoto & Manutenzione Avanzata #### 🛠️ Controllo Remoto & Manutenzione Avanzata
* **Editor .INI Remoto:** Modifica i file di configurazione (es. MMDVMHost.ini) direttamente dal pannello web, senza bisogno di accessi SSH. * **Editor .INI Remoto:** Modifica i file di configurazione (es. MMDVMHost.ini) direttamente dal pannello web, senza bisogno di accessi SSH.
* **Gestione Demoni:** Avvia, arresta o riavvia i servizi di sistema remoti con un clic. * **Gestione Demoni:** Avvia, arresta o riavvia i servizi di sistema remoti con un clic.
@@ -129,17 +144,22 @@ Il server agisce da cervello della rete:
### 🚀 Guida all'Installazione ### 🚀 Guida all'Installazione
#### 1. Requisiti di Sistema (Critici) #### 0. Privilegi di Root
Prima di installare le dipendenze Python, installa i compilatori di base e gli strumenti per gli ambienti virtuali. Su Debian/Ubuntu: Tutti i passaggi di installazione devono essere eseguiti come utente `root`. Prima di iniziare, eleva i tuoi privilegi eseguendo:
```bash ```bash
sudo apt update apt update
sudo apt install build-essential python3-dev libssl-dev libffi-dev python3-pip python3-venv apt install build-essential python3-dev libssl-dev libffi-dev python3-pip python3-venv
```
#### 1. Clonazione dei Repository
Clona il repository nella cartella /opt per assicurarti che tutti i percorsi dei servizi systemd siano corretti:
```bash
git clone https://tuo-gitea.com/utente/fleet-control-server.git /opt/fleet-control-server
cd /opt/fleet-control-server
``` ```
#### 2. Setup Ambiente Virtuale (Consigliato) #### 2. Setup Ambiente Virtuale (Consigliato)
Per evitare conflitti con i pacchetti di sistema (regola PEP 668), crea una "bolla" isolata: Per evitare conflitti con i pacchetti di sistema (regola PEP 668), crea una "bolla" isolata:
```bash ```bash
cd /opt/web-control-server cd /opt/fleet-control-server
python3 -m venv venv python3 -m venv venv
source venv/bin/activate source venv/bin/activate
pip install --upgrade pip setuptools wheel pip install --upgrade pip setuptools wheel
@@ -155,10 +175,10 @@ pip install -r requirements.txt
#### 4. Esecuzione come Servizio (systemd) #### 4. Esecuzione come Servizio (systemd)
Per eseguire il server in produzione in modo continuo e stabile con Gunicorn: Per eseguire il server in produzione in modo continuo e stabile con Gunicorn:
```bash ```bash
sudo cp fleet-control.service /etc/systemd/system/ cp fleet-console.service /etc/systemd/system/
sudo systemctl daemon-reload systemctl daemon-reload
sudo systemctl enable fleet-control systemctl enable fleet-console
sudo systemctl start fleet-control systemctl start fleet-console
``` ```
*(Assicurati che il file `.service` punti all'eseguibile `gunicorn` situato all'interno della cartella `venv`).* *(Assicurati che il file `.service` punti all'eseguibile `gunicorn` situato all'interno della cartella `venv`).*
-144
View File
@@ -1,144 +0,0 @@
# 📡 Fleet Control Console (Server)
🌍 *[Read in English](#english) | 🇮🇹 [Leggi in Italiano](#italiano)*
---
<a name="english"></a>
## 🇬🇧 English
**Fleet Control Console** is a professional, real-time command and control (C2) dashboard designed for amateur radio repeater networks (MMDVM).
![Dashboard Screenshot](images/dashboard.png)
### 🤖 Remote Agent
To monitor your remote nodes (Raspberry Pi), download the dedicated lightweight agent here:
`https://git.arifvg.it/iv3jdv/web-console-agent.git`
### ✨ Features
* **Zero-Latency Real-Time UI:** Powered by WebSockets (Socket.IO).
* **Web Push Notifications:** Instant alerts on desktop or mobile.
* **Centralized Telemetry & Service Management.**
* **Global Operations:** Switch profiles instantly.
### 🚀 Installation & Setup
------------------------------------------------------------
1. PRE-REQUISITES (CRITICAL)
------------------------------------------------------------
Before installing Python dependencies, you must install
system compilers and development libraries.
Debian/Ubuntu:
sudo apt update
sudo apt install build-essential python3-dev libssl-dev libffi-dev
Upgrade base pip tools:
pip install --upgrade pip setuptools wheel
Create a virtual environment (Recommended):
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
------------------------------------------------------------
2. SERVER SETUP (CENTRAL HUB)
------------------------------------------------------------
The server handles the web interface and user permissions.
Steps:
1. Configure 'config.json' using 'config.example.json'.
2. Enter MQTT credentials and VAPID keys.
3. Define repeaters in the 'clients.json' file.
4. Install production WSGI server packages (if not in requirements):
pip install gunicorn gevent gevent-websocket
5. Start the production server:
gunicorn -k "geventwebsocket.gunicorn.workers.GeventWebSocketWorker" -w 1 --bind 0.0.0.0:9000 app:app
------------------------------------------------------------
3. GENERATING VAPID KEYS (PUSH NOTIFICATIONS)
------------------------------------------------------------
⚠️ WARNING: Web Push Notifications strictly require the
dashboard to be accessed via a secure HTTPS connection.
They will NOT work over standard HTTP.
1. Go to https://vapidkeys.com/ and generate the keys.
2. Copy 'Public Key' and 'Private Key' into 'config.json'.
3. Set 'vapid_claim_email' (e.g., "mailto:your@email.com").
------------------------------------------------------------
4. RUNNING AS A SERVICE (SYSTEMD)
------------------------------------------------------------
Configuration:
1. Copy .service file to '/etc/systemd/system/':
sudo cp fleet-console.service /etc/systemd/system/
2. Reload systemd: sudo systemctl daemon-reload
3. Enable on boot: sudo systemctl enable fleet-console
4. Start service: sudo systemctl start fleet-console
<a name="italiano"></a>
## 🇮🇹 Italiano
**Fleet Control Console** è una dashboard di comando e controllo (C2) professionale in tempo reale per le reti di ripetitori radioamatoriali (MMDVM).
![Schermata Dashboard](images/dashboard.png)
### 🤖 Agente Remoto
Per monitorare i tuoi nodi remoti (Raspberry Pi), scarica l'agente dedicato qui:
`https://git.arifvg.it/iv3jdv/web-console-agent.git`
### ✨ Funzionalità
* **Interfaccia Real-Time a Latenza Zero** tramite WebSockets.
* **Notifiche Push Web** per allarmi critici.
* **Telemetria Centralizzata e Gestione Servizi.**
* **Operazioni Globali** su tutta la rete.
### 🚀 Installazione
------------------------------------------------------------
1. REQUISITI PRELIMINARI (CRITICI)
------------------------------------------------------------
Prima di installare le dipendenze Python, è necessario
installare i compilatori di sistema. Senza questi,
l'installazione di 'gevent' fallirà su VPS vergini.
Esegui su Debian/Ubuntu:
sudo apt update
sudo apt install build-essential python3-dev libssl-dev libffi-dev
Aggiorna gli strumenti di base di pip:
pip install --upgrade pip setuptools wheel
Crea un ambiente virtuale (consigliato):
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
------------------------------------------------------------
2. SETUP DEL SERVER
------------------------------------------------------------
Passaggi:
1. Configura 'config.json' partendo da 'config.example.json'.
2. Inserisci credenziali MQTT e chiavi VAPID.
3. Definisci i ripetitori in 'clients.json'.
4. Avvia il server di produzione:
gunicorn -k "geventwebsocket.gunicorn.workers.GeventWebSocketWorker" -w 1 --bind 0.0.0.0:9000 app:app
------------------------------------------------------------
3. GENERAZIONE CHIAVI VAPID
------------------------------------------------------------
⚠️ ATTENZIONE: Le notifiche push richiedono HTTPS.
1. Vai su https://vapidkeys.com/ e genera le chiavi.
2. Copia 'Public Key' e 'Private Key' nel 'config.json'.
3. Imposta 'vapid_claim_email' (es. "mailto:tua@email.com").
------------------------------------------------------------
4. ESECUZIONE COME SERVIZIO
------------------------------------------------------------
1. sudo cp fleet-console.service /etc/systemd/system/
2. sudo systemctl daemon-reload
3. sudo systemctl enable fleet-console
4. sudo systemctl start fleet-console
---
*Created by IV3JDV @ ARIFVG - 2026*
+96 -24
View File
@@ -151,6 +151,8 @@ last_notified_errors = {}
device_health = {} device_health = {}
last_seen_reflector = {} last_seen_reflector = {}
network_mapping = {} network_mapping = {}
node_info = {}
node_general = {}
if os.path.exists(CACHE_FILE): if os.path.exists(CACHE_FILE):
try: try:
@@ -170,18 +172,22 @@ def on_connect(client, userdata, flags, reason_code, properties=None):
logger.info("✅ Successfully connected to MQTT Broker! Subscribing to topics...") logger.info("✅ Successfully connected to MQTT Broker! Subscribing to topics...")
# Invia lo stato Online ai client web # Invia lo stato Online ai client web
socketio.emit('mqtt_status', {'connected': True}) socketio.emit('mqtt_status', {'connected': True})
client.subscribe([
("servizi/+/stat", 0), # --- LETTURA DINAMICA DEI TOPIC ---
("dmr-gateway/+/json", 0), default_topics = [
("devices/+/services", 0), "servizi/+/stat", "dmr-gateway/+/json", "devices/+/services",
("nxdn-gateway/+/json", 0), "nxdn-gateway/+/json", "ysf-gateway/+/json", "p25-gateway/+/json",
("ysf-gateway/+/json", 0), "dstar-gateway/+/json", "mmdvm/+/json", "devices/#", "data/#"
("p25-gateway/+/json", 0), ]
("dstar-gateway/+/json", 0),
("mmdvm/+/json", 0), # Cerca la lista "topics" nel config.json, se non la trova usa quella di default
("devices/#", 0), topics_list = config.get('mqtt', {}).get('topics', default_topics)
("data/#", 0)
]) # Converte la lista di stringhe nel formato richiesto da paho-mqtt: [(topic, qos), (topic, qos)...]
subscribe_list = [(topic, 0) for topic in topics_list]
client.subscribe(subscribe_list)
logger.info(f"Subscribed to {len(subscribe_list)} MQTT topics.")
else: else:
mqtt_connected_status = False mqtt_connected_status = False
socketio.emit('mqtt_status', {'connected': False}) socketio.emit('mqtt_status', {'connected': False})
@@ -301,6 +307,52 @@ def on_message(client, userdata, msg):
except Exception as e: except Exception as e:
logger.error(f"Error parsing DMRGateway for {cid}: {e}") logger.error(f"Error parsing DMRGateway for {cid}: {e}")
# --- MMDVMHOST INFO MANAGEMENT (FREQUENZE & LOCATION) ---
elif len(parts) >= 4 and parts[0] == 'data' and parts[2].lower() == 'mmdvmhost' and parts[3].lower() == 'info':
try:
cid = parts[1].lower()
data = json.loads(payload)
# Estrazione dati
tx = data.get("TXFrequency", "0")
rx = data.get("RXFrequency", "0")
lat = data.get("Latitude", "0.0")
lon = data.get("Longitude", "0.0")
loc = data.get("Location", "Sconosciuta")
# Funzione per formattare gli Hz in MHz
def format_freq(f):
if str(f).isdigit() and int(f) > 0:
return f"{int(f)/1000000:.3f} MHz"
return str(f)
# Salvataggio nel dizionario globale
node_info[cid] = {
"tx": format_freq(tx),
"rx": format_freq(rx),
"lat": lat,
"lon": lon,
"loc": loc
}
socketio.emit('dati_aggiornati')
except Exception as e:
logger.error(f"Error parsing MMDVMHost info for {cid}: {e}")
# --- MMDVMHOST GENERAL MANAGEMENT (CALLSIGN & ID & DUPLEX) ---
elif len(parts) >= 4 and parts[0] == 'data' and parts[2].lower() == 'mmdvmhost' and parts[3].lower() == 'general':
try:
cid = parts[1].lower()
data = json.loads(payload)
callsign = data.get("Callsign", "")
radio_id = data.get("Id", "")
duplex = data.get("Duplex", "1") # 1 = Repeater, 0 = Simplex
if callsign:
node_general[cid] = {"callsign": callsign, "radio_id": radio_id, "duplex": str(duplex)}
socketio.emit('dati_aggiornati')
except Exception as e:
logger.error(f"Error parsing MMDVMHost general for {cid}: {e}")
# --- OTHER GATEWAYS MANAGEMENT --- # --- OTHER GATEWAYS MANAGEMENT ---
elif parts[0] in ['dmr-gateway', 'nxdn-gateway', 'ysf-gateway', 'p25-gateway', 'dstar-gateway']: elif parts[0] in ['dmr-gateway', 'nxdn-gateway', 'ysf-gateway', 'p25-gateway', 'dstar-gateway']:
data = json.loads(payload) data = json.loads(payload)
@@ -430,7 +482,9 @@ def get_states():
"states": client_states, "states": client_states,
"telemetry": client_telemetry, "telemetry": client_telemetry,
"health": device_health, "health": device_health,
"networks": network_mapping "networks": network_mapping,
"info": node_info,
"general": node_general
}) })
@app.route('/api/stats') @app.route('/api/stats')
@@ -670,37 +724,55 @@ def global_cmd():
return jsonify({"success": True}) return jsonify({"success": True})
def auto_update_ids(): def auto_update_ids():
while True: """Versione corretta: controlla all'avvio e poi ogni notte."""
def download_logic():
try: try:
# Usiamo esattamente i nomi e le URL definiti nel tuo config/codice
with open(CONFIG_PATH, 'r') as f: with open(CONFIG_PATH, 'r') as f:
current_cfg = json.load(f) current_cfg = json.load(f)
target_time = current_cfg.get("update_schedule", "03:00")
urls = current_cfg.get("id_urls", { urls = current_cfg.get("id_urls", {
"dmr": "https://radioid.net/static/users.csv", "dmr": "https://radioid.net/static/users.csv",
"nxdn": "https://radioid.net/static/nxdn.csv" "nxdn": "https://radioid.net/static/nxdn.csv"
}) })
now = time.strftime("%H:%M")
if now == target_time:
logger.info(f">>> [AUTO-UPDATE] Scheduled time reached ({now}). Downloading...")
# Trucco: Camuffiamo Python da browser per bypassare i blocchi Cloudflare headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'} logger.info("📡 Inizio download database ID (DMR e NXDN)...")
# Download DMR # Download DMR -> dmrid.dat
req_dmr = urllib.request.Request(urls["dmr"], headers=headers) req_dmr = urllib.request.Request(urls["dmr"], headers=headers)
with urllib.request.urlopen(req_dmr) as response, open(DMR_IDS_PATH, 'wb') as out_file: with urllib.request.urlopen(req_dmr) as response, open(DMR_IDS_PATH, 'wb') as out_file:
out_file.write(response.read()) out_file.write(response.read())
# Download NXDN # Download NXDN -> nxdn.csv
req_nxdn = urllib.request.Request(urls["nxdn"], headers=headers) req_nxdn = urllib.request.Request(urls["nxdn"], headers=headers)
with urllib.request.urlopen(req_nxdn) as response, open(NXDN_IDS_PATH, 'wb') as out_file: with urllib.request.urlopen(req_nxdn) as response, open(NXDN_IDS_PATH, 'wb') as out_file:
out_file.write(response.read()) out_file.write(response.read())
load_ids() load_ids()
logger.info(f">>> [AUTO-UPDATE] Completed successfully.") logger.info("✅ Aggiornamento completato con successo.")
except Exception as e:
logger.error(f"❌ Errore durante il download: {e}")
# --- CONTROLLO INIZIALE ALL'AVVIO ---
if not os.path.exists(DMR_IDS_PATH) or not os.path.exists(NXDN_IDS_PATH):
logger.info("🔍 File ID mancanti. Avvio download immediato...")
download_logic()
# --- CICLO NOTTURNO ---
while True:
try:
now = time.strftime("%H:%M")
with open(CONFIG_PATH, 'r') as f:
target_time = json.load(f).get("update_schedule", "03:00")
if now == target_time:
logger.info(f"⏰ Orario programmato ({target_time}) raggiunto. Aggiorno...")
download_logic()
time.sleep(65) time.sleep(65)
except Exception as e: except Exception as e:
logger.error(f">>> [AUTO-UPDATE] Error: {e}") logger.error(f"⚠️ Errore nel thread update: {e}")
time.sleep(30) time.sleep(30)
@app.route('/api/ui_config', methods=['GET']) @app.route('/api/ui_config', methods=['GET'])
+13 -1
View File
@@ -4,7 +4,19 @@
"port": 1883, "port": 1883,
"user": "your_username", "user": "your_username",
"password": "your_password", "password": "your_password",
"client_id": "fleet_backend_prod" "client_id": "fleet_backend_prod",
"topics": [
"servizi/+/stat",
"dmr-gateway/+/json",
"devices/+/services",
"nxdn-gateway/+/json",
"ysf-gateway/+/json",
"p25-gateway/+/json",
"dstar-gateway/+/json",
"mmdvm/+/json",
"devices/#",
"data/#"
]
}, },
"web_admin": { "web_admin": {
"default_user": "admin", "default_user": "admin",
+30 -16
View File
@@ -2,6 +2,13 @@
INSTALLATION GUIDE - FLEET CONTROL CONSOLE (SERVER) INSTALLATION GUIDE - FLEET CONTROL CONSOLE (SERVER)
============================================================ ============================================================
------------------------------------------------------------
0. IMPORTANT: ROOT PRIVILEGES
------------------------------------------------------------
All installation steps must be executed as the "root" user.
Before starting, elevate your privileges by running:
sudo su
------------------------------------------------------------ ------------------------------------------------------------
1. PRE-REQUISITES (CRITICAL) 1. PRE-REQUISITES (CRITICAL)
------------------------------------------------------------ ------------------------------------------------------------
@@ -9,11 +16,11 @@ Before installing Python dependencies, you must install
system compilers, development libraries, and pip/venv tools. system compilers, development libraries, and pip/venv tools.
Debian/Ubuntu: Debian/Ubuntu:
sudo apt update apt update
sudo apt install build-essential python3-dev libssl-dev libffi-dev python3-pip python3-venv apt install build-essential python3-dev libssl-dev libffi-dev python3-pip python3-venv
Create and activate a virtual environment (CRITICAL on Debian 12+): Create and activate a virtual environment (CRITICAL on Debian 12+):
cd /opt/web-control-server cd /opt/fleet-control-server
python3 -m venv venv python3 -m venv venv
source venv/bin/activate source venv/bin/activate
@@ -56,20 +63,27 @@ open 'fleet-control.service' and ensure the paths point to your
virtual environment. virtual environment.
Example: Example:
WorkingDirectory=/opt/web-control-server WorkingDirectory=/opt/fleet-control-server
ExecStart=/opt/web-control-server/venv/bin/gunicorn -k ... ExecStart=/opt/fleet-control-server/venv/bin/gunicorn -k ...
Configuration: Configuration:
1. Copy .service file to '/etc/systemd/system/': 1. Copy .service file to '/etc/systemd/system/':
sudo cp fleet-control.service /etc/systemd/system/ sudo cp fleet-console.service /etc/systemd/system/
2. Reload systemd: sudo systemctl daemon-reload 2. Reload systemd: systemctl daemon-reload
3. Enable on boot: sudo systemctl enable fleet-console 3. Enable on boot: systemctl enable fleet-console
4. Start service: sudo systemctl start fleet-console 4. Start service: systemctl start fleet-console
============================================================ ============================================================
GUIDA ALL'INSTALLAZIONE - SERVER (ITALIANO) GUIDA ALL'INSTALLAZIONE - SERVER (ITALIANO)
============================================================ ============================================================
------------------------------------------------------------
0. IMPORTANTE: PRIVILEGI DI ROOT
------------------------------------------------------------
Tutti i passaggi di installazione devono essere eseguiti
come utente "root". Prima di iniziare, eleva i tuoi privilegi:
sudo su
------------------------------------------------------------ ------------------------------------------------------------
1. REQUISITI PRELIMINARI (CRITICI) 1. REQUISITI PRELIMINARI (CRITICI)
------------------------------------------------------------ ------------------------------------------------------------
@@ -82,7 +96,7 @@ Esegui su Debian/Ubuntu:
sudo apt install build-essential python3-dev libssl-dev libffi-dev python3-pip python3-venv sudo apt install build-essential python3-dev libssl-dev libffi-dev python3-pip python3-venv
Crea e attiva un ambiente virtuale (FONDAMENTALE su Debian 12+): Crea e attiva un ambiente virtuale (FONDAMENTALE su Debian 12+):
cd /opt/web-control-server cd /opt/fleet-control-server
python3 -m venv venv python3 -m venv venv
source venv/bin/activate source venv/bin/activate
@@ -118,11 +132,11 @@ servizio, apri 'fleet-control.service' e assicurati che i percorsi
puntino al tuo ambiente virtuale! puntino al tuo ambiente virtuale!
Esempio: Esempio:
WorkingDirectory=/opt/web-control-server WorkingDirectory=/opt/fleet-control-server
ExecStart=/opt/web-control-server/venv/bin/gunicorn -k ... ExecStart=/opt/fleet-control-server/venv/bin/gunicorn -k ...
Passaggi: Passaggi:
1. Copia il file in systemd: sudo cp fleet-control.service /etc/systemd/system/ 1. Copia il file in systemd: sudo cp fleet-console.service /etc/systemd/system/
2. Ricarica la configurazione: sudo systemctl daemon-reload 2. Ricarica la configurazione: systemctl daemon-reload
3. Abilita all'avvio: sudo systemctl enable fleet-console 3. Abilita all'avvio: systemctl enable fleet-console
4. Avvia il servizio: sudo systemctl start fleet-console 4. Avvia il servizio: systemctl start fleet-console
@@ -6,9 +6,9 @@ After=network.target
Type=simple Type=simple
User=root User=root
# Assicurati che questo sia il percorso esatto della cartella del tuo progetto # Assicurati che questo sia il percorso esatto della cartella del tuo progetto
WorkingDirectory=/opt/web-control-server WorkingDirectory=/opt/fleet-control-server
# PUNTA AL GUNICORN DENTRO IL VENV! # PUNTA AL GUNICORN DENTRO IL VENV!
ExecStart=/opt/web-control-server/venv/bin/gunicorn -k "geventwebsocket.gunicorn.workers.GeventWebSocketWorker" -w 1 --graceful-timeout 2 --bind 0.0.0.0:9000 app:app ExecStart=/opt/fleet-control-server/venv/bin/gunicorn -k "geventwebsocket.gunicorn.workers.GeventWebSocketWorker" -w 1 --graceful-timeout 2 --bind 0.0.0.0:9000 app:app
TimeoutStopSec=3 TimeoutStopSec=3
Restart=always Restart=always
RestartSec=5 RestartSec=5
+320 -446
View File
File diff suppressed because it is too large Load Diff