Parsing PSS/e dynamic data
A PowerSystems.jl
system can be created using a .RAW and a .DYR file. In this example we will create a three bus system from these example files:
julia> using PowerSystems
julia> file_dir = joinpath(pkgdir(PowerSystems), "docs", "src", "tutorials", "tutorials_data")
"/home/runner/work/PowerSystems.jl/PowerSystems.jl/docs/src/tutorials/tutorials_data"
julia> RAW_dir = joinpath(file_dir, "ThreeBusNetwork.raw")
"/home/runner/work/PowerSystems.jl/PowerSystems.jl/docs/src/tutorials/tutorials_data/ThreeBusNetwork.raw"
julia> DYR_dir = joinpath(file_dir, "TestGENCLS.dyr")
"/home/runner/work/PowerSystems.jl/PowerSystems.jl/docs/src/tutorials/tutorials_data/TestGENCLS.dyr"
The data in the RAW file defines a three bus system with three generators, three loads and three branches:
0, 100, 33, 0, 0, 60 / 24-Apr-2020 19:28:39 - MATPOWER 7.0.1-dev
101, 'BUS 1 ', 138, 3, 1, 1, 1, 1.02, 0, 1.1, 0.9, 1.1, 0.9
102, 'BUS 2 ', 138, 2, 1, 1, 1, 1.0142, 0, 1.1, 0.9, 1.1, 0.9
103, 'BUS 3 ', 138, 2, 1, 1, 1, 1.0059, 0, 1.1, 0.9, 1.1, 0.9
0 / END OF BUS DATA, BEGIN LOAD DATA
101, 1, 1, 1, 1, 100, 20, 0, 0, 0, 0, 1, 1, 0
102, 1, 1, 1, 1, 70, 10, 0, 0, 0, 0, 1, 1, 0
103, 1, 1, 1, 1, 50, 10, 0, 0, 0, 0, 1, 1, 0
0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA
0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA
101, 1, 20, 0, 100, -100, 1.02, 0, 100, 0, 0, 0, 0, 1, 1, 100, 318, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1
102, 1, 100, 0, 100, -100, 1.0142, 0, 100, 0, 0.7, 0, 0, 1, 1, 100, 318, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1
103, 1, 100, 0, 100, -100, 1.0059, 0, 100, 0, 0.2, 0, 0, 1, 1, 100, 318, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1
0 / END OF GENERATOR DATA, BEGIN BRANCH DATA
101, 103, 1, 0.01000, 0.12, 0.0, 250, 250, 250, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1
101, 102, 1, 0.01000, 0.12, 0.0, 250, 250, 250, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1
102, 103, 1, 0.01000, 0.12, 0.0, 250, 250, 250, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1
0 / END OF BRANCH DATA, BEGIN TRANSFORMER DATA
0 / END OF TRANSFORMER DATA, BEGIN AREA DATA
0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA
0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA
0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA
0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA
0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA
0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA
0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA
0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA
0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA
0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA
0 / END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA
0 / END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA
0 / END OF INDUCTION MACHINE DATA
Q
The dynamic data for the generators is provided in the DYR file:
101 'GENROE' 1 8.000000 0.030000 0.400000 0.050000 6.500000 0.000000 1.800000
1.700000 0.300000 0.550000 0.250000 0.200000 0.039200 0.267200 /
101 'ESST1A' 1 1 1 0.01 99 -99 1 10 1 1 200 0 4 -4 4 -4 0 0 1 0 3 /
102 'GENCLS' 1 0.0 0.0 /
103 'GENCLS' 1 3.1 2.0 /
That assigns a GENROU generator and a ESST1A voltage regulator at the generator located at bus 101, while classic machine models for the generators located at bus 102 and 103.
To create the System
in PowerSystems.jl
, we pass both files directories:
julia> dyn_system = System(RAW_dir, DYR_dir; runchecks = false)
[ Info: The PSS(R)E parser currently supports buses, loads, shunts, generators, branches, transformers, and dc lines [ Info: The PSS(R)E parser currently supports buses, loads, shunts, generators, branches, transformers, and dc lines [ Info: Parsing PSS(R)E Bus data into a PowerModels Dict... [ Info: Parsing PSS(R)E Load data into a PowerModels Dict... [ Info: Parsing PSS(R)E Shunt data into a PowerModels Dict... [ Info: Parsing PSS(R)E Generator data into a PowerModels Dict... [ Info: Parsing PSS(R)E Branch data into a PowerModels Dict... [ Info: Parsing PSS(R)E Transformer data into a PowerModels Dict... [ Info: Parsing PSS(R)E Two-Terminal and VSC DC line data into a PowerModels Dict... ┌ Warning: This PSS(R)E parser currently doesn't support Storage data parsing... └ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/parsers/pm_io/psse.jl:998 ┌ Warning: This PSS(R)E parser currently doesn't support Switch data parsing... └ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/parsers/pm_io/psse.jl:1004 [ Info: angmin and angmax values are 0, widening these values on branch 1 to +/- 60.0 deg. [ Info: angmin and angmax values are 0, widening these values on branch 2 to +/- 60.0 deg. [ Info: angmin and angmax values are 0, widening these values on branch 3 to +/- 60.0 deg. ┌ Info: Constructing System from Power Models │ data["name"] = "threebusnetwork" └ data["source_type"] = "pti" [ Info: Reading bus data [ Info: Reading Load data in PowerModels dict to populate System ... [ Info: Reading LoadZones data in PowerModels dict to populate System ... [ Info: Reading generator data [ Info: Reading branch data [ Info: Reading shunt data [ Info: Reading DC Line data [ Info: Reading storage data [ Info: Generators provided in .dyr, without a generator in .raw file will be skipped. [ Info: Machine at bus 102, id 1 has zero inertia. Modeling it as Voltage Source System ┌───────────────────┬─────────────┐ │ Property │ Value │ ├───────────────────┼─────────────┤ │ Name │ │ │ Description │ │ │ System Units Base │ SYSTEM_BASE │ │ Base Power │ 100.0 │ │ Base Frequency │ 60.0 │ │ Num Components │ 19 │ └───────────────────┴─────────────┘ Static Components ┌─────────────────┬───────┐ │ Type │ Count │ ├─────────────────┼───────┤ │ ACBus │ 3 │ │ Arc │ 3 │ │ Area │ 1 │ │ Line │ 3 │ │ LoadZone │ 1 │ │ Source │ 1 │ │ StandardLoad │ 3 │ │ ThermalStandard │ 2 │ └─────────────────┴───────┘ Dynamic Components ┌─────────────────────────────────────────────────────────────────────────────── │ Type ⋯ ├─────────────────────────────────────────────────────────────────────────────── │ DynamicGenerator{BaseMachine, SingleMass, AVRFixed, TGFixed, PSSFixed} ⋯ │ DynamicGenerator{RoundRotorExponential, SingleMass, ESST1A, TGFixed, PSSFixe ⋯ └─────────────────────────────────────────────────────────────────────────────── 2 columns omitted
Supported PSS/e Models
PSS/e's dynamic model library is extensive, we currently support parsing a limited amount of models out of the box.
Machine models | AVR Models | Prime Movers | PSS models |
---|---|---|---|
GENSAE | IEEET1 | HYGOV | IEEEST |
GENSAL | ESDC1A | IEEEG1 | |
GENROE | ESAC1A | GGOV1 | |
GENCLS | ESST4B | ||
GENROU | EXAC2 | ||
EXPIC1 | |||
ESAC6A | |||
EXAC1 | |||
SCRX | |||
ESDC2A |
Common Issue: Unique Bus Names
Please note that while PSS/e does not enforce unique bus names, PowerSystems.jl
does. To reparse bus names to comply with this requirement the bus_name_formatter
*kwarg can be used in System()
as shown in the example below:
julia> dyn_system = System( RAW_dir, DYR_dir; bus_name_formatter = x -> strip(string(x["name"])) * "-" * string(x["index"]), )
[ Info: The PSS(R)E parser currently supports buses, loads, shunts, generators, branches, transformers, and dc lines [ Info: The PSS(R)E parser currently supports buses, loads, shunts, generators, branches, transformers, and dc lines [ Info: Parsing PSS(R)E Bus data into a PowerModels Dict... [ Info: Parsing PSS(R)E Load data into a PowerModels Dict... [ Info: Parsing PSS(R)E Shunt data into a PowerModels Dict... [ Info: Parsing PSS(R)E Generator data into a PowerModels Dict... [ Info: Parsing PSS(R)E Branch data into a PowerModels Dict... [ Info: Parsing PSS(R)E Transformer data into a PowerModels Dict... [ Info: Parsing PSS(R)E Two-Terminal and VSC DC line data into a PowerModels Dict... ┌ Warning: This PSS(R)E parser currently doesn't support Storage data parsing... └ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/parsers/pm_io/psse.jl:998 ┌ Warning: This PSS(R)E parser currently doesn't support Switch data parsing... └ @ PowerSystems ~/work/PowerSystems.jl/PowerSystems.jl/src/parsers/pm_io/psse.jl:1004 [ Info: angmin and angmax values are 0, widening these values on branch 1 to +/- 60.0 deg. [ Info: angmin and angmax values are 0, widening these values on branch 2 to +/- 60.0 deg. [ Info: angmin and angmax values are 0, widening these values on branch 3 to +/- 60.0 deg. ┌ Info: Constructing System from Power Models │ data["name"] = "threebusnetwork" └ data["source_type"] = "pti" [ Info: Reading bus data [ Info: Reading Load data in PowerModels dict to populate System ... [ Info: Reading LoadZones data in PowerModels dict to populate System ... [ Info: Reading generator data [ Info: Reading branch data [ Info: Reading shunt data [ Info: Reading DC Line data [ Info: Reading storage data [ Info: Generators provided in .dyr, without a generator in .raw file will be skipped. [ Info: Machine at bus 102, id 1 has zero inertia. Modeling it as Voltage Source ┌ Warning: struct DynamicGenerator does not exist in validation configuration file, validation skipped └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/A1orZ/src/validation.jl:51 ┌ Warning: struct DynamicGenerator does not exist in validation configuration file, validation skipped └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/A1orZ/src/validation.jl:51 System ┌───────────────────┬─────────────┐ │ Property │ Value │ ├───────────────────┼─────────────┤ │ Name │ │ │ Description │ │ │ System Units Base │ SYSTEM_BASE │ │ Base Power │ 100.0 │ │ Base Frequency │ 60.0 │ │ Num Components │ 19 │ └───────────────────┴─────────────┘ Static Components ┌─────────────────┬───────┐ │ Type │ Count │ ├─────────────────┼───────┤ │ ACBus │ 3 │ │ Arc │ 3 │ │ Area │ 1 │ │ Line │ 3 │ │ LoadZone │ 1 │ │ Source │ 1 │ │ StandardLoad │ 3 │ │ ThermalStandard │ 2 │ └─────────────────┴───────┘ Dynamic Components ┌─────────────────────────────────────────────────────────────────────────────── │ Type ⋯ ├─────────────────────────────────────────────────────────────────────────────── │ DynamicGenerator{BaseMachine, SingleMass, AVRFixed, TGFixed, PSSFixed} ⋯ │ DynamicGenerator{RoundRotorExponential, SingleMass, ESST1A, TGFixed, PSSFixe ⋯ └─────────────────────────────────────────────────────────────────────────────── 2 columns omitted
In this example the anonymous function x -> strip(string(x["name"])) * "-" * string(x["index"])
takes the bus name and index from PSSe and concatenates them to produce the name.
See also:
- Parsing Matpower or PSS/e RAW Files
- Parsing table data (CSV Files)
- Parsing time series