SIIP Tutorial

How to interact with data in a PowerSystems.System struct

In this tutorial, we will walk through how to use the PowerSystems.System struct.

Loading a system

Let's start first by loading the same system we did in the previous tutorial.

using PowerSystems
using PowerSystemCaseBuilder

system = build_system(PSITestSystems, "modified_RTS_GMLC_DA_sys");

We have already learnt that the system is a PowerSystems.System.

typeof(system) === PowerSystems.System
true
πŸ“ Note Up until now, we have been using PowerSystemCaseBuilder to load a system. However, we can use the parsers in PowerSystems to load other systems as well. Here's an example of loading the 24 bus system from MATPOWER.
System("./data/case5.m")
System
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Property          β”‚ Value       β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ System Units Base β”‚ SYSTEM_BASE β”‚
β”‚ Base Power        β”‚ 100.0       β”‚
β”‚ Base Frequency    β”‚ 60.0        β”‚
β”‚ Num Components    β”‚ 27          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Static Components
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Type            β”‚ Count β”‚ Has Static Time Series β”‚ Has Forecasts β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Arc             β”‚ 6     β”‚ false                  β”‚ false         β”‚
β”‚ Area            β”‚ 1     β”‚ false                  β”‚ false         β”‚
β”‚ Bus             β”‚ 5     β”‚ false                  β”‚ false         β”‚
β”‚ Line            β”‚ 6     β”‚ false                  β”‚ false         β”‚
β”‚ LoadZone        β”‚ 1     β”‚ false                  β”‚ false         β”‚
β”‚ PowerLoad       β”‚ 3     β”‚ false                  β”‚ false         β”‚
β”‚ ThermalStandard β”‚ 5     β”‚ false                  β”‚ false         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

PowerSystems has similar parsing features for PSSE, CSV and other data formats.

In a PowerSystems.System, there may be a bunch of PowerSystems.Component types. PowerSystems.Component is a parent abstract type, and has a number of children. Here is a hierarchical tree of the children of PowerSystems.Component:

include("utils.jl")
D3PowerSystemTypes(PowerSystems.Component)

Hover over the various labels to see the struct definition. The bold types are the leaf concrete types, and are the ones you may be particularly interested in.

getter and setter accessor functions

This System type is a struct, an instance of which can contains all the data that represents a 73 bus test system.

Let's say hypothetically we wanted to get all the buses in this system. Maybe we want to verify that it is indeed a 73 bus test system. We can do that using the get_components function from PowerSystems.

buses = collect(get_components(Bus, system))
73-element Vector{PowerSystems.Bus}:
 Bus(202, Bacon, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.1877810214196211, 1.04844, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(22.0, 5.29, 1.08), Dict{String, Any}())
 Bus(321, Cobb, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.21539492271297458, 1.05, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(37.0, 3.33, 0.68), Dict{String, Any}())
 Bus(322, Cole, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.3153659860038082, 1.05, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(37.0, 3.33, 0.68), Dict{String, Any}())
 Bus(102, Adams, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.1364470483941135, 1.04783, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(12.0, 5.29, 1.08), Dict{String, Any}())
 Bus(117, Aston, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.19956391373276003, 1.04783, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(17.0, 3.33, 0.68), Dict{String, Any}())
 Bus(324, Curie, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.02279504722859714, 1.01046, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(36.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(121, Attlee, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.22840303616101354, 1.05, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(17.0, 3.33, 0.68), Dict{String, Any}())
 Bus(206, Bajer, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.28198796032281825, 1.03259, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(22.0, 5.29, 1.08), Dict{String, Any}())
 Bus(217, Bates, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.15390994022494278, 1.04847, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(27.0, 3.33, 0.68), Dict{String, Any}())
 Bus(103, Adler, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.1258539470320591, 1.01085, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(11.0, 4.33, 0.88), Dict{String, Any}())
 Bus(301, Cabell, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.1631570436678591, 1.0486, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(31.0, 4.33, 0.88), Dict{String, Any}())
 Bus(204, Bailey, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.23535398444000616, 1.0189, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(21.0, 4.33, 0.88), Dict{String, Any}())
 Bus(107, Alder, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.19681606735842017, 1.03745, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(12.0, 5.29, 1.08), Dict{String, Any}())
 Bus(311, Cary, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.10019394183631328, 1.0283, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(33.0, 3.7, 0.76), Dict{String, Any}())
 Bus(110, Allen, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.18536496213608536, 1.05, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(13.0, 3.7, 0.76), Dict{String, Any}())
 Bus(317, Chuhsi, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.18053999941894702, 1.04785, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(37.0, 3.33, 0.68), Dict{String, Any}())
 Bus(215, Barton, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.08087000542408246, 1.04327, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(26.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(323, Comte, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.15046692920953353, 1.05, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(35.0, 3.09, 0.63), Dict{String, Any}())
 Bus(201, Bach, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.18657098464921346, 1.04841, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(21.0, 4.33, 0.88), Dict{String, Any}())
 Bus(303, Caesar, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.14969497008137647, 1.01045, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(31.0, 4.33, 0.88), Dict{String, Any}())
 Bus(307, Carew, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.21900304187562247, 1.03804, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(32.0, 5.29, 1.08), Dict{String, Any}())
 Bus(205, Bain, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.23757194885344055, 1.03603, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(21.0, 4.33, 0.88), Dict{String, Any}())
 Bus(315, Chase, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.12306107116301779, 1.043, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(36.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(222, Bell, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.28679302628648384, 1.05, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(27.0, 3.33, 0.68), Dict{String, Any}())
 Bus(308, Carrel, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.26499107140227146, 1.01056, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(32.0, 5.29, 1.08), Dict{String, Any}())
 Bus(109, Ali, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.15385496235350493, 1.0261, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(13.0, 3.7, 0.76), Dict{String, Any}())
 Bus(310, Caruso, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.2146959183475509, 1.05, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(33.0, 3.7, 0.76), Dict{String, Any}())
 Bus(124, Avery, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.04159800285910765, 1.01155, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(16.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(116, Asser, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.13210903253828157, 1.04565, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(16.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(122, Aubrey, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.33073605352857105, 1.05, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(17.0, 3.33, 0.68), Dict{String, Any}())
 Bus(211, Bardeen, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.12100996022607405, 1.02735, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(23.0, 3.7, 0.76), Dict{String, Any}())
 Bus(316, Chifa, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.11516991401597582, 1.04558, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(36.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(108, Alger, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.23997701256268875, 1.01024, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(12.0, 5.29, 1.08), Dict{String, Any}())
 Bus(223, Bloch, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.125340994764898, 1.05, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(25.0, 3.09, 0.63), Dict{String, Any}())
 Bus(104, Agricola, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.18441393222667365, 1.01765, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(11.0, 4.33, 0.88), Dict{String, Any}())
 Bus(118, Astor, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.21859498389650622, 1.05, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(17.0, 3.33, 0.68), Dict{String, Any}())
 Bus(105, Aiken, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.18690504066804514, 1.03568, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(11.0, 4.33, 0.88), Dict{String, Any}())
 Bus(319, Clay, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.10324303203954738, 1.03953, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(35.0, 3.09, 0.63), Dict{String, Any}())
 Bus(213, Barlow, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.05611408078086969, 1.03752, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(24.0, 2.65, 0.54), Dict{String, Any}())
 Bus(304, Caine, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.21271793670626568, 1.01785, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(31.0, 4.33, 0.88), Dict{String, Any}())
 Bus(224, Bordet, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.01675603348377156, 1.01456, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(26.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(210, Banks, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.23526793970788284, 1.05, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(23.0, 3.7, 0.76), Dict{String, Any}())
 Bus(325, Curtiss, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.15696304468545644, 1.04986, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(35.0, 3.09, 0.63), Dict{String, Any}())
 Bus(216, Basov, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.0820320456400603, 1.04556, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(26.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(209, Balzac, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.204623972300142, 1.02781, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(23.0, 3.7, 0.76), Dict{String, Any}())
 Bus(306, Camus, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.26078796949761873, 1.0326, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(32.0, 5.29, 1.08), Dict{String, Any}())
 Bus(314, Chain, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.0559889406735017, 1.04631, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(36.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(312, Caxton, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.0723620489193857, 1.019, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(33.0, 3.7, 0.76), Dict{String, Any}())
 Bus(106, Alber, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.23176995082103577, 1.03242, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(12.0, 5.29, 1.08), Dict{String, Any}())
 Bus(318, Clark, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.19796606480255924, 1.05, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(37.0, 3.33, 0.68), Dict{String, Any}())
 Bus(119, Attar, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.11620000734050288, 1.03962, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(15.0, 3.09, 0.63), Dict{String, Any}())
 Bus(111, Anna, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.0683600089445627, 1.02764, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(13.0, 3.7, 0.76), Dict{String, Any}())
 Bus(115, Arthur, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.13892297247099264, 1.04335, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(16.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(313, Cecil, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.04215197036369065, 1.03802, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(34.0, 2.65, 0.54), Dict{String, Any}())
 Bus(220, Beethoven, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.09886400094629359, 1.0438, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(25.0, 3.09, 0.63), Dict{String, Any}())
 Bus(123, Austen, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.15805998412033487, 1.05, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(15.0, 3.09, 0.63), Dict{String, Any}())
 Bus(120, Attila, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.13509895607987307, 1.04399, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(15.0, 3.09, 0.63), Dict{String, Any}())
 Bus(101, Abel, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.13511501310899143, 1.04777, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(11.0, 4.33, 0.88), Dict{String, Any}())
 Bus(208, Balch, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.2831550619936269, 1.01203, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(22.0, 5.29, 1.08), Dict{String, Any}())
 Bus(309, Carter, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.18232006072305607, 1.02579, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(33.0, 3.7, 0.76), Dict{String, Any}())
 Bus(320, Clive, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.1256129170623587, 1.04389, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(35.0, 3.09, 0.63), Dict{String, Any}())
 Bus(221, Behring, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.1855649768683639, 1.05, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(27.0, 3.33, 0.68), Dict{String, Any}())
 Bus(305, Calvin, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.2155490352859257, 1.03609, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(31.0, 4.33, 0.88), Dict{String, Any}())
 Bus(302, Cabot, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.1646020017555852, 1.04864, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(32.0, 5.29, 1.08), Dict{String, Any}())
 Bus(218, Bayle, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.17444094634785287, 1.05, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(27.0, 3.33, 0.68), Dict{String, Any}())
 Bus(219, Bede, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.07351902768053274, 1.03946, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(25.0, 3.09, 0.63), Dict{String, Any}())
 Bus(114, Arnold, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.03020396990331307, 1.04401, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(16.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(207, Baker, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.23502708427110763, 1.03973, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(22.0, 5.29, 1.08), Dict{String, Any}())
 Bus(214, Barry, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.08177199158151313, 1.04335, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(26.0, 6.109999999999999, 1.23), Dict{String, Any}())
 Bus(212, Barkla, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.09168807972671891, 1.01921, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(23.0, 3.7, 0.76), Dict{String, Any}())
 Bus(113, Arne, PowerSystems.BusTypesModule.BusTypes.REF = 4, 0.0, 1.03943, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(14.0, 2.65, 0.54), Dict{String, Any}())
 Bus(203, Baffin, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.18281503609892163, 1.01886, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(21.0, 4.33, 0.88), Dict{String, Any}())
 Bus(112, Archer, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.042310969858547334, 1.02024, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(13.0, 3.7, 0.76), Dict{String, Any}())

Now the buses variable contains a Vector of all the Bus components.

typeof(buses)
Vector{Bus} (alias for Array{PowerSystems.Bus, 1})
πŸ“ Note In Julia, some types can be parameterized. In this case, Vector is a abstract type and Vector{Bus} is a concrete parameterized type.
πŸ‹ Exercise What do you think the result of the following will be?
numbers = [1,2,3,4]
typeof(numbers)
What about the following?
numbers = [1.,2,3,4]
typeof(numbers)

We can count the number of buses by getting the length of the Vector{Bus} instance.

length(buses)
73
πŸ’‘ Tip When you are writing code for an analysis, often you will want to assert that your code is doing the right thing. You can do this by using the @assert macro.
@assert length(buses) == 73
This line will silently pass if the assertion returns true and can be a easy way to sanity check your code. Assertions that fail will result in errors.It can also come in handy to write tests to verify that your code is working as expected. Julia has a package as part of the standard library for testing.
using Test
@test length(buses) == 73
Test Passed
  Expression: length(buses) == 73
   Evaluated: 73 == 73
πŸ‹ Exercise How many "areas" are in this test system? Can you find the answer programmatically?
We can use the Area type, the get_components function and the length to get the number of areas.
length(get_components(Area, system))
3
Note that we did not need to call collect to get the length.

Get attributes

A struct in Julia like a dataclass in Python. And these structs can have many fields. This is an example of what the PowerSystems struct looks like:

struct System
    data
    frequency
    bus_numbers
    runchecks
    units_settings
end

You'll notice that frequency is a field on the System struct. This means you can access the system's frequency by using the . operator:

system.frequency
60.0

However, these fields in PowerSystems are considered implementation details, and may change in future versions of the package.

For accessing data, PowerSystems provide a number of accessor functions. Instead of using system.frequency, it is recommended for example to use get_frequency. You'll see that this yields the same answer.

get_frequency(system)
60.0

You can find the full list of these accessor functions in the PowerSystems public API reference.

The function we used earlier, i.e. get_components is one such accessor function. This function takes in two arguments, a PowerSystems.Component type as the first argument and the system as the second argument, and returns a collection of components.

πŸ“ Note For performance and implementation-detail reasons, get_components actually returns a Iterator type.
typeof(get_components(Bus, system))
InfrastructureSystems.FlattenIteratorWrapper{PowerSystems.Bus}
However, you can call the Julia standard library collect to convert the iterator to a Vector{PowerSystem.Bus}.

If you are using a Julia REPL where the PowerSystems package is already loaded, you can type PowerSystems.get_ and hit the <TAB> key twice in quick succession. This should show a list of autocompletion options for the get_ accessor functions.

πŸ‹ Exercise Can you print the names of all the Bus components in the RTS test system? How many unique base voltage levels are there in the RTS test system?
We can get the names using Julia's broadcasting operator.
names = get_name.(get_components(Bus, system))
73-element Vector{String}:
 "Bacon"
 "Cobb"
 "Cole"
 "Adams"
 "Aston"
 "Curie"
 "Attlee"
 "Bajer"
 "Bates"
 "Adler"
 "Cabell"
 "Bailey"
 "Alder"
 "Cary"
 "Allen"
 "Chuhsi"
 "Barton"
 "Comte"
 "Bach"
 "Caesar"
 "Carew"
 "Bain"
 "Chase"
 "Bell"
 "Carrel"
 "Ali"
 "Caruso"
 "Avery"
 "Asser"
 "Aubrey"
 "Bardeen"
 "Chifa"
 "Alger"
 "Bloch"
 "Agricola"
 "Astor"
 "Aiken"
 "Clay"
 "Barlow"
 "Caine"
 "Bordet"
 "Banks"
 "Curtiss"
 "Basov"
 "Balzac"
 "Camus"
 "Chain"
 "Caxton"
 "Alber"
 "Clark"
 "Attar"
 "Anna"
 "Arthur"
 "Cecil"
 "Beethoven"
 "Austen"
 "Attila"
 "Abel"
 "Balch"
 "Carter"
 "Clive"
 "Behring"
 "Calvin"
 "Cabot"
 "Bayle"
 "Bede"
 "Arnold"
 "Baker"
 "Barry"
 "Barkla"
 "Arne"
 "Baffin"
 "Archer"
We can use Julia's unique function for this:
unique(get_base_voltage.(get_components(Bus, system)))
2-element Vector{Float64}:
 138.0
 230.0

Another reason to use get_* accessor functions is that data can be transformed appropriately when using these functions. For example, it is possible to change the base units on the system and have the accessors return the corresponding values.

set_units_base_system!(system, "SYSTEM_BASE")
gen = first(get_components(ThermalStandard, system))
get_active_power_limits(gen)
(min = 0.22, max = 0.55)
set_units_base_system!(system, "NATURAL_UNITS")
gen = first(get_components(ThermalStandard, system))
get_active_power_limits(gen)
(min = 22.0, max = 55.0)

You can think about these accessor functions as the API through which you can interact with the PowerSystems.System struct.

Similar to get_* accessor functions, there are set_* accessor functions

Here is the name of the first ThermalStandard generator.

gen = first(get_components(ThermalStandard, system))
get_name(gen)
"322_CT_6"

Let's say we wanted to change it to include the power rating.

n = get_name(gen)
min_p, max_p = get_active_power_limits(gen)
set_name!(system, gen, "$(n)_$(Int(min_p))_$(Int(max_p))")
get_name(gen)
"322_CT_6_22_55"

Add and remove components

Let's say you wanted to add a new component to an existing system. You can do that by using the add_component! function. In the Julia REPL, hit ? to enter the documentation mode and type add_component!.

help?> add_component!
add_component!(sys::PowerSystems.System, component::PowerSystems.Component; skip_validation, kwargs...)

Add a component to the system.

Throws ArgumentError if the component's name is already stored for its concrete type. Throws ArgumentError if any Component-specific rule is violated. Throws InvalidValue if any of the component's field values are outside of defined valid range.

Examples

sys = System(100.0)

# Add a single component.
add_component!(sys, bus)

# Add many at once.
buses = [bus1, bus2, bus3]
generators = [gen1, gen2, gen3]
foreach(x -> add_component!(sys, x), Iterators.flatten((buses, generators)))
add_component!(sys::PowerSystems.System, dyn_injector::PowerSystems.DynamicInjection, static_injector::PowerSystems.StaticInjection; kwargs...)

Add a dynamic injector to the system.

Throws ArgumentError if the name does not match the staticinjector name. Throws ArgumentError if the staticinjector is not attached to the system.

All rules for the generic add_component! method also apply.

This function takes a PowerSystems.System and a PowerSystems.Component. Let's create a battery storage and attach it to a bus.

loads = collect(get_components(PowerLoad, system))
battery = GenericBattery(; name = "battery",
  available = true,
  bus = get_bus(first(loads)),
  prime_mover=PrimeMovers.BA,
  initial_energy=0.0,
  state_of_charge_limits=(min=0.0, max=0.0),
  rating=0.0,
  active_power=0.0,
  input_active_power_limits=(min=0.0, max=0.0),
  output_active_power_limits=(min=0.0, max=0.0),
  efficiency=(in=0.0, out=0.0),
  reactive_power=0.0,
  reactive_power_limits=(min=0.0, max=0.0),
  base_power=0.0,
)
add_component!(system, battery)
battery
battery (PowerSystems.GenericBattery):
   name: battery
   available: true
   bus: Bacon (PowerSystems.Bus)
   prime_mover: PowerSystems.PrimeMoversModule.PrimeMovers.BA = 1
   initial_energy: 0.0
   state_of_charge_limits: (min = 0.0, max = 0.0)
   rating: 0.0
   active_power: 0.0
   input_active_power_limits: (min = 0.0, max = 0.0)
   output_active_power_limits: (min = 0.0, max = 0.0)
   efficiency: (in = 0.0, out = 0.0)
   reactive_power: 0.0
   reactive_power_limits: (min = 0.0, max = 0.0)
   base_power: 0.0
   operation_cost: nothing
   services: 0-element Vector{PowerSystems.Service}
   dynamic_injector: nothing
   ext: Dict{String, Any}()
   time_series_container: InfrastructureSystems.TimeSeriesContainer: 0
   InfrastructureSystems.SystemUnitsSettings:
      base_value: 100.0
      unit_system: InfrastructureSystems.UnitSystemModule.UnitSystem.NATURAL_UNITS = 2

And if you want to remove the component, you can use the remove_component! function:

remove_component!(system, battery)
# OR
remove_component!(system, get_component(GenericBattery, system, "battery"))

During the next session, we will explore building a formulation that includes batteries as part of the scheduling problem.

Working with time series data

Let's say we wanted to retrieve the load profile data. First, we can get all the PowerLoad components.

loads = collect(get_components(PowerLoad, system))
51-element Vector{PowerSystems.PowerLoad}:
 PowerLoad(Bacon, true, Bus(202, Bacon, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.1877810214196211, 1.04844, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(22.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 97.0, 20.0, 100.0, 97.0, 20.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Adams, true, Bus(102, Adams, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.1364470483941135, 1.04783, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(12.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 97.0, 20.0, 100.0, 97.0, 20.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Bajer, true, Bus(206, Bajer, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.28198796032281825, 1.03259, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(22.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 136.0, 28.000000000000004, 100.0, 136.0, 28.000000000000004, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Adler, true, Bus(103, Adler, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.1258539470320591, 1.01085, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(11.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 180.0, 37.0, 100.0, 180.0, 37.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Cabell, true, Bus(301, Cabell, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.1631570436678591, 1.0486, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(31.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 108.0, 22.0, 100.0, 108.0, 22.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Bailey, true, Bus(204, Bailey, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.23535398444000616, 1.0189, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(21.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 74.0, 15.0, 100.0, 74.0, 15.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Alder, true, Bus(107, Alder, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.19681606735842017, 1.03745, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(12.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 125.0, 25.0, 100.0, 125.0, 25.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Allen, true, Bus(110, Allen, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.18536496213608536, 1.05, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(13.0, 370.0, 76.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 195.0, 40.0, 100.0, 195.0, 40.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Barton, true, Bus(215, Barton, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.08087000542408246, 1.04327, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(26.0, 611.0, 123.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 317.0, 64.0, 100.0, 317.0, 64.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Bach, true, Bus(201, Bach, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.18657098464921346, 1.04841, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(21.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 108.0, 22.0, 100.0, 108.0, 22.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Caesar, true, Bus(303, Caesar, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.14969497008137647, 1.01045, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(31.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 180.0, 37.0, 100.0, 180.0, 37.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Carew, true, Bus(307, Carew, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.21900304187562247, 1.03804, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(32.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 125.0, 25.0, 100.0, 125.0, 25.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Bain, true, Bus(205, Bain, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.23757194885344055, 1.03603, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(21.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 71.0, 14.000000000000002, 100.0, 71.0, 14.000000000000002, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Chase, true, Bus(315, Chase, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.12306107116301779, 1.043, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(36.0, 611.0, 123.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 317.0, 64.0, 100.0, 317.0, 64.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Carrel, true, Bus(308, Carrel, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.26499107140227146, 1.01056, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(32.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 171.0, 35.0, 100.0, 171.0, 35.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Ali, true, Bus(109, Ali, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.15385496235350493, 1.0261, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(13.0, 370.0, 76.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 175.0, 36.0, 100.0, 175.0, 36.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Caruso, true, Bus(310, Caruso, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.2146959183475509, 1.05, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(33.0, 370.0, 76.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 195.0, 40.0, 100.0, 195.0, 40.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Asser, true, Bus(116, Asser, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.13210903253828157, 1.04565, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(16.0, 611.0, 123.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 100.0, 20.0, 100.0, 100.0, 20.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Chifa, true, Bus(316, Chifa, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.11516991401597582, 1.04558, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(36.0, 611.0, 123.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 100.0, 20.0, 100.0, 100.0, 20.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Alger, true, Bus(108, Alger, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.23997701256268875, 1.01024, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(12.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 171.0, 35.0, 100.0, 171.0, 35.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Agricola, true, Bus(104, Agricola, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.18441393222667365, 1.01765, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(11.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 74.0, 15.0, 100.0, 74.0, 15.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Astor, true, Bus(118, Astor, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.21859498389650622, 1.05, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(17.0, 333.0, 68.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 333.0, 68.0, 100.0, 333.0, 68.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Aiken, true, Bus(105, Aiken, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.18690504066804514, 1.03568, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(11.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 71.0, 14.000000000000002, 100.0, 71.0, 14.000000000000002, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Clay, true, Bus(319, Clay, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.10324303203954738, 1.03953, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(35.0, 309.0, 63.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 181.0, 37.0, 100.0, 181.0, 37.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Barlow, true, Bus(213, Barlow, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.05611408078086969, 1.03752, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(24.0, 265.0, 54.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 265.0, 54.0, 100.0, 265.0, 54.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Caine, true, Bus(304, Caine, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.21271793670626568, 1.01785, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(31.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 74.0, 15.0, 100.0, 74.0, 15.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Banks, true, Bus(210, Banks, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.23526793970788284, 1.05, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(23.0, 370.0, 76.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 195.0, 40.0, 100.0, 195.0, 40.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Basov, true, Bus(216, Basov, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.0820320456400603, 1.04556, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(26.0, 611.0, 123.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 100.0, 20.0, 100.0, 100.0, 20.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Balzac, true, Bus(209, Balzac, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.204623972300142, 1.02781, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(23.0, 370.0, 76.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 175.0, 36.0, 100.0, 175.0, 36.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Camus, true, Bus(306, Camus, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.26078796949761873, 1.0326, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(32.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 136.0, 28.000000000000004, 100.0, 136.0, 28.000000000000004, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Chain, true, Bus(314, Chain, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.0559889406735017, 1.04631, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(36.0, 611.0, 123.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 194.0, 39.0, 100.0, 194.0, 39.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Alber, true, Bus(106, Alber, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.23176995082103577, 1.03242, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(12.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 136.0, 28.000000000000004, 100.0, 136.0, 28.000000000000004, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Clark, true, Bus(318, Clark, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.19796606480255924, 1.05, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(37.0, 333.0, 68.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 333.0, 68.0, 100.0, 333.0, 68.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Attar, true, Bus(119, Attar, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.11620000734050288, 1.03962, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(15.0, 309.0, 63.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 181.0, 37.0, 100.0, 181.0, 37.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Arthur, true, Bus(115, Arthur, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.13892297247099264, 1.04335, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(16.0, 611.0, 123.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 317.0, 64.0, 100.0, 317.0, 64.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Cecil, true, Bus(313, Cecil, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.04215197036369065, 1.03802, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(34.0, 265.0, 54.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 265.0, 54.0, 100.0, 265.0, 54.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Beethoven, true, Bus(220, Beethoven, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.09886400094629359, 1.0438, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(25.0, 309.0, 63.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 128.0, 26.0, 100.0, 128.0, 26.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Attila, true, Bus(120, Attila, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.13509895607987307, 1.04399, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(15.0, 309.0, 63.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 128.0, 26.0, 100.0, 128.0, 26.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Abel, true, Bus(101, Abel, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.13511501310899143, 1.04777, (min = 0.95, max = 1.05), 138.0, Area(1, 0.0, 0.0, 0.0), LoadZone(11.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 108.0, 22.0, 100.0, 108.0, 22.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Balch, true, Bus(208, Balch, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.2831550619936269, 1.01203, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(22.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 171.0, 35.0, 100.0, 171.0, 35.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Carter, true, Bus(309, Carter, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.18232006072305607, 1.02579, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(33.0, 370.0, 76.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 175.0, 36.0, 100.0, 175.0, 36.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Clive, true, Bus(320, Clive, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.1256129170623587, 1.04389, (min = 0.95, max = 1.05), 230.0, Area(3, 0.0, 0.0, 0.0), LoadZone(35.0, 309.0, 63.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 128.0, 26.0, 100.0, 128.0, 26.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Calvin, true, Bus(305, Calvin, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.2155490352859257, 1.03609, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(31.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 71.0, 14.000000000000002, 100.0, 71.0, 14.000000000000002, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Cabot, true, Bus(302, Cabot, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.1646020017555852, 1.04864, (min = 0.95, max = 1.05), 138.0, Area(3, 0.0, 0.0, 0.0), LoadZone(32.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 97.0, 20.0, 100.0, 97.0, 20.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Bayle, true, Bus(218, Bayle, PowerSystems.BusTypesModule.BusTypes.PV = 3, 0.17444094634785287, 1.05, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(27.0, 333.0, 68.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 333.0, 68.0, 100.0, 333.0, 68.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Bede, true, Bus(219, Bede, PowerSystems.BusTypesModule.BusTypes.PQ = 2, 0.07351902768053274, 1.03946, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(25.0, 309.0, 63.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 181.0, 37.0, 100.0, 181.0, 37.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Arnold, true, Bus(114, Arnold, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.03020396990331307, 1.04401, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(16.0, 611.0, 123.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 194.0, 39.0, 100.0, 194.0, 39.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Baker, true, Bus(207, Baker, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.23502708427110763, 1.03973, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(22.0, 529.0, 108.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 125.0, 25.0, 100.0, 125.0, 25.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Barry, true, Bus(214, Barry, PowerSystems.BusTypesModule.BusTypes.PV = 3, -0.08177199158151313, 1.04335, (min = 0.95, max = 1.05), 230.0, Area(2, 0.0, 0.0, 0.0), LoadZone(26.0, 611.0, 123.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 194.0, 39.0, 100.0, 194.0, 39.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Arne, true, Bus(113, Arne, PowerSystems.BusTypesModule.BusTypes.REF = 4, 0.0, 1.03943, (min = 0.95, max = 1.05), 230.0, Area(1, 0.0, 0.0, 0.0), LoadZone(14.0, 265.0, 54.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 265.0, 54.0, 100.0, 265.0, 54.0, PowerSystems.Service[], nothing, Dict{String, Any}())
 PowerLoad(Baffin, true, Bus(203, Baffin, PowerSystems.BusTypesModule.BusTypes.PQ = 2, -0.18281503609892163, 1.01886, (min = 0.95, max = 1.05), 138.0, Area(2, 0.0, 0.0, 0.0), LoadZone(21.0, 433.0, 88.0), Dict{String, Any}()), PowerSystems.LoadModelsModule.LoadModels.ConstantPower = 3, 180.0, 37.0, 100.0, 180.0, 37.0, PowerSystems.Service[], nothing, Dict{String, Any}())

We can call get_time_series_names to see the names of all the time series attached to the loads

[names for names in get_time_series_names.(Deterministic, loads)]
51-element Vector{Vector{String}}:
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
 ["max_active_power"]
πŸ’‘ Tip You can use the broadcast operator for this instead:
get_time_series_names.(Deterministic, loads);

There's a lot of time series in there that appear to have the same name. Let's find all unique names of the kinds of time series data that we are dealing with.

only(unique(Iterators.flatten(get_time_series_names.(Deterministic, loads))))
"max_active_power"

It looks like, in this test system, there's only one kind of time series data in all the PowerLoad components, i.e. the max_active_power time series, which makes sense for Deterministic loads.

You may be wondering what other kinds of time series data is possible to store:

D3PowerSystemTypes(supertype(supertype(supertype(Deterministic))))
# Or
D3PowerSystemTypes(PowerSystems.TimeSeriesData)

Now that we know that there's only a "max_active_power" type of time series data.

data = [get_time_series_array(Deterministic, load, "max_active_power") for load in loads];
(length = length(data), type = typeof(data))
(length = 51, type = Vector{TimeSeries.TimeArray{Float64, 1, Dates.DateTime, Vector{Float64}}})

PowerGraphics has some utility functions for plotting load profiles but lets do this one manually as an exercise.

using Plots
p = plot(popfirst!(data), label = popfirst!(names))
for (name, timeseries) in zip(names, data)
  plot!(p, timeseries, label = name)
end
p
πŸ“ Note In Julia, by convention, functions that modify the first argument have a ! at the end of the function name. For plotting, the first plot object is stored in the variable p, and the subsequent function calls to plot are "modifying" the same plot object. This is why the first function doesn't have a ! but other calls for plotting do. This lets us plot all the load profiles and display them together in the same plot.
πŸ’‘ Tip In all our code samples, we have been importing a package using the using keyword. This adds all the exported symbols to the current namespace. Sometimes this might not be what you want. You can instead import a package using the import keyword.
import Plots
p = Plots.plot(popfirst!(data), label = popfirst!(names))
for (name, timeseries) in zip(names, data)
  Plots.plot!(p, timeseries, label = name)
end
p
This makes it more clearer in the code which packages the functions are coming from.

Summary

We explored the type hierarchy of the PowerSystems.Component. We also looked at how to use the accessor functions to get and set data. And finally we did some simple plots after getting time series data on the system.

πŸ‹ Exercise Can you find the names of 10 "largest on average" loads in this system?
We can use the standard library's Statistics package for the mean function.
using Statistics
 
 function get_largest_loads(system)
   reverse(
     sort(
       collect(get_components(PowerLoad, system)),
       by = load -> mean(
         values(
           get_time_series_array(
             Deterministic,
             load,
             "max_active_power"
           )
         )
       )
     )
   )
 end
 
 get_largest_load_names(system, n = 10) =
   get_name.(Iterators.take(get_largest_loads(system), n))
 
 get_largest_load_names(system, 10)
10-element Vector{String}:
 "Clark"
 "Chase"
 "Cecil"
 "Bayle"
 "Barton"
 "Astor"
 "Arthur"
 "Barlow"
 "Arne"
 "Caruso"
πŸ‹ Exercise Can you plot the network graph of the RTS system?
I like using Graphs.jl for a light weight networks / graphs package. Additionally, I like using MetaGraphs for storing additional metadata on the graphs.
using Graphs, MetaGraphs
 using GraphRecipes
 using JSONTables
 
 function create_graph(sys::PowerSystems.System)
     buses = collect(get_components(Bus, sys))
     n_bus = length(buses)
     gens = collect(get_components(Generator, sys))
     n_gen = length(gens)
     loads = collect(get_components(PowerLoad, sys))
     n_load = length(loads)
     graph = MetaGraph(SimpleGraph(n_bus + n_gen + n_load))
     from_to_buses = map(get_components(Branch, sys)) do branch
         (
             only(findall(x -> x.name === get_arc(branch).from.name, buses)),
             only(findall(x -> x.name === get_arc(branch).to.name, buses))
         )
     end
     for (f, t) in from_to_buses
         add_edge!(graph, f, t)
     end
     for (i, bus) in enumerate(buses)
         set_prop!(graph, i, :group, get_bustype(bus).value)
         set_prop!(graph, i, :name, get_name(bus))
     end
     for (i, gen) in enumerate(gens)
         gen_node = i + n_bus
         add_edge!(graph, gen_node, only(findall(x -> x.name === get_bus(gen).name, buses)))
         set_prop!(graph, gen_node, :group, 0)
         set_prop!(graph, gen_node, :name, get_name(gen))
     end
     for (i, load) in enumerate(loads)
         load_node = i + n_bus + n_gen
         add_edge!(graph, load_node, only(findall(x -> x.name === get_bus(load).name, buses)))
         set_prop!(graph, load_node, :group, 6)
         set_prop!(graph, load_node, :name, get_name(load))
         set_prop!(graph, load_node, :timeseries, arraytable(get_time_series_array(Deterministic, load, "max_active_power")))
     end
     graph
 end
 
 function create_plot(g)
     n = first(size(g))
     graphplot(
         g,
         curves = false,
         names = rpad.(lpad.(string.(1:n), 2), 2),
         nodesize = 0.2,
         nodeshape = :circle,
         method = :sfdp,
     )
 end
 
 create_plot(create_graph(system))
Unfortunately, this is not very useful for larger systems. We can also use D3.js to plot the graph of the system. Run the following in a vscode Julia session to see an example of this.
 include("utils.jl")
 D3NetworkLayout(create_graph(system))
 
CC BY-SA 4.0 "Dheepak Krishnamurthy". Last modified: August 26, 2022. Website built with Franklin.jl and the Julia programming language.