Thin Python wrapper for running and monitoring
TRNSYS batch simulations. The
package includes the trnrun.exe runner and trnrunq.exe queue.
Contents
- Requirements
- Installation
- Quick start
- Run a batch
SimulationConfigSimulationManagerSimulation- Examples
Requirements
- Windows x64
- Python 3.12 or newer
- TRNSYS 17 or 18
- Optional: Type3830 Progress Tracker for progress and stall monitoring
Installation
Install with pip:
pip install trnrun
Or with uv:
uv add trnrun
Quick start
from trnrun import SimulationConfig, SimulationManager
config = SimulationConfig()
with SimulationManager(max_concurrent=1) as manager:
simulation = manager.add(r"C:\path\to\deck.dck", config)
manager.wait(simulation)
if simulation.succeeded:
print(f"Completed: {simulation.deck_path}")
else:
print(f"Failed: {simulation.deck_path}")
Run a batch
from pathlib import Path
from trnrun import SimulationConfig, SimulationManager
config = SimulationConfig(watch_tmp=True)
decks = sorted(Path(r"C:\path\to\decks").glob("*.dck"))
with SimulationManager(max_concurrent=4) as manager:
simulations = [manager.add(deck, config) for deck in decks]
manager.wait()
print(f"{len(manager.succeeded)} succeeded, {len(manager.failed)} failed")
SimulationConfig
SimulationConfig defines how one deck is launched and monitored.
Executables and window
-
trnrun_path(str | Path, default: bundledtrnrun.exe)Path to the
trnrun.exeexecutable. -
trnexe_path(str | Path, default:C:\TRNSYS18\Exe\TrnEXE64.exe)Path to the
TrnEXE64.exeorTrnEXE.exeexecutable. -
gui_visibility(str, default:"hidden")Controls the TRNSYS simulation window. Values are case-insensitive:
keep/keepOpen: show the window and leave it open after the simulation.auto/autoClose: show the window and close it after the simulation.min/minimized: minimize the window and leave it open afterward.minAuto/minimizedAuto: minimize the window and close it afterward.hidden: hide the window and close it after the simulation.
Launch detection
-
wait_for_gui(bool, default:True)Wait for a recognized TRNSYS simulation window as part of the launch-readiness checks.
-
wait_for_lst(bool, default:True)Wait for the component-order header in the deck's
.lstfile. -
wait_for_tmp(bool, default:False)Wait for a Type3830
.tmpfile. Do not enable this for a deck without Type3830, or launch detection will wait until its deadline. -
detect_timeout_ms(int, default:300_000)Maximum time, in milliseconds, to wait for launch readiness. Set to
0to wait indefinitely. The runner holds the launch mutex for the current Windows session until detection completes. -
extra_delay_ms(int, default:0)Additional delay in milliseconds after all enabled readiness checks pass.
Runtime monitoring
-
poll_ms(int, default:100)Polling interval in milliseconds for the TRNSYS process and output files. Values below
1are clamped to1. -
watch_log(bool, default:True)Read the deck's
.logfile and emit parsedLOGevents. -
watch_tmp(bool, default:False)Read Type3830
.tmpupdates and emit configuration and progress events. Required for progress-basedCANCELLEDandSTALLEDoutcomes. -
watch_timeout_ms(int, default:0)Maximum runtime-monitoring duration in milliseconds.
0means unlimited. -
stall_timeout_ms(int, default:0)Maximum milliseconds without simulation-time progress.
0disables stall detection. Requireswatch_tmp=Trueand a valid Type3830 snapshot. -
kill_on_timeout(bool, default:False)Terminate the owned TRNSYS process when launch detection or runtime monitoring times out. If disabled, a detection timeout proceeds to runtime monitoring; after a runtime-monitoring timeout,
trnrun.exestops polling and waits for the process to exit. -
kill_on_stall(bool, default:False)Terminate the owned TRNSYS process after detecting a stall. Without it,
trnrun.exewaits for the process to exit.
Output and cleanup
-
clean_on_success(bool, default:False)Delete
.tmp,.log,.lst, and.PTIsidecar files after a successful run. -
severity(str, default:"Notice")Minimum emitted log severity:
Notice,Warning, orFatal, case-insensitively. -
write_events(bool, default:False)Mirror emitted runner events to a
.jsonlfile beside the deck, replacing any existing file when the run starts.
A configuration with every parameter set explicitly:
from pathlib import Path
from trnrun import SimulationConfig
config = SimulationConfig(
trnrun_path=Path(r"C:\path\to\trnrun.exe"),
trnexe_path=Path(r"C:\TRNSYS18\Exe\TrnEXE64.exe"),
gui_visibility="hidden",
wait_for_gui=True,
wait_for_lst=True,
wait_for_tmp=True,
detect_timeout_ms=300_000,
extra_delay_ms=0,
poll_ms=100,
watch_log=True,
watch_tmp=True,
watch_timeout_ms=300_000,
stall_timeout_ms=300_000,
clean_on_success=True,
kill_on_timeout=True,
kill_on_stall=True,
severity="Notice",
write_events=False,
)
SimulationManager
SimulationManager owns one queue process and controls how simulations are
submitted, monitored, and displayed. It is synchronous and intended for use
from one thread. Simulation state advances only while add(), wait(),
follow(), or shutdown() reads queue output.
Parameters
-
max_concurrent(int, default: logical processor count minus one, at least1)Maximum number of runners that may execute concurrently. Additional submissions wait for a worker.
-
refresh_interval(float, default:1.0)Minimum seconds between terminal-display redraws while events are being read. Set to
0or a negative value to disable the built-in display. -
trnrunq_path(str | Path, default: bundledtrnrunq.exe)Path to the
trnrunq.exeexecutable.
A manager with every parameter set explicitly:
from pathlib import Path
from trnrun import SimulationManager
with SimulationManager(
max_concurrent=4,
refresh_interval=1.0,
trnrunq_path=Path(r"C:\path\to\trnrunq.exe"),
) as manager:
...
Methods and properties
-
simulations(list[Simulation])Snapshot of all queue-accepted simulations in acceptance order.
-
succeeded(list[Simulation])Snapshot of accepted simulations that completed successfully.
-
failed(list[Simulation])Snapshot of simulations that completed without succeeding. Pending and running simulations are not included.
-
add(deck_file: str | Path, config: SimulationConfig) -> SimulationValidate and submit
deck_fileusing a copy ofconfig. Blocks until a queue worker accepts the request and returns itsSimulation. If every worker is occupied, this may not return until an earlier simulation finishes. -
wait(simulation: Simulation | None = None) -> NoneWith no argument, process events until every accepted simulation completes. Pass a manager-owned
Simulationto return when that run completes while continuing to process updates from other runs. There is no client-side timeout. -
follow(simulation: Simulation | None = None) -> Iterator[Simulation]With no argument, yield the affected
Simulationafter every newly processed event until all runs complete. Pass a manager-ownedSimulationto yield only that run's updates and return when it completes. Events for other runs are still processed, and previously consumed events are not replayed. -
shutdown() -> NoneClose queue input, finish accepted work, and reap the queue process. Called automatically when leaving a
withblock.
Example manager workflow with every method and property:
from trnrun import SimulationConfig, SimulationManager
config = SimulationConfig(watch_tmp=True)
manager = SimulationManager(max_concurrent=2)
try:
first = manager.add(r"C:\path\to\first.dck", config)
second = manager.add(r"C:\path\to\second.dck", config)
for updated in manager.follow(first):
if updated.status is not None:
print(f"{updated.deck_path}: {updated.status.status}")
manager.wait()
print(f"Simulations: {len(manager.simulations)}")
print(f"Succeeded: {len(manager.succeeded)}")
print(f"Failed: {len(manager.failed)}")
print(f"First succeeded: {first.succeeded}")
print(f"Second succeeded: {second.succeeded}")
finally:
manager.shutdown()
Simulation
SimulationManager.add() returns a Simulation containing the current state and
results of one run. The manager updates this object as it processes queue events;
applications normally inspect it rather than constructing or updating it
directly.
Identity and configuration
-
id(int)Manager-assigned simulation identifier. The queue uses its string form as the run ID.
-
deck_path(Path)Absolute path to the submitted deck.
-
config(SimulationConfig)Independent copy of the configuration used for this run.
Events
-
status(StatusEvent | None)Latest runner status, or
Nonebefore the first status event. Terminal status values areDONE,ERROR,CANCELLED,TIMEOUT, andSTALLED. -
progress(ProgressEvent | None)Latest Type3830 progress event, or
Nonewhen progress has not been reported.percentis a fraction from0to1;elapsedandetaare milliseconds. -
config_event(ConfigEvent | None)Latest simulation-time configuration event, containing
start,stop, andstep, orNonebefore Type3830 reports it. -
setting_event(SettingEvent | None)trnrun.exesettings reported when the simulation starts, orNonebefore they are received. -
completion_event(QueueEvent | None)Queue completion metadata, including
exit_code, orNoneuntil the queue finishes the request.exit_codeisNoneif the runner could not be launched. -
logs(list[LogEvent])Snapshot of the latest 5,000 log events in arrival order. Older events are discarded from this list, but remain included in the log counters.
State and outcome
-
is_running(bool)Whether the simulation is pending or running and has not received queue completion.
-
is_accepted(bool)Whether a queue worker has accepted the request.
-
is_finished(bool)Whether the queue has reported completion for the request.
-
has_terminal_status(bool)Whether the runner has reported one of the canonical terminal statuses.
-
succeeded(bool)Whether the queue completed the request and the latest runner status is exactly
DONE.
Log counters
-
log_count(int)Total number of received log events.
-
notices(int)Number of received
Noticelog events. -
warnings(int)Number of received
Warninglog events. -
fatals(int)Number of received
Fatallog events.
An example inspecting every property:
from trnrun import SimulationConfig, SimulationManager
with SimulationManager(max_concurrent=1) as manager:
simulation = manager.add(r"C:\path\to\deck.dck", SimulationConfig(watch_tmp=True))
manager.wait(simulation)
print(f"ID: {simulation.id}")
print(f"Deck: {simulation.deck_path}")
print(f"Config: {simulation.config}")
print(f"Running: {simulation.is_running}")
print(f"Accepted: {simulation.is_accepted}")
print(f"Finished: {simulation.is_finished}")
print(f"Terminal status received: {simulation.has_terminal_status}")
print(f"Succeeded: {simulation.succeeded}")
print(f"Status: {simulation.status}")
print(f"Progress: {simulation.progress}")
print(f"Simulation config event: {simulation.config_event}")
print(f"Runner settings: {simulation.setting_event}")
print(f"Queue completion: {simulation.completion_event}")
print(f"Logs: {simulation.logs}")
print(f"Log count: {simulation.log_count}")
print(f"Notices: {simulation.notices}")
print(f"Warnings: {simulation.warnings}")
print(f"Fatals: {simulation.fatals}")
Examples
Runnable examples are available in the TRNRun repository.
Metadata
Release files for trnrun 0.6.1
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.6.1-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
Release files / trnrun-0.6.1-py3-none-win_amd64.whl
| Download URL | trnrun-0.6.1-py3-none-win_amd64.whl |
|---|---|
| Size | 458.0 kB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
49fcd2585cd44b3c2d883c95bbc8a37f08db3fdd4d14044e5aa8227913bfae67
|
|
BLAKE2b-256 checksum How to use checksums |
340c15b3148bf5d4b4f70575cd2ef7637141401981693eac9d20241668ac4fe7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.2
|