La documentazione descriveva ancora il vecchio toggleTimeout (video in loop/sequenza); aggiornata a startTimeout/stopTimeout con scelta squadra/video, countdown e auto-chiusura server-side a 30s.
Segnapunti
Segnapunti digitale in tempo reale per partite di pallavolo. Un server centrale gestisce lo stato della partita; un display mostra il tabellone pubblico e un controller (smartphone o tablet) permette all'operatore di gestire punti, formazioni e cambi.
Indice
Architettura
Controller (smartphone) ──WebSocket──┐
├── Server Node.js ── gameState.js
Display (schermo) ──WebSocket──┘ │
└── .segnapunti/state.json
Il server è l'unica fonte di verità. Ogni azione del controller viene elaborata e trasmessa in broadcast a tutti i client connessi. Lo stato viene salvato su disco ad ogni azione e ricaricato all'avvio, sopravvivendo ai riavvii del server.
| Percorso | Ruolo |
|---|---|
http://<host>:3000/display |
Tabellone pubblico — sola lettura |
http://<host>:3000/controller |
Pannello operatore — gestione partita |
ws://<host>:3000/ws |
WebSocket endpoint |
Guida utente
Scenario tipico: schermo fisso + smartphone operatore
1. Avvia il server
docker compose up -d
All'avvio il terminale mostra gli URL locali e di rete.
2. Apri il display
Collega il PC/server allo schermo via HDMI e apri il browser a schermo intero:
http://localhost:3000/display
Se il display è su un dispositivo separato nella stessa rete:
http://<IP-del-server>:3000/display
Trovare l'IP: il server lo stampa all'avvio. In alternativa usa
ip asu Linux.
3. Apri il controller sullo smartphone
Connetti il telefono alla stessa rete Wi-Fi e apri:
http://<IP-del-server>:3000/controller
Installazione come app: nel browser tocca "Aggiungi a schermata Home" per avere il controller come icona dedicata.
Funzionalità
Il sistema è composto da due interfacce complementari: il display è in sola lettura e mostra al pubblico lo stato della partita; il controller è il pannello operatore da cui parte ogni azione. Tutto ciò che l'operatore tocca sul controller si riflette istantaneamente sul display via WebSocket.
Display (tabellone pubblico)
Pagina di sola visualizzazione, pensata per uno schermo grande o un proiettore. Mostra:
- Nomi squadre con indicatore di servizio (l'icona della palla compare accanto alla squadra che sta servendo).
- Punteggio del set corrente in caratteri molto grandi, leggibili da lontano.
- Contatore dei set vinti per ciascuna squadra.
- Striscia storica dei punti del set in corso: una sequenza scorrevole che ricostruisce l'andamento punto su punto.
- Modalità formazioni: in alternativa al punteggio, mostra le posizioni dei 6 giocatori in campo (numeri di maglia disposti come a referto).
- Ordine di visualizzazione invertibile: le due squadre possono essere scambiate di lato per rispecchiare l'orientamento reale del campo.
- Overlay time out / spot: durante un time out copre il tabellone con un countdown e il video scelto dall'operatore, o con la scritta TIME OUT (vedi sotto).
- Annuncio vocale del punteggio (sintesi vocale del browser), comandato dal controller.
- Indicatore di connessione: scompare quando tutto è connesso, diventa un punto rosso lampeggiante con scritta Disconnesso in caso di problemi.
- Fullscreen automatico all'apertura sui dispositivi mobili.
Controller (pannello operatore)
Il controller adatta automaticamente il proprio layout all'orientamento del dispositivo:
- Verticale (smartphone) — layout compatto: anteprima punteggio toccabile in alto e griglia di pulsanti sotto.
- Orizzontale (tablet) — layout esteso "da regia": due grandi pannelli squadra affiancati con punteggio, campo e tasto set, più una barra di azioni in basso.
Gestione del punteggio
- Punto — tocca il punteggio/la card di una squadra per assegnarle
+1. Il sistema gestisce automaticamente il cambio palla e la rotazione della squadra che riconquista il servizio. - Annulla punto — rimuove l'ultimo punto assegnato, ripristinando anche eventuale rotazione e servizio.
- Tasti SET — incrementano manualmente il contatore dei set vinti di una squadra (utile per correzioni); il contatore cicla da 0.
- Dialog automatico SET VINTO / PARTITA FINITA — compare da solo al raggiungimento delle condizioni di vittoria (25 punti, o 15 nel set decisivo, con 2 di scarto). Da qui puoi:
- VAI AL SET SUCCESSIVO — chiude il set, lo registra come vinto e prepara il set successivo aprendo la configurazione delle formazioni;
- INDIETRO — annulla l'ultimo punto se il dialog è comparso per errore;
- a partita conclusa, REFERTO per generare il referto e CHIUDI per tornare al tabellone.
Configurazione partita
Dal pulsante Config si apre una finestra che permette di impostare:
- Nomi delle squadre (Home e Guest);
- Modalità partita:
2/3(al meglio dei 3 set),3/5(al meglio dei 5 set) oAmichevole(senza vittoria automatica della partita); - Formazioni iniziali: i numeri di maglia dei 6 giocatori in campo per ciascuna squadra, disposti per zona.
Cambi giocatore
Il pulsante Cambi apre, dopo aver scelto la squadra, un dialog con righe IN → OUT. Le sostituzioni vengono validate prima di essere applicate: i numeri devono essere cifre, il giocatore entrante non può essere già in campo, quello uscente deve essere effettivamente in formazione, e nessuno può sostituire sé stesso. Eventuali errori sono segnalati in chiaro.
Servizio e visualizzazione
- Cambio Palla — assegna manualmente il servizio; disponibile solo a 0-0 (a inizio set).
- Inverti — scambia il lato delle due squadre sul display.
- Formazioni / Punteggio — alterna sul display la vista formazioni in campo e la vista punteggio.
- Striscia ON/OFF — mostra o nasconde lo storico punti del set sul display.
- Voce — fa annunciare al display il punteggio corrente con la sintesi vocale (es. "15 a 12", "15 pari", "zero a zero").
Time Out e spot pubblicitari
Il pulsante Time Out apre una finestra in cui l'operatore sceglie quale squadra ha chiamato il time out (obbligatorio) e quale video proiettare sul display, scegliendo tra i file della cartella spot/ oppure nessun video (overlay con la scritta TIME OUT). Alla conferma:
- il display copre il tabellone con un overlay a tutto schermo: countdown in sovraimpressione e video scelto; se non c'è video, o se il video finisce prima del tempo, compare la scritta TIME OUT con il nome della squadra. Nell'ultimo secondo il video sfuma in dissolvenza.
- il controller resta pienamente operativo: compare un banner TIME OUT con il conto alla rovescia e il pulsante Time Out mostra i secondi rimanenti. Ripremendolo si chiude il time out in anticipo.
- il server chiude automaticamente il time out dopo 30 secondi, anche se il controller si disconnette o va in standby.
I video da proiettare vanno messi in una cartella spot/ nella root del progetto (non versionata): vengono elencati nella finestra di scelta in ordine alfabetico (solo file .mp4). Se un display si riconnette a metà time out, il video riparte dal punto corretto.
Audio: i video partono con audio, ma il display è in genere uno schermo senza tastiera/mouse e i browser bloccano l'autoplay con suono senza un'interazione dell'utente. In assenza di configurazione il video parte automaticamente muto (il video si vede comunque). Per avere l'audio, avvia il browser del display in modalità kiosk consentendo l'autoplay con suono (es. Chrome con
--autoplay-policy=no-user-gesture-required, oppure impostando un'eccezione del sito per audio/video).
Reset e referto
- Reset — azzera la partita (punteggi, set e formazioni) previa conferma, e riapre subito la configurazione per impostare la partita successiva.
- Referto — a fine partita, dal dialog PARTITA FINITA, genera un referto di gara stampabile/PDF con i punteggi per set, le formazioni di partenza e l'andamento punto-punto. Funzione prototipale.
Regole pallavolo integrate
Le condizioni di vittoria del set sono applicate automaticamente dal server (è quello che fa comparire il dialog SET VINTO):
| Set | Condizione di vittoria |
|---|---|
| Set 1–4 (modalità 3/5) o 1–2 (modalità 2/3) | Primo a 25 con almeno 2 punti di scarto |
| Set decisivo (tie-break) | Primo a 15 con almeno 2 punti di scarto |
La partita è vinta da chi raggiunge 3 set su 5 (modalità 3/5) o 2 set su 3 (modalità 2/3). In modalità Amichevole non c'è vittoria automatica della partita: si continua a giocare set senza che compaia PARTITA FINITA.
Deploy con Docker
Prima installazione
docker compose up -d
Lo stato viene salvato nella cartella ./.segnapunti montata come volume nel container e sopravvive ai riavvii.
Video spot in Docker: la cartella
spot/non è inclusa nell'immagine. Per usare i video del time out aggiungi un volume indocker-compose.yml:./spot:/app/spot.
Aggiornamento a nuova versione
docker compose pull && docker compose up -d
Build e pubblicazione immagine
docker build \
-t santantonio.sytes.net/attilio/segnapunti:2.0.0 \
-t santantonio.sytes.net/attilio/segnapunti:latest .
docker push santantonio.sytes.net/attilio/segnapunti:2.0.0
docker push santantonio.sytes.net/attilio/segnapunti:latest
Sviluppo
Requisiti
| Strumento | Versione minima |
|---|---|
| Node.js | >= 18 |
| npm | >= 9 |
Avvio
npm install
npm run dev
| URL | Interfaccia |
|---|---|
http://localhost:5173/display |
Display |
http://localhost:5173/controller |
Controller |
Lo stato viene salvato in .segnapunti/state.json anche in modalità dev.
Comandi disponibili
| Comando | Descrizione |
|---|---|
npm run dev |
Dev server con hot reload |
npm run build |
Build di produzione in dist/ |
npm run serve |
Build + avvio server produzione |
Test
| Comando | Descrizione |
|---|---|
npm run test:unit |
Unit + integration (Vitest) |
npm run test:component |
Componenti Vue (Happy-DOM) |
npm run test:stress |
Load test WebSocket (50+ client) |
npm run test:all |
Tutti i test tranne E2E |
npm run test:ui |
Vitest con interfaccia grafica |
npm run test:e2e |
Playwright — Chromium, Firefox, Mobile Chrome |
Le suite Vitest coprono la logica di gioco (gameState, inclusa formInizio),
il protocollo e il routing del server, la persistenza, il client WebSocket
(wsMixin), i componenti Vue e la generazione del referto.
I test E2E richiedono il server in esecuzione (
npm run serve) e i browser Playwright installati:npx playwright install chromium firefox
Changelog
Vedere CHANGELOG.md per la storia delle versioni.