Recent Releases of PowerIO
PowerIO - v0.8.0
The BMOPF schema has been released: https://github.com/distribution-system-opt/bmopf-report This release aligns powerio with BMOPF schema 0.1.0, introduces one version number for .pio.json, and distribution JSON reader validation. Note the following migration protocols:
.pio.jsonfiles written by 0.7.x and earlier are rejected with an error that says to regenerate them from their source case (convert with a 0.7.x install to migrate an orphaned file),- the BMOPF writer targets the published schema 0.1.0
$id, so consumers that key on the old$schemaURI should update their accepted list.
Details
.pio.jsoncarries one version number.schema_version(now0.2.0)
covers the whole document, model JSON included: while the major is 0 an
incompatible change bumps the minor, and the reader accepts exactly its own
major.minor lineage, rejecting anything else with an error that says to
regenerate the package from its source case. Theschema,
payload_schema, andpayload_schema_versionfields and the
PIO_PACKAGE_SCHEMA_URL/PIO_PAYLOAD_*constants are gone; the payload
schema documents underdocs/schema/pio-payload-*are no longer published
(thepio-package/0.2document embeds every model type). Files written by
0.7.x and earlier are rejected with the regenerate error.schema_version
is required: it used to default to the current version when absent, which
let a document skip the lineage check by leaving the field out.- powerio-dist JSON reader validation (#262):
- PMD bound arrays keep their finite entries when another entry is a
null-derived infinity (an unbounded phase): generator
pg_lb/pg_ub/qg_lb/qg_uband linecodecm_ub/sm_ubno longer
vanish whole. The PMD writer spells nonfinite entries back as null; the
BMOPF writer drops such a field with a warning instead of coercing to 0,
and the dss writer skipsemergampswith a warning when the first
i_maxentry is nonfinite. - A PMD matrix column that is not an array warns and stays zero; the
parseable columns survive instead of the whole matrix dropping to
nothing silently. A matrix field that is not an array of columns has no
shape to keep, so it drops, but it now names itself in a warning. - Dangling cross-references warn: a BMOPF or PMD element referencing an
undefined bus, or a line referencing an undefined linecode, names the
reference instead of parsing silently into a phantom bus. parse_file/parse_strno longer route arbitrary JSON to the BMOPF
reader: a.jsonwithout the PMDdata_modelmarker, and without a
BMOPFbustable beside another BMOPF table, errors (a PowerModels
document used to parse into a bogus near-empty network). A pre-0.1.0
feeder fragment with novoltage_sourcestill classifies, because the
reader accepts it. An explicit format override still forces the reader.
- PMD bound arrays keep their finite entries when another entry is a
- BMOPF schema 0.1.0 (bmopf-report#16). The writer targets the published
schema$idand the reader keeps accepting the pre-0.1.0 spellings:metacarriescase_study_generator(wasgenerator) and the system
frequency; the reader also still accepts the legacy top-level
frequency/base_frequency.- Load
modelstrings are uppercase (CONSTANT_POWER,ZIP, ...). - Bus symmetrical component bounds are the per-sequence scalars
vpos_min/vpos_max/vneg_max/vzero_max/vn_max; legacy
vsym_min/vsym_maxarrays map on read assuming zero/positive/negative
order.DistBusrenames the fields, part of the.pio.json0.2.0 bump
above. - Three phase transformers emit one lumped
r_series/x_seriespair on
the wye base, with each winding's percent resistance referred to its own
rating before the sum; the split_from/_tofields lost their slots. - Transformer taps, neutral impedance, and no load admittance relocate to
extras.transformer.<subtype>.<name>(the schema's escape hatch); the
IBR, control profile, DC, and time series tables relocate underextras
the same way. The reader folds all of them back. - A typed
capacitorelement (DistCapacitor:bus,terminal_map,
configuration,q_rated,v_nom). The DSS converter still lowers
OpenDSS capacitors to shunt matrices; the dss and PMD writers drop typed
capacitors with a warning. - Lines accept the inline impedance alternative to
linecode+length
(read into a synthesized linecode) and carryi_max/s_max. The line
ratings map to the ENGINEERING line's owncm_ub/sm_ub(both
directions; an inline line's ratings stay on the synthesized linecode),
and the dss writer warns when it drops them (thenormamps/emergamps
mapping decision is #266). - One-triangle matrix spellings mirror on read, the shorthand
BMOPFTools' reader also accepts; a spelled cell always wins, and both
writers emit full matrices. - Generator
s_max/i_maxand linecodesourceare typed fields, read
and written; the dss and PMD writers warn when they drop them. - The
metaprovenance fields (title, description, license, authors,
data_sources, created, modified, provenance, version) survive a BMOPF
round trip; the writer keeps owning$schema,frequency, and
case_study_generator. - A grounded terminal counts as referenced, so the unused-terminal prune
no longer silently drops standalone grounding. - The vendored schema and example networks track bmopf-report@f2e3684;
cargo run -p powerio-dist --example regen_bmopf_examplesregenerates
the checked-in example outputs.
- Python:
Network.write_file(path, to)/DistNetwork.write_file(path, to)
and aconvert_file(..., out=...)output path write the serialized case to
disk exactly as produced. Writingto_formattext through
open(path, "w")corrupts a CRLF source echo on Windows (text mode turns
each\r\ninto\r\r\n, which PSS/E family tools reject as malformed
records); the new paths bypass Python's newline translation.
DistNetwork.write_filealso writes any sidecar the writer produced beside
the case, so a dss write that emits aBuscoordsdirective no longer names
a file that does not exist.
What's Changed
- ci: cancel a superseded run on a pull request branch by @samtalki in https://github.com/eigenergy/powerio/pull/277
- dist: BMOPF schema 0.1.0 alignment by @samtalki in https://github.com/eigenergy/powerio/pull/264
- test: pin the terminal renumbering scheme (#266 item 3) by @samtalki in https://github.com/eigenergy/powerio/pull/276
- dist: JSON reader validation hardening by @samtalki in https://github.com/eigenergy/powerio/pull/267
- dist: harden the JSON classifier against adversarial input by @samtalki in https://github.com/eigenergy/powerio/pull/278
- pkg: one version number for .pio.json by @samtalki in https://github.com/eigenergy/powerio/pull/269
- py: file-writing API that bypasses newline translation by @samtalki in https://github.com/eigenergy/powerio/pull/265
- Release 0.8.0 by @samtalki in https://github.com/eigenergy/powerio/pull/279
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.7.3...v0.8.0
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] 7 days ago
PowerIO - v0.7.3
Security fixes for parsing untrusted case files. The parsers are written to reject malformed input with an error, never to crash, exhaust memory, or read or write files outside the ones named on the command line; this release closes several gaps in that model.
- A PowerWorld
.auxlegacyDATAheader whose field list closes before it opens (]before[) no longer panics on an inverted slice. It returns a read error, matching the guard the parenthesized form already carried. - OpenDSS
Redirect/Compile/Buscoordsno longer read arbitrary local files. Parsing from a string (parse_dss_str, and the C ABI and Python string entry points) disables filesystem includes entirely, so untrusted.dsstext cannot pull in a file such as/etc/passwdand echo its contents back through bus names. Parsing from a file (parse_dss_file) still follows includes, now confined to the case directory: an include that resolves outside that directory is refused with a warning, whether it climbs out with..or is an absolute path outside the directory. - OpenDSS
phases,windings, andwdgcounts are capped. A single small property could otherwise size a dense n by n conductor matrix or a per-winding vector into the gigabytes; an oversized value clamps to the supported maximum with a warning. - A PMD ENGINEERING impedance or admittance matrix dimension is capped the same way, so an array of thousands of empty rows no longer demands an n by n allocation.
- The matrix pipeline and the CLI
sensitivitiescommand sanitize the case name before it forms an output filename. A name like../../xor an absolute path can no longer steer a write outside the chosen output directory. - The PowerWorld
.pwdreader groups drawing records by tag in logarithmic time and bounds its substation identity search with a probe budget, so a crafted file cannot force quadratic work. - The OpenDSS include confinement holds for a case file parsed by bare filename: an empty case directory no longer passes every path as a prefix match, so
Redirect /etc/passwdinparse_dss_file("master.dss")is refused. A case directory that itself starts with..now confines rather than refusing everything under it. - OpenDSS includes are also checked after symlink resolution: a lexically contained include that is really a symlink out of the case directory is refused.
parse_raw_filenow confines includes exactly likeparse_dss_fileinstead of following them anywhere on disk. sanitize_stemfollows Windows filename rules (trailing dots trimmed, reserved device names likeconprefixed, length capped) and appends a short hash of the original name whenever sanitization changed it, so two distinct case names that sanitize alike (a/banda_b) cannot silently overwrite each other's files in a multi case export. The gridfm dataset writer routes its output directory through the same sanitizer.- A
DistNetworkarriving without reader caps (the model JSON C entry point deserializes one unchecked) can no longer force quadratic allocation out of linear-size input: the BMOPF writer caps the dense zero fill for an absent linecode/shunt matrix and the transformerx_scpair expansion at 64 conductors/windings, with a warning. - A
NetworkJSON bus id nearusize::MAXis rejected when 3-winding transformers are present, closing an integer overflow in the synthetic star bus allocation that could alias an existing bus. An oversized piecewise costncostclamps instead of overflowing during normalization and Surge export. - The Python
mcpextra pins the SDK below 2.0, which removed themcp.server.fastmcpmodule the server imports. - OpenDSS
like=splicing is capped per object. A self-referencing or mutually-referencing chain (Edit Load.a like=arepeated) otherwise doubled an object's property count each edit, so a few hundred bytes could exhaust memory; the splice is now refused with a warning past the cap. - The PMD writer no longer panics on a transformer with no windings, reachable from a PMD or BMOPF document with the winding array absent. The emergency rating default derives from the first winding only when one exists.
- A PSS/E transformer
CODfield of an extreme magnitude (which saturates toi64::MIN) no longer overflows when the control mode is decoded; it reads as a fixed ratio. - The PowerWorld
.auxreader routes a bus's ownBusNum/Numberthrough the same validation as every bus reference, so a fractional or out-of-range value is a read error instead of a silently truncated or saturated id. - A GOC3 bus uid of
bus_<usize::MAX>no longer overflows when its suffix is mapped to a bus id; it falls back to the 1-based document position. - The MCP server's allowed-roots write check follows a symbolic link in the output filename before deciding containment. A dangling link named as the output file, sitting inside an allowed root but pointing outside it, could otherwise pass the check while the write escaped the sandbox.
- Lifting a GOC3 time series into a package operating-point series binds the declared
time_periodsto theinterval_durationarray length (the same equality the SCOPF loader enforces). An oversizedtime_periodsthat does not match the data no longer drives an unbounded per-period allocation; the series is refused with a diagnostic and the package stays static. - The PMD writer caps the conductor count it expands into square matrices. A switch or voltage source terminal map is a linear model array, and a 35 KB case file naming thousands of terminals drove a 360 MB document and 1.5 GB of resident memory; the matrices now emit at 64 conductors with a warning while the terminal list itself stays faithful. Reachable from any distribution case file, not only the unchecked C entry point.
- The dist graph builder caps the transformer winding count feeding its pair expansion, so a
DistNetworkdeserialized without reader caps cannot turn a linear winding array into a quadratic edge list. - A degenerate model matrix (rows shorter than the row count) reads as zero in the PMD writer instead of panicking on an out of range index, matching the DSS writer.
sanitize_stemhashes a name that already carries the disambiguating suffix shape, so the suffixed and unsuffixed name spaces stay disjoint: a case cannot be named to impersonate another case's disambiguated stem, which took no search to construct because the suffix derives from a published hash. The suffix widens to 64 bits, and the DC OPF bundle writer routes its output directory through the same sanitizer instead of a weaker local copy.- The CLI refuses a conversion sidecar whose path is absolute or climbs out of the output directory, closing the join before a writer can reach it.
- Fuzz harnesses cover the distribution family (
dss,pmd_json). Both parse and then write the network back, since a reader cap that does not hold shows up in the consumer that sizes an allocation from it.
What's Changed
- Harden readers against untrusted case files (0.7.3) by @samtalki in https://github.com/eigenergy/powerio/pull/271
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.7.2...v0.7.3
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] 13 days ago
PowerIO - v0.7.2
- CLI case discovery is recursive and covers every supported format (#260):
powerio batchand the TUI walk the input directory for.m,.raw,
.aux,.epc,.pwb,.json, and.dssfiles, matched case
insensitively, pruning hidden directories and the output directory. A file
that fails to load during a scan is skipped with a warning instead of
aborting the run, and the no-cases error names the supported extensions.
Distribution cases (.dss, BMOPF/PMD JSON) parse to the multiconductor
model and go through the explicitlower_multiconductor_to_balancedpass,
whose approximations and dropped fields surface as warnings. - A leading UTF-8 byte order mark no longer defeats the JSON classifier or
any text reader.classify_json_text, the transmission read funnel, the
distribution parsers (including.dssand redirected files), the PMD/BMOPF
JSON split,Network::from_json, andPackage::from_jsonall strip it,
and the parse warnings itemize the removal (a same-format echo returns the
text without the mark). parse_str_with_name:parse_strplus the name hint role the file stem
plays inparse_file. The CLI now reads and classifies a.jsoncase
once and hands the text straight to the typed parser; a batch scan
previously read each.jsontwice and DOM-parsed it three times.- A nameless distribution case loaded by the CLI takes its file stem as the
network name, so batch exports no longer collide on the lowering's
lowered-multiconductorfallback. - JSON reader hardening from a review pass over the family:
- PowerModels: a status field written as a JSON boolean (
"br_status": false) reads out of service instead of in service;baseMVAmust be
finite and positive; gencost rows padded to the MATPOWER matrix width are
trimmed to the declaredncostbefore the per-unit unscale; an
out-of-range cost model number passes through unscaled instead of
wrapping into the piecewise/polynomial rescale. - pandapower: a trafo
sn_mvaof zero or below falls back to the system
base instead of dividing the impedance by zero; string cells can no
longer smuggle"inf"/"nan"into numeric columns. - egret: a polynomial cost exponent key is bounded, so a few bytes of JSON
can no longer demand an arbitrarily large allocation or index out of
bounds. - GOC3: a duplicate
simple_dispatchable_deviceuid is rejected instead of
silently taking another device's time series bounds and cost. - Surge: a float bus reference too large for an index is rejected like the
equivalent integer instead of saturating tousize::MAX. - BMOPF: matrix key indices and winding counts are bounded (a crafted
document could previously demand gigabytes or quadratic work), a missing
linelengthwarns instead of propagating NaN silently, and themeta
block is kept in extras instead of dropped. - PMD: a
data_modelother than ENGINEERING (the index based MATHEMATICAL
model) is rejected instead of being misread as ENGINEERING. .pio.json: a semver build tag containing a hyphen (1.0.0+build-x) no
longer fails the schema version check.
- PowerModels: a status field written as a JSON boolean (
What's Changed
- cli: recursive case discovery; JSON parser hardening; 0.7.2 prep by @samtalki in https://github.com/eigenergy/powerio/pull/260
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.7.1...v0.7.2
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] 23 days ago
PowerIO - v0.7.1
- The SCOPF Julia wire conversion is structural (#252): every struct reaching
the wire classifies its fields (index, renamed, value) through an exhaustive
destructure, so a new field fails to compile until classified and a value
field reusing an index name is never renumbered. Wire output is unchanged. - GOC3 parses once per read (#250): the reader hands its parsed document
forward asParsed::document, and the package boundary derives the
operating point series from it instead of reparsing the retained text. DcOpfInstancecarries the constant cost termc0(generator and nodal
data), and the DC OPF bundle writesc0.mtx/c0_gen.mtx(bundle schema
0.3.0).- Balanced formats harvest and emit coordinates (#183): PowerWorld aux
Latitude:1/Longitude:1, pandapower busgeoPoint strings, PyPSA
buses.csvx/y, each in both directions. Writers with no geometry concept
warn that locations were dropped. - The standalone geographic document (#184):
GeoLayer/ElementKeywith
tolerant reads (headerless buscoords CSV, aliased CSV/JSON records, GeoJSON)
and canonical GeoJSON writes (.geo.json, thepowerio_geoforeign
member);DisplayFormat::GeoJson/DisplayData::Geo;
Network::geo_layer()/apply_geo_layer()with multiconductor equivalents
inpowerio-pkg;Branch.route/DistLine.routepolyline routing (payload
schemas 1.2.0);.pwdpromotion (geo_layer_from_pwd,
apply_substation_points,pwd_mercator_to_lonlat); and
powerio geo extract | apply | convertin the CLI. - C ABI and Python bindings for the new surfaces (#249, #185), all additive
(PIO_ABI_VERSIONstays 4):pio_acopf_from_network/pio_acopf_to_json
/pio_acopf_instance_free,pio_geo_parse/pio_geo_extract/
pio_geo_apply, andpio_dist_geo_extract/pio_dist_geo_apply. Python
gainsparse_geo,Network.geo_layer()/apply_geo_layer()/acopf_instance(),
and the distribution equivalents. - DeepMind OPFData reader (#258):
SourceFormat::DeepMindOpfDataJsonreads
one raw OPFData JSON document as a solved snapshot, echoes the same format
byte for byte, and converts through the standard surface (CLI, C ABI,
Python).
What's Changed
- Type the SCOPF wire renumbering and parse GOC3 once per read by @samtalki in https://github.com/eigenergy/powerio/pull/254
- Add the geographic document and balanced coordinate harvest by @samtalki in https://github.com/eigenergy/powerio/pull/255
- Bind the AC OPF instance and geographic layer over C and Python by @samtalki in https://github.com/eigenergy/powerio/pull/256
- Fix main CI: regenerate schemas, run PR workflows on stacked PRs by @samtalki in https://github.com/eigenergy/powerio/pull/259
- Add DeepMind OPFData JSON reader and conversion support by @cameronkhanpour in https://github.com/eigenergy/powerio/pull/258
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.7.0...v0.7.1
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 1 month ago
PowerIO - v0.7.0
- Add
powerio-probfor complete numerical problem instances (#238). Its
default build is matrix free; thematrixfeature adds sparse projections,
DC OPF bundle output. - Move DC OPF instance types and bundle output out of
powerio-matrix. - Keep solver formulations and KKT operators outside
powerio-prob. - Demote
powerio-jsonfrom the public case format surface (#229). It leaves
the CLI format help and the generated format tables;pio_parse_str(..., "powerio-json", ...)andpio_to_format(..., "powerio-json", ...)keep
working as ABI v4 compatibility aliases, andpio_to_json/pio_from_json
are the documented balanced model JSON API. NetworkPackage::from_balancedis format neutral. Source adapters, such as
GOC3 operating point extraction, run only for parsed reader input through
from_parsed_balanced.- Building a SCOPF instance from text requires an explicit source format.
- Add AC OPF problem instances (#248):
powerio-probgainsAcOpfInstance
andbuild_ac_opf_instance, carrying pi model branch data with separate tap
and shift, per terminal charging, bus shunts, active and reactive demand,
voltage bands, generator PQ bounds, and quadratic cost including the
constant term (GenCost::quadratic_with_constant). Relaxations such as SOC
forms consume the same instance. Matrix free; C ABI and Python exposure is
#249. powerio-probfirst publish review fixes: reserve membership sets now
assign zone indices from the same document order as the reserve rows
(sorted order previously crossedn_p/n_qbetween the two tables and
diverged fromsrc/goc3.jlpast nine zones); a GOC3 branch with
r = x = 0is rejected by name instead of writing NaN into the wire
rows; a missingdevice_typedefaults toproducer, the balanced
reader's rule; the AC instance folds self-loop branch admittance into
the bus shunt vectors, matchingbuild_ybus; both instance builders
reject a non-positive base MVA before scaling; the DC OPF bundle
directory name stays confined to the output directory, and the bundle
manifest reports the powerio core version (powerio::VERSION, new).
SCOPF row structs andDcOpfOutputsare#[non_exhaustive].- DSS reader:
linecode=now sets a line's conductor count the way the
engine's FetchLineCode does, the later ofphases=/linecode=winning.
A 4-wire line without an explicitphases=keeps its neutral instead of
truncating the terminal map to 3 against a 4x4 linecode
(frederikgeth/BMOPFTools.jl#332); thanks @frederikgeth
What's Changed
- Add C ABI construct/attach for operating point series by @samtalki in https://github.com/eigenergy/powerio/pull/239
- Add powerio-prob with matrix free DC OPF instances by @samtalki in https://github.com/eigenergy/powerio/pull/240
- Move GOC3 SCOPF instances into powerio-prob by @samtalki in https://github.com/eigenergy/powerio/pull/242
- Expose SCOPF instances over C and Python by @samtalki in https://github.com/eigenergy/powerio/pull/243
- Remove oversized GOC3 fixture and shorten C setter by @samtalki in https://github.com/eigenergy/powerio/pull/245
- DSS reader: take a line's conductor count from its linecode by @samtalki @frederikgeth in https://github.com/eigenergy/powerio/pull/247
- Enforce problem instance boundaries by @samtalki in https://github.com/eigenergy/powerio/pull/246
- Add AC OPF problem instances to powerio-prob by @samtalki in https://github.com/eigenergy/powerio/pull/251
- docs: rewrite public documentation for v0.7 by @samtalki in https://github.com/eigenergy/powerio/pull/244
- Fix powerio-prob review findings before the first publish by @samtalki in https://github.com/eigenergy/powerio/pull/253
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.6.3...v0.7.0
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 1 month ago
PowerIO - v0.6.3
- Arrow matrix axes (#234): the C ABI Arrow export gains a table catalog and
dense matrix axis maps.pio_to_arrowexposesmatrix_busand
matrix_branchaxis tables alongside theybus,incidence,bprime, and
bdoubleprimeCOO tables, which carrypowerio.row_axis/powerio.col_axis
schema metadata so a consumer maps dense matrix rows and incidence columns
back to source bus and branch rows. Matrix rows are labeled with the
matrix_busaxis, which stays correct when 3-winding transformer star-point
lowering expands the bus set past the handle bus order. - FDPF matrices (#234):
bprime/bdoubleprimefollow MATPOWERmakeB
semantics, with self-loop handling and asymmetric Matrix Market writes pinned
by Rust, C ABI, and Python coverage. - Summary JSON (#234): the C ABI exposes balanced (
pio_summary_json) and
distribution summary JSON, so a binding can render network summaries without
materializing the full model payload. - Matrix Arrow export (#234): the numeric matrix export path fills Julia-owned
buffers directly for the copy-free fast path.
What's Changed
- [codex] Add Arrow catalog and matrix axes by @samtalki in https://github.com/eigenergy/powerio/pull/234
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.6.2...v0.6.3
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 1 month ago
PowerIO - v0.6.2
- Normalization (#210): angle bound clamping now keeps every repaired branch
interval ordered. One sided intervals wholly outside the supported window are
widened to the configured pad instead of producingangmin > angmax; Rust,
C ABI, and Python normalize option coverage pin the behavior. - Binding coverage (#185): the already shipped study block and distribution
graph projection now have C ABI and Python accessors. The remaining geo
binding symbols stay in the v0.6.3 follow through. - BMOPF diagnostics (#219): distribution conversions now carry structured
diagnostics alongside warning strings, and transformer export losses expose
stableEMIT.BMOPF.*codes for downstream tests and capability checks. - BMOPF transformer fidelity (#214, #215, #216, #217): OpenDSS fixed
transformer taps, center tap convention fields, delta_wye leakage referral,
and n_windingdelta_rollnow export directly in BMOPF form with regression
coverage against schema valid output and unaffected fixture byte identity. - BMOPF source fidelity (#218): per phase OpenDSS voltage sources on the same
bus merge into one BMOPFvoltage_sourcewhen their phase angles are
coherent; ambiguous, bounded, priced, or conflicting source banks stay split
with warnings. - Distribution capabilities (#213): the C ABI
distfeature exposes
pio_dist_capabilities_json, reporting the six BMOPF fidelity flags that
PowerIO.jl and downstream tools can probe at runtime. - Geographic fields (#180): balanced and distribution models now share typed
GeoMeta/LocationJSON shapes.Network.geo,Bus.location,
DistNetwork.geo, andDistBus.locationare optional and omitted when
absent. OpenDSS Buscoords and BMOPF longitude/latitude sideloads promote into
typed bus locations; OpenDSS writes a Buscoords sidecar when locations are
present, while BMOPF longitude/latitude output remains opt in and only emits
declared geographic coordinates. .pio.jsonmodel JSON: the balanced and multiconductor payload schema
versions move from1.0.0to1.1.0for the additive geographic fields.
The package metadata schema, C ABI version, and Python package surface stay
in the 0.6 compatibility band.- JSON strategy:
.pio.jsondocs now state that it is PowerIO's compiled
artifact, not a case format; payload schemas are for validating model JSON
inside.pio.jsondocuments;powerio-jsonremains supported, is deprecated
for CLI file handoffs, and is no longer shown in the PR conversion matrix.
What's Changed
- Keep angle bound clamp repairs ordered by @samtalki in https://github.com/eigenergy/powerio/pull/211
- Expose study and dist graph bindings by @samtalki in https://github.com/eigenergy/powerio/pull/212
- Emit structured BMOPF transformer diagnostics by @samtalki in https://github.com/eigenergy/powerio/pull/220
- Preserve fixed OpenDSS transformer taps in BMOPF export by @samtalki in https://github.com/eigenergy/powerio/pull/221
- Emit BMOPF center tap transformers in the BMOPF convention by @samtalki in https://github.com/eigenergy/powerio/pull/222
- Refer BMOPF delta_wye leakage to each winding base by @samtalki in https://github.com/eigenergy/powerio/pull/223
- Emit explicit delta_roll for BMOPF n_winding transformers by @samtalki in https://github.com/eigenergy/powerio/pull/224
- Merge split OpenDSS voltage sources in BMOPF export by @samtalki in https://github.com/eigenergy/powerio/pull/225
- Expose distribution capability flags through C ABI by @samtalki in https://github.com/eigenergy/powerio/pull/226
- Add typed geographic fields to network models by @samtalki in https://github.com/eigenergy/powerio/pull/227
- Prepare v0.6.2 release by @samtalki in https://github.com/eigenergy/powerio/pull/228
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.6.1...v0.6.2
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 1 month ago
PowerIO - v0.6.1
- CI: added wasm32 coverage for the core Rust crates (#186), external BMOPF
JSON Schema validation for emitted distribution documents (#192), and
generated.pio.json/ model JSON schema drift checks (#178). - Distribution fidelity (#197): OpenDSS and BMOPF writers preserve transformer
winding voltage bases, no load admittance, tap settings, neutral impedances,
and multi winding transformer structure. Roundtripped OpenDSS decks now run
through a solve oracle that checks voltage agreement, load voltage model
behavior, and neutral return handling. - Distribution DER mapping (#197): typed IBR and control profile data now round
trips through OpenDSSPVSystem/Generator/InvControland BMOPF
ibr/control_profilerecords, with warnings for unsupported control
details. .pio.jsondocuments (#181, #193): added the study block for replayable
balanced model edits, materialization helpers, deterministic uid stamping,
and balanced reader warnings as structured.pio.jsondiagnostics.- Normalization (#188): added an opt-in angle bound clamp pass with Rust, C ABI,
and Python entry points; existing normalization behavior is unchanged. - Distribution graph projection (#182): added a bus and terminal graph view for
DistNetwork, including transformers, open switches, and terminal metadata. - Matrix bindings (#190): added Arrow C ABI matrix exports as COO triplet tables
for Ybus, incidence, B', and B'', with C and Python golden coverage. - Sensitivities (#8): added sparse and iterative PTDF/LODF export paths with
drop tolerance metadata, while retaining the dense path as the small case
oracle. - Documentation (#191): standardized released docs, READMEs, and crate metadata
around.pio.jsondocument, model JSON, and metadata terminology.
powerio-pycontinues to inherit the workspace version; no separate Python
version bump is needed.
What's Changed
- Add wasm32 CI check by @samtalki in https://github.com/eigenergy/powerio/pull/198
- Preserve transformer neutral impedance by @samtalki in https://github.com/eigenergy/powerio/pull/199
- Add OpenDSS solve fidelity oracle by @samtalki in https://github.com/eigenergy/powerio/pull/200
- Map distribution IBR controls to OpenDSS by @samtalki in https://github.com/eigenergy/powerio/pull/201
- Validate emitted BMOPF JSON in CI by @samtalki in https://github.com/eigenergy/powerio/pull/202
- Clamp normalize angle bounds opt in by @samtalki in https://github.com/eigenergy/powerio/pull/203
- Add package study block diagnostics by @samtalki in https://github.com/eigenergy/powerio/pull/204
- Add distribution graph projection by @samtalki in https://github.com/eigenergy/powerio/pull/205
- Add C ABI matrix Arrow tables by @samtalki in https://github.com/eigenergy/powerio/pull/206
- Sparse PTDF and drop tolerance by @samtalki in https://github.com/eigenergy/powerio/pull/207
- Serve generated JSON Schemas by @samtalki in https://github.com/eigenergy/powerio/pull/208
- Prepare v0.6.1 release by @samtalki in https://github.com/eigenergy/powerio/pull/209
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.6.0...v0.6.1
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 1 month ago
PowerIO - v0.6.0
- Breaking (#175):
ElementRef.rowisOption<usize>, the honest form of the
0.5.1 wire semantics.Noneaddresses by identity alone (refs built with
by_source_uid); the private wire-presence shim (wire_row()) is gone, and
rowitself says whether the wire carried one. The.pio.jsonwire format
is unchanged. The other break collected in #175, keyed-object addressing for
multiconductor operating point updates, needs design and moves to the 1.0
window (#196). - C ABI: the package payload extraction inverses land as additive symbols (no
ABI version change; probe the symbols like the other feature surfaces):
pio_package_to_balanced_networkandpio_package_to_multiconductor_network
materialize an owned network handle from a parsed.pio.jsonpackage handle,
the inverses of thepio_package_from_*constructors. A handle built from a
payload retains no source text, so a same-format write is a fresh
serialization rather than a byte-exact echo; the multiconductor payload's
parse warnings ride along. - C ABI:
pio_to_json/pio_from_jsonare the function form of the balanced
model JSON (byte identical to thepowerio-jsonwriter); the format token
remains as a compatibility alias for file based workflows. This is the
additive half of #194; retiring the token waits for 1.0. - C ABI:
pio_dist_to_json/pio_dist_from_jsonserialize a distribution
handle to its model JSON and back in one call each: the same object a
.pio.jsondocument carries undermodel.multiconductor_network, without
the surrounding document. Bindings materialize element tables with this
instead of building a throwaway package; it is not a case format (the
converter, CLI, and inference do not know it), so BMOPF JSON remains the
distribution JSON exchanged with other tools. - C ABI:
pio_classify_strclassifies in-memory JSON by the same top level
markers the transmission parser's.jsonsniffing uses, and recognizes
.pio.jsonenvelopes:transmission:<format>,distribution:<format>,
package,ambiguous, orunknown, size-then-fill. Bindings can route a
bare.jsonbefore choosing a parser instead of matching error text. - The JSON classifier reports a
.pio.jsonenvelope as its own outcome
(routing::JsonClass), so every consumer handles it: the CLI, the Python
readers, and the Pythonclassify_json_textnow name the package surface
for an envelope instead of a generic cannot-infer error (or, for the Python
string reader, a MATPOWER syntax error). Envelope detection requires
model_kindto bebalancedormulticonductor, so a case document
carrying those key names with other values still classifies as a case, and
classification parses the document once. - Directed errors at the transmission boundary: a
.dsspath, a distribution
fromtoken (dss/pmd/bmopf), and a.pio.jsonenvelope handed to the
balanced parser now name the surface that reads them instead of a generic
unknown-format message.
What's Changed
- Document what the .pio.json format is and how it relates to BMOPF by @samtalki in https://github.com/eigenergy/powerio/pull/177
- Add design chapters for geographic data and the study block by @samtalki in https://github.com/eigenergy/powerio/pull/179
- Package payload inverses, JSON classifier entry point, directed boundary errors by @samtalki in https://github.com/eigenergy/powerio/pull/187
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.5.1...v0.6.0
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 1 month ago
PowerIO - v0.5.1
The .pio.json payload schema is declared and versioned independently of the envelope (payload_schema, payload_schema_version; envelope schema_version 0.1.1). Payload rows carry stable uid identities. Operating point updates resolve by identity, a present row is a consistency check, and unknown identities are rejected at materialization and by validation. Packages from 0.5.0 read unchanged.
Python table dicts expose uid. No C ABI signature changes. Docs are restructured and served at https://powerio.dev.
Details in CHANGELOG.md.
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by samtalki about 1 month ago
PowerIO - v0.5.0
powerio-pkg:NetworkPackageis the one package type name (CompilerPackage
is gone); the Julia binding already leads withNetworkPackage. The.pio.json
format is unchanged.- Python API: the seven module level
package_*functions are replaced by the
powerio.Packagehandle class, which parses the envelope once and exposes
model_kind,operating_points(),materialize_operating_point(),
as_balanced()/as_multiconductor(),validate(),validation(),
diagnostics(), and the multiconductor to balanced preflight and lowering. .pio.jsonoperating points: the per pointlabelandduration_hoursfields
are gone;time_axis.labelsandtime_axis.duration_hours(indexed by
points[].index) are the one source of truth. Readers ignore the old fields.- Transmission formats: added GOC3 JSON input and Surge JSON read and write paths.
GOC3 packages lift source time series into.pio.jsonoperating_points,
and package APIs can materialize one point into a static package. - GOC3 reader fixes: branches with
additional_shuntkeep the line charging
(b/2per terminal added to the extra shunts, per the GO Challenge 3
formulation);ta_lb/ta_ubmap to anActiveFlowtransformer control
range instead of fabricatingangmin/angmaxbus angle limits; producers
and consumers honorinitial_status.on_statuslike every other record type;
object form section keys sort under a total order (mixed numeric and non
numeric keys no longer risk a sort panic). powerio-pkg: GOC3 operating point extraction now consumes the parser's own
document walking (device_rows,section,cost_atshared through a
bridge), so update row indices match the payload by construction, including
devices without auid. A failed extraction attaches a
READ.GOC3.OPERATING_POINTS_DROPPEDdiagnostic instead of silently
producing a static only package. Materialized packages clearpackage_id
(the parent id lives inorigin.parent_package_id).- PSS/E
.raw: revision aware record layouts for v34/v35 transformer winding
lines (twelve ratings,NODE), v35 generator records (NREG,BASLOD),
and v35 switched shunts (NREG, per block status triples), on both read and
write; the 2W/3W transformer split accepts float formKfields. The
case14_v34.raw/case14_v35.rawfixtures are regenerated in the genuine
layouts. - PSLF
.epcwriter: parallel loads and shunts on one bus get distinct ids
(extras["id"]preferred, positional fallback); the reader captures load,
shunt, and SVD ids intoextras["id"]so they survive cross format writes. - PowerWorld
.pwb: the table location search runs under a work budget, so a
crafted file fails with a read error instead of pinning a core for hours. - Surge JSON writer warns when named branch rating sets are dropped, like every
other lossy writer. - Writing a read only format (
goc3-json) returns the new
Error::WriteUnsupportedinstead of a misleadingUnknownFormat. - C ABI: the panic guard now covers index construction in the parse entry
points;pio_package_validatedocuments its exclusive access requirement
(the one nonconstentry point) and the header preamble scopes the
concurrent read guarantee accordingly;PioDistNetworkgains the same
compile timeSend + Syncassertion as the other handles. SourceFormat::name()is the one source format name mapping; the package,
CLI, and Python copies are gone.
What's Changed
- draft: v0.5.0/v1.0.0-alpha - prepare IR structs for stable construction by @samtalki in https://github.com/eigenergy/powerio/pull/169
- Add package operating points, GoC3, and Surge JSON support by @samtalki in https://github.com/eigenergy/powerio/pull/172
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.4.0...v0.5.0
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 1 month ago
PowerIO - v0.4.0
powerio-pkg:.pio.jsonreads now enforce the envelope compatibility rule:
same majorschema_versionvalues load, while incompatible major versions
fail before payload use. The mdBook schema page documents the rule.powerio-pkg: balanced package output now emits source maps for stable bus,
load, shunt, branch, and generator fields; validation diagnostics attach the
matching source reference where a map exists. Format folded fields use
mapping kinds such assplit, and defaulted fields are not marked as exact
source fields.- Converter tests now compare stable per element values across writable legacy
formats, not only counts and totals. PSLF export now warns when transformer
charging admittance is dropped. powerio-distBMOPF: OpenDSS fixed P/Q generators now emit as BMOPF
generator.*entries with pinned P/Q bounds instead of negativeload.*
entries. The old negative load warning is gone; generators without source
costs keep the existing cost 0 warning.- Python API: removed the one release
powerio.Caseand
powerio.dist.DistCasecompatibility aliases. Usepowerio.Network/
powerio.BalancedNetworkandpowerio.dist.MulticonductorNetwork/
powerio.dist.DistNetwork. - No C ABI rename in this migration slice:
PIO_ABI_VERSIONstays 4 and
PIO_DIST_ABI_VERSIONstays 1.
What's Changed
- [data] rich data model parity by @samtalki in https://github.com/eigenergy/powerio/pull/143
- [pkg] add .pio.json compiler package envelope by @samtalki in https://github.com/eigenergy/powerio/pull/156
- [codex] Add generator cost policy and package validation diagnostics by @samtalki in https://github.com/eigenergy/powerio/pull/154
- Consolidate docs into mdBook guide by @samtalki in https://github.com/eigenergy/powerio/pull/160
- Stabilize compiler package spine by @samtalki in https://github.com/eigenergy/powerio/pull/161
- Implement multiconductor lowering by @samtalki in https://github.com/eigenergy/powerio/pull/163
- Add MCP package transport by @samtalki in https://github.com/eigenergy/powerio/pull/162
- Add normalized solver table package metadata by @samtalki in https://github.com/eigenergy/powerio/pull/164
- [codex] Accept PSS/E Start of section markers by @samtalki in https://github.com/eigenergy/powerio/pull/165
- Add package C ABI surface by @samtalki in https://github.com/eigenergy/powerio/pull/166
- [codex] fix BMOPF generator export by @samtalki in https://github.com/eigenergy/powerio/pull/167
- [codex] prep v0.4.0 release by @samtalki in https://github.com/eigenergy/powerio/pull/168
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.3.3...v0.4.0
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 2 months ago
PowerIO - v0.3.3
- MCP server: unified the advertised tool surface to semantic verbs:
convert,save,summary,parse,normalize,matrix, anddisplay.
The tools route transmission cases, distribution cases, PyPSA CSV folders, and
gridfm datasets by format. Distributionparsereturns canonicalbmopf-json
as its serial transport; transmissionparsereturnspowerio-json.
summarynow has one canonical JSON schema across MCP and the CLI's new
powerio summarycommand. Gridfm is a format behindparse/save, not its
own MCP tool. PowerWorld.pwddisplay files parse throughdisplay, leaving
room for a future open display format without renaming the tool. Older case,
matrix, and PyPSA helper names stay as direct Python compatibility callables
for one release, but they are no longer advertised as MCP tools. - Python API: restored the undocumented
powerio.Case = Networkalias for one
release, but left it out of__all__and docs; remove it in 0.4.0. The
experimental distribution surface now usespowerio.dist.DistNetworkas
the primary name to match the nativeDistNetworkhub type, while the
exportedpowerio.dist.DistCase = DistNetworkalias stays for one release.
powerio.distis gated on the draft BMOPF schema (PIO_DIST_ABI_VERSION= 1)
and not yet under the stability guarantee. - No C ABI change:
PIO_ABI_VERSIONstays 4 andPIO_DIST_ABI_VERSIONstays 1,
and the matrix builders are unchanged. The native extension's internal pyclass
names changed (PyCase → PyNetwork,_DistCase → _DistNetwork) sorepr()
now renders the publicNetwork(...)/DistNetwork(...)form directly; a
rebuilt wheel is required.
What's Changed
- MCP: distribution + display tools; unified tool surface by @samtalki in https://github.com/eigenergy/powerio/pull/141
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.3.2...v0.3.3
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 2 months ago
PowerIO - v0.3.2
powerio-distOpenDSS: grounding reactors written from a bus terminal to the
same bus's node 0 now type as shunts in BMOPF instead of staying untyped.
Impedance form reactors use the equivalent admittance matrix, so neutral
grounding resistors survive DSS to BMOPF conversion.powerio-distOpenDSS: delta capacitor and reactor banks now type as shunt
admittance matrices, including off diagonal branch terms, instead of being
dropped as untyped objects.- DSS writing now regenerates conductance bearing shunts as grounding reactors
and preserves delta shunts asconn=deltawhere the typed model identifies
them. - No core or distribution C ABI break;
PIO_ABI_VERSIONstays 4 and
PIO_DIST_ABI_VERSIONstays 1.
What's Changed
- Fix DSS shunts in BMOPF conversion by @samtalki in https://github.com/eigenergy/powerio/pull/140
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.3.1...v0.3.2
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 2 months ago
PowerIO - v0.3.1
- Parser warnings: PSS/E and PowerWorld
.auxparse warnings now surface
throughParsed::warningsand the C ABI'spio_warningspath instead of
living only in docs or writer warnings. - PSS/E: hardened record tokenization and continuation handling. Slash
characters inside quoted fields are no longer treated as comments; incomplete
transformer and two-terminal DC continuation records now error clearly instead
of consuming section terminators; transformer records with non-unitCW/CZ
now warn that impedance and turns values were read without conversion. - PSS/E: load ZIP components and v34/v35 load tail fields are retained in extras
and replayed on write. If typed loadp/qno longer match retained
PL/QL/IP/IQ/YP/YQ, the writer emits typed constant power and reports the
stale extras instead of replaying wrong source components. - PSS/E: quoted IDs, names, and HVDC names are sanitized before duplicate ID
allocation, so collisions created by replacing quotes or/are handled
deterministically and reported in conversion warnings. - Normalization: generator cost per-unit scaling now dispatches through explicit
cost models, and slack bus selection ignoresNaNgeneratorpmaxvalues
when choosing among candidate reference buses. - PSLF and PowerWorld AUX tokenization: quoted
/and//text is kept as data
rather than treated as continuation or comments. PowerWorld.auxnow reports
unmodeledDATAblocks as parse warnings while retaining source text for
same-format writeback. powerio-distOpenDSS: quoted comment markers are preserved in lexer values,
indented block comments are skipped, capacitor and reactor kvar shunts share
validation, reactors with kvar/kv map to typed shunts with negative
susceptance, and invalid shunt forms stay untyped with explicit warnings.powerio-distBMOPF: fixed OpenDSS generators with fixed P/Q setpoints now
encode as negative BMOPF loads with warnings. The vendored draft schema was
refreshed for multi-digit matrix keys, corrected$id, and nonnegative
switchi_max, so 10-conductor linecode output validates without the old
schema warning.- C distribution ABI v1 (
PIO_DIST_ABI_VERSION1): directpio_dist_*callers
get a separate version check; the supported one-shot conversion order is
(input, from, to, ...). - C ABI tests now reject the old target-before-source conversion order for both
pio_convert_*andpio_dist_convert_*, including the compiled C smoke test
againstpowerio.h. - C ABI hardening: unit tests pin every public
PIO_*macro, opaque typedef,
andpio_*prototype inpowerio.h; Cargo now checks Rust source/header
symbol parity; CI builds the no-default core ABI plus the release
arrow,gridfm,distfeature smoke test and C++ header/link sanity checks. - No core C ABI break;
PIO_ABI_VERSIONstays 4. No existing Rust or Python
API was removed or reordered.
What's Changed
- [codex] Harden parser tokenization and dist shunts by @samtalki in https://github.com/eigenergy/powerio/pull/138
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.3.0...v0.3.1
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 2 months ago
PowerIO - v0.3.0
- Distribution systems: new
powerio-distcrate for multi conductor unbalanced
networks. Reads OpenDSS and the PowerModelsDistribution engineering JSON, and
reads/writes the IEEE BMOPF Taskforce JSON (schema v0.0.1). First crates.io
release ofpowerio-dist. thanks @frederikgeth @deakinmt @matheusduartedm - PSS/E: read and write support for v34 and v35 alongside v33.
- GE PSLF: an
.epcwriter, with better interoperability between PSLF and PSS/E. - Transformers with three or more windings.
- C ABI v4 (
PIO_ABI_VERSION4): a smaller canonical surface designed so future
changes stay additive. Breaking ABI change in this release. - Memory safety hardening across the readers.
What's Changed
- v0.3.0 candidate: memory safety hardening + C ABI v4 by @samtalki in https://github.com/eigenergy/powerio/pull/116
- PSS/E v33/v34/v35, A PSLF
.epcwriter, closing model gaps, and network operations toolchain by @samtalki in https://github.com/eigenergy/powerio/pull/130 - feat: powerio-dist, a multiconductor distribution crate with dss/PMD/BMOPF converters by @samtalki and @frederikgeth in https://github.com/eigenergy/powerio/pull/82
- chore(deps): update bot workflows, PyO3, Arrow/Parquet stack, and remove transitive Thrift 0.17 by dependabot in https://github.com/eigenergy/powerio/pull/128
- feat(dist): typed grounding reactor support by @matheusduartedm in https://github.com/eigenergy/powerio/pull/137
- Release: v0.3.0 by @samtalki in https://github.com/eigenergy/powerio/pull/133
New Contributors
- @matheusduartedm made their first contribution in https://github.com/eigenergy/powerio/pull/137
- @frederikgeth made their first contribution in https://github.com/eigenergy/powerio/pull/82
- special thanks to @deakinmt for the thorough review on https://github.com/eigenergy/powerio/pull/82
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.2.4...v0.3.0
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 2 months ago
PowerIO - v0.2.4
- PSLF
.epc: read support for GE PSLF power flow cases, including.epc
extension inference andpslf/epcinput aliases. The reader is read only
and keeps source text plus warnings for sections outsideNetwork. - PowerWorld
.pwb: expanded binary reader coverage across older and newer
header constants, with stricter record probes, companion format parity checks,
and clearer rejection of unsupported vintages. - PowerWorld
.pwd: display parsing keeps the separate display API path and
retains the malformed input invariant: corrupt or truncated display files
return a structured error or a parsed display, not a panic. - No C ABI break;
PIO_ABI_VERSIONstays 3.
What's Changed
- Add PSLF EPC reader + Improve coverage of PW vintages by @samtalki in https://github.com/eigenergy/powerio/pull/125
- release: v0.2.4 by @samtalki in https://github.com/eigenergy/powerio/pull/127
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.2.3...v0.2.4
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] about 2 months ago
PowerIO - v0.2.3
- Normalization:
Network::to_normalizedpreserves source bus ids instead of
renumbering surviving buses to dense 1-based ids. Dense row mapping remains
available throughIndexedNetworkand the C ABI table order.
What's Changed
- Preserve source bus IDs in normalized networks by @samtalki in https://github.com/eigenergy/powerio/pull/122
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.2.2...v0.2.3
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] 2 months ago
PowerIO - v0.2.2
- Display API:
parse_display_file/parse_display_bytesread display
artifacts separately from network cases. PowerWorld.pwdreturns
DisplayData::PowerWorld(PwdDisplay)in Rust and
DisplayData("powerworld", PwdDisplay(...))in Python.parse_file
remains Network only and points.pwdcallers at the display API. - PowerWorld AUX: name keyed complete case exports can resolve
BusName_NomVoltlabels for loads, shunts, generators, and branches. - PSS/E: the reader accepts comment headers, system wide records before
BEGIN BUS DATA, and v34 named branch records without misclassifying
long v33 branch rows. - MCP: add dedicated tools for PyPSA CSV folders and gridfm Parquet datasets.
- DC sensitivities: PTDF/LODF fall back to dense Gaussian elimination for
invertible indefinite grounded Laplacians.
What's Changed
- feat(mcp): add PyPSA CSV folder and gridfm Parquet read/write tools by @qian-harvard in https://github.com/eigenergy/powerio/pull/119
- ci: notify PowerIO.jl on release publish by @samtalki in https://github.com/eigenergy/powerio/pull/118
- feat: Add display parsing API by @samtalki in https://github.com/eigenergy/powerio/pull/120
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.2.1...v0.2.2
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] 2 months ago
PowerIO - v0.2.1
Hardening fixes only; no API or ABI change (PIO_ABI_VERSION stays 3).
- MATPOWER: a crafted
gencostNCOST (e.g.1e20) overflowed the row
width arithmetic and panicked on every build profile, a denial of
service on untrusted input through the Rust API and the CLI. The width
now saturates and the row is rejected as aShortRowparse error.
Found by malformed input fuzzing. - C ABI: error and warning messages were clipped at a raw byte count,
which could split a multibyte UTF-8 character and hand the caller an
invalid string. Truncation now lands on a character boundary. - PowerWorld
.pwd: the reader's byte accessors returnOptioninstead
of indexing, so an out of range offset from a corrupt file rejects the
record instead of panicking. A corruption sweep test pins the
invariant; the differential oracle tests pass unchanged. powerio.h: a doc comment contained a literal*/that terminated
the generated block comment, so compiling with-DPIO_GRIDFMagainst
the shipped 0.2.0 header failed withunknown type name 'raw'.
What's Changed
- release: 0.2.1 by @samtalki in https://github.com/eigenergy/powerio/pull/117
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.2.0...v0.2.1
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] 2 months ago
PowerIO - v0.2.0
- PowerWorld
.pwbbinary reader (#95, #102, #105): read only, covering
June 2016 through 2022 era exports under header constants 425, 483, 508,
537, 550, and 551, parity tested against same vintage.aux/.RAW/.m
siblings up to the 6717 bus Texas7k. Unsupported writer vintages are
rejected with the format constant named. - pandapower JSON converter (#106): read and write
pandapowerNetJSON.
Written trafo parameters reproduce the source Y_bus exactly through
pandapower 3.x's transformer model, ZIP load columns go out in both the
<= 3.1 and >= 3.2 namings, and CI validates the converter against
pandapower itself over the vendored fixtures. - PyPSA CSV folder converter (#106): read and write the static network
CSV folder, CI validated against PyPSA over the vendored fixtures.
Folders parse throughparse_file(..., "pypsa-csv"), auto-detected for
a directory holdingnetwork.csv; the CLI takes--from pypsa-csvand
--to pypsa-csv -o <dir>. - PowerWorld
.pwddisplay reader (#102): substation diagram coordinates,
matched 1-1 against the aux substations on every probed save with a same
vintage aux (the v19 resave matches 1248/1250 against the published
case, a vintage skew). - Read fidelity channel (#106):
parse_file/parse_strreturn
Parsed { network, warnings }, so what a reader cannot carry is
itemized instead of dropped silently. Python exposes
Network.read_warningsand the MCP tools report it; the C ABI gains
pio_parse_warningsandpio_write_pypsa_csv_folder(additive, ABI
version stays 3). - Full
.auxfidelity (#95): all three field naming generations through
Simulator 21+, validated against the vendored ACTIVSg200 set. docs/powerworld.mdrecords the decode evidence, mapping notes, and the
coverage matrix the corpus tests assert.
What's Changed
- feat(powerworld): full aux fidelity, .pwb reader, ACTIVSg validation by @samtalki in https://github.com/eigenergy/powerio/pull/95
- feat(powerworld): 2019+ era .pwb decode, table search at speed, .pwd substation coordinates by @samtalki in https://github.com/eigenergy/powerio/pull/102
- feat(powerworld): every Texas7k save decodes; the 2021 era record layouts and headers 483 through 551 by @samtalki in https://github.com/eigenergy/powerio/pull/105
- issue-47 by @qian-harvard in https://github.com/eigenergy/powerio/pull/106
- release: 0.2.0 by @samtalki in https://github.com/eigenergy/powerio/pull/108
- fix: rename powerworld/aux.rs, a Windows-reserved filename that broke release checkout by @samtalki in https://github.com/eigenergy/powerio/pull/110
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.1.1...v0.2.0
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] 2 months ago
PowerIO - v0.1.1
- File extension detection is case-insensitive (#97, #101):
parse_file
accepts.RAW/.M/.JSON/.AUXand any mixed case alongside the
lowercase forms, and the CLI batch discovery and TUI file browser find
such files too. Reported by @jd-foster. - MCP server error hardening (#93): an unreadable input file surfaces as
the documented ValueError shape instead of a rawPermissionError, with
defensive guards on the JSON load and matrix dispatch paths.
What's Changed
- Add Claude Code GitHub Workflow by @samtalki in https://github.com/eigenergy/powerio/pull/94
- fix: make file extension detection case-insensitive by @samtalki in https://github.com/eigenergy/powerio/pull/101
- fix(mcp): unreadable files keep the ValueError shape; harden error mapping by @samtalki in https://github.com/eigenergy/powerio/pull/93
- release: 0.1.1 by @samtalki in https://github.com/eigenergy/powerio/pull/103
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.1.0...v0.1.1
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] 2 months ago
PowerIO - v0.1.0
- gridfm read path (#70):
read_gridfm_dataset/read_gridfm_scenarios/
gridfm_base_caseinpowerio-matrix,pio_read_gridfm/
pio_gridfm_scenario_idsin the C ABI behind--features gridfm, and
powerio.read_gridfm/read_gridfm_scenariosin Python. Release tarballs
now build the C ABI with the gridfm feature, so the symbols ship to the
Julia bindings. convert_str(#88): in-memory conversion through the hub in Rust and
Python; the MCP server's inline conversion no longer stages temp files.
Closes #66.- The MCP server grows from two tools to eight (#90):
parse_case,
normalize_case, andcase_to_jsonemit the JSON transport,
compute_matrixreturns nine sparse kinds in COO form,dense_view
returns the dense table view, andsave_casewrites converted cases to
disk;convert_caseandcase_summaryare unchanged. - Docs (#92): Pages landing page with the released/development split, guide
links, and the logo; the crate homepage points at the docs site; release
drafts carry the CHANGELOG section instead of a bare title.
What's Changed
- docs: lead the crate doc with all five formats by @samtalki in https://github.com/eigenergy/powerio/pull/76
- fix(py): pack license files into the sdist; dispatchable publish; draft releases by @samtalki in https://github.com/eigenergy/powerio/pull/79
- ci: bump actions off Node 20 by @samtalki in https://github.com/eigenergy/powerio/pull/80
- ci: publish the library crates to crates.io on release by @samtalki in https://github.com/eigenergy/powerio/pull/81
- ci: pin crates-io-auth-action to v1.0.4 for Node 24 by @samtalki in https://github.com/eigenergy/powerio/pull/83
- feat(gridfm): read a gridfm Parquet dataset back into a Network (#60) by @cameronkhanpour in https://github.com/eigenergy/powerio/pull/70
- feat: in-memory convert_str through the hub, Python bindings, and the MCP server by @samtalki in https://github.com/eigenergy/powerio/pull/88
- feat: upstream the full PowerMCP tool surface into powerio.mcp.server by @samtalki in https://github.com/eigenergy/powerio/pull/90
- docs + release prep: landing page, 0.1.0 version bump, gridfm tarballs, README trim by @samtalki in https://github.com/eigenergy/powerio/pull/92
Full Changelog: https://github.com/eigenergy/powerio/compare/v0.0.1...v0.1.0
Energy Systems - Energy Data Accessibility and Integration
- Rust
Published by github-actions[bot] 2 months ago