Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.12.x mega-merge #109

Merged
merged 27 commits into from
May 2, 2022
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e2c2a9e
Squashed changes, docs pending
PMeira Mar 7, 2022
6ce62e6
Builds: cross-compile to macOS ARM64/aarch64, including GitHub Actions.
PMeira Mar 8, 2022
a754bba
User-models: update headers; remove from legacy models; consolidate f…
PMeira Mar 9, 2022
ece66dd
Add COMHelp with instructions on where to download it.
PMeira Mar 16, 2022
5777b58
Properties/RegControl.PTPhase: fix corner case in hybrid enum
PMeira Mar 17, 2022
6ea25cd
AlwaysResetYPrimInvalid: Reduce number of bits to fit in a int32 (and…
PMeira Mar 17, 2022
9b7d7b4
A few microoptimizations
PMeira Mar 17, 2022
35eed4d
Load, ZIPV model: apply some manual optimizations
PMeira Mar 17, 2022
d909f68
YMatrix_SolveSystem: fix NIL check and tweak params
PMeira Mar 19, 2022
ec0c572
Solution: check for infinites in MaxError
PMeira Mar 22, 2022
b7bebd4
CktElement/API: To match SVN, add CktElement_Set_Variable/CktElement_…
PMeira Mar 22, 2022
a8ea2ed
CIM: port recent changes.
PMeira Mar 22, 2022
d3d1f6b
InvControl(2): remove infinite loop
PMeira Mar 27, 2022
38691b2
API: fix/add invalid state checks.
PMeira Mar 27, 2022
eb8ecff
Spectrum: Fix issue when reading fewer items than specified from CSV.
PMeira Mar 30, 2022
53cd601
ExportCIMXML: port recent changes (from multiple revisions)
PMeira Mar 31, 2022
215c3b1
ExportCIMXML: port a few SVN commits
PMeira Apr 11, 2022
3e55121
Recloser: in `Sample`, check if `MonitoredObj` (`MonitoredElement`) w…
PMeira Apr 11, 2022
ecaae7e
DOScmd: introduce toggle flag and matching functions; default to disa…
PMeira Apr 11, 2022
4388b7d
ReduceAlgs, from SVN: "Checking for bus in the KeepList when reducing…
PMeira Apr 12, 2022
0d7cfb7
Capacitors/API: Fix error in format string
PMeira Apr 13, 2022
5e55d38
Port from SVN: "Fixing issues when using ActiveActor=* within a scrip…
PMeira Apr 14, 2022
c943b2b
ZIP: better error and filename handling
PMeira Apr 15, 2022
d960bd7
ZIP/API: add ZIP_Extract to get the contents of a compressed file
PMeira Apr 20, 2022
166585b
ZIP/API: Add Contains and List, and comments.
PMeira Apr 20, 2022
533b025
PVSystems: Update units in `Irradiance` comments
PMeira Apr 21, 2022
fbe465e
README: Update the basic text and diagrams
PMeira May 2, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions .github/workflows/builds.yml
Original file line number Diff line number Diff line change
@@ -72,10 +72,8 @@ jobs:
path: '${{ github.workspace }}/dss_capi/release/*.tar.gz'

build_macos_x64:
name: 'macOS x64'
name: 'macOS x64 and ARM64'
runs-on: macos-latest
env:
KLUSOLVE_URL: 'https://github.com/dss-extensions/klusolve/releases/download/1.0.0a1/klusolvex_1.0.0a1_darwin_x64.tar.gz'
steps:
- uses: actions/checkout@v2
with:
@@ -88,16 +86,23 @@ jobs:
sudo installer -package /Volumes/fpc-3.2.2.intelarm64-macosx/fpc-3.2.2-intelarm64-macosx.mpkg -target /
- name: 'Download/extract KLUSolve(X)'
run: |
wget "${KLUSOLVE_URL}" -Oklusolve.tar.gz -q
tar zxf klusolve.tar.gz
wget "https://github.com/dss-extensions/klusolve/releases/download/1.0.0a1/klusolvex_1.0.0a1_darwin_x64.tar.gz" -Oklusolve_x64.tar.gz -q
wget "https://github.com/dss-extensions/klusolve/releases/download/1.0.0a1/klusolvex_1.0.0a1_darwin_arm64.tar.gz" -Oklusolve_arm64.tar.gz -q
tar zxf klusolve_x64.tar.gz
tar zxf klusolve_arm64.tar.gz
cp -r klusolvex/lib/* dss_capi/lib/
- name: Build
- name: Build x64
run: |
cd dss_capi
source ./build/make_metadata.sh
./build/build_macos_x64.sh
ls -lR lib

- name: Build ARM64
run: |
cd dss_capi
source ./build/make_metadata.sh
./build/build_macos_arm64.sh
ls -lR lib
- name: 'Upload artifacts'
uses: "actions/upload-artifact@v2"
#if: github.event_name == 'release' && github.event.action == 'created'
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -66,3 +66,5 @@ __recovery
*.dproj.local
__history
.vscode
__pycache__
*.out.*
5 changes: 3 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Copyright (c) 2008-2019, Electric Power Research Institute, Inc.
Copyright (c) 2017-2019, Paulo Meira
Copyright (c) 2008-2022, Electric Power Research Institute, Inc.
Copyright (c) 2017-2022, Paulo Meira
Copyright (c) 2018-2022, DSS Extensions contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -18,9 +18,9 @@ If you are looking for the bindings to other languages:
- [DSS Sharp](http://github.com/dss-extensions/dss_sharp/) is available for .NET/C#, also mimics the COM classes, but Windows-only at the moment. Soon it will be possible to use it via COM too.
- [DSS MATLAB](http://github.com/dss-extensions/dss_matlab/) presents multi-platform integration (Windows, Linux, MacOS) with DSS C-API and is also very compatible bastante with the COM classes.

Version 0.10.7, based on OpenDSS revision 2963 (around version OpenDSS 9.1.3.4), with many extra/custom features.
Version 0.12.0dev, based on OpenDSS revision 3363, with many extra/custom features.

**This is the work-in-progress branch, which will become 0.12.0.**
**This is the work-in-progress branch, which will become 0.12.0. For a specific version, check the Git tags.**

While the main objective of COM compatibility has been reach, this is still a work-in-progress and is subject to changes.
*Note that, while the interface with OpenDSS is stable (v7, classic version), the OpenDSS-PM (v8, actor-based parallel machine version) interface is experimental in our builds.* From version 0.10, the v8 interface is a lot more stable than in 0.9.8. Since version 0.10.5, the parallel-machine code from Version 8 is not built for binary releases anymore -- stay tuned for a future unified version.
@@ -42,7 +42,8 @@ Since 2019-03-05, the `dss_capi` repository contains all the Pascal code used to

See [the changelog](https://github.com/dss-extensions/dss_capi/blob/0.10.x/docs/changelog.md) for a detailed list.

- **2020-03-09 / version 0.10.7-1: Includes a fix for some reports which presented corrupted text in version 0.10.7.**
- **2022-02-xx / version 0.12.0: Beta versions of 0.12.0 available. Final 0.12.0 expected in May 2022.**
- 2021-03-09 / version 0.10.7-1: Includes a fix for some reports which presented corrupted text in version 0.10.7.
- 2020-12-28 / version 0.10.7: Maintenance release based on on OpenDSS revision 2963. Includes fixes and new features from the official OpenDSS. [A new document describing the DSS properties](https://github.com/dss-extensions/dss_capi/blob/0.10.x/docs/dss_properties.md) was added.
- 2020-07-31 / version 0.10.6: New API extensions, and ported changes from the official OpenDSS codebase. Includes some bugfixes, a new extended validation error messages and new compatibility toggles.
- 2020-03-03 / version 0.10.5: Maintenance release with several minor fixes. Includes changes ported from COM and the official OpenDSS codebase. Version 8 binary releases excluded.
@@ -61,8 +62,7 @@ See [the changelog](https://github.com/dss-extensions/dss_capi/blob/0.10.x/docs/

## Missing features and limitations

- Currently not implemented:
- `DSSEvents` from `DLL/ImplEvents.pas`: seems too dependent on COM.
- Currently not fully implemented:
- Plotting in general

## Extra features
@@ -141,6 +141,8 @@ Currently most testing/validation is based on [DSS Python](http://github.com/dss

## Roadmap

(Still being updated for 0.12.x)

Besides bug fixes, the main funcionality of this library is mostly done. Notable desirable features that may be implemented are:
- Expose more classes and important methods/properties for all classes
- More and better documentation. We already integrated the help strings from the IDL/COM definition files in the header files.
9 changes: 6 additions & 3 deletions README.pt-BR.md
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
Esta biblioteca expõe o motor do OpenDSS/OpenDSS-PM (v7/v8) através de uma interface C plana, que tenta reproduzir a maioria dos métodos COM. De fato, a maior parte do código foi inicialmente derivado dos arquivos da implementação COM. O DLL resultante pode ser usado diretamente ou através de módulos de interface, como o módulo `DSS Python`. DSS Python representa um módulo para linguagem Python que imita a mesma estrutura do módulo COM (como exposto via `win32com` ou `comtypes`), efetivamente nos permitindo alcançar compatilibilidade multi-plataforma a nível de Python. Também há suporte para outras linguagens diversas -- caso tenha interesse numa linguagem não suportada, abra um novo "issue".

<p align="center">
<img alt="Visão geral dos repositórios relacionados" src="https://raw.githubusercontent.com/dss-extensions/dss_capi/master/docs/images/repomap.png" width=600>
<img alt="Visão geral dos repositórios relacionados" src="https://raw.githubusercontent.com/dss-extensions/dss_capi/master/docs/images/repomap_pt.png" width=600>
</p>

Caso procure integração com outras linguagens de programação:
@@ -18,7 +18,9 @@ Caso procure integração com outras linguagens de programação:
- [DSS Sharp](http://github.com/dss-extensions/dss_sharp/) para .NET/C#, no momento apenas Windows. Em breve também será possível usá-lo via COM.
- [DSS MATLAB](http://github.com/dss-extensions/dss_matlab/) permite integração multi-plataforma (Windows, Linux, MacOS) bastante compatível com o módulo COM, de fato contorna algumas dificuldades de COM.

Versão 0.10.7, baseada no OpenDSS SVN r2963 (em torno do OpenDSS 9.1.3.4), com várias funcionalidades extras.
Versão 0.12.0dev, baseada no OpenDSS revisão (SVN) 3363, com várias funcionalidades customizadas e extras.

**Este branch pode estar em desenvolvimento. Para uma versão específica, consulte os tags do Git do repositório.**

Apesar de o objetivo principal (compatibilidade com COM) ter sido alcançado, este é um sempre um trabalho em andamento.
*Observe que, enquanto a interface clássica (v7 + aprimoramentos) é estável, a interface para o OpenDSS-PM (v8, baseada em atores e execução paralela) ainda é experimental.* A partir da versão 0.10, a interface v8 está bem mais estável que na versão 0.9.8 da DSS C-API. A partir da versão 0.10.5, o código da pasta `Version8` não é mais compilado -- uma nova versão unificada é esperada para uma futura versão.
@@ -61,7 +63,6 @@ Veja o [registro de alterações (em inglês)](https://github.com/dss-extensions
## Funcionalidades faltantes e limitações

- Ainda não implementados:
- `DSSEvents` de `DLL/ImplEvents.pas`: parece ser muito dependente de COM.
- Gráficos em geral

## Funcionalides extras
@@ -248,6 +249,8 @@ Atualmente, todos os testes e validação são baseados no [DSS Python](http://g

## Planos

(Ainda sendo atualizados para versão 0.12.x)

Além de correções de problemas, a funcionalidade principal desta biblioteca está pronta. Alguns pontos que pretendemos trabalhar envolvem:
- Expor os principais métodos e propriedades faltantes (não presentes nem mesmo na interface COM), assim como classes.
- Documentação melhor e mais completa. As strings de ajuda dos arquivos de definição IDL/COM já estão reproduzidos nos headers (pasta `include`), mas apenas em inglês.
45 changes: 45 additions & 0 deletions build/build_macos_arm64.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/bash

set -e -x

python3 src/classic_to_ctx.py

export LDFLAGS=-L`pwd`/lib/darwin_arm64/

rm -rf build/units_arm64
mkdir build/units_arm64
fpc -Paarch64 @src/darwin-arm64.cfg -B src/dss_capi.lpr

# Make the lib look in the same folder for KLUSolveX
DSS_CAPI_LIB="lib/darwin_arm64/libdss_capi.dylib"
CURRENT_LIBKLUSOLVE=`otool -L "$DSS_CAPI_LIB" | grep libklusolvex | cut -f 1 -d ' ' | sed $'s/^[ \t]*//'`
NEW_LIBKLUSOLVE="@loader_path/./libklusolvex.dylib"
install_name_tool -change "$CURRENT_LIBKLUSOLVE" "$NEW_LIBKLUSOLVE" "$DSS_CAPI_LIB"
install_name_tool -id "@loader_path/./libdss_capi.dylib" "$DSS_CAPI_LIB"

rm -rf build/units_arm64
mkdir build/units_arm64
fpc -Paarch64 @src/darwin-arm64-dbg.cfg -B src/dss_capid.lpr

# Make the lib look in the same folder for KLUSolveX
DSS_CAPI_LIB="lib/darwin_arm64/libdss_capid.dylib"
CURRENT_LIBKLUSOLVE=`otool -L "$DSS_CAPI_LIB" | grep libklusolvex | cut -f 1 -d ' ' | sed $'s/^[ \t]*//'`
NEW_LIBKLUSOLVE="@loader_path/./libklusolvex.dylib"
install_name_tool -change "$CURRENT_LIBKLUSOLVE" "$NEW_LIBKLUSOLVE" "$DSS_CAPI_LIB"
install_name_tool -id "@loader_path/./libdss_capi.dylib" "$DSS_CAPI_LIB"

mkdir -p release/dss_capi/lib
cp -R lib/darwin_arm64 release/dss_capi/lib/darwin_arm64
cp -R include release/dss_capi/
# cp -R examples release/dss_capi/
cp LICENSE release/dss_capi/
cp OPENDSS_LICENSE release/dss_capi/
if [ -d "klusolvex" ]; then
cp klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE
else
cp ../klusolvex/LICENSE release/dss_capi/KLUSOLVE_LICENSE
fi
cd release
tar zcf "dss_capi_${DSS_CAPI_VERSION}_darwin_arm64.tar.gz" dss_capi
cd ..
rm -rf release/dss_capi
7 changes: 7 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
- expose the OpenDSS v8/v9 PM features as possible
- continue work on the plotting and extended reporting API
- see also the GitHub milestone: https://github.com/dss-extensions/dss_capi/milestone/6
- remove `LegacyModels` (older/deprecated models for PVSystem, Storage and related classes)

# Version 0.12

@@ -53,6 +54,12 @@ This version still maintains basic compatibility with the 0.10.x series of relea

- Drop function aliases: previously deprecated function aliases (`LoadShapes_Set_Sinterval` and `LoadShapes_Get_sInterval`) were removed to simplify the build process. Use `LoadShapes_Set_SInterval` and `LoadShapes_Get_SInterval` instead.
- Monitor headers: From the official OpenDSS, since May 2021, the monitor binary stream doesn't include the header anymore. When porting the change to DSS Extensions, we took the opportunity to rewrite the related code, simplifying it. As such, the implementation in DSS Extensions deviates from the official one. Extra blank chars are not included, and fields should be more consistent. As a recommendation, if your code needs to be compatible with both implementations, trimming the fields should be enough.
- Error messages: most messages are now more specific and, if running a DSS script from files, include the file names and line numbers.
- Spectrum: To reduce overhead during object edits, now required to exist before the object that uses it. This is consistent with most of the other types in OpenDSS.
- New object and batch APIs
- New experimental API for loading scripts/data from ZIP files
- New convenience functions to bulk load commands from the API
- User-models: headers updated, and removed support for user-models in `LegacyModels` mode. `LegacyModels` will be removed in v0.13.

Due to the high number of IO changes, we recommend checking the performance before and after the upgrade to ensure your use case is not affected negatively. If issues are found, please do report.

Binary file modified docs/images/repomap.png

Unable to render rich display

1,106 changes: 422 additions & 684 deletions docs/images/repomap.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/repomap_pt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
666 changes: 666 additions & 0 deletions docs/images/repomap_pt.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 44 additions & 28 deletions include/dss_UserModels.h
Original file line number Diff line number Diff line change
@@ -28,6 +28,13 @@
# endif
#endif

#ifndef dss_long_bool
#ifdef DSS_CAPI_DLL
#define dss_long_bool int32_t
#else
#define dss_long_bool bool
#endif
#endif

#ifdef __cplusplus
extern "C" {
@@ -139,8 +146,10 @@ struct TCapControlVars
DeadTime,
LastOpenTime;

dss_long_bool
Voverride;

bool
Voverride,
VoverrideEvent,
VoverrideBusSpecified; // Added 8-11-11

@@ -169,28 +178,9 @@ struct TCapControlVars
LastStepInService; // Change this to force an update of cap states


// NOTE: VOverrideBusName and CapacitorName are UnicodeStrings
//
// Without the actual string data, the total bytes for the string struct
// fields is 12 when the OpenDSS binary is built with Delphi. Since this
// pointer can be different when used with FPC (16 bytes instead of 12),
// this pointer needs to be processed different according to the compiler.
//
// Delphi UnicodeString structure seems to be:
// uint16_t codePage;
// uint16_t bytesPerChar; // should always be 2
// uint32_t refCount;
// uint32_t length;
// char *data;
//
// FPC UnicodeString structure seems to be:
// uint32_t codePage;
// uint32_t bytesPerChar; // should always be 2
// uint32_t refCount;
// uint32_t length;
// char *data;

char* VOverrideBusName; // Actual string data encoded in UTF-16
// NOTE: VOverrideBusName and CapacitorName may be UnicodeStrings in Delphi.
// These pointers could be processed different according to the Pascal compiler.
char* VOverrideBusName; // Actual string data encoded in UTF-16
char* CapacitorName; // Actual string data encoded in UTF-16

int32_t ControlActionHandle;
@@ -200,19 +190,43 @@ struct TCapControlVars

struct TStorageVars
{
double
double
kWrating,
kWhRating,
kWhStored,
kWhReserve,
ChargeEff,
DisChargeEff,
kVArating,
kVStorageBase,
kvarRequested,
RThev,
XThev,

XThev;

double
// Inverter Related Properties
kVArating,
kvarlimit,
kvarlimitneg;

dss_long_bool
P_Priority,
PF_Priority;

double
pctkWrated,
EffFactor;

double
// Interaction with InvControl
Vreg,
Vavg,
VVOperation,
VWOperation,
DRCOperation,
VVDRCOperation,
WPOperation,
WVOperation;

double
// Dynamics variables
Vthev_re, // Thevenin equivalent voltage (complex) for dynamic model
Vthev_im,
@@ -307,6 +321,8 @@ struct TDSSCallBacks
DSS_MODEL_CALLBACK(void, GetPublicDataPtr)(void **PublicData, int32_t *PublicDataBytes);
DSS_MODEL_CALLBACK(int32_t, GetActiveElementName)(char *FullName, uint32_t MaxNameLen);
DSS_MODEL_CALLBACK(void*, GetActiveElementPtr)(void); // Returns pointer to active circuit element

//TODO: check FPC vs Delphi compatibility for const parameters in ControlQueuePush
DSS_MODEL_CALLBACK(int32_t, ControlQueuePush)(const int32_t Hour, const double Sec, const int32_t Code, const int32_t ProxyHdl, void *Owner);
DSS_MODEL_CALLBACK(void, GetResultStr)(char *S, uint32_t Maxlen);
};
269 changes: 243 additions & 26 deletions include/dss_capi.h

Large diffs are not rendered by default.

175 changes: 149 additions & 26 deletions include/dss_capi_ctx.h
Original file line number Diff line number Diff line change
@@ -45,7 +45,7 @@ extern "C" {
previous prime instance returned by ctx_Set_Prime, if required.
*/
DSS_CAPI_DLL void *ctx_Set_Prime(void *ctx);


DSS_CAPI_DLL void ctx_DSS_ResetStringBuffer(void* ctx);

@@ -740,7 +740,7 @@ extern "C" {
DSS_CAPI_DLL void ctx_Circuit_Get_SubstationLosses_GR(void* ctx);

/*
Total power, watts delivered to the circuit
Total power, kW delivered to the circuit
*/
DSS_CAPI_DLL void ctx_Circuit_Get_TotalPower(void* ctx, double** ResultPtr, int32_t* ResultCount);
/*
@@ -1166,14 +1166,16 @@ extern "C" {
DSS_CAPI_DLL void ctx_CktElement_Get_AllVariableValues_GR(void* ctx);

/*
For PCElement, get the value of a variable by name. If Code>0 Then no variable by this name or not a PCelement.
For PCElement, set/get the value of a variable by name. If Code>0 Then no variable by this name or not a PCelement.
*/
DSS_CAPI_DLL double ctx_CktElement_Get_Variable(void* ctx, char* MyVarName, int32_t *Code);
DSS_CAPI_DLL double ctx_CktElement_Set_Variable(void* ctx, char* MyVarName, int32_t *Code, double Value);

/*
For PCElement, get the value of a variable by integer index.
For PCElement, set/get the value of a variable by integer index.
*/
DSS_CAPI_DLL double ctx_CktElement_Get_Variablei(void* ctx, int32_t Idx, int32_t *Code);
DSS_CAPI_DLL double ctx_CktElement_Set_Variablei(void* ctx, int32_t Idx, int32_t *Code, double Value);

/*
Array of integer containing the node numbers (representing phases, for example) for each conductor of each terminal.
@@ -1435,6 +1437,19 @@ extern "C" {
DSS_CAPI_DLL uint16_t ctx_DSS_Get_LegacyModels(void* ctx);
DSS_CAPI_DLL void ctx_DSS_Set_LegacyModels(void* ctx, uint16_t Value);

/*
If enabled, the DOScmd command is allowed. Otherwise, an error is reported if the user tries to use it.
Defaults to False/0 (disabled state). Users should consider DOScmd deprecated on DSS Extensions.
This can also be set through the environment variable DSS_CAPI_LEGACY_MODELS. Setting it to 1 enables
the legacy components, using the old models from the start.
(API Extension)
*/
DSS_CAPI_DLL uint16_t ctx_DSS_Get_AllowDOScmd(void* ctx);
DSS_CAPI_DLL void ctx_DSS_Set_AllowDOScmd(void* ctx, uint16_t Value);

/*
If disabled, the engine will not change the active working directory during execution. E.g. a "compile"
command will not "chdir" to the file path.
@@ -3378,79 +3393,79 @@ extern "C" {
/*
Delivers the number of CPUs on the current PC
*/
// DSS_CAPI_DLL int32_t Parallel_Get_NumCPUs(void);
DSS_CAPI_DLL int32_t ctx_Parallel_Get_NumCPUs(void* ctx);

/*
Delivers the number of Cores of the local PC
*/
// DSS_CAPI_DLL int32_t Parallel_Get_NumCores(void);
DSS_CAPI_DLL int32_t ctx_Parallel_Get_NumCores(void* ctx);

/*
Gets the ID of the Active Actor
*/
// DSS_CAPI_DLL int32_t Parallel_Get_ActiveActor(void);
DSS_CAPI_DLL int32_t ctx_Parallel_Get_ActiveActor(void* ctx);

/*
Sets the Active Actor
*/
// DSS_CAPI_DLL void Parallel_Set_ActiveActor(int32_t Value);
DSS_CAPI_DLL void ctx_Parallel_Set_ActiveActor(void* ctx, int32_t Value);

// DSS_CAPI_DLL void Parallel_CreateActor(void);
DSS_CAPI_DLL void ctx_Parallel_CreateActor(void* ctx);

/*
Gets the CPU of the Active Actor
*/
// DSS_CAPI_DLL int32_t Parallel_Get_ActorCPU(void);
DSS_CAPI_DLL int32_t ctx_Parallel_Get_ActorCPU(void* ctx);

/*
Sets the CPU for the Active Actor
*/
// DSS_CAPI_DLL void Parallel_Set_ActorCPU(int32_t Value);
DSS_CAPI_DLL void ctx_Parallel_Set_ActorCPU(void* ctx, int32_t Value);

/*
Gets the number of Actors created
*/
// DSS_CAPI_DLL int32_t Parallel_Get_NumOfActors(void);
DSS_CAPI_DLL int32_t ctx_Parallel_Get_NumOfActors(void* ctx);

// DSS_CAPI_DLL void Parallel_Wait(void);
DSS_CAPI_DLL void ctx_Parallel_Wait(void* ctx);

/*
Gets the progress of all existing actors in pct
*/
// DSS_CAPI_DLL void Parallel_Get_ActorProgress(int32_t** ResultPtr, int32_t* ResultCount);
DSS_CAPI_DLL void ctx_Parallel_Get_ActorProgress(void* ctx, int32_t** ResultPtr, int32_t* ResultCount);
/*
Same as Parallel_Get_ActorProgress but using the global buffer interface for results
*/
// DSS_CAPI_DLL void Parallel_Get_ActorProgress_GR(void);
DSS_CAPI_DLL void ctx_Parallel_Get_ActorProgress_GR(void* ctx);

/*
Gets the status of each actor
*/
// DSS_CAPI_DLL void Parallel_Get_ActorStatus(int32_t** ResultPtr, int32_t* ResultCount);
DSS_CAPI_DLL void ctx_Parallel_Get_ActorStatus(void* ctx, int32_t** ResultPtr, int32_t* ResultCount);
/*
Same as Parallel_Get_ActorStatus but using the global buffer interface for results
*/
// DSS_CAPI_DLL void Parallel_Get_ActorStatus_GR(void);
DSS_CAPI_DLL void ctx_Parallel_Get_ActorStatus_GR(void* ctx);

/*
Sets ON/OFF (1/0) Parallel features of the Engine
*/
// DSS_CAPI_DLL int32_t Parallel_Get_ActiveParallel(void);
DSS_CAPI_DLL int32_t ctx_Parallel_Get_ActiveParallel(void* ctx);

/*
Delivers if the Parallel features of the Engine are Active
*/
// DSS_CAPI_DLL void Parallel_Set_ActiveParallel(int32_t Value);
DSS_CAPI_DLL void ctx_Parallel_Set_ActiveParallel(void* ctx, int32_t Value);

/*
Reads the values of the ConcatenateReports option (1=enabled, 0=disabled)
*/
// DSS_CAPI_DLL int32_t Parallel_Get_ConcatenateReports(void);
DSS_CAPI_DLL int32_t ctx_Parallel_Get_ConcatenateReports(void* ctx);

/*
Enable/Disable (1/0) the ConcatenateReports option for extracting monitors data
*/
// DSS_CAPI_DLL void Parallel_Set_ConcatenateReports(int32_t Value);
DSS_CAPI_DLL void ctx_Parallel_Set_ConcatenateReports(void* ctx, int32_t Value);

/*
String to be parsed. Loading this string resets the Parser to the beginning of the line. Then parse off the tokens in sequence.
@@ -3724,7 +3739,7 @@ extern "C" {
/*
Same as PDElements_Get_AllPctEmerg but using the global buffer interface for results
*/
DSS_CAPI_DLL void ctx_PDElements_Get_AllPctEmerg_GR(void* ctx);
DSS_CAPI_DLL void ctx_PDElements_Get_AllPctEmerg_GR(void* ctx, uint16_t AllNodes);


/*
@@ -3901,12 +3916,12 @@ extern "C" {
DSS_CAPI_DLL void ctx_PVSystems_Set_Name(void* ctx, char* Value);

/*
Get the present value of the Irradiance property in W/sq-m
Get the present value of the Irradiance property in kW/sq-m
*/
DSS_CAPI_DLL double ctx_PVSystems_Get_Irradiance(void* ctx);

/*
Set the present Irradiance value in W/sq-m
Set the present Irradiance value in kW/sq-m
*/
DSS_CAPI_DLL void ctx_PVSystems_Set_Irradiance(void* ctx, double Value);

@@ -5259,7 +5274,7 @@ extern "C" {
*/
DSS_CAPI_DLL void ctx_Solution_Set_MinIterations(void* ctx, int32_t Value);

// DSS_CAPI_DLL void Solution_SolveAll(void);
DSS_CAPI_DLL void ctx_Solution_SolveAll(void* ctx);

DSS_CAPI_DLL void ctx_Solution_Get_IncMatrix(void* ctx, int32_t** ResultPtr, int32_t* ResultCount);

@@ -5976,7 +5991,7 @@ extern "C" {
DSS_CAPI_DLL void ctx_YMatrix_AddInAuxCurrents(void* ctx, int32_t SType);
DSS_CAPI_DLL void ctx_YMatrix_getIpointer(void* ctx, double **IvectorPtr);
DSS_CAPI_DLL void ctx_YMatrix_getVpointer(void* ctx, double **VvectorPtr);
DSS_CAPI_DLL int32_t ctx_YMatrix_SolveSystem(void* ctx, double **NodeVPtr);
DSS_CAPI_DLL int32_t ctx_YMatrix_SolveSystem(void* ctx, double *NodeVPtr);
DSS_CAPI_DLL void ctx_YMatrix_Set_SystemYChanged(void* ctx, uint16_t arg);
DSS_CAPI_DLL uint16_t ctx_YMatrix_Get_SystemYChanged(void* ctx);
DSS_CAPI_DLL void ctx_YMatrix_Set_UseAuxCurrents(void* ctx, uint16_t arg);
@@ -6543,6 +6558,114 @@ extern "C" {
DSS_CAPI_DLL void ctx_YMatrix_Set_SolverOptions(void* ctx, uint64_t opts);
DSS_CAPI_DLL uint64_t ctx_YMatrix_Get_SolverOptions(void* ctx);

DSS_CAPI_DLL void ctx_Text_CommandBlock(void* ctx, char *Value);
DSS_CAPI_DLL void ctx_Text_CommandArray(void* ctx, char** ValuePtr, int32_t ValueCount);

/*
Opens and prepares a ZIP file to be used by the DSS text parser.
Currently, the ZIP format support is limited by what is provided in the Free Pascal distribution.
Besides that, the full filenames inside the ZIP must be shorter than 256 characters.
The limitations should be removed in a future revision.
(API Extension)
*/
DSS_CAPI_DLL void ctx_ZIP_Open(void* ctx, char* FileName);

/*
Runs a "Redirect" command inside the current (open) ZIP file.
In the current implementation, all files required by the script must
be present inside the ZIP, using relative paths. The only exceptions are
memory-mapped files.
(API Extension)
*/
DSS_CAPI_DLL void ctx_ZIP_Redirect(void* ctx, char* FileInZip);

/*
Check if the given path name is present in the current ZIP file.
(API Extension)
*/
DSS_CAPI_DLL int16_t ctx_ZIP_Contains(void* ctx, char* Name);

/*
List of strings consisting of all names match the regular expression provided in regexp.
If no expression is provided, all names in the current open ZIP are returned.
See https://regex.sorokin.engineer/en/latest/regular_expressions.html for information on
the expression syntax and options.
(API Extension)
*/
DSS_CAPI_DLL void ctx_ZIP_List(void* ctx, char*** ResultPtr, int32_t* ResultCount, char* RegExp);

/*
Extracts the contents of the file "FileName" from the current (open) ZIP file.
Returns a byte-string.
(API Extension)
*/
DSS_CAPI_DLL void ctx_ZIP_Extract(void* ctx, int8_t** ResultPtr, int32_t* ResultCount, char* FileName);

DSS_CAPI_DLL void ctx_ZIP_Extract_GR(void* ctx, char* FileName);

/*
Closes the current open ZIP file.
(API Extension)
*/
DSS_CAPI_DLL void ctx_ZIP_Close(void* ctx);

/*
Functions for the new API
*/

/*
Extract the current properties as a JSON encoded string.
WARNING: this is unstable and subject to change.
*/



/*
Returns the object name (direct access, no copy is done, no disposal required by the user; read only!)
*/

/*
Returns the object's class name (direct access, no copy is done, no disposal required by the user; read only!)
*/



/*
Activates an object. The object is set as the current
active DSSObject or CktElement, and in the list of its parent class.
If AllLists is true, other internal lists of OpenDSS are also
updated (implies slow/linear searches).
*/

/*
Returns the pointer to the internal property fill sequence, and optionally
the highest value in CurrentCount (if not null).
*/



















#ifdef __cplusplus
} // extern "C"
4 changes: 2 additions & 2 deletions src/CAPI/CAPI_ActiveClass.pas
Original file line number Diff line number Diff line change
@@ -136,7 +136,7 @@ function ActiveClass_Get_ActiveClassParent(): PAnsiChar; CDECL;
begin
if DSSPrime.ActiveDSSClass = NIL then
begin
Result := DSS_GetAsPAnsiChar(DSSPrime, 'Parent Class unknonwn');
Result := DSS_GetAsPAnsiChar(DSSPrime, 'Parent Class unknown');
Exit;
end;

@@ -147,7 +147,7 @@ function ActiveClass_Get_ActiveClassParent(): PAnsiChar; CDECL;
else if DSSPrime.ActiveDSSClass.ClassType.InheritsFrom(TPDClass) then
Result := DSS_GetAsPAnsiChar(DSSPrime, 'TPDClass')
else if DSSPrime.ActiveDSSClass.ClassType.InheritsFrom(TPCClass) then
Result := DSS_GetAsPAnsiChar(DSSPrime, 'TPCClas') //NOTE: kept as "Clas" for compatibility
Result := DSS_GetAsPAnsiChar(DSSPrime, 'TPCClass')
else
Result := DSS_GetAsPAnsiChar(DSSPrime, 'Generic Object');
end;
71 changes: 35 additions & 36 deletions src/CAPI/CAPI_Bus.pas
Original file line number Diff line number Diff line change
@@ -71,7 +71,7 @@ implementation
CAPI_Constants,
DSSGlobals,
Circuit,
Ucomplex,
UComplex, DSSUcomplex,
MathUtil,
sysutils,
ExecHelper,
@@ -95,7 +95,7 @@ function _hasActiveBus(DSS: TDSSContext): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active bus found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, _('No active bus found! Activate one and retry.'), 8989);
end;
Exit;
end;
@@ -106,10 +106,10 @@ function _activeObj(DSS: TDSSContext; out obj: TDSSBus): Boolean; inline;
begin
Result := False;
obj := NIL;

if not _hasActiveBus(DSS) then
Exit;

obj := DSS.ActiveCircuit.Buses[DSS.ActiveCircuit.ActiveBusIndex];
Result := True;
end;
@@ -146,7 +146,7 @@ procedure Bus_Get_SeqVoltages(var ResultPtr: PDouble; ResultCount: PAPISize); CD
VPh, V012: Complex3;

begin
if (InvalidCircuit(DSSPrime)) or
if (InvalidCircuit(DSSPrime)) or
(not ((DSSPrime.ActiveCircuit.ActiveBusIndex > 0) and (DSSPrime.ActiveCircuit.ActiveBusIndex <= DSSPrime.ActiveCircuit.NumBuses))) then
begin
DefaultResult(ResultPtr, ResultCount);
@@ -282,7 +282,7 @@ procedure Bus_Get_Isc(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
i, iV, NValues: Integer;

begin
if (InvalidCircuit(DSSPrime)) or
if (InvalidCircuit(DSSPrime)) or
(not ((DSSPrime.ActiveCircuit.ActiveBusIndex > 0) and (DSSPrime.ActiveCircuit.ActiveBusIndex <= DSSPrime.ActiveCircuit.NumBuses))) then
begin
DefaultResult(ResultPtr, ResultCount);
@@ -325,7 +325,7 @@ procedure Bus_Get_Voc(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
i, iV, NValues: Integer;

begin
if (InvalidCircuit(DSSPrime)) or
if (InvalidCircuit(DSSPrime)) or
(not ((DSSPrime.ActiveCircuit.ActiveBusIndex > 0) and (DSSPrime.ActiveCircuit.ActiveBusIndex <= DSSPrime.ActiveCircuit.NumBuses))) then
begin
DefaultResult(ResultPtr, ResultCount);
@@ -426,7 +426,7 @@ procedure Bus_Get_Zsc0(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
Z: Complex;

begin
if (InvalidCircuit(DSSPrime)) or
if (InvalidCircuit(DSSPrime)) or
(not ((DSSPrime.ActiveCircuit.ActiveBusIndex > 0) and (DSSPrime.ActiveCircuit.ActiveBusIndex <= DSSPrime.ActiveCircuit.NumBuses))) then
begin
DefaultResult(ResultPtr, ResultCount);
@@ -454,13 +454,13 @@ procedure Bus_Get_Zsc1(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
Result: PDoubleArray0;
Z: Complex;
begin
if (InvalidCircuit(DSSPrime)) or
if (InvalidCircuit(DSSPrime)) or
(not ((DSSPrime.ActiveCircuit.ActiveBusIndex > 0) and (DSSPrime.ActiveCircuit.ActiveBusIndex <= DSSPrime.ActiveCircuit.NumBuses))) then
begin
DefaultResult(ResultPtr, ResultCount);
Exit;
end;

with DSSPrime.ActiveCircuit do
begin
Z := Buses^[ActiveBusIndex].Zsc1;
@@ -485,7 +485,7 @@ procedure Bus_Get_ZscMatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC

begin
DefaultResult(ResultPtr, ResultCount);
if (InvalidCircuit(DSSPrime)) or
if (InvalidCircuit(DSSPrime)) or
(not ((DSSPrime.ActiveCircuit.ActiveBusIndex > 0) and (DSSPrime.ActiveCircuit.ActiveBusIndex <= DSSPrime.ActiveCircuit.NumBuses))) then
Exit;

@@ -511,7 +511,7 @@ procedure Bus_Get_ZscMatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC
end
except
On E: Exception do
DoSimpleMsg(DSSPrime, 'ZscMatrix Error: ' + E.message + CRLF, 5016);
DoSimpleMsg(DSSPrime, 'ZscMatrix Error: %s', [E.message], 5016);
end;
end;

@@ -524,7 +524,6 @@ procedure Bus_Get_ZscMatrix_GR(); CDECL;
//------------------------------------------------------------------------------
function Bus_ZscRefresh(): TAPIBoolean; CDECL;
begin

Result := FALSE; // Init in case of failure

if DSSPrime.DSSExecutive.DoZscRefresh = 0 then
@@ -540,7 +539,7 @@ procedure Bus_Get_YscMatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC

begin
DefaultResult(ResultPtr, ResultCount);
if (InvalidCircuit(DSSPrime)) or
if (InvalidCircuit(DSSPrime)) or
(not ((DSSPrime.ActiveCircuit.ActiveBusIndex > 0) and (DSSPrime.ActiveCircuit.ActiveBusIndex <= DSSPrime.ActiveCircuit.NumBuses))) then
Exit;

@@ -565,7 +564,7 @@ procedure Bus_Get_YscMatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC
end
except
On E: Exception do
DoSimpleMsg(DSSPrime, 'ZscMatrix Error: ' + E.message + CRLF, 5017);
DoSimpleMsg(DSSPrime, 'ZscMatrix Error: %s', [E.message], 5017);
end;
end;

@@ -649,7 +648,7 @@ function Bus_GetUniqueNodeNumber(StartNumber: Integer): Integer; CDECL;
Result := 0;
if InvalidCircuit(DSSPrime) then
Exit;

with DSSPrime.ActiveCircuit do
if ActiveBusIndex > 0 then
Result := Utilities.GetUniqueNodeNumber(DSSPrime, BusList.NameOfIndex(ActiveBusIndex), StartNumber);
@@ -665,7 +664,7 @@ procedure Bus_Get_CplxSeqVoltages(var ResultPtr: PDouble; ResultCount: PAPISize)
VPh, V012: Complex3;

begin
if (InvalidCircuit(DSSPrime)) or
if (InvalidCircuit(DSSPrime)) or
(not ((DSSPrime.ActiveCircuit.ActiveBusIndex > 0) and (DSSPrime.ActiveCircuit.ActiveBusIndex <= DSSPrime.ActiveCircuit.NumBuses))) then
begin
DefaultResult(ResultPtr, ResultCount);
@@ -816,8 +815,8 @@ procedure Bus_Get_puVLL(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
NodeIdxi := FindIdx(jj); // Get the index of the Node that matches i
inc(jj);
until NodeIdxi > 0;
// (2020-03-01) Changed in DSS C-API to avoid some corner

// (2020-03-01) Changed in DSS C-API to avoid some corner
// cases that resulted in infinite loops
for k := 1 to 3 do
begin
@@ -827,7 +826,7 @@ procedure Bus_Get_puVLL(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
else
inc(jj);

if NodeIdxj > 0 then
if NodeIdxj > 0 then
break;
end;
if NodeIdxj = 0 then
@@ -838,13 +837,13 @@ procedure Bus_Get_puVLL(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
end;
//------------------------------------------------------------------------------------------------
with Solution do
Volts := Csub(NodeV^[GetRef(NodeIdxi)], NodeV^[GetRef(NodeIdxj)]);
Volts := NodeV^[GetRef(NodeIdxi)] - NodeV^[GetRef(NodeIdxj)];
Result[iV] := Volts.re / BaseFactor;
Inc(iV);
Result[iV] := Volts.im / BaseFactor;
Inc(iV);
end;
end; {With pBus}
end; // With pBus
end
else
begin // for 1-phase buses, do not attempt to compute.
@@ -900,8 +899,8 @@ procedure Bus_Get_VLL(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
NodeIdxi := FindIdx(jj); // Get the index of the Node that matches i
inc(jj);
until NodeIdxi > 0;
// (2020-03-01) Changed in DSS C-API to avoid some corner

// (2020-03-01) Changed in DSS C-API to avoid some corner
// cases that resulted in infinite loops
for k := 1 to 3 do
begin
@@ -911,7 +910,7 @@ procedure Bus_Get_VLL(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
else
inc(jj);

if NodeIdxj > 0 then
if NodeIdxj > 0 then
break;
end;
if NodeIdxj = 0 then
@@ -922,7 +921,7 @@ procedure Bus_Get_VLL(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
end;
//------------------------------------------------------------------------------------------------
with Solution do
Volts := Csub(NodeV^[GetRef(NodeIdxi)], NodeV^[GetRef(NodeIdxj)]);
Volts := NodeV^[GetRef(NodeIdxi)] - NodeV^[GetRef(NodeIdxj)];
Result[iV] := Volts.re;
Inc(iV);
Result[iV] := Volts.im;
@@ -1011,7 +1010,7 @@ procedure Bus_Get_VMagAngle(var ResultPtr: PDouble; ResultCount: PAPISize); CDEC
DefaultResult(ResultPtr, ResultCount);
Exit;
end;

with DSSPrime.ActiveCircuit do
begin
Nvalues := pBus.NumNodesThisBus;
@@ -1044,7 +1043,7 @@ procedure Bus_Get_VMagAngle_GR(); CDECL;

//------------------------------------------------------------------------------
function Bus_Get_TotalMiles(): Double; CDECL;
var
var
pBus : TDSSBus;
begin
Result := 0.0;
@@ -1054,7 +1053,7 @@ function Bus_Get_TotalMiles(): Double; CDECL;
end;
//------------------------------------------------------------------------------
function Bus_Get_SectionID(): Integer; CDECL;
var
var
pBus : TDSSBus;
begin
Result := 0;
@@ -1157,7 +1156,7 @@ procedure Bus_Get_LineList_GR(); CDECL;

//------------------------------------------------------------------------------
procedure Bus_Get_LoadList(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CDECL;
{ Returns list of LOAD elements connected to this bus}
// Returns list of LOAD elements connected to this bus
var
BusReference, j, k, LoadCount: Integer;
pElem: TDSSCktElement;
@@ -1173,7 +1172,7 @@ procedure Bus_Get_LoadList(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CD
with DSSPrime.ActiveCircuit do
begin
BusReference := ActiveBusIndex;
{ Count number of LOAD elements connected to this bus }
// Count number of LOAD elements connected to this bus
LoadCount := 0;
pElem := TDSSCktElement(Loads.First);
while pElem <> NIL do
@@ -1188,9 +1187,9 @@ procedure Bus_Get_LoadList(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CD
DefaultResult(ResultPtr, ResultCount, '');
Exit;
end;
//TODO: same list of elements to avoid a second loop through them all?

//TODO: save list of elements to avoid a second loop through them all?

Result := DSS_RecreateArray_PPAnsiChar(ResultPtr, ResultCount, LoadCount);
k := 0;
pElem := TDSSCktElement(Loads.First);
@@ -1225,15 +1224,15 @@ procedure Bus_Get_ZSC012Matrix(var ResultPtr: PDouble; ResultCount: PAPISize); C
DefaultResult(ResultPtr, ResultCount);
Exit;
end;

with pBus do
begin
if NumNodesThisBus <> 3 then
begin
DefaultResult(ResultPtr, ResultCount);
Exit;
end;

Nvalues := SQR(NumNodesThisBus) * 2; // Should be 9 complex numbers
// Compute ZSC012 for 3-phase buses else leave it zeros
// ZSC012 = Ap2s Zsc As2p
380 changes: 144 additions & 236 deletions src/CAPI/CAPI_CNData.pas

Large diffs are not rendered by default.

108 changes: 65 additions & 43 deletions src/CAPI/CAPI_CapControls.pas
Original file line number Diff line number Diff line change
@@ -55,15 +55,18 @@ implementation
Executive,
ControlElem,
CapControl,
CapControlVars,
SysUtils,
DSSPointerList,
Utilities,
DSSClass,
DSSHelper;
DSSHelper,
DSSObjectHelper;

type
TObj = TCapControlObj;

//------------------------------------------------------------------------------
function _activeObj(DSS: TDSSContext; out obj: TCapControlObj): Boolean; inline;
function _activeObj(DSS: TDSSContext; out obj: TObj): Boolean; inline;
begin
Result := False;
obj := NIL;
@@ -75,24 +78,42 @@ function _activeObj(DSS: TDSSContext; out obj: TCapControlObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active CapControl object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['CapControl'], 8989);
end;
Exit;
end;

Result := True;
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const parm: String; const val: String);
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: String); overload;
var
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
elem.ParsePropertyValue(idx, val);
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: Double); overload;
var
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
elem.SetDouble(idx, val);
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: Integer); overload;
var
cmd: String;
elem: TCapControlObj;
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
cmd := Format('capcontrol.%s.%s=%s', [elem.Name, parm, val]);
DSS.DSSExecutive.Command := cmd;
elem.SetInteger(idx, val);
end;
//------------------------------------------------------------------------------
procedure CapControls_Get_AllNames(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CDECL;
@@ -112,7 +133,7 @@ procedure CapControls_Get_AllNames_GR(); CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_Capacitor(): PAnsiChar; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
@@ -122,7 +143,7 @@ function CapControls_Get_Capacitor(): PAnsiChar; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_CTratio(): Double; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -132,7 +153,7 @@ function CapControls_Get_CTratio(): Double; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_DeadTime(): Double; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -142,7 +163,7 @@ function CapControls_Get_DeadTime(): Double; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_Delay(): Double; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -152,7 +173,7 @@ function CapControls_Get_Delay(): Double; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_DelayOff(): Double; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -178,7 +199,7 @@ function CapControls_Get_Next(): Integer; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_Mode(): Integer; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := dssCapControlVoltage;
if not _activeObj(DSSPrime, elem) then
@@ -202,17 +223,18 @@ function CapControls_Get_Mode(): Integer; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_MonitoredObj(): PAnsiChar; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.ElementName);
if elem.MonitoredElement <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, AnsiLowerCase(elem.MonitoredElement.FullName));
end;
//------------------------------------------------------------------------------
function CapControls_Get_MonitoredTerm(): Integer; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -222,7 +244,7 @@ function CapControls_Get_MonitoredTerm(): Integer; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_Name(): PAnsiChar; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
@@ -232,7 +254,7 @@ function CapControls_Get_Name(): PAnsiChar; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_OFFSetting(): Double; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -242,7 +264,7 @@ function CapControls_Get_OFFSetting(): Double; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_ONSetting(): Double; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -252,7 +274,7 @@ function CapControls_Get_ONSetting(): Double; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_PTratio(): Double; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -262,7 +284,7 @@ function CapControls_Get_PTratio(): Double; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_UseVoltOverride(): TAPIBoolean; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := FALSE;
if not _activeObj(DSSPrime, elem) then
@@ -272,7 +294,7 @@ function CapControls_Get_UseVoltOverride(): TAPIBoolean; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_Vmax(): Double; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -282,7 +304,7 @@ function CapControls_Get_Vmax(): Double; CDECL;
//------------------------------------------------------------------------------
function CapControls_Get_Vmin(): Double; CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -292,32 +314,32 @@ function CapControls_Get_Vmin(): Double; CDECL;
//------------------------------------------------------------------------------
procedure CapControls_Set_Capacitor(const Value: PAnsiChar); CDECL;
begin
Set_Parameter(DSSPrime, 'Capacitor', value);
Set_Parameter(DSSPrime, ord(TCapControlProp.Capacitor), value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_CTratio(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'CTratio', FloatToStr(value));
Set_Parameter(DSSPrime, ord(TCapControlProp.CTratio), value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_DeadTime(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'DeadTime', FloatToStr(value));
Set_Parameter(DSSPrime, ord(TCapControlProp.DeadTime), value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_Delay(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'Delay', FloatToStr(value));
Set_Parameter(DSSPrime, ord(TCapControlProp.Delay), value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_DelayOff(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'DelayOff', FloatToStr(value));
Set_Parameter(DSSPrime, ord(TCapControlProp.DelayOff), value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_Mode(Value: Integer); CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
@@ -337,12 +359,12 @@ procedure CapControls_Set_Mode(Value: Integer); CDECL;
//------------------------------------------------------------------------------
procedure CapControls_Set_MonitoredObj(const Value: PAnsiChar); CDECL;
begin
Set_Parameter(DSSPrime, 'Element', value);
Set_Parameter(DSSPrime, ord(TCapControlProp.Element), value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_MonitoredTerm(Value: Integer); CDECL;
begin
Set_Parameter(DSSPrime, 'Terminal', IntToStr(value));
Set_Parameter(DSSPrime, ord(TCapControlProp.Terminal), value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_Name(const Value: PAnsiChar); CDECL;
@@ -357,38 +379,38 @@ procedure CapControls_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'CapControl "' + Value + '" Not Found in Active Circuit.', 5003);
DoSimpleMsg(DSSPrime, 'CapControl "%d" not found in Active Circuit.', [Value], 5003);
end;
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_OFFSetting(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'OffSetting', FloatToStr(value));
Set_Parameter(DSSPrime, ord(TCapControlProp.OffSetting), value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_ONSetting(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'OnSetting', FloatToStr(value));
Set_Parameter(DSSPrime, ord(TCapControlProp.OnSetting), value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_PTratio(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'PTratio', FloatToStr(value));
Set_Parameter(DSSPrime, ord(TCapControlProp.PTratio), value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_UseVoltOverride(Value: TAPIBoolean); CDECL;
begin
Set_Parameter(DSSPrime, 'VoltOverride', StrYorN(Value = True))
Set_Parameter(DSSPrime, ord(TCapControlProp.VoltOverride), Integer(Value));
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_Vmax(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'Vmax', FloatToStr(value));
Set_Parameter(DSSPrime, ord(TCapControlProp.Vmax), Value);
end;
//------------------------------------------------------------------------------
procedure CapControls_Set_Vmin(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'Vmin', FloatToStr(value));
Set_Parameter(DSSPrime, ord(TCapControlProp.Vmin), Value);
end;
//------------------------------------------------------------------------------
function CapControls_Get_Count(): Integer; CDECL;
@@ -400,7 +422,7 @@ function CapControls_Get_Count(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure CapControls_Reset(); CDECL;
var
elem: TCapControlObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
@@ -417,14 +439,14 @@ function CapControls_Get_idx(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure CapControls_Set_idx(Value: Integer); CDECL;
var
pCapControl: TCapControlObj;
pCapControl: TObj;
begin
if InvalidCircuit(DSSPrime) then
Exit;
pCapControl := DSSPrime.ActiveCircuit.CapControls.Get(Value);
if pCapControl = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid CapControl index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['CapControl', Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pCapControl;
57 changes: 41 additions & 16 deletions src/CAPI/CAPI_Capacitors.pas
Original file line number Diff line number Diff line change
@@ -44,7 +44,11 @@ implementation
SysUtils,
DSSPointerList,
DSSClass,
DSSHelper;
DSSHelper,
DSSObjectHelper;

type
TObj = TCapacitorObj;

//------------------------------------------------------------------------------
function _activeObj(DSS: TDSSContext; out obj: TCapacitorObj): Boolean; inline;
@@ -59,24 +63,42 @@ function _activeObj(DSS: TDSSContext; out obj: TCapacitorObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active Capacitor object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['Capacitor'], 8989);
end;
Exit;
end;

Result := True;
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const parm: String; const val: String);
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: String); overload;
var
cmd: String;
elem: TCapacitorObj;
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
elem.ParsePropertyValue(idx, val);
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: Double); overload;
var
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
cmd := Format('capacitor.%s.%s=%s', [elem.Name, parm, val]);
DSS.DSSExecutive.Command := cmd;
elem.SetDouble(idx, val);
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: Integer); overload;
var
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
elem.SetInteger(idx, val);
end;
//------------------------------------------------------------------------------
procedure Capacitors_Get_AllNames(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CDECL;
@@ -118,7 +140,7 @@ function Capacitors_Get_IsDelta(): TAPIBoolean; CDECL;
Result := FALSE;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := (elem.Connection > 0);
Result := (elem.Connection = TCapacitorConnection.Delta);
end;
//------------------------------------------------------------------------------
function Capacitors_Get_kV(): Double; CDECL;
@@ -167,17 +189,20 @@ procedure Capacitors_Set_IsDelta(Value: TAPIBoolean); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.Connection := Integer(Value);
if Value then
elem.Connection := TCapacitorConnection.Delta
else
elem.Connection := TCapacitorConnection.Wye;
end;
//------------------------------------------------------------------------------
procedure Capacitors_Set_kV(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'kv', FloatToStr(Value));
Set_Parameter(DSSPrime, ord(TCapacitorProp.kv), Value);
end;
//------------------------------------------------------------------------------
procedure Capacitors_Set_kvar(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'kvar', FloatToStr(Value));
Set_Parameter(DSSPrime, ord(TCapacitorProp.kvar), Value);
end;
//------------------------------------------------------------------------------
procedure Capacitors_Set_Name(const Value: PAnsiChar); CDECL;
@@ -192,13 +217,13 @@ procedure Capacitors_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'Capacitor "' + Value + '" Not Found in Active Circuit.', 5003);
DoSimpleMsg(DSSPrime, 'Capacitor "%s" not found in Active Circuit.', [Value], 5003);
end;
end;
//------------------------------------------------------------------------------
procedure Capacitors_Set_NumSteps(Value: Integer); CDECL;
begin
Set_Parameter(DSSPrime, 'numsteps', IntToStr(Value));
Set_Parameter(DSSPrime, ord(TCapacitorProp.NumSteps), Value);
end;
//------------------------------------------------------------------------------
function Capacitors_Get_Count(): Integer; CDECL;
@@ -272,8 +297,8 @@ procedure Capacitors_Set_States(ValuePtr: PInteger; ValueCount: TAPISize); CDECL

if (ValueCount <> elem.NumSteps) and DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSSPrime, Format('The number of states provided (%d) does not match the number of steps (%d) in the active capacitor.',
[ValueCount, elem.NumSteps]),
DoSimpleMsg(DSSPrime, 'The number of states provided (%d) does not match the number of steps (%d) in the active capacitor.',
[ValueCount, elem.NumSteps],
8989
);
Exit;
@@ -344,7 +369,7 @@ procedure Capacitors_Set_idx(Value: Integer); CDECL;
pCapacitor := DSSPrime.ActiveCircuit.ShuntCapacitors.Get(Value);
if pCapacitor = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid Capacitor index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid Capacitor index: "%d".', [Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pCapacitor;
22 changes: 11 additions & 11 deletions src/CAPI/CAPI_Circuit.pas
Original file line number Diff line number Diff line change
@@ -84,7 +84,7 @@ implementation
DSSClassDefs,
DSSGlobals,
Line,
UComplex,
UComplex, DSSUcomplex,
sysutils,
CktElement,
DSSObject,
@@ -148,7 +148,7 @@ procedure Circuit_Get_LineLosses(var ResultPtr: PDouble; ResultCount: PAPISize);
Loss := Cmplx(0.0, 0.0);
while pLine <> NIL do
begin
CAccum(Loss, pLine.Losses);
Loss += pLine.Losses;
pLine := Lines.Next;
end;
Result[0] := Loss.re * 0.001;
@@ -275,7 +275,7 @@ procedure Circuit_Get_AllElementNames(var ResultPtr: PPAnsiChar; ResultCount: PA
for i := 1 to NumDevices do
begin
with TDSSCktElement(CktElements.Get(i)) do
Result[i - 1] := DSS_CopyStringAsPChar(ParentClass.Name + '.' + Name);
Result[i - 1] := DSS_CopyStringAsPChar(FullName);
end;
end
end;
@@ -304,7 +304,7 @@ procedure Circuit_Get_SubstationLosses(var ResultPtr: PDouble; ResultCount: PAPI
while pTransf <> NIL do
begin
if pTransf.Issubstation then
Caccum(Loss, pTransf.Losses);
Loss += pTransf.Losses;
pTransf := Transformers.Next;
end;
Result[0] := Loss.re * 0.001;
@@ -338,7 +338,7 @@ procedure Circuit_Get_TotalPower(var ResultPtr: PDouble; ResultCount: PAPISize);
cPower := Cmplx(0.0, 0.0);
while pCktElem <> NIL do
begin
CAccum(cPower, pcktElem.Power[1]);
cPower += pcktElem.Power[1];
pCktElem := Sources.Next;
end;
Result[0] := cPower.re * 0.001;
@@ -494,7 +494,7 @@ function Circuit_SetActiveElement(const FullName: PAnsiChar): Integer; CDECL;
Result := -1;
if InvalidCircuit(DSSPrime) then
begin
DoSimpleMsg(DSSPrime, 'Create a circuit before trying to set an element active!', 5015);
DoSimpleMsg(DSSPrime, _('Create a circuit before trying to set an element active!'), 5015);
Exit;
end;

@@ -921,7 +921,7 @@ function Circuit_SetActiveClass(const ClassName: PAnsiChar): Integer; CDECL;
DevClassIndex := DSSPrime.ClassNames.Find(ClassName);
if DevClassIndex = 0 then
begin
DoSimplemsg(DSSPrime, 'Error: Class ' + ClassName + ' not found.', 5016);
DoSimpleMsg(DSSPrime, 'Class %s not found.', [ClassName], 5016);
Exit;
end;

@@ -999,7 +999,7 @@ procedure Circuit_Get_YNodeOrder(var ResultPtr: PPAnsiChar; ResultCount: PAPISiz
for i := 1 to NumNodes do
begin
with MapNodeToBus^[i] do
Result[k] := DSS_CopyStringAsPChar(Format('%s.%-d', [Uppercase(BusList.NameOfIndex(Busref)), NodeNum]));
Result[k] := DSS_CopyStringAsPChar(Format('%s.%-d', [AnsiUpperCase(BusList.NameOfIndex(Busref)), NodeNum]));
Inc(k);
end;
end
@@ -1075,7 +1075,7 @@ procedure Circuit_SetCktElementIndex(const Value: Integer); CDECL;
begin
if InvalidCircuit(DSSPrime) then
begin
DoSimpleMsg(DSSPrime, 'Create a circuit before trying to set an element active!', 5015);
DoSimpleMsg(DSSPrime, _('Create a circuit before trying to set an element active!'), 5015);
Exit;
end;

@@ -1084,15 +1084,15 @@ procedure Circuit_SetCktElementIndex(const Value: Integer); CDECL;
if NumDevices > Value then
ActiveCktElement := CktElements.Get(Value + 1)
else
DoSimpleMsg(DSSPrime, 'Invalid CktElement index', 5030);
DoSimpleMsg(DSSPrime, _('Invalid CktElement index'), 5030);
end;
end;

procedure Circuit_SetCktElementName(const Value: PAnsiChar); CDECL;
begin
if Circuit_SetActiveElement(Value) = -1 then
begin
DoSimpleMsg(DSSPrime, Format('Invalid CktElement name "%s"', [Value]), 5031);
DoSimpleMsg(DSSPrime, 'Invalid CktElement name "%s"', [Value], 5031);
end;
end;
//------------------------------------------------------------------------------
88 changes: 72 additions & 16 deletions src/CAPI/CAPI_CktElement.pas
Original file line number Diff line number Diff line change
@@ -63,6 +63,8 @@ procedure CktElement_Get_AllVariableValues(var ResultPtr: PDouble; ResultCount:
procedure CktElement_Get_AllVariableValues_GR(); CDECL;
function CktElement_Get_Variable(const MyVarName: PAnsiChar; out Code: Integer): Double; CDECL;
function CktElement_Get_Variablei(Idx: Integer; out Code: Integer): Double; CDECL;
procedure CktElement_Set_Variable(const MyVarName: PAnsiChar; out Code: Integer; Value: Double); CDECL;
procedure CktElement_Set_Variablei(Idx: Integer; out Code: Integer; Value: Double); CDECL;
procedure CktElement_Get_NodeOrder(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL;
procedure CktElement_Get_NodeOrder_GR(); CDECL;
function CktElement_Get_HasOCPDevice(): TAPIBoolean; CDECL;
@@ -87,7 +89,7 @@ implementation
CAPI_Constants,
DSSClassDefs,
DSSGlobals,
UComplex,
UComplex, DSSUcomplex,
Sysutils,
PDElement,
PCElement,
@@ -222,7 +224,7 @@ function InvalidCktElement(DSS: TDSSContext): Boolean; inline;
Result := (DSSPrime.ActiveCircuit.ActiveCktElement = NIL);
if Result and DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active circuit element found! Activate one and retry.', 97800);
DoSimpleMsg(DSS, _('No active circuit element found! Activate one and retry.'), 97800);
end;
end;
//------------------------------------------------------------------------------
@@ -260,7 +262,7 @@ function CktElement_Get_Name(): PAnsiChar; CDECL;
Exit;

with DSSPrime.ActiveCircuit.ActiveCktElement do
Result := DSS_GetAsPAnsiChar(DSSPrime, ParentClass.Name + '.' + Name);
Result := DSS_GetAsPAnsiChar(DSSPrime, FullName);
end;
//------------------------------------------------------------------------------
function CktElement_Get_NumConductors(): Integer; CDECL;
@@ -308,9 +310,9 @@ procedure CktElement_Set_BusNames(ValuePtr: PPAnsiChar; ValueCount: TAPISize); C
if (Count <> ActiveCktElement.NTerms) AND (DSS_CAPI_EXT_ERRORS) then
begin
DoSimpleMsg(DSSPrime,
Format('The number of buses provided (%d) does not match the number of terminals (%d).',
'The number of buses provided (%d) does not match the number of terminals (%d).',
[ValueCount, Integer(ActiveCktElement.NTerms)]
), 97895
, 97895
);
Exit;
end;
@@ -597,7 +599,7 @@ procedure CktElement_Get_SeqPowers(var ResultPtr: PDouble; ResultCount: PAPISize
k := (j - 1) * NConds;
n := NodeRef^[k + 1];
Vph[1] := Solution.NodeV^[n]; // Get voltage at node
S := Cmul(Vph[1], conjg(cBuffer^[k + 1])); // Compute power per phase
S := Vph[1] * cong(cBuffer^[k + 1]); // Compute power per phase
Result[icount] := S.re * 0.003; // 3-phase kW conversion
inc(icount);
Result[icount] := S.im * 0.003; // 3-phase kvar conversion
@@ -626,7 +628,7 @@ procedure CktElement_Get_SeqPowers(var ResultPtr: PDouble; ResultCount: PAPISize
Phase2SymComp(@Vph, @V012);
for i := 1 to 3 do
begin
S := Cmul(V012[i], conjg(I012[i]));
S := V012[i] * cong(I012[i]);
Result[icount] := S.re * 0.003; // 3-phase kW conversion
inc(icount);
Result[icount] := S.im * 0.003; // 3-phase kW conversion
@@ -847,7 +849,7 @@ procedure CktElement_Get_Residuals(var ResultPtr: PDouble; ResultCount: PAPISize
for j := 1 to Nconds do
begin
inc(k);
Caccum(cResid, CBuffer^[k]);
cResid += CBuffer^[k];
end;
Result[iV] := Cabs(cResid);
Inc(iV);
@@ -898,7 +900,13 @@ function CktElement_Get_DisplayName(): PAnsiChar; CDECL;
if InvalidCktElement(DSSPrime) then
Exit;

Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ActiveCircuit.ActiveCktElement.DisplayName)
if DSSPrime.ActiveCircuit.ActiveCktElement.DisplayName <> '' then
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ActiveCircuit.ActiveCktElement.DisplayName)
else
Result := DSS_GetAsPAnsiChar(DSSPrime,
DSSPrime.ActiveCircuit.ActiveCktElement.ParentClass.Name + '_' +
DSSPrime.ActiveCircuit.ActiveCktElement.Name
);
end;

//------------------------------------------------------------------------------
@@ -942,7 +950,7 @@ function CktElement_Get_Controller(idx: Integer): PAnsiChar; CDECL;
begin
ctrl := ActiveCktElement.ControlElementList.Get(idx);
if ctrl <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, Format('%s.%s', [ctrl.ParentClass.Name, ctrl.Name]));
Result := DSS_GetAsPAnsiChar(DSSPrime, ctrl.FullName);
end;
end;
end;
@@ -956,7 +964,7 @@ function CktElement_Get_EnergyMeter(): PAnsiChar; CDECL;
if InvalidCktElement(DSSPrime) then
Exit;

if DSSPrime.ActiveCircuit.ActiveCktElement.HasEnergyMeter then
if Flg.HasEnergyMeter in DSSPrime.ActiveCircuit.ActiveCktElement.Flags then
begin
pd := DSSPrime.ActiveCircuit.ActiveCktElement as TPDElement;
Result := DSS_GetAsPAnsiChar(DSSPrime, pd.MeterObj.Name);
@@ -1209,6 +1217,54 @@ function CktElement_Get_Variablei(Idx: Integer; out Code: Integer): Double; CDEC
end;
end;
//------------------------------------------------------------------------------
procedure CktElement_Set_Variable(const MyVarName: PAnsiChar; out Code: Integer; Value: Double); CDECL; //TODO: Remove Code and use Error interface?
var
pPCElem: TPCElement;
VarIndex: Integer;
begin
Code := 1; // Signifies an error; no value set

if InvalidCktElement(DSSPrime) then
Exit;

with DSSPrime.ActiveCircuit.ActiveCktElement do
begin
if (DSSObjType and BASECLASSMASK) <> PC_ELEMENT then
Exit;

pPCElem := (DSSPrime.ActiveCircuit.ActiveCktElement as TPCElement);
VarIndex := pPCElem.LookupVariable(MyVarName);
if (VarIndex > 0) and (VarIndex <= pPCElem.NumVariables) then
begin
pPCElem.Variable[VarIndex] := Value;
Code := 0; // Signify result is OK.
end;
end;
end;
//------------------------------------------------------------------------------
procedure CktElement_Set_Variablei(Idx: Integer; out Code: Integer; Value: Double); CDECL;
var
pPCElem: TPCElement;
begin
Code := 1; // Signifies an error; no value set

if InvalidCktElement(DSSPrime) then
Exit;

with DSSPrime.ActiveCircuit.ActiveCktElement do
begin
if (DSSObjType and BASECLASSMASK) <> PC_ELEMENT then
Exit;

pPCElem := (DSSPrime.ActiveCircuit.ActiveCktElement as TPCElement);
if (Idx > 0) and (Idx <= pPCElem.NumVariables) then
begin
pPCElem.Variable[Idx] := Value;
Code := 0; // Signify result is OK.
end;
end;
end;
//------------------------------------------------------------------------------
procedure CktElement_Get_NodeOrder(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL;
var
Result: PIntegerArray0;
@@ -1228,7 +1284,7 @@ procedure CktElement_Get_NodeOrder(var ResultPtr: PInteger; ResultCount: PAPISiz
if NodeRef = NIL then
begin
// Warn and exit
DoSimpleMsg('Nodes are not initialized. Try solving the system first.', 15013);
DoSimpleMsg(_('Nodes are not initialized. Try solving the system first.'), 15013);
DefaultResult(ResultPtr, ResultCount);
Exit;
end;
@@ -1260,7 +1316,7 @@ function CktElement_Get_HasOCPDevice(): TAPIBoolean; CDECL;
Result := FALSE;
Exit;
end;
Result := DSSPrime.ActiveCircuit.ActiveCktElement.HasOCPDevice;
Result := Flg.HasOCPDevice in DSSPrime.ActiveCircuit.ActiveCktElement.Flags;
end;
//------------------------------------------------------------------------------
function CktElement_Get_NumControls(): Integer; CDECL;
@@ -1399,7 +1455,7 @@ function CktElement_Get_IsIsolated(): TAPIBoolean; CDECL;
Exit;
end;

Result := DSSPrime.ActiveCircuit.ActiveCktElement.IsIsolated;
Result := Flg.IsIsolated in DSSPrime.ActiveCircuit.ActiveCktElement.Flags;
end;
//------------------------------------------------------------------------------
procedure CktElement_Get_TotalPowers(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
@@ -1433,7 +1489,7 @@ procedure CktElement_Get_TotalPowers(var ResultPtr: PDouble; ResultCount: PAPISi
myEnd := NConds * j;
for i := myInit to myEnd do
begin
myBuffer[j - 1] := cadd(myBuffer[j - 1], cBuffer^[i]);
myBuffer[j - 1] := myBuffer[j - 1] + cBuffer^[i];
end;
Result[iV + 0] := myBuffer[j - 1].re * 0.001;
Result[iV + 1] := myBuffer[j - 1].im * 0.001;
@@ -1459,7 +1515,7 @@ procedure CktElement_Get_NodeRef(var ResultPtr: PInteger; ResultCount: PAPISize)
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSSPrime, 'NodeRef is not populated for the current element!', 97801);
DoSimpleMsg(DSSPrime, _('NodeRef is not populated for the current element!'), 97801);
end;
Exit;
end;
6 changes: 3 additions & 3 deletions src/CAPI/CAPI_CmathLib.pas
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ implementation
CAPI_Constants,
DSSClass,
DSSHelper,
Ucomplex;
UComplex, DSSUcomplex;

procedure CmathLib_Get_cmplx(var ResultPtr: PDouble; ResultCount: PAPISize; RealPart, ImagPart: Double); CDECL;
var
@@ -96,7 +96,7 @@ procedure CmathLib_Get_cmul(var ResultPtr: PDouble; ResultCount: PAPISize; a1, b
cTemp: Complex;
begin
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2);
cTemp := cmul(cmplx(a1, b1), cmplx(a2, b2));
cTemp := cmplx(a1, b1) * cmplx(a2, b2);
Result[0] := cTemp.re;
Result[1] := cTemp.im;
end;
@@ -114,7 +114,7 @@ procedure CmathLib_Get_cdiv(var ResultPtr: PDouble; ResultCount: PAPISize; a1, b
cTemp: Complex;
begin
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, 2);
cTemp := cdiv(cmplx(a1, b1), cmplx(a2, b2));
cTemp := cmplx(a1, b1) / cmplx(a2, b2);
Result[0] := cTemp.re;
Result[1] := cTemp.im;
end;
6 changes: 3 additions & 3 deletions src/CAPI/CAPI_CtrlQueue.pas
Original file line number Diff line number Diff line change
@@ -53,15 +53,15 @@ procedure CtrlQueue_Delete(ActionHandle: Integer); CDECL;
function CtrlQueue_Get_ActionCode(): Integer; CDECL;
begin
Result := 0;
if InvalidCircuit(DSSPrime) then
if InvalidCircuit(DSSPrime) or (DSSPrime.ActiveAction = NIL) then
Exit;
Result := DSSPrime.ActiveAction^.ActionCode;
end;
//------------------------------------------------------------------------------
function CtrlQueue_Get_DeviceHandle(): Integer; CDECL;
begin
Result := 0;
if InvalidCircuit(DSSPrime) then
if InvalidCircuit(DSSPrime) or (DSSPrime.ActiveAction = NIL) then
Exit;
Result := DSSPrime.ActiveAction^.DeviceHandle;
end;
@@ -87,7 +87,7 @@ procedure CtrlQueue_Show(); CDECL;
begin
if InvalidCircuit(DSSPrime) then
Exit;
DSSPrime.ActiveCircuit.ControlQueue.ShowQueue(DSSPrime.OutputDirectory + 'COMProxy_ControlQueue.CSV');
DSSPrime.ActiveCircuit.ControlQueue.ShowQueue(DSSPrime.OutputDirectory + 'COMProxy_ControlQueue.csv');
end;
//------------------------------------------------------------------------------
procedure CtrlQueue_ClearActions(); CDECL;
25 changes: 19 additions & 6 deletions src/CAPI/CAPI_DSS.pas
Original file line number Diff line number Diff line change
@@ -40,8 +40,8 @@ function DSS_Get_AllowChangeDir(): TAPIBoolean; CDECL;
procedure DSS_Set_AllowChangeDir(Value: TAPIBoolean); CDECL;
procedure DSS_RegisterPlotCallback(cb: dss_callback_plot_t); CDECL;
procedure DSS_RegisterMessageCallback(cb: dss_callback_message_t); CDECL;


function DSS_Get_AllowDOScmd(): TAPIBoolean; CDECL;
procedure DSS_Set_AllowDOScmd(Value: TAPIBoolean); CDECL;

implementation

@@ -52,7 +52,6 @@ implementation
Exechelper,
sysUtils,
Executive,
ParserDel,
CmdForms,
DSSHelper;

@@ -71,7 +70,7 @@ procedure DSS_Set_AllowForms(Value: TAPIBoolean); CDECL;
{$IFDEF WINDOWS}
if (Value) and (GetConsoleWindow() = 0) and ((@DSSPrime.DSSMessageCallback) = NIL) then
begin
DoSimplemsg(DSSPrime, 'Cannot activate output with no console available! If you want to use a message output callback, register it before enabling AllowForms.', 5096);
DoSimplemsg(DSSPrime, _('Cannot activate output with no console available! If you want to use a message output callback, register it before enabling AllowForms.'), 5096);
Exit;
end;
{$ENDIF}
@@ -99,7 +98,11 @@ function DSS_Get_NumCircuits(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure DSS_ClearAll(); CDECL;
begin
{$IFDEF DSS_CAPI_PM}
DSSPrime.DSSExecutive.DoClearAllCmd;
{$ELSE}
DSSPrime.DSSExecutive.DoClearCmd;
{$ENDIF}
end;
//------------------------------------------------------------------------------
function DSS_Get_Version(): PAnsiChar; CDECL;
@@ -118,7 +121,6 @@ procedure DSS_Get_Classes(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CDE
i, k: Integer;

begin

Result := DSS_RecreateArray_PPAnsiChar(ResultPtr, ResultCount, DSSPrime.NumIntrinsicClasses);
k := 0;
for i := 1 to DSSPrime.NumIntrinsicClasses do
@@ -165,6 +167,7 @@ function DSS_Get_DataPath(): PAnsiChar; CDECL;
//------------------------------------------------------------------------------
procedure DSS_Set_DataPath(const Value: PAnsiChar); CDECL;
begin
DSSPrime.SetCurrentDSSDir(Value);
SetDataPath(DSSPrime, Value);
end;
//------------------------------------------------------------------------------
@@ -187,7 +190,7 @@ function DSS_SetActiveClass(const ClassName: PAnsiChar): Integer; CDECL;
DevClassIndex := DSSPrime.ClassNames.Find(ClassName);
if DevClassIndex = 0 then
begin
DoSimplemsg(DSSPrime, 'Error: Class ' + ClassName + ' not found.', 5016);
DoSimpleMsg(DSSPrime, 'Class %s not found.', [ClassName], 5016);
Exit;
end;

@@ -257,4 +260,14 @@ procedure DSS_Set_COMErrorResults(Value: TAPIBoolean); CDECL;
DSS_CAPI_COM_DEFAULTS := Value;
end;
//------------------------------------------------------------------------------
function DSS_Get_AllowDOScmd(): TAPIBoolean; CDECL;
begin
Result := DSS_CAPI_ALLOW_DOSCMD;
end;
//------------------------------------------------------------------------------
procedure DSS_Set_AllowDOScmd(Value: TAPIBoolean); CDECL;
begin
DSS_CAPI_ALLOW_DOSCMD := Value;
end;
//------------------------------------------------------------------------------
end.
2 changes: 1 addition & 1 deletion src/CAPI/CAPI_DSSElement.pas
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ function DSSElement_Get_Name(): PAnsiChar; CDECL;
if (InvalidCircuit(DSSPrime)) or (DSSPrime.ActiveDSSObject = NIL) then
Exit;
with DSSPrime.ActiveDSSObject do
Result := DSS_GetAsPAnsiChar(DSSPrime, ParentClass.Name + '.' + Name);
Result := DSS_GetAsPAnsiChar(DSSPrime, FullName);
end;
//------------------------------------------------------------------------------
function DSSElement_Get_NumProperties(): Integer; CDECL;
30 changes: 15 additions & 15 deletions src/CAPI/CAPI_DSSProperty.pas
Original file line number Diff line number Diff line change
@@ -30,9 +30,9 @@ function IsPropIndexInvalid(DSS: TDSSContext; errorNum: Integer): Boolean;

if (DSS.FPropIndex > DSS.ActiveDSSObject.ParentClass.NumProperties) or (DSS.FPropIndex < 1) then
begin
DoSimpleMsg(DSS, Format(
'Invalid property index "%d" for "%s.%s"',
[DSS.FPropIndex, DSS.ActiveDSSObject.ParentClass.Name, DSS.ActiveDSSObject.Name]),
DoSimpleMsg(DSS,
'Invalid property index "%d" for "%s"',
[DSS.FPropIndex, DSS.ActiveDSSObject.FullName],
errorNum
);
Result := TRUE;
@@ -47,13 +47,13 @@ function DSSProperty_Get_Description(): PAnsiChar; CDECL;

if DSSPrime.ActiveDSSObject = NIL then
begin
DoSimpleMsg(DSSPrime, 'No active DSS object found! Activate one and try again.', 33100);
DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33100);
Exit;
end;

with DSSPrime.ActiveDSSObject.ParentClass do
if not IsPropIndexInvalid(DSSPrime, 33006) then
Result := DSS_GetAsPAnsiChar(DSSPrime, PropertyHelp^[DSSPrime.FPropIndex]);
Result := DSS_GetAsPAnsiChar(DSSPrime, GetPropertyHelp(DSSPrime.FPropIndex));
end;
//------------------------------------------------------------------------------
function DSSProperty_Get_Name(): PAnsiChar; CDECL;
@@ -66,7 +66,7 @@ function DSSProperty_Get_Name(): PAnsiChar; CDECL;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSSPrime, 'No active DSS object found! Activate one and try again.', 33101);
DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33101);
end;
Exit;
end;
@@ -87,7 +87,7 @@ function DSSProperty_Get_Val(): PAnsiChar; CDECL;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSSPrime, 'No active DSS object found! Activate one and try again.', 33102);
DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33102);
end;
Exit;
end;
@@ -96,7 +96,7 @@ function DSSProperty_Get_Val(): PAnsiChar; CDECL;
Exit;

with DSSPrime.ActiveDSSObject do
Result := DSS_GetAsPAnsiChar(DSSPrime, PropertyValue[ParentClass.PropertyIdxMap[DSSPrime.FPropIndex]]);
Result := DSS_GetAsPAnsiChar(DSSPrime, PropertyValue[DSSPrime.FPropIndex]);
end;

//------------------------------------------------------------------------------
@@ -109,7 +109,7 @@ procedure DSSProperty_Set_Val(const Value: PAnsiChar); CDECL;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSSPrime, 'No active DSS object found! Activate one and try again.', 33103);
DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33103);
end;
Exit;
end;
@@ -118,7 +118,7 @@ procedure DSSProperty_Set_Val(const Value: PAnsiChar); CDECL;
Exit;

with DSSPrime.ActiveDSSObject do
DSSPrime.DSSExecutive.Command := 'Edit ' + ParentClass.Name + '.' + Name + ' ' + ParentClass.PropertyName^[DSSPrime.FPropIndex] + '=' + (Value);
DSSPrime.DSSExecutive.Command := 'Edit ' + FullName + ' ' + ParentClass.PropertyName^[DSSPrime.FPropIndex] + '=' + (Value);
end;
//------------------------------------------------------------------------------
procedure DSSProperty_Set_Index(const Value: Integer); CDECL;
@@ -130,7 +130,7 @@ procedure DSSProperty_Set_Index(const Value: Integer); CDECL;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSSPrime, 'No active DSS object found! Activate one and try again.', 33104);
DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33104);
end;
Exit;
end;
@@ -152,7 +152,7 @@ procedure DSSProperty_Set_Name(const Value: PAnsiChar); CDECL;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSSPrime, 'No active DSS object found! Activate one and try again.', 33105);
DoSimpleMsg(DSSPrime, _('No active DSS object found! Activate one and try again.'), 33105);
end;
Exit;
end;
@@ -171,9 +171,9 @@ procedure DSSProperty_Set_Name(const Value: PAnsiChar); CDECL;
end;
end;

DoSimpleMsg(DSSPrime, Format(
'Invalid property name "%s" for "%s.%s"',
[String(Value), DSSPrime.FPropClass.Name, DSSPrime.ActiveDSSObject.Name]),
DoSimpleMsg(DSSPrime,
'Invalid property name "%s" for "%s"',
[String(Value), DSSPrime.ActiveDSSObject.FullName],
33003
);
end;
4 changes: 2 additions & 2 deletions src/CAPI/CAPI_DSS_Executive.pas
Original file line number Diff line number Diff line change
@@ -48,12 +48,12 @@ function DSS_Executive_Get_Option(i: Integer): PAnsiChar; CDECL;
//------------------------------------------------------------------------------
function DSS_Executive_Get_CommandHelp(i: Integer): PAnsiChar; CDECL;
begin
Result := DSS_GetAsPAnsiChar(DSSPrime, CommandHelp[i]);
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSHelp('Command.' + ExecCommand[i]));
end;
//------------------------------------------------------------------------------
function DSS_Executive_Get_OptionHelp(i: Integer): PAnsiChar; CDECL;
begin
Result := DSS_GetAsPAnsiChar(DSSPrime, OptionHelp[i]);
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSHelp('Executive.' + ExecOption[i]));
end;
//------------------------------------------------------------------------------
function DSS_Executive_Get_OptionValue(i: Integer): PAnsiChar; CDECL;
2 changes: 1 addition & 1 deletion src/CAPI/CAPI_DSSimComs.pas
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ interface
uses
CAPI_Utils,
CAPI_Types,
UComplex;
UComplex, DSSUcomplex;

procedure DSSimComs_BusVoltagepu(var ResultPtr: PDouble; ResultCount: PAPISize; Index: PtrUInt); CDECL;
procedure DSSimComs_BusVoltagepu_GR(Index: PtrUInt); CDECL;
156 changes: 95 additions & 61 deletions src/CAPI/CAPI_Fuses.pas

Large diffs are not rendered by default.

13 changes: 9 additions & 4 deletions src/CAPI/CAPI_GICSources.pas
Original file line number Diff line number Diff line change
@@ -59,7 +59,7 @@ function _activeObj(DSS: TDSSContext; out obj: TGICSourceObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active GICSource object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['GICSource'], 8989);
end;
Exit;
end;
@@ -126,7 +126,7 @@ procedure GICSources_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'GICSource "' + Value + '" Not Found in Active Circuit.', 77003);
DoSimpleMsg(DSSPrime, 'GICSource "%s" not found in Active Circuit.', [Value], 77003);
end;
end;
//------------------------------------------------------------------------------
@@ -148,7 +148,12 @@ procedure GICSources_Set_Phases(Value: Integer); CDECL;
if not _activeObj(DSSPrime, elem) then
Exit;

elem.nphases := Value;
if Value < 1 then
begin
DoSimpleMsg(DSSPrime, '%s: Number of phases must be a positive integer!', [elem.FullName], 6568);
Exit;
end;
elem.Fnphases := Value;
Elem.NConds := Value; // Force reallocation of terminal info
end;
//------------------------------------------------------------------------------
@@ -344,7 +349,7 @@ procedure GICSources_Set_idx(Value: Integer); CDECL;
elem := DSSPrime.GICSourceClass.ElementList.Get(Value);
if elem = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid GICSource index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['GICSource', Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := elem;
21 changes: 14 additions & 7 deletions src/CAPI/CAPI_Generators.pas
Original file line number Diff line number Diff line change
@@ -65,7 +65,7 @@ function _activeObj(DSS: TDSSContext; out obj: TGeneratorObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active Generator object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['Generator'], 8989);
end;
Exit;
end;
@@ -194,7 +194,7 @@ procedure Generators_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'Generator "' + Value + '" Not Found in Active Circuit.', 5003);
DoSimpleMsg(DSSPrime, 'Generator "%s" not found in Active Circuit.', [Value], 5003);
end;
end;
//------------------------------------------------------------------------------
@@ -270,7 +270,8 @@ procedure Generators_Set_kvar(Value: Double); CDECL;
if not _activeObj(DSSPrime, pGen) then
Exit;

pGen.Presentkvar := Value;
pGen.kvarBase := Value;
pGen.PropertySideEffects(ord(TGeneratorProp.kvar))
end;
//------------------------------------------------------------------------------
procedure Generators_Set_kW(Value: Double); CDECL;
@@ -295,12 +296,18 @@ procedure Generators_Set_PF(Value: Double); CDECL;
//------------------------------------------------------------------------------
procedure Generators_Set_Phases(Value: Integer); CDECL;
var
pGen: TGeneratorObj;
elem: TGeneratorObj;
begin
if not _activeObj(DSSPrime, pGen) then
if not _activeObj(DSSPrime, elem) then
Exit;

pGen.Nphases := Value;
if Value < 1 then
begin
DoSimpleMsg(DSSPrime, '%s: Number of phases must be a positive integer!', [elem.FullName], 6568);
Exit;
end;
elem.FNphases := Value;
//TODO: missing side-effects?
end;
//------------------------------------------------------------------------------
function Generators_Get_Count(): Integer; CDECL;
@@ -328,7 +335,7 @@ procedure Generators_Set_idx(Value: Integer); CDECL;
pGen := DSSPrime.ActiveCircuit.Generators.Get(Value);
if pGen = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid Generator index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['Generator', Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pGen;
6 changes: 3 additions & 3 deletions src/CAPI/CAPI_Isources.pas
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ function _activeObj(DSS: TDSSContext; out obj: TIsourceObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active ISource object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['ISource'], 8989);
end;
Exit;
end;
@@ -121,7 +121,7 @@ procedure ISources_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'ISource "' + Value + '" Not Found in Active Circuit.', 77003);
DoSimpleMsg(DSSPrime, 'ISource "%s" not found in Active Circuit.', [Value], 77003);
end;
end;
//------------------------------------------------------------------------------
@@ -199,7 +199,7 @@ procedure ISources_Set_idx(Value: Integer); CDECL;
pISource := DSSPrime.ISourceClass.ElementList.Get(Value);
if pISource = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid ISource index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['ISource', Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pISource;
55 changes: 23 additions & 32 deletions src/CAPI/CAPI_LineCodes.pas
Original file line number Diff line number Diff line change
@@ -55,10 +55,10 @@ implementation
sysutils,
DSSGlobals,
LineUnits,
ParserDel,
Ucomplex,
UComplex, DSSUcomplex,
DSSClass,
DSSHelper;
DSSHelper,
DSSObjectHelper;

//------------------------------------------------------------------------------
function _activeObj(DSS: TDSSContext; out obj: TLineCodeObj): Boolean; inline;
@@ -73,7 +73,7 @@ function _activeObj(DSS: TDSSContext; out obj: TLineCodeObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active LineCode object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['LineCode'], 8989);
end;
Exit;
end;
@@ -123,7 +123,7 @@ procedure LineCodes_Set_Name(const Value: PAnsiChar); CDECL;
Exit;

if not DSSPrime.LineCodeClass.SetActive(Value) then
DoSimpleMsg(DSSPrime, 'LineCode "' + Value + '" Not Found in Active Circuit.', 51008);
DoSimpleMsg(DSSPrime, 'LineCode "%s" not found in Active Circuit.', [Value], 51008);

// Still same active object if not found
end;
@@ -160,12 +160,9 @@ procedure LineCodes_Set_Units(Value: Integer); CDECL;
with pLineCode do
begin
if Value < dssLineUnitsMaxnum then
begin
DSSPrime.Parser.CmdString := Format('units=%s', [LineUnitsStr(Value)]);
Edit;
end
SetInteger(ord(TLineCodeProp.Units), Value)
else
DoSimpleMsg('Invalid line units integer. Please enter a value within range.', 183);
DoSimpleMsg(_('Invalid line units integer. Please enter a value within range.'), 183);
end;
end;
//------------------------------------------------------------------------------
@@ -208,8 +205,7 @@ procedure LineCodes_Set_R1(Value: Double); CDECL;
if not _activeObj(DSSPrime, pLineCode) then
Exit;

DSSPrime.Parser.CmdString := Format('R1=%g', [Value]);
pLineCode.Edit;
pLineCode.SetDouble(ord(TLineCodeProp.R1), Value)
end;
//------------------------------------------------------------------------------
function LineCodes_Get_X1(): Double; CDECL;
@@ -230,8 +226,7 @@ procedure LineCodes_Set_X1(Value: Double); CDECL;
if not _activeObj(DSSPrime, pLineCode) then
Exit;

DSSPrime.Parser.CmdString := Format('X1=%g', [Value]);
pLineCode.Edit;
pLineCode.SetDouble(ord(TLineCodeProp.X1), Value);
end;
//------------------------------------------------------------------------------
function LineCodes_Get_R0(): Double; CDECL;
@@ -263,8 +258,7 @@ procedure LineCodes_Set_R0(Value: Double); CDECL;
if not _activeObj(DSSPrime, pLineCode) then
Exit;

DSSPrime.Parser.CmdString := Format('R0=%g', [Value]);
pLineCode.Edit;
pLineCode.SetDouble(ord(TLineCodeProp.R0), Value);
end;
//------------------------------------------------------------------------------
procedure LineCodes_Set_X0(Value: Double); CDECL;
@@ -274,8 +268,7 @@ procedure LineCodes_Set_X0(Value: Double); CDECL;
if not _activeObj(DSSPrime, pLineCode) then
Exit;

DSSPrime.Parser.CmdString := Format('X0=%g', [Value]);
pLineCode.Edit;
pLineCode.SetDouble(ord(TLineCodeProp.X0), Value);
end;
//------------------------------------------------------------------------------
function LineCodes_Get_C0(): Double; CDECL;
@@ -307,8 +300,7 @@ procedure LineCodes_Set_C0(Value: Double); CDECL;
if not _activeObj(DSSPrime, pLineCode) then
Exit;

DSSPrime.Parser.CmdString := Format('C0=%g', [Value]);
pLineCode.Edit;
pLineCode.SetDouble(ord(TLineCodeProp.C0), Value);
end;
//------------------------------------------------------------------------------
procedure LineCodes_Set_C1(Value: Double); CDECL;
@@ -318,8 +310,7 @@ procedure LineCodes_Set_C1(Value: Double); CDECL;
if not _activeObj(DSSPrime, pLineCode) then
Exit;

DSSPrime.Parser.CmdString := Format('C1=%g', [Value]);
pLineCode.Edit;
pLineCode.SetDouble(ord(TLineCodeProp.C1), Value);
end;
//------------------------------------------------------------------------------
procedure LineCodes_Get_Cmatrix(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
@@ -438,10 +429,10 @@ procedure LineCodes_Set_Cmatrix(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
begin
if (FNPhases * FNPhases) <> ValueCount then
begin
DoSimpleMsg(Format(
DoSimpleMsg(
'The number of values provided (%d) does not match the expected (%d).',
[ValueCount, FNPhases * FNPhases]
), 183);
[ValueCount, FNPhases * FNPhases],
183);
Exit;
end;

@@ -473,10 +464,10 @@ procedure LineCodes_Set_Rmatrix(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
begin
if (FNPhases * FNPhases) <> ValueCount then
begin
DoSimpleMsg(Format(
DoSimpleMsg(
'The number of values provided (%d) does not match the expected (%d).',
[ValueCount, FNPhases * FNPhases]
), 183);
[ValueCount, FNPhases * FNPhases],
183);
Exit;
end;

@@ -508,10 +499,10 @@ procedure LineCodes_Set_Xmatrix(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
begin
if (FNPhases * FNPhases) <> ValueCount then
begin
DoSimpleMsg(Format(
DoSimpleMsg(
'The number of values provided (%d) does not match the expected (%d).',
[ValueCount, FNPhases * FNPhases]
), 183);
[ValueCount, FNPhases * FNPhases],
183);
Exit;
end;

@@ -594,7 +585,7 @@ function LineCodes_Get_idx(): Integer; CDECL;
procedure LineCodes_Set_idx(Value: Integer); CDECL;
begin
if DSSPrime.LineCodeClass.ElementList.Get(Value) = NIL then
DoSimpleMsg(DSSPrime, 'Invalid LineCode index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['LineCode', Value], 656565);
end;
//------------------------------------------------------------------------------
end.
19 changes: 10 additions & 9 deletions src/CAPI/CAPI_LineGeometries.pas
Original file line number Diff line number Diff line change
@@ -57,7 +57,7 @@ implementation
sysutils,
DSSGlobals,
LineUnits,
Ucomplex,
UComplex, DSSUcomplex,
Line,
UcMatrix,
DSSClass,
@@ -77,7 +77,7 @@ function _activeObj(DSS: TDSSContext; out obj: TLineGeometryObj): Boolean; inlin
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active LineGeometry object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['LineGeometry'], 8989);
end;
Exit;
end;
@@ -126,7 +126,7 @@ procedure LineGeometries_Set_Name(const Value: PAnsiChar); CDECL;
if InvalidCircuit(DSSPrime) then
Exit;
if not DSSPrime.LineGeometryClass.SetActive(Value) then
DoSimpleMsg(DSSPrime, 'LineGeometry "' + Value + '" Not Found in Active Circuit.', 51008);
DoSimpleMsg(DSSPrime, 'LineGeometry "%s" not found in Active Circuit.', [Value], 51008);

// Still same active object if not found
end;
@@ -148,7 +148,7 @@ procedure LineGeometries_Set_Nconds(Value: Integer); CDECL;
begin
if (Value < 1) then
begin
DoSimpleMsg(DSSPrime, Format('Invalid number of conductors (%d). Please use a value within the valid range (>0).', [Value]), 183);
DoSimpleMsg(DSSPrime, 'Invalid number of conductors (%d). Please use a value within the valid range (>0).', [Value], 183);
Exit;
end;
if not _activeObj(DSSPrime, pLineGeometry) then
@@ -175,7 +175,7 @@ procedure LineGeometries_Set_Phases(Value: Integer); CDECL;
begin
if (Value < 1) then
begin
DoSimpleMsg(DSSPrime, 'Invalid number of phases sent via C-API. Please enter a value within range.', 184);
DoSimpleMsg(DSSPrime, _('Invalid number of phases sent via C-API. Please enter a value within range.'), 184);
end;

if not _activeObj(DSSPrime, pLineGeometry) then
@@ -398,7 +398,7 @@ procedure LineGeometries_Set_Units(ValuePtr: PInteger; ValueCount: TAPISize); CD
begin
if Nconds <> ValueCount then
begin
DoSimpleMsg(Format('The number of values provided (%d) does not match the number of conductors (%d).', [ValueCount, NConds]), 183);
DoSimpleMsg('The number of values provided (%d) does not match the number of conductors (%d).', [ValueCount, NConds], 183);
Exit;
end;
Move(ValuePtr[0], FUnits[1], ValueCount * SizeOf(Double));
@@ -440,7 +440,7 @@ procedure LineGeometries_Set_Ycoords(ValuePtr: PDouble; ValueCount: TAPISize); C
begin
if Nconds <> ValueCount then
begin
DoSimpleMsg(Format('The number of values provided (%d) does not match the number of conductors (%d).', [ValueCount, NConds]), 188);
DoSimpleMsg('The number of values provided (%d) does not match the number of conductors (%d).', [ValueCount, NConds], 188);
Exit;
end;
Move(ValuePtr[0], FY[1], ValueCount * SizeOf(Double));
@@ -482,7 +482,7 @@ procedure LineGeometries_Set_Xcoords(ValuePtr: PDouble; ValueCount: TAPISize); C
begin
if Nconds <> ValueCount then
begin
DoSimpleMsg(Format('The number of values provided (%d) does not match the number of conductors (%d).', [ValueCount, NConds]), 187);
DoSimpleMsg('The number of values provided (%d) does not match the number of conductors (%d).', [ValueCount, NConds], 187);
Exit;
end;
Move(ValuePtr[0], FX[1], ValueCount * SizeOf(Double));
@@ -523,6 +523,7 @@ procedure LineGeometries_Get_Conductors(var ResultPtr: PPAnsiChar; ResultCount:
if not _activeObj(DSSPrime, pLineGeometry) then
begin
DefaultResult(ResultPtr, ResultCount);
Exit;
end;

with pLineGeometry do
@@ -568,7 +569,7 @@ procedure LineGeometries_Set_idx(Value: Integer); CDECL;
if InvalidCircuit(DSSPrime) then
Exit;
if DSSPrime.LineGeometryClass.ElementList.Get(Value) = NIL then
DoSimpleMsg(DSSPrime, 'Invalid LineGeometry index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['LineGeometry', Value], 656565);
end;
//------------------------------------------------------------------------------
end.
27 changes: 13 additions & 14 deletions src/CAPI/CAPI_LineSpacings.pas
Original file line number Diff line number Diff line change
@@ -38,8 +38,7 @@ implementation
sysutils,
DSSGlobals,
LineUnits,
ParserDel,
Ucomplex,
UComplex, DSSUcomplex,
Line,
UcMatrix,
DSSClass,
@@ -58,7 +57,7 @@ function _activeObj(DSS: TDSSContext; out obj: TLineSpacingObj): Boolean; inline
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active LineSpacing object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['LineSpacing'], 8989);
end;
Exit;
end;
@@ -107,7 +106,7 @@ procedure LineSpacings_Set_Name(const Value: PAnsiChar); CDECL;
Exit;

if not DSSPrime.LineSpacingClass.SetActive(Value) then
DoSimpleMsg(DSSPrime, 'LineSpacing "' + Value + '" Not Found in Active Circuit.', 51008);
DoSimpleMsg(DSSPrime, 'LineSpacing "%s" not found in Active Circuit.', [Value], 51008);

// Still same active object if not found
end;
@@ -129,12 +128,12 @@ procedure LineSpacings_Set_Nconds(Value: Integer); CDECL;
begin
if (Value < 1) then
begin
DoSimpleMsg(DSSPrime, Format('Invalid number of conductors (%d) sent via C-API. Please use a value within the valid range (>0).', [Value]), 183);
DoSimpleMsg(DSSPrime, 'Invalid number of conductors (%d) sent via C-API. Please use a value within the valid range (>0).', [Value], 183);
end;
if not _activeObj(DSSPrime, pLineSpacing) then
Exit;
pLineSpacing.DataChanged := TRUE;
pLineSpacing.NWires := Value;
pLineSpacing.FNConds := Value;
pLineSpacing.PropertySideEffects(ord(TLineSpacingProp.NConds), 0);
end;
//------------------------------------------------------------------------------
function LineSpacings_Get_Phases(): Integer; CDECL;
@@ -193,10 +192,10 @@ procedure LineSpacings_Set_Ycoords(ValuePtr: PDouble; ValueCount: TAPISize); CDE
begin
if NWires <> ValueCount then
begin
DoSimpleMsg(Format(
DoSimpleMsg(
'The number of values provided (%d) does not match the number of wires (%d).',
[ValueCount, NWires]
), 183);
[ValueCount, NWires],
183);
Exit;
end;
Move(ValuePtr^, FY[1], ValueCount * SizeOf(Double));
@@ -239,10 +238,10 @@ procedure LineSpacings_Set_Xcoords(ValuePtr: PDouble; ValueCount: TAPISize); CDE
begin
if NWires <> ValueCount then
begin
DoSimpleMsg(Format(
DoSimpleMsg(
'The number of values provided (%d) does not match the number of wires (%d).',
[ValueCount, NWires]
), 183);
[ValueCount, NWires],
183);
Exit;
end;
Move(ValuePtr^, FX[1], ValueCount * SizeOf(Double));
@@ -296,7 +295,7 @@ function LineSpacings_Get_idx(): Integer; CDECL;
procedure LineSpacings_Set_idx(Value: Integer); CDECL;
begin
if DSSPrime.LineSpacingClass.ElementList.Get(Value) = NIL then
DoSimpleMsg(DSSPrime, 'Invalid LineSpacing index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['LineSpacing', Value], 656565);
end;
//------------------------------------------------------------------------------
end.
132 changes: 61 additions & 71 deletions src/CAPI/CAPI_Lines.pas
Original file line number Diff line number Diff line change
@@ -83,15 +83,15 @@ implementation
DSSClassDefs,
DSSGlobals,
CktElement,
uComplex,
UComplex, DSSUcomplex,
ExecHelper,
Sysutils,
ParserDel,
Math,
LineUnits,
XYCurve,
DSSClass,
DSSHelper;
DSSHelper,
DSSObjectHelper;

//------------------------------------------------------------------------------
function _activeObj(DSS: TDSSContext; out obj: TLineObj): Boolean; inline;
@@ -111,7 +111,7 @@ function _activeObj(DSS: TDSSContext; out obj: TLineObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active Line object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['Line'], 8989);
end;
Exit;
end;
@@ -121,8 +121,8 @@ function _activeObj(DSS: TDSSContext; out obj: TLineObj): Boolean; inline;

if obj = NIL {((CktElem.DssObjtype and CLASSMASK) <> LINE_ELEMENT)} then
begin
DoSimpleMsg(DSS, 'Line Type Expected, but another found. DSS Class=' + CktElem.DSSClassName + CRLF +
'Element name=' + CktElem.Name, 5007);
DoSimpleMsg(DSS, 'Line Type Expected, but another found. DSS Class=%s, Element Name="%s"',
[CktElem.DSSClassName, CktElem.Name], 5007);
Exit;
end;

@@ -197,7 +197,8 @@ function Lines_Get_LineCode(): PAnsiChar; CDECL;
Result := NIL;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.CondCode);
if elem.LineCodeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.LineCodeObj.Name);
end;
//------------------------------------------------------------------------------
function Lines_Get_Name(): PAnsiChar; CDECL;
@@ -242,7 +243,7 @@ function Lines_Get_X1(): Double; CDECL;
//------------------------------------------------------------------------------
function Lines_New(const Name: PAnsiChar): Integer; CDECL;
begin
Result := DSSPrime.DSSExecutive.AddObject('line', Name); // Returns handle to object
DSSPrime.LineClass.NewObject(Name, True, Result);
end;
//------------------------------------------------------------------------------
procedure Lines_Set_Bus1(const Value: PAnsiChar); CDECL;
@@ -279,7 +280,14 @@ procedure Lines_Set_LineCode(const Value: PAnsiChar); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.FetchLineCode(Value);

elem.LineCodeObj := DSSPrime.LineCodeClass.Find(Value);
if elem.LineCodeObj = NIL then
begin
DoSimpleMsg(DSSPrime, 'LineCode "%s" not found.', [Value], 5009);
Exit;
end;
elem.FetchLineCode(); // Note: original didn't reproduce all side-effects from parser
elem.YprimInvalid := TRUE;
end;
//------------------------------------------------------------------------------
@@ -294,7 +302,7 @@ procedure Lines_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'Line "' + Value + '" Not Found in Active Circuit.', 5008);
DoSimpleMsg(DSSPrime, 'Line "%s" not found in Active Circuit.', [Value], 5008);
end;
end;
//------------------------------------------------------------------------------
@@ -304,7 +312,12 @@ procedure Lines_Set_Phases(Value: Integer); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.Nphases := Value;
if Value < 1 then
begin
DoSimpleMsg(DSSPrime, '%s: Number of phases must be a positive integer!', [elem.FullName], 6568);
Exit;
end;
elem.FNphases := Value;
elem.YprimInvalid := TRUE;
end;
//------------------------------------------------------------------------------
@@ -314,7 +327,7 @@ procedure Lines_Set_R1(Value: Double); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.R1 := Value;
elem.R1 := Value * elem.UnitsConvert;
elem.SymComponentsChanged := TRUE;
elem.YprimInvalid := TRUE;
end;
@@ -325,7 +338,7 @@ procedure Lines_Set_X1(Value: Double); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.X1 := Value;
elem.X1 := Value * elem.UnitsConvert;
elem.SymComponentsChanged := TRUE;
elem.YprimInvalid := TRUE;
end;
@@ -484,7 +497,7 @@ procedure Lines_Set_C0(Value: Double); CDECL;
Exit;
with elem do
begin
C0 := Value * 1.0e-9;
C0 := Value * 1.0e-9 * UnitsConvert;
SymComponentsChanged := TRUE;
YprimInvalid := TRUE;
end;
@@ -498,7 +511,7 @@ procedure Lines_Set_C1(Value: Double); CDECL;
Exit;
with elem do
begin
C1 := Value * 1.0e-9;
C1 := Value * 1.0e-9 * UnitsConvert;
SymComponentsChanged := TRUE;
YprimInvalid := TRUE;
end;
@@ -518,10 +531,10 @@ procedure Lines_Set_Cmatrix(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
begin
if (NPhases * NPhases) <> ValueCount then
begin
DoSimpleMsg(Format(
DoSimpleMsg(
'The number of values provided (%d) does not match the expected (%d).',
[ValueCount, NPhases * NPhases]
), 183);
[ValueCount, NPhases * NPhases],
183);
Exit;
end;

@@ -545,7 +558,7 @@ procedure Lines_Set_R0(Value: Double); CDECL;
Exit;
with elem do
begin
R0 := Value;
R0 := Value * UnitsConvert;
SymComponentsChanged := TRUE;
YprimInvalid := TRUE;
end;
@@ -565,10 +578,10 @@ procedure Lines_Set_Rmatrix(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
begin
if (NPhases * NPhases) <> ValueCount then
begin
DoSimpleMsg(Format(
DoSimpleMsg(
'The number of values provided (%d) does not match the expected (%d).',
[ValueCount, NPhases * NPhases]
), 183);
[ValueCount, NPhases * NPhases],
183);
Exit;
end;

@@ -592,7 +605,7 @@ procedure Lines_Set_X0(Value: Double); CDECL;
Exit;
with elem do
begin
X0 := Value;
X0 := Value * UnitsConvert;
SymComponentsChanged := TRUE;
YprimInvalid := TRUE;
end;
@@ -613,9 +626,9 @@ procedure Lines_Set_Xmatrix(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
begin
if (NPhases * NPhases) <> ValueCount then
begin
DoSimpleMsg(Format('The number of values provided (%d) does not match the expected (%d).',
[ValueCount, NPhases * NPhases]
), 183);
DoSimpleMsg('The number of values provided (%d) does not match the expected (%d).',
[ValueCount, NPhases * NPhases],
183);
Exit;
end;

@@ -676,7 +689,8 @@ function Lines_Get_Geometry(): PAnsiChar; CDECL;
Result := NIL;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.GeometryCode);
if elem.LineGeometryObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.LineGeometryObj.Name);
end;
//------------------------------------------------------------------------------
procedure Lines_Set_Geometry(const Value: PAnsiChar); CDECL;
@@ -685,12 +699,7 @@ procedure Lines_Set_Geometry(const Value: PAnsiChar); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
with elem do
begin
DSSPrime.Parser.CmdString := 'geometry=' + Value;
Edit;
YprimInvalid := TRUE;
end;
elem.ParsePropertyValue(ord(TLineProp.geometry), Value); // calls FetchGeometryCode and sets YPrimInvalid
end;
//------------------------------------------------------------------------------
function Lines_Get_Rg(): Double; CDECL;
@@ -729,12 +738,8 @@ procedure Lines_Set_Rg(Value: Double); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
with elem do
begin
DSSPrime.Parser.CmdString := Format('rg=%.7g', [Value]);
Edit;
YprimInvalid := TRUE;
end;
elem.SetDouble(ord(TLineProp.Rg), Value); //TODO: it doesn't seem to set YPrimInvalid
elem.YprimInvalid := TRUE;
end;
//------------------------------------------------------------------------------
procedure Lines_Set_Rho(Value: Double); CDECL;
@@ -743,12 +748,8 @@ procedure Lines_Set_Rho(Value: Double); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
with elem do
begin
DSSPrime.Parser.CmdString := Format('rho=%.7g', [Value]);
Edit;
YprimInvalid := TRUE;
end;
elem.SetDouble(ord(TLineProp.rho), Value); //TODO: it doesn't seem to set YPrimInvalid
elem.YprimInvalid := TRUE;
end;
//------------------------------------------------------------------------------
procedure Lines_Set_Xg(Value: Double); CDECL;
@@ -757,16 +758,12 @@ procedure Lines_Set_Xg(Value: Double); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
with elem do
begin
DSSPrime.Parser.CmdString := Format('xg=%.7g', [Value]);
Edit;
YprimInvalid := TRUE;
end;
elem.SetDouble(ord(TLineProp.xg), Value); //TODO: it doesn't seem to set YPrimInvalid
elem.YprimInvalid := TRUE;
end;
//------------------------------------------------------------------------------
procedure Lines_Get_Yprim(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
{ Return the YPrim matrix for this element }
// Return the YPrim matrix for this element
var
NValues: Integer;
cValues: pComplexArray;
@@ -806,9 +803,9 @@ procedure Lines_Set_Yprim(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
if not _activeObj(DSSPrime, elem) then
Exit;

{Do Nothing for now}
// Do Nothing for now

DoSimpleMsg(DSSPrime, 'Setting Yprim is currently not allowed.', 1833);
DoSimpleMsg(DSSPrime, _('Setting Yprim is currently not allowed.'), 1833);
end;
//------------------------------------------------------------------------------
function Lines_Get_NumCust(): Integer; CDECL;
@@ -866,7 +863,8 @@ function Lines_Get_Spacing(): PAnsiChar; CDECL;
Result := NIL;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.SpacingCode);
if elem.LineSpacingObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.LineSpacingObj.Name);
end;
//------------------------------------------------------------------------------
procedure Lines_Set_Spacing(const Value: PAnsiChar); CDECL;
@@ -875,12 +873,7 @@ procedure Lines_Set_Spacing(const Value: PAnsiChar); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
with elem do
begin
DSSPrime.Parser.CmdString := 'spacing=' + Value;
Edit;
YprimInvalid := TRUE;
end;
elem.ParsePropertyValue(ord(TLineProp.spacing), Value); // Sets YprimInvalid
end;
//------------------------------------------------------------------------------
function Lines_Get_Units(): Integer; CDECL;
@@ -894,10 +887,8 @@ function Lines_Get_Units(): Integer; CDECL;
end;
//------------------------------------------------------------------------------
procedure Lines_Set_Units(Value: Integer); CDECL;
{
This code assumes the present value of line units is NONE.
The Set functions in this interface all set values in this length unit.
}
// This code assumes the present value of line units is NONE.
// The Set functions in this interface all set values in this length unit.
var
elem: TLineObj;
begin
@@ -907,12 +898,11 @@ procedure Lines_Set_Units(Value: Integer); CDECL;
begin
if (Value >= dssLineUnitsNone) and (Value < dssLineUnitsMaxnum) then
begin
DSSPrime.Parser.CmdString := Format('units=%s', [LineUnitsStr(Value)]);
Edit;
ParsePropertyValue(ord(TLineProp.units), LineUnitsStr(Value));
YprimInvalid := TRUE;
end
else
DoSimpleMsg('Invalid line units code. Please enter a value within range.', 183);
DoSimpleMsg(_('Invalid line units code. Please enter a value within range.'), 183);
end;
end;
//------------------------------------------------------------------------------
@@ -933,7 +923,7 @@ procedure Lines_Set_idx(Value: Integer); CDECL;
pLine := DSSPrime.ActiveCircuit.Lines.Get(Value);
if pLine = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid Line index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['Line', Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pLine;
@@ -983,8 +973,8 @@ procedure Lines_Set_IsSwitch(Value: TAPIBoolean); CDECL;
// Side effects from Line.pas
SymComponentsChanged := TRUE;
YprimInvalid := TRUE;
GeometrySpecified := FALSE;
SpacingSpecified := FALSE;
KillGeometrySpecified();
KillSpacingSpecified();
r1 := 1.0;
x1 := 1.0;
r0 := 1.0;
20 changes: 10 additions & 10 deletions src/CAPI/CAPI_LoadShapes.pas
Original file line number Diff line number Diff line change
@@ -74,7 +74,7 @@ function _activeObj(DSS: TDSSContext; out obj: TLoadshapeObj): Boolean; inline;
obj := DSS.LoadshapeClass.GetActiveObj;
if obj = NIL then
begin
DoSimpleMsg(DSS, 'No active Loadshape Object found.', 61001);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['Loadshape'], 61001);
Exit;
end;

@@ -98,7 +98,7 @@ procedure LoadShapes_Set_Name(const Value: PAnsiChar); CDECL;
Exit;
if DSSPrime.LoadshapeClass.SetActive(Value) then
Exit;
DoSimpleMsg(DSSPrime, 'LoadShape "' + Value + '" Not Found in Active Circuit.', 77003);
DoSimpleMsg(DSSPrime, 'LoadShape "%s" not found in Active Circuit.', [Value], 77003);
end;
//------------------------------------------------------------------------------
function LoadShapes_Get_Count(): Integer; CDECL;
@@ -228,14 +228,14 @@ procedure LoadShapes_Set_Pmult(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
begin
if elem.ExternalMemory then
begin
DoSimpleMsg('Data cannot be changed for LoadShapes with external memory! Reset the data first.', 61101);
DoSimpleMsg(_('Data cannot be changed for LoadShapes with external memory! Reset the data first.'), 61101);
Exit;
end;

// Only accept the new data when the number of points match
if ValueCount <> NumPoints then
begin
DoSimpleMsg(Format('The number of values (%d) does not match the current Npts (%d)!', [ValueCount, NumPoints]), 61100);
DoSimpleMsg('The number of values (%d) does not match the current Npts (%d)!', [ValueCount, NumPoints], 61100);
Exit;
end;
ReallocMem(sP, 0);
@@ -256,14 +256,14 @@ procedure LoadShapes_Set_Qmult(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
begin
if ExternalMemory then
begin
DoSimpleMsg('Data cannot be changed for LoadShapes with external memory! Reset the data first.', 61101);
DoSimpleMsg(_('Data cannot be changed for LoadShapes with external memory! Reset the data first.'), 61101);
Exit;
end;

// Only accept the new data when the number of points match
if ValueCount <> NumPoints then
begin
DoSimpleMsg(Format('The number of values (%d) does not match the current Npts (%d)!', [ValueCount, NumPoints]), 61101);
DoSimpleMsg('The number of values (%d) does not match the current Npts (%d)!', [ValueCount, NumPoints], 61101);
Exit;
end;
ReallocMem(sQ, 0);
@@ -317,14 +317,14 @@ procedure LoadShapes_Set_TimeArray(ValuePtr: PDouble; ValueCount: TAPISize); CDE
begin
if elem.ExternalMemory then
begin
DoSimpleMsg('Data cannot be changed for LoadShapes with external memory! Reset the data first.', 61101);
DoSimpleMsg(_('Data cannot be changed for LoadShapes with external memory! Reset the data first.'), 61101);
Exit;
end;

// Only accept the new data when the number of points match
if ValueCount <> NumPoints then
begin
DoSimpleMsg(Format('The number of values (%d) does not match the current Npts (%d)!', [ValueCount, NumPoints]), 61102);
DoSimpleMsg('The number of values (%d) does not match the current Npts (%d)!', [ValueCount, NumPoints], 61102);
Exit;
end;
ReallocMem(sH, 0);
@@ -393,7 +393,7 @@ procedure LoadShapes_Set_SInterval(Value: Double); CDECL;
//------------------------------------------------------------------------------
function LoadShapes_New(const Name: PAnsiChar): Integer; CDECL;
begin
Result := DSSPrime.DSSExecutive.AddObject('loadshape', Name); // Returns handle to object
DSSPrime.LoadShapeClass.NewObject(Name, True, Result);
end;
//------------------------------------------------------------------------------
function LoadShapes_Get_PBase(): Double; CDECL;
@@ -461,7 +461,7 @@ function LoadShapes_Get_idx(): Integer; CDECL;
procedure LoadShapes_Set_idx(Value: Integer); CDECL;
begin
if DSSPrime.LoadShapeClass.ElementList.Get(Value) = NIL then
DoSimpleMsg(DSSPrime, 'Invalid LoadShape index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['LoadShape', Value], 656565);
end;
//------------------------------------------------------------------------------
procedure LoadShapes_Set_Points(Npts: TAPISize; HoursPtr: Pointer; PMultPtr: Pointer; QMultPtr: Pointer; ExternalMemory: TAPIBoolean; IsFloat32: TAPIBoolean; Stride: Integer); CDECL;
365 changes: 155 additions & 210 deletions src/CAPI/CAPI_Loads.pas

Large diffs are not rendered by default.

30 changes: 16 additions & 14 deletions src/CAPI/CAPI_Meters.pas
Original file line number Diff line number Diff line change
@@ -80,12 +80,13 @@ implementation
EnergyMeter,
DSSGlobals,
SysUtils,
ucomplex,
UComplex, DSSUcomplex,
CktElement,
PDElement,
CktTree,
DSSClass,
DSSHelper;
DSSHelper,
DSSObjectHelper;

//------------------------------------------------------------------------------
function _activeObj(DSS: TDSSContext; out obj: TEnergyMeterObj): Boolean; inline;
@@ -100,7 +101,7 @@ function _activeObj(DSS: TDSSContext; out obj: TEnergyMeterObj): Boolean; inline
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active EnergyMeter object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['EnergyMeter'], 8989);
end;
Exit;
end;
@@ -110,7 +111,7 @@ function _activeObj(DSS: TDSSContext; out obj: TEnergyMeterObj): Boolean; inline
//------------------------------------------------------------------------------
procedure InvalidActiveSection(DSS: TDSSContext); inline;
begin
DoSimpleMsg(DSS, 'Invalid active section. Has SetActiveSection been called?', 5055);
DoSimpleMsg(DSS, _('Invalid active section. Has SetActiveSection been called?'), 5055);
end;
//------------------------------------------------------------------------------
procedure Meters_Get_AllNames(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CDECL;
@@ -250,7 +251,7 @@ procedure Meters_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'EnergyMeter "' + Value + '" Not Found in Active Circuit.', 5005);
DoSimpleMsg(DSSPrime, 'EnergyMeter "%s" not found in Active Circuit.', [Value], 5005);
end;
end;
//------------------------------------------------------------------------------
@@ -307,7 +308,7 @@ procedure Meters_Set_Peakcurrent(ValuePtr: PDouble; ValueCount: TAPISize); CDECL

if ValueCount <> pMeterObj.NPhases then
begin
DoSimpleMsg(DSSPrime, 'The provided number of values does not match the element''s number of phases.', 5026);
DoSimpleMsg(DSSPrime, _('The provided number of values does not match the element''s number of phases.'), 5026);
Exit;
end;
Move(ValuePtr^, pMeterObj.SensorCurrent[1], ValueCount * SizeOf(Double));
@@ -348,7 +349,7 @@ procedure Meters_Set_CalcCurrent(ValuePtr: PDouble; ValueCount: TAPISize); CDECL

if ValueCount <> pMeterObj.NPhases then
begin
DoSimpleMsg(DSSPrime, 'The provided number of values does not match the element''s number of phases.', 5025);
DoSimpleMsg(DSSPrime, _('The provided number of values does not match the element''s number of phases.'), 5025);
Exit;
end;

@@ -390,7 +391,7 @@ procedure Meters_Set_AllocFactors(ValuePtr: PDouble; ValueCount: TAPISize); CDEC
Value := PDoubleArray0(ValuePtr);
if ValueCount <> pMeterObj.NPhases then
begin
DoSimpleMsg(DSSPrime, 'The provided number of values does not match the element''s number of phases.', 5026);
DoSimpleMsg(DSSPrime, _('The provided number of values does not match the element''s number of phases.'), 5026);
Exit;
end;

@@ -408,7 +409,8 @@ function Meters_Get_MeteredElement(): PAnsiChar; CDECL;
if not _activeObj(DSSPrime, pMeterObj) then
Exit;

Result := DSS_GetAsPAnsiChar(DSSPrime, pMeterObj.ElementName);
if pMeterObj.MeteredElement <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, AnsiLowerCase(pMeterObj.MeteredElement.FullName));
end;
//------------------------------------------------------------------------------
function Meters_Get_MeteredTerminal(): Integer; CDECL;
@@ -429,7 +431,7 @@ procedure Meters_Set_MeteredElement(const Value: PAnsiChar); CDECL;
if not _activeObj(DSSPrime, pMeterObj) then
Exit;

pMeterObj.elementName := Value;
pMeterObj.ParsePropertyValue(ord(TEnergyMeterProp.element), Value);
pMeterObj.MeteredElementChanged := TRUE;
pMeterObj.RecalcElementData;
end;
@@ -506,7 +508,7 @@ procedure Meters_Get_AllEndElements(var ResultPtr: PPAnsiChar; ResultCount: PAPI
begin
pMeterObj.BranchList.ZoneEndsList.Get(k + 1, node);
elem := node.CktObject;
Result[k] := DSS_CopyStringAsPChar(Format('%s.%s', [elem.ParentClass.Name, elem.Name]));
Result[k] := DSS_CopyStringAsPChar(elem.FullName);
end;
end;

@@ -567,7 +569,7 @@ procedure Meters_Get_AllBranchesInZone(var ResultPtr: PPAnsiChar; ResultCount: P
k := 0;
while pElem <> NIL do
begin
Result[k] := DSS_CopyStringAsPChar(Format('%s.%s', [pElem.ParentClass.Name, pElem.Name]));
Result[k] := DSS_CopyStringAsPChar(pElem.FullName);
inc(k);
pElem := pMeterObj.BranchList.GoForward;
end;
@@ -636,7 +638,7 @@ procedure Meters_Set_SequenceIndex(Value: Integer); CDECL;
if (Value > 0) and (Value <= SequenceList.Count) then
DSSPrime.ActiveCircuit.ActiveCktElement := SequenceList.Get(Value)
else
DoSimpleMsg(Format('Invalid index for SequenceList: %d. List size is %d.', [Value, SequenceList.Count]), 500501);
DoSimpleMsg('Invalid index for SequenceList: %d. List size is %d.', [Value, SequenceList.Count], 500501);
end;
end;
//------------------------------------------------------------------------------
@@ -899,7 +901,7 @@ procedure Meters_Set_idx(Value: Integer); CDECL;
pEnergyMeter := DSSPrime.ActiveCircuit.EnergyMeters.Get(Value);
if pEnergyMeter = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid Meter index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['Meter', Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pEnergyMeter;
22 changes: 11 additions & 11 deletions src/CAPI/CAPI_Monitors.pas
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
unit CAPI_Monitors;

//TODO: remove AuxParser usage

interface

uses
@@ -81,7 +79,7 @@ function _activeObj(DSSPrime: TDSSContext; out obj: TMonitorObj): Boolean; inlin
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSSPrime, 'No active Monitor object found! Activate one and retry.', 8989);
DoSimpleMsg(DSSPrime, 'No active %s object found! Activate one and retry.', ['Monitor'], 8989);
end;
Exit;
end;
@@ -215,7 +213,7 @@ procedure Monitors_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'Monitor "' + Value + '" Not Found in Active Circuit.', 5004);
DoSimpleMsg(DSSPrime, 'Monitor "%s" not found in Active Circuit.', [Value], 5004);
end;
end;
//------------------------------------------------------------------------------
@@ -311,10 +309,10 @@ procedure Monitors_Get_Channel(var ResultPtr: PDouble; ResultCount: PAPISize; In

if (Index < 1) or (Index > pMon.RecordSize {NumChannels}) then
begin
DoSimpleMsg(DSSPrime, Format(
DoSimpleMsg(DSSPrime,
'Monitors.Channel: invalid channel index (%d), monitor "%s" has %d channels.',
[Index, pMon.Name, pMon.RecordSize]
), 5888);
[Index, pMon.Name, pMon.RecordSize],
5888);
Exit;
end;
Result := DSS_RecreateArray_PDouble(ResultPtr, ResultCount, pMon.SampleCount);
@@ -518,7 +516,9 @@ function Monitors_Get_Element(): PAnsiChar; CDECL;
Result := NIL;
if not _activeObj(DSSPrime, pMon) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, pMon.ElementName);

if pMon.MeteredElement <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, AnsiLowerCase(pMon.MeteredElement.FullName));
end;
//------------------------------------------------------------------------------
procedure Monitors_Set_Element(const Value: PAnsiChar); CDECL;
@@ -527,8 +527,8 @@ procedure Monitors_Set_Element(const Value: PAnsiChar); CDECL;
begin
if not _activeObj(DSSPrime, pMon) then
Exit;
pMon.ElementName := Value;
pMon.PropertyValue[1] := Value;
pMon.ParsePropertyValue(ord(TMonitorProp.element), Value);
pMon.SetAsNextSeq(ord(TMonitorProp.Element));
pMon.RecalcElementData;
end;
//------------------------------------------------------------------------------
@@ -570,7 +570,7 @@ procedure Monitors_Set_idx(Value: Integer); CDECL;
pMonitor := DSSPrime.ActiveCircuit.Monitors.Get(Value);
if pMonitor = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid Monitor index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['Monitor', Value], 656565);
Exit;
end;

135 changes: 135 additions & 0 deletions src/CAPI/CAPI_NoParallel.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
unit CAPI_NoParallel;

interface

uses
CAPI_Utils,
CAPI_Types;

{$IFNDEF DSS_CAPI_PM}
function Parallel_Get_NumCPUs(): Integer; CDECL;
function Parallel_Get_NumCores(): Integer; CDECL;
function Parallel_Get_ActiveActor(): Integer; CDECL;
procedure Parallel_Set_ActiveActor(Value: Integer); CDECL;
procedure Parallel_CreateActor(); CDECL;
function Parallel_Get_ActorCPU(): Integer; CDECL;
procedure Parallel_Set_ActorCPU(Value: Integer); CDECL;
function Parallel_Get_NumOfActors(): Integer; CDECL;
procedure Parallel_Wait(); CDECL;
procedure Parallel_Get_ActorProgress(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL;
procedure Parallel_Get_ActorProgress_GR(); CDECL;
procedure Parallel_Get_ActorStatus(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL;
procedure Parallel_Get_ActorStatus_GR(); CDECL;
function Parallel_Get_ActiveParallel(): Integer; CDECL;
procedure Parallel_Set_ActiveParallel(Value: Integer); CDECL;
function Parallel_Get_ConcatenateReports(): Integer; CDECL;
procedure Parallel_Set_ConcatenateReports(Value: Integer); CDECL;
{$ENDIF}

implementation

uses
CAPI_Constants,
DSSGlobals,
Executive,
SysUtils,
solution,
CktElement,
KLUSolve,
Classes,
DSSClass,
DSSHelper;

{$IFNDEF DSS_CAPI_PM}
function NotAvailable(DSS: TDSSContext): Integer;
begin
DoSimpleMsg(DSS, _('Parallel machine functions were not compiled'), 7982);
Result := -1;
end;

function Parallel_Get_NumCPUs(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

function Parallel_Get_NumCores(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

function Parallel_Get_ActiveActor(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

procedure Parallel_Set_ActiveActor(Value: Integer); CDECL;
begin
NotAvailable(DSSPrime);
end;

procedure Parallel_CreateActor(); CDECL;
begin
NotAvailable(DSSPrime);
end;

function Parallel_Get_ActorCPU(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

procedure Parallel_Set_ActorCPU(Value: Integer); CDECL;
begin
NotAvailable(DSSPrime);
end;

function Parallel_Get_NumOfActors(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

procedure Parallel_Wait(); CDECL;
begin
NotAvailable(DSSPrime);
end;

procedure Parallel_Get_ActorProgress(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL;
begin
NotAvailable(DSSPrime);
end;

procedure Parallel_Get_ActorProgress_GR(); CDECL;
begin
NotAvailable(DSSPrime);
end;

procedure Parallel_Get_ActorStatus(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL;
begin
NotAvailable(DSSPrime);
end;

procedure Parallel_Get_ActorStatus_GR(); CDECL;
begin
NotAvailable(DSSPrime);
end;

function Parallel_Get_ActiveParallel(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

procedure Parallel_Set_ActiveParallel(Value: Integer); CDECL;
begin
NotAvailable(DSSPrime);
end;

function Parallel_Get_ConcatenateReports(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

procedure Parallel_Set_ConcatenateReports(Value: Integer); CDECL;
begin
NotAvailable(DSSPrime);
end;
{$ENDIF}
end.
1,758 changes: 1,758 additions & 0 deletions src/CAPI/CAPI_Obj.pas

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions src/CAPI/CAPI_PDElements.pas
Original file line number Diff line number Diff line change
@@ -66,7 +66,7 @@ implementation
DSSPointerList,
Bus,
XYCurve,
ucomplex,
UComplex, DSSUcomplex,
ArrayDef,
Utilities,
Math,
@@ -88,7 +88,7 @@ function _activeObj(DSS: TDSSContext; out obj: TPDElement): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active PD Element found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, _('No active PD Element found! Activate one and retry.'), 8989);
end;
Exit;
end;
@@ -97,7 +97,7 @@ function _activeObj(DSS: TDSSContext; out obj: TPDElement): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active PD Element found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, _('No active PD Element found! Activate one and retry.'), 8989);
end;
Exit;
end;
@@ -188,7 +188,7 @@ function PDElements_Get_Name(): PAnsiChar; CDECL;
Result := NIL; // return null if not a PD element
if not _activeObj(DSSPrime, ActivePDElement) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, Format('%s.%s', [ActivePDElement.Parentclass.Name, ActivePDElement.Name])); // full name
Result := DSS_GetAsPAnsiChar(DSSPrime, ActivePDElement.FullName); // full name
end;

//------------------------------------------------------------------------------
@@ -208,7 +208,7 @@ procedure PDElements_Set_Name(const Value: PAnsiChar); CDECL; //TODO: rewrite to
while Assigned(ActivePDElement) do
with ActivePDelement do
begin
if (CompareText(TestString, Format('%s.%s', [Parentclass.Name, Name])) = 0) then
if (AnsiCompareText(TestString, FullName) = 0) then
begin
ActiveCktElement := ActivePDElement;
Break;
@@ -361,7 +361,7 @@ procedure PDElements_Get_AllNames(var ResultPtr: PPAnsiChar; ResultCount: PAPISi
begin
// if (elem.Enabled or DSS_CAPI_ITERATE_DISABLED) then
begin
Result[k] := DSS_CopyStringAsPChar(elem.DSSClassName + '.' + elem.Name);
Result[k] := DSS_CopyStringAsPChar(elem.FullName);
Inc(k);
end;
elem := pList.Next;
@@ -882,7 +882,7 @@ procedure PDElements_Get_AllSeqPowers(var ResultPtr: PDouble; ResultCount: PAPIS
k := (j - 1) * NConds;
n := NodeRef^[k + 1];
Vph[1] := Solution.NodeV^[n]; // Get voltage at node
S := Cmul(Vph[1], conjg(cBuffer^[k + 1])); // Compute power per phase
S := Vph[1] * cong(cBuffer^[k + 1]); // Compute power per phase
Result[icount] := S.re * 0.003; // 3-phase kW conversion
Result[icount + 1] := S.im * 0.003; // 3-phase kvar conversion
Inc(icount, 6);
@@ -917,7 +917,7 @@ procedure PDElements_Get_AllSeqPowers(var ResultPtr: PDouble; ResultCount: PAPIS

for i := 1 to 3 do
begin
S := Cmul(V012[i], conjg(I012[i]));
S := V012[i] * cong(I012[i]);
Result[icount] := S.re * 0.003; // 3-phase kW conversion
Result[icount + 1] := S.im * 0.003; // 3-phase kW conversion
Inc(icount, 2);
108 changes: 63 additions & 45 deletions src/CAPI/CAPI_PVSystems.pas
Original file line number Diff line number Diff line change
@@ -59,6 +59,21 @@ implementation
DSSClass,
DSSHelper;


function ErrorIfTShapeNil(DSS: TDSSContext; name: String): Pointer;
begin
Result := DSS.TShapeClass.Find(name);
if (Result = NIL) and (DSS_CAPI_EXT_ERRORS) then
DoSimpleMsg(DSS, 'TShape "%s" not found!', [name], 89891);
end;

function ErrorIfLoadShapeNil(DSS: TDSSContext; name: String): Pointer;
begin
Result := DSS.LoadShapeClass.Find(name);
if (Result = NIL) and (DSS_CAPI_EXT_ERRORS) then
DoSimpleMsg(DSS, 'LoadShape "%s" not found!', [name], 89891);
end;

//------------------------------------------------------------------------------
function _activeObj(DSS: TDSSContext; out obj: TPVSystemObj): Boolean; inline;
begin
@@ -72,7 +87,7 @@ function _activeObj(DSS: TDSSContext; out obj: TPVSystemObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active PVSystem object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['PVSystem'], 8989);
end;
Exit;
end;
@@ -92,7 +107,7 @@ function _activeObj2(DSS: TDSSContext; out obj: TPVSystem2Obj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active PVSystem object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['PVSystem'], 8989);
end;
Exit;
end;
@@ -230,7 +245,7 @@ procedure PVSystems_Set_idx(Value: Integer); CDECL;
pPVSystem := DSSPrime.ActiveCircuit.PVSystems.Get(Value);
if pPVSystem = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid PVSystem index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['PVSystem', Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pPVSystem;
@@ -268,7 +283,7 @@ procedure PVSystems_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'PVSystem "' + Value + '" Not Found in Active Circuit.', 5003);
DoSimpleMsg(DSSPrime, 'PVSystem "%s" not found in Active Circuit.', [Value], 5003);
end;
Exit;
end;
@@ -280,7 +295,7 @@ procedure PVSystems_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'PVSystem "' + Value + '" Not Found in Active Circuit.', 5003);
DoSimpleMsg(DSSPrime, 'PVSystem "%s" not found in Active Circuit.', [Value], 5003);
end;
end;
//------------------------------------------------------------------------------
@@ -456,12 +471,14 @@ function PVSystems_Get_daily(): PAnsiChar; CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.DailyShape);
if elem.DailyShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.DailyShapeObj.Name);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.DailyShape);
if elem2.DailyShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.DailyShapeObj.Name);
end;
//------------------------------------------------------------------------------
procedure PVSystems_Set_daily(const Value: PAnsiChar); CDECL;
@@ -473,14 +490,12 @@ procedure PVSystems_Set_daily(const Value: PAnsiChar); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.DailyShape := Value;
elem.DailyShapeObj := DSSPrime.LoadShapeClass.Find(elem.DailyShape);
elem.DailyShapeObj := ErrorIfLoadShapeNil(DSSPrime, Value);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
elem2.DailyShape := Value;
elem2.DailyShapeObj := DSSPrime.LoadShapeClass.Find(elem2.DailyShape);
elem2.DailyShapeObj := ErrorIfLoadShapeNil(DSSPrime, Value);
end;
//------------------------------------------------------------------------------
function PVSystems_Get_duty(): PAnsiChar; CDECL;
@@ -493,12 +508,15 @@ function PVSystems_Get_duty(): PAnsiChar; CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.DutyShape);
if elem.DutyShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.DutyShapeObj.Name);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.DutyShape);

if elem2.DutyShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.DutyShapeObj.Name);
end;
//------------------------------------------------------------------------------
procedure PVSystems_Set_duty(const Value: PAnsiChar); CDECL;
@@ -510,14 +528,12 @@ procedure PVSystems_Set_duty(const Value: PAnsiChar); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.DutyShape := Value;
elem.DutyShapeObj := DSSPrime.LoadShapeClass.Find(elem.DutyShape);
elem.DutyShapeObj := ErrorIfLoadShapeNil(DSSPrime, Value);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
elem2.DutyShape := Value;
elem2.DutyShapeObj := DSSPrime.LoadShapeClass.Find(elem2.DutyShape);
elem2.DutyShapeObj := ErrorIfLoadShapeNil(DSSPrime, Value);
end;
//------------------------------------------------------------------------------
function PVSystems_Get_yearly(): PAnsiChar; CDECL;
@@ -530,12 +546,14 @@ function PVSystems_Get_yearly(): PAnsiChar; CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.YearlyShape);
if elem.YearlyShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.YearlyShapeObj.Name);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.YearlyShape);
if elem2.YearlyShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.YearlyShapeObj.Name);
end;
//------------------------------------------------------------------------------
procedure PVSystems_Set_yearly(const Value: PAnsiChar); CDECL;
@@ -547,14 +565,12 @@ procedure PVSystems_Set_yearly(const Value: PAnsiChar); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.YearlyShape := Value;
elem.YearlyShapeObj := DSSPrime.LoadShapeClass.Find(elem.YearlyShape);
elem.YearlyShapeObj := ErrorIfLoadShapeNil(DSSPrime, Value);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
elem2.YearlyShape := Value;
elem2.YearlyShapeObj := DSSPrime.LoadShapeClass.Find(elem2.YearlyShape);
elem2.YearlyShapeObj := ErrorIfLoadShapeNil(DSSPrime, Value);
end;
//------------------------------------------------------------------------------
function PVSystems_Get_Tdaily(): PAnsiChar; CDECL;
@@ -567,12 +583,14 @@ function PVSystems_Get_Tdaily(): PAnsiChar; CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.DailyTShape);
if elem.DailyTShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.DailyTShapeObj.Name);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.DailyTShape);
if elem2.DailyTShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.DailyTShapeObj.Name);
end;
//------------------------------------------------------------------------------
procedure PVSystems_Set_Tdaily(const Value: PAnsiChar); CDECL;
@@ -584,14 +602,12 @@ procedure PVSystems_Set_Tdaily(const Value: PAnsiChar); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.DailyTShape := Value;
elem.DailyTShapeObj := DSSPrime.TShapeClass.Find(elem.DailyTShape);
elem.DailyTShapeObj := ErrorIfTShapeNil(DSSPrime, Value);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
elem2.DailyTShape := Value;
elem2.DailyTShapeObj := DSSPrime.TShapeClass.Find(elem2.DailyTShape);
elem2.DailyTShapeObj := ErrorIfTShapeNil(DSSPrime, Value);
end;
//------------------------------------------------------------------------------
function PVSystems_Get_Tduty(): PAnsiChar; CDECL;
@@ -604,12 +620,15 @@ function PVSystems_Get_Tduty(): PAnsiChar; CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.DutyTShape);
if elem.DutyTShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.DutyTShapeObj.Name);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.DutyTShape);

if elem2.DutyTShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.DutyTShapeObj.Name);
end;
//------------------------------------------------------------------------------
procedure PVSystems_Set_Tduty(const Value: PAnsiChar); CDECL;
@@ -621,14 +640,12 @@ procedure PVSystems_Set_Tduty(const Value: PAnsiChar); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.DutyTShape := Value;
elem.DutyTShapeObj := DSSPrime.TShapeClass.Find(elem.DutyTShape);
elem.DutyTShapeObj := ErrorIfTShapeNil(DSSPrime, Value);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
elem2.DutyTShape := Value;
elem2.DutyTShapeObj := DSSPrime.TShapeClass.Find(elem2.DutyTShape);
elem2.DutyTShapeObj := ErrorIfTShapeNil(DSSPrime, Value);
end;
//------------------------------------------------------------------------------
function PVSystems_Get_Tyearly(): PAnsiChar; CDECL;
@@ -641,12 +658,15 @@ function PVSystems_Get_Tyearly(): PAnsiChar; CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.YearlyTShape);
if elem.YearlyTShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.YearlyTShapeObj.Name);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.YearlyTShape);

if elem2.YearlyTShapeObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.YearlyTShapeObj.Name);
end;
//------------------------------------------------------------------------------
procedure PVSystems_Set_Tyearly(const Value: PAnsiChar); CDECL;
@@ -658,14 +678,12 @@ procedure PVSystems_Set_Tyearly(const Value: PAnsiChar); CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.YearlyTShape := Value;
elem.YearlyTShapeObj := DSSPrime.TShapeClass.Find(elem.YearlyTShape);
elem.YearlyTShapeObj := ErrorIfTShapeNil(DSSPrime, Value);
Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;
elem2.YearlyTShape := Value;
elem2.YearlyTShapeObj := DSSPrime.TShapeClass.Find(elem2.YearlyTShape);
elem2.YearlyTShapeObj := ErrorIfTShapeNil(DSSPrime, Value);
end;
//------------------------------------------------------------------------------
function PVSystems_Get_Pmpp(): Double; CDECL;
@@ -731,16 +749,16 @@ function PVSystems_Get_Sensor(): PAnsiChar; CDECL;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
if elem.SensorObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.SensorObj.ElementName);
if (elem.SensorObj <> NIL) and (elem.SensorObj.MeteredElement <> NIL) then
Result := DSS_GetAsPAnsiChar(DSSPrime, AnsiLowerCase(elem.SensorObj.MeteredElement.FullName));

Exit;
end;
if not _activeObj2(DSSPrime, elem2) then
Exit;

if elem2.SensorObj <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, elem2.SensorObj.ElementName);
if (elem2.SensorObj <> NIL) and (elem2.SensorObj.MeteredElement <> NIL) then
Result := DSS_GetAsPAnsiChar(DSSPrime, AnsiLowerCase(elem2.SensorObj.MeteredElement.FullName));
end;
//------------------------------------------------------------------------------
end.
117 changes: 9 additions & 108 deletions src/CAPI/CAPI_Parallel.pas
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ interface
CAPI_Utils,
CAPI_Types;

{$IFDEF DSS_CAPI_PM}
function Parallel_Get_NumCPUs(): Integer; CDECL;
function Parallel_Get_NumCores(): Integer; CDECL;
function Parallel_Get_ActiveActor(): Integer; CDECL;
@@ -23,37 +24,35 @@ function Parallel_Get_ActiveParallel(): Integer; CDECL;
procedure Parallel_Set_ActiveParallel(Value: Integer); CDECL;
function Parallel_Get_ConcatenateReports(): Integer; CDECL;
procedure Parallel_Set_ConcatenateReports(Value: Integer); CDECL;

{$ENDIF}
implementation

{$IFDEF DSS_CAPI_PM}
uses
CAPI_Constants,
DSSGlobals,
Executive,
SysUtils,
solution,
CktElement,
ParserDel,
KLUSolve,
Classes,
DSSClass,
DSSHelper;


{$IFDEF DSS_CAPI_PM}
function Parallel_Get_NumCPUs(): Integer; CDECL;
begin
Result := CPU_Cores;
end;
//------------------------------------------------------------------------------
function Parallel_Get_NumCores(): Integer; CDECL;
begin
Result := round(CPU_Cores / 2); //TODO: fix
Result := CPU_Cores div 2; //TODO: fix
end;
//------------------------------------------------------------------------------
function Parallel_Get_ActiveActor(): Integer; CDECL;
begin
Result := DSSPrime.ActiveChildIndex;
Result := DSSPrime.ActiveChildIndex + 1;
end;
//------------------------------------------------------------------------------
procedure Parallel_Set_ActiveActor(Value: Integer); CDECL;
@@ -64,7 +63,7 @@ procedure Parallel_Set_ActiveActor(Value: Integer); CDECL;
DSSPrime.ActiveChild := DSSPrime.Children[DSSPrime.ActiveChildIndex];
end
else
DoSimpleMsg(DSSPrime, 'The actor does not exists', 7002);
DoSimpleMsg(DSSPrime, _('The actor does not exists'), 7002);
end;
//------------------------------------------------------------------------------
procedure Parallel_CreateActor(); CDECL;
@@ -85,7 +84,7 @@ procedure Parallel_Set_ActorCPU(Value: Integer); CDECL;
if DSSPrime.ActiveChild.ActorThread <> nil then
DSSPrime.ActiveChild.ActorThread.CPU := value;
end
else DoSimpleMsg(DSSPrime, 'The CPU does not exist', 7004);
else DoSimpleMsg(DSSPrime, _('The CPU does not exist'), 7004);
end;
//------------------------------------------------------------------------------
function Parallel_Get_NumOfActors(): Integer; CDECL;
@@ -94,8 +93,6 @@ function Parallel_Get_NumOfActors(): Integer; CDECL;
end;
//------------------------------------------------------------------------------
procedure Parallel_Wait(); CDECL;
var
i: Integer;
begin
if DSSPrime.Parallel_enabled then
Wait4Actors(DSSPrime, 0);
@@ -127,12 +124,7 @@ procedure Parallel_Get_ActorStatus(var ResultPtr: PInteger; ResultCount: PAPISiz
begin
Result := DSS_RecreateArray_PInteger(ResultPtr, ResultCount, DSSPrime.NumOfActors);
for idx := 0 to High(DSSPrime.Children) do
begin
if DSSPrime.Children[idx].ActorThread.Is_Busy then
Result[idx] := Ord(TActorStatus.Busy)
else
Result[idx] := Ord(TActorStatus.Idle);
end;
Result[idx] := Ord(DSSPrime.Children[idx].ActorStatus);
end;

procedure Parallel_Get_ActorStatus_GR(); CDECL;
@@ -152,7 +144,7 @@ function Parallel_Get_ActiveParallel(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Parallel_Set_ActiveParallel(Value: Integer); CDECL;
begin
DSSPrime.Parallel_enabled := (Value = 1); //TODO
DSSPrime.Parallel_enabled := (Value = 1);
end;
//------------------------------------------------------------------------------
function Parallel_Get_ConcatenateReports(): Integer; CDECL;
@@ -168,96 +160,5 @@ procedure Parallel_Set_ConcatenateReports(Value: Integer); CDECL;
DSSPrime.ConcatenateReports := (Value = 1);
end;
//------------------------------------------------------------------------------
{$ELSE}
function NotAvailable(DSS: TDSSContext): Integer;
begin
DoSimpleMsg(DSS, 'Parallel machine functions were not compiled', 7982);
Result := -1;
end;

function Parallel_Get_NumCPUs(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

function Parallel_Get_NumCores(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

function Parallel_Get_ActiveActor(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

procedure Parallel_Set_ActiveActor(Value: Integer); CDECL;
begin
NotAvailable(DSSPrime);
end;

procedure Parallel_CreateActor(); CDECL;
begin
NotAvailable(DSSPrime);
end;

function Parallel_Get_ActorCPU(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

procedure Parallel_Set_ActorCPU(Value: Integer); CDECL;
begin
NotAvailable(DSSPrime);
end;

function Parallel_Get_NumOfActors(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

procedure Parallel_Wait(); CDECL;
begin
NotAvailable(DSSPrime);
end;

procedure Parallel_Get_ActorProgress(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL;
begin
NotAvailable(DSSPrime);
end;

procedure Parallel_Get_ActorProgress_GR(); CDECL;
begin
NotAvailable(DSSPrime);
end;

procedure Parallel_Get_ActorStatus(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL;
begin
NotAvailable(DSSPrime);
end;

procedure Parallel_Get_ActorStatus_GR(); CDECL;
begin
NotAvailable(DSSPrime);
end;

function Parallel_Get_ActiveParallel(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

procedure Parallel_Set_ActiveParallel(Value: Integer); CDECL;
begin
NotAvailable(DSSPrime);
end;

function Parallel_Get_ConcatenateReports(): Integer; CDECL;
begin
Result := NotAvailable(DSSPrime);
end;

procedure Parallel_Set_ConcatenateReports(Value: Integer); CDECL;
begin
NotAvailable(DSSPrime);
end;
{$ENDIF}
end.
47 changes: 20 additions & 27 deletions src/CAPI/CAPI_Parser.pas
Original file line number Diff line number Diff line change
@@ -38,101 +38,98 @@ implementation
ArrayDef,
DSSClass;

var
ComParser: ParserDel.TParser;

//------------------------------------------------------------------------------
function Parser_Get_CmdString(): PAnsiChar; CDECL;
begin
Result := DSS_GetAsPAnsiChar(DSSPrime, ComParser.CmdString);
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ComParser.CmdString);
end;
//------------------------------------------------------------------------------
procedure Parser_Set_CmdString(const Value: PAnsiChar); CDECL;
begin
ComParser.CmdString := Value;
DSSPrime.ComParser.CmdString := Value;
end;
//------------------------------------------------------------------------------
function Parser_Get_NextParam(): PAnsiChar; CDECL;
begin
Result := DSS_GetAsPAnsiChar(DSSPrime, ComParser.NextParam);
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ComParser.NextParam);
end;
//------------------------------------------------------------------------------
function Parser_Get_AutoIncrement(): TAPIBoolean; CDECL;
begin
Result := ComParser.AutoIncrement;
Result := DSSPrime.ComParser.AutoIncrement;
end;
//------------------------------------------------------------------------------
procedure Parser_Set_AutoIncrement(Value: TAPIBoolean); CDECL;
begin
ComParser.AutoIncrement := Value;
DSSPrime.ComParser.AutoIncrement := Value;
end;
//------------------------------------------------------------------------------
function Parser_Get_DblValue(): Double; CDECL;
begin
Result := ComParser.DblValue;
Result := DSSPrime.ComParser.DblValue;
end;
//------------------------------------------------------------------------------
function Parser_Get_IntValue(): Integer; CDECL;
begin
Result := ComParser.IntValue;
Result := DSSPrime.ComParser.IntValue;
end;
//------------------------------------------------------------------------------
function Parser_Get_StrValue(): PAnsiChar; CDECL;
begin
Result := DSS_GetAsPAnsiChar(DSSPrime, ComParser.StrValue);
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ComParser.StrValue);
end;
//------------------------------------------------------------------------------
function Parser_Get_WhiteSpace(): PAnsiChar; CDECL;
begin
Result := DSS_GetAsPAnsiChar(DSSPrime, Comparser.Whitespace);
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ComParser.Whitespace);
end;
//------------------------------------------------------------------------------
procedure Parser_Set_WhiteSpace(const Value: PAnsiChar); CDECL;
begin
ComParser.Whitespace := Value;
DSSPrime.ComParser.Whitespace := Value;
end;
//------------------------------------------------------------------------------
function Parser_Get_BeginQuote(): PAnsiChar; CDECL;
begin
Result := DSS_GetAsPAnsiChar(DSSPrime, ComParser.BeginQuoteChars);
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ComParser.BeginQuoteChars);
end;
//------------------------------------------------------------------------------
function Parser_Get_EndQuote(): PAnsiChar; CDECL;
begin
Result := DSS_GetAsPAnsiChar(DSSPrime, ComParser.EndQuoteChars);
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ComParser.EndQuoteChars);
end;
//------------------------------------------------------------------------------
procedure Parser_Set_BeginQuote(const Value: PAnsiChar); CDECL;
begin
ComParser.BeginQuoteChars := Value;
DSSPrime.ComParser.BeginQuoteChars := Value;
end;
//------------------------------------------------------------------------------
procedure Parser_Set_EndQuote(const Value: PAnsiChar); CDECL;
begin
ComParser.EndQuoteChars := Value;
DSSPrime.ComParser.EndQuoteChars := Value;
end;
//------------------------------------------------------------------------------
function Parser_Get_Delimiters(): PAnsiChar; CDECL;
begin
Result := DSS_GetAsPAnsiChar(DSSPrime, ComParser.Delimiters);
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.ComParser.Delimiters);
end;
//------------------------------------------------------------------------------
procedure Parser_Set_Delimiters(const Value: PAnsiChar); CDECL;
begin
ComParser.Delimiters := Value;
DSSPrime.ComParser.Delimiters := Value;
end;
//------------------------------------------------------------------------------
procedure Parser_ResetDelimiters(); CDECL;
begin
ComParser.ResetDelims;
DSSPrime.ComParser.ResetDelims;
end;
//------------------------------------------------------------------------------
procedure Parser_Get_Vector(var ResultPtr: PDouble; ResultCount: PAPISize; ExpectedSize: Integer); CDECL;
var
ActualSize: Integer;
begin
DSS_RecreateArray_PDouble(ResultPtr, ResultCount, ExpectedSize);
ActualSize := ComParser.ParseAsVector(ResultCount^, ArrayDef.PDoubleArray(ResultPtr));
ActualSize := DSSPrime.ComParser.ParseAsVector(ResultCount^, ArrayDef.PDoubleArray(ResultPtr));
ResultCount^ := ActualSize;
end;

@@ -146,7 +143,7 @@ procedure Parser_Get_Vector_GR(ExpectedSize: Integer); CDECL;
procedure Parser_Get_Matrix(var ResultPtr: PDouble; ResultCount: PAPISize; ExpectedOrder: Integer); CDECL;
begin
DSS_RecreateArray_PDouble(ResultPtr, ResultCount, ExpectedOrder * ExpectedOrder);
ComParser.ParseAsMatrix(ResultCount^, ArrayDef.PDoubleArray(ResultPtr));
DSSPrime.ComParser.ParseAsMatrix(ResultCount^, ArrayDef.PDoubleArray(ResultPtr));
end;

procedure Parser_Get_Matrix_GR(ExpectedOrder: Integer); CDECL;
@@ -159,7 +156,7 @@ procedure Parser_Get_Matrix_GR(ExpectedOrder: Integer); CDECL;
procedure Parser_Get_SymMatrix(var ResultPtr: PDouble; ResultCount: PAPISize; ExpectedOrder: Integer); CDECL;
begin
DSS_RecreateArray_PDouble(ResultPtr, ResultCount, ExpectedOrder * ExpectedOrder);
ComParser.ParseAsSymMatrix(ResultCount^, ArrayDef.PDoubleArray(ResultPtr));
DSSPrime.ComParser.ParseAsSymMatrix(ResultCount^, ArrayDef.PDoubleArray(ResultPtr));
end;

procedure Parser_Get_SymMatrix_GR(ExpectedOrder: Integer); CDECL;
@@ -168,8 +165,4 @@ procedure Parser_Get_SymMatrix_GR(ExpectedOrder: Integer); CDECL;
Parser_Get_SymMatrix(DSSPrime.GR_DataPtr_PDouble, DSSPrime.GR_Counts_PDouble, ExpectedOrder)
end;

//------------------------------------------------------------------------------
initialization
ComParser := ParserDel.TParser.Create; // create COM Parser object

end.
251 changes: 78 additions & 173 deletions src/CAPI/CAPI_Reactors.pas

Large diffs are not rendered by default.

123 changes: 76 additions & 47 deletions src/CAPI/CAPI_Reclosers.pas
Original file line number Diff line number Diff line change
@@ -57,10 +57,14 @@ implementation
DSSGlobals,
DSSClassDefs,
DSSClass,
DSSHelper;
DSSHelper,
DSSObjectHelper;

type
TObj = TRecloserObj;

//------------------------------------------------------------------------------
function _activeObj(DSS: TDSSContext; out obj: TRecloserObj): Boolean; inline;
function _activeObj(DSS: TDSSContext; out obj: TObj): Boolean; inline;
begin
Result := False;
obj := NIL;
@@ -72,25 +76,42 @@ function _activeObj(DSS: TDSSContext; out obj: TRecloserObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active Recloser object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['Recloser'], 8989);
end;
Exit;
end;

Result := True;
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const parm: String; const val: String);
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: String); overload;
var
cmd: String;
elem: TRecloserObj;
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
elem.ParsePropertyValue(idx, val);
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: Double); overload;
var
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
elem.SetDouble(idx, val);
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: Integer); overload;
var
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;

DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
cmd := Format('recloser.%s.%s=%s', [elem.Name, parm, val]);
DSS.DSSExecutive.Command := cmd;
elem.SetInteger(idx, val);
end;
//------------------------------------------------------------------------------
procedure Reclosers_Get_AllNames(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CDECL;
@@ -134,7 +155,7 @@ function Reclosers_Get_Next(): Integer; CDECL;
//------------------------------------------------------------------------------
function Reclosers_Get_Name(): PAnsiChar; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
@@ -154,13 +175,13 @@ procedure Reclosers_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'Recloser "' + Value + '" Not Found in Active Circuit.', 77003);
DoSimpleMsg(DSSPrime, 'Recloser "%s" not found in Active Circuit.', [Value], 77003);
end;
end;
//------------------------------------------------------------------------------
function Reclosers_Get_MonitoredTerm(): Integer; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -170,37 +191,39 @@ function Reclosers_Get_MonitoredTerm(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Reclosers_Set_MonitoredTerm(Value: Integer); CDECL;
begin
Set_Parameter(DSSPrime, 'monitoredterm', IntToStr(Value));
Set_Parameter(DSSPrime, ord(TRecloserProp.monitoredterm), Value);
end;
//------------------------------------------------------------------------------
function Reclosers_Get_SwitchedObj(): PAnsiChar; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.ElementName);
if elem.ControlledElement <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, AnsiLowerCase(elem.ControlledElement.FullName));
end;
//------------------------------------------------------------------------------
procedure Reclosers_Set_SwitchedObj(const Value: PAnsiChar); CDECL;
begin
Set_Parameter(DSSPrime, 'SwitchedObj', Value);
Set_Parameter(DSSPrime, ord(TRecloserProp.SwitchedObj), Value);
end;
//------------------------------------------------------------------------------
function Reclosers_Get_MonitoredObj(): PAnsiChar; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.MonitoredElementName);
if elem.MonitoredElement <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, AnsiLowerCase(elem.MonitoredElement.FullName));
end;
//------------------------------------------------------------------------------
function Reclosers_Get_SwitchedTerm(): Integer; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -210,17 +233,17 @@ function Reclosers_Get_SwitchedTerm(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Reclosers_Set_MonitoredObj(const Value: PAnsiChar); CDECL;
begin
Set_Parameter(DSSPrime, 'monitoredObj', Value);
Set_Parameter(DSSPrime, ord(TRecloserProp.monitoredObj), Value);
end;
//------------------------------------------------------------------------------
procedure Reclosers_Set_SwitchedTerm(Value: Integer); CDECL;
begin
Set_Parameter(DSSPrime, 'SwitchedTerm', IntToStr(Value));
Set_Parameter(DSSPrime, ord(TRecloserProp.SwitchedTerm), Value);
end;
//------------------------------------------------------------------------------
function Reclosers_Get_NumFast(): Integer; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -232,7 +255,7 @@ procedure Reclosers_Get_RecloseIntervals(var ResultPtr: PDouble; ResultCount: PA
// return reclose intervals in seconds
var
Result: PDoubleArray0;
elem: TRecloserObj;
elem: TObj;
i, k: Integer;
begin
if not _activeObj(DSSPrime, elem) then
@@ -259,7 +282,7 @@ procedure Reclosers_Get_RecloseIntervals_GR(); CDECL;
//------------------------------------------------------------------------------
function Reclosers_Get_Shots(): Integer; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -269,17 +292,17 @@ function Reclosers_Get_Shots(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Reclosers_Set_NumFast(Value: Integer); CDECL;
begin
Set_Parameter(DSSPrime, 'numfast', IntToStr(Value));
Set_Parameter(DSSPrime, ord(TRecloserProp.numfast), Value);
end;
//------------------------------------------------------------------------------
procedure Reclosers_Set_Shots(Value: Integer); CDECL;
begin
Set_Parameter(DSSPrime, 'shots', IntToStr(Value));
Set_Parameter(DSSPrime, ord(TRecloserProp.shots), Value);
end;
//------------------------------------------------------------------------------
function Reclosers_Get_PhaseTrip(): Double; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -289,12 +312,12 @@ function Reclosers_Get_PhaseTrip(): Double; CDECL;
//------------------------------------------------------------------------------
procedure Reclosers_Set_PhaseTrip(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'PhaseTrip', Format('%.g', [Value]));
Set_Parameter(DSSPrime, ord(TRecloserProp.PhaseTrip), Value);
end;
//------------------------------------------------------------------------------
function Reclosers_Get_GroundInst(): Double; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -304,7 +327,7 @@ function Reclosers_Get_GroundInst(): Double; CDECL;
//------------------------------------------------------------------------------
function Reclosers_Get_GroundTrip(): Double; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -314,7 +337,7 @@ function Reclosers_Get_GroundTrip(): Double; CDECL;
//------------------------------------------------------------------------------
function Reclosers_Get_PhaseInst(): Double; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -324,27 +347,27 @@ function Reclosers_Get_PhaseInst(): Double; CDECL;
//------------------------------------------------------------------------------
procedure Reclosers_Set_GroundInst(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'GroundInst', Format('%.g', [Value]));
Set_Parameter(DSSPrime, ord(TRecloserProp.GroundInst), Value);
end;
//------------------------------------------------------------------------------
procedure Reclosers_Set_GroundTrip(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'GroundTrip', Format('%.g', [Value]));
Set_Parameter(DSSPrime, ord(TRecloserProp.GroundTrip), Value);
end;
//------------------------------------------------------------------------------
procedure Reclosers_Set_PhaseInst(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'Phaseinst', Format('%.g', [Value]));
Set_Parameter(DSSPrime, ord(TRecloserProp.PhaseInst), Value);
end;
//------------------------------------------------------------------------------
procedure Reclosers_Close(); CDECL;
begin
Set_Parameter(DSSPrime, 'Action', 'close');
Set_Parameter(DSSPrime, ord(TRecloserProp.Action), 'close');
end;
//------------------------------------------------------------------------------
procedure Reclosers_Open(); CDECL;
begin
Set_Parameter(DSSPrime, 'Action', 'open');
Set_Parameter(DSSPrime, ord(TRecloserProp.Action), 'open');
end;
//------------------------------------------------------------------------------
function Reclosers_Get_idx(): Integer; CDECL;
@@ -357,22 +380,22 @@ function Reclosers_Get_idx(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Reclosers_Set_idx(Value: Integer); CDECL;
var
pRecloser: TRecloserObj;
pRecloser: TObj;
begin
if InvalidCircuit(DSSPrime) then
Exit;
pRecloser := DSSPrime.ActiveCircuit.Reclosers.Get(Value);
if pRecloser = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid Recloser index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['Recloser', Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pRecloser;
end;
//------------------------------------------------------------------------------
procedure Reclosers_Reset(); CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
@@ -381,7 +404,7 @@ procedure Reclosers_Reset(); CDECL;
//------------------------------------------------------------------------------
function Reclosers_Get_NormalState(): Integer; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -391,23 +414,29 @@ function Reclosers_Get_NormalState(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Reclosers_Set_NormalState(Value: Integer); CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
if Value = dssActionOpen then //TODO: use the same enum
elem.NormalState := CTRL_OPEN
begin
elem.NormalState := CTRL_OPEN;
elem.NormalStateSet := True;
end
else if Value = dssActionClose then
elem.NormalState := CTRL_CLOSE
begin
elem.NormalState := CTRL_CLOSE;
elem.NormalStateSet := True;
end
else
begin
DoSimpleMsg(DSSPrime, 'Invalid Recloser normal state: "' + IntToStr(Value) + '".', 656566);
DoSimpleMsg(DSSPrime, 'Invalid Recloser normal state: "%d".', [Value], 656566);
end;
end;
//------------------------------------------------------------------------------
function Reclosers_Get_State(): Integer; CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -417,7 +446,7 @@ function Reclosers_Get_State(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Reclosers_Set_State(Value: Integer); CDECL;
var
elem: TRecloserObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
@@ -427,7 +456,7 @@ procedure Reclosers_Set_State(Value: Integer); CDECL;
elem.PresentState := CTRL_CLOSE
else
begin
DoSimpleMsg(DSSPrime, 'Invalid Recloser state: "' + IntToStr(Value) + '".', 656567);
DoSimpleMsg(DSSPrime, 'Invalid Recloser state: "%d".', [Value], 656567);
end;
end;
//------------------------------------------------------------------------------
172 changes: 94 additions & 78 deletions src/CAPI/CAPI_RegControls.pas

Large diffs are not rendered by default.

97 changes: 63 additions & 34 deletions src/CAPI/CAPI_Relays.pas
Original file line number Diff line number Diff line change
@@ -43,10 +43,14 @@ implementation
Sysutils,
DSSPointerList,
DSSClass,
DSSHelper;
DSSHelper,
DSSObjectHelper;

type
TObj = TRelayObj;

//------------------------------------------------------------------------------
function _activeObj(DSS: TDSSContext; out obj: TRelayObj): Boolean; inline;
function _activeObj(DSS: TDSSContext; out obj: TObj): Boolean; inline;
begin
Result := False;
obj := NIL;
@@ -58,24 +62,42 @@ function _activeObj(DSS: TDSSContext; out obj: TRelayObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active Relay object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['Relay'], 8989);
end;
Exit;
end;

Result := True;
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const parm: String; const val: String);
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: String); overload;
var
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
elem.ParsePropertyValue(idx, val);
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: Double); overload;
var
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
elem.SetDouble(idx, val);
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: Integer); overload;
var
cmd: String;
elem: TRelayObj;
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
cmd := Format('Relay.%s.%s=%s', [elem.Name, parm, val]);
DSS.DSSExecutive.Command := cmd;
elem.SetInteger(idx, val);
end;
//------------------------------------------------------------------------------
procedure Relays_Get_AllNames(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CDECL;
@@ -119,7 +141,7 @@ function Relays_Get_Next(): Integer; CDECL;
//------------------------------------------------------------------------------
function Relays_Get_Name(): PAnsiChar; CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
@@ -129,7 +151,6 @@ function Relays_Get_Name(): PAnsiChar; CDECL;
//------------------------------------------------------------------------------
procedure Relays_Set_Name(const Value: PAnsiChar); CDECL;
// Set element active by name

begin
if InvalidCircuit(DSSPrime) then
Exit;
@@ -140,29 +161,30 @@ procedure Relays_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'Relay "' + Value + '" Not Found in Active Circuit.', 77003);
DoSimpleMsg(DSSPrime, 'Relay "%s" not found in Active Circuit.', [Value], 77003);
end;
end;
//------------------------------------------------------------------------------
function Relays_Get_MonitoredObj(): PAnsiChar; CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.MonitoredElementName);
if elem.MonitoredElement <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, AnsiLowerCase(elem.MonitoredElement.FullName));
end;

//------------------------------------------------------------------------------
procedure Relays_Set_MonitoredObj(const Value: PAnsiChar); CDECL;
begin
Set_Parameter(DSSPrime, 'monitoredObj', Value);
Set_Parameter(DSSPrime, ord(TRelayProp.monitoredObj), Value);
end;
//------------------------------------------------------------------------------
function Relays_Get_MonitoredTerm(): Integer; CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -172,28 +194,29 @@ function Relays_Get_MonitoredTerm(): Integer; CDECL;
//------------------------------------------------------------------------------
function Relays_Get_SwitchedObj(): PAnsiChar; CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.ElementName);
if elem.ControlledElement <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, AnsiLowerCase(elem.ControlledElement.FullName));
end;

//------------------------------------------------------------------------------
procedure Relays_Set_MonitoredTerm(Value: Integer); CDECL;
begin
Set_Parameter(DSSPrime, 'monitoredterm', IntToStr(Value));
Set_Parameter(DSSPrime, ord(TRelayProp.monitoredterm), Value);
end;
//------------------------------------------------------------------------------
procedure Relays_Set_SwitchedObj(const Value: PAnsiChar); CDECL;
begin
Set_Parameter(DSSPrime, 'SwitchedObj', Value);
Set_Parameter(DSSPrime, ord(TRelayProp.SwitchedObj), Value);
end;
//------------------------------------------------------------------------------
function Relays_Get_SwitchedTerm(): Integer; CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -203,7 +226,7 @@ function Relays_Get_SwitchedTerm(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Relays_Set_SwitchedTerm(Value: Integer); CDECL;
begin
Set_Parameter(DSSPrime, 'SwitchedTerm', IntToStr(Value));
Set_Parameter(DSSPrime, ord(TRelayProp.SwitchedTerm), Value);
end;
//------------------------------------------------------------------------------
function Relays_Get_idx(): Integer; CDECL;
@@ -216,21 +239,21 @@ function Relays_Get_idx(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Relays_Set_idx(Value: Integer); CDECL;
var
pRelay: TRelayObj;
pRelay: TObj;
begin
if InvalidCircuit(DSSPrime) then
Exit;
pRelay := DSSPrime.ActiveCircuit.Relays.Get(Value);
if pRelay = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid Relay index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['Relay', Value], 656565);
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pRelay;
end;
//------------------------------------------------------------------------------
procedure Relays_Close(); CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
@@ -239,7 +262,7 @@ procedure Relays_Close(); CDECL;
//------------------------------------------------------------------------------
procedure Relays_Open(); CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
@@ -248,7 +271,7 @@ procedure Relays_Open(); CDECL;
//------------------------------------------------------------------------------
procedure Relays_Reset(); CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
@@ -257,7 +280,7 @@ procedure Relays_Reset(); CDECL;
//------------------------------------------------------------------------------
function Relays_Get_NormalState(): Integer; CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -267,23 +290,29 @@ function Relays_Get_NormalState(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Relays_Set_NormalState(Value: Integer); CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
if Value = dssActionOpen then
elem.NormalState := CTRL_OPEN
begin
elem.NormalState := CTRL_OPEN;
elem.NormalStateSet := True;
end
else if Value = dssActionClose then
elem.NormalState := CTRL_CLOSE
begin
elem.NormalState := CTRL_CLOSE;
elem.NormalStateSet := True;
end
else
begin
DoSimpleMsg(DSSPrime, 'Invalid Relay normal state: "' + IntToStr(Value) + '".', 656569);
DoSimpleMsg(DSSPrime, 'Invalid Relay normal state: "%d".', [Value], 656569);
end;
end;
//------------------------------------------------------------------------------
function Relays_Get_State(): Integer; CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -293,7 +322,7 @@ function Relays_Get_State(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Relays_Set_State(Value: Integer); CDECL;
var
elem: TRelayObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
@@ -303,7 +332,7 @@ procedure Relays_Set_State(Value: Integer); CDECL;
elem.PresentState := CTRL_CLOSE
else
begin
DoSimpleMsg(DSSPrime, 'Invalid Relay state: "' + IntToStr(Value) + '".', 656568);
DoSimpleMsg(DSSPrime, 'Invalid Relay state: "%d".', [Value], 656568);
end;
end;
//------------------------------------------------------------------------------
114 changes: 69 additions & 45 deletions src/CAPI/CAPI_Sensors.pas
Original file line number Diff line number Diff line change
@@ -59,10 +59,14 @@ implementation
Executive,
SysUtils,
DSSClass,
DSSHelper;
DSSHelper,
DSSObjectHelper;

type
TObj = TSensorObj;

//------------------------------------------------------------------------------
function _activeObj(DSS: TDSSContext; out obj: TSensorObj): Boolean; inline;
function _activeObj(DSS: TDSSContext; out obj: TObj): Boolean; inline;
begin
Result := False;
obj := NIL;
@@ -74,24 +78,42 @@ function _activeObj(DSS: TDSSContext; out obj: TSensorObj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active Sensor object found! Activate one and retry.', 8989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['Sensor'], 8989);
end;
Exit;
end;

Result := True;
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const parm: String; const val: String);
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: String); overload;
var
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
elem.ParsePropertyValue(idx, val);
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: Double); overload;
var
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
elem.SetDouble(idx, val);
end;
//------------------------------------------------------------------------------
procedure Set_Parameter(DSS: TDSSContext; const idx: Integer; const val: Integer); overload;
var
cmd: String;
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSS, elem) then
Exit;
DSS.SolutionAbort := FALSE; // Reset for commands entered from outside
cmd := Format('sensor.%s.%s=%s', [elem.Name, parm, val]);
DSS.DSSExecutive.Command := cmd;
elem.SetInteger(idx, val);
end;
//------------------------------------------------------------------------------
procedure Sensors_Get_AllNames(var ResultPtr: PPAnsiChar; ResultCount: PAPISize); CDECL;
@@ -119,7 +141,7 @@ function Sensors_Get_Count(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Sensors_Get_Currents(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
begin
@@ -156,17 +178,17 @@ function Sensors_Get_Next(): Integer; CDECL;
//------------------------------------------------------------------------------
function Sensors_Get_IsDelta(): TAPIBoolean; CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
Result := FALSE;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := (elem.Conn > 0);
Result := (elem.FConn > 0);
end;
//------------------------------------------------------------------------------
procedure Sensors_Get_kVARS(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
begin
@@ -186,7 +208,7 @@ procedure Sensors_Get_kVARS_GR(); CDECL;
//------------------------------------------------------------------------------
procedure Sensors_Get_kVS(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
begin
@@ -206,7 +228,7 @@ procedure Sensors_Get_kVS_GR(); CDECL;
//------------------------------------------------------------------------------
procedure Sensors_Get_kWS(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
begin
@@ -226,17 +248,18 @@ procedure Sensors_Get_kWS_GR(); CDECL;
//------------------------------------------------------------------------------
function Sensors_Get_MeteredElement(): PAnsiChar; CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, elem.ElementName);
if elem.MeteredElement <> NIL then
Result := DSS_GetAsPAnsiChar(DSSPrime, AnsiLowerCase(elem.MeteredElement.FullName));
end;
//------------------------------------------------------------------------------
function Sensors_Get_MeteredTerminal(): Integer; CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
Result := 0;
if not _activeObj(DSSPrime, elem) then
@@ -246,7 +269,7 @@ function Sensors_Get_MeteredTerminal(): Integer; CDECL;
//------------------------------------------------------------------------------
function Sensors_Get_Name(): PAnsiChar; CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
Result := NIL;
if not _activeObj(DSSPrime, elem) then
@@ -256,7 +279,7 @@ function Sensors_Get_Name(): PAnsiChar; CDECL;
//------------------------------------------------------------------------------
function Sensors_Get_PctError(): Double; CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -266,7 +289,7 @@ function Sensors_Get_PctError(): Double; CDECL;
//------------------------------------------------------------------------------
function Sensors_Get_ReverseDelta(): TAPIBoolean; CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
Result := FALSE;
if not _activeObj(DSSPrime, elem) then
@@ -276,7 +299,7 @@ function Sensors_Get_ReverseDelta(): TAPIBoolean; CDECL;
//------------------------------------------------------------------------------
function Sensors_Get_Weight(): Double; CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -286,7 +309,7 @@ function Sensors_Get_Weight(): Double; CDECL;
//------------------------------------------------------------------------------
procedure Sensors_Reset(); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
@@ -302,81 +325,82 @@ procedure Sensors_ResetAll(); CDECL;
//------------------------------------------------------------------------------
procedure Sensors_Set_Currents(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;

if ValueCount <> elem.NPhases then
begin
DoSimpleMsg(DSSPrime, 'The provided number of values does not match the element''s number of phases.', 5023);
DoSimpleMsg(DSSPrime, _('The provided number of values does not match the element''s number of phases.'), 5023);
Exit;
end;
Move(ValuePtr^, elem.SensorCurrent[1], elem.NPhases * SizeOf(Double));
end;
//------------------------------------------------------------------------------
procedure Sensors_Set_IsDelta(Value: TAPIBoolean); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;
elem.Conn := Integer(Value);
elem.FConn := Integer(Value);
elem.RecalcVbase;
end;
//------------------------------------------------------------------------------
procedure Sensors_Set_kVARS(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;

if ValueCount <> elem.NPhases then
begin
DoSimpleMsg(DSSPrime, 'The provided number of values does not match the element''s number of phases.', 5024);
DoSimpleMsg(DSSPrime, _('The provided number of values does not match the element''s number of phases.'), 5024);
Exit;
end;
Move(ValuePtr^, elem.SensorQ[1], elem.NPhases * SizeOf(Double));
end;
//------------------------------------------------------------------------------
procedure Sensors_Set_kVS(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;

if ValueCount <> elem.NPhases then
begin
DoSimpleMsg(DSSPrime, 'The provided number of values does not match the element''s number of phases.', 5024);
DoSimpleMsg(DSSPrime, _('The provided number of values does not match the element''s number of phases.'), 5024);
Exit;
end;
Move(ValuePtr^, elem.SensorVoltage[1], elem.NPhases * SizeOf(Double));
end;
//------------------------------------------------------------------------------
procedure Sensors_Set_kWS(ValuePtr: PDouble; ValueCount: TAPISize); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
Exit;

if ValueCount <> elem.NPhases then
begin
DoSimpleMsg(DSSPrime, 'The provided number of values does not match the element''s number of phases.', 5024);
DoSimpleMsg(DSSPrime, _('The provided number of values does not match the element''s number of phases.'), 5024);
Exit;
end;
Move(ValuePtr^, elem.SensorP[1], elem.NPhases * SizeOf(Double));
end;
//------------------------------------------------------------------------------
procedure Sensors_Set_MeteredElement(const Value: PAnsiChar); CDECL;
begin
Set_Parameter(DSSPrime, 'element', Value);
Set_Parameter(DSSPrime, ord(TSensorProp.element), Value);
end;
//------------------------------------------------------------------------------
procedure Sensors_Set_MeteredTerminal(Value: Integer); CDECL;
begin
Set_Parameter(DSSPrime, 'terminal', IntToStr(Value));
Set_Parameter(DSSPrime, ord(TSensorProp.terminal), Value);
end;
//------------------------------------------------------------------------------
procedure Sensors_Set_Name(const Value: PAnsiChar); CDECL;
@@ -390,31 +414,31 @@ procedure Sensors_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'Sensor "' + Value + '" Not Found in Active Circuit.', 5003);
DoSimpleMsg(DSSPrime, 'Sensor "%s" not found in Active Circuit.', [Value], 5003);
end;
end;
//------------------------------------------------------------------------------
procedure Sensors_Set_PctError(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, '%error', FloatToStr(Value));
Set_Parameter(DSSPrime, ord(TSensorProp.pcterror), Value);
end;
//------------------------------------------------------------------------------
procedure Sensors_Set_ReverseDelta(Value: TAPIBoolean); CDECL;
begin
if Value = TRUE then
Set_Parameter(DSSPrime, 'DeltaDirection', '-1')
if Value then
Set_Parameter(DSSPrime, ord(TSensorProp.DeltaDirection), -1)
else
Set_Parameter(DSSPrime, 'DeltaDirection', '1');
Set_Parameter(DSSPrime, ord(TSensorProp.DeltaDirection), 1);
end;
//------------------------------------------------------------------------------
procedure Sensors_Set_Weight(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'weight', FloatToStr(Value));
Set_Parameter(DSSPrime, ord(TSensorProp.weight), Value);
end;
//------------------------------------------------------------------------------
function Sensors_Get_kVbase(): Double; CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
Result := 0.0;
if not _activeObj(DSSPrime, elem) then
@@ -424,7 +448,7 @@ function Sensors_Get_kVbase(): Double; CDECL;
//------------------------------------------------------------------------------
procedure Sensors_Set_kVbase(Value: Double); CDECL;
begin
Set_Parameter(DSSPrime, 'kvbase', FloatToStr(Value));
Set_Parameter(DSSPrime, ord(TSensorProp.kvbase), Value);
end;
//------------------------------------------------------------------------------
function Sensors_Get_idx(): Integer; CDECL;
@@ -437,22 +461,22 @@ function Sensors_Get_idx(): Integer; CDECL;
//------------------------------------------------------------------------------
procedure Sensors_Set_idx(Value: Integer); CDECL;
var
pSensor: TSensorObj;
pSensor: TObj;
begin
if InvalidCircuit(DSSPrime) then
Exit;
pSensor := DSSPrime.ActiveCircuit.Sensors.Get(Value);
if pSensor = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid Sensor index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['Sensor', Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pSensor;
end;
//------------------------------------------------------------------------------
procedure Sensors_Get_AllocationFactor(var ResultPtr: PDouble; ResultCount: PAPISize); CDECL;
var
elem: TSensorObj;
elem: TObj;
begin
if not _activeObj(DSSPrime, elem) then
begin
5 changes: 3 additions & 2 deletions src/CAPI/CAPI_Settings.pas
Original file line number Diff line number Diff line change
@@ -59,7 +59,8 @@ implementation
ExecHelper,
Executive,
DSSClass,
DSSHelper;
DSSHelper,
SysUtils;

function Settings_Get_AllowDuplicates(): TAPIBoolean; CDECL;
begin
@@ -393,7 +394,7 @@ procedure Settings_Set_PriceCurve(const Value: PAnsiChar); CDECL;
PriceCurve := Value;
PriceCurveObj := DSSPrime.LoadShapeClass.Find(Pricecurve);
if PriceCurveObj = NIL then
DoSimpleMsg(DSSPrime, 'Price Curve: "' + Pricecurve + '" not found.', 5006);
DoSimpleMsg(DSSPrime, 'Price Curve: "%s" not found.', [PriceCurve], 5006);
end;
end;
//------------------------------------------------------------------------------
24 changes: 12 additions & 12 deletions src/CAPI/CAPI_Solution.pas
Original file line number Diff line number Diff line change
@@ -166,7 +166,6 @@ function Solution_Get_MaxIterations(): Integer; CDECL;
//------------------------------------------------------------------------------
function Solution_Get_Mode(): Integer; CDECL;
begin
//If not InvalidCircuit(DSSPrime) Then Result := GetSolutionModeID changed to integer 8/16/00
Result := 0;
if InvalidCircuit(DSSPrime) then
Exit;
@@ -260,7 +259,7 @@ procedure Solution_Set_Mode(Mode: Integer); CDECL;
if (Mode >= Ord(Low(TSolveMode))) and (Mode <= Ord(High(TSolveMode))) then
DSSPrime.ActiveCircuit.Solution.Mode := TSolveMode(Mode)
else
DoSimpleMsg(DSSPrime, Format('Invalid solution mode (%d).', [Mode]), 5004);
DoSimpleMsg(DSSPrime, 'Invalid solution mode (%d).', [Mode], 5004);
end;
//------------------------------------------------------------------------------
procedure Solution_Set_Number(Value: Integer); CDECL;
@@ -323,7 +322,7 @@ function Solution_Get_ModeID(): PAnsiChar; CDECL;
Result := NIL;
if InvalidCircuit(DSSPrime) then
Exit;
Result := DSS_GetAsPAnsiChar(DSSPrime, GetSolutionModeID(DSSPrime))
Result := DSS_GetAsPAnsiChar(DSSPrime, DSSPrime.SolveModeEnum.OrdinalToString(ord(DSSPrime.ActiveCircuit.Solution.Mode)))
end;
//------------------------------------------------------------------------------
function Solution_Get_LoadModel(): Integer; CDECL;
@@ -362,7 +361,7 @@ procedure Solution_Set_LDCurve(const Value: PAnsiChar); CDECL;
LoadDurCurve := Value;
LoadDurCurveObj := DSSPrime.LoadShapeClass.Find(LoadDurCurve);
if LoadDurCurveObj = NIL then
DoSimpleMsg(DSSPrime, 'Load-Duration Curve not found.', 5001);
DoSimpleMsg(DSSPrime, _('Load-Duration Curve not found.'), 5001);
end;
end;
//------------------------------------------------------------------------------
@@ -866,23 +865,24 @@ procedure Solution_Set_MinIterations(Value: Integer); CDECL;
DSSPrime.ActiveCircuit.Solution.MinIterations := Value;
end;

{$IFDEF DSS_CAPI_PM}
//------------------------------------------------------------------------------
procedure Solution_SolveAll();cdecl;
{$IFDEF DSS_CAPI_PM}
var
i : Integer;
PMParent: TDSSContext;
begin
for i := 0 to High(DSSPrime.Children) do
PMParent := DSSPrime.GetPrime();
for i := 0 to High(PMParent.Children) do
begin
DSSPrime.CmdResult := DoSetCmd(DSSPrime.Children[i], 1);
PMParent.ActiveChild := PMParent.Children[i];
DSSPrime.CmdResult := DoSetCmd(PMParent.Children[i], 1);
end;
end;
{$ELSE}
procedure Solution_SolveAll();cdecl;
begin
DoSimpleMsg(DSSPrime, 'Parallel machine functions were not compiled', 7983);
end;
DoSimpleMsg(DSSPrime, _('Parallel machine functions were not compiled'), 7983);
{$ENDIF}
end;
//------------------------------------------------------------------------------
procedure Solution_Get_Laplacian(var ResultPtr: PInteger; ResultCount: PAPISize); CDECL;
var
@@ -935,7 +935,7 @@ procedure Solution_Get_IncMatrix(var ResultPtr: PInteger; ResultCount: PAPISize)
with DSSPrime.ActiveCircuit.Solution do
begin
ArrSize := IncMat.NZero * 3;
Result := DSS_RecreateArray_PInteger(ResultPtr, ResultCount, ArrSize + 1); // TODO: remove +1?
Result := DSS_RecreateArray_PInteger(ResultPtr, ResultCount, ArrSize + 1); // TODO: remove +1? Left for compatibility with the official version
Counter := 0;
IMIdx := 0;
while IMIdx < ArrSize do
10 changes: 5 additions & 5 deletions src/CAPI/CAPI_Storages.pas
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ function OldModels(DSS: TDSSContext): Boolean;
begin
Result := DSS_CAPI_LEGACY_MODELS;
if DSS_CAPI_LEGACY_MODELS then
DoSimpleMsg(DSS, 'The Storages API is not available in the legacy-models mode!', 18990);
DoSimpleMsg(DSS, _('The Storages API is not available in the legacy-models mode!'), 18990);
end;

//------------------------------------------------------------------------------
@@ -55,7 +55,7 @@ function _activeObj(DSS: TDSSContext; out obj: TStorage2Obj): Boolean; inline;
begin
if DSS_CAPI_EXT_ERRORS then
begin
DoSimpleMsg(DSS, 'No active Storage object found! Activate one and retry.', 18989);
DoSimpleMsg(DSS, 'No active %s object found! Activate one and retry.', ['Storage'], 18989);
end;
Exit;
end;
@@ -118,7 +118,7 @@ procedure Storages_Set_Name(const Value: PAnsiChar); CDECL;
end
else
begin
DoSimpleMsg(DSSPrime, 'Storage "' + Value + '" Not Found in Active Circuit.', 77003);
DoSimpleMsg(DSSPrime, 'Storage "%s" not found in Active Circuit.', [Value], 77003);
end;
end;
//------------------------------------------------------------------------------
@@ -139,7 +139,7 @@ procedure Storages_Set_idx(Value: Integer); CDECL;
pStorage := DSSPrime.ActiveCircuit.StorageElements.Get(Value);
if pStorage = NIL then
begin
DoSimpleMsg(DSSPrime, 'Invalid Storage index: "' + IntToStr(Value) + '".', 656565);
DoSimpleMsg(DSSPrime, 'Invalid %s index: "%d".', ['Storage', Value], 656565);
Exit;
end;
DSSPrime.ActiveCircuit.ActiveCktElement := pStorage;
@@ -223,7 +223,7 @@ procedure Storages_Set_State(Value: Integer); CDECL;
(Value <> STORE_IDLING) and
(Value <> STORE_DISCHARGING) then
begin
DoSimpleMsg(DSSPrime, 'Invalid Storage state: "' + IntToStr(Value) + '".', 656568);
DoSimpleMsg(DSSPrime, 'Invalid Storage state: "%d".', [Value], 656568);
end;
elem.StorageState := Value;
end;
Loading