feat: add real-time TX/RX frequency display to node cards
This commit is contained in:
@@ -151,6 +151,7 @@ last_notified_errors = {}
|
|||||||
device_health = {}
|
device_health = {}
|
||||||
last_seen_reflector = {}
|
last_seen_reflector = {}
|
||||||
network_mapping = {}
|
network_mapping = {}
|
||||||
|
node_info = {}
|
||||||
|
|
||||||
if os.path.exists(CACHE_FILE):
|
if os.path.exists(CACHE_FILE):
|
||||||
try:
|
try:
|
||||||
@@ -301,6 +302,25 @@ 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) ---
|
||||||
|
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)
|
||||||
|
tx = data.get("TXFrequency", "0")
|
||||||
|
rx = data.get("RXFrequency", "0")
|
||||||
|
|
||||||
|
# Funzione per formattare gli Hz in MHz (es. 430500000 -> 430.500 MHz)
|
||||||
|
def format_freq(f):
|
||||||
|
if str(f).isdigit() and int(f) > 0:
|
||||||
|
return f"{int(f)/1000000:.3f} MHz"
|
||||||
|
return str(f)
|
||||||
|
|
||||||
|
node_info[cid] = {"tx": format_freq(tx), "rx": format_freq(rx)}
|
||||||
|
socketio.emit('dati_aggiornati') # <--- Aggiorna la UI in tempo reale
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error parsing MMDVMHost info 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 +450,8 @@ 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
|
||||||
})
|
})
|
||||||
|
|
||||||
@app.route('/api/stats')
|
@app.route('/api/stats')
|
||||||
|
|||||||
@@ -47,6 +47,11 @@
|
|||||||
/* Telemetria stile terminale */
|
/* Telemetria stile terminale */
|
||||||
.health-bar { display: flex; justify-content: space-between; font-size: 0.75rem; font-weight: 600; background: #010409; padding: 8px 12px; border-radius: 3px; margin-bottom: 15px; border: 1px solid var(--border-color); font-family: 'JetBrains Mono', monospace; }
|
.health-bar { display: flex; justify-content: space-between; font-size: 0.75rem; font-weight: 600; background: #010409; padding: 8px 12px; border-radius: 3px; margin-bottom: 15px; border: 1px solid var(--border-color); font-family: 'JetBrains Mono', monospace; }
|
||||||
|
|
||||||
|
/* Frequenze Radio */
|
||||||
|
.freq-bar { display: flex; justify-content: space-around; font-size: 0.8rem; font-weight: 800; background: rgba(0,0,0,0.2); padding: 8px 10px; border-radius: 3px; margin-bottom: 15px; border: 1px dashed var(--border-color); font-family: 'JetBrains Mono', monospace; }
|
||||||
|
.freq-tx { color: #f87171; } /* Rosso per la TX */
|
||||||
|
.freq-rx { color: #4ade80; } /* Verde per la RX */
|
||||||
|
|
||||||
/* Display Stato */
|
/* Display Stato */
|
||||||
.status-display { text-align: center; font-family: 'JetBrains Mono', monospace; font-size: 0.9rem; font-weight: 700; padding: 8px; border-radius: 3px; background: #010409; border: 1px solid var(--border-color); margin-bottom: 15px; color: var(--text-muted); }
|
.status-display { text-align: center; font-family: 'JetBrains Mono', monospace; font-size: 0.9rem; font-weight: 700; padding: 8px; border-radius: 3px; background: #010409; border: 1px solid var(--border-color); margin-bottom: 15px; color: var(--text-muted); }
|
||||||
.card.online .status-display { color: var(--success); border-color: rgba(46, 160, 67, 0.4); }
|
.card.online .status-display { color: var(--success); border-color: rgba(46, 160, 67, 0.4); }
|
||||||
@@ -588,6 +593,10 @@
|
|||||||
<span class="badge-id">ID: ${c.id.toUpperCase()}</span>
|
<span class="badge-id">ID: ${c.id.toUpperCase()}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="freq-bar" id="freq-container-${c.id}" style="display: none;">
|
||||||
|
<span><span class="freq-tx">TX:</span> <span id="freq-tx-${c.id}">...</span></span>
|
||||||
|
<span><span class="freq-rx">RX:</span> <span id="freq-rx-${c.id}">...</span></span>
|
||||||
|
</div>
|
||||||
<div class="health-bar" id="health-${c.id}" style="display: none;">
|
<div class="health-bar" id="health-${c.id}" style="display: none;">
|
||||||
<span>⚡ <span id="cpu-${c.id}">--</span>%</span>
|
<span>⚡ <span id="cpu-${c.id}">--</span>%</span>
|
||||||
<span>🌡️ <span id="temp-${c.id}">--</span>°C</span>
|
<span>🌡️ <span id="temp-${c.id}">--</span>°C</span>
|
||||||
@@ -701,6 +710,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let healthObj = data.health && data.health[c.id.toLowerCase()];
|
let healthObj = data.health && data.health[c.id.toLowerCase()];
|
||||||
|
let infoObj = data.info && data.info[c.id.toLowerCase()];
|
||||||
|
const freqContainer = document.getElementById(`freq-container-${c.id}`);
|
||||||
|
const freqTx = document.getElementById(`freq-tx-${c.id}`);
|
||||||
|
const freqRx = document.getElementById(`freq-rx-${c.id}`);
|
||||||
|
|
||||||
|
if (infoObj && isOnline) {
|
||||||
|
if (freqContainer) {
|
||||||
|
freqContainer.style.display = 'flex';
|
||||||
|
freqTx.innerText = infoObj.tx;
|
||||||
|
freqRx.innerText = infoObj.rx;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (freqContainer) freqContainer.style.display = 'none';
|
||||||
|
}
|
||||||
const healthContainer = document.getElementById(`health-${c.id}`); const cpuSpan = document.getElementById(`cpu-${c.id}`); const tempSpan = document.getElementById(`temp-${c.id}`); const ramSpan = document.getElementById(`ram-${c.id}`); const diskSpan = document.getElementById(`disk-${c.id}`);
|
const healthContainer = document.getElementById(`health-${c.id}`); const cpuSpan = document.getElementById(`cpu-${c.id}`); const tempSpan = document.getElementById(`temp-${c.id}`); const ramSpan = document.getElementById(`ram-${c.id}`); const diskSpan = document.getElementById(`disk-${c.id}`);
|
||||||
|
|
||||||
if (healthObj && isOnline) {
|
if (healthObj && isOnline) {
|
||||||
|
|||||||
Reference in New Issue
Block a user