Skip to content

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 07 Aug 13:00
· 34 commits to main since this release
e99e174

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.json files 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 $schema URI should update their accepted list.

Details

  • .pio.json carries one version number. schema_version (now 0.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. The schema,
    payload_schema, and payload_schema_version fields and the
    PIO_PACKAGE_SCHEMA_URL / PIO_PAYLOAD_* constants are gone; the payload
    schema documents under docs/schema/pio-payload-* are no longer published
    (the pio-package/0.2 document 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_ub and linecode cm_ub/sm_ub no 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 skips emergamps with a warning when the first
      i_max entry 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_str no longer route arbitrary JSON to the BMOPF
      reader: a .json without the PMD data_model marker, and without a
      BMOPF bus table 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 no voltage_source still classifies, because the
      reader accepts it. An explicit format override still forces the reader.
  • BMOPF schema 0.1.0 (bmopf-report#16). The writer targets the published
    schema $id and the reader keeps accepting the pre-0.1.0 spellings:
    • meta carries case_study_generator (was generator) and the system
      frequency; the reader also still accepts the legacy top-level
      frequency/base_frequency.
    • Load model strings 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_max arrays map on read assuming zero/positive/negative
      order. DistBus renames the fields, part of the .pio.json 0.2.0 bump
      above.
    • Three phase transformers emit one lumped r_series/x_series pair on
      the wye base, with each winding's percent resistance referred to its own
      rating before the sum; the split _from/_to fields 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 under extras
      the same way. The reader folds all of them back.
    • A typed capacitor element (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 carry i_max/s_max. The line
      ratings map to the ENGINEERING line's own cm_ub/sm_ub (both
      directions; an inline line's ratings stay on the synthesized linecode),
      and the dss writer warns when it drops them (the normamps/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_max and linecode source are typed fields, read
      and written; the dss and PMD writers warn when they drop them.
    • The meta provenance 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_examples regenerates
      the checked-in example outputs.
  • Python: Network.write_file(path, to) / DistNetwork.write_file(path, to)
    and a convert_file(..., out=...) output path write the serialized case to
    disk exactly as produced. Writing to_format text through
    open(path, "w") corrupts a CRLF source echo on Windows (text mode turns
    each \r\n into \r\r\n, which PSS/E family tools reject as malformed
    records); the new paths bypass Python's newline translation.
    DistNetwork.write_file also writes any sidecar the writer produced beside
    the case, so a dss write that emits a Buscoords directive no longer names
    a file that does not exist.

What's Changed

Full Changelog: v0.7.3...v0.8.0