Magic Grid 2: Problem Domain, prospettiva white-box (stazione meteo)
📍 Fase: Modellazione SysML v2 — qui si costruisce il modello (requisiti, architettura, verifica). La parte tecnica di dettaglio (schematico KiCad, firmware) è nella serie tutorial ESP32/Nordic.
Nel primo articolo operativo abbiamo chiuso il black-box: Stakeholder Needs, System Context, Use Cases, MoE. Ora apriamo la scatola — prospettiva white-box — restando ancora nel Problem Domain: si tratta di capire cosa succede dentro il sistema, non ancora con quali componenti. Le celle di oggi: Functional Analysis, Conceptual Subsystems, MoE for Subsystems, Traceability to Stakeholder Needs (che chiude il Problem Domain).
1. Functional Analysis
Si decompone la funzione black-box RiceviAggiornamentiPeriodici (dal precedente articolo) in sotto-funzioni interne, con un action def annidato e sequenziato da first/then.
package FunctionalAnalysis {
action def RiceviAggiornamentiPeriodici {
action f1 : LeggiDatiAmbientali;
action f2 : ConnettiRete;
action f3 : RecuperaPrevisioni;
action f4 : AggiornaDisplay;
action f5 : GestisciRisparmioEnergetico;
first f1;
then f2;
then f3;
then f4;
then f5;
}
action def LeggiDatiAmbientali {
out temperaturaC : Real;
out umiditaPct : Real;
out pressioneHPa : Real;
}
action def ConnettiRete {
out connesso : Boolean;
}
action def RecuperaPrevisioni {
in connesso : Boolean;
out previsione : String;
}
action def AggiornaDisplay {
in previsione : String;
in temperaturaC : Real;
}
action def GestisciRisparmioEnergetico;
}

Nessuna delle cinque funzioni menziona ancora un componente reale: LeggiDatiAmbientali non dice “BME280”, AggiornaDisplay non dice “e-paper”. Restiamo nel cosa.
2. Conceptual Subsystems
La decomposizione funzionale suggerisce da sola i sottosistemi concettuali: cinque raggruppamenti coerenti di funzioni, non ancora componenti fisici. Li dichiariamo come part def e li componiamo nella part def della stazione, allocando le funzioni con perform action.
package ConceptualSubsystems {
private import FunctionalAnalysis::*;
part def SottosistemaAcquisizione {
perform action leggi : LeggiDatiAmbientali;
}
part def SottosistemaComunicazione {
perform action connetti : ConnettiRete;
perform action recupera : RecuperaPrevisioni;
}
part def SottosistemaElaborazione;
part def SottosistemaPresentazione {
perform action aggiorna : AggiornaDisplay;
}
part def SottosistemaAlimentazione {
perform action risparmia : GestisciRisparmioEnergetico;
}
part def StazioneMeteo {
part acquisizione : SottosistemaAcquisizione;
part elaborazione : SottosistemaElaborazione;
part comunicazione : SottosistemaComunicazione;
part presentazione : SottosistemaPresentazione;
part alimentazione : SottosistemaAlimentazione;
connect acquisizione to elaborazione;
connect elaborazione to comunicazione;
connect elaborazione to presentazione;
connect alimentazione to acquisizione;
connect alimentazione to comunicazione;
connect alimentazione to presentazione;
connect alimentazione to elaborazione;
}
}

Da notare: Alimentazione non compariva tra i bisogni funzionali (nessuno stakeholder need dice “voglio l’alimentazione”), ma è comunque un sottosistema concettuale a sé, perché alimenta trasversalmente gli altri quattro ed è il principale responsabile di MOE-01/MOE-02 (autonomia, corrente in deep sleep). Il libro MagicGrid stesso nota che non tutti i sottosistemi derivano da una funzione black-box: alcuni emergono per esigenze trasversali (qualità, vincoli non funzionali).
3. MoE for Subsystems
Cella opzionale: solo quando serve un dettaglio più fine di quello già definito a livello di intero sistema. Qui ha senso per Alimentazione, dove vogliamo un budget di corrente dedicato invece del solo totale.
package MoEsForSubsystems {
private import ConceptualSubsystems::SottosistemaAlimentazione;
requirement def <MOE2.1> BudgetCorrenteAlimentazione {
subject alimentazione : SottosistemaAlimentazione;
attribute correnteMassimaPropiaMicroA : Real = 15;
doc /* Il sottosistema Alimentazione (PMIC + regolatore) non deve consumare
da solo piu di 15 microA in deep sleep, lasciando margine agli altri
sottosistemi entro il budget totale di MOE-02 (50 microA). */
}
}
4. Traceability to Stakeholder Needs
Chiude il Problem Domain: ogni stakeholder need deve essere raffinato da almeno un elemento white-box (funzione, sottosistema, MoE). In SysML v2 questo si scrive come relazione satisfy — qui usata nel senso di “raffina”, dall’elemento più concreto verso il bisogno più astratto.
package TraceabilityToStakeholderNeeds {
private import StakeholderNeeds::*;
private import FunctionalAnalysis::*;
private import ConceptualSubsystems::*;
private import MeasuresOfEffectiveness::*;
satisfy SN1 by AggiornaDisplay;
satisfy SN2 by RiceviAggiornamentiPeriodici;
satisfy SN3 by SystemContext::contestoConfigurazione;
satisfy SN4 by SottosistemaAlimentazione;
satisfy SN5 by MOE3;
satisfy SN6 by MOE1;
satisfy SN6 by MOE2;
satisfy SN7 by MOE4;
satisfy SN7 by MOE5;
satisfy SN8 by StazioneMeteo;
}
| Stakeholder Need | Raffinato da |
|---|---|
| SN1 – Dati a colpo d’occhio | AggiornaDisplay (funzione) |
| SN2 – Aggiornamento automatico | RiceviAggiornamentiPeriodici (funzione) |
| SN3 – Configurazione Wi-Fi | contestoConfigurazione (system context) |
| SN4 – Avviso batteria scarica | SottosistemaAlimentazione |
| SN5 – Leggibilità permanente | MOE3 (tempo di refresh) |
| SN6 – Autonomia lunga | MOE1, MOE2 (autonomia, corrente deep sleep) |
| SN7 – Costruibile da hobbista | MOE4, MOE5 (costo, volume di stampa) |
| SN8 – Apertura e riproducibilità | StazioneMeteo (l’intero modello, aperto per costruzione) |
Tutti gli otto bisogni sono coperti: nessuno resta orfano. Se ne trovassimo uno scoperto, sarebbe il segnale che l’analisi funzionale è incompleta — non un problema da correggere più avanti, ma da risolvere subito, prima di passare al Solution Domain.
Cosa segue
Il Problem Domain è completo. Il prossimo passo è il Solution Domain, a livello di sistema: trasformiamo tutto questo in requisiti formali (shall), in un’architettura logica reale, e nei primi calcoli parametrici (autonomia stimata). Si continua con Magic Grid 3: Solution Domain, livello di sistema.
