25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 

129 satır
4.7 KiB

  1. import streamlit as st
  2. import pandas as pd
  3. import psutil
  4. import os
  5. import time
  6. import json
  7. import paho.mqtt.client as mqtt
  8. import requests
  9. def get_system_metrics():
  10. """Recupera statistiche hardware del server."""
  11. return {
  12. "cpu": psutil.cpu_percent(interval=None),
  13. "ram": psutil.virtual_memory().percent,
  14. "disk": psutil.disk_usage('/').percent,
  15. "net_recv": psutil.net_io_counters().bytes_recv / (1024**2)
  16. }
  17. def get_api_data(cfg, sec):
  18. """Fetch reale dei beacon dalle API OIDC."""
  19. if not sec or 'oidc' not in sec:
  20. return None, "Segreti mancanti"
  21. try:
  22. auth_res = requests.post(
  23. cfg['api']['token_url'],
  24. data={
  25. "grant_type": "password",
  26. "client_id": cfg['api']['client_id'],
  27. "client_secret": sec['oidc']['client_secret'],
  28. "username": sec['oidc']['username'],
  29. "password": sec['oidc']['password'],
  30. },
  31. verify=cfg['api'].get('verify_tls', False),
  32. timeout=5
  33. )
  34. token = auth_res.json().get("access_token")
  35. res = requests.get(
  36. cfg['api']['get_beacons_url'],
  37. headers={"Authorization": f"Bearer {token}"},
  38. verify=cfg['api'].get('verify_tls', False),
  39. timeout=5
  40. )
  41. return res.json(), "OK"
  42. except Exception as e:
  43. return None, str(e)
  44. def show_system_status(cfg, sec=None):
  45. st.title("🛰️ Diagnostica & Sniffer")
  46. # --- 1. RISORSE DI SISTEMA ---
  47. st.subheader("🖥️ Risorse Hardware")
  48. m = get_system_metrics()
  49. c1, c2, c3, c4 = st.columns(4)
  50. c1.metric("CPU", f"{m['cpu']}%")
  51. c2.metric("RAM", f"{m['ram']}%")
  52. c3.metric("Disco", f"{m['disk']}%")
  53. c4.metric("Rete", f"{m['net_recv']:.1f} MB")
  54. st.divider()
  55. # --- 2. CONNETTIVITÀ & DATI API ---
  56. st.subheader("🔌 Connettività & API")
  57. col_api, col_mq = st.columns(2)
  58. with col_api:
  59. st.markdown("**Server API OIDC**")
  60. beacons_api_data, api_msg = get_api_data(cfg, sec)
  61. if beacons_api_data:
  62. st.success(f"✅ Connesso ({len(beacons_api_data)} beacon)")
  63. with st.expander("Visualizza Tabella Dati API"):
  64. # Mostriamo i dati API in una tabella senza scroll eccessivo
  65. df_api = pd.DataFrame(beacons_api_data)
  66. st.table(df_api.head(10))
  67. else:
  68. st.error(f"❌ Errore: {api_msg}")
  69. with col_mq:
  70. st.markdown("**Broker MQTT**")
  71. mq_host = cfg.get('mqtt', {}).get('host', '127.0.0.1')
  72. st.info(f"Host: `{mq_host}`")
  73. st.success("✅ Configurazione Caricata")
  74. st.divider()
  75. # --- 3. SNIFFER DATI MQTT ---
  76. st.subheader("🎯 Sniffer Real-Time")
  77. st.caption("Inserisci un MAC per intercettare il traffico live (10 secondi)")
  78. target_mac = st.text_input("MAC da sniffare (es. ac233fc1dd49)", "").lower().replace(":", "")
  79. if st.button("🚀 AVVIA CATTURA", use_container_width=True, type="primary"):
  80. if not target_mac:
  81. st.warning("Inserisci un MAC prima di iniziare.")
  82. else:
  83. captured = []
  84. def on_message(client, userdata, message):
  85. payload = message.payload.decode()
  86. topic = message.topic
  87. if target_mac in topic.lower() or target_mac in payload.lower():
  88. captured.append({
  89. "Ora": time.strftime("%H:%M:%S"),
  90. "Topic": topic,
  91. "Dati": payload[:100] + "..." # Accorciamo per la tabella
  92. })
  93. client = mqtt.Client(client_id=f"Sniffer_{int(time.time())}")
  94. try:
  95. client.on_message = on_message
  96. client.connect(cfg['mqtt']['host'], cfg['mqtt']['port'], 60)
  97. client.subscribe("#")
  98. client.loop_start()
  99. with st.status("Cattura in corso...") as status:
  100. progress = st.progress(0)
  101. for i in range(100):
  102. time.sleep(0.1)
  103. progress.progress(i + 1)
  104. client.loop_stop()
  105. status.update(label="Cattura completata!", state="complete")
  106. if captured:
  107. st.success(f"Intercettati {len(captured)} messaggi per `{target_mac}`")
  108. # Usiamo st.table per evitare le slidebar (renderizza tutto il contenuto)
  109. st.table(pd.DataFrame(captured))
  110. else:
  111. st.warning("Nessun messaggio trovato. Controlla che il dispositivo sia acceso.")
  112. except Exception as e:
  113. st.error(f"Connessione fallita: {e}")