Skip to content
Start free evaluation

Automate the simulator and reproduce errors

In this tutorial, you:

  • Test your own program with the simulator as the other equipment or host.
  • Automate tests with headless scenarios and judge them by exit code.
  • Cause a refused connection, a session ID mismatch, a T3 timeout, an unhandled request and write backpressure on purpose, and see what each one looks like.
  • Keep what you reproduced as trace files and logs.
  • Finish First communication. This tutorial uses the C++ tutorial example build/pdcomm-tutorial.
  • Set PDCOMM_ROOT and PDCOMM_SIMULATOR.

The commands use a Linux or macOS shell. On Windows, replace "$PDCOMM_SIMULATOR/pdcomm-simulator-headless" with & "$Simulator\pdcomm-simulator-headless.exe".

1. Test your host against a simulated equipment

Section titled “1. Test your host against a simulated equipment”

The external-peer scenario starts an equipment and waits for an external host to send S1F13 and S1F1 and then disconnect.

터미널 창
"$PDCOMM_SIMULATOR/pdcomm-simulator-headless" --scenario external-peer --session-id 7 --timeout-ms 20000

Connect a host to the local_address on the second line, such as 127.0.0.1:50092, and type establish, identity and quit:

터미널 창
"$PDCOMM_ROOT/build/pdcomm-tutorial" host active 127.0.0.1:50092

The simulator records s1f13, s1f1 and disconnect, then ends with "outcome":"passed" and exit code 0. To put your own host program into an automated test, read the address from the second output line, pass it to your host, and use the simulator’s exit code as the verdict.

2. Test your equipment against a simulated host

Section titled “2. Test your equipment against a simulated host”

Start the tutorial equipment first:

터미널 창
"$PDCOMM_ROOT/build/pdcomm-tutorial" equipment passive 127.0.0.1:5006

In another terminal, run the simulator as the host:

터미널 창
"$PDCOMM_SIMULATOR/pdcomm-simulator-headless" --role host --address 127.0.0.1:5006 --session-id 7

The simulator connects, establishes communication and ends with "outcome":"passed". The equipment terminal shows RESULT kind=1 request=0 outcome=2 for the S1F13 it received.

The headless simulator includes a round-trip scenario for each capability. Run the scenarios that match the tutorials to confirm that your SDK and simulator support those capabilities:

터미널 창
mkdir -p results
for scenario in status-round-trip data-report-round-trip directory-round-trip remote-report-config-round-trip typed-command-round-trip; do
"$PDCOMM_SIMULATOR/pdcomm-simulator-headless" --scenario "$scenario" > "results/$scenario.jsonl"
echo "$scenario exit=$?"
done
status-round-trip exit=0
data-report-round-trip exit=0
directory-round-trip exit=0
remote-report-config-round-trip exit=0
typed-command-round-trip exit=0

The headless simulator guide lists every scenario and the output format. Profiles and scenarios you build in the GUI run the same way once you save them in a project file.

4. Drive the simulator from a script or an AI tool

Section titled “4. Drive the simulator from a script or an AI tool”

When you start the GUI with --mcp-stdio, an MCP client can create and start sessions in the GUI. The GUI moves bytes on its own, so external programs can connect to those sessions right away.

This sequence creates a simulated equipment, connects the tutorial host and changes a value under test control:

  1. simulator.session.create with role equipment, mode passive, address 127.0.0.1:5000 and protocol_session_id 7.
  2. simulator.lifecycle.start. Pass the generation and revision from each response to the next call.
  3. In the tutorial host, establish and values 1001 1002 return SECS-II 01 02 41 04 49 44 4c 45 b1 04 00 00 00 00.
  4. simulator.status_data.update with kind status, id 1002 and value "5".
  5. In the tutorial host, values 1001 1002 now ends with b1 04 00 00 00 05.

The simulator MCP server guide covers the server configuration and the tools.

When you’ve caused a failure yourself, you recognize it faster on real equipment. Stop all programs after each experiment before you start the next one.

Start only the host, with no equipment:

터미널 창
"$PDCOMM_ROOT/build/pdcomm-tutorial" host active 127.0.0.1:5010

After a few seconds, state prints STATE tcp=5 gem=0. State 5 is RetryWait: after each refused connection, the host waits T5 (one second in the tutorial) and tries again. Type quit to stop.

Start two equipment programs on the same address. The second one immediately prints PDComm native operation failed and exits with code 1. The C# example also names the status, IoError.

Simulator activity log reporting that the HSMS port is already in useSimulator activity log reporting that the HSMS port is already in use

Start the simulator GUI as Equipment, Passive - listen on 127.0.0.1:5000, but leave Session ID at its default of 0. Connect the tutorial host (session ID 7) and type establish. The connection and Select succeed (STATE tcp=4), but RESULT kind=3 request=1 outcome=0 appears only after five seconds (T3): the peer doesn’t process data messages with a different session ID.

Connect the equipment and the host and run establish. In a third terminal, suspend the equipment process:

터미널 창
kill -STOP "$(pgrep -f 'pdcomm-tutorial equipment passive 127.0.0.1:5000')"

Type values 1 2 in the host. After five seconds, RESULT kind=3 request=3 outcome=0 appears. Resume the equipment:

터미널 창
kill -CONT "$(pgrep -f 'pdcomm-tutorial equipment passive 127.0.0.1:5000')"

The equipment answers the queued S1F3 late. The host drops that reply because the transaction is already over, and the connection stays Selected; the next values 1 2 succeeds. Diagnose failures and ask for help shows how to follow this in the logs.

Send alarms from the C# host to the tutorial equipment. The equipment has no alarm catalog, so it doesn’t handle the request and aborts the transaction with ABORT S5F0 for S5F5. The host gets RESULT kind=3 request=13 at once instead of waiting for T3. Step 7 of First communication explains why.

터미널 창
"$PDCOMM_SIMULATOR/pdcomm-simulator-headless" --scenario transport-backpressure-recovery --transport-fault-profile write_backpressure

At second-send-limit-exceeded, a send is rejected at the limit; after transport-fault-released, retry-send-accepted shows the same request going through. In the GUI, set Transport fault to Write backpressure in Overview before you start the session, then use Arm and Release under Transport fault profile in Message Trace & Diagnostics once communication is established.

  • GUI: click Export trace in Message Trace & Diagnostics, or choose File > Export Trace…, to save a JSON file. It contains no message bodies.
  • Headless project mode: save the trace with --trace-output <file>.
  • SDK programs: write JSON Lines diagnostics with the PDCOMM_LOG environment variable.
Message Trace & Diagnostics workspace with the GEM records of a host traceMessage Trace & Diagnostics workspace with the GEM records of a host trace

Type quit in the tutorial examples, and click Stop in the GUI before you close it. If a suspended process is left over, resume it with kill -CONT and then stop it. Delete the results folder if you don’t need it.