feat(plexosdb): PLEXOSDB connector — plexosdb-mcp CRUD + translate_to_sienna/compare_solutions via r2x - #55
Conversation
…_to_sienna/compare_solutions via r2x) Closes Power-Agent#53. - powermcp/registry.py: new "plexosdb" Tool entry (server_dir="PLEXOSDB", kind="closed-source" per the PLEXOS engine it wraps, windows_only=False since plexosdb needs no PLEXOS install). Launched as run_kind="script" rather than "module": PLEXOSDB/plexosdb_mcp/main.py deliberately shares its package name with the upstream plexosdb-mcp distribution it re-exports, and module-style launch (which would add PLEXOSDB/ itself to sys.path) causes a confirmed self-shadow where `import plexosdb_mcp` inside main.py resolves to itself instead of the real installed package. Script launch avoids this. - PLEXOSDB/plexosdb_mcp/main.py: thin re-export of plexosdb-mcp's FastMCP server (mcp = build_mcp_server()), covering all 29 upstream CRUD tools, plus translate_to_sienna and compare_solutions calling r2x's real public API directly (r2x_plexos.PLEXOSParser -> r2x_plexos_to_sienna.plexos_to_sienna -> r2x_sienna.SiennaExporter) with no PowerMCP-authored bridge module. - PLEXOSDB/pyproject.toml: standalone installable package (PSCAD precedent), distribution name "powermcp-plexosdb" to avoid PyPI confusion with the upstream plexosdb-mcp project; depends only on r2x (the one PyPI-installable piece needed at import time by our own tools). - Root pyproject.toml: "plexosdb" extra covers only r2x (PyPI-installable); plexosdb-mcp's git install is documented, not silently assumed. PLEXOSDB/ force-included in the wheel/sdist build like every other connector. - PLEXOSDB/tests/test_tools.py: MagicMock-based tests for translate_to_sienna/ compare_solutions (PSCAD/tests/test_tools.py style), plus a re-export shape check. tests/test_vendor_import.py: side-effect-free import test for plexosdb_mcp.main, monkeypatching plexosdb_mcp in sys.modules (same pattern as the PSS/E psspy and PSLF PSLF_PYTHON tests) so no PLEXOS/plexosdb install is required to run it. - PLEXOSDB/README.md: install steps (including the manual plexosdb-mcp git install), usage, and a documented upstream limitation found while verifying translate_to_sienna against a real PLEXOS XML study (plexosdb's own run_of_river_case/TestSystem.xml fixture, 103 classes / 7 models): r2x_plexos 0.2.0's horizon resolution only catches AssertionError for a missing Horizon Chrono Date attribute, but plexosdb raises NotFoundError instead, so PLEXOSParser.run() fails on any PLEXOS model without explicit chronological horizon config -- the common case, reproduced on every model in the fixture. Session inspection (open XML, list classes/objects/properties/memberships) was verified working end-to-end against the same real fixture. Verified for real (not just mocked): `uv pip install plexosdb r2x` and `uv pip install "plexosdb-mcp @ git+https://github.com/NatLabRockies/plexosdb.git@main#subdirectory=src/plexosdb-mcp"` both succeed; plexosdb-mcp's build_mcp_server() registers all 29 tools; a real PLEXOS XML study loads and is fully inspectable through the re-exported tools.
…tion r2x (the meta-package) transitively pins the buggy r2x-plexos==0.2.0. 0.3.0 already fixes the NotFoundError/AssertionError mismatch that broke translate_to_sienna on every model in the real test fixture. Verified against the same fixture: full PLEXOS XML -> Sienna PSY JSON translation now succeeds end-to-end. r2x-plexos>=0.3.0 requires plexosdb>=1.6.0, whose plexos2duckdb>=0.1.0b11 dependency has no non-yanked stable release, so this currently needs --prerelease=allow. Filed upstream: - NatLabRockies/R2X#299 (bump r2x's r2x-plexos pin) - epri-dev/plexos2duckdb#3 (cut a non-yanked stable release)
|
Update: the translation blocker noted in the original PR description is now fixed and verified end-to-end. Root cause (confirmed by inspecting real released wheels and reproducing against plexosdb's own test fixture): Getting This PR now pins Full detail in |
Relates to #53.
Summary
PLEXOSDBconnector: thin re-export ofplexosdb-mcp's ~29 CRUD tools (matchespowerio/powerio_mcp.py's re-export pattern), plustranslate_to_sienna/compare_solutionscallingr2x-plexos/r2x-plexos-to-sienna/r2x-siennadirectly (no PowerMCP-authored bridge module).powermcp/registry.py: new"plexosdb"entry.PLEXOSDB/pyproject.toml, README (including the manual git-install step forplexosdb-mcp, which isn't on PyPI), and tests.What's verified for real (not mocked)
plexosdb,r2x, and the git-onlyplexosdb-mcpall install and run for real.open_xml_session,list_classes,list_objects_by_class,get_object_properties,list_object_memberships).run_kind="script"(notmodule, unlike PSCAD/HOPE) — testing caught that the module-launch path shadows the upstreamplexosdb_mcpimport viasys.path; documented in the registry entry,main.py,pyproject.toml, and README.pytest tests/ PLEXOSDB/tests/ -q→ 111 passed, 4 pre-existing skips, 0 failures.test_registry.pypasses unmodified. Wheel/sdist build cleanly withPLEXOSDB/force-included.Update: translation blocker resolved
r2x_plexos==0.2.0(pulled in by ther2xmeta-package) didn't catch the exceptionplexosdbraises on Horizons without explicit Chrono Date attributes — the common case, reproducing on all 7 models in the real test fixture. Fixed upstream inr2x_plexos>=0.3.0(verified against the released wheel); this PR now pins that directly rather than ther2xmeta-package. That version needsplexosdb>=1.6.0, whoseplexos2duckdbdependency has no non-yanked stable release, so install currently needs--prerelease=allow. Both gaps filed upstream: NatLabRockies/R2X#299, epri-dev/plexos2duckdb#3. Fulltranslate_to_siennapipeline re-verified end-to-end against the same fixture — seePLEXOSDB/README.md.Test plan
pytest tests/ PLEXOSDB/tests/ -qpython -m build(wheel + sdist)translate_to_siennafull round-trip — verified against the real fixture after pinningr2x-plexos>=0.3.0(--prerelease=allow)