From 3f2116175a06ee28bf39f8d414b33ae1fc72f43f Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Tue, 14 Apr 2026 14:48:07 +1200 Subject: [PATCH 1/2] Remove LoggingExtras and use a package-local logger instead of global --- Project.toml | 4 +- src/PowerModelsDistribution.jl | 7 +- src/core/constraint_template.jl | 10 +- src/core/data.jl | 38 ++++---- src/core/logging.jl | 97 ++++++++----------- src/core/objective.jl | 2 +- src/core/ref.jl | 2 +- src/core/solution.jl | 2 +- src/data_model/base/parse.jl | 10 +- src/data_model/checks.jl | 2 +- src/data_model/components.jl | 2 +- src/data_model/multinetwork.jl | 12 +-- src/data_model/transformations/dss2eng.jl | 10 +- src/data_model/transformations/eng2math.jl | 4 +- .../transformations/initialization.jl | 4 +- src/data_model/transformations/rawdss2dss.jl | 28 +++--- src/data_model/units.jl | 4 +- src/data_model/utils.jl | 4 +- src/form/bf_mx_lin.jl | 2 +- src/form/en_ivr.jl | 6 +- src/io/dss/line_constants.jl | 2 +- src/io/dss/parse.jl | 12 +-- src/io/json/json.jl | 6 +- src/io/utils.jl | 16 +-- src/prob/common.jl | 6 +- src/prob/native_pf.jl | 10 +- src/prob/opf.jl | 2 +- test/opendss.jl | 34 ++++++- test/runtests.jl | 16 +++ 29 files changed, 186 insertions(+), 168 deletions(-) diff --git a/Project.toml b/Project.toml index 278cb445f..5337b2bfc 100644 --- a/Project.toml +++ b/Project.toml @@ -15,7 +15,6 @@ JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" JuMP = "4076af6c-e467-56ae-b986-b466b2749572" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" -LoggingExtras = "e6f89c97-d47a-5376-807f-9c37f3926c36" PolyhedralRelaxations = "2e741578-48fa-11ea-2d62-b52c946f73a0" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" @@ -30,11 +29,10 @@ InfrastructureModels = "0.7.3, 0.7.5" Ipopt = "1" JSON = "0.18, 0.19, 0.20, 0.21" JuMP = "1.23.2" -LoggingExtras = "0.4.7, 1" PolyhedralRelaxations = "0.3.5" SCS = "0.9, 1.0, 1.1" SpecialFunctions = "2" -julia = "1.6" +julia = "1.10" [extras] Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9" diff --git a/src/PowerModelsDistribution.jl b/src/PowerModelsDistribution.jl index 0a8443a3a..c7175ec39 100644 --- a/src/PowerModelsDistribution.jl +++ b/src/PowerModelsDistribution.jl @@ -17,7 +17,6 @@ module PowerModelsDistribution # Logging Utilities import Logging - import LoggingExtras # Stdlib Imports import Dates @@ -44,10 +43,8 @@ module PowerModelsDistribution # Setup Logging include("core/logging.jl") function __init__() - global _DEFAULT_LOGGER = Logging.current_logger() - global _LOGGER = Logging.ConsoleLogger(; meta_formatter=PowerModelsDistribution._pmd_metafmt) - - Logging.global_logger(_LOGGER) + reset_logging_level!() + return end include("core/base.jl") diff --git a/src/core/constraint_template.jl b/src/core/constraint_template.jl index 2e057b3d5..19bbee052 100644 --- a/src/core/constraint_template.jl +++ b/src/core/constraint_template.jl @@ -474,7 +474,7 @@ function constraint_mc_ohms_yt_from(pm::AbstractUnbalancedPowerModel, i::Int; nw t_idx = (i, t_bus, f_bus) if all(all(isapprox.(branch[k], 0.0)) for k in ["br_r", "br_x", "g_fr", "g_to", "b_fr", "b_to"]) - @debug "branch $(branch["source_id"]) being treated as superconducting (effective zero impedance)" + @_debug "branch $(branch["source_id"]) being treated as superconducting (effective zero impedance)" if !haskey(con(pm, nw), :branch_flow) con(pm, nw)[:branch_flow] = Dict{Int,Vector{Vector{<:JuMP.ConstraintRef}}}() end @@ -502,7 +502,7 @@ function constraint_mc_ohms_yt_to(pm::AbstractUnbalancedPowerModel, i::Int; nw:: t_idx = (i, t_bus, f_bus) if all(all(isapprox.(branch[k], 0.0)) for k in ["br_r", "br_x", "g_fr", "g_to", "b_fr", "b_to"]) - @debug "branch $(branch["source_id"]) being treated as superconducting (effective zero impedance)" + @_debug "branch $(branch["source_id"]) being treated as superconducting (effective zero impedance)" if !haskey(con(pm, nw), :branch_flow) con(pm, nw)[:branch_flow] = Dict{Int,Vector{Vector{<:JuMP.ConstraintRef}}}() end @@ -1008,7 +1008,7 @@ function constraint_storage_state(pm::AbstractUnbalancedPowerModel, i::Int; nw:: if haskey(ref(pm, nw), :time_elapsed) time_elapsed = ref(pm, nw, :time_elapsed) else - @warn "network data should specify time_elapsed in hours, using 1.0 as a default" + @_warn "network data should specify time_elapsed in hours, using 1.0 as a default" time_elapsed = 1.0 end @@ -1028,7 +1028,7 @@ function constraint_storage_state(pm::AbstractUnbalancedPowerModel, i::Int, nw_1 if haskey(ref(pm, nw_2), :time_elapsed) time_elapsed = ref(pm, nw_2, :time_elapsed) else - @warn "network $(nw_2) should specify time_elapsed in hours, using 1.0 as a default" + @_warn "network $(nw_2) should specify time_elapsed in hours, using 1.0 as a default" time_elapsed = 1.0 end @@ -1036,7 +1036,7 @@ function constraint_storage_state(pm::AbstractUnbalancedPowerModel, i::Int, nw_1 constraint_storage_state(pm, nw_1, nw_2, i, storage["charge_efficiency"], storage["discharge_efficiency"], time_elapsed) else # if the storage device has status=0 in nw_1, then the stored energy variable will not exist. Initialize storage from data model instead. - @warn "storage component $(i) was not found in network $(nw_1) while building constraint_storage_state between networks $(nw_1) and $(nw_2). Using the energy value from the storage component in network $(nw_2) instead" + @_warn "storage component $(i) was not found in network $(nw_1) while building constraint_storage_state between networks $(nw_1) and $(nw_2). Using the energy value from the storage component in network $(nw_2) instead" constraint_storage_state_initial(pm, nw_2, i, storage["energy"], storage["charge_efficiency"], storage["discharge_efficiency"], time_elapsed) end nothing diff --git a/src/core/data.jl b/src/core/data.jl index 3e568b516..1a3b5631d 100644 --- a/src/core/data.jl +++ b/src/core/data.jl @@ -840,21 +840,21 @@ function _correct_mc_voltage_angle_differences!(nw::Dict{String,<:Any}, default_ angmax = branch["angmax"] if any(angmin .<= -pi/2) - @warn "this code only supports angmin values in -90 deg. to 90 deg., tightening the value on branch $(i) from $(rad2deg(angmin)) to -$(default_pad_deg) deg." + @_warn "this code only supports angmin values in -90 deg. to 90 deg., tightening the value on branch $(i) from $(rad2deg(angmin)) to -$(default_pad_deg) deg." branch["angmin"][angmin .<= -pi/2] .= -default_pad push!(modified, branch["index"]) end if any(angmax .>= pi/2) - @warn "this code only supports angmax values in -90 deg. to 90 deg., tightening the value on branch $(i) from $(rad2deg(angmax)) to $(default_pad_deg) deg." + @_warn "this code only supports angmax values in -90 deg. to 90 deg., tightening the value on branch $(i) from $(rad2deg(angmax)) to $(default_pad_deg) deg." branch["angmax"][angmax .>= pi/2] .= default_pad push!(modified, branch["index"]) end if any((angmin .== 0.0) .& (angmax .== 0.0)) - @warn "angmin and angmax values are 0, widening these values on branch $(i) to +/- $(default_pad_deg) deg." + @_warn "angmin and angmax values are 0, widening these values on branch $(i) to +/- $(default_pad_deg) deg." branch["angmin"][(angmin .== 0.0) .& (angmax .== 0.0)] .= -default_pad branch["angmax"][(angmin .== 0.0) .& (angmax .== 0.0)] .= default_pad @@ -902,7 +902,7 @@ function _correct_mc_thermal_limits!(nw::Dict{String,<:Any})::Set{Int} if all(isapprox.(rate_value, 0.0)) delete!(branch, rate_key) - @warn "removing zero $(rate_key) limit on branch $(branch["index"])" + @_warn "removing zero $(rate_key) limit on branch $(branch["index"])" push!(modified, branch["index"]) end @@ -1129,7 +1129,7 @@ function _rescale_cost_model!(comp::Dict{String,<:Any}, scale::Real) comp["cost"][i] = item*(scale^(degree-i)) end else - @warn "Skipping cost model of type $(comp["model"]) in per unit transformation" + @_warn "Skipping cost model of type $(comp["model"]) in per unit transformation" end end end @@ -1153,7 +1153,7 @@ function _correct_branch_directions!(pm_data::Dict{String,<:Any}) orientation_rev = (branch["t_bus"], branch["f_bus"]) if in(orientation_rev, orientations) - @warn "reversing the orientation of branch $(i) $(orientation) to be consistent with other parallel branches" + @_warn "reversing the orientation of branch $(i) $(orientation) to be consistent with other parallel branches" branch_orginal = copy(branch) branch["f_bus"] = branch_orginal["t_bus"] branch["t_bus"] = branch_orginal["f_bus"] @@ -1303,13 +1303,13 @@ function _correct_bus_types!(pm_data::Dict{String,<:Any})::Set{Int} for (i, bus) in filter(x->x.second["bus_i"] in island, pm_data["bus"]) if bus["bus_type"] == 1 if !isempty(bus_gens[i]) # PQ - @info "active generators found at bus $(bus["bus_i"]), updating to bus type from $(bus["bus_type"]) to 2" + @_info "active generators found at bus $(bus["bus_i"]), updating to bus type from $(bus["bus_type"]) to 2" bus["bus_type"] = 2 push!(modified, bus["bus_i"]) end elseif bus["bus_type"] == 2 # PV if isempty(bus_gens[i]) - @info "no active generators found at bus $(bus["bus_i"]), updating to bus type from $(bus["bus_type"]) to 1" + @_info "no active generators found at bus $(bus["bus_i"]), updating to bus type from $(bus["bus_type"]) to 1" bus["bus_type"] = 1 push!(modified, bus["bus_i"]) end @@ -1317,7 +1317,7 @@ function _correct_bus_types!(pm_data::Dict{String,<:Any})::Set{Int} if !isempty(bus_gens[i]) slack_found = true else - @info "no active generators found at bus $(bus["bus_i"]), updating to bus type from $(bus["bus_type"]) to 1" + @_info "no active generators found at bus $(bus["bus_i"]), updating to bus type from $(bus["bus_type"]) to 1" bus["bus_type"] = 1 push!(modified, bus["bus_i"]) end @@ -1328,7 +1328,7 @@ function _correct_bus_types!(pm_data::Dict{String,<:Any})::Set{Int} if length(bus_gens[i]) != 0 new_bus_type = 2 end - @info "bus $(bus["bus_i"]) has an unrecongized bus_type $(bus["bus_type"]), updating to bus_type $(new_bus_type)" + @_info "bus $(bus["bus_i"]) has an unrecongized bus_type $(bus["bus_type"]), updating to bus_type $(new_bus_type)" bus["bus_type"] = new_bus_type push!(modified, bus["bus_i"]) end @@ -1340,9 +1340,9 @@ function _correct_bus_types!(pm_data::Dict{String,<:Any})::Set{Int} ref_bus = pm_data["bus"]["$(der["bus"])"] ref_bus["bus_type"] = 3 push!(modified, der["bus"]) - @info "no reference bus found, setting bus $(der["bus"]) as reference based on $(der["type"]) $(der["id"])" + @_info "no reference bus found, setting bus $(der["bus"]) as reference based on $(der["type"]) $(der["id"])" else - @info "no generators found in the given network data, disabling island" + @_info "no generators found in the given network data, disabling island" for bus in island pm_data["bus"]["$bus"]["bus_type"] = 4 push!(modified, bus) @@ -1358,7 +1358,7 @@ end "finds the largest active generation asset (gen, storage) in an island" function _biggest_der(pm_data::Dict{String,<:Any}; island::Set{Int}=Set{Int}([bus["bus_i"] for (_,bus) in get(pm_data, "bus", Dict())]))::Dict{String,Any} if length(filter(x->x.second["gen_bus"] in island && x.second["gen_status"] == 1, get(pm_data, "gen", Dict()))) + length(filter(x->x.second["storage_bus"] in island && x.second["status"] == 1, get(pm_data, "storage", Dict()))) == 0 - @debug "there are no active DERs in the island $island" + @_debug "there are no active DERs in the island $island" end biggest_der = Dict{String,Any}() @@ -1493,7 +1493,7 @@ function _correct_cost_function!(id, comp, type_name, pmin_key, pmax_key) error("ncost of $(comp["ncost"]) not consistent with $(length(comp["cost"])) cost values on $(type_name) $(id)") end else - @warn "Unknown cost model of type $(comp["model"]) on $(type_name) $(id)" + @_warn "Unknown cost model of type $(comp["model"]) on $(type_name) $(id)" end end @@ -1517,7 +1517,7 @@ function _remove_pwl_cost_duplicates!(id, comp, type_name; tolerance=1e-2) end if length(unique_costs) < length(comp["cost"]) - @warn "removing duplicate points from pwl cost on $(type_name) $(id), $(comp["cost"]) -> $(unique_costs)" + @_warn "removing duplicate points from pwl cost on $(type_name) $(id), $(comp["cost"]) -> $(unique_costs)" comp["cost"] = unique_costs comp["ncost"] = div(length(unique_costs), 2) return true @@ -1557,7 +1557,7 @@ function _simplify_pwl_cost!(id, comp, type_name; tolerance=1e-2) push!(smpl_cost, y2) if length(smpl_cost) < length(comp["cost"]) - @warn "simplifying pwl cost on $(type_name) $(id), $(comp["cost"]) -> $(smpl_cost)" + @_warn "simplifying pwl cost on $(type_name) $(id), $(comp["cost"]) -> $(smpl_cost)" comp["cost"] = smpl_cost comp["ncost"] = div(length(smpl_cost), 2) return true @@ -1592,7 +1592,7 @@ function _simplify_cost_terms!(pm_data::Dict{String,<:Any}) end if length(gen["cost"]) != ncost gen["ncost"] = length(gen["cost"]) - @info "removing $(ncost - gen["ncost"]) cost terms from generator $(i): $(gen["cost"])" + @_info "removing $(ncost - gen["ncost"]) cost terms from generator $(i): $(gen["cost"])" end end end @@ -1640,7 +1640,7 @@ function standardize_cost_terms!(data::Dict{String,<:Any}; order=-1) comp_max_order = order+1 else if order != -1 # if not the default - @warn "a standard cost order of $(order) was requested but the given data requires an order of at least $(comp_max_order-1)" + @_warn "a standard cost order of $(order) was requested but the given data requires an order of at least $(comp_max_order-1)" end end @@ -1669,7 +1669,7 @@ function _standardize_cost_terms!(components::Dict{String,<:Any}, comp_order::In #println("std gen cost: $(comp["cost"])") subnet = !isempty(nw) ? " on subnetwork $nw" : "" - @info "updated $(cost_comp_name) $(comp["index"])$(subnet) cost function with order $(length(current_cost)) to a function of order $(comp_order): $(comp["cost"])" + @_info "updated $(cost_comp_name) $(comp["index"])$(subnet) cost function with order $(length(current_cost)) to a function of order $(comp_order): $(comp["cost"])" push!(modified, comp["index"]) end end diff --git a/src/core/logging.jl b/src/core/logging.jl index 6865aa7b9..5665db59a 100644 --- a/src/core/logging.jl +++ b/src/core/logging.jl @@ -1,85 +1,68 @@ -""" - _pmd_metafmt(level::Logging.LogLevel, _module, group, id, file, line) +const _LOGGER = Ref{Logging.ConsoleLogger}() -MetaFormatter for ConsoleLogger for PMD to adjust log message format """ -function _pmd_metafmt(level::Logging.LogLevel, _module, group, id, file, line) - @nospecialize - color = Logging.default_logcolor(level) - prefix = "$(_module) | " * (level == Logging.Warn ? "Warning" : string(level)) * " ] :" - suffix = "" - Logging.Info <= level < Logging.Warn && return color, prefix, suffix - _module !== nothing && (suffix *= "$(_module)") - if file !== nothing - _module !== nothing && (suffix *= " ") - suffix *= Base.contractuser(file) - if line !== nothing - suffix *= ":$(isa(line, UnitRange) ? "$(first(line))-$(last(line))" : line)" - end - end - !isempty(suffix) && (suffix = "@ " * suffix) - - return color, prefix, suffix -end + silence!() +Silence logging within PowerModelsDistribution. +This is equivalent to calling `set_logging_level!(:Error)`. """ - silence!() +silence!() = set_logging_level!(:Error) -Sets loglevel for PMD to :Error, silencing Info and Warn """ -function silence!() - set_logging_level!(:Error) -end + reset_logging_level!() +Resets the log level to `:Info`. +This is equivalent to calling `set_logging_level!(:Info)`. """ - reset_logging_level!() +reset_logging_level!() = set_logging_level!(:Info) -Resets the log level to Info -""" -function reset_logging_level!() - Logging.global_logger(_LOGGER) +# A no-op. We keep this method for backward compatibility. +restore_global_logger!() = nothing - return +function _meta_formatter(level::Logging.LogLevel, _module, args...) + return Logging.default_logcolor(level), "$(_module) | $level]:", "" end - -""" - restore_global_logger!() - -Restores the global logger to its default state (before PMD was loaded) -""" -function restore_global_logger!() - Logging.global_logger(_DEFAULT_LOGGER) - +function set_logging_level!(level::Logging.LogLevel) + _LOGGER[] = + Logging.ConsoleLogger(stdout, level; meta_formatter = _meta_formatter) return end - """ set_logging_level!(level::Symbol) -Sets the logging level for PMD: :Info, :Warn, :Error +Set the logging level within PowerModelsDistribution. + +`level` must be one of `:Error`, `:Warn`, `:Info`, or `:Debug`. """ -function set_logging_level!(level::Symbol) - Logging.global_logger(_make_filtered_logger(getfield(Logging, level))) +set_logging_level!(level::Symbol) = set_logging_level!(getfield(Logging, level)) +function _log_if_level(f, level, logger = _LOGGER[]) + if level >= Logging.min_enabled_level(logger) + Logging.with_logger(f, logger) + end return end +# Currently unused. +# macro _error(msg) +# return quote +# $_log_if_level(() -> @error($msg), $(Logging.Error)) +# error($msg) +# end |> esc +# end -""" - _make_filtered_logger(level::Logging.LogLevel) +macro _warn(msg) + return :($_log_if_level(() -> @warn($msg), $(Logging.Warn)) )|> esc +end -Helper function to create the filtered logger for PMD -""" -function _make_filtered_logger(level) - LoggingExtras.EarlyFilteredLogger(_LOGGER) do log - if log._module == PowerModelsDistribution && log.level < level - return false - else - return true - end - end +macro _debug(msg) + return :($_log_if_level(() -> @debug($msg), $(Logging.Debug))) |> esc +end + +macro _info(msg) + return :($_log_if_level(() -> @info($msg), $(Logging.Info)) )|> esc end diff --git a/src/core/objective.jl b/src/core/objective.jl index 233dbc6a2..ae01ae4ea 100644 --- a/src/core/objective.jl +++ b/src/core/objective.jl @@ -587,7 +587,7 @@ function _calc_max_cost_index(data::Dict{String,<:Any}) max_index = max(max_index, length(gen["cost"])) end else - @warn "skipping cost generator $(i) cost model in calc_cost_order, only model 2 is supported." + @_warn "skipping cost generator $(i) cost model in calc_cost_order, only model 2 is supported." end end end diff --git a/src/core/ref.jl b/src/core/ref.jl index 8d1fea555..ac3824eeb 100644 --- a/src/core/ref.jl +++ b/src/core/ref.jl @@ -231,7 +231,7 @@ function ref_add_core!(ref::Dict{Symbol,Any}) nw_ref[:ref_buses] = ref_buses if length(ref_buses) > 1 - @debug "multiple reference buses found, $(keys(ref_buses)), this can cause infeasibility if they are in the same connected component" + @_debug "multiple reference buses found, $(keys(ref_buses)), this can cause infeasibility if they are in the same connected component" end ### aggregate info for pairs of connected buses ### diff --git a/src/core/solution.jl b/src/core/solution.jl index d39b51661..5d445a3ad 100644 --- a/src/core/solution.jl +++ b/src/core/solution.jl @@ -160,5 +160,5 @@ end does nothing (no `sol_data_model!` exists for the formulation attempting to be converted) """ function sol_data_model!(pm::AbstractUnbalancedPowerModel, solution::Dict{String,<:Any}) - @info "sol_data_model! not defined for power model of type $(typeof(pm))" + @_info "sol_data_model! not defined for power model of type $(typeof(pm))" end diff --git a/src/data_model/base/parse.jl b/src/data_model/base/parse.jl index b2d4081eb..1f9f1584e 100644 --- a/src/data_model/base/parse.jl +++ b/src/data_model/base/parse.jl @@ -29,7 +29,7 @@ function Base.parse(::Type{T}, conn::String)::T where T <: ConnConfig return DELTA end - @warn "Unsupported connection $conn, defaulting to WYE" + @_warn "Unsupported connection $conn, defaulting to WYE" return WYE end @@ -37,10 +37,10 @@ end function Base.parse(::Type{T}, model::String)::T where T <: LoadModel model = parse(Int, model) if model ∈ [3, 4, 7] - @warn "dss load model $model not supported; treating as constant POWER model" + @_warn "dss load model $model not supported; treating as constant POWER model" model = 1 elseif model == 6 - @warn "dss load model $model identical to model 1 in current feature set; treating as constant POWER model" + @_warn "dss load model $model identical to model 1 in current feature set; treating as constant POWER model" model = 1 end @@ -60,7 +60,7 @@ function Base.parse(::Type{T}, model::String)::T where T <: CapControlType elseif model == "time" return CAP_TIME else - @warn "cap control type '$(model)' unrecognized, returning CAP_DISABLED" + @_warn "cap control type '$(model)' unrecognized, returning CAP_DISABLED" return CAP_DISABLED end @@ -74,6 +74,6 @@ function Base.parse(::Type{T}, status::String)::T where T <: Status return DISABLED end - @warn "enabled code '$status' not recognized, defaulting to ENABLED" + @_warn "enabled code '$status' not recognized, defaulting to ENABLED" return ENABLED end diff --git a/src/data_model/checks.jl b/src/data_model/checks.jl index 345765903..44e394757 100644 --- a/src/data_model/checks.jl +++ b/src/data_model/checks.jl @@ -346,7 +346,7 @@ function _check_eng_component_dtypes(data_eng::Dict{String,<:Any}, component_typ end end else - @warn "$component_type $component_name does not exist" + @_warn "$component_type $component_name does not exist" end end diff --git a/src/data_model/components.jl b/src/data_model/components.jl index 971061a5b..125e27a49 100644 --- a/src/data_model/components.jl +++ b/src/data_model/components.jl @@ -83,7 +83,7 @@ function Model(model_type::DataModel=ENGINEERING; kwargs...)::Dict{String,Any} _add_unused_kwargs!(data_model["settings"], kwargs) elseif model_type == MATHEMATICAL - @warn "There are not currently any helper functions to help build a mathematical model, this will only instantiate required fields." + @_warn "There are not currently any helper functions to help build a mathematical model, this will only instantiate required fields." data_model = Dict{String,Any}( "bus" => Dict{String,Any}(), "load" => Dict{String,Any}(), diff --git a/src/data_model/multinetwork.jl b/src/data_model/multinetwork.jl index 80d3015d8..82f401eca 100644 --- a/src/data_model/multinetwork.jl +++ b/src/data_model/multinetwork.jl @@ -51,7 +51,7 @@ function make_multinetwork( )::Dict{String,Any} if ismultinetwork(data) - @info "data is already multinetwork, returning" + @_info "data is already multinetwork, returning" return data elseif iseng(data) return _make_multinetwork_eng(data; sparse=sparse, time_elapsed=time_elapsed, global_keys=global_keys) @@ -94,17 +94,17 @@ function _make_multinetwork_eng( end if eltype(times) == Any && length(unique([typeof(el) for el in times])) > 1 - @warn "Time steps in this data model are of mixed type, multinetwork frames may be out of order. You may want to manually correct this with sort_multinetwork!" + @_warn "Time steps in this data model are of mixed type, multinetwork frames may be out of order. You may want to manually correct this with sort_multinetwork!" times = [t for t in times] if ismissing(time_elapsed) - @warn "Cannot infer time_elapsed, setting to 1.0. You can manually adjust with set_time_elapsed!" + @_warn "Cannot infer time_elapsed, setting to 1.0. You can manually adjust with set_time_elapsed!" time_elapsed = 1.0 end else times = sort([t for t in times]) if ismissing(time_elapsed) if eltype(times) <: Real - @info "assuming time is in hours for time_elapsed inference. if this is incorrect, manually adjust with set_time_elapsed!" + @_info "assuming time is in hours for time_elapsed inference. if this is incorrect, manually adjust with set_time_elapsed!" time_elapsed = diff(times) push!(time_elapsed, time_elapsed[end]) else @@ -114,7 +114,7 @@ function _make_multinetwork_eng( push!(delta, delta[end]) time_elapsed = [Dates.toms(dt) / 3.6e6 for dt in delta] catch err - @warn "Cannot infer time_elapsed, setting to 1.0. You can manually adjust with set_time_elapsed!" + @_warn "Cannot infer time_elapsed, setting to 1.0. You can manually adjust with set_time_elapsed!" time_elapsed = 1.0 end end @@ -179,7 +179,7 @@ function _make_multinetwork_math( )::Dict{String,Any} @assert ismath(data_math) "wrong data model for _make_multinetwork_math" - @info "Converting a MATHEMATICAL data model into multinetwork assumes the InfrastructureModels data structure ( see https://github.com/lanl-ansi/InfrastructureModels.jl/blob/master/src/core/data.jl#L135 )" + @_info "Converting a MATHEMATICAL data model into multinetwork assumes the InfrastructureModels data structure ( see https://github.com/lanl-ansi/InfrastructureModels.jl/blob/master/src/core/data.jl#L135 )" return _IM.make_multinetwork(data_math, pmd_it_name, union(_pmd_math_global_keys, global_keys)) end diff --git a/src/data_model/transformations/dss2eng.jl b/src/data_model/transformations/dss2eng.jl index 59f4b2d96..ef2abf729 100644 --- a/src/data_model/transformations/dss2eng.jl +++ b/src/data_model/transformations/dss2eng.jl @@ -41,7 +41,7 @@ function _dss2eng_loadshape!(data_eng::Dict{String,<:Any}, data_dss::OpenDssData end if _is_loadshape_split(dss_obj) - @info "Loadshape '$id' contains mismatched pmult and qmult, splitting into `time_series` ids '$(id)_p' and '$(id)_q'" + @_info "Loadshape '$id' contains mismatched pmult and qmult, splitting into `time_series` ids '$(id)_p' and '$(id)_q'" _add_eng_obj!(data_eng, "time_series", "$(id)_p", eng_obj) eng_obj_qmult = deepcopy(eng_obj) @@ -188,7 +188,7 @@ function _dss2eng_capacitor!(data_eng::Dict{String,<:Any}, data_dss::OpenDssData _add_eng_obj!(data_eng, "shunt", id, eng_obj) else - @warn "capacitors as constant impedance elements is not yet supported, treating reactor.$id like line" + @_warn "capacitors as constant impedance elements is not yet supported, treating reactor.$id like line" _eng_obj = Dict{String,Any}( "f_bus" => _parse_bus_id(dss_obj["bus1"])[1], "t_bus" => _parse_bus_id(dss_obj["bus2"])[1], @@ -260,7 +260,7 @@ function _dss2eng_reactor!(data_eng::Dict{String,<:Any}, data_dss::OpenDssDataMo _add_eng_obj!(data_eng, "shunt", id, eng_obj) else - @warn "reactors as constant impedance elements is not yet supported, treating reactor.$id like line" + @_warn "reactors as constant impedance elements is not yet supported, treating reactor.$id like line" nphases = dss_obj["phases"] @@ -419,7 +419,7 @@ end function _dss2eng_line!(data_eng::Dict{String,<:Any}, data_dss::OpenDssDataModel, import_all::Bool) for (id, dss_obj) in get(data_dss, "line", Dict()) if haskey(dss_obj, "basefreq") && dss_obj["basefreq"] != data_eng["settings"]["base_frequency"] - @warn "basefreq=$(dss_obj["basefreq"]) on line.$id does not match circuit basefreq=$(data_eng["settings"]["base_frequency"])" + @_warn "basefreq=$(dss_obj["basefreq"]) on line.$id does not match circuit basefreq=$(data_eng["settings"]["base_frequency"])" end nphases = dss_obj["phases"] @@ -1028,7 +1028,7 @@ function parse_opendss( data_eng["settings"]["voltage_scale_factor"] = 1e3 data_eng["settings"]["power_scale_factor"] = 1e3 data_eng["settings"]["vbases_default"] = Dict{String,Real}() - dss_obj["basemva"] == 100.0 && @info "basemva=100 is the default value, you may want to adjust sbase_default for better convergence" + dss_obj["basemva"] == 100.0 && @_info "basemva=100 is the default value, you may want to adjust sbase_default for better convergence" data_eng["settings"]["sbase_default"] = dss_obj["basemva"] * 1e3 data_eng["settings"]["base_frequency"] = data_dss.options.defaultbasefrequency diff --git a/src/data_model/transformations/eng2math.jl b/src/data_model/transformations/eng2math.jl index f82208778..102600f03 100644 --- a/src/data_model/transformations/eng2math.jl +++ b/src/data_model/transformations/eng2math.jl @@ -161,10 +161,10 @@ function transform_data_model( return data_math elseif ismath(data) - @info "A MATHEMATICAL data model cannot be converted back to an ENGINEERING data model, irreversible transformations have already been made" + @_info "A MATHEMATICAL data model cannot be converted back to an ENGINEERING data model, irreversible transformations have already been made" return data else - @info "Data model '$current_data_model' is not recognized, no model type transformation performed" + @_info "Data model '$current_data_model' is not recognized, no model type transformation performed" return data end end diff --git a/src/data_model/transformations/initialization.jl b/src/data_model/transformations/initialization.jl index 92225d9fe..6bf048ff7 100644 --- a/src/data_model/transformations/initialization.jl +++ b/src/data_model/transformations/initialization.jl @@ -55,7 +55,7 @@ function calc_start_voltage( end progress = round(sum(ismissing.(values(v_start))) / length(v_start) * 100, digits=2) - @debug "it. 0:\t$(100-progress)% specified at start" + @_debug "it. 0:\t$(100-progress)% specified at start" # propogate within zones and then between them across transformers as long as progress is made # a 'zone' in this context is a collection of buses which are galvanically connected @@ -182,7 +182,7 @@ function calc_start_voltage( end end progress = round(sum(ismissing.(values(v_start))) / length(v_start) * 100, digits=2) - @debug "it. $count:\t$progress% left to initialize at end" + @_debug "it. $count:\t$progress% left to initialize at end" end # increment non-grounded zero values with epsilon diff --git a/src/data_model/transformations/rawdss2dss.jl b/src/data_model/transformations/rawdss2dss.jl index d2fdc46cd..b2823f63a 100644 --- a/src/data_model/transformations/rawdss2dss.jl +++ b/src/data_model/transformations/rawdss2dss.jl @@ -14,7 +14,7 @@ function transform_data_model(::Type{DssModel}, raw_dss::OpenDssRawDataModel)::O elseif pn == "buscoordinates" setproperty!(dss, Symbol(pn), Dict{String,DssBuscoords}(buscoords.bus => buscoords for buscoords in property)) elseif !isempty(property) && pn ∉ ["current_state", "filename", "options"] - @info "missing parser for '$pn'" + @_info "missing parser for '$pn'" end end @@ -42,7 +42,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St for (pn, v) in filter(x->x.first != "__path__", property_pairs) pn = _infer_partial_property_name(pn, dss_obj) if Symbol(pn) ∉ propertynames(dss_obj) && pn != "__path__" - @warn "$(T) has no field `$(pn)`, skipping..." + @_warn "$(T) has no field `$(pn)`, skipping..." continue end @@ -64,7 +64,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St for (pn, v) in filter(x->x.first != "__path__", property_pairs) pn = _infer_partial_property_name(pn, dss_obj) if Symbol(pn) ∉ propertynames(dss_obj) && pn != "__path__" - @warn "$(T) has no field `$(pn)`, skipping..." + @_warn "$(T) has no field `$(pn)`, skipping..." continue end if pn == "like" @@ -73,7 +73,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St elseif v in keys(getproperty(dss_raw, obj_type)) like_dss_obj = create_dss_object(T, getproperty(dss_raw, obj_type)[v], dss, dss_raw) else - @warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" + @_warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" continue end merge!(dss_obj, like_dss_obj) @@ -98,7 +98,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St for (pn, v) in filter(x->x.first != "__path__", property_pairs) pn = _infer_partial_property_name(pn, dss_obj) if Symbol(pn) ∉ propertynames(dss_obj) && pn != "__path__" - @warn "$(T) has no field `$(pn)`, skipping..." + @_warn "$(T) has no field `$(pn)`, skipping..." continue end if pn == "like" @@ -107,7 +107,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St elseif v in keys(getproperty(dss_raw, obj_type)) like_dss_obj = create_dss_object(T, getproperty(dss_raw, obj_type)[v], dss, dss_raw) else - @warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" + @_warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" continue end merge!(dss_obj, like_dss_obj) @@ -138,7 +138,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St for (pn, v) in property_pairs pn = _infer_partial_property_name(pn, dss_obj) if Symbol(pn) ∉ propertynames(dss_obj) && pn != "__path__" - @warn "$(T) has no field `$(pn)`, skipping..." + @_warn "$(T) has no field `$(pn)`, skipping..." continue end @@ -152,7 +152,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St elseif v in keys(getproperty(dss_raw, obj_type)) like_dss_obj = create_dss_object(T, getproperty(dss_raw, obj_type)[v], dss, dss_raw) else - @warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" + @_warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" continue end merge!(dss_obj, like_dss_obj) @@ -212,7 +212,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St for (pn, v) in property_pairs pn = _infer_partial_property_name(pn, dss_obj) if Symbol(pn) ∉ propertynames(dss_obj) && pn != "__path__" - @warn "$(T) has no field `$(pn)`, skipping..." + @_warn "$(T) has no field `$(pn)`, skipping..." continue end @@ -226,7 +226,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St elseif v in keys(getproperty(dss_raw, obj_type)) like_dss_obj = create_dss_object(T, getproperty(dss_raw, obj_type)[v], dss, dss_raw) else - @warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" + @_warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" continue end merge!(dss_obj, like_dss_obj) @@ -265,7 +265,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St _wdg = windings for (pn, v) in filter(x->x.first != "__path__", property_pairs) if Symbol(pn) ∉ propertynames(dss_obj) && pn != "__path__" - @warn "$(T) has no field `$(pn)`, skipping..." + @_warn "$(T) has no field `$(pn)`, skipping..." continue end @@ -275,7 +275,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St elseif v in keys(getproperty(dss_raw, obj_type)) like_dss_obj = create_dss_object(T, getproperty(dss_raw, obj_type)[v], dss, dss_raw) else - @warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" + @_warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" continue end merge!(dss_obj, like_dss_obj) @@ -311,7 +311,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St _cond = 1 for (pn, v) in filter(x->x.first != "__path__", property_pairs) if Symbol(pn) ∉ propertynames(dss_obj) && pn != "__path__" - @warn "$(T) has no field `$(pn)`, skipping..." + @_warn "$(T) has no field `$(pn)`, skipping..." continue end @@ -321,7 +321,7 @@ function _apply_property_pairs(dss_obj::T, property_pairs::Vector{Pair{String,St elseif v in keys(getproperty(dss_raw, obj_type)) like_dss_obj = create_dss_object(T, getproperty(dss_raw, obj_type)[v], dss, dss_raw) else - @warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" + @_warn "$(obj_type).$(v) does not exist, can't apply 'like' on $(obj_type).$(getproperty(dss_obj, :name))" continue end merge!(dss_obj, like_dss_obj) diff --git a/src/data_model/units.jl b/src/data_model/units.jl index d7dfac219..9b31e04d4 100644 --- a/src/data_model/units.jl +++ b/src/data_model/units.jl @@ -102,7 +102,7 @@ function make_per_unit!( end end else - @warn "Data model '$data_model_type' is not recognized, no per-unit transformation performed" + @_warn "Data model '$data_model_type' is not recognized, no per-unit transformation performed" end end @@ -215,7 +215,7 @@ function _calc_voltage_bases(data_model::Dict{String,<:Any}, vbase_sources::Dict zone_vbase = Dict{Int, Union{Missing,Real}}([(zone,missing) for zone in keys(zones)]) for (bus,vbase) in vbase_sources if !ismissing(zone_vbase[bus_to_zone[bus]]) - @warn "You supplied multiple voltage bases for the same zone; ignoring all but the last one." + @_warn "You supplied multiple voltage bases for the same zone; ignoring all but the last one." end zone_vbase[bus_to_zone[bus]] = vbase end diff --git a/src/data_model/utils.jl b/src/data_model/utils.jl index 806efbe5a..b35d155fd 100644 --- a/src/data_model/utils.jl +++ b/src/data_model/utils.jl @@ -27,7 +27,7 @@ ismath(data::InfrastructureModel) = false **Hacky** helper function to transform single-conductor network data, from, e.g., matpower/psse, into multi-conductor data. """ function make_multiconductor!(data::Dict{String,<:Any}, conductors::Int) - @info "This function is not meant to be an officially supported method for creating reasonable multiconductor data sets" + @_info "This function is not meant to be an officially supported method for creating reasonable multiconductor data sets" if ismultinetwork(data) for (i,nw_data) in data["nw"] _make_multiconductor!(nw_data, conductors) @@ -41,7 +41,7 @@ end "Hacky helper function to transform single-conductor network data, from, e.g., matpower/psse, into multi-conductor data" function _make_multiconductor!(data::Dict{String,<:Any}, conductors::Real) if haskey(data, "conductor_ids") - @warn "skipping network that is already multiconductor" + @_warn "skipping network that is already multiconductor" return end diff --git a/src/form/bf_mx_lin.jl b/src/form/bf_mx_lin.jl index 6891e1e45..10a440207 100644 --- a/src/form/bf_mx_lin.jl +++ b/src/form/bf_mx_lin.jl @@ -533,7 +533,7 @@ This method is not yet implemented for AbstractLPUBFModel. If the limit is finite, a warning is thrown. """ function constraint_mc_switch_thermal_limit(pm::AbstractLPUBFModel, nw::Int, f_idx::Tuple{Int,Int,Int}, f_connections::Vector{Int}, rating::Vector{Float64}) - @warn "Encountered a finite switch thermal limit; these are not yet implemented for AbstractLPUBFModel." + @_warn "Encountered a finite switch thermal limit; these are not yet implemented for AbstractLPUBFModel." end diff --git a/src/form/en_ivr.jl b/src/form/en_ivr.jl index 6ada2a75f..d626ed578 100644 --- a/src/form/en_ivr.jl +++ b/src/form/en_ivr.jl @@ -1486,7 +1486,7 @@ without introducing explicit power variables. """ function constraint_mc_thermal_limit_from(pm::AbstractQuadraticExplicitNeutralIVRModel, nw::Int, f_idx::Tuple{Int,Int,Int}, f_connections::Vector{Int}, rate_a::Vector{<:Real}) if any(rate_a. 1 - @warn "'$expr' is not valid Reverse Polish Notation, leaving as String" + @_warn "'$expr' is not valid Reverse Polish Notation, leaving as String" return expr else return stack[1] @@ -203,20 +203,20 @@ function _bank_transformers!(data_eng::Dict{String,<:Any}) props = ["bus", "noloadloss", "xsc", "rw", "cmag", "vm_nom", "sm_nom", "polarity", "configuration", "sm_ub"] btrans = Dict{String, Any}(prop=>trs[1][prop] for prop in props) if !all(tr[prop]==btrans[prop] for tr in trs, prop in props) - @warn "Not all across-phase properties match among transfomers identified by bank='$bank', aborting attempt to bank" + @_warn "Not all across-phase properties match among transfomers identified by bank='$bank', aborting attempt to bank" continue end nrw = length(btrans["bus"]) # only attempt to bank wye-connected transformers if !all(all(conf==WYE for conf in tr["configuration"]) for tr in trs) - @warn "Not all configurations 'wye' on transformers identified by bank='$bank', aborting attempt to bank" + @_warn "Not all configurations 'wye' on transformers identified by bank='$bank', aborting attempt to bank" continue end neutrals = [conns[end] for conns in trs[1]["connections"]] # ensure all windings have the same neutral if !all(all(conns[end]==neutrals[w] for (w, conns) in enumerate(tr["connections"])) for tr in trs) - @warn "Not all neutral phases match on transfomers identified by bank='$bank', aborting attempt to bank" + @_warn "Not all neutral phases match on transfomers identified by bank='$bank', aborting attempt to bank" continue end @@ -346,7 +346,7 @@ function _get_conductors_ordered(busname::AbstractString; default::Vector{Int}=I end if check_length && length(default)!=length(ret) - @info "An inconsistent number of nodes was specified on $(parts[1]); |$(parts[2])|!=$(length(default))." + @_info "An inconsistent number of nodes was specified on $(parts[1]); |$(parts[2])|!=$(length(default))." end return ret @@ -472,7 +472,7 @@ function _add_eng_obj!(data_eng::Dict{String,<:Any}, eng_obj_type::String, eng_o end if haskey(data_eng[eng_obj_type], eng_obj_id) - @warn "id '$eng_obj_id' already exists in $eng_obj_type, renaming to '$(eng_obj["source_id"])'" + @_warn "id '$eng_obj_id' already exists in $eng_obj_type, renaming to '$(eng_obj["source_id"])'" eng_obj_id = eng_obj["source_id"] end diff --git a/src/prob/common.jl b/src/prob/common.jl index d0f9ea408..70329398e 100644 --- a/src/prob/common.jl +++ b/src/prob/common.jl @@ -42,7 +42,7 @@ function _solve_mc_model( multinetwork=multinetwork, kwargs... ) - @debug "pm model build time: $(time() - start_time)" + @_debug "pm model build time: $(time() - start_time)" start_time = time() result = optimize_model!( @@ -51,7 +51,7 @@ function _solve_mc_model( optimizer=optimizer, solution_processors=solution_processors ) - @debug "pm model solve and solution time: $(time() - start_time)" + @_debug "pm model solve and solution time: $(time() - start_time)" return result end @@ -105,7 +105,7 @@ function instantiate_mc_model( ) if iseng(data) - @info "Converting ENGINEERING data model to MATHEMATICAL first to build JuMP model" + @_info "Converting ENGINEERING data model to MATHEMATICAL first to build JuMP model" data = transform_data_model( data; multinetwork=multinetwork, diff --git a/src/prob/native_pf.jl b/src/prob/native_pf.jl index 60ea74b3a..27e4763e9 100644 --- a/src/prob/native_pf.jl +++ b/src/prob/native_pf.jl @@ -212,9 +212,9 @@ Takes data in either the ENGINEERING or MATHEMATICAL model, a model type (_e.g._ and model builder function (_e.g._, [`build_mc_opf`](@ref build_mc_opf)), and returns a solution in the original data model defined by `data`. -Technical description of the native power flow can be found at https://arxiv.org/abs/2305.04405 where implementation fo the -fixed-point current injection algorithm, inspired by the existing open-source implementation in OpenDSS. -The current injection method is commonly conceived as a system of nonlinear equalities solved by Newton’s method. +Technical description of the native power flow can be found at https://arxiv.org/abs/2305.04405 where implementation fo the +fixed-point current injection algorithm, inspired by the existing open-source implementation in OpenDSS. +The current injection method is commonly conceived as a system of nonlinear equalities solved by Newton’s method. However, the fixed point iteration variant commonly outperforms most methods, while supporting meshed topologies from the ground up If `make_si` is false, data will remain in per-unit. @@ -324,14 +324,14 @@ function _compute_mc_pf( end else nw_dm = data_math["nw"] - @warn("The native power flow solver may not be accurate to the tolerance of 1E-6") + @_warn("The native power flow solver may not be accurate to the tolerance of 1E-6") for (b, branch) in data_math["nw"]["1"]["branch"] append!(br_sizes, size(branch["br_r"], 1)) end end if maximum(br_sizes) > 4 - @warn("Line impedance matrices should be up to 4x4, but go up to $(maximum(br_sizes))x$(maximum(br_sizes))") + @_warn("Line impedance matrices should be up to 4x4, but go up to $(maximum(br_sizes))x$(maximum(br_sizes))") end sol = Dict{String,Any}() diff --git a/src/prob/opf.jl b/src/prob/opf.jl index 923bca408..ed4fe1840 100644 --- a/src/prob/opf.jl +++ b/src/prob/opf.jl @@ -688,7 +688,7 @@ function build_mn_mc_opf(pm::AbstractExplicitNeutralIVRModel) end if !isempty(ids(pm, n, :storage)) - @warn "This formulation lacks support for storage components." + @_warn "This formulation lacks support for storage components." end for i in ids(pm, n, :bus) diff --git a/test/opendss.jl b/test/opendss.jl index 415d81e45..81de07336 100644 --- a/test/opendss.jl +++ b/test/opendss.jl @@ -28,13 +28,28 @@ @test PMD._isa_rpn("2 pi * 60 * .001 *") @test !PMD._isa_rpn("[ 2 10 ]") - @test_logs (:warn, "_parse_rpn does not support 'rollup', 'rolldn', or 'swap', leaving as String") match_mode=:any PowerModelsDistribution._parse_rpn("1 2 swap atan2") - @test_logs (:warn, "' 1 2 + - ' is not valid Reverse Polish Notation, leaving as String") match_mode=:any PowerModelsDistribution._parse_rpn(" 1 2 + - ") - @test_logs (:warn, "'1 2 3 +' is not valid Reverse Polish Notation, leaving as String") match_mode=:any PowerModelsDistribution._parse_rpn("1 2 3 +") + _test_logs( + () -> PowerModelsDistribution._parse_rpn("1 2 swap atan2"), + (:warn, "_parse_rpn does not support 'rollup', 'rolldn', or 'swap', leaving as String"), + ) + _test_logs( + () -> PowerModelsDistribution._parse_rpn(" 1 2 + - "), + (:warn, "' 1 2 + - ' is not valid Reverse Polish Notation, leaving as String"), + ) + _test_logs( + () -> PowerModelsDistribution._parse_rpn("1 2 3 +"), + (:warn, "'1 2 3 +' is not valid Reverse Polish Notation, leaving as String"), + ) end @testset "opendss parse load model warnings" begin - @test_logs (:warn, "dss load model 3 not supported; treating as constant POWER model") (:warn, "dss load model 6 identical to model 1 in current feature set; treating as constant POWER model") (:warn, "dss load model 7 not supported; treating as constant POWER model") (:warn, "dss load model 4 not supported; treating as constant POWER model") match_mode=:any parse_file("../test/data/opendss/loadparser_warn_model.dss") + _test_logs( + () -> parse_file("../test/data/opendss/loadparser_warn_model.dss"), + (:warn, "dss load model 3 not supported; treating as constant POWER model"), + (:warn, "dss load model 6 identical to model 1 in current feature set; treating as constant POWER model"), + (:warn, "dss load model 7 not supported; treating as constant POWER model"), + (:warn, "dss load model 4 not supported; treating as constant POWER model"), + ) end @testset "opendss parse spectrum objects" begin @@ -49,7 +64,16 @@ @testset "opendss parse generic warnings and errors" begin @test_throws ErrorException parse_file("../test/data/opendss/test_simple2.dss"; data_model=MATHEMATICAL) - @test_logs (:info, "Command 'solve' on line 70 in 'test2_master.dss' is not supported, skipping.") (:info, "Command 'show' on line 72 in 'test2_master.dss' is not supported, skipping.") (:warn, "reactors as constant impedance elements is not yet supported, treating reactor.reactor1 like line") (:warn, "line.something does not exist, can't apply 'like' on line.l1") (:info, "Circuit has been reset with the 'clear' on line 2 in 'test2_master.dss'") (:info, "Redirecting to 'test2_linecodes.dss' on line 10 in 'test2_Linecodes.dss'") (:info, "Redirecting to 'test2_loadshape.dss' on line 11 in 'test2_Linecodes.dss'") match_mode=:any parse_file("../test/data/opendss/test2_master.dss") + _test_logs( + () -> parse_file("../test/data/opendss/test2_master.dss"), + (:info, "Command 'solve' on line 70 in 'test2_master.dss' is not supported, skipping."), + (:info, "Command 'show' on line 72 in 'test2_master.dss' is not supported, skipping."), + (:warn, "reactors as constant impedance elements is not yet supported, treating reactor.reactor1 like line"), + (:warn, "line.something does not exist, can't apply 'like' on line.l1"), + (:info, "Circuit has been reset with the 'clear' on line 2 in 'test2_master.dss'"), + (:info, "Redirecting to 'test2_linecodes.dss' on line 10 in 'test2_Linecodes.dss'"), + (:info, "Redirecting to 'test2_loadshape.dss' on line 11 in 'test2_Linecodes.dss'"), + ) end raw_dss = parse_raw_dss("../test/data/opendss/test2_master.dss") diff --git a/test/runtests.jl b/test/runtests.jl index 167b4f52b..9cf0e35c8 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -10,6 +10,7 @@ import Ipopt import SCS import JSON +import Logging using Test using LinearAlgebra @@ -23,6 +24,21 @@ scs_solver = optimizer_with_attributes(SCS.Optimizer, "verbose"=>0) include("common.jl") include("test_cases.jl") +function _test_logs(f, args...) + log_msg = sprint() do io + old_logger = PowerModelsDistribution._LOGGER[] + PowerModelsDistribution._LOGGER[] = + Logging.ConsoleLogger(io, Logging.Debug) + f() + PowerModelsDistribution._LOGGER[] = old_logger + return + end + for (type, msg) in args + @test occursin(type == :warn ? "Warning: $msg" : "Info: $msg", log_msg) + end + return +end + @testset "PowerModelsDistribution" begin include("opendss.jl") From e4ca9ac6cf042720f75e643445959e154b9a532f Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Tue, 14 Apr 2026 15:34:26 +1200 Subject: [PATCH 2/2] UPD: update versions in GitHub actions --- .github/workflows/ci.yml | 33 ++++++++++++++--------------- .github/workflows/documentation.yml | 2 +- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 431f4b036..aaf859cf8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,14 @@ name: CI on: - - push - - pull_request + push: + branches: + - main + pull_request: + types: [opened, synchronize, reopened] +# needed to allow julia-actions/cache to delete old caches that it has created +permissions: + actions: write + contents: read jobs: test: if: "!contains(github.event.head_commit.message, 'skip ci')" @@ -11,7 +18,7 @@ jobs: fail-fast: false matrix: version: - - '1.6' + - '1.10' - '1' - 'nightly' os: @@ -21,26 +28,18 @@ jobs: arch: - x64 steps: - - uses: actions/checkout@v3 - - uses: julia-actions/setup-julia@v1 + - uses: actions/checkout@v6 + - uses: julia-actions/setup-julia@v2 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v3 - env: - cache-name: cache-artifacts - with: - path: ~/.julia/artifacts - key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }} - restore-keys: | - ${{ runner.os }}-test-${{ env.cache-name }}- - ${{ runner.os }}-test- - ${{ runner.os }}- + - uses: julia-actions/cache@v3 - uses: julia-actions/julia-buildpkg@latest continue-on-error: ${{ matrix.version == 'nightly' }} - uses: julia-actions/julia-runtest@latest continue-on-error: ${{ matrix.version == 'nightly' }} - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v3 + - uses: codecov/codecov-action@v6 with: - file: lcov.info + files: lcov.info + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index f6afdb0f4..9bbf4dc33 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -11,7 +11,7 @@ jobs: name: Documentation runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6 - uses: julia-actions/setup-julia@latest with: version: '1'