Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@ JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
OpenAPI = "d5e62ea6-ddf3-4d43-8e4c-ad5e6c8bfd7d"
PowerCoreOpenAPIModels = "b7b40286-e793-417d-a9a0-b1583e4da1cb"
PowerDynamicsOpenAPIModels = "044a0b22-31f8-4ef6-8282-c9a61b3013f6"
PowerInvestmentsOpenAPIModels = "33cb4396-f4d9-4f59-8585-787ebb56cb1b"
PowerOpenAPIModels = "0730f07c-cff6-4c3b-a9df-c546153be50a"
PowerOperationsOpenAPIModels = "a372b6d7-45a2-44c2-8199-6a724b72e8ff"
PowerTimeSeriesOpenAPIModels = "8c2f6a0d-6b0e-4d0a-9d8f-2b5e6a4f9c31"
Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[sources]
# These packages are generated and not yet released, so they resolve from the branch
# rather than the registry. Switch to a tagged rev once one exists.
PowerCoreOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerCoreOpenAPIModels.jl"}
PowerOperationsOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerOperationsOpenAPIModels.jl"}
PowerOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerOpenAPIModels.jl"}
PowerDynamicsOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerDynamicsOpenAPIModels.jl"}
PowerInvestmentsOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerInvestmentsOpenAPIModels.jl"}
PowerTimeSeriesOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerTimeSeriesOpenAPIModels.jl"}
InfrastructureSystems = {rev = "IS4", url = "https://github.com/Sienna-Platform/InfrastructureSystems.jl"}

[compat]
Expand All @@ -30,7 +36,10 @@ JSON = "1"
LinearAlgebra = "1"
OpenAPI = "0.2"
PowerCoreOpenAPIModels = "0.1"
PowerDynamicsOpenAPIModels = "0.1"
PowerInvestmentsOpenAPIModels = "0.1"
PowerOpenAPIModels = "0.1"
PowerOperationsOpenAPIModels = "0.1"
PowerTimeSeriesOpenAPIModels = "0.1"
Unicode = "1"
julia = "^1.10"
12 changes: 5 additions & 7 deletions src/pm_io/psse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -951,17 +951,15 @@ function _psse2pm_shunt!(pm_data::Dict, pti_data::Dict, import_all::Bool, nb)

sub_data["ext"]["NREG"] = pop!(switched_shunt, "NREG")
elseif pm_data["source_version"] ∈ ("30", "32", "33")
sub_data["initial_status"] = ones(Int, length(sub_data["y_increment"]))
# Pre-v35 SWITCHED SHUNT records carry no per-block status field. BINIT
# already holds the total in-service admittance, which `bs` above passes
# on, so every block must start out of service whatever MODSW says —
# counting any of them in would double-count that same admittance.
sub_data["initial_status"] = zeros(Int, length(sub_data["y_increment"]))
else
error("Unsupported PSS(R)E source version: $(pm_data["source_version"])")
end

if switched_shunt["MODSW"] ∈ (0, 1, 2)
# BINIT is treated as the total shunt admittance.
# Keep Y_increase but zero all initial states to avoid double counting.
sub_data["initial_status"] = zeros(Int, length(sub_data["y_increment"]))
end

sub_data["index"] = length(pm_data["switched_shunt"]) + 1
sub_data["source_id"] = ["switched shunt", bus_number, sub_data["index"]]

Expand Down
9 changes: 7 additions & 2 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
[deps]
PowerOpenAPIModels = "0730f07c-cff6-4c3b-a9df-c546153be50a"
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
InfrastructureSystems = "2cd47ed4-ca9b-11e9-27f2-ab636a7671f1"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
OpenAPI = "d5e62ea6-ddf3-4d43-8e4c-ad5e6c8bfd7d"
PowerCoreOpenAPIModels = "b7b40286-e793-417d-a9a0-b1583e4da1cb"
PowerDynamicsOpenAPIModels = "044a0b22-31f8-4ef6-8282-c9a61b3013f6"
PowerFlowFileParser = "bed98974-b02e-5e2f-9ee0-a103f5c450dd"
PowerInvestmentsOpenAPIModels = "33cb4396-f4d9-4f59-8585-787ebb56cb1b"
PowerOpenAPIModels = "0730f07c-cff6-4c3b-a9df-c546153be50a"
PowerOperationsOpenAPIModels = "a372b6d7-45a2-44c2-8199-6a724b72e8ff"
PowerTimeSeriesOpenAPIModels = "8c2f6a0d-6b0e-4d0a-9d8f-2b5e6a4f9c31"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[sources]
PowerFlowFileParser = {path = ".."}
PowerCoreOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerCoreOpenAPIModels.jl"}
PowerOperationsOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerOperationsOpenAPIModels.jl"}
PowerOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerOpenAPIModels.jl"}
PowerDynamicsOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerDynamicsOpenAPIModels.jl"}
PowerInvestmentsOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerInvestmentsOpenAPIModels.jl"}
PowerTimeSeriesOpenAPIModels = {url = "https://github.com/Sienna-Platform/PowerOpenAPIModels.git", rev = "main", subdir = "PowerTimeSeriesOpenAPIModels.jl"}

[compat]
julia = "^1.6"
28 changes: 28 additions & 0 deletions test/test_parse_psse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,31 @@ end
@test pm_v33["bus"][1]["area_slack"] === true
@test !haskey(pm_v33["bus"][3], "area_slack")
end

@testset "PSSE pre-v35 switched shunt blocks start out of service" begin
# Pre-v35 SWITCHED SHUNT records have no per-block status field, so the parser has to
# fabricate one. BINIT already carries the total in-service admittance into `bs`, so
# every block must start at zero whatever MODSW says; an in-service block would
# double-count the admittance BINIT has already contributed.
raw = read_fixture(FOURTEEN_BUS_FIXTURE)
pm_data = parse_file(IOBuffer(raw); filetype = "raw")
@test pm_data["source_version"] == "33"

shunts = collect(values(pm_data["switched_shunt"]))
@test !isempty(shunts)
for shunt in shunts
@test shunt["initial_status"] == zeros(Int, length(shunt["y_increment"]))
end

# Bus 101's record is MODSW=1, which an earlier mode-specific patch already zeroed.
# MODSW=3 took the fabricated all-ones path and is the case this fixes.
modsw3 = replace(raw, " 101,1,0,1," => " 101,3,0,1,"; count = 1)
@test modsw3 != raw
pm_modsw3 = parse_file(IOBuffer(modsw3); filetype = "raw")
shunt_101 =
only(v for v in values(pm_modsw3["switched_shunt"]) if v["shunt_bus"] == 101)
@test shunt_101["control_mode"] == 3
@test shunt_101["step_number"] == [5]
@test length(shunt_101["y_increment"]) == 1
@test shunt_101["initial_status"] == [0]
end
Loading