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 PowerSystemsjulia> 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
QThe 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/LEg3t/src/validation.jl:51 ┌ Warning: struct DynamicGenerator does not exist in validation configuration file, validation skipped └ @ InfrastructureSystems ~/.julia/packages/InfrastructureSystems/LEg3t/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