Giter Club home page Giter Club logo

opendssdirect.jl's Introduction

OpenDSSDirect.jl

GitHub Actions: Tests

OpenDSSDirect.jl is a cross-platform Julia package implements a "direct" library interface to OpenDSS using DSS C-API, an alternative implementation.

OpenDSS is an open-source distribution system simulator.

Originally, the package used the OpenDSSDirect library from the official OpenDSS repository. Since OpenDSS is officially Windows-only, this package was migrated to use DSS C-API in 2019. The DSS C-API library is a community implementation of the OpenDSS engine built with the Free Pascal compiler, targeting cross-platform compatibility and an extended API. See its repository here for the full Pascal/Delphi code, or https://dss-extensions.org/ for an overview of the projects around it.

For a general FAQ and many other links, see https://github.com/dss-extensions/dss-extensions#readme

See also OpenDSSDirect.py for a package in Python with similar calling style, or DSS-Python, DSS_MATLAB and dss_sharp for packages that mimic the OpenDSS COM API organization and style.

This package is available for Windows, macOS (x86 and ARM processors), and Linux (x86 and ARM processors).

Documentation

The documentation for the development version of this package is here.

We also recommend reading the known differences document from DSS C-API, which lists the notable behavior differences versus the official OpenDSS engine.

An up-to-date reference of the properties on the level of the DSS language is also available.

Installation

Use the Julia package manager to install OpenDSSDirect

julia> ]
(v1.1)> add OpenDSSDirect

Troubleshooting

This package interfaces with the OpenDSS engine using a library interface, so a good understanding of OpenDSS will help troubleshooting. There are plenty of useful resources located here. If you have experience with the official OpenDSS COM implementation, the following document compares our two Python modules, DSS-Python (same structure as the OpenDSS COM module) and OpenDSSDirect.py (similar structure to OpenDSSDirect.jl): DSS-Extensions — OpenDSS: Overview of Python APIs.

If you are having issues using this Julia interface, feel free to open an Issue on GitHub here or post at our general Discussions page.

Thanks

Thanks to @tshort for the original package.
Thanks to @kdheepak, @PMeira and @GordStephen for their contributions.

opendssdirect.jl's People

Contributors

fbinot avatar gordstephen avatar juliatagbot avatar kdheepak avatar michaelhatherly avatar pmeira avatar staticfloat avatar tshort avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opendssdirect.jl's Issues

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Solving iterative power flow by changing the generator outputs on the fly

Hi, I am trying to do a sensitivity analysis study by running the following example script where I first solve the original circuit with base parameters. I want to increase the generator's output by a given rate and then solve the power flow again for the second time with a new generation increment. After each solve, I collect the voltages to calculate voltage sensitivities.

It seems the generator output is not being set by DSS.Generators.kW(DSS.Generators.kW()*rate), and I am getting the same voltage values.

Is there any other thing that I am missing in the code or a better way to do this analysis with the .jl interface?

DSS.Text.Command( string("Compile"," ",main_path,"/Master.dss") );
DSS.Text.Command( string("set controlmode=OFF") );

# Run the first power flow
DSS.Solution.Mode(0) # set solution mode as snap=>0, daily=>1
DSS.Solution.Solve()
println( DSS.Solution.Converged()==true ? "SOLVED" : "NOT SOLVED" )
v0 = DSS.Circuit.AllBusMagPu() # Record voltage profile
println(DSS.Generators.kW())

# Run the second power flow by incresing the generator output by a rate
DSS.Generators.kW(DSS.Generators.kW()*rate)
println(DSS.Generators.kW())

DSS.Solution.Mode(0) # set solution mode as snap=>0, daily=>1
DSS.Solution.Solve()
println( DSS.Solution.Converged()==true ? "SOLVED" : "NOT SOLVED" )

v1 = DSS.Circuit.AllBusMagPu() #

Migrate from Travis-CI

I'm preparing a maintenance release in the coming days. With the recent Travis-CI changes, we need to move the testing process.

Some options are:

  • Move to GitHub actions. It seems easy enough and there are a bunch of Actions available on the marketplace (from https://github.com/julia-actions). There's also https://github.com/marketplace/actions/run-travis-yml but that's not really needed for Julia. Note that TagBot is installed as a GitHub action already. Downsides: more dependency on GitHub.
  • Consolidate on AppVeyor, which nowadays supports MacOS too. Downsides: it's probably the slower solution (1 concurrent job).
  • Circle-CI? Downsides: credits for macOS are limited but should still be enough (they also changed how their billing works in 2020 but the open-source support is way better than the current Travis-CI scenario).
  • GitLab also offers some free minutes.
  • If the situation keeps changing in the future, we could move to self-hosted GitLab workers. I could easily host Windows and Linux workers, but not macOS. Downsides: potentially more maintenance, security concerns.

For ODD.jl, I'm considering just moving to GitHub actions since the tests are simple enough. I'll give it a try tomorrow.

By the way, support for Apple M1 seems overall limited for everything at the moment. We'll need to revisit that later. On the medium term, I suspect the main issue will be building the Pascal library. There is general support in FPC but also specific bugs. I imagine it probably won't be fully released for a while.

DocStringExtensions Compatibility

I'm trying to use OpenDSSDirect in tandem with the FMIImport.jl. Due to some bugfixes I need the latest version 15.6 of that package, but this results in a non-resolvable environment due to the compatibility requirements between OpenDSS and DocStringExtensions.

If I install OpenDSSDirect locally and allow DocStringExtensions 0.9 in the Project.toml the conflict is resolved. OpenDSSDirect tests also pass in this case. Would it be possible to modify the Project.toml?

CI: Address warnings from GitHub Actions

  1. More urgent, but should be trivial to update:
Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: actions/checkout@v3, julia-actions/setup-julia@v1, codecov/codecov-action@v1. For more information see: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/.
  1. New warning just now:
[julia-buildpkg] Caching of the julia depot was not detected
Consider using `julia-actions/cache` to speed up runs https://github.com/julia-actions/cache. To ignore, set input `ignore-no-cache: true`

Different values on `Circuit.YCurrents()`

Hi!

Maybe I'm missing something, but I was making a test and found a difference between currents get from Circuit.YCurrents() and what they should be. Here is an example:

DSS File
Just a 3-bus 13.8kV balanced system with one 1MW/0.5MVAr 3ph load.

// main.dss
new   circuit.test  basekv=13.8 bus1=SOURCEBUS   pu=1.0 MVAsc3=999999 MVAsc1=999999

New   Line.Line_1   bus1=SOURCEBUS   bus2=BUS_1 R1=3.0 X1=3.0 Length=1.0

New   Line.Line_2   bus1=BUS_1   bus2=BUS_2 R1=3.0 X1=3.0 Length=1.0

New   Load.Load_1   phases=3   conn=Wye   bus1=BUS_2   kw=1000   kvar=500   model=1 kV=13.8

Set Voltagebases=[13.8]

The Julia file

using OpenDSSDirect
using Test
dss("""
    clear
    redirect main.dss
    solve   
""")
nodes = Circuit.YNodeOrder()
I = Circuit.YCurrents()
V = Circuit.YNodeVArray()
S = V.*conj.(I)

println(nodes[end]) # BUS_2.3
# Power injected by the load in the node BUS_2.3
P_MW = real(S[end])/1e6 
Q_MVAr = imag(S[end])/1e6

# The system nearly balanced, so we can just multiply by 3.
P_load = P_MW*3
Q_load = Q_MVAr*3

# So, the load calculated must have the same power as the .dss file
@test P_load  -1.0 atol = 0.1 # This causes a error because P_load = -0.09716 not -1.0
@test Q_load  -0.5 atol = 0.1 # This causes a error because P_load = -0.04858 not -0.5

Once run this code, the power injected is not the same as the load. Actually, you "need" to multiply the current by 10 to get the same values of the calculated.

Am I missing something? If yes, why the value of Circuit.YCurrents() is 10 times less than it should be?

How to access attributes of multiple circuit elements?

I am trying to access a specific generator element to set/get its attribute values. When I defined multiple generators and wanted to set/get their attributes individually or collectively. The DSS.Generator.Function() only sets/gets the information that belongs to the last generator defined in the DSS file. For example I define two generators in the system as

New` Generator.GEN671  Bus1=671  kV=4.16 kW=200 Pf=1  Model=1 conn=3
New Generator.GEN680  Bus1=680  kV=4.16 kW=100 Pf=0.95  Model=1 conn=3 

After compiling the circuit, and using DSS.Generator.kW(), it only returns 100 which is GEN680's kWrating. I have also tried

DSS.Circuit.SetActiveElement("GEN671")
DSS.Generators.kW()

it does not get the specified generator's kW rating attribute.

Is there any function equivalent that I can use as follows?
DSSObj.ActiveCircuit.CktElements('GEN680'); => API function DSS.Circuit.SetActiveElement("GEN671")
DSSObj.ActiveCircuit.ActiveDSSElement.Properties('kW').Val => ???

Build error with Julia-1.3.0 on Windows

I'm getting a build error in when trying to build OpenDSSDirect.jl with Julia-1.3.0 on Windows:

┌ Error: Error building `OpenDSSDirect`: 
│ ERROR: LoadError: IOError: could not spawn `'C:\Users\username\AppData\Local\Julia-1.3.0\bin/7z' x 'C:\Users\username\.julia\packages\OpenDSSDirect\wldy1\deps\dss_capi.zip' -y '-oC:\Users\username\.julia\packages\OpenDSSDirect\wldy1\deps'`: no such file or directory (ENOENT)
│ Stacktrace:
│  [1] _spawn_primitive(::String, ::Cmd, ::Array{Any,1}) at .\process.jl:99
│  [2] setup_stdios(::Base.var"#554#555"{Cmd}, ::Array{Any,1}) at .\process.jl:112
│  [3] success(::Cmd) at .\process.jl:111
│  [4] download(::Type{Windows}) at C:\Users\username\.julia\packages\OpenDSSDirect\wldy1\deps\build.jl:64
│  [5] top-level scope at C:\Users\username\.julia\packages\OpenDSSDirect\wldy1\deps\build.jl:84
│  [6] include at .\boot.jl:328 [inlined]
│  [7] include_relative(::Module, ::String) at .\loading.jl:1105
│  [8] include(::Module, ::String) at .\Base.jl:31
│  [9] include(::String) at .\client.jl:424
│  [10] top-level scope at none:5
│ in expression starting at C:\Users\username\.julia\packages\OpenDSSDirect\wldy1\deps\build.jl:84
│ url = "https://github.com/dss-extensions/dss_capi/releases/download/0.10.1/dss_capi_0.10.1_win_x64.zip"
└ @ Pkg.Operations D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.3\Pkg\src\backwards_compatible_isolation.jl:649

This may be related to 7z having been moved in Julia-1.3.0: JuliaLang/julia#33493

Multiple DSS contexts

DSS C-API 0.12 supports creating multiple DSS instances that can be used separately, in threads, etc.

Should we expose this in ODD.jl? If so, what would be the best approach?

Inconsistent casing in Lines and LineCodes for rmatrix, xmatrix and cmatrix

Currently the ODD interface exposes the following functions:

Lines.RMatrix
LineCodes.Rmatrix

Lines.XMatrix
LineCodes.Xmatrix

Lines.CMatrix
LineCodes.Cmatrix

It would be nice if these are consistent. @tshort, @PMeira any preferences?

The C API uses Lines_Get_Rmatrix, LineCodes_Get_Rmatrix, etc. So my vote is to use the same casing, i.e. change the functions in the Lines module. I believe the COM interface in the official distribution also uses this casing here.

The main reason I'm opening an issue for this is that this is technically an API breaking change, so it would require a major version update. But given that v0.5.0 hasn't been updated on the METADATA.jl yet, it might be safe to assume no one is using the tagged v0.5.0 version yet and maybe we can get away with the change in v0.5.1. Thoughts?

Alternatively, we can go with deprecation warnings and remove the other functions in the next major release.

Docs: split `api.md`

The generated HTML is beyond the default size threshold and running newer Documenter versions result in an error. I'm setting it to ignore that, but we should probably split that file.

This is not an urgent issue; more of an SEO issue than anything.

New release?

I am trying to use the Pmpp parameter for PVsystems. It seems that it is not supported in the last release but it is added on Master. Could you release new version?

Thank you!

Julia v1.1.0 - Installation Error

Only the development version can be installed.

When I try to install the stable version:

julia> VERSION
v"1.1.0"
julia> Pkg.add("OpenDSSDirect")
 Resolving package versions...
ERROR: Unsatisfiable requirements detected for package OpenDSSDirect [a8b11937]:
 OpenDSSDirect [a8b11937] log:
 ├─possible versions are: [0.1.0-0.1.1, 0.2.0, 0.3.1-0.3.2, 0.4.0] or uninstalled
 ├─restricted to versions * by an explicit requirement, leaving only versions [0.1.0-0.1.1, 0.2.0, 0.3.1-0.3.2, 0.4.0]
 └─restricted by julia compatibility requirements to versions: uninstalled — no versions

Minimal test coverage

Since there have been several new modules added both through our own API extensions and ported from the official OpenDSS, we need to add a lot more tests to achieve some minimum coverage of the new features.

Bus voltage problem

Julia_code.zip

Hello,
I am a new user of OpenDSS with Julia. I previously use with Matlab.
I develop a small network Network000.dss. This network is managed by a DSS file Network_master.dss. When I run it on OpenDSS, the network is solved and I get the voltage profile.

I develop a similar code main_julia.jl in Julia. This code should give me bus voltage but I only receive zero for all the LV bus.
I tested main_julia.jl with Master.dss of 8500bus network and I receive good values (non-zero voltages). I tested my
code in Vscode and Juno with same results.

Juno_display

All the data are available in the Zip folder Julia_code.zip. I don't understand what I am doing wrong.
Regards,
Fbinot

parsing error of transformer xhl vs x12 parameters in circuit.ToJSON()

I'm not sure if this is the right repository to report this problem, but it looks like the circuit.ToJSON function of OpenDSSDirect will ignore transformer parameters xhl, xht, and xlt, thus setting these parameters to their default values. But it will recognize the alternative versions of the parameters, x12, x13, and x23.

An example DSS file comes from the test sets of PowerModelsDistribtion, given below. Saving this as a file and using the script below to generate a JSON object, the object has default values for xhl, xht, and xlt of transformer [1], rather than zeros. Changing the DSS file to use x12=0, x13=0, and x23=0 instead results in a JSON object with the correct (zero) values.

Julia Script, where the DSS file is saved as filename.dss:

import OpenDSSDirect as DSS
DSS.Basic.AllowEditor(false)
DSS.dss("""
    clear
    redirect "filename.dss"
    """)
ckt = DSS.Circuit.ToJSON(Int32(1)|Int32(4)|Int32(32)|Int32(64)|Int32(128)|Int32(512))
println("xlt= ", ckt["transformer"][1]["xlt"])  # should be 0.0

DSS script:

clear

! Base Frequency
Set DefaultBaseFrequency=50

! New Circuit
New circuit.ut_trans
~ BasekV=11 BaseMVA=0.1 pu=1.0  ISC3=9999999999 ISC1=9999999999

! Transformers
New Transformer.TX1 windings=3 phases=3 Buses=[1 2 3]
~ Conns=[Delta Wye Wye]
~ kVs=[11 4 0.4]
~ kVAs=[500 500 500]
~ %Rs=[0 0 0]
~ xhl=0 xht=0 xlt=0
~ %noloadloss=0
~ %imag=0
~ leadlag=lead

! Transmission Lines
New Line.LINE1 Bus1=SourceBus Bus2=1 phases=3 X1=3 R1=6

! Loads
New Load.LOAD1 Phases=1 Bus1=2.1 kV=2.30 kW=43 kvar=76 vminpu=0.8 vmaxpu=1.2
New Load.LOAD2 Phases=1 Bus1=2.2 kV=2.30 kW=52 kvar=85 vminpu=0.8 vmaxpu=1.2
New Load.LOAD3 Phases=1 Bus1=2.3 kV=2.30 kW=61 kvar=94 vminpu=0.8 vmaxpu=1.2
New Load.LOAD4 Phases=1 Bus1=3.1 kV=0.23 kW=74 kvar=41 vminpu=0.8 vmaxpu=1.2
New Load.LOAD5 Phases=1 Bus1=3.2 kV=0.23 kW=85 kvar=52 vminpu=0.8 vmaxpu=1.2
New Load.LOAD6 Phases=1 Bus1=3.3 kV=0.23 kW=96 kvar=63 vminpu=0.8 vmaxpu=1.2
New Load.LOAD7 Phases=1 Bus1=1.3 kV=6.351 kW=205 kvar=185 vminpu=0.8 vmaxpu=1.2

! Set Voltage Bases
Set voltagebases=[11  4 0.4]
Calcvoltagebases

! Solve network
solve

Enums and bitmasks

A few enumerations are used in bitmasks or mixed enum+mask. Currently, CEnum doesn't allow this.

An interim fix was added for Monitors.Mode in #75 (just allow integers without restricting to the enum values), but a more elegant solution would be better. I also noticed a few projects vendor CEnum and modify it, for example https://github.com/JuliaGPU/VulkanCore.jl/pull/17/files

Looking for alternative packages, so far I found https://github.com/jmert/BitFlags.jl
Should we adopt it here?

Segmentation fault in getYsparse() on Mac

Hi @tshort,

Do you happen to know why there is a segfault when calling getYsparse on a Mac? This line results in this function never being called in the examples and hence the tests all pass. When I try calling this function it segfaults, the stack trace is below.

julia> Y = DSSCore.getYsparse()

signal (11): Segmentation fault: 11
while loading no file, in expression starting on line 0
_ZN9KLUSystem12FactorSystemEv at ~/.julia/v0.6/OpenDSSDirect/deps/apple/libklusolve.dylib (unknown line)
FactorSparseMatrix at ~/.julia/v0.6/OpenDSSDirect/deps/apple/libklusolve.dylib (unknown line)
Allocations: 3872081 (Pool: 3870540; Big: 1541); GC: 6
[1]    90509 segmentation fault  julia

The segfault happens when InitAndGetYParams is called. I get the same segfault in Python.

Support matrix instead of vector of float64

Currently, the Lines.RMatrix functions accept and return a vector of floats. But they can accept / return a Matrix instead

    """Resistance matrix (full), ohms per unit length. Array of doubles. (Getter)"""
    function RMatrix()::Matrix{Float64}
        n = Phases()
        if n == 0
            rmatrix = Matrix{Float64}[]
        else
            rmatrix = reshape(Utils.get_float64_array(Lib.Lines_Get_Rmatrix), (n, n))
        end
        return rmatrix
    end

    """Resistance matrix (full), ohms per unit length. Array of doubles. (Setter)"""
    function RMatrix(Value::Matrix{Float64})
        n = Phases()
        RMatrix(reshape(Value, (n * n, 1)))
    end

    """Resistance matrix (full), ohms per unit length. Array of doubles. (Setter)"""
    function RMatrix(Value::Vector{Float64})
        Value, ValuePtr, ValueCount = Utils.prepare_float64_array(Value)
        Lib.Lines_Set_Rmatrix(ValuePtr, ValueCount)
    end

Alternatively, we can accept/return as a Matrix{ComplexF64} instead. RMatrix in this case would be just reals. XMatrix can be just imaginary values in this matrix. I'd prefer just returning a Matrix{Float64} and letting users deal with converting it to the corresponding complex numbers.

Thoughts?

Exposing all DSS objects and uniform batches

In DSS C-API v0.12.0, there are two sets of functions Obj_* and Batch_* to manipulate DSS properties directly, bypassing the textual parser and string conversion to read/write the properties.

Initially, my plan would be to generate code from the schema like in IObj.py (also WIP) -- for Python I added the "magic numbers" directly to avoid the lookup overhead, Julia could use enums/constants. Most of the code is very simple (mapping class id, property id and property type to the language types). I also plan to publish a C++ version of that in a few days.

Besides some general things like naming conventions (ideally we should try to use a default convention across all projects), does anyone have suggestions before I try this? We can always add an initial implementation and iterate later, as long as things work.

We should add more functions to get/manipulate the power flow state in DSS C-API v0.12.1, effectively moving away from the classic API based on the original COM implementation and the "Active..." concept. And dss-extensions/dss_capi#113 will allow us to return the matrix shapes.

EDIT: Some samples for Python available in test_obj.py and test_batch.py.

`Transformers.kVA` returns wrong value

Hi guys!

I'm facing a weird issue once I run a large distribution system. The Transformers.kVA is give me wrong values, but the Properties.Value("kVA") is right, comparing with OpenDSS.

Here is an example with the IEEE 8500 Node in the OpenDSS\IEEETestCases\8500-Node folder.

using OpenDSSDirect

sys = """
clear
Compile Master-unbal.dss     ! unbalanced load master

New Energymeter.m1 Line.ln5815900-1 1
New Monitor.m1 Line.ln5815900-1 1


Solve
"""

dss(sys)
Circuit.SetActiveElement("Transformer.T5337697B")
Transformers.Wdg(1.0)
Transformers.kVA() # Wrong value
Properties.Value("kVA") # Right value

But If I try a small distribution system, the Transformers.kVA() works here on my tests.

Is this a bug?

cc @Ibrahim-a-Ibrahim

Plotting: add as a package extension

This is a planning and tracking issue for the plotting implementation. As suggested by Tom, we can add this as a package extension so it won't affect negatively users that don't want or expect plots from DSS scripts. Toggling the AllowForms value would be enough to control whether plots would be enabled even if the dependencies are installed.

The main plotting alternatives seem to be Plots.jl and Makie.jl. Both have multiple backends and are not lightweight. Ideally, since most of the work is actually preparing the data, we can add basic support for both later.

Tasks:

  • Add the basic code infrastruture
  • For testing, add examples, even if they don't output any figures at first. One of the alternatives for notebooks could help.
  • Implement most DSS plot commands:
    • Scatter
    • Daisy
    • TShape
    • PriceShape
    • LoadShape
    • Monitor
    • Circuit
    • Profile
    • Visualize
    • YearlyCurve
    • Matrix
    • GeneralData
    • DI
    • MeterZones
    • CompareCases (this one is a maybe)
  • Formalize and document the API for plotting without using the DSS commands. This would also be useful when we reintroduce support for the official ODD.DLL.
    • Investigate what other (custom) plot types we could add
  • Add support for old .DSV files?
  • Evaluate adding support for the official TCP connection.

Some of basic plots are very easy to implement, some not so much (lots of details). Depending on the progress, we can add plot types piecewise since some plots would be better than none.

Plot commands

DSS-Python already implements most of plot commands and the code there can be used as a reference: https://dss-extensions.org/DSS-Python/examples/Plotting

Note that the plots are kinda ugly since they are intended to mirror the original OpenDSS experience. We probably should change that though (I was thinking in adding an option to use a custom style in Python too).

Current tests

The integration is achieved using a simple callback that returns a JSON-encoded string with the basic plot parameters. Most of the data is collected through the API to finally plot it. Julia makes this very easy. From my current tests:

function plot_cb(ctx::Ptr{Cvoid}, jsonParams_c::Cstring)::Int32
    # TODO: map context pointer
    # TODO: try/catch, returning the error to DSS C-API

    if jsonParams_c != C_NULL
        jsonParams = unsafe_string(jsonParams_c)
    else
        jsonParams = "{}"
    end
    params = JSON.parse(jsonParams)
    ptype = params["PlotType"]

    if ptype == "Profile"
        dss_profile_plot(params)
    end
    
    return 0
end

OpenDSSDirect.Lib.DSS_RegisterPlotCallback(OpenDSSDirect.DSS_DEFAULT_CTX.ctx, @cfunction(plot_cb, Int32, (Ptr{Cvoid}, Cstring)))

OpenDSSDirect.dss("""
    redirect electricdss-tst/Version8/Distrib/EPRITestCircuits/ckt5/Master_ckt5.dss
    solve
    plot profile
""")

I started playing with Plots.jl first:

Sample output from "plot profile" with Plots.jl

I'll open a PR with some of this soon.

Extend the C-API?

It might be useful to extend the API to return some prepared data for circuit and profile plots to avoid redoing the work for every target language on DSS-Extensions.

On the official OpenDSS plots

There are two separate plotting implementations in the official OpenDSS:

  • Legacy version uses DSSView.exe; this uses the .DSV files. The files are written and DSSView is started. Adding support for reading those files could be useful.
  • The newer OpenDSS Viewer (it had different names in the past, a.k.a. OpenDSS Visualization Tool). This one is fed JSON from a TCP connection.

Both tools have minor issues, and some plot commands don't work on either, some for a few years, some for more than a decade. (technically, DSS-Python currently supports more plots than both, but no interactive features).

Although most of the plot setup code is in Pascal and open-source, the actual plotting tools are not open-source. I think OpenDSS-G is in a similar situation, as well as OpenDSS-GIS.

Note that I did remove the TCP connection code from DSS C-API since I don't like that enabled by default. DSS C-API will have a plug-in system soon, so we could readd it as an optional feature for interactive usage if required.

Use of DSS.Lib.ActionCodes

I am getting the error when using action codes like DSS.SwtControls.Action(DSS.Lib.ActionCodes_Open), as ActionCodes_Open::ActionCodes = 0x00000001 but the function accepts only integer numbers.

Changing Vsource in OpenDSSDirect.jl

I am running power flow in OpenDSSDirect. jl and at some stage in my code, I need to change the substation setpoint voltage, Vsource, in my code. Here is the piece of code that I use to update Vsource, but it is not working, still my Vsource value remains = 1 per unit. Any help is appreciated. Thank you.

for i=1:10 # i is time
if i>=3
_ODSS.Vsources.AllNames()
_ODSS.Vsources.Name("source")
_ODSS.Vsources.PU(1.2)
else
_ODSS.Vsources.AllNames()
_ODSS.Vsources.Name("source")
_ODSS.Vsources.PU(1.0)
end
V_source =_ODSS.Vsources.PU()
@show V_source
end

ToJSON errors when called on elements

It appears that the element.ToJSON() function is not working properly, or at least not working as I expect. Apparently, it should be called with an Int64, but this throws a UndefVarError: getstring not defined error.

Here is an example, using the simple DSS file from Issue 101, where the file is saved as filename.dss:

import OpenDSSDirect as DSS
DSS.Basic.AllowEditor(false)
DSS.dss("""
    clear
    redirect "filename.dss"
    """)

DSS.Transformers.First()
1

infil> DSS.Element.Name()
"Transformer.tx1"

infil> DSS.Element.ToJSON()
ERROR: MethodError: no method matching ToJSON()

Closest candidates are:
  ToJSON(::Int64)
   @ OpenDSSDirect ~/.julia/packages/OpenDSSDirect/TOPxW/src/element.jl:41
  ToJSON(::OpenDSSDirect.DSSContext, ::Int64)
   @ OpenDSSDirect ~/.julia/packages/OpenDSSDirect/TOPxW/src/element.jl:38

infil> DSS.Element.ToJSON(0)
ERROR: UndefVarError: `getstring` not defined
Stacktrace:
 [1] ToJSON(dss::OpenDSSDirect.DSSContext, Flags::Int64)
   @ OpenDSSDirect.Element ~/.julia/packages/OpenDSSDirect/TOPxW/src/element.jl:39
 [2] ToJSON(Flags::Int64)
   @ OpenDSSDirect.Element ~/.julia/packages/OpenDSSDirect/TOPxW/src/element.jl:41

The same error occurs with other Int64s, such as ToJSON(1). I suspect it should accept an Int32, rather than Int64. For example, this works: DSS.Circuit.ToJSON(Int32(1)).

@PMeira, thanks for your help and the excellent explanation on Issue 101. I thought I would also create an issue for this ToJSON problem in case you want to include a fix in the upcoming release.

Any way to avoid working directory being reset at the end of a run?

Upon trying to run the tutorial example for this package, I realized that running it once changes my directory to the one containing the .dss file, making any further runs after the first one futile, if I'm not using absolute paths, but relative paths.

In this code, I'm bypassing this problem by manually saving my original directory address and cd-ing to it at the end of the run, but is there a simpler way to do the same?

using OpenDSSDirect

# Store the current directory to cd to later, as I don't like the package changing my directory at the end of the run
original_directory = pwd()

foldername = joinpath(".", "OpenDSSDirect", "5wwHs", "examples", "8500-Node") # Works

filename = joinpath(foldername, "Master.dss")

dss("""
    clear
    compile $(filename)
    solve
""")

function main()
    loadnumber = Loads.First()
    kWsum = 0.0
    kvarsum = 0.0
    
    while loadnumber > 0
        kWsum += Loads.kW()
        kvarsum += Loads.kvar()
        loadnumber = Loads.Next()
    end

    kWsum, kvarsum
end

result = main()

# Reset the working directory to its original state
cd(original_directory)

println(result)

Common interface specification

Hi @tshort,

Would you be interested in having a common interface specification between OpenDSSDirect.jl
and OpenDSSDirect.py? My understanding is that you are using meta data for each function (in the xlsx file?) to create functions for the user interface. I'm doing something similar, using a interface.json. It'll be great to combine these, or create a new file that both of us can use, since then any updates to OpenDSS can be implemented in the interface specification and then both packages can benefit from this change with little source code updates. Ideally, the interface specification would be generated from the OpenDSS DirectDLL interface source code itself.

Thoughts? This is probably not immediately necessary, but will be a great to have in the long run.

DSS file not detected if `filename` string has any spaces.

Upon trying to run the tutorial example for this package, I realized that compile $(filename) only works with filename with no spaces. Since my computer username itself has spaces in it, the original code, which uses an absolute directory, would throw up an error, saying that truncated_filename (I mean filename truncated at the first space encountered) doesn't exist. To test this, I copied the files to a local folder and was able to replicate the problem.

using OpenDSSDirect

# Store the current directory to cd to later, as I don't like the package changing my directory at the end of the run
original_directory = pwd()

foldername = joinpath(".", "OpenDSSDirect", "5wwHs", "examples", "8500-Node") # Works

# foldername = joinpath(".", "OpenDSSDirect", "5wwHs", "examples", "8500-Node with some spaces in the name") 
# I've created a duplicate of the 8500-Node folder but inserted spaces in its name # Doesn't work

filename = joinpath(foldername, "Master.dss")

dss("""
    clear
    compile $(filename)
    solve
""")

function main()
    loadnumber = Loads.First()
    kWsum = 0.0
    kvarsum = 0.0
    
    while loadnumber > 0
        kWsum += Loads.kW()
        kvarsum += Loads.kvar()
        loadnumber = Loads.Next()
    end

    kWsum, kvarsum
end

result = main()

# Reset the working directory to its original state
cd(original_directory)

println(result)

Translating OpenDSS Errors into exceptions

The idea is just to check if Error.Number() (or the contents of the Error pointer directly) is non-zero, mapping Error.Description() into an exception frequently. This should avoid many issues since there are many places that use the Error interface to report errors in the Pascal code.

Adding this shouldn't be too hard. First we need to move this snippet into a new function:

error_num = Lib.Error_Get_Number()
if (error_num != 0)
description = Utils.get_string(Lib.Error_Get_Description())
throw(
OpenDSSDirectException(
"[ERROR $error_num] $description"
)
)
end

Then,

  1. insert calls to it through the code as I've been doing for the other projects, or
  2. use a macro to wrap (nearly) all functions somehow

A similar approach is already being used in DSS Python/MATLAB.

Sync to the current API

Even in the classic OpenDSS API, there are a few functions that are not exposed in Julia yet.

We need to regenerate the lib module from the header(s) and add a few functions and modules (notably Parallel).

Storage Controller Monitored Element.

Hello,

Im Ignacio Pérez from Adolfo Ibañes University of Chile. Im Trying to use the StorageController Element of Open Dss with the OpenDSSDirect.jl extensión. I have been trying to solve a problem related with the use of the controller, but I really don´t know what to do.

When i use: OpenDSSDirect.Text.Command(“ New StorageController.btcont
~ Element="Element_name"
~ terminal=1
~ MonPhase=AVG
~ %reserve=20
~ enabled=No
~ eventlog=yes
")

There is allways the next error: ERROR: OpenDSSDirect.Utils.OpenDSSDirectException("[ERROR 372] Monitored Element in StorageController.btcont is not set")

I don´t know why this is happening, I use the OpenDSSDirect.Lines.Idx(1) to set the active element and the command OpenDSSDirect.CktElement.Name() to obtain the name of the element that I want to monitor, I have set all the circuit before and all the elements exist.

I would be very grateful if someone could help me with my issue.

Best regards,

Ignacio Pérez

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.