TRNRun
trnrun is a Python package that drives the TRNRun runner (trnrun.exe) to launch, monitor, and
manage TRNSYS simulations from Python. It runs multiple decks concurrently through a bounded worker
pool, mirrors each run's status, progress, config, setting, and log events behind thread-safe objects,
and renders a live terminal display while simulations run, making it suitable for batch studies,
parametric runs, and job orchestration.
Each simulation is executed by its own trnrun.exe process, which handles launch serialization
within the current Windows logon session, startup detection, runtime monitoring, and log parsing on
its own (see the runner documentation). The manager consumes the runner's line-delimited JSON output
from stdout and exposes it through a typed, thread-safe Python API.
Requirements
- Windows
- Python >= 3.12
- TRNSYS v17 or v18
- Optional: Progress Tracker (Type3830)
Dependencies
Installation
PyPI:
pip install trnrun
Quick start
Run a single deck:
from trnrun import SimulationConfig, SimulationManager
config = SimulationConfig(watch_tmp=True)
with SimulationManager() as manager:
manager.add("path/to/deck.dck", config)
manager.wait()
or
from trnrun import SimulationConfig, SimulationManager
config = SimulationConfig(watch_tmp=True)
manager = SimulationManager()
manager.add("path/to/deck.dck", config)
manager.wait()
Run a folder of decks with bounded concurrency:
from pathlib import Path
from trnrun import SimulationConfig, SimulationManager
config = SimulationConfig(watch_tmp=True)
with SimulationManager(max_concurrent=4) as manager:
for deck in sorted(Path(r"C:\path\to\dck").glob("*.dck")):
manager.add(deck, config)
manager.wait()
print(f"succeeded: {len(manager.succeeded)} failed: {len(manager.failed)}")
Do your own results aggregation:
import time
from trnrun import SimulationConfig, SimulationManager
config = SimulationConfig(watch_tmp=True)
with SimulationManager(refresh_interval=0, block=False) as manager: # 0 disables the built-in display
sim = manager.add("example.dck", config)
while not sim.is_finished:
snap = sim.snapshot()
if snap.progress is not None:
print(f"{snap.progress.percent:6.1%} (N:{snap.notices} W:{snap.warnings} F:{snap.fatals})", end="\r")
time.sleep(1.0)
print(f"\nexit code: {sim.exit_code} succeeded: {sim.succeeded}")
API reference
Simulation states
Reported through Simulation.status:
| Status | Meaning |
|---|---|
PENDING |
Waiting for the launch mutex in the current Windows logon session. |
LAUNCHING |
Mutex acquired; stale sidecars are removed and TrnEXE is started. |
RUNNING |
The runner entered runtime monitoring. |
DONE |
Completed successfully. |
CANCELLED |
The process exited before simulation time reached 100 %. |
ERROR |
Launch or pre-launch cleanup failed, or a fatal log entry was detected. |
TIMEOUT |
Exceeded watch_timeout_ms (or detect_timeout_ms with kill_on_timeout). |
STALLED |
Simulation time stopped advancing for longer than stall_timeout_ms. |
CANCELLEDandSTALLEDrequirewatch_tmp=True(Type3830), since both are derived from simulation progress. Without it, an early exit is reported asDONE.
SimulationManager
Runs simulations using a bounded pool of worker threads.
SimulationManager(max_concurrent=DEFAULT_MAX_CONCURRENT, refresh_interval=1.0, block=True)
| Parameter | Type | Default | Description |
|---|---|---|---|
max_concurrent |
int |
cpu_count() - 1 |
Maximum number of simulations running at the same time. Must be >= 1. |
refresh_interval |
float |
1.0 |
Seconds between terminal display updates. A value <= 0 disables the display. |
block |
bool |
True |
If True, add() blocks until a worker is available; if False, returns immediately. |
| Member | Description |
|---|---|
add(deck_file, config) |
Start a simulation as soon as a worker is available and return its Simulation. |
wait(timeout=None) |
Block until every simulation added before this call has finished, or the timeout (seconds) expires. Returns True if all of them finished. |
simulations |
All added simulations, in creation order. |
succeeded() |
Simulations that completed successfully. |
failed() |
Simulations that finished without succeeding (fatal errors, non-zero exit, cancellation, launch failure). |
cancel() |
Request cancellation of every added simulation. |
shutdown(cancel=False, wait=True) |
Close the manager; further add() calls raise. With cancel=True running simulations are cancelled first; with wait=True the call blocks until the workers exit. |
SimulationManager is a context manager. Leaving the with block calls shutdown(), which waits
for running simulations to finish
Simulation
A handle for one runner process, normally obtained from SimulationManager.add(). TRNRun owns the
simulation state; this object mirrors the latest state events received on stdout, retains a rolling
log window, and tracks local process bookkeeping (PID, exit code, cancellation).
All members are thread-safe. Each property acquires the internal lock separately, so two
consecutive reads may straddle an event - use snapshot() whenever a consistent multi-field view
is required.
| Member | Type | Description |
|---|---|---|
id |
int | None |
Identifier assigned by the manager. |
deck_path |
str | Path |
Deck (.dck) file passed to the runner. |
config |
SimulationConfig |
Python configuration used to invoke the runner. |
status |
StatusEvent | None |
Latest STATUS event. |
progress |
ProgressEvent | None |
Latest PROGRESS event. Requires watch_tmp=True. |
config_event |
ConfigEvent | None |
Latest CONFIG event with simulation start / stop / step. |
setting_event |
SettingEvent | None |
Latest SETTING event with the configured runner settings. |
logs |
list[LogEvent] |
Rolling window of LOG events (default: last 5 000). |
notices, warnings, fatals |
int |
Event counters, kept over the whole run — even after older events leave the rolling window. |
exit_code |
int | None |
None while running; the runner exit code afterwards. |
error |
str | None |
Python-side failure description (spawn failure, cancelled before start, ...). |
cancelled |
bool |
Whether cancel() was requested. |
pid |
int | None |
Runner process ID. |
is_running |
bool |
Runner process is alive. |
is_finished |
bool |
An exit code has been recorded. |
succeeded |
bool |
Success criteria under Exit codes. |
snapshot() |
SimulationSnapshot |
Consistent view of the snapshot fields below, captured under a single lock. |
cancel() |
None |
Request termination of the runner process. Safe to call before or after start. |
run() |
None |
Spawn the runner and consume stdout until it exits. Called by the manager's worker thread |
SimulationSnapshot
Frozen dataclass returned by Simulation.snapshot() with the fields id, deck_path, status,
progress, config_event, setting_event, notices, warnings, fatals, log_count, exit_code,
error, and cancelled. Every field is captured in one critical section, so a consumer can never
mix state from either side of an event.
SimulationConfig
Dataclass describing how the runner is invoked. Each field maps to a trnrun.exe flag (passed as
--name:value), and the defaults mirror the runner's own CLI defaults. See the runner
documentation for full flag semantics.
| Field | Runner flag | Default | Description |
|---|---|---|---|
trnrun_path |
— | bundled trnrun.exe |
Runner executable to invoke. |
trnexe_path |
--trnexePath |
C:\TRNSYS18\Exe\TrnEXE64.exe |
TRNSYS executable (TrnEXE64.exe / TrnEXE.exe). |
gui_visibility |
--guiVisibility |
"hidden" |
TRNSYS window behavior: keep, auto, min, minAuto, hidden. |
wait_for_gui |
--waitForGui |
True |
Launch detection: wait for a TRNSYS GUI. |
wait_for_lst |
--waitForLst |
True |
Launch detection: wait for a specific string in the *.lst. |
wait_for_tmp |
--waitForTmp |
False |
Launch detection: wait for the *.tmp file. (Requires Type3830.) |
detect_timeout_ms |
--detectTimeout |
300000 |
Timeout in ms for the detection stages; 0 = unlimited. |
extra_delay_ms |
--extraDelay |
0 |
Additional delay in ms after detection passes. |
poll_ms |
--pollMs |
100 |
Polling interval in ms for the output files and the process. |
watch_log |
--watchLog |
True |
Stream *.log entries as LOG events. |
watch_tmp |
--watchTmp |
False |
Stream *.tmp updates as CONFIG/PROGRESS events. (Type3830.) |
watch_timeout_ms |
--watchTimeout |
0 |
Maximum monitoring duration in ms; 0 = unlimited. |
stall_timeout_ms |
--stallTimeout |
0 |
Max wall-clock ms without progress; 0 = disabled. Needs watch_tmp. |
clean_on_success |
--clean |
False |
Also delete sidecars after success; stale sidecars are always removed before launch. |
kill_on_timeout |
--killOnTimeout |
False |
Kill TRNSYS on a detection or watch timeout. |
kill_on_stall |
--killOnStall |
False |
Kill TRNSYS when a stall is detected. |
severity |
--severity |
"Notice" |
Minimum log severity to emit: Notice, Warning, Fatal. |
write_events |
--writeEvents |
False |
Write every event to <deckFile>.jsonl, replacing any existing file. |
Display
A live terminal display is enabled by default: one line per simulation, refreshed every
refresh_interval seconds. Pass refresh_interval=0 (or any non-positive value) to disable it.
Recipes
Batch run with full monitoring
Python equivalent of the runner's batch recipe: runtime and stall monitoring per run, cleanup on success, and a summary at the end.
from pathlib import Path
from trnrun import SimulationConfig, SimulationManager
config = SimulationConfig(
watch_tmp=True,
watch_timeout_ms=300_000,
kill_on_timeout=True,
stall_timeout_ms=300_000,
kill_on_stall=True,
clean_on_success=True,
)
decks = sorted(Path(r"C:\path\to\dck").glob("*.dck"))
with SimulationManager(max_concurrent=4) as manager:
for deck in decks:
manager.add(deck, config)
manager.wait()
for sim in manager.failed:
print(f"{sim.deck_path} failed: exit={sim.exit_code} error={sim.error!r}")
Metadata
Release files for trnrun 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| trnrun-0.5.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
Release files / trnrun-0.5.0-py3-none-win_amd64.whl
| Download URL | trnrun-0.5.0-py3-none-win_amd64.whl |
|---|---|
| Size | 201.8 kB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
487ed278bd74c0c1a02dcebcc68b302eb3c24f79f2aeacc01f44fa4f62f0e8a4
|
|
BLAKE2b-256 checksum How to use checksums |
e431ef685af2c1756219b500756e14128f614b8c4abed04cbe388553fc3d6fe0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.2
|