Skip to content

Commit

Permalink
API: new Circuit_Save function to complement the save circuit command.
Browse files Browse the repository at this point in the history
Changelog and headers updated.

Ref: #129
  • Loading branch information
PMeira committed Jan 18, 2024
1 parent 068d3fc commit 54d601b
Show file tree
Hide file tree
Showing 10 changed files with 554 additions and 200 deletions.
11 changes: 7 additions & 4 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ Starting on this version, we will call DSS C-API and related projects AltDSS, an

This version should match OpenDSS v9.7.1.1 (SVN r3646). Remember to check the compatibility flags and [Known differences](https://github.com/dss-extensions/dss_capi/blob/master/docs/known_differences.md). Other recent SVN commits, up to r3717 (dated 2023-12-11), either do not update code or are not relevant for the implementation on AltDSS/DSS C-API.

- Another large internal code refactoring step and general clean-up. Check the commits for details, too many to list. A last step is under progress and will be merged in the next major release.
- Another large internal (Pascal) code refactoring step and general clean-up. Check the commits for details, too many to list. A last step is under progress and will be merged in the next major release.

- **Capitalization of property names adjusted!** A first pass was done to try to make the property names more uniform. Since **OpenDSS is case insensitive**, we are free to change the capitalization as we see fit. In the past, the official OpenDSS already changed some property names, so a general suggestion for users that process the property names is to transform the names to upper or lower cases before comparing. This should ensure better stability across past and future versions of both DSS-Extensions and the official OpenDSS. For code that do not check the names in a case insensitive approach, DSS C-API 0.14.0 provides a function to adjust the property names (`Settings_SetPropertyNameStyle`), allowing the user to choose between three alternatives: the "Modern" version with adjusted capitalization; "Lowercase" names; and "Legacy" names. "Legacy" names can be used to avoid updating the names.

- **Introduces a preview of JSON schema (new), JSON export (updated) and import (new).** Too many details to include in the changelog. Includes many updates to the internal metadata. A separate project will be posted at https://github.com/dss-extensions/AltDSS-Schema and community feedback is welcome. Note: the JSON schema will be used for projects and features beyond JSON IO.

- **Introduced options and improve correctness for `save circuit`.** During the testing of the JSON dump, issues were fixed when saving Line, LineGeometry, Transformer, AutoTrans, XfmrCode. The issues vary from simple omissions to invalid exported DSS code. The property tracking feature below also helps generating clear and valid DSS scripts from `save circuit`, eliminating properties invalidated when changing some component definitions. To allow easier control of the save function without modifying the DSS language, a **new** `Save` function was added to the circuit API (`Circuit_Save`), coupled with the new `DSSSaveFlags` enumeration, which contains the option flags. This function also allows exporting the whole circuit as a single string.

- **Introduce property tracking.** Setting some properties now mark conflicting property definitions as unset. This affects some functionality for saving circuits and is also used for the JSON schema, for instance. An example: a user creates a load with `kW=10 kvar=0`. Later, the user updates the load, setting `PF=0.9`. Setting the power factor toggles the load internal state to use kW and PF as the load definition, but `kvar` is still marked as set. The DSS engine correctly tracks the order that properties were defined, so everything works as expected. Now, with the growing usage of DSS implementation to export the circuit, every single user is required to correctly implement this tracking if they want to ensure compatibility. That is, dumping the data from this example generator in an unordered dictionary/map/etc. for processing and later dumping back to DSS scripts will result in the wrong model.
- Users can, of course, still query the value of all properties.
- See also `NoPropertyTracking` compat flag.
- Currently implemented, at least partially, in the following DSS classes (plus Lines and Loads API): LineCode, LineGeometry, LoadShape, Generator, Load, PVSystem, Storage, VSource, Fault, Line, Reactor, Transformer.
- This functionally may be extended to other classes, if required.
- This functionally may be extended to other classes in future versions, if required.

- **Introduce "Setter" flags.** These are flags used to tweak how the property update is done. Notably,`AvoidFullRecalc` (some other flags are only using by the engine, internally): some specific properties like `Load.kW` can be updated both directly through a DSS script (or Text interface), or through the dedicated Loads API in any of the specific language bindings of the many APIs. The dedicated API does not force a YPrim update and full load model recalculation.
- When using this flag `AvoidFullRecalc` in the Obj/Batch APIs, the behavior will follow the dedicated Loads API.
Expand All @@ -53,7 +57,7 @@ This version should match OpenDSS v9.7.1.1 (SVN r3646). Remember to check the co
- Headers:
- Remove `stdint_compat.h`. This was only required for very old or non-standard compiler like MSVC 2008. Users that require that can still source the file from older releases or get similar files from other sources.
- Include `stddef.h` when building as C code.
- Mark `CktElement_Get_IsIsolated` with `(API Extension)``
- Mark `CktElement_Get_IsIsolated` with `(API Extension)`

- Specific bug fixes:
- AutoTrans: fix `DumpProperties`, readd `bank` property (unused internally).
Expand All @@ -74,7 +78,6 @@ This version should match OpenDSS v9.7.1.1 (SVN r3646). Remember to check the co
- Circuit/API: fix `Circuit_Enable` and `Circuit_Disable` (enabling/disabling circuit elements by name). An equivalent fix is included in the official OpenDSS v9.7.1.1, in the COM interface. Additionally, provide error message when trying to use invalid element names.
- Obj/Batch API: better handling of booleans. With this change, any non-zero value is interpreted as `true`, which simplifies integration with other programming languages. This was the original intention.
- API/Iteration: Fix issues with iteration in a few of the internal functions which could have resulted in empty results in some situations. These situations occurred only during testing, so we don't expect many users were affected.
- `save circuit`: include `set EarthModel=...`; adjust order of elements.

- Misc:
- Error handling: add a few numeric checks, and check for errors in more places during solution algorithms. The changes should help finding issues earlier and/or more easily.
Expand Down
40 changes: 40 additions & 0 deletions include/dss_capi.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,23 @@ extern "C" {
DSSPropertyNameStyle_Legacy = 2 //< Use the previous capitalization of the property names.
};

/*!
DSSSaveFlags are bit flags used in the Circuit_Save function to
customize the saved circuit.
*/
enum DSSSaveFlags {
DSSSaveFlags_CalcVoltageBases = 0x0001, ///< Include the command CalcVoltageBases.
DSSSaveFlags_SetVoltageBases = 0x0002, ///< Include commands to set the voltage bases individually.
DSSSaveFlags_IncludeOptions = 0x0004, ///< Include most of the options (from the Set/Get DSS commands).
DSSSaveFlags_IncludeDisabled = 0x0008, ///< Include disabled circuit elements (and LoadShapes).
DSSSaveFlags_ExcludeDefault = 0x0010, ///< Exclude default DSS items if they are not modified by the user.
DSSSaveFlags_SingleFile = 0x0020, ///< Use a single file instead of a folder for output.
DSSSaveFlags_KeepOrder = 0x0040, ///< Save the circuit elements in the order they were loaded in the active circuit. Guarantees better reproducibility, especially when the system is ill-conditioned. Requires "SingleFile" flag.
DSSSaveFlags_ExcludeMeterZones = 0x0080, ///< Do not export meter zones (as "feeders") separately. Has no effect when using a single file.
DSSSaveFlags_IsOpen = 0x0100, ///< Export commands to open terminals of elements.
DSSSaveFlags_ToString = 0x0200 ///< Export to the result string. Requires "SingleFile" flag.
};

enum BatchOperation {
BatchOperation_Set = 0,
BatchOperation_Multiply = 1,
Expand Down Expand Up @@ -1228,6 +1245,29 @@ extern "C" {
*/
DSS_CAPI_DLL const char* Circuit_ToJSON(int32_t options);

/*
Equivalent of the "save circuit" DSS command, but allows customization
through the `saveFlags` argument, which is a set of bit flags.
See the "DSSSaveFlags" enumeration for available flags:
- `CalcVoltageBases`: Include the command CalcVoltageBases.
- `SetVoltageBases`: Include commands to set the voltage bases individually.
- `IncludeOptions`: Include most of the options (from the Set/Get DSS commands).
- `IncludeDisabled`: Include disabled circuit elements (and LoadShapes).
- `ExcludeDefault`: Exclude default DSS items if they are not modified by the user.
- `SingleFile`: Use a single file instead of a folder for output.
- `KeepOrder`: Save the circuit elements in the order they were loaded in the active circuit. Guarantees better reproducibility, especially when the system is ill-conditioned. Requires "SingleFile" flag.
- `ExcludeMeterZones`: Do not export meter zones (as "feeders") separately. Has no effect when using a single file.
- `IsOpen`: Export commands to open terminals of elements.
- `ToString`: to the result string. Requires "SingleFile" flag.
If `SingleFile` is enabled, the first argument (`dirOrFilePath`) is the file path,
otherwise it is the folder path. For string output, the argument is not used.
(API Extension)
*/
DSS_CAPI_DLL const char* Circuit_Save(const char* dirOrFilePath, int32_t saveFlags);

/*
EXPERIMENTAL: Loads a full circuit from a JSON-encoded string. The data must
be encoded using the proposed AltDSS Schema, see
Expand Down
23 changes: 23 additions & 0 deletions include/dss_capi_ctx.h
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,29 @@ extern "C" {
*/
DSS_CAPI_DLL const char* ctx_Circuit_ToJSON(const void* ctx, int32_t options);

/*
Equivalent of the "save circuit" DSS command, but allows customization
through the `saveFlags` argument, which is a set of bit flags.
See the "DSSSaveFlags" enumeration for available flags:
- `CalcVoltageBases`: Include the command CalcVoltageBases.
- `SetVoltageBases`: Include commands to set the voltage bases individually.
- `IncludeOptions`: Include most of the options (from the Set/Get DSS commands).
- `IncludeDisabled`: Include disabled circuit elements (and LoadShapes).
- `ExcludeDefault`: Exclude default DSS items if they are not modified by the user.
- `SingleFile`: Use a single file instead of a folder for output.
- `KeepOrder`: Save the circuit elements in the order they were loaded in the active circuit. Guarantees better reproducibility, especially when the system is ill-conditioned. Requires "SingleFile" flag.
- `ExcludeMeterZones`: Do not export meter zones (as "feeders") separately. Has no effect when using a single file.
- `IsOpen`: Export commands to open terminals of elements.
- `ToString`: to the result string. Requires "SingleFile" flag.
If `SingleFile` is enabled, the first argument (`dirOrFilePath`) is the file path,
otherwise it is the folder path. For string output, the argument is not used.
(API Extension)
*/
DSS_CAPI_DLL const char* ctx_Circuit_Save(const void* ctx, const char* dirOrFilePath, int32_t saveFlags);

/*
EXPERIMENTAL: Loads a full circuit from a JSON-encoded string. The data must
be encoded using the proposed AltDSS Schema, see
Expand Down
15 changes: 13 additions & 2 deletions src/CAPI/CAPI_Circuit.pas
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ interface

uses
CAPI_Utils,
CAPI_Types;
CAPI_Types,
DSSClass;

function Circuit_Get_Name(): PAnsiChar; CDECL;
function Circuit_Get_NumBuses(): Integer; CDECL;
Expand Down Expand Up @@ -78,6 +79,7 @@ procedure Circuit_Get_ElementLosses(var ResultPtr: PDouble; ResultCount: PAPISiz
procedure Circuit_Get_ElementLosses_GR(ElementsPtr: PInteger; ElementsCount: TAPISize); CDECL;
function Circuit_ToJSON(options: Integer): PAnsiChar; CDECL;
procedure Circuit_FromJSON(circStr: PAnsiChar; options: Integer); CDECL;
function Circuit_Save(dirfilepath: PAnsiChar; saveFlags: DSSSaveFlags): PAnsiChar; CDECL;

implementation

Expand All @@ -90,7 +92,6 @@ implementation
sysutils,
CktElement,
DSSObject,
DSSClass,
Transformer,
PCElement,
PDElement,
Expand Down Expand Up @@ -1136,4 +1137,14 @@ procedure Circuit_FromJSON(circStr: PAnsiChar; options: Integer); CDECL;
DoSimpleMsg(DSSPrime, 'Error converting data from JSON: %s', [errorMsg], 20230919);
end;
//------------------------------------------------------------------------------
function Circuit_Save(dirfilepath: PAnsiChar; saveFlags: DSSSaveFlags): PAnsiChar; CDECL;
var
res: String;
begin
res := '';
Result := NIL;
if DSSPrime.ActiveCircuit.Save(dirfilepath, @saveFlags, @res) then
Result := DSS_GetAsPAnsiChar(DSSPrime, res);
end;
//------------------------------------------------------------------------------
end.
Loading

0 comments on commit 54d601b

Please sign in to comment.