Your Complete System Model
Over the past nine chapters, you built a coffee machine model piece by piece: structure, ports, connections, actions, states, constraints, requirements, and verification. Each chapter added one concern. This chapter assembles everything into a single coherent system model.
This chapter does not teach new syntax. Instead, it shows how the pieces fit together – and what a complete, reviewable system model looks like.
The Model So Far
Here is what each chapter contributed:
- Chapter 2 defined the core types:
Grinder,Brewer,WaterTank,CoffeeMachine, plus item definitions forWater,CoffeeBeans, andBrewedCoffee. - Chapter 5 added typed ports to each component:
beanInputandgroundOutputon the grinder;waterInlet,groundInput, andbrewOutputon the brewer;waterOuton the water tank. - Chapter 6 wired the components together with connections and typed item flows.
- Chapter 7 defined
BrewCycleas a sequence of actions with parallel branches. - Chapter 8 defined
MachineStateswith guarded transitions between operating modes. - Chapter 9 added
BrewTempTarget(calculation) andSafetyInterlock(constraint). - Chapter 10 added requirements with
satisfyandverifylinks.
Now we bring all of these into one model.
Package Organization
A complete model needs clear package organization. Here is a practical layout:
package CoffeeMachineDomain {
import ScalarValues::*;
// Domain vocabulary
item def Water;
item def CoffeeBeans;
item def BrewedCoffee;
enum def GrindSetting {
fine;
medium;
coarse;
}
}
package CoffeeMachineStructure {
import ScalarValues::*;
import CoffeeMachineDomain::*;
port def BeanInputPort {
in item beans : CoffeeBeans;
}
port def GroundCoffeePort {
out item grounds : CoffeeBeans;
}
port def WaterPort {
in item water : Water;
}
port def WaterSupplyPort {
out item water : Water;
}
port def BrewOutputPort {
out item coffee : BrewedCoffee;
}
part def Grinder {
attribute grindSize : GrindSetting;
port beanInput : BeanInputPort;
port groundOutput : GroundCoffeePort;
}
part def Brewer {
attribute waterTemp : Real;
attribute brewPressure : Real;
port waterInlet : WaterPort;
port groundInput : BeanInputPort;
port brewOutput : BrewOutputPort;
}
part def WaterTank {
attribute currentLevel : Real;
attribute maxCapacity : Real;
port waterOut : WaterSupplyPort;
}
part def CoffeeMachine {
part grinder : Grinder;
part brewer : Brewer;
part waterTank : WaterTank;
attribute serialNumber : String;
connect waterTank.waterOut to brewer.waterInlet;
connect grinder.groundOutput to brewer.groundInput;
}
}
package CoffeeMachineBehavior {
import CoffeeMachineStructure::*;
action def GrindBeans {
in item beans : CoffeeBeans;
}
action def HeatWater;
action def ExtractCoffee {
in item water : Water;
in item grounds : CoffeeBeans;
out item coffee : BrewedCoffee;
}
action def DispenseCoffee {
in item coffee : BrewedCoffee;
}
action def BrewCycle {
action grind : GrindBeans;
action heat : HeatWater;
action extract : ExtractCoffee;
action dispense : DispenseCoffee;
first grind then heat;
// After heating, extract and dispense in sequence
first heat then extract;
first extract then dispense;
}
state def Idle;
state def Brewing;
state def Cleaning;
state def Error;
state def MachineStates {
state idle : Idle;
state brewing : Brewing;
state cleaning : Cleaning;
state error : Error;
transition idleToBrewing
first idle
then brewing;
transition brewingToIdle
first brewing
then idle;
transition idleToCleaning
first idle
then cleaning;
transition cleaningToIdle
first cleaning
then idle;
transition anyToError
first idle
then error;
}
}
package CoffeeMachineAnalysis {
import ScalarValues::*;
calc def BrewTempTarget {
in ambient : Real;
return result : Real;
result = if ambient < 18.0 ? 94.0 else 93.0;
}
constraint def BrewTempSafe {
in temp : Real;
temp >= 90.0 and temp <= 96.0;
}
constraint def SafetyInterlock {
in cupDetected : Boolean;
in brewCommand : Boolean;
not brewCommand or cupDetected;
}
}
package CoffeeMachineRequirements {
import ScalarValues::*;
import CoffeeMachineStructure::*;
import CoffeeMachineAnalysis::*;
requirement def <'REQ-TEMP-001'> BrewTempReq {
doc /* The extraction temperature shall remain between 90 and 96 degrees Celsius
during the brew cycle. */
subject coffeeMachine : CoffeeMachine;
}
requirement def <'REQ-SAFE-001'> SafetyInterlockReq {
doc /* The system shall not begin a brew cycle unless a cup is detected
on the drip tray. */
subject coffeeMachine : CoffeeMachine;
}
requirement def <'REQ-TIME-001'> BrewTimeReq {
doc /* A standard brew cycle shall complete within 60 seconds. */
subject coffeeMachine : CoffeeMachine;
}
}
package CoffeeMachineVerification {
import CoffeeMachineRequirements::*;
verification def BrewTempTest {
doc /* Measure extraction temperature during a standard brew cycle. */
objective {
verify requirement : BrewTempReq;
}
}
verification def SafetyInterlockTest {
doc /* Attempt to start a brew cycle without a cup. Confirm the system
refuses. */
objective {
verify requirement : SafetyInterlockReq;
}
}
verification def BrewTimeTest {
doc /* Time a standard brew cycle from start signal to dispensing
complete. */
objective {
verify requirement : BrewTimeReq;
}
}
}
How the Packages Connect
The packages form a clear dependency chain:
CoffeeMachineDomain (items, enums -- no imports)
↓
CoffeeMachineStructure (parts, ports, connections -- imports Domain)
↓
CoffeeMachineBehavior (actions, states -- imports Structure)
↓
CoffeeMachineAnalysis (calcs, constraints -- imports ScalarValues)
↓
CoffeeMachineRequirements (requirements -- imports Structure + Analysis)
↓
CoffeeMachineVerification (verification cases -- imports Requirements)
Each package depends only on packages above it. No circular imports. A reviewer can read the model top-down: vocabulary, then structure, then behavior, then analysis, then requirements, then verification.
Cross-Concern Traceability
The real power of a complete model is traceability across concerns. From any requirement, you can follow links to:
- The design element that satisfies it (via
subjecton the requirement) - The constraint that formalizes its condition (in the Analysis package)
- The verification case that will produce evidence (via
verify) - The state or action that exercises the relevant behavior
For example, BrewTempReq traces to:
CoffeeMachine(the subject that must satisfy it)BrewTempSafeconstraint (the formal condition: 90–96 C)BrewTempTestverification case (how you prove compliance)BrewCycleaction (the behavior under test)
This is the traceability loop that SysML v2 is designed for. Without it, requirements live in spreadsheets, design lives in diagrams, and verification lives in test plans – all disconnected. With it, everything is linked in one reviewable model.
What Makes This Model Review-Ready
A reviewer looking at this model can answer key questions quickly:
- What is the system made of? Read
CoffeeMachineStructure. Every component, port, and connection is visible. - What does it do? Read
CoffeeMachineBehavior. The brew cycle sequence and operating modes are explicit. - What must it satisfy? Read
CoffeeMachineRequirements. Every requirement has a subject and formal text. - How will we verify it? Read
CoffeeMachineVerification. Every requirement has a planned verification case. - What constraints apply? Read
CoffeeMachineAnalysis. Safety interlocks and temperature bounds are checkable.
No concern is hidden. No link is implicit. That is the goal.
The Model on Disk
Everything in this book is snippets of one model, and that model exists as files.
If you cloned this repository, it is under examples/coffee-machine/ – fifteen
.sysml files plus a sysml.toml, checkable with sysml check.
Reading a whole model is a different experience from reading it a construct at a time, and it is worth doing once. Here is which file goes with which chapter:
| File | Chapter |
|---|---|
definitions.sysml | 3 – definitions and usages |
package-structure.sysml | 4 – packages, visibility, public import |
ports-and-interfaces.sysml | 5, 6 – ports and interface definitions |
connections.sysml | 6 – connections and connectors |
flows.sysml | 6 – flows and messages |
actions.sysml | 7 – actions and control behaviour |
brew-cycle-flow.sysml | 7 – the brew cycle alone, for diagram generation |
states.sysml | 8 – states and transitions |
calculations.sysml | 9 – calculations and constraints |
requirements.sysml | 10 – requirements and verification |
typing-and-specialization.sysml | 12 – typing, specialization, redefinition |
metadata.sysml | 13 – metadata and documentation |
views.sysml | 13 – viewpoints, views, renderings |
orchestration.sysml | 16 – multi-subsystem simulation |
demo-analysis.sysml | 10, 16 – an analysis case |
Two other example projects sit beside it: examples/beverage-workspace/, the
multi-project workspace Chapter 15 walks
through, and examples/views-library/, eleven small models that each isolate one
piece of the view chain.
A caveat so you are not surprised: views.sysml reports three diagnostics about
satisfying a viewpoint. The model is correct – a viewpoint definition is a kind
of requirement definition, so satisfying one is what the specification intends –
and the resolver in the current tool does not accept it. The file is left as the
specification says it should be written.
Exploring the Model
The complete coffee machine model can be explored from four different perspectives. Each tab shows the same underlying model through a different diagram view:
Extending the Model
This model is a foundation, not a finished product. Real projects extend it in several directions:
- More requirements. Add power consumption, noise level, maintenance interval requirements.
- More states. Add
Steaming,Descaling,Standbymodes with guarded transitions. - More actions. Add
SteamMilk,RunDescaleactions with their own control flow. - Variants. Use specialization (Chapter 12) to create
EspressoMachineandDripMachinevariants. - Governance. Use metadata and views (Chapter 13) to add review status and stakeholder-specific model slices.
- Physical units. Use library quantities (Chapter 14) to replace
RealwithTemperatureValueandPressureValue.
The structure is ready for all of these. Each extension adds to the model without rewriting what exists.