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
This commit is contained in:
@@ -152,6 +152,7 @@ device_health = {}
|
|||||||
last_seen_reflector = {}
|
last_seen_reflector = {}
|
||||||
network_mapping = {}
|
network_mapping = {}
|
||||||
node_info = {}
|
node_info = {}
|
||||||
|
node_general = {}
|
||||||
|
|
||||||
if os.path.exists(CACHE_FILE):
|
if os.path.exists(CACHE_FILE):
|
||||||
try:
|
try:
|
||||||
@@ -302,6 +303,7 @@ 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':
|
elif len(parts) >= 4 and parts[0] == 'data' and parts[2].lower() == 'mmdvmhost' and parts[3].lower() == 'info':
|
||||||
try:
|
try:
|
||||||
cid = parts[1].lower()
|
cid = parts[1].lower()
|
||||||
@@ -332,6 +334,20 @@ def on_message(client, userdata, msg):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error parsing MMDVMHost info for {cid}: {e}")
|
logger.error(f"Error parsing MMDVMHost info for {cid}: {e}")
|
||||||
|
|
||||||
|
# --- MMDVMHOST GENERAL MANAGEMENT (CALLSIGN & ID) ---
|
||||||
|
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", "")
|
||||||
|
|
||||||
|
if callsign:
|
||||||
|
node_general[cid] = {"callsign": callsign, "radio_id": radio_id}
|
||||||
|
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)
|
||||||
@@ -462,7 +478,8 @@ def get_states():
|
|||||||
"telemetry": client_telemetry,
|
"telemetry": client_telemetry,
|
||||||
"health": device_health,
|
"health": device_health,
|
||||||
"networks": network_mapping,
|
"networks": network_mapping,
|
||||||
"info": node_info
|
"info": node_info,
|
||||||
|
"general": node_general
|
||||||
})
|
})
|
||||||
|
|
||||||
@app.route('/api/stats')
|
@app.route('/api/stats')
|
||||||
|
|||||||
+22
-2
@@ -670,10 +670,31 @@
|
|||||||
const statusDiv = document.getElementById(`status-${c.id}`); const cardDiv = document.getElementById(`card-${c.id}`);
|
const statusDiv = document.getElementById(`status-${c.id}`); const cardDiv = document.getElementById(`card-${c.id}`);
|
||||||
if (!statusDiv || !cardDiv) return;
|
if (!statusDiv || !cardDiv) return;
|
||||||
|
|
||||||
|
// 1. PRIMA CALCOLIAMO SE È ONLINE
|
||||||
let stateValue = data.states[c.id.toLowerCase()] || data.states[c.id] || "OFFLINE";
|
let stateValue = data.states[c.id.toLowerCase()] || data.states[c.id] || "OFFLINE";
|
||||||
stateValue = String(stateValue).trim().toUpperCase(); statusDiv.innerText = stateValue;
|
stateValue = String(stateValue).trim().toUpperCase(); statusDiv.innerText = stateValue;
|
||||||
const isOnline = !stateValue.includes("OFF") && stateValue !== "";
|
const isOnline = !stateValue.includes("OFF") && stateValue !== "";
|
||||||
|
|
||||||
|
// 2. POI AGGIORNIAMO NOME E ID DINAMICI
|
||||||
|
let genObj = data.general && data.general[c.id.toLowerCase()];
|
||||||
|
const nameSpan = cardDiv.querySelector('.client-name');
|
||||||
|
const idBadge = cardDiv.querySelector('.badge-id');
|
||||||
|
|
||||||
|
if (genObj && isOnline) {
|
||||||
|
nameSpan.innerText = genObj.callsign;
|
||||||
|
idBadge.innerText = `ID: ${genObj.radio_id}`;
|
||||||
|
idBadge.style.background = "var(--primary)";
|
||||||
|
idBadge.style.color = "#ffffff"; // <--- FORZA IL TESTO BIANCO
|
||||||
|
idBadge.style.borderColor = "var(--primary)"; // <--- ADATTA IL BORDO
|
||||||
|
} else {
|
||||||
|
nameSpan.innerText = c.name;
|
||||||
|
idBadge.innerText = `ID: ${c.id.toUpperCase()}`;
|
||||||
|
idBadge.style.background = "rgba(255,255,255,0.1)";
|
||||||
|
idBadge.style.color = "var(--text-muted)"; // <--- RIPRISTINA IL GRIGIO
|
||||||
|
idBadge.style.borderColor = "var(--border-color)";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. TELEMETRIA E STATO (PULITO DAI DUPLICATI)
|
||||||
let telemetryObj = data.telemetry[c.id.toLowerCase()] || data.telemetry[c.id] || { ts1: "...", ts2: "...", alt: "", idle: true };
|
let telemetryObj = data.telemetry[c.id.toLowerCase()] || data.telemetry[c.id] || { ts1: "...", ts2: "...", alt: "", idle: true };
|
||||||
if (typeof telemetryObj === 'string') telemetryObj = { ts1: telemetryObj, ts2: "...", alt: "", idle: true };
|
if (typeof telemetryObj === 'string') telemetryObj = { ts1: telemetryObj, ts2: "...", alt: "", idle: true };
|
||||||
|
|
||||||
@@ -717,7 +738,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let healthObj = data.health && data.health[c.id.toLowerCase()];
|
let healthObj = data.health && data.health[c.id.toLowerCase()];
|
||||||
// --- INIZIO BLOCCO INFO AGGIUNTIVE (FREQ + LOC) ---
|
|
||||||
let infoObj = data.info && data.info[c.id.toLowerCase()];
|
let infoObj = data.info && data.info[c.id.toLowerCase()];
|
||||||
const freqContainer = document.getElementById(`freq-container-${c.id}`);
|
const freqContainer = document.getElementById(`freq-container-${c.id}`);
|
||||||
const freqTx = document.getElementById(`freq-tx-${c.id}`);
|
const freqTx = document.getElementById(`freq-tx-${c.id}`);
|
||||||
@@ -743,7 +763,7 @@
|
|||||||
if (freqContainer) freqContainer.style.display = 'none';
|
if (freqContainer) freqContainer.style.display = 'none';
|
||||||
if (metaContainer) metaContainer.style.display = 'none';
|
if (metaContainer) metaContainer.style.display = 'none';
|
||||||
}
|
}
|
||||||
// --- FINE BLOCCO INFO AGGIUNTIVE ---
|
|
||||||
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