Repository navigation
Releases: Molonverona/BHAM
Release list
Release v1.3.0
Avanzamento di tutte le dipendenze alle versioni correnti, driver di protocollo compresi. In v1.2.5 erano stati lasciati pinnati proprio perché governano il comportamento sul filo: l'avanzamento ha confermato il rischio, portando a galla tre rotture reali che la suite di test non poteva vedere. Tutte risolte, e ora coperte da test che parlano con le librerie vere.
Risolto (critico)
- Ogni lettura e scrittura Modbus reale era rotta da pymodbus 3.16 (
scanners/modbus.py,scanners/field_tools.py):countè diventato keyword-only:read_holding_registers(0, 1, slave=…)sollevaTypeError.slave=è stato rinominatodevice_id=su tutte le letture e scritture.pymodbus.mei_messageè stato spostato inpymodbus.pdu.mei_message, e nella richiesta FC43slave=è diventatodev_id=.client.execute()ha ora due argomenti posizionali:execute(no_response_expected, request).- Corretti tutti i 17 siti di chiamata. Il Simulatore d'Impianto Virtuale intercetta le operazioni Modbus prima che raggiungano pymodbus, quindi i 162 test preesistenti passavano comunque: in campo ogni lettura reale sarebbe fallita.
- Letture di registri silenziosamente vuote (
scanners/field_tools.py):- Il tipo di dato veniva scelto annusando gli attributi della risposta (
rr.bits[:count] if hasattr(rr, "bits") else rr.registers). Da pymodbus 3.16 ogni PDU di risposta esponebits(vuoto per le risposte a registri), quindi tutte le letture di holding e input register restituivano una lista vuota dichiarandosuccess: true: l'operatore avrebbe visto l'esito positivo senza alcun valore, difetto peggiore di un errore esplicito. - Il tipo si deduce ora dal function code, che è noto ed esplicito.
- Il tipo di dato veniva scelto annusando gli attributi della risposta (
Aggiunto
- Test dei driver contro le librerie reali (
tests/test_protocol_drivers.py):- Viene avviato un server Modbus TCP di pymodbus su loopback con un datastore noto, e le funzioni di BHAM ci parlano sopra con il simulatore disattivato: letture holding/input con valori esatti, offset e
countrispettati, round-trip di scrittura singola e multipla, scansione Modbus TCP che censisce il server, Smart Register Scan sul percorso reale, e blocco del Safe Mode Interlock verificato su un bus vero. - I generatori di report sono verificati sull'artefatto prodotto: il PDF deve avere intestazione
%PDF-, terminatore%%EOFe dimensione plausibile; l'Excel deve riaprirsi con i suoi fogli. Con un avanzamento major di reportlab, "non ha sollevato eccezioni" non è una verifica. - Presidio sulle firme delle librerie (
device_id,countkeyword-only,dev_id, ordine degli argomenti diexecute, punti d'ingresso di bacpypes3 e scapy): un rename a monte viene ora intercettato in CI invece che in cantiere.
- Viene avviato un server Modbus TCP di pymodbus su loopback con un datastore noto, e le funzioni di BHAM ci parlano sopra con il simulatore disattivato: letture holding/input con valori esatti, offset e
Modificato
- Dipendenze: tutte alle versioni correnti:
- Driver di protocollo e report: pymodbus
3.7.2→3.16.1, bacpypes30.0.102→0.0.110, scapy2.6.0→2.8.0, reportlab4.2.5→5.1.0, psutil→7.2.2. - Infrastruttura già allineata in v1.2.5 e riconfermata: fastapi
0.162.0, uvicorn0.54.0, websockets17.3, pydantic2.14.1, pydantic-settings2.16.1, aiofiles25.1.0, python-dotenv1.2.4, python-multipart0.0.32. - Minimi allineati anche in
pyproject.toml: con le API cambiate, una versione precedente non è più supportabile.
- Driver di protocollo e report: pymodbus
bham.spec: dichiaratipymodbus.pduepymodbus.pdu.mei_message, che per l'import tardivo della FC43 devono finire nel bundle. Verificata la presenza effettiva nel PYZ dell'eseguibile compilato (45 moduli pymodbus, 194 scapy).
Test
- Suite estesa da 162 a 179 test, verdi su Linux e Windows.
Resta da validare su impianto
I test parlano con un server Modbus TCP reale: coprono la forma delle chiamate, la decodifica e il round-trip, ma non la temporizzazione del bus RS485 fisico (auto-baud, inter-frame gap, terminazioni), la FC43 su seriale, il discovery BACnet/IP su rete di impianto né la cattura L2 con Npcap. Queste restano verifiche da fare con strumentazione in linea.
What's Changed
- BHAM v1.3.0 – tutte le librerie alle versioni correnti e driver di protocollo riparati by @Molonverona in #3
Full Changelog: v1.2.5...v1.3.0
Release v1.2.5
Versione dedicata al controllo generale dell'applicazione: i rilievi dell'audit storico sono stati ricontrollati uno per uno sul codice attuale (tutti confermati chiusi) e sono emersi 6 difetti nuovi, qui risolti. Il dettaglio completo, con la tabella di verifica, è in AUDIT.md.
Risolto (critico)
- L'arresto d'emergenza globale rispondeva HTTP 500 (
api/routes.py,scanners/base.py):POST /api/v1/scan/abortdichiaraScanAbortResponse.sessionscomelist[str]("Elenco ID delle sessioni terminate"), ma l'handler restituiva l'intero diabort_all(). La validazione della risposta di FastAPI falliva e l'endpoint rispondeva 500 Internal Server Error: la funzione di arresto d'emergenza non ha mai funzionato via HTTP.- Il difetto era sfuggito perché la suite invoca le funzioni handler direttamente, bypassando la validazione contro il
response_model: nessun test esercitava i contratti dichiarati. abort_all()ritorna ora la lista degli ID effettivamente fermati, coerente con lo schema e più informativa.
Aggiunto
- Mutua esclusione sulle risorse di campo esclusive (
core/resource_guard.py):- Una porta RS485 ammette un solo lettore, ma nulla impediva di avviare contemporaneamente una scansione Modbus RTU e uno sniffer passivo sulla stessa
/dev/ttyUSB0: i due consumatori si rubano i byte a vicenda, falsando mappatura e diagnosi di Bus Health senza alcun avviso. Lo stesso valeva per il discovery BACnet/IP (bind della 47808) e per discovery KNXnet/IP e Group Monitor, che condividono il socket multicast 3671. - Le route di avvio rivendicano ora la risorsa; il conflitto viene rifiutato con HTTP 409 indicando quale operazione la detiene, da quanti secondi e come arrestarla. La verifica precede la creazione della sessione, così un conflitto non lascia una sessione fantasma nello storico.
- Risorsa e stato di abort vengono liberati quando il task termina, in qualunque modo, tramite done-callback.
- Nuovo endpoint
GET /api/v1/system/resourcesper ispezionare le risorse occupate: serve a capire perché un avvio è stato rifiutato.
- Una porta RS485 ammette un solo lettore, ma nulla impediva di avviare contemporaneamente una scansione Modbus RTU e uno sniffer passivo sulla stessa
- Test di contratto sulle risposte API (
tests/test_resource_contracts.py):- L'uscita degli handler viene validata contro il
response_modelrealmente dichiarato sulla route — la verifica che avrebbe intercettato l'arresto d'emergenza rotto — e ogni endpoint/scan*deve dichiararne uno.
- L'uscita degli handler viene validata contro il
- Verifica del canale WebSocket nello smoke test (
scripts/smoke_frozen.py):- La telemetria live è il cuore della console di collaudo, ma lo smoke test copriva solo le route REST: un bundle con l'implementazione WebSocket incompleta lo avrebbe superato. Ora apre una connessione al canale live e pretende lo snapshot iniziale, verificando anche il registro risorse.
Modificato
- Registro degli abort: perdita di memoria e conteggio fuorviante (
scanners/base.py):_abort_eventsaccumulava una voce per ogni scansione e non veniva mai ripulito, crescendo per tutta la durata del processo. La pulizia avviene ora al termine del task.abort_all()ritornava il numero di sessioni mai registrate invece delle scansioni attive;abort_session()segnala ora una sola volta e riporta se ha effettivamente fermato qualcosa.
- Storico sessioni: tetto, lock e azzeramento coerente (
data/state.py):self.sessionsnon aveva alcun limite ed era serializzato integralmente in ognisnapshot(), cioè a ogni connessione WebSocket e a ogni evento di stato: durante una giornata di collaudo con decine di scansioni il payload cresceva di continuo. Introdotto il tettomax_sessions(200) che scarta le più vecchie fra quelle concluse, mai le scansioni in corso.sessionsera l'unica collezione mutata fuori da_state_lockmentresnapshot()la itera tenendolo — residuo del rilievo #2, corretto altrove ma non qui. Gli scanner aggiornano le sessioni da thread di executor, quindi la lettura poteva risultare incoerente.clear()azzera ora lo storico concluso come le altre collezioni, preservando le sessioni attive.
- Dipendenze: aggiornamento con cautela differenziata:
- 12 delle 14 dipendenze pinnate erano ferme da circa due anni. Aggiornate e verificate quelle infrastrutturali: fastapi
0.115.0→0.162.0, uvicorn0.30.6→0.54.0, websockets13.1→17.3, pydantic2.9.2→2.14.1, pydantic-settings2.5.2→2.16.1, aiofiles24.1.0→25.1.0, python-dotenv1.0.1→1.2.4, python-multipart0.0.9→0.0.32. - Deliberatamente lasciate pinnate
pymodbus,bacpypes3,scapyereportlab: governano il comportamento sul filo (RS485, BACnet/IP, cattura L2) e l'impaginazione dei certificati PDF. Il simulatore non sostituisce una validazione su hardware reale, quindi il loro avanzamento resta da pianificare con strumentazione in linea. bham.spec: rimossiwsprotoewsproto_impl, non più dipendenze diuvicorn[standard](producevano solo un avviso di hiddenimport mancante a ogni build); aggiunta l'implementazione sans-io che--ws autoseleziona.
- 12 delle 14 dipendenze pinnate erano ferme da circa due anni. Aggiornate e verificate quelle infrastrutturali: fastapi
- Spegnimento più pulito (
main.py): le risorse rivendicate vengono rilasciate all'arresto, così un riavvio immediato non trova porte seriali o socket marcati come occupati da sessioni ormai morte; il numero di scansioni interrotte viene registrato nel log.
Test
- Suite estesa da 140 a 162 test, verdi su Linux e Windows. Le nuove aree coperte: contratti di risposta contro i
response_modeldichiarati, registro di mutua esclusione (conflitto, idempotenza, rilascio protetto dal proprietario), rifiuto HTTP 409 delle route di avvio senza sessioni fantasma, rilascio di risorsa e stato di abort al termine del task, tetto e ritenzione dello storico sessioni.
What's Changed
- BHAM v1.2.5 – controllo generale, mutua esclusione risorse, dipendenze by @Molonverona in #2
Full Changelog: v1.2.0...v1.2.5
Release v1.2.0
Risolto (critico)
- Il binario standalone non si avviava: installazione Windows inutilizzabile (
main.py,bham.spec):main.pyconsegnava a uvicorn la stringa di import"main:app". In un bundle PyInstaller lo script di ingresso viene eseguito come__main__e il modulomainnon è importabile: l'eseguibile terminava immediatamente con
ERROR: Error loading ASGI app. Could not import module "main".- Il guasto colpiva tutti gli artefatti compilati:
bham.exeinstallato dall'installer Inno Setup, l'edizione portablebham-windows-x64-portable.zipe il binario Linuxbham-linux-x64.tar.gz. Restava funzionante solo l'avvio da sorgente (bham.py/bham.bat), motivo per cui la CI non lo rilevava. - Introdotta
server_target(): in modalità congelata viene passato direttamente l'oggetto applicazione, da sorgente si mantiene la stringa di import necessaria all'auto-reload. L'auto-reload viene ora disattivato d'ufficio quando il target non è una stringa. - Il re-exec automatico nel virtualenv è disattivato nel binario congelato: l'eseguibile porta con sé il proprio runtime e non deve mai saltare in un
.venvpresente accanto a sé. - Rimossa la dipendenza del runtime dal launcher:
main.pynon importa piùbham.py(le utility di apertura browser vivono incore/browser.py, solo stdlib).
Aggiunto
- Preflight di avvio & fallback automatico di porta (
core/preflight.py):- Verifica della directory dati effettivamente scrivibile (diagnostica immediata delle installazioni in
Program Files), della presenza reale degli asset del frontend nel bundle (causa tipica della pagina bianca) e della disponibilità della porta di ascolto. - Se la porta 8765 è occupata da un'istanza già avviata, BHAM passa automaticamente alla prima porta libera invece di terminare con un traceback, allineando log di avvio, URL LAN e QR code di pairing alla porta reale.
- Messaggi di errore azionabili in italiano al posto delle eccezioni non gestite;
--no-port-fallbackripristina il comportamento rigido.
- Verifica della directory dati effettivamente scrivibile (diagnostica immediata delle installazioni in
- Interfaccia a riga di comando del binario standalone (
main.py):- L'eseguibile accettava e ignorava qualunque argomento. Nuovi flag:
--host,--port,--no-browser,--demo,--no-port-fallback,--check(preflight ed uscita, 0 = OK) e--version.
- L'eseguibile accettava e ignorava qualunque argomento. Nuovi flag:
- Rilevamento regola Windows Firewall (
core/system_requirements.py,installer/bham.iss):check_windows_firewall_rule()verifica vianetshla presenza della regola che autorizza BHAM: la sua assenza è la causa più frequente di "il QR code non si apre dal telefono", con il demone raggiungibile solo da localhost.- L'installer crea la regola in ingresso su richiesta (porta 8765/TCP, profili
privateedomain— maipublic) e la rimuove alla disinstallazione.
- Verifica dei motori di protocollo nel pacchetto compilato (
core/preflight.py,main.py --check):check_engines()tenta il caricamento di Modbus, BACnet, sniffer L2, seriale RS485, report Excel/PDF e telemetria di sistema. In un bundle PyInstaller unhiddenimportdimenticato non si manifesta all'avvio: l'eseguibile parte regolarmente e fallisce settimane dopo, in cantiere, all'apertura della funzione. La verifica è particolarmente rilevante su Windows, dove scapy carica moduli di piattaforma diversi da quelli raccolti nella build Linux.- Distinzione esplicita fra
[ASSENTE](modulo non presente nel pacchetto → bundle incompleto, va reinstallato) e[LIMITATO](modulo presente ma non inizializzabile su quella macchina, tipicamente per l'assenza del driver Npcap): solo il primo caso fa fallire--check, evitando di suggerire una reinstallazione inutile. - Gli avvisi e i traceback che scapy scrive su stderr durante l'import vengono trattenuti, mantenendo leggibile l'esito della verifica.
- Collegamento "Verifica installazione" nel menu Start (
installer/verifica-installazione.bat,installer/bham.iss):- Script wrapper che esegue
bham.exe --checke mantiene la finestra aperta, con esito tradotto in azioni concrete ([ASSENTE]→ reinstallare,[LIMITATO]→ driver di sistema mancante). Il tecnico può così diagnosticare una postazione senza aprire un prompt dei comandi a mano. - Incluso anche nell'edizione portable, dove non esiste un menu Start.
- Script wrapper che esegue
- Manifest Windows: code page UTF-8 e percorsi lunghi (
bham.exe.manifest):activeCodePage = UTF-8(Windows 10 1903+): la console rende correttamente i messaggi accentati e i caratteri di cornice del banner di avvio, risolvendo il problema di codifica all'origine invece di aggirarlo.longPathAware = true(Windows 10 1607+): verbali di collaudo e snapshot di sessione salvati sotto cartelle di commessa profondamente annidate non superano più il limite di 260 caratteri.
- Smoke test del binario congelato (
scripts/smoke_frozen.py,.github/workflows/ci.yml):- Nuovo job CI su Linux e Windows che compila l'eseguibile, lo avvia davvero e verifica
--version,--check,/api/v1/health, la console web servita dal bundle e l'endpoint di diagnostica. È il controllo che intercetta le regressioni di packaging invisibili ai test unitari. - Su Windows il job compila anche l'installer Inno Setup e lo pubblica come artefatto scaricabile per il collaudo manuale: prima lo script
bham.issveniva compilato per la prima volta durante la release, dove un errore di sintassi blocca la pubblicazione. - La suite gira ora anche sui rami di lavoro (
claude/**,feature/**,fix/**) e può essere lanciata a richiesta (workflow_dispatch): in precedenza una feature branch non riceveva alcuna verifica fino all'apertura della pull request. - Arresto dell'eseguibile per albero di processi: in un bundle onefile PyInstaller il bootloader avvia l'applicazione come processo figlio, quindi su Windows
terminate()chiudeva solo il bootloader lasciando il server orfano con la porta occupata. Lo smoke test usa orataskkill /Te verifica esplicitamente il rilascio della porta.
- Nuovo job CI su Linux e Windows che compila l'eseguibile, lo avvia davvero e verifica
Verificato su Windows
- Build e avvio reale dell'eseguibile su
windows-latest:--version,--check(tutti e 7 i motori caricati dal bundle, scapy incluso con i suoi moduli di piattaforma Windows),/api/v1/health, console web e diagnostica. - Compilazione dello script Inno Setup con ISCC 6.7.1 e produzione dell'installer firmabile da 30,1 MB, pubblicato come artefatto di CI per il collaudo manuale.
- Metadati di packaging nella diagnostica (
/api/v1/system/diagnostics):- Nuovi campi
app_version,is_frozen,is_portable,listen_portewindows_firewall_ruleper il supporto di campo. - Il binario congelato non segnala più come "non supportata" la versione dell'interprete di sistema: il runtime è incorporato nell'eseguibile.
- Nuovi campi
Modificato
- Hardening del packaging Windows (
bham.spec):- Il manifest applicativo
bham.exe.manifest(UACasInvoker, DPI awarenessPerMonitorV2) era presente nel repository ma non veniva mai applicato all'eseguibile: ora viene generato con la versione corrente e incorporato. - Aggiunta la risorsa
VERSIONINFO(nome prodotto, versione, publisher, copyright): senza di essa SmartScreen e gli antivirus trattano l'eseguibile come binario anonimo. - UPX disattivato: la compressione corrompe alcune DLL del runtime Python e innesca falsi positivi antivirus sui bundle onefile, bloccando l'installazione.
- Versione letta direttamente da
pyproject.toml(unica fonte di verità) ehiddenimportsestesi (implementazioni HTTP/WebSocket di uvicorn,serial.tools.list_ports,core.preflight,core.browser,core.qr_svg,core.tag_exporter).
- Il manifest applicativo
- Installer Inno Setup (
installer/bham.iss):CloseApplications=yescon Restart Manager: l'aggiornamento sopra una versione precedente non fallisce più con "file in uso" quando BHAM è in esecuzione.- Aggiunti
SetupMutex,MinVersion=6.3,AppVerName,UninstallDisplayIcon,UninstallDisplayNamee le risorseVersionInfo*del setup.
- Launcher a doppio clic Windows (
bham.bat):- Il file conteneva caratteri Unicode (
⚡,–) resi illeggibili dalle code page legacy della console Windows (850 / 437): ora è puro ASCII, conchcp 65001per l'output del processo Python figlio. Un controllo CI impedisce la regressione. - Rilevamento esteso a Python 3.13 (
py -3.13e%LOCALAPPDATA%\Programs\Python\Python313), prima cercato solo per 3.12.
- Il file conteneva caratteri Unicode (
- Manifest winget (
winget/):InstallerUrlpuntava al repository errato (BacsHelp/BHAMinvece diMolonverona/BHAM) e a un asset inesistente (bham-windows-x64.zipinvece dibham-windows-x64-portable.zip): entrambe le installazioni via winget restituivano 404.- Il workflow di release genera e pubblica il manifest già compilato con lo SHA256 reale dell'asset.
- Variabili d'ambiente con prefisso di progetto (
core/config.py):BHAM_API_TOKENera documentato ma non veniva letto (la configurazione accettava soloAPI_TOKEN). Orahost,port,debug,api_tokenelan_auth_requiredaccettano sia il nome semplice sia la formaBHAM_*, coerentemente conBHAM_DEMO/BHAM_NO_BROWSER/BHAM_PORTABLE.
- Sincronizzazione versioni (
scripts/bump_version.py,.github/workflows/ci.yml):bham.bat,scripts/bootstrap_windows.ps1ecore/system_requirements.pycontenevano la versione in chiaro ma non erano coperti né dallo script di bump né dal controllo CI: erano rimasti indietro. Ora sono target di bump e il job statico verifica ogni file di packaging.
Test
- Suite estesa da 90 a 128 test unitari e di integrazione, eseguiti con successo su Linux e Windows: scelta del target ASGI in modalità congelata, flag CLI, preflight e fallback di porta, rilevamento firewall Windows, alias delle variabili d'ambiente, allineamento versioni su 15 file di packaging, validità dei manifest winget e hardening dello spec PyInstaller.
What's Changed
- BHAM v1.2.0 –...
Release v1.1.0
Aggiunto
-
Network Security, LAN Token & CORS Hardening (
main.py,core/config.py,api/routes.py,frontend/js/app.js):- Middleware di sicurezza
lan_security_middlewarecon token crittografico casuale a 16 byte (generato automaticamente o configurabile viaBHAM_API_TOKEN). - Esenzione automatica trasparente per tutte le connessioni originate da localhost e loopback (
127.0.0.1,::1). - Protezione zero-trust per connessioni LAN remote su tutte le chiamate REST e canali WebSocket (rifiuto con codice 4401 in assenza di token).
- Iniezione automatica del token di sicurezza nei codici QR generati per accoppiamento mobile immediato e protetto da tablet e smartphone di cantiere.
- Policy CORS formalmente hardening conforme agli standard OWASP (
allow_credentials=Falseconallow_origins=["*"]). - Risoluzione definitiva dell'audit issue #8.
- Middleware di sicurezza
-
KNX Group Monitor & Live Telegram Sniffer (
scanners/knx.py,api/routes.py,data/models.py,data/state.py,frontend/):- Ricevitore asincrono passivo multicast UDP su
224.0.23.12:3671(standard KNXnet/IP) per la cattura trasparente di frameROUTING_INDICATIONeTUNNELING_REQUEST. - Motore di parsing cEMI nativo con decodifica di Control Field (priorità system, urgent, normal, low), Hop Count, Indirizzo Sorgente Individuale, Indirizzo di Gruppo Destinazione (notazione a 3 livelli Main/Middle/Sub) e APCI Service (
GroupValueWrite,GroupValueResponse,GroupValueRead). - Decodificatore euristico DPT per datapoint comuni: DPT 1.001 Bool (
ON/OFF), DPT 5.001 Percentuale (0-100%), DPT 9.001 Float16 2-octet (°C), DPT 14.xxx Float32 IEEE 754 e stringhe ASCII DPT 16.001. - Generazione di telegrammi sintetici realistici nel Simulatore d'Impianto Virtuale in Demo Mode.
- Nuova scheda "KNX Monitor" nella console di collaudo con badge conteggio, filtro per gruppo/indirizzo, auto-scroll ed esportazione della sequenza in CSV.
- Endpoint REST dedicati:
POST /api/v1/knx/monitor/start,POST /api/v1/knx/monitor/stop,GET /api/v1/knx/telegrams,DELETE /api/v1/knx/telegrams.
- Ricevitore asincrono passivo multicast UDP su
-
BACnet Point Trend Polling & Integrazione Watch List (
scanners/field_tools.py,api/routes.py,frontend/js/app.js):- Nuovo endpoint di lettura real-time
POST /api/v1/tools/bacnet/readcon supporto completo a dispositivi fisici viabacpypes3e al Virtual Plant Simulator. - Pulsante 📈 Segui integrato direttamente in ogni riga del modale BACnet Object Explorer per aggiungere istantaneamente qualsiasi oggetto alla Watch List.
- Polling periodico automatico della Watch List esteso a oggetti BACnet con mini-grafici SVG sparkline, tracciamento min/max, calcolo delta e feedback audio hands-free.
- Esportazione unificata Modbus & BACnet in formato CSV.
- Nuovo endpoint di lettura real-time
-
Modbus Decodifica & Scrittura Estesa 32-bit e 64-bit (
scanners/field_tools.py):- Estensione di
decode_modbus_valueeencode_modbus_valuecon supporto a:- 32-bit:
uint32_be,uint32_le(word-swapped CDAB),int32_be,int32_le. - 64-bit:
float64_be(doppia precisione IEEE 754 su 4 registri) eint64.
- 32-bit:
- Estensione di
-
Manuale Tecnico & Guida Operativa di Campo:
- Aggiunto Capitolo 23 completo in Italiano, Inglese e Spagnolo (
MANUALE_UTENTE.md,frontend/MANUALE_UTENTE.mdefrontend/js/manual-content.js).
- Aggiunto Capitolo 23 completo in Italiano, Inglese e Spagnolo (
-
Session Diff Engine Evolvuto & As-Built Tracking (
core/session_diff.py,frontend/index.html,frontend/js/app.js):- Tracciamento analitico delle variazioni di stato collaudo (
commissioning_statuse note peritalicommissioning_notes) tra snapshot baseline e target per tutti i protocolli (Modbus, BACnet, KNX, Host IP). - Confronto dettagliato dei valori dei registri Modbus comuni (scostamenti di setpoint e registri di stato da vecchio a nuovo valore).
- Rilevamento variazioni degli elenchi oggetti BACnet censiti oltre al conteggio complessivo.
- Ricerca full-text istantanea integrata nella barra filtri del visualizzatore di confronto e pill cromatiche per gli esiti As-Built.
- Tracciamento analitico delle variazioni di stato collaudo (
-
Safe Mode Interlock Hardening & Estensione a Caldo (
core/safe_mode.py,api/routes.py,api/schemas.py,frontend/):- Nuovo endpoint
POST /api/v1/safe-mode/extende metodoextend(extra_minutes)protetto da lock rientrantethreading.RLock()per prolungare la finestra temporale attiva (+15m, +30m) senza interruzioni operative, con tracciamento crittografico WAL. - Memorizzazione persistente operatore/commessa in
localStoragecon auto-fill automatico all'apertura del modale. - Live dynamic ticker a 1Hz con countdown continuo al secondo (
MM:SS) sia nel modale che nel badge in testata. - Indicatore visivo di allerta per scadenza imminente (
bham-safe-mode-expiring) sotto i 2 minuti. - Intercettazione automatica dei comandi di forzatura bloccati con apertura contestuale del modale di sblocco.
- Nuovo endpoint
-
Cross-Platform Parity & Auto-Provisioning Prerequisiti (
bham.bat,scripts/bootstrap_windows.ps1,core/system_requirements.py,core/priv_check.py,api/):- Launcher a doppio clic Windows (
bham.bat): Rilevamento automatico di Python 3.12/3.13; se assente o obsoleto, chiede conferma all'utente e provvede al download e installazione autonoma tramite PowerShell e python.org. - Script PowerShell di bootstrap (
scripts/bootstrap_windows.ps1): Download e installazione controllata di Python 3.12 (con pip e PATH abilitati) e driver Npcap. - Modulo unificato requisiti di sistema (
core/system_requirements.py): Rilevamento completo e continuo di OS, runtime Python, virtualenv, driver di cattura L2 (Npcap su Windows, CAP_NET_RAW su Linux), porte seriali e strumenti companion (Wireshark/tshark). - Download controllato companion tools (
POST /api/v1/system/companions/download): Download su richiesta utente dell'installer ufficiale Npcap (npcap-1.80.exe) con registrazione WAL e guida all'installazione. - Endpoint diagnostico
/api/v1/system/diagnostics: Fornisce al frontend il quadro analitico dei requisiti di sistema e le azioni correttive consigliate. - Scheda "Diagnostica & Requisiti" nella Web UI: Tab dedicato nel centro impostazioni per monitorare la salute di sistema, con rilevamento istantaneo dell'assenza di Npcap su Windows e pulsante di download guidato 1-click.
- Launcher a doppio clic Windows (
-
Engine i18n & Sidebar Channel Hardening (
frontend/js/i18n.js,frontend/index.html):- Blindata la funzione
applyTranslations()con guardiaif (trans && trans !== key)per prevenire l'esposizione di chiavi grezze. - Copertura e allineamento trilingue (IT, EN, ES) al 100% su tutte le 332 chiavi dell'interfaccia (233 attributi
data-i18ne 15 chiavi runtime) e su tutti i 23 capitoli della documentazione tecnica.
- Blindata la funzione
-
Allineamento Versioni Core Exporters (
core/tag_exporter.py,reports/pdf.py):- Versionamento centralizzato tramite
settings.app_versionper esportazioni JSON di tag BMS e intestazioni dei certificati di collaudo PDF.
- Versionamento centralizzato tramite
-
Test Suite Completa BHAM: Espansione a 90 test unitari e di integrazione eseguiti con successo al 100% su Linux e Windows (copertura LAN security, cEMI parser, DPT decoding, Safe Mode extend, session diff con collaudo/registri, requisiti di sistema cross-platform e CI green).
-
Integrità WAL: Registro manovre certificato con oltre 1620 record concatenati SHA-256 e zero errori di catena.
Full Changelog: v1.0.0...v1.1.0
Release v1.0.0
Aggiunto
- Live Watch List & Register Polling Monitor (
frontend/js/app.js):- Monitoraggio continuo in tempo reale di registri Modbus selezionati (Holding e Input) con frequenze regolabili (500ms, 1s, 2s, 5s).
- Evidenziazione dinamica dei delta con transizioni cromatiche e buzzer audio hands-free sintetizzato via Web Audio API.
- Esportazione cronologica dei campionamenti in formato CSV.
- RS485 Stress Test & Latency Benchmark (
scanners/field_tools.py,api/routes.py,api/schemas.py):- Test diagnostico fisico del bus RS485/Modbus con calcolo in tempo reale di Packet Error Rate (PER %), latenza RTT (min, max, avg), jitter e frame scartati per checksum CRC corrotto.
- Diagnostica fisica guidata con raccomandazione analitica del baudrate ottimale.
- Endpoint dedicati
POST /api/v1/tools/modbus/benchmarkePOST /api/v1/modbus/benchmark.
- BMS/SCADA Multi-Vendor Tag Exporter (
core/tag_exporter.py,api/routes.py):- Esportazione istantanea dei punti e registri censiti nei formati nativi dei principali supervisori BMS: Tridium Niagara 4 (XML), Siemens Desigo CC (CSV), Schneider EcoStruxure Building Operation (CSV) e BACnet CSV generico.
- Endpoint dedicato
GET /api/v1/export/tags?format=standard_csv|niagara_csv|json.
- Accesso Mobile Hands-Free con Pairing QR Code (
core/qr_svg.py,api/routes.py):- Generatore vettoriale SVG standalone di QR Code per connessione istantanea da smartphone o tablet sulla rete LAN (
0.0.0.0:8765), 100% offline senza dipendenze cloud o esterne. - Endpoint dedicato
GET /api/v1/network/qr-code.
- Generatore vettoriale SVG standalone di QR Code per connessione istantanea da smartphone o tablet sulla rete LAN (
- As-Built Commissioning Checklist & Certificazione (
data/state.py,api/routes.py):- Checklist ufficiale per la validazione punto per punto dei dispositivi collaudati con annotazioni tecniche e firma operatore.
- Endpoint
POST /api/v1/device/commissioning-status.
- 1-Click Launch Script (
open.sh) & Auto-Browser Robustness:- Script eseguibile per avvio immediato e rilancio sicuro del browser.
- Risoluzione intelligente del browser di sistema (fallback esplicito su
/usr/bin/firefoxquando assentegoogle-chrome). - Auto-reexec trasparente in virtualenv (
.venv/bin/python3) inmain.pye preservazione variabili grafiche$DISPLAYe$XAUTHORITYinstart.sh.
Modificato & Ottimizzato
- Centro Assistenza & Manuale di Campo: Esteso a 22 capitoli tecnici completi in Italiano, Inglese e Spagnolo, con calcolatori integrati e guide al troubleshooting.
- Esclusione M-Bus: Rimozione completa di ogni riferimento o dipendenza M-Bus per garantire massima focalizzazione e pulizia architetturale.
- Parità Crittografica WAL: Verifica di integrità forense su 1073 record del registro manovre con certificazione SHA-256 e zero errori.
- Test Suite: Espansione a 58 test unitari e di integrazione passati con successo al 100%.
Full Changelog: v0.8.5...v1.0.0
Release v0.9.1
Release v0.9.1
Full Changelog: v0.8.5...v0.9.1
Release v0.8.5
Aggiunto
- Collaudo Hardware Reale USB↔RS485 (Industrial Field-Ready):
- Rilevamento automatico chipset Moxa UPort 1150 (VID
0x110A, PID0x1150, TI 3410) e adattatori standard FTDI, CH340, CP210x, Prolific. - Verifica permessi non-root Linux flessibile (
uucp,dialout, ACL POSIXos.access(..., R_OK | W_OK)). - Self-Test hardware 1-Click con misurazione latenza di apertura porta (<75ms).
- Sniffer RS485 Zero-TX ultra-resiliente con gestione hot-plug USB: recupero automatico in caso di scollegamento accidentale con riapertura trasparente al reinserimento e broadcast eventi WebSocket (
hardware_disconnect,hardware_reconnect). - Protezione linea flottante/a vuoto: azzeramento divisioni per zero ed emissione corretta di telemetria e diagnostica a 0 frame/s senza errori.
- Rilevamento automatico chipset Moxa UPort 1150 (VID
- Banco Prova Operativo ("Field Operational Tools"):
- Modbus Quick Commander: lettura (FC01..FC04) e scrittura/forzatura (FC05, FC06, FC15, FC16) sia seriale RTU che Ethernet TCP.
- Decodifica ingegneristica automatica in UInt16, Int16 Signed, Float32 IEEE-754 (Big-Endian e Word-Swapped Little-Endian), Hex e Booleani / Coils.
- Integrazione diretta nello Slave Inspector Modbus (tab "⚡ Quick Commander") e nel modale standalone unificato da barra comandi.
- BACnet Point Commander: forzatura immediata del
presentValuesu oggettianalogOutput,binaryOutput,multiStateOutput, ecc., con gestione del Priority Array (default Priorità 8: Operatore Manuale) e rilascio forzatura (Relinquish / NULL). - Mini-modal di override richiamabile direttamente da ogni riga della tabella oggetti BACnet.
- Simulatore d'Impianto Virtuale (Demo / Offline Mode):
- Motore di simulazione HVAC/BACS integrato con ciclo asincrono di oscillazione dinamica dei valori (temperatura, pressione, potenza, stati).
- Dispositivi virtuali pre-popolati: Chiller Modbus (Slave 1), Pompa Primaria (Slave 2), Analizzatore Rete (Slave 3), Unità Trattamento Aria BACnet (Device 1001), VAV Box (Device 1002), KNX Touch & Sensore (1.1.1, 1.1.2), Host ARP.
- Switcher rapido nella barra comandi superiore con pill dinamica
DEMO: ON / DEMO: OFFe flag CLI--demo.
- Live Log Viewer & Dock Console Avanzato:
- Filtro per livello di severità in tempo reale (
ALL,DEBUG,INFO,WARN,ERROR). - Casella di ricerca full-text istantanea con evidenziazione.
- Formato strutturato dei messaggi WebSocket (
level,logger,created,message). - Sistema di notifiche Toast non-bloccanti a scomparsa automatica con codice colore semantico.
- Filtro per livello di severità in tempo reale (
- Libreria Profili Modbus Estesa & Custom Profiles Manager:
- 13 profili industriali integrati: Multimetri (ABB B23, Carlo Gavazzi EM24, Carlo Gavazzi EM111, IME Nemo 96, Schneider iEM3150, Schneider PM5350, Siemens PAC3200), Contabilizzatori ed Energia (Belimo Energy Valve EV, Isoil ISOMAG, Diehl/Hydrometer Sharky 775, Emerson Rosemount 8712), Attuatori & Regolatori HVAC (Belimo Attuatore Modbus, Trox VAV Compact, iSMA-B-4I4O, Riello Caldaia Condexa Pro, Carel pCO).
- Gestione profili personalizzati (creazione, visualizzazione, import/export JSON, eliminazione).
- Funzione "Applica a Slave": mappatura istantanea su slave ID e inserimento punti nei registri e mappe d'impianto.
- Registro Manovre Certificato (Crash-Proof WAL & Chaining Crittografico SHA-256):
- Write-Ahead Log su file append-only
audit_journal.jsonl. - Registrazione preventiva dell'intento con
os.fsyncprima della trasmissione fisica sul bus o rete IP. - Registrazione del risultato con tempo di risposta, stato di successo/errore e valore verificato.
- Concatenazione crittografica (blockchain-style): ogni riga calcola
entry_hash = SHA-256(prev_hash + campi). - Recupero automatico degli intenti orfani all'avvio in caso di crash o interruzione improvvisa dell'alimentazione.
- Endpoint e modale di verifica integrità del registro con rilevamento manomissioni.
- Esportazione certificata dell'audit journal in formato JSON firmabile.
- Write-Ahead Log su file append-only
- Blocco Sicurezza Manovre (Safe Mode Interlock):
- Blocco preventivo delle manovre di scrittura su registri Modbus e override BACnet con codice
403 Forbidden. - Sblocco temporizzato ("Arm") con obbligo di specificare Nome Operatore / Tecnico, Commessa / Ordine di Lavoro, e Finestra Temporale di sblocco (15, 30, 60, 120 minuti).
- Disarmo manuale immediato o automatico al decorso del timeout.
- Badge dinamico in testata (verde: protetto / bloccato; rosso pulsante: sbloccato / armato con conto alla rovescia).
- Blocco preventivo delle manovre di scrittura su registri Modbus e override BACnet con codice
- Packaging Unificato Standalone (Portable vs Installed) & Firma Digitale SignPath:
- Risoluzione runtime dei percorsi tramite
core/paths.py: supporto per PyInstaller congelato (sys._MEIPASS), rilevamento modalità portatile (portable.flag) e fallback su percorsi standard di sistema (%LOCALAPPDATA%/~/.local/share/bham). - Script Inno Setup
installer/bham.issper installer Windows x64 pulito con creazione collegamenti e disinstallazione. - Pipeline GitHub Actions
.github/workflows/release.ymlcon integrazioneSignPath/github-action-submit-signing-request@v2per firma autenticata del codice e rilascio sia dell'archivio portatile (.zip conportable.flag) sia dell'installer Windows (.exe firmato).
- Risoluzione runtime dei percorsi tramite
Modificato
- Bump versione globale a
0.8.0in tutti i componenti (backend, frontend, packaging Debian, Winget, documentazione OpenAPI). - Sincronizzazione i18n al 100% su 289 chiavi per ciascuna lingua (Italiano, Inglese, Spagnolo).
Full Changelog: v0.8.1...v0.8.5
Release v0.7.0
Aggiunto
- Launcher cross-platform
bham.py(Windows e Linux): un solo comando per installare e avviare.- Legge
requirements.txte confronta ogni pacchetto con quanto installato nel.venv. - Mostra l'elenco delle dipendenze mancanti o con versione diversa, chiede conferma e installa tutto da solo in un ambiente isolato.
- Auto-apertura del browser web predefinito all'avvio su localhost (con supporto ambienti headless e flag
--no-browser). - Flag
--yes(non interattivo),--check(solo verifica, exit code 0/1),--no-reload(uso in cantiere).
- Legge
- Accesso Remoto e da Rete Locale (LAN):
- Piena compatibilità d'uso su Raspberry Pi o PC di quadro industriale con connessione remota tramite browser (
http://192.168.x.x:8765). - Stampa automatica a terminale di tutti gli URL LAN rilevati all'avvio con indicazioni firewall (
ufw allow 8765/tcp). - Box dedicato "Accesso Remoto LAN" in Impostazioni con URL rilevati e pulsante di copia negli appunti con feedback visivo.
- WebSocket resiliente e protocol-aware (
wss:su HTTPS/tunnel ews:su standard HTTP).
- Piena compatibilità d'uso su Raspberry Pi o PC di quadro industriale con connessione remota tramite browser (
- Diagnostica Euristica Qualità Bus RS485: calcolo automatico dello stato del livello fisico del bus nello sniffer seriale con allarmi per terminazioni 120Ω mancanti, polarità A(+)/B(-) invertita, disturbi o saturazione del bus. Badge informativo e tooltip nel banner Bus Health.
- Quick Diagnostic Self-Test 1-Click: endpoint
GET /api/v1/hardware/self-teste card diagnostica nelle impostazioni per collaudo rapido di apertura porta seriale RS485 con tempi di latenza, stato schede di rete e privilegi OS (dialout/admin/Npcap). - Profili Impianto Rapidi (Preset): selettore a tendina in sidebar e impostazioni per applicare con 1 click configurazioni per HVAC Standard, Contatori Energia, Gateway DALI o Ricerche Approfondite.
- CI: smoke test dell'auto-installazione su Ubuntu e Windows, controllo sintassi JavaScript, verifica dell'allineamento di tutte le stringhe di versione.
- Release: note di rilascio estratte da questo CHANGELOG e nuovo bundle
bham-source-<ver>.zip(sorgenti + launcher).
Modificato
- Centro Impostazioni: le tab orizzontali sono sostituite da una colonna laterale con le macro-voci (Adattatori & Porte, Connettività & Scansione, Tema & Lingua, Sessioni Salvate, Mappe BACS Help).
- Tema e Lingua: menu a tendina al posto dei pulsanti, sincronizzati con la preferenza salvata.
scripts/bump_version.pyora sincronizza anche frontend (titolo, badge, cache-buster), i18n, manuali epackage_deb.sh; nuovo--filesper gli script di release.- Il report Excel legge la versione da
core/config.pyinvece di averla scritta nel codice.
Full Changelog: v0.6.1...v0.7.0
Release v0.6.1
Full Changelog: v0.5.1...v0.6.1
Release v0.5.1
Full Changelog: v0.4.1...v0.5.1