mambo_power.io.pandapower_json¶
pandapower JSON (pp.to_json / pp.from_json) importer and exporter: load / loads /
load_with_report read a pandapowerNet document into a Network; dumps / dump /
dumps_with_report write one that loads in pp.from_json and on which pandapower's own
rundcpp / runpp agree with pf.solve_dc / pf.solve_ac. pandapower is imported lazily.
See File formats › pandapower JSON for the table map,
unit conversions, the ext_grid rule, report codes and limitations.
mambo_power.io.pandapower_json
¶
pandapower JSON (pp.to_json / pp.from_json) importer and exporter (wave M8, W1/W2).
pandapower is imported lazily inside the functions that need it, so mambo_power itself
keeps its zero-optional-dependency import (R9). Every conversion is best effort + report
(design item D1): anything the other side cannot hold is dropped or repaired and named in
the returned ImportReport /
ExportReport with the element id and the field. An empty
report means the conversion was lossless. Nothing is logged or printed.
Tables read on import: bus, ext_grid, gen, sgen, load, shunt, line,
trafo, poly_cost, pwl_cost. Results tables (res_*) are neither read nor written
(the wave's "Not doing"; M8 critic finding 10): a bus's stored vm_pu/va_deg does not
travel through this format except for the slack, whose state is the ext_grid setpoint; the
export names every other bus that had one (FIELD_DROPPED). Every other non-empty table
(trafo3w, switch, impedance, ward, xward, dcline, storage, ...) is
dropped row by row with ELEMENT_DROPPED.
Unit conventions (measured on pandapower 3.3.0 against fixtures/matpower/case14.m,
record/m8-research.md §1; Zb = vn_kv(from)² / sn_mva):
- line:
r = r_ohm_per_km · length / parallel / Zb(same forx);b = 2π·f_hz · c_nf_per_km·1e-9 · length · parallel · Zb;rating_mva = max_i_ka · df · parallel · √3 · vn_kv(from); - trafo:
z = vk_percent/100 · sn_mva/sn_trafo · (vn_lv_kv/vn(lv bus))² / parallel,rfromvkr_percentthe same way,x = √(z² − r²);tap_ratio = (vn_hv_kv/vn(hv bus)) / (vn_lv_kv/vn(lv bus))after the tap changer has scaled the tapped winding (1 + (tap_pos − tap_neutral)·tap_step_percent/100for aRatiotap; pandapower 3.3's full rule,tap_changer_typeNone= no tap, is in_Importer.tap_changer);from_bus = hv_bus(mambo's tap side),shift_deg = shift_degreeplus what the changer adds; - shunt: pandapower's
p_mw/q_mvarare consumption, mambo'sb_mvaris injection:b_mvar = −q_mvar · step · (vn(bus)/vn_kv)²,g_mw = p_mw · step · (vn(bus)/vn_kv)²; - costs:
poly_costcp2/cp1/cp0↔PolynomialCost.coefficients == [c2, c1, c0];pwl_cost.points == [[p0, p1, slope], ...]↔PiecewiseCostbreakpoints with the cost atp0taken as 0 (pandapower has no offset column).
Bus roles: the first in-service ext_grid is the slack (mambo needs exactly one); any other
ext_grid becomes a PV generator (EXTRA_EXT_GRID_DEMOTED); with no in-service ext_grid
the first in-service gen with slack = True is the slack (GEN_SLACK_PROMOTED); a bus
with an in-service gen is pv; everything else pq. A file with neither leaves the
network without a slack, which Network refuses (NO_SLACK). On export the rule runs
backwards: the first in-service generator of the slack bus becomes ext_grid, PV-bus
generators gen, PQ-bus generators sgen. Ids: import takes name when it is present,
else <table>-<index>; export writes
the id into name. Bus.area travels as an extra bus.area column (pandapower keeps
unknown columns through to_json, measured).
CODES
module-attribute
¶
CODES: tuple[str, ...] = (
"EXTRA_EXT_GRID_DEMOTED",
"COLUMN_DROPPED",
"ELEMENT_DROPPED",
"FIELD_DEFAULTED",
"ISLAND_DEACTIVATED",
"TAP_CHANGER_TYPE_UNSUPPORTED",
"GEN_SLACK_PROMOTED",
"FIELD_DROPPED",
"COST_DROPPED",
"BID_DROPPED",
)
Every report code this module emits (import: the first seven; export: the last three plus
ELEMENT_DROPPED for storage and FIELD_DEFAULTED for an unrated transformer's
sn_mva). Registered in mambo_power.io.limitations.LIMITATIONS.
DEFAULT_F_HZ
module-attribute
¶
net.f_hz written by the exporter unless given; it only enters the b ↔ c_nf_per_km
conversion and the importer inverts it with the file's own f_hz.
load_with_report
¶
load_with_report(
source: str | PathLike[str],
) -> tuple[Network, ImportReport]
Read the file at source and return (network, report).
loads_with_report
¶
loads_with_report(
text: str,
) -> tuple[Network, ImportReport]
Read pandapower JSON text and return (network, report); see the module docstring.
Source code in src/mambo_power/io/pandapower_json.py
dumps
¶
dumps(net: Network, *, f_hz: float = DEFAULT_F_HZ) -> str
dump
¶
dump(
net: Network,
target: str | PathLike[str],
*,
f_hz: float = DEFAULT_F_HZ,
) -> None
Write pandapower JSON for net to target; the report is discarded.
Source code in src/mambo_power/io/pandapower_json.py
dumps_with_report
¶
dumps_with_report(
net: Network, *, f_hz: float = DEFAULT_F_HZ
) -> tuple[str, ExportReport]
pandapower JSON text for net and the ExportReport of what was dropped.