Improve Dashboard functionality
This commit is contained in:
@@ -98,7 +98,7 @@ def carica_rubrica():
|
||||
UTENTI_SIP_DMR = carica_rubrica()
|
||||
|
||||
# ====================================================================
|
||||
# DASHBOARD MANAGER (Motore Dati)
|
||||
# DASHBOARD MANAGER (Motore Dati - Modificato Sincrono)
|
||||
# ====================================================================
|
||||
class DashboardManager:
|
||||
def __init__(self):
|
||||
@@ -112,7 +112,7 @@ class DashboardManager:
|
||||
try: await ws.send_str(msg_str)
|
||||
except Exception: self.ws_clients.discard(ws)
|
||||
|
||||
async def inizia_chiamata(self, id_chiamata, direzione, mittente, destinatario):
|
||||
def inizia_chiamata(self, id_chiamata, direzione, mittente, destinatario):
|
||||
nom_mittente = get_nominativo(mittente)
|
||||
nom_dest = get_nominativo(destinatario)
|
||||
|
||||
@@ -126,20 +126,20 @@ class DashboardManager:
|
||||
"stato": "ON"
|
||||
}
|
||||
self.chiamate_attive[id_chiamata] = dati
|
||||
await self.broadcast({"evento": "chiamata_iniziata", "dati": dati})
|
||||
asyncio.create_task(self.broadcast({"evento": "chiamata_iniziata", "dati": dati}))
|
||||
|
||||
async def aggiorna_rx(self, id_chiamata):
|
||||
def aggiorna_rx(self, id_chiamata):
|
||||
if id_chiamata in self.chiamate_attive:
|
||||
self.chiamate_attive[id_chiamata]["ultimo_frame"] = time.time()
|
||||
|
||||
async def termina_chiamata(self, id_chiamata):
|
||||
def termina_chiamata(self, id_chiamata):
|
||||
if id_chiamata in self.chiamate_attive:
|
||||
dati = self.chiamate_attive.pop(id_chiamata)
|
||||
dati["fine"] = time.time()
|
||||
dati["durata"] = round(dati["fine"] - dati["inizio"], 1)
|
||||
dati["stato"] = "OFF"
|
||||
self.storico.appendleft(dati)
|
||||
await self.broadcast({"evento": "chiamata_terminata", "dati": dati})
|
||||
asyncio.create_task(self.broadcast({"evento": "chiamata_terminata", "dati": dati}))
|
||||
|
||||
async def watchdog_rx(self):
|
||||
while True:
|
||||
@@ -147,7 +147,7 @@ class DashboardManager:
|
||||
ora = time.time()
|
||||
for id_chiamata, dati in list(self.chiamate_attive.items()):
|
||||
if dati["direzione"] == "RX" and ora - dati.get("ultimo_frame", ora) > 1.5:
|
||||
await self.termina_chiamata(id_chiamata)
|
||||
self.termina_chiamata(id_chiamata)
|
||||
|
||||
# ====================================================================
|
||||
# ENDPOINT WEB (aiohttp)
|
||||
@@ -353,10 +353,10 @@ class SessionManager:
|
||||
self.gestisci_ptt(sess, False)
|
||||
self.vocoder.rilascia_porta(f"SIP_{call_id}")
|
||||
|
||||
# PULIZIA FORZATA: Chiudiamo eventuali righe RX rimaste appese per questo interno
|
||||
# Chiusura sincrona per evitare code
|
||||
for id_dash in list(dashboard_app.chiamate_attive.keys()):
|
||||
if id_dash.startswith("RX_") and id_dash.endswith(f"_{call_id}"):
|
||||
asyncio.create_task(dashboard_app.termina_chiamata(id_dash))
|
||||
dashboard_app.termina_chiamata(id_dash)
|
||||
|
||||
del self.sessioni[call_id]
|
||||
asyncio.create_task(dashboard_app.broadcast({"evento": "estensioni_update"}))
|
||||
@@ -372,11 +372,11 @@ class SessionManager:
|
||||
|
||||
nome_base = get_nominativo(sess.dmr_id)
|
||||
mittente_display = f"{nome_base} (Est. {sess.chiamante})"
|
||||
asyncio.create_task(dashboard_app.inizia_chiamata(id_dash_tx, "TX", mittente_display, sess.tg_destinazione))
|
||||
dashboard_app.inizia_chiamata(id_dash_tx, "TX", mittente_display, sess.tg_destinazione)
|
||||
elif stato is False and sess.ptt_attivo:
|
||||
sess.ptt_attivo = False
|
||||
if self.openbridge: self.openbridge.chiudi_flusso_chiamata(sess)
|
||||
asyncio.create_task(dashboard_app.termina_chiamata(id_dash_tx))
|
||||
dashboard_app.termina_chiamata(id_dash_tx)
|
||||
|
||||
def gestisci_dtmf_digit(self, sess, digit):
|
||||
if sess.ptt_attivo: return
|
||||
@@ -424,9 +424,9 @@ class SessionManager:
|
||||
|
||||
if id_dash_rx not in dashboard_app.chiamate_attive:
|
||||
dest_display = f"{sess.chiamante} (TG {tg_arrivo})"
|
||||
asyncio.create_task(dashboard_app.inizia_chiamata(id_dash_rx, "RX", src_id, dest_display))
|
||||
dashboard_app.inizia_chiamata(id_dash_rx, "RX", src_id, dest_display)
|
||||
else:
|
||||
asyncio.create_task(dashboard_app.aggiorna_rx(id_dash_rx))
|
||||
dashboard_app.aggiorna_rx(id_dash_rx)
|
||||
|
||||
if sess.ultimo_src_id != src_id:
|
||||
sess.ultimo_src_id = src_id
|
||||
@@ -540,9 +540,7 @@ class SipProtocol(asyncio.DatagramProtocol):
|
||||
def connection_made(self, transport): self.manager.sip_transport = transport
|
||||
def datagram_received(self, data, addr):
|
||||
if addr[0] != FREEPBX_IP and FREEPBX_IP != "0.0.0.0": return
|
||||
msg = data.decode('utf-8', errors='ignore')
|
||||
|
||||
# FIX: splitlines() digerisce correttamente sia \r\n che \n
|
||||
msg = data.decode('utf-8', errors='ignore').lstrip()
|
||||
lines = msg.splitlines()
|
||||
headers = {line.split(":", 1)[0].strip().upper(): line.split(":", 1)[1].strip() for line in lines[1:] if ":" in line}
|
||||
call_id = headers.get('CALL-ID', '')
|
||||
@@ -585,7 +583,6 @@ class SipProtocol(asyncio.DatagramProtocol):
|
||||
f"Max-Forwards: 70\r\nFrom: {headers.get('FROM', '')}\r\nTo: {headers.get('TO', '')}\r\n"
|
||||
f"Call-ID: {call_id}\r\nCSeq: {headers.get('CSEQ', '').split()[0]} ACK\r\nContent-Length: 0\r\n\r\n")
|
||||
self.manager.sip_transport.sendto(ack.encode('utf-8'), addr)
|
||||
# FIX: Aggiunto supporto al CANCEL e chiusura forzata in dashboard
|
||||
elif msg.startswith("BYE") or msg.startswith("CANCEL"):
|
||||
self.manager.termina_chiamata(call_id)
|
||||
resp = (f"SIP/2.0 200 OK\r\nVia: {headers.get('VIA', '')}\r\nFrom: {headers.get('FROM', '')}\r\nTo: {headers.get('TO', '')}\r\n"
|
||||
|
||||
Reference in New Issue
Block a user