powerio.dist
Multiconductor distribution network values.
The typed model uses wire coordinates. Supported formats are OpenDSS .dss,
PowerModelsDistribution ENGINEERING JSON (pmd-json), and BMOPF JSON
(bmopf-json). Same format emissions can return retained source bytes. Cross
format emissions report unsupported fields as diagnostics.
import powerio
module = powerio.parse("feeder.dss")
net = module.value
for diagnostic in module.diagnostics:
print("parse:", diagnostic)
conv = powerio.emit(module, "pmd-json")
1"""Multiconductor distribution network values. 2 3The typed model uses wire coordinates. Supported formats are OpenDSS ``.dss``, 4PowerModelsDistribution ENGINEERING JSON (``pmd-json``), and BMOPF JSON 5(``bmopf-json``). Same format emissions can return retained source bytes. Cross 6format emissions report unsupported fields as diagnostics. 7 8 import powerio 9 10 module = powerio.parse("feeder.dss") 11 net = module.value 12 for diagnostic in module.diagnostics: 13 print("parse:", diagnostic) 14 conv = powerio.emit(module, "pmd-json") 15""" 16 17from __future__ import annotations 18 19import json as _json 20from typing import Any, Optional 21 22from ._guard import guard_class as _guard_class 23 24__all__ = ["MulticonductorNetwork"] 25 26 27@_guard_class 28class MulticonductorNetwork: 29 """A parsed multiconductor distribution network in wire coordinates. 30 31 Buses carry named terminals, lines carry conductor impedance matrices, and 32 transformers carry per winding connections. This type is distinct from the 33 positive sequence :class:`powerio.BalancedNetwork`; balanced matrix calculations do not 34 accept it. 35 """ 36 37 def __init__(self, inner) -> None: 38 self._inner = inner 39 40 @property 41 def name(self) -> Optional[str]: 42 """Distribution network name when the source format carries one.""" 43 return self._inner.name() 44 45 @property 46 def source_format(self) -> Optional[str]: 47 """Format parsed from: ``dss``, ``pmd-json``, or ``bmopf-json``.""" 48 return self._inner.source_format() 49 50 @property 51 def base_frequency(self) -> float: 52 """System base frequency in hertz.""" 53 return self._inner.base_frequency() 54 55 @property 56 def n_buses(self) -> int: 57 return self._inner.n_buses() 58 59 @property 60 def n_lines(self) -> int: 61 return self._inner.n_lines() 62 63 @property 64 def n_line_codes(self) -> int: 65 return self._inner.n_line_codes() 66 67 @property 68 def n_switches(self) -> int: 69 return self._inner.n_switches() 70 71 @property 72 def n_transformers(self) -> int: 73 return self._inner.n_transformers() 74 75 @property 76 def n_loads(self) -> int: 77 return self._inner.n_loads() 78 79 @property 80 def n_generators(self) -> int: 81 return self._inner.n_generators() 82 83 @property 84 def n_ibrs(self) -> int: 85 return self._inner.n_ibrs() 86 87 @property 88 def n_control_profiles(self) -> int: 89 return self._inner.n_control_profiles() 90 91 @property 92 def n_shunts(self) -> int: 93 return self._inner.n_shunts() 94 95 @property 96 def n_capacitors(self) -> int: 97 return self._inner.n_capacitors() 98 99 @property 100 def n_voltage_sources(self) -> int: 101 """Number of grid forming voltage sources.""" 102 return self._inner.n_voltage_sources() 103 104 @property 105 def n_untyped_objects(self) -> int: 106 return self._inner.n_untyped_objects() 107 108 # These properties are copies of the native model tables. Nested field 109 # names come from the Rust model's serialization, so this wrapper does not 110 # maintain a second distribution schema. 111 112 @property 113 def buses(self) -> "list[dict[str, Any]]": 114 return self._inner.buses() 115 116 @property 117 def line_codes(self) -> "list[dict[str, Any]]": 118 return self._inner.line_codes() 119 120 @property 121 def lines(self) -> "list[dict[str, Any]]": 122 return self._inner.lines() 123 124 @property 125 def switches(self) -> "list[dict[str, Any]]": 126 return self._inner.switches() 127 128 @property 129 def transformers(self) -> "list[dict[str, Any]]": 130 return self._inner.transformers() 131 132 @property 133 def loads(self) -> "list[dict[str, Any]]": 134 return self._inner.loads() 135 136 @property 137 def generators(self) -> "list[dict[str, Any]]": 138 return self._inner.generators() 139 140 @property 141 def ibrs(self) -> "list[dict[str, Any]]": 142 return self._inner.ibrs() 143 144 @property 145 def control_profiles(self) -> "list[dict[str, Any]]": 146 return self._inner.control_profiles() 147 148 @property 149 def shunts(self) -> "list[dict[str, Any]]": 150 return self._inner.shunts() 151 152 @property 153 def capacitors(self) -> "list[dict[str, Any]]": 154 return self._inner.capacitors() 155 156 @property 157 def voltage_sources(self) -> "list[dict[str, Any]]": 158 return self._inner.voltage_sources() 159 160 @property 161 def untyped_objects(self) -> "list[dict[str, Any]]": 162 return self._inner.untyped_objects() 163 164 def to_graph(self) -> Any: 165 """Transform the network to collapsed bus and terminal graph data.""" 166 return _json.loads(self._inner.graph_json()) 167 168 def to_geo_layer(self) -> Any: 169 """Transform coordinates to a canonical GeoJSON FeatureCollection. 170 171 A network without coordinates produces an empty feature collection. 172 """ 173 return _json.loads(self._inner.to_geo_layer_json()) 174 175 def apply_geo_layer( 176 self, text: str, name_hint: Optional[str] = None 177 ) -> tuple["MulticonductorNetwork", Any]: 178 """Apply a geographic sidecar and return ``(placed, report)``. 179 180 ``text`` is any form :func:`powerio.parse_geo` accepts. This network 181 is unchanged; the placed copy drops the retained source text, so a 182 same-format emission re-serializes. 183 """ 184 inner, report = self._inner.apply_geo_layer(text, name_hint) 185 return MulticonductorNetwork(inner), report 186 187 def __repr__(self) -> str: 188 return self._inner.__repr__()
28@_guard_class 29class MulticonductorNetwork: 30 """A parsed multiconductor distribution network in wire coordinates. 31 32 Buses carry named terminals, lines carry conductor impedance matrices, and 33 transformers carry per winding connections. This type is distinct from the 34 positive sequence :class:`powerio.BalancedNetwork`; balanced matrix calculations do not 35 accept it. 36 """ 37 38 def __init__(self, inner) -> None: 39 self._inner = inner 40 41 @property 42 def name(self) -> Optional[str]: 43 """Distribution network name when the source format carries one.""" 44 return self._inner.name() 45 46 @property 47 def source_format(self) -> Optional[str]: 48 """Format parsed from: ``dss``, ``pmd-json``, or ``bmopf-json``.""" 49 return self._inner.source_format() 50 51 @property 52 def base_frequency(self) -> float: 53 """System base frequency in hertz.""" 54 return self._inner.base_frequency() 55 56 @property 57 def n_buses(self) -> int: 58 return self._inner.n_buses() 59 60 @property 61 def n_lines(self) -> int: 62 return self._inner.n_lines() 63 64 @property 65 def n_line_codes(self) -> int: 66 return self._inner.n_line_codes() 67 68 @property 69 def n_switches(self) -> int: 70 return self._inner.n_switches() 71 72 @property 73 def n_transformers(self) -> int: 74 return self._inner.n_transformers() 75 76 @property 77 def n_loads(self) -> int: 78 return self._inner.n_loads() 79 80 @property 81 def n_generators(self) -> int: 82 return self._inner.n_generators() 83 84 @property 85 def n_ibrs(self) -> int: 86 return self._inner.n_ibrs() 87 88 @property 89 def n_control_profiles(self) -> int: 90 return self._inner.n_control_profiles() 91 92 @property 93 def n_shunts(self) -> int: 94 return self._inner.n_shunts() 95 96 @property 97 def n_capacitors(self) -> int: 98 return self._inner.n_capacitors() 99 100 @property 101 def n_voltage_sources(self) -> int: 102 """Number of grid forming voltage sources.""" 103 return self._inner.n_voltage_sources() 104 105 @property 106 def n_untyped_objects(self) -> int: 107 return self._inner.n_untyped_objects() 108 109 # These properties are copies of the native model tables. Nested field 110 # names come from the Rust model's serialization, so this wrapper does not 111 # maintain a second distribution schema. 112 113 @property 114 def buses(self) -> "list[dict[str, Any]]": 115 return self._inner.buses() 116 117 @property 118 def line_codes(self) -> "list[dict[str, Any]]": 119 return self._inner.line_codes() 120 121 @property 122 def lines(self) -> "list[dict[str, Any]]": 123 return self._inner.lines() 124 125 @property 126 def switches(self) -> "list[dict[str, Any]]": 127 return self._inner.switches() 128 129 @property 130 def transformers(self) -> "list[dict[str, Any]]": 131 return self._inner.transformers() 132 133 @property 134 def loads(self) -> "list[dict[str, Any]]": 135 return self._inner.loads() 136 137 @property 138 def generators(self) -> "list[dict[str, Any]]": 139 return self._inner.generators() 140 141 @property 142 def ibrs(self) -> "list[dict[str, Any]]": 143 return self._inner.ibrs() 144 145 @property 146 def control_profiles(self) -> "list[dict[str, Any]]": 147 return self._inner.control_profiles() 148 149 @property 150 def shunts(self) -> "list[dict[str, Any]]": 151 return self._inner.shunts() 152 153 @property 154 def capacitors(self) -> "list[dict[str, Any]]": 155 return self._inner.capacitors() 156 157 @property 158 def voltage_sources(self) -> "list[dict[str, Any]]": 159 return self._inner.voltage_sources() 160 161 @property 162 def untyped_objects(self) -> "list[dict[str, Any]]": 163 return self._inner.untyped_objects() 164 165 def to_graph(self) -> Any: 166 """Transform the network to collapsed bus and terminal graph data.""" 167 return _json.loads(self._inner.graph_json()) 168 169 def to_geo_layer(self) -> Any: 170 """Transform coordinates to a canonical GeoJSON FeatureCollection. 171 172 A network without coordinates produces an empty feature collection. 173 """ 174 return _json.loads(self._inner.to_geo_layer_json()) 175 176 def apply_geo_layer( 177 self, text: str, name_hint: Optional[str] = None 178 ) -> tuple["MulticonductorNetwork", Any]: 179 """Apply a geographic sidecar and return ``(placed, report)``. 180 181 ``text`` is any form :func:`powerio.parse_geo` accepts. This network 182 is unchanged; the placed copy drops the retained source text, so a 183 same-format emission re-serializes. 184 """ 185 inner, report = self._inner.apply_geo_layer(text, name_hint) 186 return MulticonductorNetwork(inner), report 187 188 def __repr__(self) -> str: 189 return self._inner.__repr__()
A parsed multiconductor distribution network in wire coordinates.
Buses carry named terminals, lines carry conductor impedance matrices, and
transformers carry per winding connections. This type is distinct from the
positive sequence powerio.BalancedNetwork; balanced matrix calculations do not
accept it.
41 @property 42 def name(self) -> Optional[str]: 43 """Distribution network name when the source format carries one.""" 44 return self._inner.name()
Distribution network name when the source format carries one.
46 @property 47 def source_format(self) -> Optional[str]: 48 """Format parsed from: ``dss``, ``pmd-json``, or ``bmopf-json``.""" 49 return self._inner.source_format()
Format parsed from: dss, pmd-json, or bmopf-json.
51 @property 52 def base_frequency(self) -> float: 53 """System base frequency in hertz.""" 54 return self._inner.base_frequency()
System base frequency in hertz.
100 @property 101 def n_voltage_sources(self) -> int: 102 """Number of grid forming voltage sources.""" 103 return self._inner.n_voltage_sources()
Number of grid forming voltage sources.
165 def to_graph(self) -> Any: 166 """Transform the network to collapsed bus and terminal graph data.""" 167 return _json.loads(self._inner.graph_json())
Transform the network to collapsed bus and terminal graph data.
169 def to_geo_layer(self) -> Any: 170 """Transform coordinates to a canonical GeoJSON FeatureCollection. 171 172 A network without coordinates produces an empty feature collection. 173 """ 174 return _json.loads(self._inner.to_geo_layer_json())
Transform coordinates to a canonical GeoJSON FeatureCollection.
A network without coordinates produces an empty feature collection.
176 def apply_geo_layer( 177 self, text: str, name_hint: Optional[str] = None 178 ) -> tuple["MulticonductorNetwork", Any]: 179 """Apply a geographic sidecar and return ``(placed, report)``. 180 181 ``text`` is any form :func:`powerio.parse_geo` accepts. This network 182 is unchanged; the placed copy drops the retained source text, so a 183 same-format emission re-serializes. 184 """ 185 inner, report = self._inner.apply_geo_layer(text, name_hint) 186 return MulticonductorNetwork(inner), report
Apply a geographic sidecar and return (placed, report).
text is any form powerio.parse_geo() accepts. This network
is unchanged; the placed copy drops the retained source text, so a
same-format emission re-serializes.