Skip to main content

Virtual Commissioning: Protocol Emulators and the Hardware-Free Testbed

📍 Where we are: Part I · The Blueprint — Chapter 3. The stack is running on your laptop (Chapter 2); before we give it a data spine (Chapter 4), this chapter names what that running stack already is — a hardware-free testbed where every later chapter's integration can be proven on emulated devices, with the cost of a mistake a failed test instead of a misread batch.

The simple version

You would never wire a brand-new collector straight into a million-dollar bioreactor to see if your code works — if it sends the wrong command or misreads a value, you have a ruined batch and an investigation. Industry's answer, borrowed from car factories and chip fabs, is to build a flight simulator for the plant: a piece of software that behaves exactly like the real instrument — same protocol, same data, same quirks — so you can plug your integration into the simulator, watch it fly, and fix every crash on the bench. Only when it passes on the simulator do you point it at the real device. That practice is called virtual commissioning, and the surprising part is that you already built the simulator in Chapter 2: the companion stack's emulated OPC UA bioreactor and Modbus skid, fed by the deterministic cell-culture simulator, are the flight simulator. This chapter makes that explicit and adds the one thing that turns a demo into a discipline: an acceptance gate the testbed must pass before any integration is trusted.

What this chapter covers

Chapter 2 stood up the stack; Chapter 4 gives it a relational spine. In between sits a discipline that the rest of the book quietly depends on. We cover:

  • Virtual commissioning (VC) — the established Industry 4.0 practice of validating control software, communication protocols, and integration logic against simulated devices before physical deployment — and why it is the only honest way to develop a regulated integration.
  • The emulator stack you already have — the asyncua OPC UA bioreactor (opcua_server.py), the Modbus skid reader (modbus_reader.py), and the deterministic CHO simulator (bioproc_sim) that drives them — read as a coherent, hardware-free testbed rather than three separate demos.
  • A runnable acceptance gateexamples/chapters/03-virtual-commissioning/vc_acceptance.py — that runs a commissioning checklist over each emulated endpoint and refuses to pass an integration until the emulated device demonstrably reproduces the contract the plant model expects.
  • The sandbox argument — why an isolated, no-production-connection testbed is the right (and, for risky or AI-driven integration work, the only defensible) place to develop, and how this is the sandbox the agentic connectivity PoC of the ML book must run behind.
  • VC and GxP commissioning — where a virtual-commissioning record sits relative to IQ/OQ qualification, and what it does and does not let you claim.

Why prove it on a simulator first

A bioprocess integration is unusually unforgiving to develop against live equipment. A bioreactor running a 14-day CHO culture cannot be rebooted because your collector mishandled a reconnect; a write to the wrong register can move a real setpoint; and a mis-scaled reading — the 1850 that should be 1.85 bar and is silently stored as 18.5 — corrupts a record a process-validation reviewer will later trust (the legacy-skids chapter dwells on exactly this). You cannot iterate freely on hardware that is making a drug.

Virtual commissioning is the discipline that resolves this, and it is not a workaround invented for this book — it is established Industry 4.0 engineering practice: model-based testing, verification, and validation of automation control systems together with their communication interfaces and integration logic in a virtual environment, before any physical deployment [1]. Its logic is the same one a flight simulator runs on: the cost of a crash should be a failed test, not a wrecked aircraft. For a data platform that means standing up software that behaves like the instrument — advertises the same address space, emits the same datatypes and units (and the same omissions), replays realistic values — and developing every collector, every mapping, every contextualization join against that emulator until it passes, before a single byte crosses to a real device.

The practice has direct, recent precedent in exactly the AI-meets-control territory the companion books reach toward: LLM-driven PLC control has been developed and validated entirely inside a process emulator and a Modbus protocol simulator precisely to demonstrate safe, hardware-free testing of automation logic before touching a real controller [2]. The lesson generalizes: the riskier and less deterministic the thing you are wiring in, the more it belongs on a simulator first.

The testbed you already built

Here is the part that surprises people: you stood up a virtual-commissioning testbed in Chapter 2 without it being named one. Three pieces the book has already built combine into it.

  • The emulated OPC UA bioreactor. examples/chapters/05-connectivity-opcua-mqtt/opcua_server.py stands up a real OPC UA server with asyncua (the pure-Python FreeOpcUa stack) and exposes BR101 as an address space — one self-describing node per process variable, each carrying value, datatype, unit, timestamp, and quality [3]. To a collector on the other end it is indistinguishable from a vendor's server; it simply has no stainless steel behind it.
  • The emulated Modbus skid. examples/chapters/09-legacy-skids-modbus-s7/modbus_reader.py models a legacy TFF skid the way a real one presents itself — raw scaled integers in numbered registers, no units, no quality — so the integration logic that scales and names them can be exercised against the same awkward contract a real skid imposes.
  • The deterministic CHO simulator. examples/sim/bioproc_sim replays a reproducible fed-batch cell culture — temperature, pH, dissolved oxygen, glucose, titer — into those emulated endpoints, so the values flowing through the testbed are not random noise but a realistic, repeatable batch trajectory. Determinism is the quiet hero: because the same run produces byte-identical numbers every time, a commissioning test that passes today passes tomorrow, and a failure is a real regression rather than simulator weather.

Read together, these three are a flight simulator for the plant's data layer. Every later chapter — the edge gateway, the historian load, the contextualization join — develops against this testbed, which is why the book can claim its code is run, not asserted: it runs against software that behaves like the plant.

The acceptance gate: vc_acceptance.py

A testbed without an acceptance criterion is just a sandbox to play in. Virtual commissioning becomes a discipline when you state, up front, what the emulated device must demonstrate before any integration built on it is trusted — and gate on it. The module examples/chapters/03-virtual-commissioning/vc_acceptance.py is that gate, deterministic and network-free. For every canonical tag the plant model declares, it runs a five-point commissioning checklist against the emulated endpoint that serves it:

# examples/chapters/03-virtual-commissioning/vc_acceptance.py (excerpt)
def commission(tag: str, emu: EmuNode) -> dict:
"""Run the five-check commissioning checklist for one emulated tag against the canonical spec."""
c = CANON[tag]
checks = {
"served": True, # reached here => the emulator advertises it
"datatype": emu.datatype == c.datatype,
"unit": emu.unit == c.unit,
"in_range": c.lo <= emu.sample <= c.hi,
"roundtrip": emu.source != "", # collector can resolve a non-empty source
}
return {"tag": tag, "checks": checks, "ready": all(checks.values())}

The emulated devices deliberately include the defect a real legacy skid imposes — the Modbus TFF emulator advertises a flux reading with no engineering unit, exactly the wire-omits-meaning failure mode the protocol guarantees. Running python vc_acceptance.py prints the following, verbatim:

virtual-commissioning acceptance gate — emulated stack, no hardware, no network
canonical tags: 5 emulated devices: 2

-- opcua-bioreactor (asyncua) --
[READY] BR101.Temp.PV all commissioning checks pass
[READY] BR101.pH.PV all commissioning checks pass
[READY] BR101.DO.PV all commissioning checks pass
-- modbus-tff-skid (pymodbus) --
[READY] TFF01.TMP.PV all commissioning checks pass
[HOLD ] TFF01.Flux.PV FAILS: unit

canonical tags served by an emulator : 5/5 (unserved: none)
emulated tags that pass commissioning: 4/5

NOTE: the TFF01.Flux node is HELD — the emulated legacy skid advertises no unit, exactly
the wire-omits-meaning defect of a real Modbus device. Caught on the bench, it is a config
fix; caught in production, it is a mis-scaled CQA-adjacent record. THAT is what virtual
commissioning buys: the integration is proven on emulators before any hardware is touched,
and this gate is the sandbox the Book 5 agentic connectivity PoC must pass behind.

ASSERT ok: the emulated testbed serves every canonical tag and the VC gate catches the defect.

Read the HOLD line as the whole point of the chapter. On the bench, TFF01.Flux failing its unit check is a five-minute fix in the edge-layer scaling table; in production, the same defect is a flux reading stored without its LMH unit, a record a downstream model or reviewer silently misinterprets. The gate moved that discovery from the plant floor to a laptop. And the gate's own acceptance criterion — the module's assert — is itself instructive: it asserts not that every tag passes, but that the gate catches the defect and that every canonical tag the plant needs is served by some emulator. A virtual-commissioning gate that passed a unit-less skid would be worse than useless; its job is to fail loudly on the bench.

Hero diagram of the hardware-free virtual-commissioning testbed drawn as a closed loop on the left and a guarded boundary to hardware on the right. On the left, a deterministic CHO simulator box in green feeds a realistic fed-batch trajectory into two emulated devices: an asyncua OPC UA bioreactor in indigo exposing BR101 nodes with value, datatype, unit, timestamp and quality, and a pymodbus TFF skid in cyan exposing raw scaled integer registers with no unit. Both feed an edge collector under development, whose output flows into a virtual-commissioning acceptance gate drawn as an amber checklist box listing served, datatype, unit, in-range, roundtrip, marking BR101 tags READY in green and the unit-less TFF01.Flux node HOLD in rose. A dashed rose vertical boundary on the right, labelled no production or GxP connection, separates the whole sandbox from a greyed-out real bioreactor and real skid; a single gated arrow crosses it labelled only after the gate passes. A small caption notes the same sandbox hosts the agentic connectivity PoC. The testbed as a flight simulator for the data layer: the deterministic CHO simulator drives an emulated OPC UA bioreactor and an emulated Modbus skid; the integration under development runs entirely inside the sandbox; a virtual-commissioning acceptance gate must pass before a single gated arrow crosses the dashed boundary to real hardware — and the same isolated sandbox is where risky or AI-driven integration work belongs. Original diagram by the authors, created with AI assistance.

The sandbox is the safe home for the riskiest integration work

Virtual commissioning is valuable for ordinary integration; it becomes essential the moment the thing you are wiring in is non-deterministic or experimental. That is precisely the case the ML book's agentic connectivity chapter makes: an LLM-enabled agent that drafts connector configurations must never touch a production or GxP-regulated system, both because an agent writing configs into a live gateway is an unreviewed-action risk and because you cannot responsibly let a probabilistic system near instruments that make a medicine. The resolution there and here is the same word — sandbox: an isolated environment with no connection to production, with simulated devices standing in for hardware, where a defective proposal fails a test instead of corrupting a record. This chapter's testbed is that sandbox. The agent's proposed mappings are exercised against the emulated OPC UA server, so a hallucinated node simply fails to resolve against the simulator; its acceptance is gated by exactly the kind of checklist vc_acceptance.py runs.

That isolation is also a security control, not only a safety one. The OT-segmentation discipline the book treats as a compensating control for insecure protocols (NIST SP 800-82, IEC 62443 zones and conduits) has a development-time cousin: the commissioning sandbox sits in its own zone with no conduit to the production OT network at all, so experimental code — and any agent driving it — is physically incapable of reaching a real device until a human moves the validated artifact across the boundary deliberately [6].

Where a virtual-commissioning record sits in GxP

It is worth being precise about what virtual commissioning lets you claim, because over-claiming it is its own compliance trap. A VC pass on emulators is not qualification of the physical system — it does not replace IQ/OQ/PQ (Installation, Operational, and Performance Qualification, the documented proof that the real installed equipment performs as intended). What it is is the development-and-integration evidence that precedes them: under the risk-based CSA posture and GAMP 5, demonstrating integration logic on a simulated device before deployment is exactly the kind of leveraged, lower-risk testing that lets the on-hardware qualification concentrate its scripted effort where the residual risk actually is. The deterministic testbed makes that evidence reproducible — a VC acceptance run pinned to the simulator's fixed seed produces byte-identical output, so "the integration passed commissioning on BATCH-2026-001's trace" is a re-runnable record, not a one-time screenshot. The honest framing the rest of the book keeps: virtual commissioning proves the software and its integration; qualification proves the installed system; you need both, and doing the first on a simulator is what keeps the second cheap and safe.

Why it matters

Every other chapter in this book develops code that touches simulated equipment, and that is not a limitation of a teaching repo — it is the correct engineering posture, named. A plant that develops its collectors, mappings, and especially its AI-assisted integrations directly against live bioreactors is one mishandled reconnect away from a deviation; a plant that builds a faithful emulator and a commissioning gate catches its TFF01.Flux unit defect on a laptop. The discipline costs almost nothing once the emulators exist — and in this book they already do — and it buys the freedom to iterate fearlessly, the reproducibility that turns a passing test into a record, and the hard isolation that lets you point even a probabilistic agent at the problem without it being able to reach a real device. The simulator is not a poor substitute for the plant; for development, it is the right place to be.

In the real world

Virtual commissioning is mature industrial practice, not a novelty: model-based testing of automation and its communication interfaces before physical deployment is an established standard across Industry 4.0 automation engineering [1], and the specific pattern of validating control logic inside a process emulator plus a Modbus simulator before touching hardware is exactly how recent LLM-plus-PLC work demonstrated safe, hardware-free testing [2]. The building blocks this chapter leans on are all real, open-source, and run today: the asyncua FreeOpcUa stack stands up a conformant OPC UA server in pure Python [3], open-source OPC UA implementations are mature enough to serve as faithful emulated endpoints [4], and methodological OPC UA integration examples document the pattern end to end [5]. The honest OSS-versus-commercial line is the book's recurring one: commercial vendors sell polished digital-twin and virtual-commissioning suites (Siemens, AVEVA, and others) with validated-component packages, while the open-source path gives you the same testbed at no licence cost with code you can read and seed — and you own proving, in a commissioning record, that the emulator faithfully reproduces the contract the real device will impose. The sandbox boundary itself rides on the same OT-segmentation guidance (NIST SP 800-82, IEC 62443) the book applies to production [6].

Key terms

  • Virtual commissioning (VC) — validating control software, communication protocols, and integration logic against simulated devices in a virtual environment before any physical deployment; mature Industry 4.0 practice and the development posture this whole book assumes.
  • Protocol emulator — software that behaves like a real device on the wire (an asyncua OPC UA server, a pymodbus skid) so integration logic can be exercised against the same address space, datatypes, units, and quirks a real instrument imposes, with no hardware.
  • Hardware-free testbed — the combined emulated OPC UA bioreactor, emulated Modbus skid, and deterministic CHO simulator, read as one coherent flight simulator for the plant's data layer.
  • Deterministic simulator — a process simulator (bioproc_sim) whose fixed seed replays byte-identical values every run, so a commissioning test that passes is reproducible and a failure is a real regression, not noise.
  • Acceptance gate — the stated, up-front commissioning checklist (served, datatype, unit, in-range, roundtrip) an emulated endpoint must pass before an integration built on it is trusted; vc_acceptance.py is the runnable gate, and it is designed to fail loudly on a defect.
  • Sandbox — an isolated environment with no connection to production or GxP-regulated systems, where experimental or AI-driven integration work runs against emulators; a defective proposal fails a test instead of corrupting a record. The same sandbox hosts the agentic connectivity PoC.
  • VC versus IQ/OQ/PQ — virtual commissioning proves the software and its integration on a simulator; Installation/Operational/Performance Qualification prove the installed physical system. VC precedes and de-risks qualification; it does not replace it.

Where this leads

The stack is running and we now know what it really is — a hardware-free testbed with an acceptance gate, the safe place every later integration is proven. But the readings flowing through it are still orphans: a BR101.DO.PV value is a labelled float with no notion of which batch, which recipe, which phase it belongs to. The next chapter, The Batch & Equipment Data Model: ISA-88/95 in PostgreSQL, builds the relational spine that turns every emulated and, later, real reading into a fact about a batch — the model the rest of the platform hangs from.