|
- import streamlit as st
- import pandas as pd
- import psutil
- import os
- import time
- import json
- import paho.mqtt.client as mqtt
- import requests
-
- def get_system_metrics():
- """Recupera statistiche hardware del server."""
- return {
- "cpu": psutil.cpu_percent(interval=None),
- "ram": psutil.virtual_memory().percent,
- "disk": psutil.disk_usage('/').percent,
- "net_recv": psutil.net_io_counters().bytes_recv / (1024**2)
- }
-
- def get_api_data(cfg, sec):
- """Fetch reale dei beacon dalle API OIDC."""
- if not sec or 'oidc' not in sec:
- return None, "Segreti mancanti"
- try:
- auth_res = requests.post(
- cfg['api']['token_url'],
- data={
- "grant_type": "password",
- "client_id": cfg['api']['client_id'],
- "client_secret": sec['oidc']['client_secret'],
- "username": sec['oidc']['username'],
- "password": sec['oidc']['password'],
- },
- verify=cfg['api'].get('verify_tls', False),
- timeout=5
- )
- token = auth_res.json().get("access_token")
- res = requests.get(
- cfg['api']['get_beacons_url'],
- headers={"Authorization": f"Bearer {token}"},
- verify=cfg['api'].get('verify_tls', False),
- timeout=5
- )
- return res.json(), "OK"
- except Exception as e:
- return None, str(e)
-
- def show_system_status(cfg, sec=None):
- st.title("🛰️ Diagnostica & Sniffer")
-
- # --- 1. RISORSE DI SISTEMA ---
- st.subheader("🖥️ Risorse Hardware")
- m = get_system_metrics()
- c1, c2, c3, c4 = st.columns(4)
- c1.metric("CPU", f"{m['cpu']}%")
- c2.metric("RAM", f"{m['ram']}%")
- c3.metric("Disco", f"{m['disk']}%")
- c4.metric("Rete", f"{m['net_recv']:.1f} MB")
-
- st.divider()
-
- # --- 2. CONNETTIVITÀ & DATI API ---
- st.subheader("🔌 Connettività & API")
- col_api, col_mq = st.columns(2)
-
- with col_api:
- st.markdown("**Server API OIDC**")
- beacons_api_data, api_msg = get_api_data(cfg, sec)
- if beacons_api_data:
- st.success(f"✅ Connesso ({len(beacons_api_data)} beacon)")
- with st.expander("Visualizza Tabella Dati API"):
- # Mostriamo i dati API in una tabella senza scroll eccessivo
- df_api = pd.DataFrame(beacons_api_data)
- st.table(df_api.head(10))
- else:
- st.error(f"❌ Errore: {api_msg}")
-
- with col_mq:
- st.markdown("**Broker MQTT**")
- mq_host = cfg.get('mqtt', {}).get('host', '127.0.0.1')
- st.info(f"Host: `{mq_host}`")
- st.success("✅ Configurazione Caricata")
-
- st.divider()
-
- # --- 3. SNIFFER DATI MQTT ---
- st.subheader("🎯 Sniffer Real-Time")
- st.caption("Inserisci un MAC per intercettare il traffico live (10 secondi)")
-
- target_mac = st.text_input("MAC da sniffare (es. ac233fc1dd49)", "").lower().replace(":", "")
-
- if st.button("🚀 AVVIA CATTURA", use_container_width=True, type="primary"):
- if not target_mac:
- st.warning("Inserisci un MAC prima di iniziare.")
- else:
- captured = []
- def on_message(client, userdata, message):
- payload = message.payload.decode()
- topic = message.topic
- if target_mac in topic.lower() or target_mac in payload.lower():
- captured.append({
- "Ora": time.strftime("%H:%M:%S"),
- "Topic": topic,
- "Dati": payload[:100] + "..." # Accorciamo per la tabella
- })
-
- client = mqtt.Client(client_id=f"Sniffer_{int(time.time())}")
- try:
- client.on_message = on_message
- client.connect(cfg['mqtt']['host'], cfg['mqtt']['port'], 60)
- client.subscribe("#")
- client.loop_start()
-
- with st.status("Cattura in corso...") as status:
- progress = st.progress(0)
- for i in range(100):
- time.sleep(0.1)
- progress.progress(i + 1)
- client.loop_stop()
- status.update(label="Cattura completata!", state="complete")
-
- if captured:
- st.success(f"Intercettati {len(captured)} messaggi per `{target_mac}`")
- # Usiamo st.table per evitare le slidebar (renderizza tutto il contenuto)
- st.table(pd.DataFrame(captured))
- else:
- st.warning("Nessun messaggio trovato. Controlla che il dispositivo sia acceso.")
- except Exception as e:
- st.error(f"Connessione fallita: {e}")
|