Electrical Diagrams - statnett/Talk2PowerSystem GitHub Wiki
Table of Contents
Intro
We use PowSyBl Diagram (docs) to generate two kinds of electrical diagrams:

- Network-area diagrams (NAD).
- These show voltage levels as nodes, and the lines and transformers between voltage levels as edges
- Can display the whole grid, one or several voltage levels, and the neighborhood of one or several voltage levels up to a given depth
- Single-line diagrams (SLD).
- These show equipment (switches, disconnectors, busbars, voltage levels, power transformers, loads, generators), adjacent lines, voltages and input/output flows
- Can display one or several substations, voltage levels or areas
- If several substations are requested, the user needs to provide a 2D array of their MRIDs and they are laid out in a matrix exactly like the 2D array
Section Example Diagrams shows the 4 types of diagram that we have generated (2 NAD and 2 SLD).
Other kinds of electrical diagrams can be found in:
- Dataset Telemark 120#diagrams in this wiki, and CIM4NoUtility/Telemark-120/diagrams/svg in the respective github repo: at least 5 kinds of diagrams, some of them instantiated for about 10 substations
- Nordic44/Grid/svg: 3 kinds of CimDesk substation diagrams,
Diagrammable PSRs
Let's count Nordic44+Telemark120 Power System Resources (PSR) that can be diagrammed by PowSyBl. TODO: amend the page Areas and Zones
PREFIX nc: <https://cim4.eu/ns/nc#>
PREFIX cim: <https://cim.ucaiug.io/ns#>
select ?type (count(*) as ?c) {
values ?type {
cim:Substation cim:VoltageLevel
cim:ConformLoad cim:NonConformLoad cim:ConformLoadGroup cim:NonConformLoadGroup
cim:GeographicalRegion cim:SubGeographicalRegion
cim:ControlArea nc:SchedulingArea nc:BiddingZone
cim:LoadArea cim:SubLoadArea
}
?x a ?type
} group by ?type order by ?type
| ?type | ?c |
|---|---|
| cim:ConformLoad | 50 |
| cim:ConformLoadGroup | 37 |
| cim:ControlArea | 5 |
| cim:GeographicalRegion | 1 |
| cim:LoadArea | 5 |
| cim:NonConformLoad | 13 |
| cim:NonConformLoadGroup | 13 |
| cim:SubGeographicalRegion | 11 |
| cim:SubLoadArea | 12 |
| cim:Substation | 55 |
| cim:VoltageLevel | 60 |
| nc:BiddingZone | 45 |
| nc:SchedulingArea | 11 |
Note: PowSyBl can diagram directly substations and voltage levels. But we can diagram all voltage levels within an area, so we also count different kinds of areas present in our data.
Let's count relations between all these PSRs:
PREFIX onto: <http://www.ontotext.com/>
PREFIX nc: <https://cim4.eu/ns/nc#>
PREFIX cim: <https://cim.ucaiug.io/ns#>
select ?type1 ?p ?type2 (count(*) as ?c)
from onto:explicit {
values ?type1 {
cim:Substation cim:VoltageLevel
cim:ConformLoad cim:NonConformLoad cim:ConformLoadGroup cim:NonConformLoadGroup
cim:GeographicalRegion cim:SubGeographicalRegion
cim:ControlArea nc:SchedulingArea nc:BiddingZone
cim:LoadArea cim:SubLoadArea
}
values ?type2 {
cim:Substation cim:VoltageLevel
cim:ConformLoad cim:NonConformLoad cim:ConformLoadGroup cim:NonConformLoadGroup
cim:GeographicalRegion cim:SubGeographicalRegion
cim:ControlArea nc:SchedulingArea nc:BiddingZone
cim:LoadArea cim:SubLoadArea
}
?x a ?type1.
?x ?p ?y.
?y a ?type2.
} group by ?type1 ?p ?type2 order by ?type1 ?p ?type2
| ?type1 | ?p | ?type2 | ?c |
|---|---|---|---|
| cim:ConformLoad | cim:ConformLoad.LoadGroup | cim:ConformLoadGroup | 50 |
| cim:ConformLoad | cim:Equipment.EquipmentContainer | cim:VoltageLevel | 50 |
| cim:ConformLoadGroup | cim:LoadGroup.SubLoadArea | cim:SubLoadArea | 37 |
| cim:ControlArea | cim:ControlArea.EnergyArea | cim:LoadArea | 4 |
| cim:NonConformLoad | cim:Equipment.EquipmentContainer | cim:VoltageLevel | 13 |
| cim:NonConformLoad | cim:NonConformLoad.LoadGroup | cim:NonConformLoadGroup | 13 |
| cim:NonConformLoadGroup | cim:LoadGroup.SubLoadArea | cim:SubLoadArea | 13 |
| cim:SubGeographicalRegion | cim:SubGeographicalRegion.Region | cim:GeographicalRegion | 11 |
| cim:SubLoadArea | cim:SubLoadArea.LoadArea | cim:LoadArea | 12 |
| cim:Substation | cim:Substation.Region | cim:SubGeographicalRegion | 55 |
| cim:VoltageLevel | cim:VoltageLevel.Substation | cim:Substation | 60 |
| nc:SchedulingArea | nc:SchedulingArea.BiddingZone | nc:BiddingZone | 11 |
| nc:SchedulingArea | nc:SchedulingArea.ControlArea | cim:ControlArea | 11 |
Let's show this as a diagram:

Connectivity:
cim:GeographicalRegion, cim:SubGeographicalRegionare related tocim:VoltageLevelthroughcim:Substationcim:LoadArea, cim:SubLoadAreaare related tocim:VoltageLevelthroughConformLoadorNonConformLoadandLoadGroup, namely this property path (we have checked that eachVoltageLevelrelates to only oneSubLoadArea):
?voltageLevel cim:EquipmentContainer.Equipments/(cim:ConformLoad.LoadGroup|cim:NonConformLoad.LoadGroup)/cim:LoadGroup.SubLoadArea ?subLoadArea
Generate Diagram Metadata
We write a number of CONSTRUCT queries to make RDF that describes diagram instances. These queries select appropriate PSRs for PowSyBl diagramming:
| Query | cimr:DiagramKind.PowSyBl- | PSRs |
|---|---|---|
| PowSyBl-SLD-substation.rq | SingleLineDiagram | Substation |
| PowSyBl-SLD-2substations.rq | SingleLineDiagram-Multi | Substation pairs connected through a Line or directly (that's a Nordic44 modeling shortcut) |
| PowSyBl-NAD-all.rq | NetworkAreaDiagram | Full NAD of all voltage levels |
| PowSyBl-NAD-SubGeographicalRegion.rq | NetworkAreaDiagram | NAD of voltage levels in a SubGeographicalRegion |
| PowSyBl-NAD-LoadArea.rq | NetworkAreaDiagram | NAD of voltage levels in a LoadArea |
| PowSyBl-NAD-SubLoadArea.rq | NetworkAreaDiagram | NAD of voltage levels in a SubLoadArea |
The metadata uses cimr:Diagram terms as described at page Diagrams,
and as defined in cimr-diagrams.ttl.
The query 2substations is most complicated because it picks pairs of substations and
It looks like this:
PREFIX cimd: <https://cim.ucaiug.io/diagrams#>
PREFIX cimr: <https://cim.ucaiug.io/rules#>
PREFIX cim: <https://cim.ucaiug.io/ns#>
PREFIX afn: <http://jena.apache.org/ARQ/function#>
PREFIX dct: <http://purl.org/dc/terms/>
prefix geo: <http://www.opengis.net/ont/geosparql#>
construct {
?diag a cimd:Diagram; cimd:Diagram.kind cimd:DiagramKind.PowSyBl-SingleLineDiagram-Multi;
cim:IdentifiedObject.name ?diagName; cim:IdentifiedObject.mRID ?diagMrid; cim:IdentifiedObject.description ?diagDescr;
cimd:Diagram.PowerSystemResource ?psr1,?psr2; cimd:Diagram.mRIDs ?mrids; cimd:Diagram.link ?link; dct:format "image/svg+xml"
}
where {
{select distinct ?psr1 ?psr2 ?psr1Name ?psr2Name ?psr1Mrid ?psr2Mrid ?x1 ?x2 {
?psr1 a cim:Substation; cim:IdentifiedObject.name ?psr1Name; cim:IdentifiedObject.mRID ?psr1Mrid.
?psr2 a cim:Substation; cim:IdentifiedObject.name ?psr2Name; cim:IdentifiedObject.mRID ?psr2Mrid.
{?psr1 cimr:connectedThroughPart ?psr2}
union {?psr1 cimr:connectedThroughPart ?line. ?line a cim:Line. ?psr2 cimr:connectedThroughPart ?line}
filter(?psr1Name < ?psr2Name)
optional {
?psr1 geo:hasGeometry/geo:asWKT ?geo1.
?psr2 geo:hasGeometry/geo:asWKT ?geo2
bind(xsd:decimal(replace(str(?geo1),".*POINT *[(]([0-9.]+) ([0-9.]+)[)]","$1","i")) as ?x1)
bind(xsd:decimal(replace(str(?geo2),".*POINT *[(]([0-9.]+) ([0-9.]+)[)]","$1","i")) as ?x2)
}
}}
bind(coalesce(?x1 > ?x2, false) as ?swap)
bind(replace(?psr1Name," ","-") as ?psr1Slug)
bind(replace(?psr2Name," ","-") as ?psr2Slug)
bind(uuid() as ?diag)
bind(afn:localname(?diag) as ?diagMrid)
bind(concat("Diagram of substations ",
if(?swap,?psr2Name,?psr1Name)," and ",if(?swap,?psr1Name,?psr2Name)) as ?diagName)
bind(concat("PowSyBl Single-Line-Diagram of substations ",
if(?swap,?psr2Name,?psr1Name)," and ",if(?swap,?psr1Name,?psr2Name)) as ?diagDescr)
bind(concat('["',if(?swap,?psr2Mrid,?psr1Mrid),'","',if(?swap,?psr1Mrid,?psr2Mrid),'"](/statnett/Talk2PowerSystem/wiki/"',if(?swap,?psr2Mrid,?psr1Mrid),'","',if(?swap,?psr1Mrid,?psr2Mrid),'")') as ?mrids)
bind(concat("PowSyBl-SLD-2substations-",
if(?swap,?psr2Slug,?psr1Slug),"-and-",if(?swap,?psr1Slug,?psr2Slug),".svg") as ?link)
}
Notes:
- The triple patterns are in a subquery before invoking
uuid()to work around the bug uuid() sometimes yields same result over different query solutions. - We select pairs of substations that are connected:
- Either directly through some of their parts (this is a modeling shortcut in Nordic44)
- Or through a shared
Line
- We eliminate pair permutations by a filter
?psr1Name < ?psr2Name - However, we want to order each pair by Longitude (the more western substation first, the more eastern substaion second).
This is
- So we fetch the
geo:asWKT(GeoSPARQL WKT) geometries of both substations - Extract the
x1, x2coordinates through regexreplace()because GraphDB doesn't have the GeoSPARQL 1.1 functionsgeof:minX, maxX - Compute a flag
?swap: whether the order of the two substations (which is alphabetical) needs to be swapped
- So we fetch the
- Then we transform each
NametoSlugby converting spaces to dashes - Generate a new URN for the Diagram object:
bind(uuid() as ?diag) - Fetch only the UUID part of the URN as
?diagMrid - Form several strings (
name, descr, mrids, link) by using a pattern likeconcat(if(?swap...))to account for the order of the two substationsmridsis a list of mRIDs of the PSRs to show on the diagram, as needs to be passed to PowSyBl. See next section for details.
It produces metadata like this:
<urn:uuid:2a665063-e775-404f-80a2-ecd0a3774b8d> a cimd:Diagram;
cimd:Diagram.kind cimd:DiagramKind.PowSyBl-SingleLineDiagram-Multi;
cim:IdentifiedObject.name "Diagram of substations NEDENES and TELEMA2 04 CB6";
cim:IdentifiedObject.mRID "2a665063-e775-404f-80a2-ecd0a3774b8d";
cim:IdentifiedObject.description "PowSyBl Single-Line-Diagram of substations NEDENES and TELEMA2 04 CB6";
cimd:Diagram.PowerSystemResource <urn:uuid:681a2179-5a55-11eb-a658-74e5f963e191>,
<urn:uuid:811613d5-c44f-4daa-9dc1-03005740a4e5>;
cimd:Diagram.mRIDs "[\"681a2179-5a55-11eb-a658-74e5f963e191\",\"811613d5-c44f-4daa-9dc1-03005740a4e5\"](/statnett/Talk2PowerSystem/wiki/\"681a2179-5a55-11eb-a658-74e5f963e191\",\"811613d5-c44f-4daa-9dc1-03005740a4e5\")";
cimd:Diagram.link "PowSyBl-SLD-2substations-NEDENES-and-TELEMA2-04-CB6.svg";
dct:format "image/svg+xml" .
The metadata for all diagrams is concatenated as diagrams.ttl.
Generate Diagrams
This query SELECTS a table of parameters to drive PowSyBl diagram generation:
select ?kind ?mrids ?link {
?x a cimr:Diagram;
cimr:Diagram.kind ?kindUrl;
cimr:Diagram.mRIDs ?mrids;
cimr:Diagram.link ?link.
bind(strafter(str(?kindUrl),"PowSyBl-") as ?kind)
}
It can be run in two ways:
- On
diagrams.ttlusing Jena ARQ (currently we use this way) - Or the turtle file can be loaded in GraphDB first, then the query can be run using
curl
The result is saved as diagrams.tsv and looks like this.
mrids is a string representation of the Python parameter that needs to be passed to PowSyBl
| ?kind | ?mrids | ?link | What is mrids |
|---|---|---|---|
| "SingleLineDiagram" | ""f17696b8-9aeb-11e5-91da-b8763fd99c5f"" | "PowSyBl-SLD-substation-VYBORG_HVDC.svg" | single substation |
| "SingleLineDiagram-Multi" | ""f17695fe-9aeb-11e5-91da-b8763fd99c5f",..." | "PowSyBl-SLD-2substations-AJAURE-and-GRUNDFORS.svg" | 2D vector consisting of a single row of 2 substations |
| "NetworkAreaDiagram" | "PowSyBl-NAD-all.svg" | none | |
| "NetworkAreaDiagram" | "("d82114b7-09c0-4cb4-b9c8-19a5fdaf991a",...)" | "PowSyBl-NAD-SubGeographicalRegion-DSO-V.svg" | array of VoltageLevels in that SubGeographicalRegion |
| "NetworkAreaDiagram" | "("d82114b7-09c0-4cb4-b9c8-19a5fdaf991a",...)" | "PowSyBl-NAD-SubLoadArea-FI-SLA.svg" | array of VoltageLevels in that SubLoadArea |
| "NetworkAreaDiagram" | "("d82114b7-09c0-4cb4-b9c8-19a5fdaf991a",...)" | "PowSyBl-NAD-LoadArea-FI-LA.svg" | array of VoltageLevels in that LoadArea |
IMPORTANT: I hoped that TSV export will omit all the ugly quoting but unfortunately that's not the case.
So we need to use proper TSV parsing to ensure that mrids pases through ok.
Running Python
We use the Python version of PowSyBl (which is on par with the Java version).
The Python script TODO:
- Loads a zip of Nordic44 and Telemark120 Grid data to PowSyBl
- Loads the above TSV and iterates over each row
- Saves each genrated diagram to folder
tsvusing the filename provided inlink
Example Diagrams
This section gives an example of each of the generated diagrams:
Single-Line-Diagram of Substation
Arendal:

Single-Line-Diagram of Two Substations
Kristiansand and Arendal:

Network Area Diagram
All voltage levels in Nordic44 (Telemark120 is not shown, but is present in PowSyBl-NAD-all.svg).

Network Area Diagram of SubGeographicalArea
TODO