Skip to content

feat: add PSS/E dynamic output reading - #97

Merged
qian-harvard merged 3 commits into
Power-Agent:mainfrom
BurhanAbdullah:psse-dynamic-output
Oct 6, 2026
Merged

qian-harvard merged 3 commits into
Power-Agent:mainfrom
BurhanAbdullah:psse-dynamic-output

Conversation

@BurhanAbdullah

Copy link
Copy Markdown
Contributor

Summary

  • add MCP support for reading PSS/E dynamic simulation output files
  • add a tool to list available dynamic output channels
  • add a tool to read selected dynamic output time-series channels
  • validate legacy .out files using dyntools.CHNF(outvrsn=0)
  • add regression coverage for missing files, channel selection, invalid channel inputs, and a real PSS/E Xplore 36.7 output

Validation

Validated with PSS/E Xplore 36.7 / Python 3.14:

  • 6 dynamic output channels
  • 123 time points
  • successful channel listing and time-series extraction
  • 3 passed for PSSE/tests/test_dynamic_output.py

qian-harvard and others added 2 commits October 6, 2026 13:21
dyntools ships in the PSSPY directory, which only _ensure_psse puts on
sys.path. Both new tools imported it directly, so in a fresh session, which
is the usual case for reading an existing .out file, they failed with "No
module named 'dyntools'". They now start the engine first, through a
_dyntools() helper.

tests/test_psse_server.py drives both tools with a fake dyntools that, like
the real one, can only be imported after the engine starts. It covers channel
selection, the input checks, and path containment. The four cases that read
a file fail on the code as first submitted.

Also: register both tools' outfile in the sandbox test's GUARDED table, list
them in the PSS/E README, document outvrsn=1 for .outx, and import psse_mcp
as PSSE.psse_mcp in the live test instead of editing sys.path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@qian-harvard

Copy link
Copy Markdown
Contributor

Thanks. Reading dynamic output back through MCP was a real gap, and I'm merging this.

I pushed b857f1f as a maintainer edit, on top of a merge of current main (which now includes #94):

  • Blocker: import dyntools before the engine starts. dyntools ships in the PSSPY directory, and only _ensure_psse() puts that directory on sys.path. In a fresh session, which is the usual case for reading an existing .out file, both tools failed with No module named 'dyntools'. Your live test didn't catch it because it ran in a process where PSS/E was already on the path. Both tools now go through a _dyntools() helper that starts the engine first.
  • Tests that CI runs. tests/test_psse_server.py drives both tools with a fake dyntools that, like the real one, can only be imported after the engine starts. It covers channel selection, the input checks, and path containment. The four cases that read a file fail on the code as first submitted.
  • Registered both tools' outfile in the GUARDED table in tests/test_sandbox.py, listed them in the PSS/E README, documented outvrsn=1 for .outx, and switched the live test to from PSSE import psse_mcp instead of editing sys.path.

A possible follow-up: with no channels, read_dynamic_output returns every channel at every time step. For a long run with many channels, that can be a very large response for a model to receive. A point cap or a decimation option would help.

@qian-harvard
qian-harvard merged commit 24b2924 into Power-Agent:main Oct 6, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants