Vai al contenuto

Midserver (mdm_mid_server)

Il server centrale del sistema nuovo. Riceve stato ed eventi dai box, inoltra i comandi di pannello e qAlarm, alimenta lo stream di eventi verso qAlarm.

Due versioni

v2 (Flask) v3 (FastAPI)
Branch main (2.2.0), dev (2.4.0) refactor/v1 (3.0.0)
Dove gira prod, ServerIT, container midserver, immagine mid-server:2.2.0 costruita sul server Coolify dev, mdm.dev.midserver.bsqdev.uk
Server web flask run in modalità sviluppo (M4) uvicorn
Porta 5000 5005
Health /health/status (JWT + round-trip MQTT, inutile per i controlli automatici) /health
MQTT paho-mqtt in thread aiomqtt
Task ritardati celery celery
Ultimo commit dev 03/06/2026 18/06/2026

La v3 è una riscrittura: le modifiche della v2 non si possono unire con un merge, vanno riportate a mano. Uno dei due autori (Franco) non è più in azienda.

Cosa contiene lo stack (compose)

Midserver, celery_worker, MySQL (q_alarm_mid), Redis, Mosquitto, OvenMediaEngine, phpMyAdmin; in prod anche Nginx Proxy Manager e il container del pannello. Dettagli di prod in ServerIT, di dev in Coolify dev.

Interfacce

Verso i box (chiamate dai box, mdm_installation/app/clients/mid_server_client.py):

Endpoint v2 v3
POST installation/new/register ✅ ✅
POST common/installation/sync_state/{mac} ✅ ✅ (redirect)
POST common/installation/error/{mac} ✅ ✅ (redirect)
POST common/installation/callback/{token} ✅ ✅ (redirect)
POST common/installation/async/callback/{token} ✅ ❌ manca
POST installation/receive_log/{mac} ✅ ❌ manca
POST chat/snapshot ❌ ❌ (non serve: nessuno attiva più la funzione, D17)

Verso l'app Protexia e api.bsq: - pagina HTML GET /installation/live_stream/<token>?mac= aperta dall'app: ✅ v2, ❌ manca nella v3 (M22, T3.12); - 17 chiamate di api.bsq (sound, disarm, privacy mode, nuove installazioni, snapshot, restart, info, config, alarm_in, live_stream): 15 presenti nella v3; sound/upload manca anche nella v2; frigate/pin/trigger riguarda il PIN, che nessun box ha.

Verso qAlarm 2: 14 chiamate, tutte presenti nella v3.

MQTT: il midserver ascolta q_security/event e q_security/log, pubblica i comandi sul topic dell'installazione. La v3 sceglie il topic in base alla versione del box (app/core/mqtt/installation_command_publish_router.py, soglia 10.0.0).

Verso il pannello e qAlarm: API REST con JWT. Matrice completa delle chiamate del pannello in parita-midserver-v3.md.

Verso qAlarm: Redis Stream event_stream (app/events/sinks/redis_stream_sink.py).

Dati

  • Redis: stato dei box (chiave = MAC, senza scadenza), presenza online (MAC_<mac>, con scadenza), risposte ai comandi (liste per token), contatori errori, stream eventi, coda celery. È l'unico registro delle installazioni.
  • MySQL q_alarm_mid: backup delle configurazioni (installations), registrazioni in corso (new_installations), log delle richieste del pannello, errori, eventi, utenti, trigger e pianificazioni.

Vedi dati e registro installazioni.

Problemi noti

M3 (Redis senza persistenza vera), M4 (Flask dev server), M5 (health), M6 (consumer duplicati con più istanze), M7 (eventi MQTT persi durante i fermi), M8 (backup MySQL), M10 (KEYS *), M16 (credenziali nell'installer). Dettagli in rischi e problemi.

Build e deploy

  • Nessuna pipeline: nessun CodeBuild, nessun trigger. Deploy in prod = SSH sul server, git pull, docker compose --env-file .env.prod up -d --build (o make prod-up). Il server ha una modifica locale non committata al docker-compose.yml (immagine di phpMyAdmin).
  • Esiste un repository ECR mdm8670650/mid-server, ma non c'è una build che lo alimenti.
  • Su Coolify dev il deploy è manuale dal pannello di Coolify.

Cose da sapere prima di modificarlo

  • Nel codice c'è una parte datata scritta da Mohammad e Marco nelle prime versioni (per esempio la parte OME), poi in parte sostituita da Franco; sul server è rimasta anche roba vecchia (Michele, 28/10). Prima di portare funzioni nella v3, chiarire con Mohammad cosa è ancora usato. Michele ha preparato l'infrastruttura e il container di ewelink, ma non conosce il codice del midserver.

  • I box chiamano http://172.16.16.253:5000/: la porta 5000 e i path esistenti sono un contratto.

  • Il nome dei campi e dei path con errori di battitura (request/erros, contianer, compilete_registration) è un contratto con pannello e box.
  • Prima di cambiare il formato dello stato, ricordare che il pannello legge lo stato così come lo manda il box: il midserver fa da proxy.