diff --git a/CHANGELOG b/CHANGELOG index f39877ad..353ecb83 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,9 @@ +Changes to version 1.6.1 +------------------------ + +-.NET Tools: in the Tools folder you can find the .net project to generate Static and Dynamic Models +- SCLParser: also available on tools, you can load your SCL model and use it with our library + Changes to version 1.6.0 ------------------------ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 93aa670f..6b6671ff 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory(server_example_control) add_subdirectory(server_example_dynamic) add_subdirectory(server_example_config_file) add_subdirectory(server_example_complex_array) +add_subdirectory(server_example_SMV) add_subdirectory(server_example_threadless) add_subdirectory(server_example_61400_25) add_subdirectory(server_example_setting_groups) diff --git a/examples/Makefile b/examples/Makefile index ebc03899..abddfb97 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -15,6 +15,7 @@ EXAMPLE_DIRS += server_example_control EXAMPLE_DIRS += server_example_config_file EXAMPLE_DIRS += server_example_dynamic EXAMPLE_DIRS += server_example_complex_array +EXAMPLE_DIRS += server_example_SMV EXAMPLE_DIRS += server_example_61400_25 EXAMPLE_DIRS += server_example_threadless EXAMPLE_DIRS += server_example_setting_groups diff --git a/examples/server_example_SMV/CMakeLists.txt b/examples/server_example_SMV/CMakeLists.txt new file mode 100644 index 00000000..b0461bc8 --- /dev/null +++ b/examples/server_example_SMV/CMakeLists.txt @@ -0,0 +1,21 @@ +include_directories( + . +) + +set(server_example_SMV_SRCS + server_example_SMV.c + static_model.c +) + +IF(MSVC) +set_source_files_properties(${server_example_SMV_SRCS} + PROPERTIES LANGUAGE CXX) +ENDIF(MSVC) + +add_executable(server_example_SMV + ${server_example_SMV_SRCS} +) + +target_link_libraries(server_example_SMV + iec61850 +) diff --git a/examples/server_example_SMV/Makefile b/examples/server_example_SMV/Makefile new file mode 100644 index 00000000..ae4b1449 --- /dev/null +++ b/examples/server_example_SMV/Makefile @@ -0,0 +1,26 @@ +LIBIEC_HOME=../.. + +PROJECT_BINARY_NAME = server_example_SMV +PROJECT_SOURCES = server_example_SMV.c +PROJECT_SOURCES += static_model.c + +PROJECT_ICD_FILE = sampleModel.cid + +include $(LIBIEC_HOME)/make/target_system.mk +include $(LIBIEC_HOME)/make/stack_includes.mk + +all: $(PROJECT_BINARY_NAME) + +include $(LIBIEC_HOME)/make/common_targets.mk + +model: $(PROJECT_ICD_FILE) + java -jar $(LIBIEC_HOME)/tools/model_generator/genmodel.jar $(PROJECT_ICD_FILE) + + +$(PROJECT_BINARY_NAME): $(PROJECT_SOURCES) $(LIB_NAME) + $(CC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT_BINARY_NAME) $(PROJECT_SOURCES) $(INCLUDES) $(LIB_NAME) $(LDLIBS) + +clean: + rm -f $(PROJECT_BINARY_NAME) + + diff --git a/examples/server_example_SMV/mhai_array_old.cid b/examples/server_example_SMV/mhai_array_old.cid new file mode 100644 index 00000000..1d347328 --- /dev/null +++ b/examples/server_example_SMV/mhai_array_old.cid @@ -0,0 +1,313 @@ + + + +
+
+ + + + +
+

0.0.0.0

+

255.255.255.0

+

192.168.2.1

+

1,3,9999,33

+

33

+

00000001

+

0001

+

0001

+

102

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + ok + + + + + + + + on + + + status-only + + + + + on + + + + + ok + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + + + + + + + + + + + + + + + + + + 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + blocked + test + test/blocked + off + + + + ok + warning + alarm + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + + +
diff --git a/examples/server_example_SMV/sampleModel.cid b/examples/server_example_SMV/sampleModel.cid new file mode 100644 index 00000000..80ab35ae --- /dev/null +++ b/examples/server_example_SMV/sampleModel.cid @@ -0,0 +1,193 @@ + + +
+ + + + +
+

01-0C-CD-04-00-01

+

4000

+

4

+

123

+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + + + status-only + + + + + + + status-only + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + \ No newline at end of file diff --git a/examples/server_example_SMV/server_example_SMV.c b/examples/server_example_SMV/server_example_SMV.c new file mode 100644 index 00000000..3f5b4c8d --- /dev/null +++ b/examples/server_example_SMV/server_example_SMV.c @@ -0,0 +1,136 @@ +/* + * server_example_SMV.c + * + * This example shows how to handle complex arrays (arrays of data objects). + */ + +#include "iec61850_server.h" +#include "hal_thread.h" +#include +#include +#include + +#include "static_model.h" + +#include + +static int running = 0; + +static void +sigint_handler(int signalId) +{ + running = 0; +} + +static void +updateCMVArrayElement(IedServer server, DataObject* phsAHar, int idx, float magnitude, float angle, Quality quality, Timestamp timestamp) +{ + DataObject* phsAHarArrayElem = (DataObject*)ModelNode_getChildWithIdx((ModelNode*)phsAHar, idx); + + if (phsAHarArrayElem) { + + DataAttribute* mag = (DataAttribute*)ModelNode_getChild((ModelNode*)phsAHarArrayElem, "cVal.mag.f"); + DataAttribute* ang = (DataAttribute*)ModelNode_getChild((ModelNode*)phsAHarArrayElem, "cVal.ang.f"); + DataAttribute* q = (DataAttribute*)ModelNode_getChild((ModelNode*)phsAHarArrayElem, "q"); + DataAttribute* t = (DataAttribute*)ModelNode_getChild((ModelNode*)phsAHarArrayElem, "t"); + + if (mag && ang && q && t) { + IedServer_updateQuality(server, q, quality); + IedServer_updateTimestampAttributeValue(server, t, ×tamp); + IedServer_updateFloatAttributeValue(server, mag, magnitude); + IedServer_updateFloatAttributeValue(server, ang, angle); + } + else { + printf("one of mag, ang, q, t not found\n"); + } + } + else { + printf("Element with index %i not found\n", idx); + } +} + +int +main(int argc, char **argv) +{ + + int tcpPort = 102; + + if (argc > 1) { + tcpPort = atoi(argv[1]); + } + + IedServer iedServer = IedServer_create(&iedModel); + + LogicalDevice* logicalDevice = iedModel.firstChild; + + LogicalNode* logicalNode = LogicalDevice_getLogicalNode(logicalDevice, "666LLN051"); + + SVControlBlock* sMVcontrolBlock = + (SVControlBlock*)IedModel_getSVControlBlock(&iedModel, logicalNode, "NewSMVControl"); + + ///* Get access to the MHAI1.HA data object handle - for static and dynamic model*/ + //DataObject* mhai1_ha_phsAHar = (DataObject*) + // IedModel_getModelNodeByShortObjectReference(&iedModel, "ComplexArray/MHAI1.HA.phsAHar"); + + ///* assuming the array has 16 elements */ + //float mag = 200.f; + //float angle = 0.01f; + + /*Quality quality = QUALITY_VALIDITY_GOOD; + Timestamp timestamp; + + Timestamp_setTimeInMilliseconds(×tamp, Hal_getTimeInMs()); + + int i; + for (i = 0; i < 16; i++) { + updateCMVArrayElement(iedServer, mhai1_ha_phsAHar, i, mag, angle, quality, timestamp); + mag += 1.f; + angle += 0.01f; + }*/ + + /* MMS server will be instructed to start listening to client connections. */ + IedServer_start(iedServer, tcpPort); + + if (!IedServer_isRunning(iedServer)) { + printf("Starting server failed! Exit.\n"); + IedServer_destroy(iedServer); + exit(-1); + } + + running = 1; + + signal(SIGINT, sigint_handler); + + int counter = 0; + + while (running) { + Thread_sleep(1000); + + //Timestamp_setTimeInMilliseconds(×tamp, Hal_getTimeInMs()); + + IedServer_lockDataModel(iedServer); + + /*for (i = 0; i < 16; i++) { + updateCMVArrayElement(iedServer, mhai1_ha_phsAHar, i, mag, angle, quality, timestamp); + mag += 0.1f; + angle += 0.05f; + }*/ + + IedServer_unlockDataModel(iedServer); + + //if (counter == 10) { + // /* Now a problem occurs - measurements are invalid */ + // quality = QUALITY_VALIDITY_INVALID | QUALITY_DETAIL_FAILURE; + //} + + //counter++; + } + + /* stop MMS server - close TCP server socket and all client sockets */ + IedServer_stop(iedServer); + + /* Cleanup - free all resources */ + IedServer_destroy(iedServer); + + return 0; +} /* main() */ diff --git a/examples/server_example_SMV/static_model.c b/examples/server_example_SMV/static_model.c new file mode 100644 index 00000000..5a27de9f --- /dev/null +++ b/examples/server_example_SMV/static_model.c @@ -0,0 +1,371 @@ +/* + * static_model.c + * + * automatically generated from ICDFiles/simpleIO_smv.icd + */ +#include "static_model.h" + +static void initializeValues(); + + + +LogicalDevice iedModel_GenericIO = { + LogicalDeviceModelType, + "GenericIO", + (ModelNode*) &iedModel, + NULL, + (ModelNode*) &iedModel_GenericIO_666LLN051, + NULL +}; + +LogicalNode iedModel_GenericIO_666LLN051 = { + LogicalNodeModelType, + "666LLN051", + (ModelNode*) &iedModel_GenericIO, + NULL, + (ModelNode*) &iedModel_GenericIO_666LLN051_Mod +}; + +DataObject iedModel_GenericIO_666LLN051_Mod = { + DataObjectModelType, + "Mod", + (ModelNode*) &iedModel_GenericIO_666LLN051, + (ModelNode*) &iedModel_GenericIO_666LLN051_Beh, + (ModelNode*) &iedModel_GenericIO_666LLN051_Mod_stVal, + 0, + -1 +}; +DataAttribute iedModel_GenericIO_666LLN051_Mod_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_GenericIO_666LLN051_Mod, + (ModelNode*) &iedModel_GenericIO_666LLN051_Mod_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE + TRG_OPT_QUALITY_CHANGED, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_Mod_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_GenericIO_666LLN051_Mod, + (ModelNode*) &iedModel_GenericIO_666LLN051_Mod_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_Mod_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_GenericIO_666LLN051_Mod, + (ModelNode*) &iedModel_GenericIO_666LLN051_Mod_ctlModel, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_Mod_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_GenericIO_666LLN051_Mod, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_ENUMERATED, + 0, + NULL, + 0 +}; +DataObject iedModel_GenericIO_666LLN051_Beh = { + DataObjectModelType, + "Beh", + (ModelNode*) &iedModel_GenericIO_666LLN051, + (ModelNode*) &iedModel_GenericIO_666LLN051_Health, + (ModelNode*) &iedModel_GenericIO_666LLN051_Beh_stVal, + 0, + -1 +}; +DataAttribute iedModel_GenericIO_666LLN051_Beh_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_GenericIO_666LLN051_Beh, + (ModelNode*) &iedModel_GenericIO_666LLN051_Beh_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE + TRG_OPT_QUALITY_CHANGED, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_Beh_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_GenericIO_666LLN051_Beh, + (ModelNode*) &iedModel_GenericIO_666LLN051_Beh_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_Beh_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_GenericIO_666LLN051_Beh, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0 +}; +DataObject iedModel_GenericIO_666LLN051_Health = { + DataObjectModelType, + "Health", + (ModelNode*) &iedModel_GenericIO_666LLN051, + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt, + (ModelNode*) &iedModel_GenericIO_666LLN051_Health_stVal, + 0, + -1 +}; +DataAttribute iedModel_GenericIO_666LLN051_Health_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_GenericIO_666LLN051_Health, + (ModelNode*) &iedModel_GenericIO_666LLN051_Health_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE + TRG_OPT_QUALITY_CHANGED, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_Health_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_GenericIO_666LLN051_Health, + (ModelNode*) &iedModel_GenericIO_666LLN051_Health_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_Health_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_GenericIO_666LLN051_Health, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0 +}; +DataObject iedModel_GenericIO_666LLN051_NamPlt = { + DataObjectModelType, + "NamPlt", + (ModelNode*) &iedModel_GenericIO_666LLN051, + NULL, + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt_vendor, + 0, + -1 +}; +DataAttribute iedModel_GenericIO_666LLN051_NamPlt_vendor = { + DataAttributeModelType, + "vendor", + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt, + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt_swRev, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_NamPlt_swRev = { + DataAttributeModelType, + "swRev", + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt, + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt_d, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_NamPlt_d = { + DataAttributeModelType, + "d", + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt, + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt_configRev, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_NamPlt_configRev = { + DataAttributeModelType, + "configRev", + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt, + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt_ldNs, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0 +}; +DataAttribute iedModel_GenericIO_666LLN051_NamPlt_ldNs = { + DataAttributeModelType, + "ldNs", + (ModelNode*) &iedModel_GenericIO_666LLN051_NamPlt, + NULL, + NULL, + 0, + -1, + IEC61850_FC_EX, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0 +}; + + + +extern SettingGroupControlBlock iedModel_GenericIO_666LLN051_sgcb; + +SettingGroupControlBlock iedModel_GenericIO_666LLN051_sgcb = { + &iedModel_GenericIO_666LLN051, + 98, + 77, + 0, + false, + 0, + 0, + NULL, +}; + +extern SVControlBlock iedModel_GenericIO_666LLN051_smv0; +extern SVControlBlock iedModel_GenericIO_666LLN051_smv1; + + +static PhyComAddress iedModel_GenericIO_666LLN051_smv0_address = { + 4, + 123, + 4000, + {0x1, 0xc, 0xcd, 0x4, 0x0, 0x1} +}; + +SVControlBlock iedModel_GenericIO_666LLN051_smv0 = { + &iedModel_GenericIO_666LLN051, + "NewSMVControl", + "666655dd", + "Events2", + 23, + 1, + 555, + 5, + &iedModel_GenericIO_666LLN051_smv0_address, + true, + 98, + &iedModel_GenericIO_666LLN051_smv1 +}; + +static PhyComAddress iedModel_GenericIO_666LLN051_smv1_address = { + 4, + 123, + 4000, + {0x1, 0xc, 0xcd, 0x4, 0x0, 0x1} +}; + +SVControlBlock iedModel_GenericIO_666LLN051_smv1 = { + &iedModel_GenericIO_666LLN051, + "NewSMVControl1", + NULL, + "Events2", + 0, + NULL, + -1, + -1, + &iedModel_GenericIO_666LLN051_smv1_address, + false, + -1, + NULL +}; + + + +IedModel iedModel = { + "simpleIO", + &iedModel_GenericIO, + NULL, + NULL, + NULL, + &iedModel_GenericIO_666LLN051_smv0, + &iedModel_GenericIO_666LLN051_sgcb, + NULL, + NULL, + initializeValues +}; + +static void +initializeValues() +{ + +iedModel_GenericIO_666LLN051_Mod_stVal.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_GenericIO_666LLN051_Mod_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(0); + +iedModel_GenericIO_666LLN051_Beh_stVal.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_GenericIO_666LLN051_Health_stVal.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_GenericIO_666LLN051_NamPlt_vendor.mmsValue = MmsValue_newVisibleString("MZ Automation"); + +iedModel_GenericIO_666LLN051_NamPlt_swRev.mmsValue = MmsValue_newVisibleString("1.3.0"); + +iedModel_GenericIO_666LLN051_NamPlt_d.mmsValue = MmsValue_newVisibleString("libiec61850 server example"); +} diff --git a/examples/server_example_SMV/static_model.h b/examples/server_example_SMV/static_model.h new file mode 100644 index 00000000..8c57d157 --- /dev/null +++ b/examples/server_example_SMV/static_model.h @@ -0,0 +1,62 @@ +/* + * static_model.h + * + * automatically generated from ICDFiles/simpleIO_smv.icd + */ + +#ifndef STATIC_MODEL_H_ +#define STATIC_MODEL_H_ + +#include +#include "iec61850_model.h" + +extern IedModel iedModel; +extern LogicalDevice iedModel_GenericIO; +extern LogicalNode iedModel_GenericIO_666LLN051; +extern DataObject iedModel_GenericIO_666LLN051_Mod; +extern DataAttribute iedModel_GenericIO_666LLN051_Mod_stVal; +extern DataAttribute iedModel_GenericIO_666LLN051_Mod_q; +extern DataAttribute iedModel_GenericIO_666LLN051_Mod_t; +extern DataAttribute iedModel_GenericIO_666LLN051_Mod_ctlModel; +extern DataObject iedModel_GenericIO_666LLN051_Beh; +extern DataAttribute iedModel_GenericIO_666LLN051_Beh_stVal; +extern DataAttribute iedModel_GenericIO_666LLN051_Beh_q; +extern DataAttribute iedModel_GenericIO_666LLN051_Beh_t; +extern DataObject iedModel_GenericIO_666LLN051_Health; +extern DataAttribute iedModel_GenericIO_666LLN051_Health_stVal; +extern DataAttribute iedModel_GenericIO_666LLN051_Health_q; +extern DataAttribute iedModel_GenericIO_666LLN051_Health_t; +extern DataObject iedModel_GenericIO_666LLN051_NamPlt; +extern DataAttribute iedModel_GenericIO_666LLN051_NamPlt_vendor; +extern DataAttribute iedModel_GenericIO_666LLN051_NamPlt_swRev; +extern DataAttribute iedModel_GenericIO_666LLN051_NamPlt_d; +extern DataAttribute iedModel_GenericIO_666LLN051_NamPlt_configRev; +extern DataAttribute iedModel_GenericIO_666LLN051_NamPlt_ldNs; + + + + +#define IEDMODEL_GenericIO (&iedModel_GenericIO) +#define IEDMODEL_GenericIO_666LLN051 (&iedModel_GenericIO_666LLN051) +#define IEDMODEL_GenericIO_666LLN051_Mod (&iedModel_GenericIO_666LLN051_Mod) +#define IEDMODEL_GenericIO_666LLN051_Mod_stVal (&iedModel_GenericIO_666LLN051_Mod_stVal) +#define IEDMODEL_GenericIO_666LLN051_Mod_q (&iedModel_GenericIO_666LLN051_Mod_q) +#define IEDMODEL_GenericIO_666LLN051_Mod_t (&iedModel_GenericIO_666LLN051_Mod_t) +#define IEDMODEL_GenericIO_666LLN051_Mod_ctlModel (&iedModel_GenericIO_666LLN051_Mod_ctlModel) +#define IEDMODEL_GenericIO_666LLN051_Beh (&iedModel_GenericIO_666LLN051_Beh) +#define IEDMODEL_GenericIO_666LLN051_Beh_stVal (&iedModel_GenericIO_666LLN051_Beh_stVal) +#define IEDMODEL_GenericIO_666LLN051_Beh_q (&iedModel_GenericIO_666LLN051_Beh_q) +#define IEDMODEL_GenericIO_666LLN051_Beh_t (&iedModel_GenericIO_666LLN051_Beh_t) +#define IEDMODEL_GenericIO_666LLN051_Health (&iedModel_GenericIO_666LLN051_Health) +#define IEDMODEL_GenericIO_666LLN051_Health_stVal (&iedModel_GenericIO_666LLN051_Health_stVal) +#define IEDMODEL_GenericIO_666LLN051_Health_q (&iedModel_GenericIO_666LLN051_Health_q) +#define IEDMODEL_GenericIO_666LLN051_Health_t (&iedModel_GenericIO_666LLN051_Health_t) +#define IEDMODEL_GenericIO_666LLN051_NamPlt (&iedModel_GenericIO_666LLN051_NamPlt) +#define IEDMODEL_GenericIO_666LLN051_NamPlt_vendor (&iedModel_GenericIO_666LLN051_NamPlt_vendor) +#define IEDMODEL_GenericIO_666LLN051_NamPlt_swRev (&iedModel_GenericIO_666LLN051_NamPlt_swRev) +#define IEDMODEL_GenericIO_666LLN051_NamPlt_d (&iedModel_GenericIO_666LLN051_NamPlt_d) +#define IEDMODEL_GenericIO_666LLN051_NamPlt_configRev (&iedModel_GenericIO_666LLN051_NamPlt_configRev) +#define IEDMODEL_GenericIO_666LLN051_NamPlt_ldNs (&iedModel_GenericIO_666LLN051_NamPlt_ldNs) + +#endif /* STATIC_MODEL_H_ */ + diff --git a/examples/server_example_SMV/static_model_5.c b/examples/server_example_SMV/static_model_5.c new file mode 100644 index 00000000..c4daacdf --- /dev/null +++ b/examples/server_example_SMV/static_model_5.c @@ -0,0 +1,3880 @@ +/* + * static_model.c + * + * automatically generated from mhai_array.cid + */ +#include "static_model.h" + +static void initializeValues(); + +extern DataSet iedModelds_ComplexArray_MHAI1_TestMHAI; + + +extern DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda0; +extern DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda1; +extern DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda2; +extern DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda3; +extern DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda4; + +DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda0 = { + "ComplexArray", + false, + "MHAI1$MX$HA$phsAHar", + 7, + NULL, + NULL, + &iedModelds_ComplexArray_MHAI1_TestMHAI_fcda1 +}; + +DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda1 = { + "ComplexArray", + false, + "MHAI1$MX$HA$phsAHar", + 8, + NULL, + NULL, + &iedModelds_ComplexArray_MHAI1_TestMHAI_fcda2 +}; + +DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda2 = { + "ComplexArray", + false, + "MHAI1$MX$HA$phsAHar", + 9, + "cVal", + NULL, + &iedModelds_ComplexArray_MHAI1_TestMHAI_fcda3 +}; + +DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda3 = { + "ComplexArray", + false, + "MHAI1$MX$HA$phsAHar", + 10, + "cVal$mag", + NULL, + &iedModelds_ComplexArray_MHAI1_TestMHAI_fcda4 +}; + +DataSetEntry iedModelds_ComplexArray_MHAI1_TestMHAI_fcda4 = { + "ComplexArray", + false, + "MHAI1$MX$HA$phsAHar", + 11, + "cVal$mag$f", + NULL, + NULL +}; + +DataSet iedModelds_ComplexArray_MHAI1_TestMHAI = { + "ComplexArray", + "MHAI1$TestMHAI", + 5, + &iedModelds_ComplexArray_MHAI1_TestMHAI_fcda0, + NULL +}; + +LogicalDevice iedModel_ComplexArray = { + LogicalDeviceModelType, + "ComplexArray", + (ModelNode*) &iedModel, + NULL, + (ModelNode*) &iedModel_ComplexArray_LLN0, + NULL +}; + +LogicalNode iedModel_ComplexArray_LLN0 = { + LogicalNodeModelType, + "LLN0", + (ModelNode*) &iedModel_ComplexArray, + (ModelNode*) &iedModel_ComplexArray_LPHD1, + (ModelNode*) &iedModel_ComplexArray_LLN0_Mod, +}; + +DataObject iedModel_ComplexArray_LLN0_Mod = { + DataObjectModelType, + "Mod", + (ModelNode*) &iedModel_ComplexArray_LLN0, + (ModelNode*) &iedModel_ComplexArray_LLN0_Beh, + (ModelNode*) &iedModel_ComplexArray_LLN0_Mod_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_LLN0_Mod_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_LLN0_Mod, + (ModelNode*) &iedModel_ComplexArray_LLN0_Mod_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_Mod_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_LLN0_Mod, + (ModelNode*) &iedModel_ComplexArray_LLN0_Mod_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_Mod_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_LLN0_Mod, + (ModelNode*) &iedModel_ComplexArray_LLN0_Mod_ctlModel, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_Mod_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_ComplexArray_LLN0_Mod, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_LLN0_Beh = { + DataObjectModelType, + "Beh", + (ModelNode*) &iedModel_ComplexArray_LLN0, + (ModelNode*) &iedModel_ComplexArray_LLN0_Health, + (ModelNode*) &iedModel_ComplexArray_LLN0_Beh_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_LLN0_Beh_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_LLN0_Beh, + (ModelNode*) &iedModel_ComplexArray_LLN0_Beh_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_Beh_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_LLN0_Beh, + (ModelNode*) &iedModel_ComplexArray_LLN0_Beh_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_Beh_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_LLN0_Beh, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_LLN0_Health = { + DataObjectModelType, + "Health", + (ModelNode*) &iedModel_ComplexArray_LLN0, + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt, + (ModelNode*) &iedModel_ComplexArray_LLN0_Health_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_LLN0_Health_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_LLN0_Health, + (ModelNode*) &iedModel_ComplexArray_LLN0_Health_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_Health_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_LLN0_Health, + (ModelNode*) &iedModel_ComplexArray_LLN0_Health_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_Health_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_LLN0_Health, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_LLN0_NamPlt = { + DataObjectModelType, + "NamPlt", + (ModelNode*) &iedModel_ComplexArray_LLN0, + NULL, + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt_vendor, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_LLN0_NamPlt_vendor = { + DataAttributeModelType, + "vendor", + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt, + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt_swRev, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_NamPlt_swRev = { + DataAttributeModelType, + "swRev", + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt, + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt_d, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_NamPlt_d = { + DataAttributeModelType, + "d", + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt, + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt_configRev, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_NamPlt_configRev = { + DataAttributeModelType, + "configRev", + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt, + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt_ldNs, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LLN0_NamPlt_ldNs = { + DataAttributeModelType, + "ldNs", + (ModelNode*) &iedModel_ComplexArray_LLN0_NamPlt, + NULL, + NULL, + 0, + -1, + IEC61850_FC_EX, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0}; + +LogicalNode iedModel_ComplexArray_LPHD1 = { + LogicalNodeModelType, + "LPHD1", + (ModelNode*) &iedModel_ComplexArray, + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_LPHD1_PhyNam, +}; + +DataObject iedModel_ComplexArray_LPHD1_PhyNam = { + DataObjectModelType, + "PhyNam", + (ModelNode*) &iedModel_ComplexArray_LPHD1, + (ModelNode*) &iedModel_ComplexArray_LPHD1_PhyHealth, + (ModelNode*) &iedModel_ComplexArray_LPHD1_PhyNam_vendor, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_LPHD1_PhyNam_vendor = { + DataAttributeModelType, + "vendor", + (ModelNode*) &iedModel_ComplexArray_LPHD1_PhyNam, + NULL, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_LPHD1_PhyHealth = { + DataObjectModelType, + "PhyHealth", + (ModelNode*) &iedModel_ComplexArray_LPHD1, + (ModelNode*) &iedModel_ComplexArray_LPHD1_Proxy, + (ModelNode*) &iedModel_ComplexArray_LPHD1_PhyHealth_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_LPHD1_PhyHealth_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_LPHD1_PhyHealth, + (ModelNode*) &iedModel_ComplexArray_LPHD1_PhyHealth_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LPHD1_PhyHealth_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_LPHD1_PhyHealth, + (ModelNode*) &iedModel_ComplexArray_LPHD1_PhyHealth_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LPHD1_PhyHealth_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_LPHD1_PhyHealth, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_LPHD1_Proxy = { + DataObjectModelType, + "Proxy", + (ModelNode*) &iedModel_ComplexArray_LPHD1, + NULL, + (ModelNode*) &iedModel_ComplexArray_LPHD1_Proxy_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_LPHD1_Proxy_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_LPHD1_Proxy, + (ModelNode*) &iedModel_ComplexArray_LPHD1_Proxy_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LPHD1_Proxy_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_LPHD1_Proxy, + (ModelNode*) &iedModel_ComplexArray_LPHD1_Proxy_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_LPHD1_Proxy_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_LPHD1_Proxy, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +LogicalNode iedModel_ComplexArray_GGIO1 = { + LogicalNodeModelType, + "GGIO1", + (ModelNode*) &iedModel_ComplexArray, + (ModelNode*) &iedModel_ComplexArray_MHAI1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Mod, +}; + +DataObject iedModel_ComplexArray_GGIO1_Mod = { + DataObjectModelType, + "Mod", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Beh, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Mod_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_Mod_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Mod, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Mod_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Mod_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Mod, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Mod_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Mod_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Mod, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Mod_ctlModel, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Mod_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Mod, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_Beh = { + DataObjectModelType, + "Beh", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Health, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Beh_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_Beh_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Beh, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Beh_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Beh_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Beh, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Beh_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Beh_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Beh, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_Health = { + DataObjectModelType, + "Health", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_NamPlt, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Health_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_Health_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Health, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Health_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Health_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Health, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Health_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Health_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Health, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_NamPlt = { + DataObjectModelType, + "NamPlt", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_NamPlt_vendor, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_NamPlt_vendor = { + DataAttributeModelType, + "vendor", + (ModelNode*) &iedModel_ComplexArray_GGIO1_NamPlt, + (ModelNode*) &iedModel_ComplexArray_GGIO1_NamPlt_swRev, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_NamPlt_swRev = { + DataAttributeModelType, + "swRev", + (ModelNode*) &iedModel_ComplexArray_GGIO1_NamPlt, + (ModelNode*) &iedModel_ComplexArray_GGIO1_NamPlt_d, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_NamPlt_d = { + DataAttributeModelType, + "d", + (ModelNode*) &iedModel_ComplexArray_GGIO1_NamPlt, + (ModelNode*) &iedModel_ComplexArray_GGIO1_NamPlt_dU, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_VISIBLE_STRING_255, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_NamPlt_dU = { + DataAttributeModelType, + "dU", + (ModelNode*) &iedModel_ComplexArray_GGIO1_NamPlt, + NULL, + NULL, + 0, + -1, + IEC61850_FC_DC, + IEC61850_UNICODE_STRING_255, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_AnIn1 = { + DataObjectModelType, + "AnIn1", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn1_mag, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn1_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn1_q, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn1_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn1_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn1_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn1_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn1_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn1_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn1, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_AnIn2 = { + DataObjectModelType, + "AnIn2", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn2_mag, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn2_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn2_q, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn2_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn2_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn2_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn2_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn2_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn2_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn2, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_AnIn3 = { + DataObjectModelType, + "AnIn3", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn3_mag, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn3_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn3_q, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn3_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn3_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn3_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn3_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn3_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn3_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn3, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_AnIn4 = { + DataObjectModelType, + "AnIn4", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn4_mag, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn4_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn4_q, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn4_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn4_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn4_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn4_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn4_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_AnIn4_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_AnIn4, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_SPCSO1 = { + DataObjectModelType, + "SPCSO1", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_origin, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_origin = { + DataAttributeModelType, + "origin", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_ctlNum, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_origin_orCat, + 0, + -1, + IEC61850_FC_ST, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_origin_orCat = { + DataAttributeModelType, + "orCat", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_origin, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_origin_orIdent, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_origin_orIdent = { + DataAttributeModelType, + "orIdent", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_origin, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_OCTET_STRING_64, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_ctlNum = { + DataAttributeModelType, + "ctlNum", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_stVal, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_INT8U, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_ctlModel, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper = { + DataAttributeModelType, + "Oper", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1, + NULL, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper_ctlVal, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_ctlVal = { + DataAttributeModelType, + "ctlVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_BOOLEAN, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin = { + DataAttributeModelType, + "origin", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper_ctlNum, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin_orCat, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin_orCat = { + DataAttributeModelType, + "orCat", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin_orIdent, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin_orIdent = { + DataAttributeModelType, + "orIdent", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_OCTET_STRING_64, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_ctlNum = { + DataAttributeModelType, + "ctlNum", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper_T, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_INT8U, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_T = { + DataAttributeModelType, + "T", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper_Test, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_Test = { + DataAttributeModelType, + "Test", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper_Check, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_BOOLEAN, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_Check = { + DataAttributeModelType, + "Check", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO1_Oper, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CHECK, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_SPCSO2 = { + DataObjectModelType, + "SPCSO2", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper = { + DataAttributeModelType, + "Oper", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_ctlModel, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper_ctlVal, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_ctlVal = { + DataAttributeModelType, + "ctlVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_BOOLEAN, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin = { + DataAttributeModelType, + "origin", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper_ctlNum, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin_orCat, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin_orCat = { + DataAttributeModelType, + "orCat", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin_orIdent, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin_orIdent = { + DataAttributeModelType, + "orIdent", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_OCTET_STRING_64, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_ctlNum = { + DataAttributeModelType, + "ctlNum", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper_T, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_INT8U, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_T = { + DataAttributeModelType, + "T", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper_Test, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_Test = { + DataAttributeModelType, + "Test", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper_Check, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_BOOLEAN, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_Check = { + DataAttributeModelType, + "Check", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_Oper, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CHECK, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2_t, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO2, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_SPCSO3 = { + DataObjectModelType, + "SPCSO3", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper = { + DataAttributeModelType, + "Oper", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_ctlModel, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper_ctlVal, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_ctlVal = { + DataAttributeModelType, + "ctlVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_BOOLEAN, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin = { + DataAttributeModelType, + "origin", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper_ctlNum, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin_orCat, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin_orCat = { + DataAttributeModelType, + "orCat", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin_orIdent, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin_orIdent = { + DataAttributeModelType, + "orIdent", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_OCTET_STRING_64, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_ctlNum = { + DataAttributeModelType, + "ctlNum", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper_T, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_INT8U, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_T = { + DataAttributeModelType, + "T", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper_Test, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_Test = { + DataAttributeModelType, + "Test", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper_Check, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_BOOLEAN, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_Check = { + DataAttributeModelType, + "Check", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_Oper, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CHECK, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3_t, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO3, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_SPCSO4 = { + DataObjectModelType, + "SPCSO4", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper = { + DataAttributeModelType, + "Oper", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_ctlModel, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper_ctlVal, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_ctlVal = { + DataAttributeModelType, + "ctlVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_BOOLEAN, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin = { + DataAttributeModelType, + "origin", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper_ctlNum, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin_orCat, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin_orCat = { + DataAttributeModelType, + "orCat", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin_orIdent, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin_orIdent = { + DataAttributeModelType, + "orIdent", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_OCTET_STRING_64, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_ctlNum = { + DataAttributeModelType, + "ctlNum", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper_T, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_INT8U, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_T = { + DataAttributeModelType, + "T", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper_Test, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_Test = { + DataAttributeModelType, + "Test", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper_Check, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_BOOLEAN, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_Check = { + DataAttributeModelType, + "Check", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_Oper, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CO, + IEC61850_CHECK, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_ctlModel = { + DataAttributeModelType, + "ctlModel", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4_t, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_ENUMERATED, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_SPCSO4, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_Ind1 = { + DataObjectModelType, + "Ind1", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind1_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind1_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind1_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind1_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind1_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind1_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind1, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_Ind2 = { + DataObjectModelType, + "Ind2", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind2_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind2_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind2_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind2_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind2, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind2_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind2_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind2, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_Ind3 = { + DataObjectModelType, + "Ind3", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind3_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind3_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind3_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind3_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind3, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind3_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind3_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind3, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_GGIO1_Ind4 = { + DataObjectModelType, + "Ind4", + (ModelNode*) &iedModel_ComplexArray_GGIO1, + NULL, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind4_stVal, + 0, + -1 +}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind4_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind4_q, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_BOOLEAN, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind4_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind4, + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind4_t, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_GGIO1_Ind4_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_GGIO1_Ind4, + NULL, + NULL, + 0, + -1, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +LogicalNode iedModel_ComplexArray_MHAI1 = { + LogicalNodeModelType, + "MHAI1", + (ModelNode*) &iedModel_ComplexArray, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA, +}; + +DataObject iedModel_ComplexArray_MHAI1_HA = { + DataObjectModelType, + "HA", + (ModelNode*) &iedModel_ComplexArray_MHAI1, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + 0, + -1 +}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_numHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0, + 16, + 0-1 +}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_0 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal, + 0, + 0 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_0, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_1 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal, + 0, + 1 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_1, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_2 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal, + 0, + 2 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_2, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_3 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal, + 0, + 3 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_3, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_4 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal, + 0, + 4 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_4, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_5 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal, + 0, + 5 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_5, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_6 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal, + 0, + 6 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_6, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_7 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal, + 0, + 7 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_7, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_8 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal, + 0, + 8 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_8, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_9 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal, + 0, + 9 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_9, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_10 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal, + 0, + 10 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_10, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_11 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal, + 0, + 11 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_11, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_12 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal, + 0, + 12 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_12, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_13 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal, + 0, + 13 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_13, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_14 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal, + 0, + 14 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_14, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_15 = { + DataObjectModelType, + "phsAHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal, + 0, + 15 +}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal = { + DataAttributeModelType, + "cVal", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_q, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag = { + DataAttributeModelType, + "mag", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang = { + DataAttributeModelType, + "ang", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal, + NULL, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang_f, + 0, + -1, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang_f = { + DataAttributeModelType, + "f", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED + TRG_OPT_DATA_UPDATE, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15_t, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0 + TRG_OPT_QUALITY_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_phsAHar_15, + NULL, + NULL, + 0, + -1, + IEC61850_FC_MX, + IEC61850_TIMESTAMP, + 0, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_numHar = { + DataAttributeModelType, + "numHar", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_numCyc, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_INT16U, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_numCyc = { + DataAttributeModelType, + "numCyc", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_evalTm, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_INT16U, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_evalTm = { + DataAttributeModelType, + "evalTm", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA, + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA_frequency, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_INT16U, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_ComplexArray_MHAI1_HA_frequency = { + DataAttributeModelType, + "frequency", + (ModelNode*) &iedModel_ComplexArray_MHAI1_HA, + NULL, + NULL, + 0, + -1, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +extern ReportControlBlock iedModel_ComplexArray_MHAI1_report0; + +ReportControlBlock iedModel_ComplexArray_MHAI1_report0 = {&iedModel_ComplexArray_MHAI1, "MHAIRCB01", "TestMHAI", false, "TestMHAI", 1, 24, 175, 50, 1000, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, NULL}; + + + + + + + +IedModel iedModel = { + "test", + &iedModel_ComplexArray, + &iedModelds_ComplexArray_MHAI1_TestMHAI, + &iedModel_ComplexArray_MHAI1_report0, + NULL, + NULL, + NULL, + NULL, + NULL, + initializeValues +}; + +static void +initializeValues() +{ + +iedModel_ComplexArray_LLN0_Mod_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(0); + +iedModel_ComplexArray_LPHD1_PhyHealth_stVal.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_ComplexArray_GGIO1_Mod_stVal.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_ComplexArray_GGIO1_Mod_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(0); + +iedModel_ComplexArray_GGIO1_Beh_stVal.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_ComplexArray_GGIO1_Health_stVal.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_ComplexArray_GGIO1_SPCSO1_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_ComplexArray_GGIO1_SPCSO2_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_ComplexArray_GGIO1_SPCSO3_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_ComplexArray_GGIO1_SPCSO4_ctlModel.mmsValue = MmsValue_newIntegerFromInt32(1); + +iedModel_ComplexArray_MHAI1_HA_numHar.mmsValue = MmsValue_newUnsignedFromUint32(16); +} diff --git a/examples/server_example_SMV/static_model_5.h b/examples/server_example_SMV/static_model_5.h new file mode 100644 index 00000000..77bb51c2 --- /dev/null +++ b/examples/server_example_SMV/static_model_5.h @@ -0,0 +1,567 @@ +/* + * static_model.h + * + * automatically generated from mhai_array.cid + */ + +#ifndef STATIC_MODEL_H_ +#define STATIC_MODEL_H_ + +#include +#include "iec61850_model.h" + +extern IedModel iedModel; +extern LogicalDevice iedModel_ComplexArray; +extern LogicalNode iedModel_ComplexArray_LLN0; +extern DataObject iedModel_ComplexArray_LLN0_Mod; +extern DataAttribute iedModel_ComplexArray_LLN0_Mod_stVal; +extern DataAttribute iedModel_ComplexArray_LLN0_Mod_q; +extern DataAttribute iedModel_ComplexArray_LLN0_Mod_t; +extern DataAttribute iedModel_ComplexArray_LLN0_Mod_ctlModel; +extern DataObject iedModel_ComplexArray_LLN0_Beh; +extern DataAttribute iedModel_ComplexArray_LLN0_Beh_stVal; +extern DataAttribute iedModel_ComplexArray_LLN0_Beh_q; +extern DataAttribute iedModel_ComplexArray_LLN0_Beh_t; +extern DataObject iedModel_ComplexArray_LLN0_Health; +extern DataAttribute iedModel_ComplexArray_LLN0_Health_stVal; +extern DataAttribute iedModel_ComplexArray_LLN0_Health_q; +extern DataAttribute iedModel_ComplexArray_LLN0_Health_t; +extern DataObject iedModel_ComplexArray_LLN0_NamPlt; +extern DataAttribute iedModel_ComplexArray_LLN0_NamPlt_vendor; +extern DataAttribute iedModel_ComplexArray_LLN0_NamPlt_swRev; +extern DataAttribute iedModel_ComplexArray_LLN0_NamPlt_d; +extern DataAttribute iedModel_ComplexArray_LLN0_NamPlt_configRev; +extern DataAttribute iedModel_ComplexArray_LLN0_NamPlt_ldNs; +extern LogicalNode iedModel_ComplexArray_LPHD1; +extern DataObject iedModel_ComplexArray_LPHD1_PhyNam; +extern DataAttribute iedModel_ComplexArray_LPHD1_PhyNam_vendor; +extern DataObject iedModel_ComplexArray_LPHD1_PhyHealth; +extern DataAttribute iedModel_ComplexArray_LPHD1_PhyHealth_stVal; +extern DataAttribute iedModel_ComplexArray_LPHD1_PhyHealth_q; +extern DataAttribute iedModel_ComplexArray_LPHD1_PhyHealth_t; +extern DataObject iedModel_ComplexArray_LPHD1_Proxy; +extern DataAttribute iedModel_ComplexArray_LPHD1_Proxy_stVal; +extern DataAttribute iedModel_ComplexArray_LPHD1_Proxy_q; +extern DataAttribute iedModel_ComplexArray_LPHD1_Proxy_t; +extern LogicalNode iedModel_ComplexArray_GGIO1; +extern DataObject iedModel_ComplexArray_GGIO1_Mod; +extern DataAttribute iedModel_ComplexArray_GGIO1_Mod_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_Mod_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_Mod_t; +extern DataAttribute iedModel_ComplexArray_GGIO1_Mod_ctlModel; +extern DataObject iedModel_ComplexArray_GGIO1_Beh; +extern DataAttribute iedModel_ComplexArray_GGIO1_Beh_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_Beh_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_Beh_t; +extern DataObject iedModel_ComplexArray_GGIO1_Health; +extern DataAttribute iedModel_ComplexArray_GGIO1_Health_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_Health_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_Health_t; +extern DataObject iedModel_ComplexArray_GGIO1_NamPlt; +extern DataAttribute iedModel_ComplexArray_GGIO1_NamPlt_vendor; +extern DataAttribute iedModel_ComplexArray_GGIO1_NamPlt_swRev; +extern DataAttribute iedModel_ComplexArray_GGIO1_NamPlt_d; +extern DataAttribute iedModel_ComplexArray_GGIO1_NamPlt_dU; +extern DataObject iedModel_ComplexArray_GGIO1_AnIn1; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn1_mag; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn1_mag_f; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn1_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn1_t; +extern DataObject iedModel_ComplexArray_GGIO1_AnIn2; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn2_mag; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn2_mag_f; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn2_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn2_t; +extern DataObject iedModel_ComplexArray_GGIO1_AnIn3; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn3_mag; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn3_mag_f; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn3_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn3_t; +extern DataObject iedModel_ComplexArray_GGIO1_AnIn4; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn4_mag; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn4_mag_f; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn4_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_AnIn4_t; +extern DataObject iedModel_ComplexArray_GGIO1_SPCSO1; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_origin; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_origin_orCat; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_origin_orIdent; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_ctlNum; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_t; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_ctlModel; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_ctlVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin_orCat; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin_orIdent; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_ctlNum; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_T; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_Test; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO1_Oper_Check; +extern DataObject iedModel_ComplexArray_GGIO1_SPCSO2; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_ctlVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin_orCat; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin_orIdent; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_ctlNum; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_T; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_Test; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_Oper_Check; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_ctlModel; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO2_t; +extern DataObject iedModel_ComplexArray_GGIO1_SPCSO3; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_ctlVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin_orCat; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin_orIdent; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_ctlNum; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_T; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_Test; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_Oper_Check; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_ctlModel; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO3_t; +extern DataObject iedModel_ComplexArray_GGIO1_SPCSO4; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_ctlVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin_orCat; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin_orIdent; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_ctlNum; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_T; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_Test; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_Oper_Check; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_ctlModel; +extern DataAttribute iedModel_ComplexArray_GGIO1_SPCSO4_t; +extern DataObject iedModel_ComplexArray_GGIO1_Ind1; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind1_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind1_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind1_t; +extern DataObject iedModel_ComplexArray_GGIO1_Ind2; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind2_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind2_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind2_t; +extern DataObject iedModel_ComplexArray_GGIO1_Ind3; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind3_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind3_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind3_t; +extern DataObject iedModel_ComplexArray_GGIO1_Ind4; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind4_stVal; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind4_q; +extern DataAttribute iedModel_ComplexArray_GGIO1_Ind4_t; +extern LogicalNode iedModel_ComplexArray_MHAI1; +extern DataObject iedModel_ComplexArray_MHAI1_HA; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_0; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_0_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_1; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_1_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_2; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_2_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_3; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_3_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_4; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_4_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_5; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_5_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_6; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_6_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_7; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_7_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_8; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_8_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_9; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_9_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_10; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_10_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_11; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_11_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_12; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_12_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_13; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_13_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_14; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_14_t; +extern DataObject iedModel_ComplexArray_MHAI1_HA_phsAHar_15; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang_f; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_q; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_phsAHar_15_t; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_numHar; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_numCyc; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_evalTm; +extern DataAttribute iedModel_ComplexArray_MHAI1_HA_frequency; + + + +#define IEDMODEL_ComplexArray (&iedModel_ComplexArray) +#define IEDMODEL_ComplexArray_LLN0 (&iedModel_ComplexArray_LLN0) +#define IEDMODEL_ComplexArray_LLN0_Mod (&iedModel_ComplexArray_LLN0_Mod) +#define IEDMODEL_ComplexArray_LLN0_Mod_stVal (&iedModel_ComplexArray_LLN0_Mod_stVal) +#define IEDMODEL_ComplexArray_LLN0_Mod_q (&iedModel_ComplexArray_LLN0_Mod_q) +#define IEDMODEL_ComplexArray_LLN0_Mod_t (&iedModel_ComplexArray_LLN0_Mod_t) +#define IEDMODEL_ComplexArray_LLN0_Mod_ctlModel (&iedModel_ComplexArray_LLN0_Mod_ctlModel) +#define IEDMODEL_ComplexArray_LLN0_Beh (&iedModel_ComplexArray_LLN0_Beh) +#define IEDMODEL_ComplexArray_LLN0_Beh_stVal (&iedModel_ComplexArray_LLN0_Beh_stVal) +#define IEDMODEL_ComplexArray_LLN0_Beh_q (&iedModel_ComplexArray_LLN0_Beh_q) +#define IEDMODEL_ComplexArray_LLN0_Beh_t (&iedModel_ComplexArray_LLN0_Beh_t) +#define IEDMODEL_ComplexArray_LLN0_Health (&iedModel_ComplexArray_LLN0_Health) +#define IEDMODEL_ComplexArray_LLN0_Health_stVal (&iedModel_ComplexArray_LLN0_Health_stVal) +#define IEDMODEL_ComplexArray_LLN0_Health_q (&iedModel_ComplexArray_LLN0_Health_q) +#define IEDMODEL_ComplexArray_LLN0_Health_t (&iedModel_ComplexArray_LLN0_Health_t) +#define IEDMODEL_ComplexArray_LLN0_NamPlt (&iedModel_ComplexArray_LLN0_NamPlt) +#define IEDMODEL_ComplexArray_LLN0_NamPlt_vendor (&iedModel_ComplexArray_LLN0_NamPlt_vendor) +#define IEDMODEL_ComplexArray_LLN0_NamPlt_swRev (&iedModel_ComplexArray_LLN0_NamPlt_swRev) +#define IEDMODEL_ComplexArray_LLN0_NamPlt_d (&iedModel_ComplexArray_LLN0_NamPlt_d) +#define IEDMODEL_ComplexArray_LLN0_NamPlt_configRev (&iedModel_ComplexArray_LLN0_NamPlt_configRev) +#define IEDMODEL_ComplexArray_LLN0_NamPlt_ldNs (&iedModel_ComplexArray_LLN0_NamPlt_ldNs) +#define IEDMODEL_ComplexArray_LPHD1 (&iedModel_ComplexArray_LPHD1) +#define IEDMODEL_ComplexArray_LPHD1_PhyNam (&iedModel_ComplexArray_LPHD1_PhyNam) +#define IEDMODEL_ComplexArray_LPHD1_PhyNam_vendor (&iedModel_ComplexArray_LPHD1_PhyNam_vendor) +#define IEDMODEL_ComplexArray_LPHD1_PhyHealth (&iedModel_ComplexArray_LPHD1_PhyHealth) +#define IEDMODEL_ComplexArray_LPHD1_PhyHealth_stVal (&iedModel_ComplexArray_LPHD1_PhyHealth_stVal) +#define IEDMODEL_ComplexArray_LPHD1_PhyHealth_q (&iedModel_ComplexArray_LPHD1_PhyHealth_q) +#define IEDMODEL_ComplexArray_LPHD1_PhyHealth_t (&iedModel_ComplexArray_LPHD1_PhyHealth_t) +#define IEDMODEL_ComplexArray_LPHD1_Proxy (&iedModel_ComplexArray_LPHD1_Proxy) +#define IEDMODEL_ComplexArray_LPHD1_Proxy_stVal (&iedModel_ComplexArray_LPHD1_Proxy_stVal) +#define IEDMODEL_ComplexArray_LPHD1_Proxy_q (&iedModel_ComplexArray_LPHD1_Proxy_q) +#define IEDMODEL_ComplexArray_LPHD1_Proxy_t (&iedModel_ComplexArray_LPHD1_Proxy_t) +#define IEDMODEL_ComplexArray_GGIO1 (&iedModel_ComplexArray_GGIO1) +#define IEDMODEL_ComplexArray_GGIO1_Mod (&iedModel_ComplexArray_GGIO1_Mod) +#define IEDMODEL_ComplexArray_GGIO1_Mod_stVal (&iedModel_ComplexArray_GGIO1_Mod_stVal) +#define IEDMODEL_ComplexArray_GGIO1_Mod_q (&iedModel_ComplexArray_GGIO1_Mod_q) +#define IEDMODEL_ComplexArray_GGIO1_Mod_t (&iedModel_ComplexArray_GGIO1_Mod_t) +#define IEDMODEL_ComplexArray_GGIO1_Mod_ctlModel (&iedModel_ComplexArray_GGIO1_Mod_ctlModel) +#define IEDMODEL_ComplexArray_GGIO1_Beh (&iedModel_ComplexArray_GGIO1_Beh) +#define IEDMODEL_ComplexArray_GGIO1_Beh_stVal (&iedModel_ComplexArray_GGIO1_Beh_stVal) +#define IEDMODEL_ComplexArray_GGIO1_Beh_q (&iedModel_ComplexArray_GGIO1_Beh_q) +#define IEDMODEL_ComplexArray_GGIO1_Beh_t (&iedModel_ComplexArray_GGIO1_Beh_t) +#define IEDMODEL_ComplexArray_GGIO1_Health (&iedModel_ComplexArray_GGIO1_Health) +#define IEDMODEL_ComplexArray_GGIO1_Health_stVal (&iedModel_ComplexArray_GGIO1_Health_stVal) +#define IEDMODEL_ComplexArray_GGIO1_Health_q (&iedModel_ComplexArray_GGIO1_Health_q) +#define IEDMODEL_ComplexArray_GGIO1_Health_t (&iedModel_ComplexArray_GGIO1_Health_t) +#define IEDMODEL_ComplexArray_GGIO1_NamPlt (&iedModel_ComplexArray_GGIO1_NamPlt) +#define IEDMODEL_ComplexArray_GGIO1_NamPlt_vendor (&iedModel_ComplexArray_GGIO1_NamPlt_vendor) +#define IEDMODEL_ComplexArray_GGIO1_NamPlt_swRev (&iedModel_ComplexArray_GGIO1_NamPlt_swRev) +#define IEDMODEL_ComplexArray_GGIO1_NamPlt_d (&iedModel_ComplexArray_GGIO1_NamPlt_d) +#define IEDMODEL_ComplexArray_GGIO1_NamPlt_dU (&iedModel_ComplexArray_GGIO1_NamPlt_dU) +#define IEDMODEL_ComplexArray_GGIO1_AnIn1 (&iedModel_ComplexArray_GGIO1_AnIn1) +#define IEDMODEL_ComplexArray_GGIO1_AnIn1_mag (&iedModel_ComplexArray_GGIO1_AnIn1_mag) +#define IEDMODEL_ComplexArray_GGIO1_AnIn1_mag_f (&iedModel_ComplexArray_GGIO1_AnIn1_mag_f) +#define IEDMODEL_ComplexArray_GGIO1_AnIn1_q (&iedModel_ComplexArray_GGIO1_AnIn1_q) +#define IEDMODEL_ComplexArray_GGIO1_AnIn1_t (&iedModel_ComplexArray_GGIO1_AnIn1_t) +#define IEDMODEL_ComplexArray_GGIO1_AnIn2 (&iedModel_ComplexArray_GGIO1_AnIn2) +#define IEDMODEL_ComplexArray_GGIO1_AnIn2_mag (&iedModel_ComplexArray_GGIO1_AnIn2_mag) +#define IEDMODEL_ComplexArray_GGIO1_AnIn2_mag_f (&iedModel_ComplexArray_GGIO1_AnIn2_mag_f) +#define IEDMODEL_ComplexArray_GGIO1_AnIn2_q (&iedModel_ComplexArray_GGIO1_AnIn2_q) +#define IEDMODEL_ComplexArray_GGIO1_AnIn2_t (&iedModel_ComplexArray_GGIO1_AnIn2_t) +#define IEDMODEL_ComplexArray_GGIO1_AnIn3 (&iedModel_ComplexArray_GGIO1_AnIn3) +#define IEDMODEL_ComplexArray_GGIO1_AnIn3_mag (&iedModel_ComplexArray_GGIO1_AnIn3_mag) +#define IEDMODEL_ComplexArray_GGIO1_AnIn3_mag_f (&iedModel_ComplexArray_GGIO1_AnIn3_mag_f) +#define IEDMODEL_ComplexArray_GGIO1_AnIn3_q (&iedModel_ComplexArray_GGIO1_AnIn3_q) +#define IEDMODEL_ComplexArray_GGIO1_AnIn3_t (&iedModel_ComplexArray_GGIO1_AnIn3_t) +#define IEDMODEL_ComplexArray_GGIO1_AnIn4 (&iedModel_ComplexArray_GGIO1_AnIn4) +#define IEDMODEL_ComplexArray_GGIO1_AnIn4_mag (&iedModel_ComplexArray_GGIO1_AnIn4_mag) +#define IEDMODEL_ComplexArray_GGIO1_AnIn4_mag_f (&iedModel_ComplexArray_GGIO1_AnIn4_mag_f) +#define IEDMODEL_ComplexArray_GGIO1_AnIn4_q (&iedModel_ComplexArray_GGIO1_AnIn4_q) +#define IEDMODEL_ComplexArray_GGIO1_AnIn4_t (&iedModel_ComplexArray_GGIO1_AnIn4_t) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1 (&iedModel_ComplexArray_GGIO1_SPCSO1) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_origin (&iedModel_ComplexArray_GGIO1_SPCSO1_origin) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_origin_orCat (&iedModel_ComplexArray_GGIO1_SPCSO1_origin_orCat) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_origin_orIdent (&iedModel_ComplexArray_GGIO1_SPCSO1_origin_orIdent) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_ctlNum (&iedModel_ComplexArray_GGIO1_SPCSO1_ctlNum) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_stVal (&iedModel_ComplexArray_GGIO1_SPCSO1_stVal) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_q (&iedModel_ComplexArray_GGIO1_SPCSO1_q) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_t (&iedModel_ComplexArray_GGIO1_SPCSO1_t) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_ctlModel (&iedModel_ComplexArray_GGIO1_SPCSO1_ctlModel) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_Oper (&iedModel_ComplexArray_GGIO1_SPCSO1_Oper) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_Oper_ctlVal (&iedModel_ComplexArray_GGIO1_SPCSO1_Oper_ctlVal) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_Oper_origin (&iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_Oper_origin_orCat (&iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin_orCat) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_Oper_origin_orIdent (&iedModel_ComplexArray_GGIO1_SPCSO1_Oper_origin_orIdent) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_Oper_ctlNum (&iedModel_ComplexArray_GGIO1_SPCSO1_Oper_ctlNum) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_Oper_T (&iedModel_ComplexArray_GGIO1_SPCSO1_Oper_T) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_Oper_Test (&iedModel_ComplexArray_GGIO1_SPCSO1_Oper_Test) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO1_Oper_Check (&iedModel_ComplexArray_GGIO1_SPCSO1_Oper_Check) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2 (&iedModel_ComplexArray_GGIO1_SPCSO2) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_stVal (&iedModel_ComplexArray_GGIO1_SPCSO2_stVal) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_q (&iedModel_ComplexArray_GGIO1_SPCSO2_q) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_Oper (&iedModel_ComplexArray_GGIO1_SPCSO2_Oper) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_Oper_ctlVal (&iedModel_ComplexArray_GGIO1_SPCSO2_Oper_ctlVal) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_Oper_origin (&iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_Oper_origin_orCat (&iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin_orCat) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_Oper_origin_orIdent (&iedModel_ComplexArray_GGIO1_SPCSO2_Oper_origin_orIdent) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_Oper_ctlNum (&iedModel_ComplexArray_GGIO1_SPCSO2_Oper_ctlNum) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_Oper_T (&iedModel_ComplexArray_GGIO1_SPCSO2_Oper_T) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_Oper_Test (&iedModel_ComplexArray_GGIO1_SPCSO2_Oper_Test) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_Oper_Check (&iedModel_ComplexArray_GGIO1_SPCSO2_Oper_Check) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_ctlModel (&iedModel_ComplexArray_GGIO1_SPCSO2_ctlModel) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO2_t (&iedModel_ComplexArray_GGIO1_SPCSO2_t) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3 (&iedModel_ComplexArray_GGIO1_SPCSO3) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_stVal (&iedModel_ComplexArray_GGIO1_SPCSO3_stVal) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_q (&iedModel_ComplexArray_GGIO1_SPCSO3_q) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_Oper (&iedModel_ComplexArray_GGIO1_SPCSO3_Oper) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_Oper_ctlVal (&iedModel_ComplexArray_GGIO1_SPCSO3_Oper_ctlVal) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_Oper_origin (&iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_Oper_origin_orCat (&iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin_orCat) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_Oper_origin_orIdent (&iedModel_ComplexArray_GGIO1_SPCSO3_Oper_origin_orIdent) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_Oper_ctlNum (&iedModel_ComplexArray_GGIO1_SPCSO3_Oper_ctlNum) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_Oper_T (&iedModel_ComplexArray_GGIO1_SPCSO3_Oper_T) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_Oper_Test (&iedModel_ComplexArray_GGIO1_SPCSO3_Oper_Test) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_Oper_Check (&iedModel_ComplexArray_GGIO1_SPCSO3_Oper_Check) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_ctlModel (&iedModel_ComplexArray_GGIO1_SPCSO3_ctlModel) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO3_t (&iedModel_ComplexArray_GGIO1_SPCSO3_t) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4 (&iedModel_ComplexArray_GGIO1_SPCSO4) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_stVal (&iedModel_ComplexArray_GGIO1_SPCSO4_stVal) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_q (&iedModel_ComplexArray_GGIO1_SPCSO4_q) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_Oper (&iedModel_ComplexArray_GGIO1_SPCSO4_Oper) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_Oper_ctlVal (&iedModel_ComplexArray_GGIO1_SPCSO4_Oper_ctlVal) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_Oper_origin (&iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_Oper_origin_orCat (&iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin_orCat) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_Oper_origin_orIdent (&iedModel_ComplexArray_GGIO1_SPCSO4_Oper_origin_orIdent) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_Oper_ctlNum (&iedModel_ComplexArray_GGIO1_SPCSO4_Oper_ctlNum) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_Oper_T (&iedModel_ComplexArray_GGIO1_SPCSO4_Oper_T) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_Oper_Test (&iedModel_ComplexArray_GGIO1_SPCSO4_Oper_Test) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_Oper_Check (&iedModel_ComplexArray_GGIO1_SPCSO4_Oper_Check) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_ctlModel (&iedModel_ComplexArray_GGIO1_SPCSO4_ctlModel) +#define IEDMODEL_ComplexArray_GGIO1_SPCSO4_t (&iedModel_ComplexArray_GGIO1_SPCSO4_t) +#define IEDMODEL_ComplexArray_GGIO1_Ind1 (&iedModel_ComplexArray_GGIO1_Ind1) +#define IEDMODEL_ComplexArray_GGIO1_Ind1_stVal (&iedModel_ComplexArray_GGIO1_Ind1_stVal) +#define IEDMODEL_ComplexArray_GGIO1_Ind1_q (&iedModel_ComplexArray_GGIO1_Ind1_q) +#define IEDMODEL_ComplexArray_GGIO1_Ind1_t (&iedModel_ComplexArray_GGIO1_Ind1_t) +#define IEDMODEL_ComplexArray_GGIO1_Ind2 (&iedModel_ComplexArray_GGIO1_Ind2) +#define IEDMODEL_ComplexArray_GGIO1_Ind2_stVal (&iedModel_ComplexArray_GGIO1_Ind2_stVal) +#define IEDMODEL_ComplexArray_GGIO1_Ind2_q (&iedModel_ComplexArray_GGIO1_Ind2_q) +#define IEDMODEL_ComplexArray_GGIO1_Ind2_t (&iedModel_ComplexArray_GGIO1_Ind2_t) +#define IEDMODEL_ComplexArray_GGIO1_Ind3 (&iedModel_ComplexArray_GGIO1_Ind3) +#define IEDMODEL_ComplexArray_GGIO1_Ind3_stVal (&iedModel_ComplexArray_GGIO1_Ind3_stVal) +#define IEDMODEL_ComplexArray_GGIO1_Ind3_q (&iedModel_ComplexArray_GGIO1_Ind3_q) +#define IEDMODEL_ComplexArray_GGIO1_Ind3_t (&iedModel_ComplexArray_GGIO1_Ind3_t) +#define IEDMODEL_ComplexArray_GGIO1_Ind4 (&iedModel_ComplexArray_GGIO1_Ind4) +#define IEDMODEL_ComplexArray_GGIO1_Ind4_stVal (&iedModel_ComplexArray_GGIO1_Ind4_stVal) +#define IEDMODEL_ComplexArray_GGIO1_Ind4_q (&iedModel_ComplexArray_GGIO1_Ind4_q) +#define IEDMODEL_ComplexArray_GGIO1_Ind4_t (&iedModel_ComplexArray_GGIO1_Ind4_t) +#define IEDMODEL_ComplexArray_MHAI1 (&iedModel_ComplexArray_MHAI1) +#define IEDMODEL_ComplexArray_MHAI1_HA (&iedModel_ComplexArray_MHAI1_HA) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar (&iedModel_ComplexArray_MHAI1_HA_phsAHar) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_0_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_0_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_0_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_0_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_0_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_0_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_1_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_1_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_1_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_1_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_1_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_1_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_2_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_2_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_2_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_2_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_2_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_2_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_3_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_3_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_3_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_3_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_3_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_3_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_4_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_4_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_4_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_4_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_4_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_4_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_5_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_5_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_5_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_5_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_5_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_5_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_6_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_6_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_6_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_6_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_6_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_6_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_7_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_7_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_7_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_7_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_7_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_7_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_8_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_8_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_8_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_8_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_8_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_8_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_9_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_9_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_9_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_9_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_9_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_9_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_10_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_10_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_10_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_10_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_10_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_10_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_11_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_11_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_11_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_11_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_11_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_11_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_12_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_12_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_12_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_12_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_12_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_12_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_13_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_13_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_13_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_13_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_13_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_13_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_14_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_14_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_14_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_14_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_14_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_14_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_15_cVal (&iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag (&iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_mag_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang (&iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang_f (&iedModel_ComplexArray_MHAI1_HA_phsAHar_15_cVal_ang_f) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_15_q (&iedModel_ComplexArray_MHAI1_HA_phsAHar_15_q) +#define IEDMODEL_ComplexArray_MHAI1_HA_phsAHar_15_t (&iedModel_ComplexArray_MHAI1_HA_phsAHar_15_t) +#define IEDMODEL_ComplexArray_MHAI1_HA_numHar (&iedModel_ComplexArray_MHAI1_HA_numHar) +#define IEDMODEL_ComplexArray_MHAI1_HA_numCyc (&iedModel_ComplexArray_MHAI1_HA_numCyc) +#define IEDMODEL_ComplexArray_MHAI1_HA_evalTm (&iedModel_ComplexArray_MHAI1_HA_evalTm) +#define IEDMODEL_ComplexArray_MHAI1_HA_frequency (&iedModel_ComplexArray_MHAI1_HA_frequency) + +#endif /* STATIC_MODEL_H_ */ + diff --git a/release_script.sh b/release_script.sh new file mode 100644 index 00000000..9e0794c5 --- /dev/null +++ b/release_script.sh @@ -0,0 +1,103 @@ +#!/bin/bash + +###### Function to replace tabs with spaces in all .cs files################ +format_cs_files() { + echo "Formatting .cs files: Replacing tabs with spaces..." + find . -type f -name "*.cs" -exec sed -i 's/\t/ /g' {} + + echo "Formatting completed!" +} + +###### Function to replace tabs with spaces in all .cs files################ +format_c_files() { + echo "Formatting .c files: Replacing tabs with spaces..." + find . -type f -name "*.c" -exec sed -i 's/\t/ /g' {} + + echo "Formatting completed!" +} + +#########Clean directory######################### +clean_build_directories() +{ + echo "Removing .vs/, bin/, obj/ folders, any .git directories or files, and doxydoc.NET folder..." + find "$FOLDER_NAME" -type d \( -name "vs" -o -name "bin" -o -name "obj" -o -name "doxydoc.NET" -o -name ".git" \) -exec rm -rf {} + + find "$FOLDER_NAME" -type f -name ".git" -exec rm -f {} + + echo "Cleanup completed!" +} + +##########Create release folder##################### +create_release_folder() +{ + # Print the value + echo "Creating folder: $FOLDER_NAME" + + # Create the folder + mkdir -p "$FOLDER_NAME" + + echo "Folder '$FOLDER_NAME' created successfully!" + + cp -rf config $FOLDER_NAME + cp -rf demos $FOLDER_NAME + cp -rf dotnet $FOLDER_NAME + cp -rf examples $FOLDER_NAME + cp -rf fuzz $FOLDER_NAME + cp -rf hal $FOLDER_NAME + cp -rf pyiec61850 $FOLDER_NAME + cp -rf src $FOLDER_NAME + cp -rf tools $FOLDER_NAME + cp -rf CHANGELOG $FOLDER_NAME + cp -rf CMakeLists.txt $FOLDER_NAME + cp -rf Makefile $FOLDER_NAME + cp -rf COPYING $FOLDER_NAME + cp -rf mingw-w64-x86_64.cmake $FOLDER_NAME + cp -rf README.md $FOLDER_NAME + cp -rf SECURITY.md $FOLDER_NAME + +} + +################ Function to create a tar.gz archive############################ +compress_to_tar() { + ARCHIVE_NAME="$FOLDER_NAME.tar.gz" + echo "Creating archive: $ARCHIVE_NAME" + tar -czf "$ARCHIVE_NAME" -C "$(dirname "$FOLDER_NAME")" "$(basename "$FOLDER_NAME")" + echo "Archive '$ARCHIVE_NAME' created successfully!" +} + +# Wait for user input if arguments are missing +while [ -z "$1" ]; do + read -p "Enter version: " VERSION_NAME_INPUT + set -- "$VERSION_NAME_INPUT" "$2" +done + +while [ -z "$2" ]; do + read -p "Enter option ([1]release/[2]formatFiles/[3]all): " OPTION_INPUT + set -- "$1" "$OPTION_INPUT" +done + +# Store arguments +PREFIX="../libiec61850-" +FOLDER_NAME="${PREFIX}${1}" +OPTION="$2" + +# Execute option case +case "$OPTION" in + 1) + create_release_folder + ;; +2) + format_cs_files + format_c_files + ;; + 3) + format_cs_files + format_c_files + create_release_folder + clean_build_directories + compress_to_tar + ;; + *) + echo "Invalid option. Use 'prepare', 'release', or 'delete'." + exit 1 + ;; +esac + + +##################################################### diff --git a/tools/model_generator_dotnet/DynamicModelGenerator/DynamicModel.cs b/tools/model_generator_dotnet/DynamicModelGenerator/DynamicModel.cs new file mode 100644 index 00000000..a7bfe7e0 --- /dev/null +++ b/tools/model_generator_dotnet/DynamicModelGenerator/DynamicModel.cs @@ -0,0 +1,59 @@ +using IEC61850.SCL; +using IEC61850.SCL.DataModel; +using System; +using System.IO; +using System.Linq; +using System.Xml; + +namespace DynamicModel +{ + public class DynamicModel + { + public DynamicModel(string fileName, FileStream stream, + string iedName, string accessPointName) + { + try + { + SclDocument sclParser = new SclDocument(fileName); + + SclIED ied = null; + + if (iedName == null) + ied = sclParser.IEDs.First(); + else + ied = sclParser.IEDs.Find(x => x.Name == iedName); + + if (ied == null) + { + throw new Exception("IED model not found in SCL file! Exit."); + } + + SclAccessPoint accessPoint = null; + + if (accessPointName == null) + accessPoint = ied.AccessPoints.First(); + else + accessPoint = ied.AccessPoints.Find(x => x.Name == accessPointName); + + if (accessPoint == null) + { + throw new Exception("AccessPoint not found in SCL file! Exit."); + } + + IEDDataModel iedModel = sclParser.GetDataModel(ied.Name, accessPoint.Name); + + + using (StreamWriter writer = new StreamWriter(stream)) + { + + DynamicModelGenerator dynamicModelGenerator = new DynamicModelGenerator(sclParser, writer, iedModel, accessPoint); + } + } + catch (Exception ex) + { + Console.Write(ex.ToString()); + } + + } + } +} diff --git a/tools/model_generator_dotnet/DynamicModelGenerator/DynamicModelGenerator.csproj b/tools/model_generator_dotnet/DynamicModelGenerator/DynamicModelGenerator.csproj new file mode 100644 index 00000000..4e4c8ce8 --- /dev/null +++ b/tools/model_generator_dotnet/DynamicModelGenerator/DynamicModelGenerator.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.0 + + + + + + + diff --git a/tools/model_generator_dotnet/README.md b/tools/model_generator_dotnet/README.md new file mode 100644 index 00000000..878d5ae9 --- /dev/null +++ b/tools/model_generator_dotnet/README.md @@ -0,0 +1,11 @@ +This tool can be accessed from both the command line of visual studio. +To run the tool from the command line a command of the following format has to be generated: + + -ied -ap -out -modelprefix + +The values in <> have to be replaced with the values corresponding to an arbitrary ICD file. +To run this command completely the command should look like this: + +Example: + +dotnet Tools.dll 1 ICDFiles/genericIO.icd -ied simpleIO -ap accessPoint1 -out static_model -modelprefix iedModel \ No newline at end of file diff --git a/tools/model_generator_dotnet/SCLParser/SCLParser.csproj b/tools/model_generator_dotnet/SCLParser/SCLParser.csproj new file mode 100644 index 00000000..dbdcea46 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/SCLParser.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/tools/model_generator_dotnet/SCLParser/src/CommonDataClasses.cs b/tools/model_generator_dotnet/SCLParser/src/CommonDataClasses.cs new file mode 100644 index 00000000..28e8016b --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/CommonDataClasses.cs @@ -0,0 +1,161 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System.Collections.Generic; + +namespace IEC61850.SCL +{ + public enum CDCAttributeTrgOp + { + NONE, + DCHG, + QCHG, + DUPD + } + + public enum CDCAttributeOptionality + { + M, + O, + PICS_SUBST, + AC_DLNDA_M, + AC_DLN_M + } + + public class CDCAttribute + { + private string name; + private AttributeType bType; + private string type = null; + private SclFC fc; + CDCAttributeTrgOp trgOp; + CDCAttributeOptionality optionality; + + public string Name + { + get + { + return name; + } + } + + public AttributeType BType + { + get + { + return bType; + } + } + + public string Type + { + get + { + return type; + } + } + + public SclFC Fc + { + get + { + return fc; + } + } + + public CDCAttributeTrgOp TrgOp + { + get + { + return trgOp; + } + } + + public CDCAttribute(string name, AttributeType bType, string type, SclFC fc, CDCAttributeTrgOp trgOp, CDCAttributeOptionality optionality) + { + this.name = name; + this.bType = bType; + this.type = type; + this.fc = fc; + this.trgOp = trgOp; + this.optionality = optionality; + } + + } + + public class CommonDataClass + { + private string name; + + public string Name + { + get + { + return name; + } + } + + public List Attributes + { + get + { + return attributes; + } + } + + List attributes = new List(); + + public CommonDataClass(string name, CDCAttribute[] attributes) + { + this.name = name; + + foreach (CDCAttribute cdcAttribute in attributes) + this.attributes.Add(cdcAttribute); + } + } + + public class StandardCommonDataClasses + { + private List cdcs = new List(); + + public StandardCommonDataClasses() + { + cdcs.Add(new CommonDataClass("SPS", new CDCAttribute[] { + new CDCAttribute("stVal", AttributeType.BOOLEAN, null, SclFC.ST, CDCAttributeTrgOp.DCHG, CDCAttributeOptionality.M), + new CDCAttribute("q", AttributeType.QUALITY, null, SclFC.ST, CDCAttributeTrgOp.QCHG, CDCAttributeOptionality.M), + new CDCAttribute("t", AttributeType.TIMESTAMP, null, SclFC.ST, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.M), + + new CDCAttribute("subEna", AttributeType.BOOLEAN, null, SclFC.SV, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.PICS_SUBST), + new CDCAttribute("subVal", AttributeType.BOOLEAN, null, SclFC.SV, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.PICS_SUBST), + new CDCAttribute("subQ", AttributeType.QUALITY, null, SclFC.SV, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.PICS_SUBST), + new CDCAttribute("subID", AttributeType.VISIBLE_STRING_64, null, SclFC.SV, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.PICS_SUBST), + new CDCAttribute("blkEna", AttributeType.BOOLEAN, null, SclFC.BL, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.O), + + new CDCAttribute("d", AttributeType.VISIBLE_STRING_255, null, SclFC.DC, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.O), + new CDCAttribute("dU", AttributeType.UNICODE_STRING_255, null, SclFC.DC, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.O), + + new CDCAttribute("cdcNs", AttributeType.VISIBLE_STRING_255, null, SclFC.EX, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.AC_DLNDA_M), + new CDCAttribute("cdcName", AttributeType.VISIBLE_STRING_255, null, SclFC.EX, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.AC_DLNDA_M), + new CDCAttribute("dataNs", AttributeType.VISIBLE_STRING_255, null, SclFC.EX, CDCAttributeTrgOp.NONE, CDCAttributeOptionality.AC_DLN_M) + })); + } + + + public CommonDataClass GetByName(string cdcName) + { + foreach (CommonDataClass cdc in cdcs) + { + if (cdc.Name.Equals(cdcName)) + return cdc; + } + + return null; + } + } +} + diff --git a/tools/model_generator_dotnet/SCLParser/src/DataModel.cs b/tools/model_generator_dotnet/SCLParser/src/DataModel.cs new file mode 100644 index 00000000..d70f3121 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/DataModel.cs @@ -0,0 +1,852 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System.Collections.Generic; + + +namespace IEC61850 +{ + namespace SCL + { + + namespace DataModel + { + + public class IEDModelNode + { + protected string name; + + protected string objRef; + + private IEDModelNode parent; + + public IEDModelNode Parent + { + get + { + return parent; + } + } + + public string ObjRef + { + get + { + return objRef; + } + } + + public string Name + { + get + { + return name; + } + set + { + name = value; + //change objRef; + int index = objRef.LastIndexOf("."); + if (index >= 0) + objRef = objRef.Substring(0, index + 1) + value; + + + } + } + + public string IedName + { + get + { + if (this is IEDDataModel) + return Name; + else + return parent.IedName; + } + } + + public IEDModelNode(string name, IEDModelNode parent) + { + this.name = name; + this.parent = parent; + } + } + + public class IEDDataModel : IEDModelNode + { + private List logicalDevices = new List(); + + public List LogicalDevices + { + get + { + return logicalDevices; + } + } + + public IEDDataModel(string name) : base(name, null) + { + } + + private IEDModelNode GetChildNode(IEDModelNode node, string objRefPart) + { + string[] tokens = objRefPart.Split(new char[] { '.' }, 2); + + if (tokens.Length > 0) + { + if (node is LogicalDevice) + { + LogicalDevice ld = node as LogicalDevice; + + foreach (LogicalNode ln in ld.LogicalNodes) + { + if (ln.Name.Equals(tokens[0])) + { + if (tokens.Length == 1) + return ln; + else + { + return GetChildNode(ln, tokens[1]); + } + } + } + } + else if (node is LogicalNode) + { + LogicalNode ln = node as LogicalNode; + + foreach (DataObject dobj in ln.DataObjects) + { + if (dobj.Name.Equals(tokens[0])) + { + if (tokens.Length == 1) + return dobj; + else + { + return GetChildNode(dobj, tokens[1]); + } + } + } + + } + else if (node is DataObject) + { + DataObject dobj = node as DataObject; + + foreach (DataObjectOrAttribute doa in dobj.DataObjectsAndAttributes) + { + if (doa.Name.Equals(tokens[0])) + { + if (tokens.Length == 1) + return doa; + else + { + return GetChildNode(doa, tokens[1]); + } + } + } + } + else if (node is DataAttribute) + { + DataAttribute da = node as DataAttribute; + + foreach (DataAttribute sda in da.SubDataAttributes) + { + if (sda.Name.Equals(tokens[0])) + { + if (tokens.Length == 1) + return sda; + else + { + return GetChildNode(sda, tokens[1]); + } + } + } + } + + return null; + } + else + return null; + } + + /// + /// Get the model node with the provided object reference + /// + /// object reference in the format LD/LN.DO[.SDO].DA[.SDA] + /// + public IEDModelNode GetModelNode(string objRef) + { + string[] tokens = objRef.Split(new char[] { '/' }, 2); + + if (tokens.Length > 0) + { + foreach (LogicalDevice ld in logicalDevices) + { + if (ld.ObjRef.Equals(tokens[0])) + { + if (tokens.Length == 1) + return ld; + else + { + return GetChildNode(ld, tokens[1]); + } + } + } + + return null; + } + else + return null; + + } + } + + public class LogicalDevice : IEDModelNode + { + private SclDocument SclDocument = null; + private List logicalNodes = new List(); + + private SclLDevice sclLDevice; + private Namespace nameSpace = null; + + private string inst; + + + public void UpdateName() + { + string name = ""; + + if (IedName != null) + name += IedName; + + if (inst != null) + name += inst; + + this.name = name; + objRef = name; + } + + public SclLDevice SclLDevice + { + get => sclLDevice; set => sclLDevice = value; + + } + + public string Inst + { + get + { + return inst; + } + set + { + inst = value; + UpdateName(); + } + } + + public List LogicalNodes + { + get + { + return logicalNodes; + } + } + + public Namespace NameSpace { get => nameSpace; set => nameSpace = value; } + + public LogicalNode AddLogicalNode(SclLN ln) + { + LogicalNode logicalNode = new LogicalNode(ln, this); + + SclDocument.AddDataObjectsToLogicalNode(logicalNode, ln); + + LogicalNodes.Add(logicalNode); + + return logicalNode; + } + + public LogicalDevice(SclDocument sclDocument, SclLDevice sclLDevice, string name, string inst, IEDModelNode parent) : base(name, parent) + { + SclDocument = sclDocument; + this.name = name; + this.inst = inst; + objRef = this.name; + this.sclLDevice = sclLDevice; + } + } + + public class LogicalNode : IEDModelNode + { + private string prefix; + private string lnClass; + private string inst; + private Namespace nameSpace = null; + + private SclLN sclElement = null; + + private List dataSets = null; + private List logs = null; + private List reportControls = null; + private List gseControls = null; + private List sMVControls = null; + private List logControls = null; + private List dataObjects = new List(); + private Inputs inputs = null; + private SclSettingControl settingControl = null; + + public SclLN SclElement { get => sclElement; set => sclElement = value; } + + public void UpdateName() + { + string name = ""; + + if (prefix != null) + name += prefix; + + name += lnClass; + + if (inst != null) + name += inst; + + this.name = name; + } + + public string Prefix + { + get + { + return prefix; + } + set + { + prefix = value; + } + } + + public string LnClass + { + get + { + return lnClass; + } + set + { + lnClass = value; + } + } + + public string Inst + { + get + { + return inst; + } + set + { + inst = value; + } + } + + public List DataSets + { + get + { + if (dataSets == null) + { + dataSets = new List(); + + if (sclElement != null) + { + foreach (SclDataSet sclDataSet in sclElement.DataSets) + { + dataSets.Add(new DataSet(sclDataSet, this)); + } + } + } + + return dataSets; + } + } + + public List Logs + { + get + { + if (logs == null) + { + logs = new List(); + + if (sclElement != null) + { + foreach (SclLog sclLog in sclElement.Logs) + { + logs.Add(new Log(sclLog, this)); + } + } + } + + return logs; + } + } + + public List ReportControlBlocks + { + get + { + if (reportControls == null) + { + reportControls = new List(); + + if (sclElement != null) + { + foreach (SclReportControl sclReportControl in sclElement.ReportControls) + { + reportControls.Add(new ReportControl(sclReportControl, this)); + } + } + } + + return reportControls; + } + } + + public List GSEControls + { + get + { + if (gseControls == null) + { + gseControls = new List(); + + if (sclElement != null) + { + foreach (SclGSEControl sclGSEControl in sclElement.GSEControls) + { + gseControls.Add(new GSEControl(sclGSEControl, this)); + } + } + } + + return gseControls; + } + } + + public List SMVControls + { + get + { + if (sMVControls == null) + { + sMVControls = new List(); + + if (sclElement != null) + { + foreach (SclSMVControl sclSMVControl in sclElement.SclSMVControls) + { + sMVControls.Add(new SMVControl(sclSMVControl, this)); + } + } + } + + return sMVControls; + } + } + + public List LogControls + { + get + { + if (logControls == null) + { + logControls = new List(); + + if (sclElement != null) + { + foreach (SclLogControl sclLogControl in sclElement.LogControls) + { + logControls.Add(new LogControl(sclLogControl, this)); + } + } + } + + return logControls; + } + } + + public Inputs Inputs + { + get + { + if (inputs == null) + { + if (sclElement != null) + { + if (sclElement.Inputs != null) + { + inputs = sclElement.Inputs; + inputs.Parent = this; + + foreach (SclExtRef extRef in inputs.ExtRefs) + extRef.Parent = inputs; + } + } + } + + return inputs; + } + set + { + inputs = value; + if (inputs != null) + inputs.Parent = this; + } + } + + public SclSettingControl SettingControl + { + get + { + if (settingControl == null) + { + if (sclElement != null) + { + if (sclElement.SettingControl != null) + { + settingControl = sclElement.SettingControl; + settingControl.Parent = this; + } + } + } + + return settingControl; + } + set + { + settingControl = value; + if (settingControl != null) + settingControl.Parent = this; + } + } + + public List DataObjects + { + get + { + return dataObjects; + } + + } + + public Namespace NameSpace { get => nameSpace; set => nameSpace = value; } + + public LogicalNode(string prefix, string lnClass, string inst, IEDModelNode parent) : base(null, parent) + { + this.prefix = prefix; + this.lnClass = lnClass; + this.inst = inst; + UpdateName(); + objRef = parent.Name + "/" + name; + } + + public LogicalNode(SclLN ln, IEDModelNode parent) : base(null, parent) + { + prefix = ln.Prefix; + lnClass = ln.LnClass; + inst = ln.Inst; + //this.name = ln.InstanceName; + //if (ln.InstanceName == null) + UpdateName(); + objRef = parent.Name + "/" + name; + sclElement = ln; + } + } + + public class DataObjectOrAttribute : IEDModelNode + { + public DataObjectOrAttribute(string name, IEDModelNode parent) : base(name, parent) + { + } + } + + public class DataObject : DataObjectOrAttribute + { + private List dataObjectsAndAttributes = new List(); + + private int count = 0; + private SclDOType doType; + private bool trans = false; + + public bool IsTransiente + { + get + { + return trans; + } + } + + public SclDOType DOType + { + get + { + return doType; + } + + } + + public int Count + { + get + { + return count; + } + } + + public List DataObjectsAndAttributes + { + get + { + return dataObjectsAndAttributes; + } + } + + public DataObject(SclDataObjectDefinition dod, SclDOType doType, IEDModelNode parent) : base(dod.Name, parent) + { + count = dod.Count; + this.doType = doType; + objRef = parent.ObjRef + "." + name; + + trans = dod.IsTransient; + } + + private bool HasChildWithFc(DataObject dobj, SclFC fc) + { + foreach (DataObjectOrAttribute doa in dobj.DataObjectsAndAttributes) + { + if (doa is DataAttribute) + { + DataAttribute da = doa as DataAttribute; + + if (da.Fc == fc) + return true; + } + else if (doa is DataObject) + { + DataObject sdo = doa as DataObject; + + if (HasChildWithFc(sdo, fc)) + return true; + } + } + + return false; + } + + public bool HasChildWithFc(SclFC fc) + { + return HasChildWithFc(this, fc); + } + + + } + + public class DataAttribute : DataObjectOrAttribute + { + public List subDataAttributes = new List(); + + private AttributeType attributeType; + private SclFC fc; + private int count = 0; + private SclDataAttributeDefinition definition = null; + + public List SubDataAttributes + { + get + { + return subDataAttributes; + } + } + + public SclDataAttributeDefinition Definition + { + get + { + return definition; + } + } + + public AttributeType AttributeType + { + get + { + return attributeType; + } + } + + public SclFC Fc + { + get + { + return fc; + } + } + + public int Count + { + get + { + return count; + } + } + + public DataAttribute(string name, IEDModelNode parent, SclFC fc, AttributeType bType, int count) : base(name, parent) + { + this.fc = fc; + attributeType = bType; + this.count = count; + + if (attributeType == AttributeType.CONSTRUCTED) + subDataAttributes = new List(); + + objRef = parent.ObjRef + "." + name; + } + + public DataAttribute(string name, IEDModelNode parent, SclFC fc, AttributeType bType, int count, SclDataAttributeDefinition def) : base(name, parent) + { + this.fc = fc; + attributeType = bType; + this.count = count; + definition = def; + + if (attributeType == AttributeType.CONSTRUCTED) + subDataAttributes = new List(); + + if (objRef == null) + objRef = parent.ObjRef + "." + name; + } + } + + public class DataSet : IEDModelNode + { + private SclDataSet sclDataSet; + + public DataSet(string name, IEDModelNode parent) : base(name, parent) + { + objRef = parent.ObjRef + "." + name; + } + + public DataSet(SclDataSet sclDataSet, IEDModelNode parent) : base(sclDataSet.Name, parent) + { + this.sclDataSet = sclDataSet; + objRef = parent.ObjRef + "." + name; + } + + public SclDataSet SclDataSet { get => sclDataSet; set => sclDataSet = value; } + } + + public class Log : IEDModelNode + { + private SclLog sclLog; + + public Log(string name, IEDModelNode parent) : base(name, parent) + { + objRef = parent.ObjRef + "." + name; + } + + public Log(SclLog sclLog, IEDModelNode parent) : base(sclLog.Name, parent) + { + this.sclLog = sclLog; + objRef = parent.ObjRef + "." + name; + } + + public SclLog SclLog { get => sclLog; set => sclLog = value; } + } + + + public class ReportControl : IEDModelNode + { + private SclReportControl sclReportControl; + private bool buffered = false; + + public SclReportControl SclReportControl { get => sclReportControl; set => sclReportControl = value; } + public bool Buffered { get => buffered; set => buffered = value; } + + public ReportControl(string name, bool buffered, IEDModelNode parent) : base(name, parent) + { + objRef = parent.ObjRef + "." + name; + this.buffered = buffered; + } + + + public ReportControl(SclReportControl sclReportControl, IEDModelNode parent) : base(sclReportControl.Name, parent) + { + this.sclReportControl = sclReportControl; + + buffered = sclReportControl.Buffered; + + objRef = parent.ObjRef + "." + name; + } + } + + public class GSEControl : IEDModelNode + { + private SclGSEControl sclGSEControl; + + public GSEControl(string name, IEDModelNode parent) : base(name, parent) + { + objRef = parent.ObjRef + "." + name; + } + + public GSEControl(SclGSEControl sclGSEControl, IEDModelNode parent) : base(sclGSEControl.Name, parent) + { + objRef = parent.ObjRef + "." + name; + this.sclGSEControl = sclGSEControl; + } + + public SclGSEControl SclGSEControl { get => sclGSEControl; set => sclGSEControl = value; } + } + + public class SMVControl : IEDModelNode + { + private SclSMVControl sclSMVControl; + + public SMVControl(string name, IEDModelNode parent) : base(name, parent) + { + objRef = parent.ObjRef + "." + name; + } + + public SMVControl(SclSMVControl sclSMVControl, IEDModelNode parent) : base(sclSMVControl.Name, parent) + { + objRef = parent.ObjRef + "." + name; + this.sclSMVControl = sclSMVControl; + } + + public SclSMVControl SclSMVControl { get => sclSMVControl; set => sclSMVControl = value; } + } + + public class LogControl : IEDModelNode + { + private SclLogControl sclLogControl; + + public LogControl(string name, IEDModelNode parent) : base(name, parent) + { + objRef = parent.ObjRef + "." + name; + } + + public LogControl(SclLogControl sclLogControl, IEDModelNode parent) : base(sclLogControl.Name, parent) + { + objRef = parent.ObjRef + "." + name; + this.sclLogControl = sclLogControl; + } + + public SclLogControl SclLogControl { get => sclLogControl; set => sclLogControl = value; } + } + } + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/DynamicModelGenerator.cs b/tools/model_generator_dotnet/SCLParser/src/DynamicModelGenerator.cs new file mode 100644 index 00000000..388a78ee --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/DynamicModelGenerator.cs @@ -0,0 +1,1223 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using IEC61850.SCL.DataModel; +using System; +using System.IO; +using System.Runtime.InteropServices.ComTypes; +using System.Xml.Linq; + +namespace IEC61850.SCL +{ + public class DynamicModelGenerator + { + private SclConnectedAP connectedAP = null; + private SclIED ied = null; + private bool hasOwner = false; + private IEDDataModel iED = null; + private SclDocument sclDocument; + + public DynamicModelGenerator(SclDocument sclDocument, StreamWriter output, IEDDataModel iED, SclAccessPoint accessPoint) + { + this.sclDocument = sclDocument; + this.iED = iED; + + connectedAP = sclDocument.GetConnectedAP(accessPoint.Name, iED.Name); + + output.WriteLine("MODEL(" + iED.Name + "){"); + foreach (LogicalDevice ld in iED.LogicalDevices) + { + output.Write("LD(" + ld.Inst + "){\n"); + + ExportLogicalNodes(output, ld); + + output.WriteLine("}"); + } + output.WriteLine("}"); + } + + private void ExportLogicalNodes(StreamWriter output, LogicalDevice logicalDevice) + { + foreach (LogicalNode logicalNode in logicalDevice.LogicalNodes) + { + output.Write("LN(" + logicalNode.Name + "){\n"); + + ExportLogicalNode(output, logicalNode, logicalDevice); + + output.WriteLine("}"); + } + } + + private void ExportLogicalNode(StreamWriter output, LogicalNode logicalNode, LogicalDevice logicalDevice) + { + if (logicalNode.SettingControl != null) + output.Write("SG(" + logicalNode.SettingControl.ActSG + " " + logicalNode.SettingControl.NumOfSGs + ")\n"); + + + foreach (DataObject dataObject in logicalNode.DataObjects) + { + output.Write("DO(" + dataObject.Name + " " + dataObject.Count + "){\n"); + + ExportDataObject(output, dataObject, false); + + output.WriteLine("}"); + } + + foreach (DataSet dataSet in logicalNode.DataSets) + ExportDataSet(output, dataSet, logicalNode); + + foreach (ReportControl rcb in logicalNode.ReportControlBlocks) + { + if (rcb.SclReportControl.Indexed) + { + + int maxInstances = 1; + + if (rcb.SclReportControl.RptEna != null) + maxInstances = rcb.SclReportControl.RptEna.Max; + + for (int i = 0; i < maxInstances; i++) + { + string index = (i + 1).ToString("00"); + PrintRCBInstance(output, rcb, index); + } + } + else + PrintRCBInstance(output, rcb, ""); + } + + foreach (LogControl lcb in logicalNode.LogControls) + PrintLCB(output, lcb, logicalNode, logicalDevice); + + foreach (Log log in logicalNode.Logs) + output.WriteLine("LOG(" + log.Name + ");"); + + foreach (GSEControl gcb in logicalNode.GSEControls) + { + PrintGSEControl(output, gcb); + } + + foreach (SMVControl smv in logicalNode.SMVControls) + { + PrintSMVControl(output, smv); + } + } + + private void PrintGSEControl(StreamWriter output, GSEControl gcb) + { + SclGSE gse = null; + SclAddress gseAddress = null; + + if (connectedAP != null) + { + gse = connectedAP.GSEs.Find(x => x.CbName == gcb.Name); + + if (gse != null) + gseAddress = gse.SclAddress; + } + else + Console.WriteLine("WARNING: IED \"" + ied.Name + "\" has no connected access point!"); + + output.Write("GC("); + output.Write(gcb.Name + " "); + + if (gcb.SclGSEControl.AppID != null) + output.Write(gcb.SclGSEControl.AppID + " "); + else + output.Write("null "); + + + if (gcb.SclGSEControl.DatSet != null) + output.Write(gcb.SclGSEControl.DatSet + " "); + else + output.Write("null "); + + if (gcb.SclGSEControl.ConfRev >= 0) + output.Write(gcb.SclGSEControl.ConfRev + " "); + else + output.Write("0 "); + + if (gcb.SclGSEControl.FixedOffs) + output.Write('1'); + else + output.Write('0'); + + output.Write(' '); + + if (gse != null) + { + if (gse.Mintime != null) + output.Write(gse.Mintime); + else + output.Write("0"); + + output.Write(' '); + + if (gse.Maxtime != null) + output.Write(gse.Maxtime); + else + output.Write("0"); + } + else + { + output.Write("0 0"); + } + + if (gseAddress == null) + { + output.WriteLine(");"); + } + else + { + output.WriteLine("){"); + + output.Write("PA("); + output.Write(gseAddress.VlanPriority + " "); + output.Write(gseAddress.VlanId + " "); + output.Write(gseAddress.AppId + " "); + + for (int i = 0; i < 6; i++) + { + string hexValue = gseAddress.MacAddress[i].ToString("X2"); + output.Write(hexValue); + } + + output.WriteLine(");"); + + output.WriteLine("}"); + } + } + + private void PrintSMVControl(StreamWriter output, SMVControl smv) + { + SclSMV sclsmv = null; + SclAddress smvAddress = null; + + if (connectedAP != null) + { + sclsmv = connectedAP.SMVs.Find(x => x.CbName == smv.Name); + + if (sclsmv != null) + smvAddress = sclsmv.SclAddress; + } + + output.Write("SMVC("); + output.Write(smv.Name + " "); + if (smv.SclSMVControl.SmvID != null) + output.Write(smv.SclSMVControl.SmvID + " "); + else + output.Write("null "); + + if (smv.SclSMVControl.DataSet != null) + output.Write(smv.SclSMVControl.DataSet + " "); + else + output.Write("null "); + + if (smv.SclSMVControl.ConfRev >= 0) + output.Write(smv.SclSMVControl.ConfRev + " "); + else + output.Write("0 "); + + if (smv.SclSMVControl.SmpMod != null) + output.Write(smv.SclSMVControl.SmpMod + " "); + else + output.Write("0 "); + + if(smv.SclSMVControl.SmpRate != -1) + output.Write(smv.SclSMVControl.SmpRate + " "); + else + output.Write("0 "); + //output.Write(smv.SclSMVControl.SmpRate + " "); + + if (smv.SclSMVControl.SclSmvOpts != null) + output.Write(smv.SclSMVControl.SclSmvOpts.GetIntValue()); + else + output.Write("0"); + + output.Write(' '); + + if (smv.SclSMVControl.Multicast) + output.Write('1'); + else + output.Write("0"); + output.Write(' '); + + + if (smvAddress == null) + { + output.WriteLine(");"); + } + else + { + output.WriteLine("){"); + + output.Write("PA("); + output.Write(smvAddress.VlanPriority + " "); + output.Write(smvAddress.VlanId + " "); + output.Write(smvAddress.AppId + " "); + + for (int i = 0; i < 6; i++) + { + string hexValue = smvAddress.MacAddress[i].ToString("X2"); + output.Write(hexValue); + } + + output.WriteLine(");"); + + output.WriteLine("}"); + } + } + + private void PrintLCB(StreamWriter output, LogControl lcb, LogicalNode ln, LogicalDevice logicalDevice) + { + output.Write("LC("); + output.Write(lcb.Name + " "); + + if (lcb.SclLogControl.DatSet != null && lcb.SclLogControl.DatSet != "") + output.Write(lcb.SclLogControl.DatSet + " "); + else + output.Write("- "); + + if (lcb.SclLogControl.LogName != null && lcb.SclLogControl.LogName != "") + { + String logRef = logicalDevice.Inst + "/" + ln.Name + "$" + lcb.SclLogControl.LogName; + output.Write(logRef + " "); + } + else + output.Write("- "); + + if (lcb.SclLogControl.TrgOps != null) + { + output.Write(lcb.SclLogControl.TrgOps.GetIntValue() + " "); + } + + + if(lcb.SclLogControl.IntgPd is null) + output.Write("0 "); + else + output.Write(lcb.SclLogControl.IntgPd + " "); + + + if (lcb.SclLogControl.LogEna) + output.Write("1 "); + else + output.Write("0 "); + + if (lcb.SclLogControl.ReasonCode) + output.WriteLine("1);"); + else + output.WriteLine("0);"); + } + + private void PrintRCBInstance(StreamWriter output, ReportControl rcb, string index) + { + output.Write("RC("); + output.Write(rcb.Name + index + " "); + + if (rcb.SclReportControl.RptID != null) + output.Write(rcb.SclReportControl.RptID + " "); + else + output.Write("- "); + + if (rcb.SclReportControl.Buffered) + output.Write("1 "); + else + output.Write("0 "); + + if (rcb.SclReportControl.DatSet != null) + output.Write(rcb.SclReportControl.DatSet + " "); + else + output.Write("- "); + + if (rcb.SclReportControl.IntConfRev >= 0) + output.Write(rcb.SclReportControl.IntConfRev + " "); + else + output.Write("0 "); + + int triggerOptions = 0; + + if (rcb.SclReportControl.TrgOps != null) + { + triggerOptions = rcb.SclReportControl.TrgOps.GetIntValue(); + } + + if (hasOwner) + triggerOptions += 64; + + output.Write(triggerOptions + " "); + + int OptFields = 0; + if (rcb.SclReportControl.OptFields != null) + { + OptFields = rcb.SclReportControl.OptFields.GetIntValue(); + } + output.Write(OptFields + " "); + + + if (rcb.SclReportControl.BufTime != null) + output.Write(rcb.SclReportControl.BufTime + " "); + else + output.Write("0 "); + + + if (rcb.SclReportControl.IntgPd != null) + output.Write(rcb.SclReportControl.IntgPd); + else + output.Write("0"); + + + output.WriteLine(");"); + } + + private void exportDataObjectChild(StreamWriter output, DataObject dataObject, bool isTransient) + { + + foreach (DataObjectOrAttribute child in dataObject.DataObjectsAndAttributes) + { + if (child is DataObject) + { + DataObject subDataObject = child as DataObject; + output.Write("DO(" + subDataObject.Name + " " + subDataObject.Count + "){\n"); + + ExportDataObject(output, subDataObject, isTransient); + + output.WriteLine("}"); + } + else + { + DataAttribute dataAttribute = child as DataAttribute; + ExportDataAttribute(output, dataAttribute, isTransient); + } + } + + + } + + private void ExportDataObject(StreamWriter output, DataObject dataObject, bool isTransient) + { + + if (dataObject.IsTransiente) + isTransient = true; + + if (dataObject.Count > 0) + { + /* data object is an array */ + for (int i = 0; i < dataObject.Count; i++) + { + output.WriteLine("[" + i + "]{\n"); + + exportDataObjectChild(output, dataObject, isTransient); + + output.Write("}\n"); + } + } + else + { + exportDataObjectChild(output, dataObject, isTransient); + + } + + } + + //private void printDataAttributeValue(StreamWriter output, DataAttribute dataAttribute, bool isTransient) + //{ + // if (dataAttribute.AttributeType != AttributeType.CONSTRUCTED) + // { + // SclVal value = dataAttribute.Definition.GetVal(); + + // /* if no value is given use default value for type if present */ + // if (value == null) + // { + // value = dataAttribute.Definition.GetVal(); + + // //if (value != null) + // // if (value.Value == null) + // // value.updateEnumOrdValue(ied.getTypeDeclarations()); + // } + + // if (value != null) + // { + + // switch (dataAttribute.AttributeType) + // { + // case AttributeType.ENUMERATED: + // case AttributeType.INT8: + // case AttributeType.INT16: + // case AttributeType.INT32: + // case AttributeType.INT64: + // output.Write("=" + value.Value()); + // break; + // case AttributeType.INT8U: + // case AttributeType.INT16U: + // case AttributeType.INT24U: + // case AttributeType.INT32U: + // output.Write("=" + value.getLongValue()); + // break; + // case AttributeType.BOOLEAN: + // { + // Boolean boolVal = (Boolean)value.getValue(); + + // if (boolVal.booleanValue()) + // output.print("=1"); + // } + // break; + // case AttributeType.UNICODE_STRING_255: + // output.print("=\"" + value.getValue() + "\""); + // break; + // case AttributeType.CURRENCY: + // case AttributeType.VISIBLE_STRING_32: + // case AttributeType.VISIBLE_STRING_64: + // case AttributeType.VISIBLE_STRING_129: + // case AttributeType.VISIBLE_STRING_255: + // case AttributeType.VISIBLE_STRING_65: + // output.Write("=\"" + value.getValue() + "\""); + // break; + // case AttributeType.FLOAT32: + // case AttributeType.FLOAT64: + // output.Write("=" + value.getValue()); + // break; + // case AttributeType.TIMESTAMP: + // case AttributeType.ENTRY_TIME: + // output.Write("=" + value.getLongValue()); + // break; + + // default: + // System.out.println("Unknown default value for " + dataAttribute.getName() + " type: " + dataAttribute.getType()); + // break; + // } + + // } + + // output.Write(";"); + // } + // else + // { + // output.Write("{"); + + // foreach (DataAttribute subDataAttribute in dataAttribute.subDataAttributes) + // { + // ExportDataAttribute(output, subDataAttribute, isTransient); + // } + + // output.Write("}"); + // } + //} + SclDAI getDAI(object parent, string name) + { + if (parent == null) + return null; + + if (parent is SclDOI sclDOI) + return sclDOI.SclDAIs.Find(x => x.Name == name); + else if (parent is SclSDI sclSDI) + return sclSDI.SclDAIs.Find(x => x.Name == name); + else + return null; + } + + DataObject findDOParent(DataAttribute dataAttribute) + { + DataObject parentObject = null; + //DataObjectOrAttribute obj = null; + + while(!(dataAttribute.Parent is DataObject)) + { + dataAttribute = dataAttribute.Parent as DataAttribute; + } + parentObject = dataAttribute.Parent as DataObject; + + + return parentObject; + + + } + + LogicalNode findLNParent(DataObject dataObject) + { + LogicalNode parentObject = null; + //DataObjectOrAttribute obj = null; + + while (!(dataObject.Parent is LogicalNode)) + { + dataObject = dataObject.Parent as DataObject; + } + parentObject = dataObject.Parent as LogicalNode; + + + return parentObject; + + + } + + public SclDataAttributeDefinition GetDA(string name, SclDOType doType) + { + foreach (SclDataAttributeDefinition sclDa in doType.DataAttributes) + { + if (sclDa.Name != null && sclDa.Name.Equals(name)) + return sclDa; + } + + return null; + } + + //private void SetPredefindedValuesForDAI(LogicalNode ln, DataAttribute dataAttribute, DataObject dataObject) + //{ + // if (dai.Name != null) + // { + + //} + + //private void SetPredefinedValuesForSDI(LogicalNode ln, string path, SclSDI sclSdi, SclDOType doType, SclDAType daType, SclDataTypeTemplates types, DataAttribute dataAttribute) + //{ + // if (sclSdi.Name != null) + // { + // string extendedPath = path + "." + sclSdi.Name; + + // foreach (SclDAI dai in sclSdi.SclDAIs) + // { + // if (doType != null) + // { + // SclDataAttributeDefinition sclDa = GetDA(dai.Name, doType); + + // if (sclDa != null) + // { + // DataAttributeType bType = (DataAttributeType)sclDa.AttributeType; + + // SetPredefindedValuesForDAI(ln, extendedPath, dai, bType, sclDa.Type, types); + // } + // else + // { + // logMessage(IedModelFactoryLogLevel.ERROR, "SCL: DA for name " + dai.Name + " not found"); + // } + // } + // else if (daType != null) + // { + // SclDataAttributeDefinition sclBda = daType.GetBDA(dai.Name); + + // if (sclBda != null) + // { + // DataAttributeType bType = (DataAttributeType)sclBda.AttributeType; + + // SetPredefindedValuesForDAI(ln, extendedPath, dai, bType, sclBda.Type, types); + // } + + // } + // } + + // foreach (SclSDI sdi in sclSdi.SclSDIs) + // { + // if (doType != null) + // { + // SclDataAttributeDefinition da = doType.GetDA(sdi.Name, dataAttribute); + + // if (da != null) + // { + // SclDAType subDaType = types.GetDAType(da.Type); + + // if (subDaType != null) + // { + // SetPredefinedValuesForSDI(ln, extendedPath, sdi, null, subDaType, types); + // } + // } + // else + // { + // SclDataObjectDefinition sdo = doType.GetSDO(sdi.Name); + + // if (sdo != null) + // { + // SclDOType subDoType = types.GetDOType(sdo.Type); + + // if (subDoType != null) + // { + // SetPredefinedValuesForSDI(ln, extendedPath, sdi, subDoType, null, types); + // } + + // } + + // } + // } + // else if (daType != null) + // { + // SclDataAttributeDefinition bda = daType.GetBDA(sdi.Name); + + // if (bda != null) + // { + // SclDAType subDaType = types.GetDAType(bda.Type); + + // if (subDaType != null) + // { + // SetPredefinedValuesForSDI(ln, extendedPath, sdi, null, subDaType, types); + // } + + // } + + // } + // } + // } + //} + + + + //object findValue(DataAttribute dataAttribute) + //{ + // object value = null; + + // if(dataAttribute.Parent is DataAttribute dataAttribute1) + // { + // SclDAI sclDAI = getDAI(dataAttribute1.Parent, dataAttribute.Name); + + + // SclSDO sclSDOI = null; + // sclSDOI. + // } + + // return value; + //} + + SclDAI getDAIInternal(SclSDI sclSDI, DataAttribute dataAttribute) + { + SclDAI returnValue = null; + foreach(SclDAI sclDAI1 in sclSDI.SclDAIs) + { + if(sclDAI1.Name == dataAttribute.Name) + { + if (dataAttribute.ObjRef.EndsWith("." + sclSDI.Name + "." + sclDAI1.Name)) + { + + returnValue = sclDAI1; + break; + + } + } + } + + return returnValue; + } + + string getSDIValue(DataAttribute dataAttribute, object DIObject) + { + string value = null; + + SclSDI sclSDI1 = DIObject as SclSDI; + if (sclSDI1 == null) + return value; + + + SclDAI sclDAI = getDAIInternal(sclSDI1, dataAttribute); + + + if (sclDAI != null) + { + + value = sclDAI.Val; + } + + else + { + foreach (SclSDI sclSDI in sclSDI1.SclSDIs) + { + string fValue = getSDIValue(dataAttribute, sclSDI); + if (fValue != null) + { + value = fValue; + break; + } + } + } + + + return value; + + } + + string getDAIValue(DataAttribute dataAttribute, SclDOI sclDOI) + { + if (sclDOI == null) + return null; + + string value = null; + SclDAI sclDAI = sclDOI.SclDAIs.Find(x => x.Name == dataAttribute.Name); + if (sclDAI != null) + { + value = sclDAI.Val; + } + else + { + foreach (SclSDI sclSDI in sclDOI.SclSDIs) + { + string fValue = getSDIValue(dataAttribute, sclSDI); + if (fValue != null) + { + value = fValue; + break; + } + } + + } + + return value; + + } + + string getObjRef(string initialString, SclSDI sclSDI) + { + object parent = sclSDI.Parent; + while(!(parent is SclDOI)) + { + SclSDI sclSDI1 = parent as SclSDI; + parent = sclSDI1.Parent; + } + SclDOI doName = (SclDOI)parent; + initialString += "." + doName.Name; + + + return initialString; + } + + SclDOI getDOIfromSDAI(SclSDI sclSDI) + { + object parent = sclSDI.Parent; + while (!(parent is SclDOI)) + { + SclSDI sclSDI1 = parent as SclSDI; + parent = sclSDI1.Parent; + } + SclDOI doName = (SclDOI)parent; + + + return doName; + } + SclSDI getSDIIInternal(SclSDI sclSDI, DataObject dataObject, LogicalNode logicalNode) + { + SclSDI returnValue = null; + foreach (SclSDI sclSDI1 in sclSDI.SclSDIs) + { + if (sclSDI1.Name == dataObject.Name) + { + string hh = ((LogicalDevice)logicalNode.Parent).Name + "/" + logicalNode.Name; + + string objRefString = getObjRef(hh, sclSDI); + if (dataObject.ObjRef.StartsWith(objRefString)) + { + + returnValue = sclSDI1; + break; + + } + } + } + + return returnValue; + } + + SclSDI getSDI(LogicalNode logicalNode, DataObject dataObject, object DIObject) + { + SclSDI returnValue = null; + SclSDI sclSDI1 = DIObject as SclSDI; + if (sclSDI1 == null) + return null; + + + SclSDI sclSDI_internal = getSDIIInternal(sclSDI1, dataObject, logicalNode); + + + if (sclSDI_internal != null) + { + + return sclSDI_internal; + } + + else + { + foreach (SclSDI sclSDI in sclSDI1.SclSDIs) + { + SclSDI sclSDI2 = getSDI(logicalNode, dataObject, sclSDI); + if (sclSDI2 != null) + { + returnValue = sclSDI2; + break; + } + + } + } + + + return returnValue; + + } + + SclDOI getSDO(LogicalNode logicalNode, DataObject dataObject) + { + SclSDI returnSDI = null; + + + foreach (SclDOI sclDOI1 in logicalNode.SclElement.DOIs) + { + foreach(SclSDI sclSDI in sclDOI1.SclSDIs) + { + returnSDI = getSDI(logicalNode, dataObject, sclSDI); + if(returnSDI != null) + { + break; + } + } + + if(returnSDI != null) + { + break; + } + } + if (returnSDI == null) + return null; + else + return getDOIfromSDAI(returnSDI); + + } + + void printDataAttributes(StreamWriter output, DataAttribute dataAttribute, bool isTransient) + { + if (dataAttribute.ObjRef.Contains("serNum")) + { + Console.WriteLine("Debug"); + } + + if (dataAttribute.AttributeType != AttributeType.CONSTRUCTED) + { + //if (value != null) + //{ + + DataObject dataObject = findDOParent(dataAttribute); + //DataObject dataObject = dataAttribute.Parent as DataObject; + //LogicalNode logicalNode = dataObject.Parent as LogicalNode; + LogicalNode logicalNode = findLNParent(dataObject); + + SclDOI sclDOI = logicalNode.SclElement.DOIs.Find(x => x.Name == dataObject.Name); + + if(sclDOI == null) + { + sclDOI = getSDO(logicalNode, dataObject); + } + SclDAI sclDAI = getDAI(sclDOI, dataAttribute.Name); + + + string obValue = getDAIValue(dataAttribute, sclDOI); + + if (obValue == null) + { + output.WriteLine(";"); + + return; + } + //string value = sclDAI.Val; + string value = obValue; + + if (value != null) + { + switch (dataAttribute.AttributeType) + { + case AttributeType.ENUMERATED: + SclEnumType sclEnumType = sclDocument.DataTypeTemplates.GetEnumType(dataAttribute.Definition.Type); + + if (sclEnumType != null) + { + if (sclEnumType.EnumValues.Count > 0) + { + SclEnumVal sclEnumVal = sclEnumType.EnumValues[0]; + int value1 = sclEnumVal.Ord; + output.Write("=" + sclEnumVal.Ord); + + } + + } + + break; + + case AttributeType.INT8: + case AttributeType.INT16: + case AttributeType.INT32: + case AttributeType.INT64: + case AttributeType.INT8U: + case AttributeType.INT16U: + case AttributeType.INT24U: + case AttributeType.INT32U: + output.Write("=" + value); + break; + + case AttributeType.BOOLEAN: + if (value == "true") + output.Write("=1"); + else + output.Write("=0"); + break; + + case AttributeType.UNICODE_STRING_255: + output.Write("=\"" + value + "\""); + break; + + case AttributeType.CURRENCY: + case AttributeType.VISIBLE_STRING_32: + case AttributeType.VISIBLE_STRING_64: + case AttributeType.VISIBLE_STRING_129: + case AttributeType.VISIBLE_STRING_255: + case AttributeType.VISIBLE_STRING_65: + output.Write("=\"" + value + "\""); + break; + + case AttributeType.OCTET_STRING_64: + output.Write("=\"" + value + "\""); + break; + + case AttributeType.FLOAT32: + case AttributeType.FLOAT64: + output.Write("=" + value); + break; + + default: + Console.WriteLine("Unknown default value for " + dataAttribute.Name + " type: " + dataAttribute.AttributeType); + break; + + } + + //} + } + + output.WriteLine(";"); + + } + + else + { + output.WriteLine("{"); + + foreach (DataAttribute subDataAttribute in dataAttribute.SubDataAttributes) + { + ExportDataAttribute(output, subDataAttribute, isTransient); + } + + output.WriteLine("}"); + } + + } + + private void ExportDataAttribute(StreamWriter output, DataAttribute dataAttribute, bool isTransient) + { + output.Write("DA(" + dataAttribute.Name + " "); + output.Write(dataAttribute.Count + " "); + output.Write((int)dataAttribute.AttributeType + " "); + output.Write((int)dataAttribute.Fc + " "); + + if (dataAttribute.Definition.TriggerOptions != null) + { + int trgOpsVal = dataAttribute.Definition.TriggerOptions.GetIntValue(); + + if (isTransient) + trgOpsVal += 128; + + output.Write(trgOpsVal + " "); + } + + + if (dataAttribute.Definition.SAddr != null) + output.Write(dataAttribute.Definition.SAddr); + else + output.Write("0"); + + output.Write(")"); + + if (dataAttribute.Count > 0) + { + output.WriteLine("{"); + + for (int i = 0; i < dataAttribute.Count; i++) + { + output.Write("[" + i + "]"); + + printDataAttributes(output, dataAttribute, isTransient); + } + + output.WriteLine("}"); + } + + else + { + + printDataAttributes(output, dataAttribute, isTransient); + } + + + + + //if (value != null) + //{ + // switch (dataAttribute.AttributeType) + // { + // case AttributeType.ENUMERATED: + // string EnumType = dataAttribute.Definition.Type; + // SclEnumType sclEnumType; + // if (EnumType != null) + // { + // sclEnumType = sclDocument.DataTypeTemplates.GetEnumType(EnumType); + // if (sclEnumType != null) + // { + // SclEnumVal sclEnumVal = sclEnumType.EnumValues.Find(x => x.SymbolicName == value.Value); + // output.Write("=" + sclEnumVal.Ord); + // } + // } + + // break; + + // case AttributeType.INT8: + // case AttributeType.INT16: + // case AttributeType.INT32: + // case AttributeType.INT64: + // output.Write("=" + value.Value); + // break; + // case AttributeType.INT8U: + // case AttributeType.INT16U: + // case AttributeType.INT24U: + // case AttributeType.INT32U: + // output.Write("=" + value.Value); + // break; + + // case AttributeType.BOOLEAN: + // if (value.Value == "true") + // output.Write("=1"); + // else + // output.Write("=0"); + // break; + + // case AttributeType.UNICODE_STRING_255: + // output.Write("=\"" + value.Value + "\""); + // break; + + // case AttributeType.CURRENCY: + // case AttributeType.VISIBLE_STRING_32: + // case AttributeType.VISIBLE_STRING_64: + // case AttributeType.VISIBLE_STRING_129: + // case AttributeType.VISIBLE_STRING_255: + // case AttributeType.VISIBLE_STRING_65: + // output.Write("=\"" + value.Value + "\""); + // break; + + // case AttributeType.OCTET_STRING_64: + // output.Write("=\"" + value.Value + "\""); + // break; + + // case AttributeType.FLOAT32: + // case AttributeType.FLOAT64: + // output.Write("=" + value.Value); + // break; + + // default: + // Console.WriteLine("Unknown default value for " + dataAttribute.Name + " type: " + dataAttribute.AttributeType); + // break; + // } + + //} + + //output.WriteLine(";"); + //} + + + } + + private static String toMmsString(String iecString) + { + return iecString.Replace('.', '$'); + } + + private void ExportDataSet(StreamWriter output, DataSet dataSet, LogicalNode logicalNode) + { + output.Write("DS(" + dataSet.Name + "){\n"); + + foreach (SclFCDA fcda in dataSet.SclDataSet.Fcdas) + { + String mmsVariableName = ""; + + if (fcda.Prefix != null) + mmsVariableName += fcda.Prefix; + + mmsVariableName += fcda.LnClass; + + if (fcda.LnInst != null) + mmsVariableName += fcda.LnInst; + + mmsVariableName += "$" + fcda.Fc; + + mmsVariableName += "$" + fcda.DoName; + + if (fcda.DaName != null) + mmsVariableName += "$" + toMmsString(fcda.DaName); + + int arrayStart = mmsVariableName.IndexOf('('); + + String variableName = mmsVariableName; + int arrayIndex = -1; + string componentName = null; + + + if (arrayStart != -1) + { + variableName = mmsVariableName.Substring(0, arrayStart); + int arrayEnd = mmsVariableName.IndexOf(')'); + + string arrayIndexStr = mmsVariableName.Substring(arrayStart + 1, arrayEnd); + arrayIndex = int.Parse(arrayIndexStr); + //if (arrayIndex < 0) + // throw new SclParserException("Array index out of range in data set entry definition"); + + string componentNamePart = mmsVariableName.Substring(arrayEnd + 1); + + if ((componentNamePart != null) && (componentNamePart.Length > 0)) + { + if (componentNamePart[0] == '$') + { + componentNamePart = componentNamePart.Substring(1); + } + + if ((componentNamePart != null) && (componentNamePart.Length > 0)) + componentName = componentNamePart; + } + } + + /* check for LD name */ + + String logicalDeviceName = null; + + if (fcda.LdInst != null) + { + + if (fcda.LdInst != (logicalNode.Parent as LogicalDevice).Inst) + { + logicalDeviceName = fcda.LdInst; + } + } + + if (logicalDeviceName != null) + variableName = logicalDeviceName + "/" + variableName; + + if (variableName != null && arrayIndex != -1 && componentName != null) + { + output.Write("DE(" + variableName + " " + arrayIndex + " " + componentName + ");\n"); + } + else if (variableName != null && arrayIndex != -1) + { + output.Write("DE(" + variableName + " " + arrayIndex + ");\n"); + } + else if (variableName != null) + { + output.Write("DE(" + variableName + ");\n"); + } + + } + + output.WriteLine("}"); + + } + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/ExtRef.cs b/tools/model_generator_dotnet/SCLParser/src/ExtRef.cs new file mode 100644 index 00000000..18c76700 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/ExtRef.cs @@ -0,0 +1,270 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclExtRef + { + public XmlNode xmlNode; + private XmlDocument xmlDocument; + public Inputs Parent; + + //public XmlNode XmlNode + //{ + // get { return xmlNode; } + //} + + public SclExtRef(SclDocument sclDocument, XmlNode xmlNode) + { + this.xmlNode = xmlNode; + xmlDocument = sclDocument.XmlDocument; + } + + public string IedName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "iedName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "iedName", value); + } + } + + public string LdInst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "ldInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "ldInst", value); + } + } + + public string Prefix + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "prefix"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "prefix", value); + } + } + + public string LnClass + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnClass"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnClass", value); + } + } + + public string LnInst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnInst", value); + } + } + + public string DoName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "doName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "doName", value); + } + } + + public string DaName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "daName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "daName", value); + } + } + + public string IntAddr + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "intAddr"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "intAddr", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + public string ServiceType + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "serviceType"); + + } + set + { + if (value == null) + { + XmlAttribute xmlAttribute = xmlNode.Attributes["serviceType"]; + if (xmlAttribute != null) + xmlNode.Attributes.Remove(xmlAttribute); + } + else + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "serviceType", value); + PServT = value; + } + } + + public string SrcLDInst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "srcLDInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "srcLDInst", value); + } + } + + public string SrcPrefix + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "srcPrefix"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "srcPrefix", value); + } + } + + public string SrcLNClass + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "srcLNClass"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "srcLNClass", value); + } + } + + public string SrcLNInst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "srcLNInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "srcLNInst", value); + } + } + + public string SrcCBName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "srcCBName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "srcCBName", value); + } + } + + public string PDO + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "pDO"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "pDO", value); + } + } + + public string PLN + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "pLN"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "pLN", value); + } + } + + public string PDA + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "pDA"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "pDA", value); + } + } + + public string PServT + { + + get + { + return XmlHelper.GetAttributeValue(xmlNode, "pServT"); + } + set + { + + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "pServT", value); + + } + } + + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclBaseElement.cs b/tools/model_generator_dotnet/SCLParser/src/SclBaseElement.cs new file mode 100644 index 00000000..3b218947 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclBaseElement.cs @@ -0,0 +1,68 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + + +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclBaseElement + { + protected SclDocument sclDocument; + + public XmlNode xmlNode; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + + public SclBaseElement(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode) + { + this.xmlNode = xmlNode; + this.sclDocument = sclDocument; + } + + /// + /// Gets the attribute value. + /// + /// The attribute value. + /// Attribute name. + public string GetAttributeValue(string attributeName) + { + return XmlHelper.GetAttributeValue(xmlNode, attributeName); + } + + /// + /// Sets the attribute value. + /// + /// Attribute name. + /// Value. + public void SetAttributeValue(string attributeName, string value) + { + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, xmlNode, attributeName, value); + } + + /// + /// Gets or sets the text content of the element + /// + /// the text content + public string Text + { + get + { + return xmlNode.InnerText; + } + + set + { + xmlNode.InnerText = value; + } + } + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclCommunication.cs b/tools/model_generator_dotnet/SCLParser/src/SclCommunication.cs new file mode 100644 index 00000000..06205ded --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclCommunication.cs @@ -0,0 +1,829 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System; +using System.Collections.Generic; +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclCommunication + { + private XmlDocument xmlDoc; + private XmlNamespaceManager nsManager; + public XmlNode xmlNode; + private SclDocument sclDocument; + + private List subNetworks = new List(); + + + public bool DeleteSubnetwork(SclSubNetwork sclSubNetwork) + { + if (subNetworks.Exists(x => x == sclSubNetwork)) + { + subNetworks.Remove(sclSubNetwork); + xmlNode.RemoveChild(sclSubNetwork.xmlNode); + + return true; + } + else + return false; + } + + public SclSubNetwork AddSubNetwork(SclSubNetwork sclSubNetwork) + { + XmlNode newNode = sclSubNetwork.xmlNode; + + if (newNode.OwnerDocument != xmlDoc) + { + newNode = xmlDoc.ImportNode(sclSubNetwork.xmlNode.CloneNode(true), true); + } + + if (GetSubNetworks().Count > 0) + xmlNode.InsertAfter(newNode, GetSubNetworks()[GetSubNetworks().Count - 1].xmlNode); + else + { + xmlNode.AppendChild(newNode); + + } + + try + { + SclSubNetwork newSubNetwork = new SclSubNetwork(newNode, sclDocument, nsManager); + subNetworks.Add(newSubNetwork); + + return newSubNetwork; + + } + catch (SclParserException ex) + { + Console.WriteLine(ex.ToString()); + return null; + } + } + + private void ParseSubNetworks() + { + if (subNetworks == null) + subNetworks = new List(); + + XmlNodeList subNetworkNodes = xmlNode.SelectNodes("scl:SubNetwork", nsManager); + + foreach (XmlNode snNode in subNetworkNodes) + { + subNetworks.Add(new SclSubNetwork(snNode, sclDocument, nsManager)); + } + } + + internal SclCommunication(XmlNode comNode, SclDocument SclxmlDoc, XmlNamespaceManager nsManager) + { + xmlDoc = SclxmlDoc.XmlDocument; + xmlNode = comNode; + this.nsManager = nsManager; + sclDocument = SclxmlDoc; + + ParseSubNetworks(); + } + + public List GetSubNetworks() + { + if (subNetworks == null) + ParseSubNetworks(); + + return subNetworks; + } + + public SclConnectedAP GetConnectedAP(string apName, string iedName) + { + foreach (SclSubNetwork subNetwork in GetSubNetworks()) + { + foreach (SclConnectedAP connectedAp in subNetwork.GetConnectedAPs()) + { + if (connectedAp.ApName.Equals(apName) && connectedAp.IedName.Equals(iedName)) + return connectedAp; + } + } + + return null; + } + + public SclSubNetwork GetSubNetwork(string apName, string iedName) + { + foreach (SclSubNetwork subNetwork in GetSubNetworks()) + { + foreach (SclConnectedAP connectedAp in subNetwork.GetConnectedAPs()) + { + if (connectedAp.ApName.Equals(apName) && connectedAp.IedName.Equals(iedName)) + return subNetwork; + } + } + + return null; + } + } + + public class SclSubNetwork + { + private XmlDocument xmlDoc; + internal XmlNode xmlNode; + private XmlNamespaceManager nsManager; + private SclDocument sclDocument; + + public XmlNode XmlNodeClone() + { + XmlNode newNode = xmlNode.CloneNode(true); + + return newNode; + } + + private XmlNamespaceManager NsManager + { + get { return nsManager; } + } + + private List connectedAPs = null; + + private void ParseConnectedAPs() + { + if (connectedAPs == null) + connectedAPs = new List(); + + if (connectedAPs.Count > 0) + connectedAPs.Clear(); + + XmlNodeList connectedAPNodes = xmlNode.SelectNodes("scl:ConnectedAP", nsManager); + + foreach (XmlNode node in connectedAPNodes) + { + connectedAPs.Add(new SclConnectedAP(node, sclDocument, nsManager)); + } + } + + public SclSubNetwork(XmlNode snNode, SclDocument SclxmlDoc, XmlNamespaceManager nsManager) + { + xmlNode = snNode; + xmlDoc = SclxmlDoc.XmlDocument; + sclDocument = SclxmlDoc; + this.nsManager = nsManager; + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "Name", Name); + + if (Name == null) + SclxmlDoc.AddIssue(snNode, "ERROR", "Model integrity", "SubNetwork has no name attribute", this, "MissingName"); + + ParseConnectedAPs(); + } + + + public List GetConnectedAPs() + { + if (connectedAPs == null) + ParseConnectedAPs(); + + return connectedAPs; + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "name", value); + } + } + + public string Type + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "type", value); + } + } + } + + public class SclConnectedAP + { + private SclDocument sclDocument; + private XmlDocument xmlDoc; + internal XmlNode xmlNode; + private SclAddress address = null; + private XmlNamespaceManager nsManager; + private List gses = new List(); + private List smvs = new List(); + + public XmlNode XmlNodeClone() + { + XmlNode newNode = xmlNode.CloneNode(true); + + return newNode; + } + + private XmlNamespaceManager NsManager + { + get { return nsManager; } + } + + public SclConnectedAP(XmlNode apNode, SclDocument SclxmlDoc, XmlNamespaceManager nsManager) + { + sclDocument = SclxmlDoc; + xmlNode = apNode; + xmlDoc = SclxmlDoc.XmlDocument; + this.nsManager = nsManager; + + if (IedName == null) + SclxmlDoc.AddIssue(xmlNode, "ERROR", "Model integrity", "ConnectedAP is missing required attribute iedName", this, "connectedAP"); + + //throw new SclParserException(apNode, "ConnectedAP is missing required attribute."); + + if (ApName == null) + SclxmlDoc.AddIssue(xmlNode, "ERROR", "Model integrity", "ConnectedAP is missing required attribute apName", this, "connectedAP"); + + + XmlNode AddressNode = xmlNode.SelectSingleNode("scl:Address", nsManager); + if (AddressNode != null) + { + address = new SclAddress(AddressNode, SclxmlDoc, nsManager); + } + + XmlNodeList GSENodes = xmlNode.SelectNodes("scl:GSE", nsManager); + + foreach (XmlNode node in GSENodes) + { + gses.Add(new SclGSE(node, SclxmlDoc, nsManager)); + } + + XmlNodeList SMVNodes = xmlNode.SelectNodes("scl:SMV", nsManager); + + foreach (XmlNode node in SMVNodes) + { + smvs.Add(new SclSMV(node, SclxmlDoc, nsManager)); + } + } + + + public List GSEs + { + get { return gses; } + set { gses = value; } + + } + + public List SMVs + { + get { return smvs; } + set { smvs = value; } + + } + + public SclAddress Address + { + get { return address; } + set { address = value; } + + } + + public SclAddress GetAddress() + { + if (address != null) + return address; + + XmlNode addrNode = xmlNode.SelectSingleNode("scl:Address", nsManager); + + if (addrNode != null) + { + address = new SclAddress(addrNode, sclDocument, nsManager); + + return address; + } + else + return null; + } + + public string IedName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "iedName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "iedName", value); + } + } + + public string ApName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "apName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "apName", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "desc", value); + } + } + + public string RedProt + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "redProt"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "redProt", value); + } + } + } + + public class SclGSE + { + public XmlNode gseNode; + private XmlDocument xmlDoc; + private XmlNamespaceManager nsManager; + private SclAddress sclAddress = null; + private XmlNode minTime = null; + private XmlNode maxTime = null; + + public XmlNode Node { get { return gseNode; } set { gseNode = value; } } + public SclAddress SclAddress { get { return sclAddress; } set { sclAddress = value; } } + + public SclGSE(XmlNode GSENode, SclDocument SclxmlDoc, XmlNamespaceManager nsManager) + { + gseNode = GSENode; + xmlDoc = SclxmlDoc.XmlDocument; + this.nsManager = nsManager; + + XmlAttribute nameAttr = gseNode.Attributes["cbName"]; + if (nameAttr == null) + SclxmlDoc.AddIssue(GSENode, "ERROR", "Model integrity", "GSE has no cbName attribute", this, "MissingName"); + + XmlNode AddressNode = gseNode.SelectSingleNode("scl:Address", nsManager); + if (AddressNode != null) + { + sclAddress = new SclAddress(AddressNode, SclxmlDoc, nsManager); + } + + XmlNode min = gseNode.SelectSingleNode("scl:MinTime", nsManager); + if (min != null) + { + minTime = min; + } + + XmlNode max = gseNode.SelectSingleNode("scl:MaxTime", nsManager); + if (max != null) + { + maxTime = max; + } + + } + + public string Mintime + { + get + { + if (minTime != null) + { + return minTime.InnerText; + } + else + return null; + } + } + + public string Maxtime + { + get + { + if (maxTime != null) + { + return maxTime.InnerText; + } + else + return null; + } + } + + public string CbName + { + get + { + return XmlHelper.GetAttributeValue(gseNode, "cbName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, gseNode, "cbName", value); + } + } + + public string LdInst + { + get + { + return XmlHelper.GetAttributeValue(gseNode, "ldInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, gseNode, "ldInst", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(gseNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, gseNode, "desc", value); + } + } + } + + public class SclSMV + { + public XmlNode smvNode; + private XmlDocument xmlDoc; + private XmlNamespaceManager nsManager; + private SclAddress sclAddress = null; + + public SclAddress SclAddress { get { return sclAddress; } set { sclAddress = value; } } + + public SclSMV(XmlNode SMVNode, SclDocument SclxmlDoc, XmlNamespaceManager nsManager) + { + smvNode = SMVNode; + xmlDoc = SclxmlDoc.XmlDocument; + this.nsManager = nsManager; + + XmlAttribute nameAttr = smvNode.Attributes["cbName"]; + if (nameAttr == null) + SclxmlDoc.AddIssue(SMVNode, "ERROR", "Model integrity", "SMV has no cbName attribute", this, "MissingName"); + + XmlNode AddressNode = smvNode.SelectSingleNode("scl:Address", nsManager); + if (AddressNode != null) + { + sclAddress = new SclAddress(AddressNode, SclxmlDoc, nsManager); + } + + + } + + public string CbName + { + get + { + return XmlHelper.GetAttributeValue(smvNode, "cbName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, smvNode, "cbName", value); + } + } + + public string LdInst + { + get + { + return XmlHelper.GetAttributeValue(smvNode, "ldInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, smvNode, "ldInst", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(smvNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, smvNode, "desc", value); + } + } + } + + public class SclAddress + { + public XmlNode addrNode; + private XmlDocument xmlDoc; + private XmlNamespaceManager nsManager; + + public XmlNode Node { get { return addrNode; } set { addrNode = value; } } + private string vlanId = "0"; + private string vlanPriority = "0"; + private string appId = "0"; + private int[] macAddress = null; + + public string VlanId + { + get + { + return vlanId; + } + set + { + vlanId = value; + } + + } + + public string VlanPriority + { + get + { + return vlanPriority; + } + set + { + vlanPriority = value; + } + + } + + public string AppId + { + get + { + return appId; + } + set + { + appId = value; + } + + } + + public int[] MacAddress + { + get + { + return macAddress; + + } + set + { + macAddress = value; + } + } + + private List sclPs = new List(); + + public List SclPs { get { return sclPs; } set { sclPs = value; } } + + public void CheckIfPValueisCorrect(SclDocument sclDocument, SclP sclP) + { + if (sclP.Text != null) + { + if (sclP.Type == "APPID") + { + if (System.Text.RegularExpressions.Regex.IsMatch(sclP.Text, @"\A\b[0-9a-fA-F]+\b\Z")) + { + if (sclP.Text.Length != 4) + { + sclDocument.AddIssue(sclP.Node, "ERROR", "Model integrity", "P address of type " + sclP.Type + " size it is not 4. Actual size: " + sclP.Text.Length.ToString(), sclP, "value"); + + } + } + else + { + sclDocument.AddIssue(sclP.Node, "ERROR", "Model integrity", "P address of type " + sclP.Type + " does not have a Hex value. Value is: " + sclP.Text, sclP, "value"); + + } + + } + else if (sclP.Type == "VLAN-ID") + { + if (System.Text.RegularExpressions.Regex.IsMatch(sclP.Text, @"\A\b[0-9a-fA-F]+\b\Z")) + { + if (sclP.Text.Length != 3) + { + sclDocument.AddIssue(sclP.Node, "ERROR", "Model integrity", "P address of type " + sclP.Type + " size it is not 3. Actual size: " + sclP.Text.Length.ToString(), sclP, "value"); + + } + } + else + { + sclDocument.AddIssue(sclP.Node, "ERROR", "Model integrity", "P address of type " + sclP.Type + " does not have a Hex value. Value is: " + sclP.Text, sclP, "value"); + + } + + } + else if (sclP.Type == "VLAN-PRIORITY") + { + if (System.Text.RegularExpressions.Regex.IsMatch(sclP.Text, @"\A\b[0-7]+\b\Z")) + { + } + else + { + sclDocument.AddIssue(sclP.Node, "ERROR", "Model integrity", "P address of type " + sclP.Type + " does not have a 0-7 value. Value is: " + sclP.Text, sclP, "value"); + + } + } + else if (sclP.Type == "MAC-Address") + { + string[] addressElements = sclP.Text.Split('-'); + + if (addressElements.Length == 6) + { + for (int i = 0; i < addressElements.Length; i++) + { + if (System.Text.RegularExpressions.Regex.IsMatch(addressElements[i], @"\A\b[0-9a-fA-F]+\b\Z")) + { + if (addressElements[i].Length != 2) + sclDocument.AddIssue(sclP.Node, "ERROR", "Model integrity", "P address of type " + sclP.Type + " size it is not 2 on position " + i + ". Actual size: " + addressElements[i].Length.ToString(), sclP, "value"); + + } + else + { + sclDocument.AddIssue(sclP.Node, "ERROR", "Model integrity", "P address of type " + sclP.Type + " does not have a Hex value on position " + i + ". Value is: " + addressElements[i], sclP, "value"); + + } + } + } + else + sclDocument.AddIssue(sclP.Node, "ERROR", "Model integrity", "P address of type " + sclP.Type + " does not have a array size 6 value. Actual size: " + addressElements.Length.ToString(), sclP, "value"); + + } + + } + + } + + public SclAddress(XmlNode addrNode, SclDocument sclDocument, XmlNamespaceManager nsManager) + { + this.addrNode = addrNode; + xmlDoc = sclDocument.XmlDocument; + this.nsManager = nsManager; + + XmlNodeList pNodes = addrNode.SelectNodes("scl:P", nsManager); + + foreach (XmlNode pNode in pNodes) + { + SclP sclP = new SclP(pNode, xmlDoc); + sclPs.Add(sclP); + + CheckIfPValueisCorrect(sclDocument, sclP); + + if (sclP.Text != null) + { + if (sclP.Type == "VLAN-ID") + VlanId = sclP.Text; + else if (sclP.Type == "VLAN-PRIORITY") + VlanPriority = sclP.Text; + else if (sclP.Type == "APPID") + AppId = sclP.Text; + else if (sclP.Type == "MAC-Address") + { + string[] addressElements = sclP.Text.Split('-'); + + if (addressElements.Length == 6) + { + macAddress = new int[6]; + + for (int i = 0; i < addressElements.Length; i++) + { + macAddress[i] = int.Parse(addressElements[i], System.Globalization.NumberStyles.AllowHexSpecifier); + } + } + + } + + + + } + + + else if (sclP.Type == "MAC-Address") + { + string[] addressElements = sclP.Text.Split('-'); + + if (addressElements.Length == 6) + { + macAddress = new int[6]; + + for (int i = 0; i < addressElements.Length; i++) + { + macAddress[i] = int.Parse(addressElements[i], System.Globalization.NumberStyles.AllowHexSpecifier); + } + } + + } + } + } + + public List GetAddressParameters() + { + if (sclPs == null) + { + sclPs = new List(); + + XmlNodeList pNodes = addrNode.SelectNodes("scl:P", nsManager); + + foreach (XmlNode pNode in pNodes) + { + sclPs.Add(new SclP(pNode, xmlDoc)); + } + } + + return sclPs; + } + + public SclP GetAddressParameter(string type) + { + foreach (SclP p in GetAddressParameters()) + { + if (p.Type != null) + { + if (p.Type.Equals(type)) + return p; + } + } + + return null; + } + } + + public class SclP + { + private XmlNode pNode; + private XmlDocument xmlDoc; + + internal XmlNode Node { get { return pNode; } set { pNode = value; } } + + public SclP(XmlNode pNode, XmlDocument xmlDoc) + { + this.pNode = pNode; + this.xmlDoc = xmlDoc; + } + + public XmlNode XmlNode + { + get { return pNode; } + } + + public string Type + { + get + { + return XmlHelper.GetAttributeValue(pNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, pNode, "type", value); + } + } + + public string XsiType + { + get + { + return XmlHelper.GetAttributeValue(pNode, "xsi:type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, pNode, "xsi:type", value); + } + } + + public string Text + { + get + { + return pNode.InnerText; + } + + set + { + pNode.InnerText = value; + } + } + } + +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclDataTypeTemplates.cs b/tools/model_generator_dotnet/SCLParser/src/SclDataTypeTemplates.cs new file mode 100644 index 00000000..5ba561e4 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclDataTypeTemplates.cs @@ -0,0 +1,258 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System.Collections.Generic; +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclDataTypeTemplates : SclElementWithPrivate + { + private List lnTypes = new List(); + private List doTypes = new List(); + private List daTypes = new List(); + private List enumTypes = new List(); + + + internal SclDataTypeTemplates(SclDocument sclDocument, XmlNode xmlNode) + : base(sclDocument, xmlNode) + { + foreach (XmlNode lNodeType in xmlNode.SelectNodes("scl:LNodeType", sclDocument.NsManager)) + { + SclLNodeType newType = new SclLNodeType(sclDocument, lNodeType); + + if (newType != null) + lnTypes.Add(newType); + } + + foreach (XmlNode doType in xmlNode.SelectNodes("scl:DOType", sclDocument.NsManager)) + { + SclDOType newType = new SclDOType(sclDocument, doType); + + if (newType != null) + doTypes.Add(newType); + } + + foreach (XmlNode daType in xmlNode.SelectNodes("scl:DAType", sclDocument.NsManager)) + { + SclDAType newType = new SclDAType(sclDocument, daType); + + if (newType != null) + daTypes.Add(newType); + } + + foreach (XmlNode enumType in xmlNode.SelectNodes("scl:EnumType", sclDocument.NsManager)) + { + SclEnumType newType = new SclEnumType(sclDocument, enumType); + + if (newType != null) + enumTypes.Add(newType); + } + } + + /// + /// Add a new type to the DataTypeTemplates section. The type will be placed at the correct position + /// according to the class. + /// + /// the new type to add + public SclType AddType(SclType sclType) + { + if (sclType.xmlNode.OwnerDocument != sclDocument.XmlDocument) + { + XmlNode importedNode = sclDocument.XmlDocument.ImportNode(sclType.xmlNode, true); + sclType.xmlNode = importedNode; + } + + if (sclType is SclLNodeType) + { + if (doTypes.Count > 0) + xmlNode.InsertBefore(sclType.xmlNode, doTypes[0].xmlNode); + else if (daTypes.Count > 0) + xmlNode.InsertBefore(sclType.xmlNode, daTypes[0].xmlNode); + else if (enumTypes.Count > 0) + xmlNode.InsertBefore(sclType.xmlNode, enumTypes[0].xmlNode); + else + xmlNode.InsertBefore(sclType.xmlNode, null); + + lnTypes.Add(sclType as SclLNodeType); + } + else if (sclType is SclDOType) + { + if (daTypes.Count > 0) + xmlNode.InsertBefore(sclType.xmlNode, daTypes[0].xmlNode); + else if (enumTypes.Count > 0) + xmlNode.InsertBefore(sclType.xmlNode, enumTypes[0].xmlNode); + else + xmlNode.InsertBefore(sclType.xmlNode, null); + + doTypes.Add(sclType as SclDOType); + } + else if (sclType is SclDAType) + { + if (enumTypes.Count > 0) + xmlNode.InsertBefore(sclType.xmlNode, enumTypes[0].xmlNode); + else + xmlNode.InsertBefore(sclType.xmlNode, null); + + daTypes.Add(sclType as SclDAType); + } + else if (sclType is SclEnumType) + { + xmlNode.InsertBefore(sclType.xmlNode, null); + + enumTypes.Add(sclType as SclEnumType); + } + + return sclType; + } + + + + /// + /// Remove a type from the DataTypeTemplates section. + /// + /// the type to remove + public void RemoveType(SclType type) + { + if (type is SclLNodeType) + lnTypes.Remove(type as SclLNodeType); + else if (type is SclDOType) + doTypes.Remove(type as SclDOType); + else if (type is SclDAType) + daTypes.Remove(type as SclDAType); + else if (type is SclEnumType) + enumTypes.Remove(type as SclEnumType); + + if (type.xmlNode.ParentNode != null) + type.xmlNode.ParentNode.RemoveChild(type.xmlNode); + } + + public void RemoveIfUnused(SclType sclType) + { + if (sclType.IsUsed == false) + { + RemoveType(sclType); + } + } + + /// + /// Remove all unused types from the DataTypeTemplates section + /// + public void RemoveUnusedTypes() + { + List types = new List(); + types.AddRange(LNTypes); + types.AddRange(DOTypes); + types.AddRange(DATypes); + types.AddRange(EnumTypes); + + foreach (SclType sclType in types) + RemoveIfUnused(sclType); + + } + + public SclLNodeType GetLNodeType(string id) + { + foreach (SclLNodeType type in lnTypes) + { + if (type.Id.Equals(id)) + return type; + } + + return null; + } + + public SclDOType GetDOType(string id) + { + foreach (SclDOType type in doTypes) + { + if (type.Id.Equals(id)) + return type; + } + + return null; + } + + public SclDAType GetDAType(string id) + { + foreach (SclDAType type in daTypes) + { + if (type.Id.Equals(id)) + return type; + } + + return null; + } + + public SclEnumType GetEnumType(string id) + { + foreach (SclEnumType type in enumTypes) + { + if (type.Id.Equals(id)) + return type; + } + + return null; + } + + public List LNTypes + { + get + { + return new List(lnTypes); + } + } + + public List DOTypes + { + get + { + return new List(doTypes); + } + } + + public List DATypes + { + get + { + return new List(daTypes); + } + } + + public List EnumTypes + { + get + { + return new List(enumTypes); + } + } + + public List AllTypes + { + get + { + List types = new List(); + + foreach (SclType type in lnTypes) + types.Add(type); + + foreach (SclType type in doTypes) + types.Add(type); + + foreach (SclType type in daTypes) + types.Add(type); + + foreach (SclType type in enumTypes) + types.Add(type); + + return types; + } + } + + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclDocument.cs b/tools/model_generator_dotnet/SCLParser/src/SclDocument.cs new file mode 100644 index 00000000..e0facf7f --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclDocument.cs @@ -0,0 +1,2171 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using IEC61850.SCL.DataModel; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Xml; +using System.Xml.Schema; +using DataSet = IEC61850.SCL.DataModel.DataSet; + +namespace IEC61850.SCL +{ + + public class SclParserException : Exception + { + private XmlNode xmlNode; + + public XmlNode XmlNode + { + get + { + return xmlNode; + } + } + + public SclParserException(XmlNode xmlNode, string message) + : base(message) + { + this.xmlNode = xmlNode; + } + } + + public class SclFileIssue + { + public string Severity { get; set; } + + public int Line { get; set; } + + public string Type { get; set; } + + public string Issue { get; set; } + + public object Object { get; set; } + + public string ObjectIssue { get; set; } + + public int Index { get; set; } + + public override string ToString() + { + return "Severity: " + Severity + "| Line: " + Line.ToString() + " | Type: " + Type + " | Issue: " + Issue; + } + + } + + public class SclDocument + { + public const string SCL_XMLNS = "http://www.iec.ch/61850/2003/SCL"; + private string filename = null; + private List sclFileIssues = new List(); + private List messages = new List(); + private PositionXmlDocument doc; + + public void InitializePositionDoc() + { + using (var reader = new XmlTextReader(filename)) + { + doc = new PositionXmlDocument(); + doc.Load(reader); + } + } + + public PositionXmlElement GetXmlNodePosition(XmlNode xmlNode) + { + try + { + if (doc == null) + InitializePositionDoc(); + + string xpath = FindXPath(xmlNode); + var node = doc.SelectSingleNode(xpath, nsManager); + + return (PositionXmlElement)node; + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + return null; + } + + } + + static string FindXPath(XmlNode node) + { + StringBuilder builder = new StringBuilder(); + while (node != null) + { + switch (node.NodeType) + { + case XmlNodeType.Attribute: + builder.Insert(0, "/@" + node.Name); + node = ((XmlAttribute)node).OwnerElement; + break; + case XmlNodeType.Element: + + int index = FindElementIndex((XmlElement)node); + + if (node.ParentNode.Name == "SCL") + { + builder.Insert(0, "//scl:" + node.Name + "[" + index + "]"); + return builder.ToString(); + } + else + { + builder.Insert(0, "/scl:" + node.Name + "[" + index + "]"); + node = node.ParentNode; + } + + break; + case XmlNodeType.Document: + return builder.ToString(); + default: + throw new ArgumentException("Only elements and attributes are supported"); + } + } + throw new ArgumentException("Node was not in a document"); + } + + static int FindElementIndex(XmlElement element) + { + XmlNode parentNode = element.ParentNode; + if (parentNode is XmlDocument) + { + return 1; + } + XmlElement parent = (XmlElement)parentNode; + int index = 1; + foreach (XmlNode candidate in parent.ChildNodes) + { + if (candidate is XmlElement && candidate.Name == element.Name) + { + if (candidate == element) + { + return index; + } + index++; + } + } + throw new ArgumentException("Couldn't find element within parent"); + } + + public List Messages + { + get + { + return messages; + } + } + + private XmlDocument sclDocument; + private XmlNamespaceManager nsManager; + + public XmlNamespaceManager NsManager + { + get { return nsManager; } + } + + private SclDataTypeTemplates dataTypeTemplates = null; + + private List ieds = null; + private List substations = null; + private SclHeader header = null; + private SclCommunication communication = null; + private string sclVersion = null; + private string sclRevision = null; + private string sclRelease = null; + private static bool changed = false; + + + + public string SclVersion + { + get { return sclVersion; } + + set { XmlHelper.SetAttributeCreateIfNotExists(sclDocument, sclDocument.SelectSingleNode("//scl:SCL", nsManager), "version", value); sclVersion = value; } + + } + + public string SclRevision + { + get { return sclRevision; } + + set { XmlHelper.SetAttributeCreateIfNotExists(sclDocument, sclDocument.SelectSingleNode("//scl:SCL", nsManager), "revision", value); sclRevision = value; } + + } + + public string SclRelease + { + get { return sclRelease; } + } + + XmlNodeChangedEventHandler handler = (sender, e) => changed = true; + + private List schemaFiles = new List {"SCL.xsd", "SCL_BaseSimpleTypes.xsd","SCL_BaseTypes.xsd", "SCL_Communication.xsd", + "SCL_DataTypeTemplates.xsd","SCL_Enums.xsd","SCL_IED.xsd","SCL_Substation.xsd"}; + + private string ProgramDirectory() + { + return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + } + + private void XmlDocValidation() + { + + if (!changed) + { + XmlReaderSettings xmlSettings = new XmlReaderSettings(); + + if (sclRevision != null) + { + if (sclRevision == "B") + { + foreach (string schemaName in schemaFiles) + { + if (sclRelease == null) + { + xmlSettings.Schemas.Add("http://www.iec.ch/61850/2003/SCL", ProgramDirectory() + "\\IEC_61850-6.2009.SCL.2007B\\" + schemaName); + + } + else if (sclRelease == "4") + { + xmlSettings.Schemas.Add("http://www.iec.ch/61850/2003/SCL", ProgramDirectory() + "\\IEC_61850-6.2018.SCL.2007B4\\" + schemaName); + } + + } + } + else + { + foreach (string schemaName in schemaFiles) + { + xmlSettings.Schemas.Add("http://www.iec.ch/61850/2003/SCL", ProgramDirectory() + "\\IEC_61850-6.2018.SCL.2007A\\" + schemaName); + } + + } + } + else + { + foreach (string schemaName in schemaFiles) + { + + if (sclRelease == null) + { + xmlSettings.Schemas.Add("http://www.iec.ch/61850/2003/SCL", ProgramDirectory() + "\\IEC_61850-6.2009.SCL.2007B\\" + schemaName); + + } + else if (sclRelease == "4") + { + xmlSettings.Schemas.Add("http://www.iec.ch/61850/2003/SCL", ProgramDirectory() + "\\IEC_61850-6.2018.SCL.2007B4\\" + schemaName); + + } + + } + + } + + xmlSettings.Schemas.XmlResolver = new XmlUrlResolver(); + + xmlSettings.ValidationType = ValidationType.Schema; + + xmlSettings.ValidationEventHandler += new ValidationEventHandler(delegate (object sender, ValidationEventArgs e) + { + + if (e.Exception != null) + messages.Add(new SclValidatorMessage(e.Severity, e.Message, e.Exception.LineNumber, e.Exception.LinePosition)); + else + messages.Add(new SclValidatorMessage(e.Severity, e.Message)); + + + }); + + try + { + if (filename != null) + { + XmlReader scl = XmlReader.Create(filename, xmlSettings); + + while (scl.Read()) + { + } + + scl.Dispose(); + } + + } + catch (XmlSchemaValidationException e) + { + + if (e.SourceObject != null) + Console.WriteLine(e.SourceObject.ToString()); + + Console.WriteLine(e.Message); + + if (e.SourceSchemaObject != null) + Console.WriteLine(e.SourceSchemaObject.SourceUri); + + Console.WriteLine(e.LineNumber); + Console.WriteLine(e.SourceUri); + } + } + else + { + XmlDocument xmlDoc = sclDocument; + + xmlDoc.Schemas = new XmlSchemaSet(); + + if (header != null) + { + if (sclRevision == "B") + { + foreach (string schemaName in schemaFiles) + { + if (sclRelease == null) + xmlDoc.Schemas.Add("http://www.iec.ch/61850/2003/SCL", ProgramDirectory() + "\\IEC_61850-6.2009.SCL.2007B\\" + schemaName); + else if (sclRelease == "4") + xmlDoc.Schemas.Add("http://www.iec.ch/61850/2003/SCL", ProgramDirectory() + "\\IEC_61850-6.2018.SCL.2007B4\\" + schemaName); + } + + } + else + { + foreach (string schemaName in schemaFiles) + { + xmlDoc.Schemas.Add("http://www.iec.ch/61850/2003/SCL", ProgramDirectory() + "\\IEC_61850-6.2018.SCL.2007A\\" + schemaName); + + } + + } + } + else + { + foreach (string schemaName in schemaFiles) + { + if (sclRelease == null) + xmlDoc.Schemas.Add("http://www.iec.ch/61850/2003/SCL", ProgramDirectory() + "\\IEC_61850-6.2009.SCL.2007B\\" + schemaName); + else if (sclRelease == "4") + xmlDoc.Schemas.Add("http://www.iec.ch/61850/2003/SCL", ProgramDirectory() + "\\IEC_61850-6.2018.SCL.2007B4\\" + schemaName); + } + } + + xmlDoc.Validate(new ValidationEventHandler(delegate (object sender, ValidationEventArgs e) + { + if (e.Exception != null) + messages.Add(new SclValidatorMessage(e.Severity, e.Message, e.Exception.LineNumber, e.Exception.LinePosition)); + else + messages.Add(new SclValidatorMessage(e.Severity, e.Message)); + + })); + } + + + } + + public void AddIssue(XmlNode xmlNode, string Severity, string Type, string Issue, object Object, string ObjectIssue) + { + SclFileIssue sclFileIssue = new SclFileIssue(); + sclFileIssue.Issue = Issue; + sclFileIssue.Severity = Severity; + sclFileIssue.Type = Type; + sclFileIssue.Object = Object; + sclFileIssue.ObjectIssue = ObjectIssue; + + if (xmlNode != null) + { + PositionXmlElement positionXmlElement = GetXmlNodePosition(xmlNode); + if (positionXmlElement != null) + sclFileIssue.Line = positionXmlElement.LineNumber; + + } + + if (!sclFileIssues.Exists(x => x.Issue == sclFileIssue.Issue && x.Severity == sclFileIssue.Severity && x.Type == sclFileIssue.Type && x.Object == sclFileIssue.Object && + x.ObjectIssue == sclFileIssue.ObjectIssue && x.Line == sclFileIssue.Line)) + sclFileIssues.Add(sclFileIssue); + } + + public List SclFileIssues + { + get { return sclFileIssues; } + } + + public List ValidationMessages() + { + List validationMessages = new List(); + + messages = new List(); + + XmlDocValidation(); + + foreach (SclValidatorMessage msg in messages) + { + validationMessages.Add(new SclFileIssue() + { + Line = msg.LineNo, + Severity = msg.Level == System.Xml.Schema.XmlSeverityType.Error ? "ERROR" : "WARNING", + Type = "Schema", + Issue = msg.Message + }); + } + + return validationMessages; + + + } + + public XmlDocument XmlDocument + { + get + { + return sclDocument; + } + set + { + sclDocument = value; + } + } + + public List IEDs + { + get + { + return new List(ieds); + } + } + + public void CheckUsedDataTypes() + { + if (dataTypeTemplates != null) + MarkAllDataTypesAsUnused(); + + foreach (SclIED ied in ieds) + { + foreach (SclAccessPoint ap in ied.AccessPoints) + { + if (ap.Server != null) + { + IEDDataModel iedModel = GetDataModel(ied.Name, ap.Name); + + foreach (LogicalDevice ld in iedModel.LogicalDevices) + { + foreach (LogicalNode ln in ld.LogicalNodes) + { + if (dataTypeTemplates != null) + { + SclLNodeType sclLNodeType = dataTypeTemplates.LNTypes.Find(x => x.Id == ln.SclElement.LnType); + + CheckUsedEnumtypes(ln); + + if (sclLNodeType != null) + { + sclLNodeType.IsUsed = true; + if (!sclLNodeType.UsedOn.Contains(ln)) + sclLNodeType.UsedOn.Add(ln); + } + + foreach (DataObject dobj in ln.DataObjects) + { + CheckUsedDataObject(dobj); + } + } + + } + } + } + } + } + } + + private void CheckUsedEnumtypes(LogicalNode logicalNode) + { + foreach (SclDOI sclDOI_ in logicalNode.SclElement.DOIs) + { + CheckUsedPredefinedValuesEnumType(sclDOI_, logicalNode, null); + } + } + + private void CheckUsedPredefinedValuesEnumType(Object Object, LogicalNode logicalNode, SclDOI sclDOI_) + { + if (Object is SclDOI sclDOI) + { + if (sclDOI.SclDAIs.Count > 0) + { + foreach (SclDAI sclDAI in sclDOI.SclDAIs) + { + foreach (SclVal sclVal in sclDAI.GetValues()) + { + DataAttribute dataAttribute = GetDataAttribute(logicalNode, sclDOI, sclDAI); + if (dataAttribute != null) + { + if (sclVal.Value != null) + { + if (dataAttribute.Definition.AttributeType == AttributeType.ENUMERATED) + { + + string EnumType = dataAttribute.Definition.Type; + if (EnumType != null) + { + SclEnumType sclEnumType = DataTypeTemplates.GetEnumType(EnumType); + if (sclEnumType != null) + { + sclEnumType.IsUsed = true; + if (!sclEnumType.UsedOn.Contains(dataAttribute)) + sclEnumType.UsedOn.Add(dataAttribute); + } + } + } + } + } + } + } + + } + + if (sclDOI.SclSDIs.Count > 0) + { + foreach (SclSDI sclSDI in sclDOI.SclSDIs) + CheckUsedPredefinedValuesEnumType(sclSDI, logicalNode, sclDOI); + } + } + + else if (Object is SclSDI) + { + SclSDI sclSDI = Object as SclSDI; + + if (sclSDI.SclSDIs.Count > 0) + { + foreach (SclSDI sclSDI_ in sclSDI.SclSDIs) + CheckUsedPredefinedValuesEnumType(sclSDI_, logicalNode, sclDOI_); + } + } + } + + private void CheckUsedDataObject(DataObject dataObject) + { + SclDOType sclDOType = dataTypeTemplates.DOTypes.Find(x => x == dataObject.DOType); + + if (sclDOType != null) + { + sclDOType.IsUsed = true; + if (!sclDOType.UsedOn.Contains(dataObject)) + sclDOType.UsedOn.Add(dataObject); + + CheckUsedSubDataObjectsAndDataAttributes(sclDOType); + } + } + + private void CheckUsedSubDataObjectsAndDataAttributes(SclDOType type) + { + if (type.SubDataObjects != null) + { + foreach (SclDataObjectDefinition doDef in type.SubDataObjects) + { + SclDOType doType = DataTypeTemplates?.GetDOType(doDef.Type); + + if (doType != null) + { + doType.IsUsed = true; + + CheckUsedSubDataObjectsAndDataAttributes(doType); + + } + + } + } + + if (type.DataAttributes != null) + { + + foreach (SclDataAttributeDefinition daDef in type.DataAttributes) + { + if (daDef.AttributeType == AttributeType.CONSTRUCTED) + { + SclDAType daType = DataTypeTemplates?.GetDAType(daDef.Type); + + if (daType != null) + { + daType.IsUsed = true; + + CheckUsedSubDataAttributes(daDef.Fc, daType); + } + + + } + else if (daDef.AttributeType == AttributeType.ENUMERATED) + { + SclEnumType enumType = DataTypeTemplates?.GetEnumType(daDef.Type); + + if (enumType != null) + enumType.IsUsed = true; + } + } + + } + + } + + private void CheckUsedSubDataAttributes(SclFC fc, SclDAType daType) + { + foreach (SclDataAttributeDefinition daDef in daType.SubDataAttributes) + { + + SclFC newFc; + + if (daDef.Fc != SclFC.NONE) + newFc = daDef.Fc; + else + newFc = fc; + + + if (daDef.AttributeType == AttributeType.CONSTRUCTED) + { + SclDAType subDaType = DataTypeTemplates?.GetDAType(daDef.Type); + + if (subDaType != null) + { + subDaType.IsUsed = true; + + //CheckUsedSubDataAttributes(newFc, subDaType);// check this statement + } + + } + else + { + if (daDef.AttributeType == AttributeType.ENUMERATED) + { + SclEnumType enumType = DataTypeTemplates?.GetEnumType(daDef.Type); + + if (enumType == null) + enumType.IsUsed = true; + } + } + } + } + + private void MarkAllDataTypesAsUnused() + { + foreach (SclType type in dataTypeTemplates.AllTypes) + { + type.IsUsed = false; + type.UsedOn.Clear(); + } + } + + public SclDataTypeTemplates DataTypeTemplates + { + get + { + return dataTypeTemplates; + } + set + { + dataTypeTemplates = value; + } + } + + public void Remove(SclIED ied) + { + XmlNode parent = ied.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(ied.xmlNode); + } + + ieds.Remove(ied); + } + + public void RemoveSubstation(SclSubstation sclSubstation) + { + XmlNode parent = sclSubstation.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(sclSubstation.xmlNode); + } + + substations.Remove(sclSubstation); + } + + + public List Substations + { + get + { + return new List(substations); + } + } + + public void Remove(SclSubstation substation) + { + XmlNode parent = substation.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(substation.xmlNode); + } + + substations.Remove(substation); + } + + public bool HasDataTypeTemplates() => (dataTypeTemplates != null); + + public SclHeader Header + { + get + { + return header; + } + } + + public SclCommunication Communication + { + get + { + return communication; + } + } + + public string Filename + { + get + { + return filename; + } + set + { + filename = value; + } + + } + + public void Save(string filename) + { + if (filename != null) + { + sclDocument.Save(filename); + + changed = false; + } + + } + + private void ParseDataTypeTemplatesSection() + { + XmlNode dttNode = sclDocument.SelectSingleNode("//scl:DataTypeTemplates", nsManager); + + if (dttNode != null) + { + dataTypeTemplates = new SclDataTypeTemplates(this, dttNode); + } + } + + public SclHeader AddHeader() + { + if (header == null) + { + SclHeader newheader = new SclHeader(this, NsManager); + + XmlNode newNode = newheader.XmlNode; + + if (newNode.OwnerDocument != sclDocument) + { + newNode = sclDocument.ImportNode(newheader.XmlNode.CloneNode(true), true); + } + + if (substations.Count > 0) + { + XmlNode parent = substations[0].xmlNode.ParentNode; + + parent.InsertBefore(newNode, substations[0].xmlNode); + } + + else if (communication != null) + { + XmlNode parent = communication.xmlNode.ParentNode; + + parent.InsertAfter(newNode, communication.xmlNode); + } + + else if (ieds.Count > 0) + { + XmlNode parent = ieds[0].xmlNode.ParentNode; + + parent.InsertBefore(newNode, ieds[0].xmlNode); + } + + else if (dataTypeTemplates != null) + { + XmlNode parent = dataTypeTemplates.xmlNode.ParentNode; + + parent.InsertBefore(newNode, dataTypeTemplates.xmlNode); + } + + else + { + XmlNode parent = sclDocument.SelectSingleNode("//scl:SCL", nsManager); + parent.AppendChild(newNode); + + } + + try + { + header = new SclHeader(this, newNode, NsManager); + return header; + + } + catch (SclParserException e) + { + Console.WriteLine("Failed to add Header"); + Console.WriteLine(e.ToString()); + + return null; + } + } + else + return null; + } + + public bool DeleteHeader() + { + if (header != null) + { + XmlNode parent = header.XmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(header.XmlNode); + } + + header = null; + + return true; + } + + return false; + } + + public bool DeleteDataTypeTemplates() + { + if (dataTypeTemplates != null) + { + XmlNode parent = dataTypeTemplates.XmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(dataTypeTemplates.XmlNode); + } + + dataTypeTemplates = null; + + return true; + } + + return false; + } + + private void ParseIEDSections() + { + XmlNodeList iedNodes = sclDocument.SelectNodes("//scl:SCL/scl:IED", nsManager); + + if (iedNodes.Count < 1) + AddIssue(null, "ERROR", "Model integrity", "SCL contains no IED element", this, "IED"); + + foreach (XmlNode ied in iedNodes) + { + ieds.Add(new SclIED(this, ied, nsManager)); + } + + if (Communication != null) + { + List subNetworks = communication.GetSubNetworks(); + + if (subNetworks != null) + { + foreach (SclSubNetwork subnetwork in subNetworks) + { + List connectedAPs = subnetwork.GetConnectedAPs(); + + if (connectedAPs != null) + { + foreach (SclConnectedAP connectedAP in connectedAPs) + { + SclIED connectedAP_IED = ieds.Find(x => x.Name == connectedAP.IedName); + + if (connectedAP_IED == null) + { + AddIssue(connectedAP.xmlNode, "ERROR", "Model integrity", "IED " + connectedAP.IedName + " in ConnectedAP doesn't exist", this, "connectedAP"); + AddIssue(connectedAP.xmlNode, "ERROR", "Model integrity", "Access Point " + connectedAP.ApName + " in ConnectedAP doesn't exist", this, "connectedAP"); + } + else + { + if (connectedAP_IED.AccessPoints.Find(x => x.Name == connectedAP.ApName) == null) + { + AddIssue(connectedAP.xmlNode, "ERROR", "Model integrity", "Access Point " + connectedAP.ApName + " in ConnectedAP doesn't exist", this, "connectedAP"); + } + } + } + } + } + } + } + + } + + private void ParseSubstationSections() + { + XmlNodeList substationNodes = sclDocument.SelectNodes("//scl:SCL/scl:Substation", nsManager); + + foreach (XmlNode substationNode in substationNodes) + { + substations.Add(new SclSubstation(sclDocument, this, substationNode, nsManager)); + } + } + + private void ParseScl() + { + XmlNode sclVersion = sclDocument.SelectSingleNode("//scl:SCL", nsManager); + if (sclVersion != null) + { + this.sclVersion = XmlHelper.GetAttributeValue(sclVersion, "version"); + sclRevision = XmlHelper.GetAttributeValue(sclVersion, "revision"); + sclRelease = XmlHelper.GetAttributeValue(sclVersion, "release"); + + } + } + + private void ParseHeaderSection() + { + XmlNode headerNode = sclDocument.SelectSingleNode("//scl:Header", nsManager); + + if (headerNode == null) + AddIssue(null, "ERROR", "Model integrity", "Header is missing", this, "Header"); + else + header = new SclHeader(this, headerNode, nsManager); + } + + private void ParseCommunicationSection() + { + XmlNode communicationNode = sclDocument.SelectSingleNode("//scl:Communication", nsManager); + + if (communicationNode != null) + communication = new SclCommunication(communicationNode, this, nsManager); + } + + private void ParseDocument() + { + ieds = new List(); + substations = new List(); + header = null; + communication = null; + + ParseScl(); + + ParseHeaderSection(); + + ParseSubstationSections(); + + ParseCommunicationSection(); + + ParseDataTypeTemplatesSection(); + + ParseIEDSections(); + } + + /// + /// Rebuild the internal document structure by the DOM model + /// + public void Rebuild() + { + ParseDocument(); + } + + /// + /// Removes the "Private" elements from the SCL document. + /// + public void RemovePrivateElements() + { + XmlNodeList privateNodes = sclDocument.SelectNodes("//scl:Private", nsManager); + + foreach (XmlNode privateNode in privateNodes) + { + XmlNode parent = privateNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(privateNode); + } + } + } + + private void InitializeDocument() + { + nsManager = new XmlNamespaceManager(sclDocument.NameTable); + nsManager.AddNamespace("scl", SCL_XMLNS); + + ParseDocument(); + } + + public SclDocument(XmlDocument xmlDocument) + { + sclDocument = xmlDocument; + + InitializeDocument(); + } + + public SclDocument(string filePath) + { + Filename = filePath; + sclDocument = new XmlDocument(); + + sclDocument.Load(filePath); + + InitializeDocument(); + + sclDocument.NodeChanged += handler; + sclDocument.NodeInserted += handler; + sclDocument.NodeRemoved += handler; + } + + public List GetIedNames() + { + List iedNames = new List(); + + foreach (SclIED ied in ieds) + iedNames.Add(ied.Name); + + return iedNames; + } + + private SclIED GetIedByName(string iedName) + { + foreach (SclIED ied in ieds) + { + if (ied.Name.Equals(iedName)) + return ied; + } + + return null; + } + + private void AddSubDataAttributesToDataAttribute(DataAttribute da, SclFC fc, SclDAType daType) + { + foreach (SclDataAttributeDefinition daDef in daType.SubDataAttributes) + { + + SclFC newFc; + + if (daDef.Fc != SclFC.NONE) + newFc = daDef.Fc; + else + newFc = fc; + + DataAttribute subDataAttribute = new DataAttribute(daDef.Name, da, newFc, daDef.AttributeType, daDef.Count, daDef); + + if (daDef.AttributeType == AttributeType.CONSTRUCTED) + { + SclDAType subDaType = DataTypeTemplates?.GetDAType(daDef.Type); + + if (subDaType == null) + AddIssue(daDef.XmlNode, "ERROR", "Model integrity", "DAType \"" + daDef.Type + "\" of DA \"" + daDef.Name + "\" is not defined", this, "DAType"); + else + { + subDaType.IsUsed = true; + AddSubDataAttributesToDataAttribute(subDataAttribute, newFc, subDaType); + } + + } + else + { + if (daDef.AttributeType == AttributeType.ENUMERATED) + { + SclEnumType enumType = DataTypeTemplates?.GetEnumType(daDef.Type); + + if (enumType == null) + AddIssue(daDef.XmlNode, "ERROR", "Model integrity", "EnumType \"" + daDef.Type + "\" of DA \"" + daDef.Name + "\" is not defined", this, "EnumType"); + else + enumType.IsUsed = true; + } + } + + da.SubDataAttributes.Add(subDataAttribute); + } + } + + private void AddSubDataObjectsAndDataAttributesToDataObject(DataObject dataObject, SclDOType type) + { + + if (type.SubDataObjects != null) + { + foreach (SclDataObjectDefinition doDef in type.SubDataObjects) + { + + SclDOType doType = DataTypeTemplates?.GetDOType(doDef.Type); + + if (doType == null) + AddIssue(doDef.XmlNode, "ERROR", "Model integrity", "DOType \"" + doDef.Type + "\" of DO \"" + doDef.Name + "\" is not defined", this, "DOType"); + else + { + doType.IsUsed = true; + + DataObject subDataObject = new DataObject(doDef, doType, dataObject); + AddSubDataObjectsAndDataAttributesToDataObject(subDataObject, doType);// EXCEPTION WHEN ADDING NEW LN + + dataObject.DataObjectsAndAttributes.Add(subDataObject); + } + + } + } + + if (type.DataAttributes != null) + { + + foreach (SclDataAttributeDefinition daDef in type.DataAttributes) + { + + DataAttribute da = new DataAttribute(daDef.Name, dataObject, daDef.Fc, daDef.AttributeType, daDef.Count, daDef); + + if (daDef.AttributeType == AttributeType.CONSTRUCTED) + { + SclDAType daType = DataTypeTemplates?.GetDAType(daDef.Type); + + if (daType == null) + AddIssue(daDef.XmlNode, "ERROR", "Model integrity", "DAType \"" + daDef.Type + "\" of DA \"" + daDef.Name + "\" is not defined", this, "DAType"); + else + { + daType.IsUsed = true; + if (!da.ObjRef.EndsWith(daDef.Name + "." + daDef.Name)) + AddSubDataAttributesToDataAttribute(da, daDef.Fc, daType); + } + + + } + else if (daDef.AttributeType == AttributeType.ENUMERATED) + { + SclEnumType enumType = DataTypeTemplates?.GetEnumType(daDef.Type); + + if (enumType == null) + AddIssue(daDef.XmlNode, "ERROR", "Model integrity", "EnumType \"" + daDef.Type + "\" of DA \"" + daDef.Name + "\" is not defined", this, "EnumType"); + else + enumType.IsUsed = true; + } + + dataObject.DataObjectsAndAttributes.Add(da); + } + + } + + } + + public void AddDataObjectsToLogicalNode(LogicalNode logicalNode, SclLN ln) + { + SclLNodeType lnType = DataTypeTemplates?.GetLNodeType(ln.LnType); + + if (lnType == null) + AddIssue(ln.xmlNode, "ERROR", "Model integrity", "LNType \"" + ln.LnType + "\" of LN \"" + logicalNode.ObjRef + "\" is not defined", this, "LNType"); + else + { + lnType.IsUsed = true; + + if (logicalNode.DataObjects.Count > 0) + logicalNode.DataObjects.Clear(); + + foreach (SclDataObjectDefinition doDef in lnType.DataObjects) + { + + SclDOType doType = DataTypeTemplates?.GetDOType(doDef.Type); + + if (doType == null) + AddIssue(doDef.XmlNode, "ERROR", "Model integrity", "DOType \"" + doDef.Type + "\" of DO \"" + doDef.Name + "\" is not defined", this, "DOType"); + else + { + doType.IsUsed = true; + + DataObject dobject = new DataObject(doDef, doType, logicalNode); + AddSubDataObjectsAndDataAttributesToDataObject(dobject, doType); + + logicalNode.DataObjects.Add(dobject); + } + + + } + } + + + } + + private void AddLogicalNodesToLogicalDevice(LogicalDevice logicalDevice, SclLDevice lDevice) + { + if (lDevice.LogicalNodes != null) + { + foreach (SclLN ln in lDevice.LogicalNodes) + { + + LogicalNode logicalNode = new LogicalNode(ln, logicalDevice); + + AddDataObjectsToLogicalNode(logicalNode, ln); + + logicalDevice.LogicalNodes.Add(logicalNode); + + CheckIfControlExistForDOIandDAI(logicalNode); + + //CheckIfFcdaExistsOnDataTemplates(logicalNode); + + if (logicalNode.LnClass == "LLN0") + CheckIf_LLN0NamPltconfigRevExist(logicalNode); + + CheckDANameSpaces(logicalNode); + } + } + } + + private List NSDsNameSpace = new List() { "IEC_61850-7-4", "IEC_61850-7-4_2003", "IEC_61850-7-4_2007","IEC_61850-7-4_2007A", + "IEC_61850-7-4_2007B","IEC_61850-7-2_2007A3", "IEC_61850-7-2_2007B3", "IEC_61850-7-3_2007A3", "IEC_61850-7-3_2007B3", + "IEC_61850-7-4_2007A3", "IEC_61850-7-4_2007B3", "IEC_61850-7-420_2019A4", "IEC_61850-7-420_2019A", "IEC_61850-8-1_2003A2"}; + + private void CheckDANameSpaces(LogicalNode logicalNode) + { + string ldNsValue = null; + bool ldNsFound = false; + string lnn0NsValue = null; + bool lnn0Found = false; + string lnNsValue = null; + bool lnNsFound = false; + LogicalDevice logicalDevice = logicalNode.Parent as LogicalDevice; + + if (logicalNode.LnClass == "LLN0") + { + SclDOI sclDOI = logicalNode.SclElement.DOIs.Find(x => x.Name == "NamPlt"); + + if (sclDOI != null) + { + SclDAI sclDAIldNs = sclDOI.SclDAIs.Find(x => x.Name == "ldNs"); + + if (sclDAIldNs != null) + { + ldNsFound = true; + string value = sclDAIldNs.Val; + + if (value != null) + { + ldNsValue = value; + } + } + + SclDAI sclDAIlnNs = sclDOI.SclDAIs.Find(x => x.Name == "lnNs"); + + if (sclDAIlnNs != null) + { + lnn0Found = true; + string value = sclDAIlnNs.Val; + + if (value != null) + { + lnn0NsValue = value; + } + } + } + + if (ldNsValue == null) + { + DataObject dataObject = logicalNode.DataObjects.Find(x => x.Name == "NamPlt" && x.DOType.Cdc == "LPL"); + + if (dataObject != null) + { + SclDataAttributeDefinition daLdNs = dataObject.DOType.DataAttributes.Find(x => x.Name == "ldNs" && x.Fc == SclFC.EX); + + if (daLdNs != null) + { + ldNsFound = true; + SclVal sclVal = daLdNs.GetVal(); + if (sclVal != null) + { + ldNsValue = sclVal.Value; + } + + } + } + } + + if (ldNsValue != null) + { + try + { + logicalDevice.NameSpace = new Namespace(ldNsValue); + + if (!NSDsNameSpace.Contains(logicalDevice.NameSpace.NsdPath)) + { + logicalDevice.NameSpace.NsdPathFound = false; + AddIssue(logicalNode.SclElement.XmlNode, "WARNING", "Model integrity", "Namespace on " + logicalDevice.Name + "/" + logicalNode.Name + ".NamPlt.ldNs not found on NSD files. Value: " + ldNsValue, this, "LLN0.NamPlt.ldNs"); + } + } + catch (Exception) + { + AddIssue(logicalNode.SclElement.XmlNode, "WARNING", "Model integrity", "Namespace on " + logicalDevice.Name + "/" + logicalNode.Name + ".NamPlt.ldNs not found on NSD files. Value: " + ldNsValue, this, "LLN0.NamPlt.ldNs"); + } + } + + if (ldNsValue == null && ldNsFound) + { + AddIssue(logicalNode.SclElement.XmlNode, "ERROR", "Model integrity", "Namespace on " + logicalDevice.Name + "/" + logicalNode.Name + ".NamPlt.ldNs has no value", this, "LLN0.NamPlt.ldNs"); + } + + if (lnn0NsValue == null) + { + DataObject dataObject = logicalNode.DataObjects.Find(x => x.Name == "NamPlt" && x.DOType.Cdc == "LPL"); + + if (dataObject != null) + { + SclDataAttributeDefinition daLnNs = dataObject.DOType.DataAttributes.Find(x => x.Name == "lnNs" && x.Fc == SclFC.EX); + + if (daLnNs != null) + { + lnn0Found = true; + SclVal sclVal = daLnNs.GetVal(); + + if (sclVal != null) + { + lnn0NsValue = sclVal.Value; + } + + } + } + + + } + + if (lnn0NsValue != null) + { + try + { + + logicalNode.NameSpace = new Namespace(lnn0NsValue); + + if (!NSDsNameSpace.Contains(logicalNode.NameSpace.NsdPath)) + { + logicalNode.NameSpace.NsdPathFound = false; + + AddIssue(logicalNode.SclElement.XmlNode, "WARNING", "Model integrity", "Namespace on " + logicalDevice.Name + "/" + logicalNode.Name + ".NamPlt.lnNs not found on NSD files. Value: " + lnn0NsValue, this, "LLN0.NamPlt.lnNs"); + } + } + catch (Exception) + { + AddIssue(logicalNode.SclElement.XmlNode, "WARNING", "Model integrity", "Namespace on " + logicalDevice.Name + "/" + logicalNode.Name + ".NamPlt.lnNs not found on NSD files. Value: " + lnn0NsValue, this, "LLN0.NamPlt.lnNs"); + } + } + + if (lnn0NsValue == null && lnn0Found) + { + AddIssue(logicalNode.SclElement.XmlNode, "ERROR", "Model integrity", "Namespace on " + logicalDevice.Name + "/" + logicalNode.Name + ".NamPlt.lnNs has no value", this, "LLN0.NamPlt.lnNs"); + } + + + } + else + { + SclDOI sclDOI = logicalNode.SclElement.DOIs.Find(x => x.Name == "NamPlt"); + + if (sclDOI != null) + { + SclDAI sclDAIlnNs = sclDOI.SclDAIs.Find(x => x.Name == "lnNs"); + + if (sclDAIlnNs != null) + { + lnNsFound = true; + string value = sclDAIlnNs.Val; + + if (value != null) + { + lnNsValue = value; + } + } + } + + if (lnNsValue == null) + { + DataObject dataObject = logicalNode.DataObjects.Find(x => x.Name == "NamPlt" && x.DOType.Cdc == "LPL"); + + if (dataObject != null) + { + //Attribute for logical device basic namespace (LNName.NamPlt.lnNs) + SclDataAttributeDefinition daLnNs = dataObject.DOType.DataAttributes.Find(x => x.Name == "lnNs" && x.Fc == SclFC.EX); + + if (daLnNs != null) + { + lnNsFound = true; + SclVal sclVal = daLnNs.GetVal(); + + if (sclVal != null) + { + lnNsValue = sclVal.Value; + + } + } + } + } + + if (lnNsValue != null) + { + try + { + logicalNode.NameSpace = new Namespace(lnNsValue); + + if (!NSDsNameSpace.Contains(logicalNode.NameSpace.NsdPath)) + { + logicalNode.NameSpace.NsdPathFound = false; + + AddIssue(logicalNode.SclElement.XmlNode, "WARNING", "Model integrity", "Namespace on " + logicalDevice.Name + "/" + logicalNode.Name + ".NamPlt.lnNs not found on NSD files. Value: " + lnNsValue, this, "LLN0.NamPlt.lnNs"); + } + } + catch (Exception) + { + AddIssue(logicalNode.SclElement.XmlNode, "WARNING", "Model integrity", "Namespace on " + logicalDevice.Name + "/" + logicalNode.Name + ".NamPlt.lnNs not found on NSD files. Value: " + lnNsValue, this, "LLN0.NamPlt.lnNs"); + } + } + + if (lnNsValue == null && lnNsFound) + { + AddIssue(logicalNode.SclElement.XmlNode, "ERROR", "Model integrity", "Namespace on " + logicalDevice.Name + "/" + logicalNode.Name + ".NamPlt.lnNs has no value", this, "LLN0.NamPlt.ldNs"); + } + } + } + + private void CheckIf_LLN0NamPltconfigRevExist(LogicalNode LLNO) + { + bool LLN0NamPltconfigRev = false; + DataObject dataObject = LLNO.DataObjects.Find(x => x.Name == "NamPlt"); + if (dataObject != null) + { + SclDataAttributeDefinition da = dataObject.DOType.DataAttributes.Find(x => x.Name == "configRev"); + if (da != null) + { + LLN0NamPltconfigRev = true; + + if (da.GetVal() != null) + { + LogicalDevice logicalDevice = LLNO.Parent as LogicalDevice; + AddIssue(LLNO.SclElement.XmlNode, "ERROR", "Model integrity", "DataAttribute LLN0.NamPlt.configRev found on LD " + logicalDevice.Inst + " but has not value", this, "LLN0.NamPlt.configRev"); + } + else + { + LLN0NamPltconfigRev = true; + } + } + } + + if (!LLN0NamPltconfigRev) + { + SclDOI sclDOI = LLNO.SclElement.DOIs.Find(x => x.Name == "NamPlt"); + if (sclDOI != null) + { + SclDAI sclDAI = sclDOI.SclDAIs.Find(x => x.Name == "configRev"); + if (sclDAI != null) + { + LLN0NamPltconfigRev = true; + + if (sclDAI.Val == null) + { + LogicalDevice logicalDevice = LLNO.Parent as LogicalDevice; + AddIssue(LLNO.SclElement.XmlNode, "ERROR", "Model integrity", "DAI LLN0.NamPlt.configRev found on LD " + logicalDevice.Inst + " but has not value", this, "LLN0.NamPlt.configRev"); + + } + + + } + } + } + + if (!LLN0NamPltconfigRev) + { + LogicalDevice logicalDevice = LLNO.Parent as LogicalDevice; + AddIssue(LLNO.SclElement.XmlNode, "ERROR", "Model integrity", "DA or DAI LLN0.NamPlt.configRev not found on LD " + logicalDevice.Inst, this, "LLN0.NamPlt.configRev"); + + } + } + + private void CheckIfFcdaExistsOnDataTemplates(LogicalNode logicalNode) + { + try + { + foreach (DataSet dataSet in logicalNode.DataSets) + { + foreach (SclFCDA sclFCDA in dataSet.SclDataSet.Fcdas) + { + LogicalDevice logicalDevice = logicalNode.Parent as LogicalDevice; + IEDDataModel iEDDataModel = logicalDevice.Parent as IEDDataModel; + LogicalDevice fcdaLD = iEDDataModel.LogicalDevices.Find(x => x.Inst == sclFCDA.LdInst); + + if (fcdaLD == null) + { + AddIssue(sclFCDA.xmlNode, "ERROR", "Model integrity", "FCDA " + sclFCDA.GetObjectReference() + " on DataSet " + dataSet.ObjRef + " not found on data type templates", this, "FCDA"); + break; + } + + string lnName = ""; + if (sclFCDA.Prefix != null) + lnName += sclFCDA.Prefix; + if (sclFCDA.LnClass != null) + lnName += sclFCDA.LnClass; + if (sclFCDA.LnInst != null) + lnName += sclFCDA.LnInst; + + LogicalNode fcdaLN = fcdaLD.LogicalNodes.Find(x => x.Name == lnName); + if (fcdaLN == null) + { + AddIssue(sclFCDA.xmlNode, "ERROR", "Model integrity", "FCDA " + sclFCDA.GetObjectReference() + " on DataSet " + dataSet.ObjRef + " not found on data type templates", this, "FCDA"); + break; + } + + SclLNodeType sclLNodeType = dataTypeTemplates.GetLNodeType(fcdaLN.SclElement.LnType); + + if (sclLNodeType != null) + { + + SclDataObjectDefinition dataObject = sclLNodeType.DataObjects.Find(x => x.Name == sclFCDA.DoName); + + if (dataObject == null) + { + AddIssue(sclFCDA.xmlNode, "ERROR", "Model integrity", "FCDA " + sclFCDA.GetObjectReference() + " on DataSet " + dataSet.ObjRef + " not found on data type templates", this, "FCDA"); + } + else + { + SclDOType sclDoType = dataTypeTemplates.GetDOType(dataObject.Type); + + if (sclDoType == null) + { + AddIssue(sclFCDA.xmlNode, "ERROR", "Model integrity", "FCDA " + sclFCDA.GetObjectReference() + " on DataSet " + dataSet.ObjRef + " not found on data type templates", this, "FCDA"); + } + + else + { + if (sclFCDA.DaName != null) + { + + SclDataAttributeDefinition sclDataAttributeDefinition = GetSclDataAttributeDefinition(sclDoType, sclFCDA.DaName); + //SclDataAttributeDefinition sclDataAttributeDefinition = sclDoType.DataAttributes.Find(x => x.Name == sclFCDA.DaName); + + if (sclDataAttributeDefinition == null) + { + AddIssue(sclFCDA.xmlNode, "ERROR", "Model integrity", "FCDA " + sclFCDA.GetObjectReference() + " on DataSet " + dataSet.ObjRef + " not found on data type templates", this, "FCDA"); + + } + + } + + } + + } + } + else + { + AddIssue(sclFCDA.xmlNode, "ERROR", "Model integrity", "FCDA " + sclFCDA.GetObjectReference() + " on DataSet " + dataSet.ObjRef + " not found on data type templates", this, "FCDA"); + + } + + } + } + + + } + catch (Exception) + { + + } + + } + + private SclDataAttributeDefinition GetSclDataAttributeDefinition(object parent, string name) + { + + SclDataAttributeDefinition sclDataAttributeDefinition = null; + int index = name.IndexOf("."); + + if (index > 0) + { + string ParentName = name.Substring(0, index); + + SclDataAttributeDefinition parentDA; + if (parent is SclDOType doType) + { + parentDA = doType.DataAttributes.Find(x => x.Name == ParentName); + } + else + { + parentDA = (parent as SclDAType).SubDataAttributes.Find(x => x.Name == ParentName); + } + + SclDAType daType = dataTypeTemplates.GetDAType(parentDA.Type); + + string daName = name.Substring(index + 1); + + return GetSclDataAttributeDefinition(daType, daName); + } + else + { + if (parent is SclDOType doType) + { + sclDataAttributeDefinition = doType.DataAttributes.Find(x => x.Name == name); + } + else + { + sclDataAttributeDefinition = (parent as SclDAType).SubDataAttributes.Find(x => x.Name == name); + } + + + } + + return sclDataAttributeDefinition; + } + + private void CheckIfControlExistForDOIandDAI(LogicalNode logicalNode) + { + foreach (SclDOI sclDOI_ in logicalNode.SclElement.DOIs) + CheckPredefinedValuesExiste(sclDOI_, logicalNode, null, null, null); + } + + private DataAttribute GetDataAttribute(LogicalNode logicalNode, SclDOI sclDOI, SclDAI sclDAI) + { + DataAttribute dataAttribute = null; + foreach (DataObject dataObject in logicalNode.DataObjects) + { + if (dataObject.Name == sclDOI.Name) + { + foreach (DataAttribute dataAttribute_ in GetDataAttribute(dataObject)) + { + if (dataAttribute_.Name == sclDAI.Name) + { + dataAttribute = dataAttribute_; + break; + } + + } + break; + } + } + + return dataAttribute; + } + + private List GetDataAttribute(object Object) + { + List dataAttributes = new List(); + + if (Object is DataObject) + { + DataObject dataObject = Object as DataObject; + + foreach (DataObjectOrAttribute DataObjectOrAttribute in dataObject.DataObjectsAndAttributes) + { + foreach (DataAttribute attribute in GetDataAttribute(DataObjectOrAttribute)) + dataAttributes.Add(attribute); + } + + } + else + { + DataAttribute dataAttribute_ = Object as DataAttribute; + + if (dataAttribute_.SubDataAttributes != null) + { + foreach (DataAttribute subDataAttribute in dataAttribute_.SubDataAttributes) + { + foreach (DataAttribute attribute in GetDataAttribute(subDataAttribute)) + dataAttributes.Add(attribute); + } + } + else + dataAttributes.Add(dataAttribute_); + } + + return dataAttributes; + } + + private readonly List attributeTypeVisibleString = new List + { + AttributeType.VISIBLE_STRING_32, AttributeType.VISIBLE_STRING_64, + AttributeType.VISIBLE_STRING_65,AttributeType.VISIBLE_STRING_129,AttributeType.VISIBLE_STRING_255 + }; + + private readonly List attributeTypeInteger = new List + { + AttributeType.INT8, AttributeType.INT16, + AttributeType.INT32, AttributeType.INT64, AttributeType.INT8U, AttributeType.INT16U, AttributeType.INT24U, AttributeType.INT32U + }; + + private readonly List attributeTypeFloat = new List + { + AttributeType.FLOAT32, + AttributeType.FLOAT64 + }; + + public bool IsBase64String(string value) + { + if (value == null || value.Length == 0 || value.Length % 4 != 0 + || value.Contains(' ') || value.Contains('\t') || value.Contains('\r') || value.Contains('\n')) + return false; + + var index = value.Length - 1; + + if (value[index] == '=') + index--; + if (value[index] == '=') + index--; + + for (var i = 0; i <= index; i++) + if (IsInvalid(value[i])) + return false; + return true; + } + + private bool IsInvalid(char value) + { + var intValue = (Int32)value; + if (intValue >= 48 && intValue <= 57) + return false; + if (intValue >= 65 && intValue <= 90) + return false; + if (intValue >= 97 && intValue <= 122) + return false; + return intValue != 43 && intValue != 47; + } + + private bool CheckValidDaiValue(string value, AttributeType attributeType) + { + if (attributeTypeInteger.Contains(attributeType) || attributeTypeFloat.Contains(attributeType)) + { + if (attributeType == AttributeType.INT8) + { + if (int.TryParse(value, out int i)) + { + if (i >= -128 && i <= 127) + return true; + else + return false; + } + else + return false; + } + else if (attributeType == AttributeType.INT16) + { + return Int16.TryParse(value, out Int16 i); + } + else if (attributeType == AttributeType.INT32) + { + return Int32.TryParse(value, out Int32 i); + } + else if (attributeType == AttributeType.INT64) + { + return Int64.TryParse(value, out Int64 i); + } + else if (attributeType == AttributeType.INT8U) + { + if (int.TryParse(value, out int i)) + { + if (i >= 0 && i <= 255) + return true; + else + return false; + } + else + return false; + + } + else if (attributeType == AttributeType.INT16U) + { + return UInt16.TryParse(value, out UInt16 i); + } + else if (attributeType == AttributeType.INT32U) + { + return UInt32.TryParse(value, out UInt32 i); + } + else if (attributeType == AttributeType.FLOAT32 || attributeType == AttributeType.FLOAT64) + { + return float.TryParse(value, out float i); + } + else + return false; + + } + + else + { + if (attributeType == AttributeType.OCTET_STRING_64) + { + return IsBase64String(value); + } + else + return true; + + } + } + + + private void CheckPredefinedValuesExiste(Object Object, LogicalNode logicalNode, SclDOI sclDOI_, string sclSdiNames, DataObject dataObject) + { + if (Object is SclDOI sclDOI) + { + if (sclDOI.SclDAIs.Count > 0) + { + foreach (SclDAI sclDAI in sclDOI.SclDAIs) + { + foreach (SclVal sclVal in sclDAI.GetValues()) + { + DataAttribute dataAttribute = GetDataAttribute(logicalNode, sclDOI, sclDAI); + if (dataAttribute != null) + { + if (sclVal.Value != null) + { + if (dataAttribute.Definition.AttributeType == AttributeType.ENUMERATED) + { + + string EnumType = dataAttribute.Definition.Type; + if (EnumType != null) + { + SclEnumType sclEnumType = DataTypeTemplates.GetEnumType(EnumType); + if (sclEnumType != null) + { + if (!sclEnumType.EnumValues.Exists(x => x.SymbolicName == sclVal.Value)) + { + AddIssue(sclDAI.Node, "ERROR", "Model integrity", "Value " + sclVal.Value + " in DAI " + dataAttribute.ObjRef + + " does not exist in enumerated type " + EnumType + ". Reload the file after fixing the problem!", this, "DAI_DataAttributeMissing"); + + } + } + else + { + AddIssue(sclDAI.Node, "ERROR", "Model integrity", "Wrong ENUMERATED type " + EnumType + " in DAI " + dataAttribute.ObjRef + , this, "DAI_DataAttributeMissing"); + } + + } + else + { + AddIssue(sclDAI.Node, "ERROR", "Model integrity", "Wrong ENUMERATED type in DAI " + dataAttribute.ObjRef, this, "DAI_DataAttributeMissing"); + } + + } + else if (attributeTypeInteger.Contains(dataAttribute.Definition.AttributeType) || + attributeTypeFloat.Contains(dataAttribute.Definition.AttributeType) || dataAttribute.Definition.AttributeType == AttributeType.OCTET_STRING_64) + { + if (!CheckValidDaiValue(sclVal.Value, dataAttribute.Definition.AttributeType)) + { + AddIssue(sclDAI.Node, "ERROR", "Model integrity", "Value " + sclVal.Value + " in DAI " + dataAttribute.ObjRef + + " wrong for attribute type " + dataAttribute.Definition.AttributeType.ToString() + ". Reload the file after fixing the problem!", this, "DAI_DataAttributeMissing"); + + } + + } + + } + + + + } + else + { + AddIssue(sclDAI.Node, "ERROR", "Model integrity", "There is no DataAttribute definition for DAI " + sclDAI.Name + " on LogicalNode " + logicalNode.ObjRef, this, "DAI_DataAttributeMissing"); + } + } + } + + } + + if (sclDOI.SclSDIs.Count > 0) + { + foreach (SclSDI sclSDI in sclDOI.SclSDIs) + CheckPredefinedValuesExiste(sclSDI, logicalNode, sclDOI, null, dataObject); + } + } + + else if (Object is SclSDI) + { + SclSDI sclSDI = Object as SclSDI; + string name = null; + + if (sclSdiNames != null) + { + name = sclSdiNames + "." + sclSDI.Name; + + if (sclSDI.Ix != null) + name += "[" + sclSDI.Ix + "]"; + } + + else + { + name = sclSDI.Name; + + if (sclSDI.Ix != null) + name += "[" + sclSDI.Ix + "]"; + } + + if (sclSDI.SclDAIs.Count > 0) + { + foreach (SclDAI sclDAI in sclSDI.SclDAIs) + { + foreach (SclVal sclVal in sclDAI.GetValues()) + { + DataAttribute dataAttribute = GetDataAttribute(logicalNode, sclDOI_, sclDAI); + if (dataAttribute != null) + { + //TODO check if values is correct + } + else + { + AddIssue(sclDAI.Node, "ERROR", "Model integrity", "There is no SubDataAttribute for DAI " + name + " on LogicalNode " + logicalNode.ObjRef, this, "DAI_DataAttributeMissing"); + } + } + + + } + + } + + if (sclSDI.SclSDIs.Count > 0) + { + foreach (SclSDI sclSDI_ in sclSDI.SclSDIs) + CheckPredefinedValuesExiste(sclSDI_, logicalNode, sclDOI_, name, dataObject); + } + } + } + + + + private IEDDataModel CreateDataModel(string iedName, SclAccessPoint ap) + { + IEDDataModel dataModel = null; + + SclServer server = ap.Server; + + dataModel = new IEDDataModel(iedName); + + if (server != null) + { + List lDevices = server.LogicalDevices; + + if (lDevices != null) + { + foreach (SclLDevice lDevice in lDevices) + { + string ldName = lDevice.LdName; + + if (ldName == null) + ldName = iedName + lDevice.Inst; + + LogicalDevice logicalDevice = new LogicalDevice(this, lDevice, ldName, lDevice.Inst, dataModel); + + AddLogicalNodesToLogicalDevice(logicalDevice, lDevice); + + dataModel.LogicalDevices.Add(logicalDevice); + } + } + + } + + return dataModel; + } + + public IEDDataModel GetDataModel(string iedName, string accessPointName) + { + IEDDataModel dataModel = null; + + if (iedName != null) + { + SclIED ied = GetIedByName(iedName); + + if (ied != null) + { + foreach (SclAccessPoint ap in ied.AccessPoints) + { + + if ((accessPointName == null) || ap.Name.Equals(accessPointName)) + { + dataModel = CreateDataModel(iedName, ap); + + if (dataModel != null) + { + foreach (LogicalDevice logicalDevice in dataModel.LogicalDevices) + { + foreach (LogicalNode logicalNode in logicalDevice.LogicalNodes) + CheckIfFcdaExistsOnDataTemplates(logicalNode); + } + } + + break; + } + } + } + } + + + return dataModel; + } + + public SclConnectedAP GetConnectedAP(string apName, string iedName) + { + if (Communication != null) + return communication.GetConnectedAP(apName, iedName); + else + return null; + } + } + + public class PositionXmlDocument : XmlDocument + { + IXmlLineInfo lineInfo; // a reference to the XmlReader, only set during load time + + /// + /// Creates a PositionXmlElement. + /// + public override XmlElement CreateElement(string prefix, string localName, string namespaceURI) + { + return new PositionXmlElement(prefix, localName, namespaceURI, this, lineInfo); + } + + /// + /// Loads the XML document from the specified . + /// + public override void Load(XmlReader reader) + { + lineInfo = reader as IXmlLineInfo; + try + { + base.Load(reader); + } + finally + { + lineInfo = null; + } + } + } + + public class PositionXmlElement : XmlElement, IXmlLineInfo + { + internal PositionXmlElement(string prefix, string localName, string namespaceURI, XmlDocument doc, IXmlLineInfo lineInfo) + : base(prefix, localName, namespaceURI, doc) + { + if (lineInfo != null) + { + lineNumber = lineInfo.LineNumber; + linePosition = lineInfo.LinePosition; + hasLineInfo = true; + } + } + + int lineNumber; + int linePosition; + bool hasLineInfo; + + /// + /// Gets whether the element has line information. + /// + public bool HasLineInfo() + { + return hasLineInfo; + } + + /// + /// Gets the line number. + /// + public int LineNumber + { + get { return lineNumber; } + } + + /// + /// Gets the line position (column). + /// + public int LinePosition + { + get { return linePosition; } + } + } + + public class Namespace + { + private string namespaceIdentifier = null; + private string version = null; + private string revision = null; + private string release = null; + private string nsdPath = null; + private bool nsdPathFound = true; + + public Namespace(string fullNamespaceName) + { + try + { + string namespaceIdentifier_ = null; + string version_ = null; + string revision_ = null; + string release_ = null; + string nsdPath_ = null; + + if (fullNamespaceName != null) + { + int index = fullNamespaceName.IndexOf(":"); + + if (index != -1) + { + namespaceIdentifier_ = fullNamespaceName.Substring(0, index); + + version_ = fullNamespaceName.Substring(index + 1, 4); + + if ((index + 5) < fullNamespaceName.Length) + revision_ = fullNamespaceName.Substring(index + 5, 1); + + if (revision_ == null) + revision_ = "A"; + + if ((index + 6) < fullNamespaceName.Length) + release_ = fullNamespaceName.Substring(index + 6, fullNamespaceName.Length - index - 6); + + nsdPath_ = fullNamespaceName.Replace(" ", "_"); + nsdPath_ = nsdPath_.Replace(":", "_"); + } + + if (namespaceIdentifier_ != null) + namespaceIdentifier = namespaceIdentifier_; + + if (version_ != null) + version = version_; + + if (revision_ != null) + revision = revision_; + + if (release_ != null) + release = release_; + + if (nsdPath_ != null) + nsdPath = nsdPath_; + + } + } + catch (Exception) + { + + } + + + } + + public Namespace() + { + + } + + public string NamespaceIdentifier { get => namespaceIdentifier; set => namespaceIdentifier = value; } + public string Version { get => version; set => version = value; } + public string Revision { get => revision; set => revision = value; } + public string Release { get => release; set => release = value; } + public string NsdPath { get => nsdPath; set => nsdPath = value; } + public bool NsdPathFound { get => nsdPathFound; set => nsdPathFound = value; } + } + +} + diff --git a/tools/model_generator_dotnet/SCLParser/src/SclElementWithPrivate.cs b/tools/model_generator_dotnet/SCLParser/src/SclElementWithPrivate.cs new file mode 100644 index 00000000..54721775 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclElementWithPrivate.cs @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System.Collections.Generic; +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclElementWithPrivate : SclBaseElement + { + private List privateElements = new List(); + + internal SclElementWithPrivate(SclDocument sclDocument, XmlNode xmlNode) + : base(sclDocument.XmlDocument, sclDocument, xmlNode) + { + + XmlNodeList privateNodes = xmlNode.SelectNodes("Private"); + + foreach (XmlNode privateNode in privateNodes) + { + SclPrivate priv = new SclPrivate(sclDocument.XmlDocument, sclDocument, privateNode); + + if (priv != null) + { + privateElements.Add(priv); + } + } + } + + public List PrivateElements + { + get + { + return new List(privateElements); + } + } + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclElements.cs b/tools/model_generator_dotnet/SCLParser/src/SclElements.cs new file mode 100644 index 00000000..64a47e9d --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclElements.cs @@ -0,0 +1,2568 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using IEC61850.SCL.DataModel; +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; +using System.Xml; + +namespace IEC61850.SCL +{ + + public class NodeExtraAttributes + { + private string name; + private string value; + + public NodeExtraAttributes(string name, string value) + { + Name = name; + Value = value; + + } + + public string Name { get => name; set => name = value; } + public string Value { get => value; set => this.value = value; } + } + public class SclIED + { + private List accessPoints = new List(); + private SclServices sclServices; + private XmlDocument xmlDocument; + private SclDocument sclDocument; + private XmlNamespaceManager nsManager; + public List NodeExtraAttributes = new List(); + + + internal XmlNode xmlNode; + + public SclServices SclServices + { + get + { + return sclServices; + } + + set + { + sclServices = value; + } + } + + public string OriginalSclRevision + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "originalSclRevision"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "originalSclRevision", value); + } + } + + public string OriginalSclVersion + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "originalSclVersion"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "originalSclVersion", value); + } + } + + public string OriginalSclRelease + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "originalSclRelease"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "originalSclRelease", value); + } + } + + public string EngRight + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "engRight"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "engRight", value); + } + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", value); + } + } + + public string Type + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "type", value); + } + } + + public string Manufacturer + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "manufacturer"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "manufacturer", value); + } + } + + public string ConfigVersion + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "configVersion"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "configVersion", value); + } + } + + public string Owner + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "owner"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "owner", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + public List AccessPoints + { + get + { + + if (accessPoints == null) + accessPoints = new List(); + + return accessPoints; + } + } + + public static bool CheckIEDName(string iedName) + { + + bool isValid = true; + + // 1.) Starting with alpha char + + // 2.) only alphanumeric chars and underscore + + // 3.) maximum 64 characters + if (iedName.Length > 64 || !Regex.IsMatch(iedName[0].ToString(), @"^[a-zA-Z]")) + isValid = false; + + return isValid; + } + + public bool DeleteAccessPoint(string name) + { + if (name != null) + { + SclAccessPoint sclAccessPoint = accessPoints.Find(x => x.Name == name); + + if (sclAccessPoint != null) + { + accessPoints.Remove(sclAccessPoint); + + xmlNode.RemoveChild(sclAccessPoint.XmlNode); + + return true; + + } + + } + + return false; + + } + + public bool DeleteServices() + { + if (sclServices != null) + { + xmlNode.RemoveChild(sclServices.XmlNode); + sclServices = null; + + return true; + + } + + return false; + + } + + public SclIED(SclDocument SclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.xmlNode = xmlNode; + xmlDocument = SclDocument.XmlDocument; + sclDocument = SclDocument; + this.nsManager = nsManager; + + if (xmlNode.Attributes != null) + { + foreach (XmlAttribute xmlAttribute in xmlNode.Attributes) + { + if (xmlAttribute.Name != "name" && xmlAttribute.Name != "desc" && + xmlAttribute.Name != "type" && + xmlAttribute.Name != "manufacturer" && xmlAttribute.Name != "configVersion" && + xmlAttribute.Name != "originalSclVersion" + && xmlAttribute.Name != "originalSclRevision" + && xmlAttribute.Name != "originalSclRelease" + && xmlAttribute.Name != "engRight" + && xmlAttribute.Name != "owner") + { + NodeExtraAttributes.Add(new SCL.NodeExtraAttributes(xmlAttribute.Name, xmlAttribute.Value)); + } + } + } + + if (Name == null) + { + SclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No name attribute!", this, "MissingName"); + } + else + { + if (CheckIEDName(Name) == false) + SclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "Invalid IED name \"" + Name + "\"", this, "InvalidName"); + } + + XmlNodeList apNodes = xmlNode.SelectNodes("scl:AccessPoint", nsManager); + + if (apNodes.Count < 1) + { + //accessPoints = null; + SclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No AccessPoint in IED \"" + Name + "\"", this, "accessPoint"); + } + + foreach (XmlNode apNode in apNodes) + { + accessPoints.Add(new SclAccessPoint(SclDocument, apNode, nsManager)); + } + + XmlNode serviceNode = xmlNode.SelectSingleNode("scl:Services", nsManager); + if (serviceNode == null) + { + sclServices = null; + + if (accessPoints != null) + { + if (!accessPoints.Exists(x => x.SclServices != null)) + SclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No Services in IED \"" + Name + "\"", this, "service"); + + } + //SclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No Service in IED \"" + Name + "\"", this, "service"); + } + else + { + sclServices = new SclServices(SclDocument, serviceNode, nsManager); + } + + + if (AccessPoints != null) + { + foreach (SclAccessPoint ap in AccessPoints) + { + if (ap.ServerAt != null) + { + bool serverAtExists = false; + foreach (SclAccessPoint apCheck in AccessPoints) + { + if (apCheck.Name == ap.ServerAt.ApName) + { + serverAtExists = true; + } + } + + if (serverAtExists == false) + { + XmlNode serverAtNode = ap.ServerAt.XmlNode; + SclDocument.AddIssue(serverAtNode, "ERROR", "Model integrity", "Referenced Access Point " + ap.ServerAt.ApName + " does not exist", this, "accessPoint"); + } + } + } + + } + + } + + } + + public class SclAccessPoint + { + private SclServer server = null; + private SclServices sclServices = null; + private SclServerAt serverAt = null; + private XmlDocument xmlDocument; + private List logicalNodes = new List(); + private XmlNode xmlNode; + private SclDocument sclDocument; + private XmlNamespaceManager nsManager; + + public XmlNode XmlNode + { + get + { + return xmlNode; + } + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + public string Router + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "router"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "router", value); + } + } + + public string Clock + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "clock"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "clock", value); + } + } + + public List LogicalNodes + { + get + { + return logicalNodes; + } + } + + public SclServer Server + { + get + { + return server; + } + } + + public SclServerAt ServerAt + { + get + { + return serverAt; + } + } + + public SclServices SclServices + { + get + { + return sclServices; + } + } + + public bool DeleteServices() + { + if (sclServices != null) + { + xmlNode.RemoveChild(sclServices.XmlNode); + sclServices = null; + + return true; + + } + + return false; + + } + + public SclAccessPoint(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + xmlDocument = SclxmlDocument.XmlDocument; + this.xmlNode = xmlNode; + sclDocument = SclxmlDocument; + this.nsManager = nsManager; + bool serverInFile = false; + bool serverAtInFile = false; + bool LNodesInFile = false; + + XmlAttribute nameAttr = xmlNode.Attributes["name"]; + + if (nameAttr == null) + { + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No name attribute", this, "MissingName"); + } + + XmlNode serviceNode = xmlNode.SelectSingleNode("scl:Services", nsManager); + if (serviceNode == null) + { + sclServices = null; + } + else + { + sclServices = new SclServices(sclDocument, serviceNode, nsManager); + } + + + XmlNode serverNode = xmlNode.SelectSingleNode("scl:Server", nsManager); + + if (serverNode != null) + { + server = new SclServer(SclxmlDocument, serverNode, nsManager); + serverInFile = true; + } + else + { + server = null; + } + + XmlNode serverAtNode = xmlNode.SelectSingleNode("scl:ServerAt", nsManager); + + if (serverAtNode != null) + { + serverAt = new SclServerAt(SclxmlDocument, serverAtNode, nsManager); + serverAtInFile = true; + } + else + { + serverAt = null; + } + + XmlNodeList lnNodes = xmlNode.SelectNodes("scl:LN", nsManager); + + if (lnNodes != null) + { + foreach (XmlNode lnNode in lnNodes) + logicalNodes.Add(new SclLN(SclxmlDocument, lnNode, nsManager)); + + if (lnNodes.Count > 0) + LNodesInFile = true; + } + else + { + logicalNodes = null; + } + + if ((serverInFile == true && serverAtInFile == true) || (serverInFile == true && LNodesInFile == true) || (serverAtInFile == true && LNodesInFile == true)) + { + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "Access point contains more than one server description", this, "server"); + } + } + + } + + public class SclServer + { + private SclAuthentication authentication = null; + private List logicalDevices = new List(); + private XmlDocument xmlDocument; + private SclDocument sclDocument; + private XmlNode xmlNode; + private XmlNamespaceManager nsManager; + + public SclAuthentication Authentication + { + get + { + return authentication; + } + set + { + authentication = value; + + } + } + + public List LogicalDevices + { + get + { + return logicalDevices; + } + } + + public XmlNode XmlNode + { + get + { + return xmlNode; + } + } + + public void DeleteLogicalDevice(SclLDevice sclLD) + { + xmlNode.RemoveChild(sclLD.XmlNode); + + logicalDevices.Remove(sclLD); + } + + public SclServer(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + xmlDocument = SclxmlDocument.XmlDocument; + sclDocument = SclxmlDocument; + this.xmlNode = xmlNode; + this.nsManager = nsManager; + + XmlNode authNode = xmlNode.SelectSingleNode("scl:Authentication", nsManager); + + if (authNode == null) + { + authentication = null; + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "Server has no Authentication", this, "authentication"); + } + + if (authNode != null) + authentication = new SclAuthentication(authNode, nsManager); + + XmlNodeList ldNodes = xmlNode.SelectNodes("scl:LDevice", nsManager); + + if (ldNodes.Count < 1) + { + //logicalDevices = null; + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "Server has no LDevice", this, "lDevice"); + } + + foreach (XmlNode ldNode in ldNodes) + logicalDevices.Add(new SclLDevice(SclxmlDocument, ldNode, nsManager)); + } + + } + + public class SclServerAt + { + private XmlDocument xmlDocument; + private string apName; + public XmlNode XmlNode; + private SclDocument sclDocument; + private XmlNamespaceManager nsManager; + + public string ApName + { + get { return XmlHelper.GetAttributeValue(XmlNode, "apName"); } + + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, XmlNode, "apName", value); } + } + + public SclServerAt(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + xmlDocument = SclxmlDocument.XmlDocument; + XmlNode = xmlNode; + + XmlAttribute apNameAttr = xmlNode.Attributes["apName"]; + + if (apNameAttr == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No apName attribute in ServerAt", this, "MissingApName"); + + } + + } + + + public class SclAuthentication + { + + public SclAuthentication(XmlNode xmlNode, XmlNamespaceManager nsManager) + { + } + } + + public class SclLDevice + { + private string inst; + private string ldName = null; + private string desc = null; + private List logicalNodes = new List(); + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + private XmlNamespaceManager nsManager; + + + public XmlNode XmlNode + { + get + { + return xmlNode; + } + } + + public void DeleteLogicalNode(SclLN sclLN) + { + xmlNode.RemoveChild(sclLN.xmlNode); + + logicalNodes.Remove(sclLN); + } + + public bool AddLogicalNodeOnLntargetIndex(SclLN sourceSclLN, SclLN targetSclLn) + { + try + { + logicalNodes.Remove(sourceSclLN); + logicalNodes.Insert(logicalNodes.IndexOf(targetSclLn), sourceSclLN); + + XmlNodeList xmlNodeList = xmlNode.ChildNodes; + foreach (XmlNode item in xmlNodeList) + xmlNode.RemoveChild(item); + + foreach (SclLN sclLN in logicalNodes) + xmlNode.AppendChild(sclLN.xmlNode); + + + return true; + } + catch (Exception) + { + return false; + } + + } + + public string Inst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "inst"); + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "inst", value); + } + } + + public string Desc + { + get + { + return desc; + } + } + + public string LdName + { + get + { + return ldName; + } + + } + + public List LogicalNodes + { + get + { + return logicalNodes; + } + } + + public SclLDevice(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.nsManager = nsManager; + sclDocument = SclxmlDocument; + this.xmlNode = xmlNode; + xmlDocument = SclxmlDocument.XmlDocument; + XmlAttribute instAttr = xmlNode.Attributes["inst"]; + + if (instAttr == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No inst attribute", this, "MissintInst"); + + inst = instAttr.Value; + + XmlAttribute ldNameAttr = xmlNode.Attributes["ldName"]; + + if (ldNameAttr != null) + ldName = ldNameAttr.Value; + + XmlAttribute descAttr = xmlNode.Attributes["desc"]; + + if (descAttr != null) + desc = descAttr.Value; + + XmlNodeList xmlNodeList = xmlNode.ChildNodes; + int ln0 = 0; + + if (xmlNodeList.Count > 0) + { + foreach (XmlNode lnNode in xmlNodeList) + { + if (lnNode.Name == "LN" || lnNode.Name == "LN0") + { + if (lnNode.Name == "LN0") + ln0++; + + logicalNodes.Add(new SclLN(SclxmlDocument, lnNode, nsManager)); + } + } + + } + else + { + logicalNodes = null; + } + + if (ln0 == 0) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "LDevice \"" + inst + "\" has no LN0", this, "lN0"); + + } + + } + + public class SclFCDA + { + public string LdInst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "ldInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "ldInst", value); + } + } + + public string Prefix + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "prefix"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "prefix", value); + } + } + + public string LnClass + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnClass"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnClass", value); + } + } + + public string LnInst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnInst", value); + } + } + + public string DoName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "doName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "doName", value); + } + } + + public string DaName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "daName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "daName", value); + } + } + + public SclFC Fc + { + get + { + string fcAttr = XmlHelper.GetAttributeValue(xmlNode, "fc"); + if (fcAttr != null) + return (SclFC)Enum.Parse(typeof(SclFC), fcAttr); + else + return (SclFC.NONE); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "fc", value.ToString()); + } + } + + public string Index + { + get + { + string ixStr = XmlHelper.GetAttributeValue(xmlNode, "ix"); + + if (ixStr != null) + { + int retVal = -1; + Int32.TryParse(ixStr, out retVal); + + return (retVal.ToString()); + } + else + return (""); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "ix", value.ToString()); + } + } + + internal XmlNode xmlNode = null; + private XmlDocument xmlDocument; + + public SclFCDA(XmlNode xmlNode, XmlDocument xmlDocument) + { + this.xmlDocument = xmlDocument; + this.xmlNode = xmlNode; + } + + public string GetReferenceString() + { + string refStr = LdInst + "/"; + + if (Prefix != null) + refStr += Prefix; + + refStr += LnClass; + + if (LnInst != null) + refStr += LnInst; + + if (DoName != null) + { + refStr += "."; + refStr += DoName; + + if (DaName != null) + if (DaName != "") + refStr += "." + DaName; + } + + refStr += "[" + Fc.ToString() + "]"; + + return refStr; + } + + public string GetObjectReference() + { + string refStr = LdInst + "/"; + + if (Prefix != null) + refStr += Prefix; + + refStr += LnClass; + + if (LnInst != null) + refStr += LnInst; + + if (DoName != null) + { + refStr += "."; + refStr += DoName; + + if (DaName != null) + refStr += "." + DaName; + } + + return refStr; + } + + public override string ToString() + { + return GetReferenceString(); + } + } + + public class SclDataSet + { + internal XmlNode xmlNode; + private XmlDocument xmlDocument; + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + private List fcdas = new List(); + + public List Fcdas + { + get + { + return fcdas; + } + } + + public void Add(SclFCDA fcda) + { + xmlNode.AppendChild(fcda.xmlNode); + fcdas.Add(fcda); + } + + public void Remove(SclFCDA fcda) + { + xmlNode.RemoveChild(fcda.xmlNode); + fcdas.Remove(fcda); + } + + public void RemoveAllFcdas() + { + foreach (XmlNode xmlNodes in xmlNode.ChildNodes) + xmlNode.RemoveChild(xmlNodes); + + fcdas.Clear(); + } + + public void RemoveAll() + { + xmlNode.RemoveAll(); + fcdas.Clear(); + } + + + public SclDataSet(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + xmlDocument = SclxmlDocument.XmlDocument; + this.xmlNode = xmlNode; + + XmlAttribute nameAttr = xmlNode.Attributes["name"]; + + if (nameAttr == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "DataSet has no name attribute", this, "MissingName"); + + + XmlNodeList fcdaNodes = xmlNode.SelectNodes("scl:FCDA", nsManager); + + foreach (XmlNode fcdaNode in fcdaNodes) + { + SclFCDA sclFCDA = new SclFCDA(fcdaNode, xmlDocument); + fcdas.Add(sclFCDA); + } + } + } + + public class SclLog + { + internal XmlNode xmlNode; + private XmlDocument xmlDocument; + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", value); + } + } + + public SclLog(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + xmlDocument = SclxmlDocument.XmlDocument; + this.xmlNode = xmlNode; + + XmlAttribute nameAttr = xmlNode.Attributes["name"]; + + if (nameAttr == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "Log has no name attribute", this, "MissingName"); + + } + } + + public class SclTrgOps + { + internal XmlNode xmlNode = null; + private XmlDocument xmlDocument; + + public int GetIntValue() + { + int intValue = 0; + + if (Dchg) intValue += 1; + if (Qchg) intValue += 2; + if (Dupd) intValue += 4; + if (Period) intValue += 8; + if (GI) intValue += 16; + + return intValue; + } + + public bool Dchg + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "dchg", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "dchg", value); + } + } + + public bool Qchg + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "qchg", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "qchg", value); + } + } + + public bool Dupd + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "dupd", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "dupd", value); + } + } + + public bool Period + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "period", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "period", value); + } + } + + public bool GI + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "gi", true); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "gi", value); + } + } + + public SclTrgOps(XmlDocument xmlDoc, XmlNode xmlNode) + { + xmlDocument = xmlDoc; + this.xmlNode = xmlNode; + } + } + + public class SclOptFields + { + internal XmlNode xmlNode = null; + private XmlDocument xmlDocument; + + public int GetIntValue() + { + int intValue = 0; + + if (SeqNum) intValue += 1; + if (TimeStamp) intValue += 2; + if (ReasonCode) intValue += 4; + if (DataSet) intValue += 8; + if (DataRef) intValue += 16; + if (BufOvfl) intValue += 32; + if (EntryID) intValue += 64; + if (ConfigRef) intValue += 128; + + return intValue; + } + + public bool SeqNum + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "seqNum", false); ; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "seqNum", value); + } + } + + public bool TimeStamp + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "timeStamp", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "timeStamp", value); + } + } + + public bool DataSet + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "dataSet", false); ; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "dataSet", value); + } + } + + public bool ReasonCode + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "reasonCode", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "reasonCode", value); + } + } + + public bool DataRef + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "dataRef", false); ; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "dataRef", value); + } + } + + public bool EntryID + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "entryID", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "entryID", value); + } + } + + public bool ConfigRef + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "configRef", false); ; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "configRef", value); + } + } + + public bool BufOvfl + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "bufOvfl", true); ; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "bufOvfl", value); + } + } + + + public SclOptFields(XmlDocument xmlDocument, XmlNode xmlNode) + { + this.xmlNode = xmlNode; + this.xmlDocument = xmlDocument; + } + } + + public class SclClientLN + { + private string iedName = null; + private string apRef = null; + private string ldInst = null; + private string prefix = null; + private string lnClass = null; + private string lnInst = null; + private string desc = null; + private XmlDocument xmlDoc; + + public string IedName + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "iedName"); + + if (valStr != null) + return valStr; + else + return null; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "iedName", value.ToString()); + } + } + + public string ApRef + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "apRef"); + + if (valStr != null) + return valStr; + else + return null; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "apRef", value.ToString()); + } + } + + public string LdInst + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "ldInst"); + + if (valStr != null) + return valStr; + else + return null; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "ldInst", value.ToString()); + } + } + + public string Prefix + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "prefix"); + + if (valStr != null) + return valStr; + else + return null; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "prefix", value.ToString()); + } + } + + public string LnClass + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "lnClass"); + + if (valStr != null) + return valStr; + else + return null; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "lnClass", value.ToString()); + } + } + + public string LnInst + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "lnInst"); + + if (valStr != null) + return valStr; + else + return null; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "lnInst", value.ToString()); + } + } + + public string Desc + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "desc"); + + if (valStr != null) + return valStr; + else + return null; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "desc", value.ToString()); + } + } + + public XmlNode xmlNode = null; + + public SclClientLN(XmlNode xmlNode, XmlDocument xmlDoc) + { + this.xmlNode = xmlNode; + this.xmlDoc = xmlDoc; + + XmlAttribute iedNameAttr = xmlNode.Attributes["iedName"]; + + if (iedNameAttr != null) + iedName = iedNameAttr.Value; + + XmlAttribute apRefAttr = xmlNode.Attributes["apRef"]; + + if (apRefAttr != null) + apRef = apRefAttr.Value; + + XmlAttribute ldInstAttr = xmlNode.Attributes["ldInst"]; + + if (ldInstAttr != null) + ldInst = ldInstAttr.Value; + + XmlAttribute prefixAttr = xmlNode.Attributes["prefix"]; + + if (prefixAttr != null) + prefix = prefixAttr.Value; + + XmlAttribute lnClassAttr = xmlNode.Attributes["lnClass"]; + + if (lnClassAttr != null) + lnClass = lnClassAttr.Value; + + XmlAttribute lnInstAttr = xmlNode.Attributes["lnInst"]; + + if (lnInstAttr != null) + lnInst = lnInstAttr.Value; + + XmlAttribute descAttr = xmlNode.Attributes["desc"]; + + if (descAttr != null) + desc = descAttr.Value; + } + + public string GetReferenceString() + { + string refStr = ""; + + if (apRef != null) + refStr += apRef + ":"; + + if (iedName != null) + refStr += iedName + "/"; + + if (prefix != null) + refStr += prefix; + + refStr += lnClass; + + if (lnInst != null) + refStr += lnInst; + + return refStr; + } + } + + public class SclRptEnabled + { + public XmlNode xmlNode = null; + private XmlDocument xmlDoc; + private XmlNamespaceManager nsManager; + + + private List clientLNs = new List(); + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "desc", value); + } + } + + public int Max + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "max"); + + if (valStr != null) + { + int retVal = 1; + Int32.TryParse(valStr, out retVal); + + return (retVal); + } + else + return 1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "max", value.ToString()); + } + } + + public void AddClientLN(SclClientLN clientLn) + { + xmlNode.AppendChild(clientLn.xmlNode); + clientLNs.Add(clientLn); + } + + + public void RemoveAllClientLNs() + { + foreach (XmlNode xmlNodes in xmlNode.ChildNodes) + xmlNode.RemoveChild(xmlNodes); + + clientLNs.Clear(); + } + + public void RemoveClientLN(SclClientLN sclClientLN) + { + xmlNode.RemoveChild(sclClientLN.xmlNode); + clientLNs.Remove(sclClientLN); + } + + public List ClientLNs + { + get + { + return clientLNs; + } + } + + public SclRptEnabled(XmlNode xmlNode, XmlDocument xmlDoc, XmlNamespaceManager nsManager) + { + this.xmlNode = xmlNode; + this.xmlDoc = xmlDoc; + this.nsManager = nsManager; + + XmlNodeList clientLNNodes = xmlNode.SelectNodes("scl:ClientLN", nsManager); + + if (clientLNNodes != null) + { + foreach (XmlNode clientLNNode in clientLNNodes) + { + SclClientLN clientLN = new SclClientLN(clientLNNode, xmlDoc); + + clientLNs.Add(clientLN); + } + } + + } + + } + + public class SclReportControl + { + private string name = null; + private string desc = null; + private string datSet = null; + private int intgPd = -1; + private string rptID = null; + private long confRev = -1; + private bool buffered = false; + private int bufTime = 0; + private bool indexed = true; + + private SclTrgOps trgOps = null; + private SclOptFields optFields = null; + private SclRptEnabled rptEna = null; + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + public string DatSet + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "datSet"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "datSet", value); + } + } + + public string IntgPd + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "intgPd"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "intgPd", value); + } + } + + public string RptID + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "rptID"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "rptID", value); + } + } + + public string ConfRev + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "confRev"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "confRev", value); + } + } + + public int IntConfRev + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "confRev"); + + if (valStr != null) + { + int retVal = -1; + Int32.TryParse(valStr, out retVal); + + return (retVal); + } + else + return (-1); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "confRev", value.ToString()); + } + } + + public bool Buffered + { + get + { + string result = XmlHelper.GetAttributeValue(xmlNode, "buffered"); + + if (result == "true") + return true; + else + return false; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "buffered", value); + } + } + + public string BufTime + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "bufTime"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "bufTime", value); + } + } + + public bool Indexed + { + get + { + + string result = XmlHelper.GetAttributeValue(xmlNode, "indexed"); + + if (result == null) + return true; + + if (result == "true") + return true; + else + return false; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "indexed", value); + } + } + + public SclTrgOps TrgOps + { + get + { + return trgOps; + } + } + + public SclOptFields OptFields + { + get + { + return optFields; + } + } + + public SclRptEnabled RptEna + { + get + { + return rptEna; + } + } + + public XmlNode xmlNode = null; + private XmlDocument xmlDocument; + + private bool ParseBooleanAttribute(string attributeName, bool defaultValue) + { + XmlAttribute attr = xmlNode.Attributes[attributeName]; + + bool attrVal = defaultValue; + + if (attr != null) + { + if (Boolean.TryParse(attr.Value, out attrVal) == false) + throw new SclParserException(xmlNode, "ReportControl: failed to parse boolean attribute"); + } + + return attrVal; + } + + public SclReportControl(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.xmlNode = xmlNode; + xmlDocument = SclxmlDocument.XmlDocument; + + indexed = ParseBooleanAttribute("indexed", indexed); + + XmlAttribute bufTimeAttr = xmlNode.Attributes["bufTime"]; + + if (bufTimeAttr != null) + { + if (int.TryParse(bufTimeAttr.Value, out bufTime) == false) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "ReportControl: failed to parse \"bufTime\" attribute", this, "BufTimeFailed"); + } + + buffered = ParseBooleanAttribute("buffered", buffered); + + XmlAttribute confRevAttr = xmlNode.Attributes["confRev"]; + + if (confRevAttr != null) + { + if (long.TryParse(confRevAttr.Value, out confRev) == false) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "ReportControl: failed to parse \"confRev\" attribute", this, "ConfRevFailed"); + } + + XmlAttribute rptIDAttr = xmlNode.Attributes["rptID"]; + + if (rptIDAttr != null) + rptID = rptIDAttr.Value; + + XmlAttribute intgPdAttr = xmlNode.Attributes["intgPd"]; + + if (intgPdAttr != null) + { + if (int.TryParse(intgPdAttr.Value, out intgPd) == false) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "ReportControl: failed to parse \"intgPd\" attribute", this, "IntgPdFailed"); + } + + XmlAttribute datSetAttr = xmlNode.Attributes["datSet"]; + + if (datSetAttr != null) + datSet = datSetAttr.Value; + + XmlAttribute nameAttr = xmlNode.Attributes["name"]; + + if (nameAttr != null) + { + name = nameAttr.Value; + } + else + { + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "ReportControl has no name attribute", this, "MissingName"); + } + + + XmlAttribute descAttr = xmlNode.Attributes["desc"]; + + if (descAttr != null) + desc = descAttr.Value; + + XmlNode trgOpsNode = xmlNode.SelectSingleNode("scl:TrgOps", nsManager); + + if (trgOpsNode != null) + trgOps = new SclTrgOps(xmlDocument, trgOpsNode); + + XmlNode optFieldsNode = xmlNode.SelectSingleNode("scl:OptFields", nsManager); + + if (optFieldsNode != null) + optFields = new SclOptFields(xmlDocument, optFieldsNode); + + XmlNode rptEnaNode = xmlNode.SelectSingleNode("scl:RptEnabled", nsManager); + + if (rptEnaNode != null) + rptEna = new SclRptEnabled(rptEnaNode, xmlDocument, nsManager); + } + } + + public class SclDAI + { + private XmlNode xmlNode; + private XmlDocument xmlDoc; + private XmlNamespaceManager nsManager; + private object parent; + private List values = new List(); + + public List GetValues() + { + return values; + } + + public object Parent { get { return parent; } set { parent = value; } } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "desc", value); + } + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "name", value); + } + + } + + public string SAddr + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "sAddr"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "sAddr", value); + } + } + + public string ValKind + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "valKind"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "valKind", value); + } + } + + public string ValImport + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "valImport"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "valImport", value); + } + } + + public string Ix + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "ix"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "ix", value); + } + } + + public string Val + { + get + { + XmlNode VALNode = null; + + if (nsManager != null) + VALNode = xmlNode.SelectSingleNode("scl:Val", nsManager); + else + VALNode = xmlNode.SelectSingleNode("Val"); + + if (VALNode != null) + return VALNode.InnerText; + else + return null; + } + } + + public XmlNode Node { get { return xmlNode; } set { xmlNode = value; } } + + public XmlDocument XmlDoc { get { return xmlDoc; } set { xmlDoc = value; } } + + public XmlNamespaceManager NsManager { get { return nsManager; } set { nsManager = value; } } + + + public SclDAI(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager, string objRef = null) + { + xmlDoc = SclxmlDocument.XmlDocument; + this.xmlNode = xmlNode; + this.nsManager = nsManager; + + XmlAttribute DAIname = xmlNode.Attributes["name"]; + + if (DAIname == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "DAI has no name attribute", this, "MissingName"); + + if (objRef != null && DAIname != null) + objRef += "." + DAIname.Value; + + XmlNodeList valNodes = xmlNode.SelectNodes("scl:Val", nsManager); + if (valNodes.Count == 0) + { + //TODO + //Only show warninf when there is no value and no sAddr + //if (DAIname != null) + //{ + // if(objRef != null) + // SclxmlDocument.AddIssue(xmlNode, "WARNING", "Model integrity", "DAI " + objRef + " has no value attribute", this, "MissingValue"); + // else + // SclxmlDocument.AddIssue(xmlNode, "WARNING", "Model integrity", "DAI " + DAIname.Value + " has no value attribute", this, "MissingValue"); + + //} + //else + // SclxmlDocument.AddIssue(xmlNode, "WARNING", "Model integrity", "DAI has no value attribute", this, "MissingValue"); + } + else + { + foreach (XmlNode valNode in valNodes) + values.Add(new SclVal(xmlDoc, valNode)); + } + } + } + + public class SclDOI + { + private XmlNode xmlNode; + private XmlDocument xmlDoc; + private XmlNamespaceManager nsManager; + + private List sclDAIs = new List(); + private List sclSDIs = new List(); + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "desc", value); + } + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "name", value); + } + } + + public string AccessControl + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "accessControl"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "accessControl", value); + } + } + + public List SclDAIs { get { return sclDAIs; } set { sclDAIs = value; } } + + public List SclSDIs { get { return sclSDIs; } set { sclSDIs = value; } } + + public string Ix + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "ix"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "ix", value); + } + } + + + public SclDOI(SclDocument SclxmlDoc, XmlNode xmlNode, XmlNamespaceManager nsManager, string objRef = null) + { + xmlDoc = SclxmlDoc.XmlDocument; + this.xmlNode = xmlNode; + this.nsManager = nsManager; + + XmlAttribute nameAttr = xmlNode.Attributes["name"]; + + if (nameAttr == null) + SclxmlDoc.AddIssue(xmlNode, "ERROR", "Model integrity", "DOI has no name attribute", this, "MissingName"); + + if (nameAttr != null) + { + if (objRef != null) + objRef += nameAttr.Value; + else + objRef = nameAttr.Value; + } + + XmlNodeList DAINodes = xmlNode.SelectNodes("scl:DAI", nsManager); + if (DAINodes != null) + { + foreach (XmlNode DAINode in DAINodes) + { + SclDAI sclDAI = new SclDAI(SclxmlDoc, DAINode, nsManager, objRef); + sclDAI.Parent = this; + sclDAIs.Add(sclDAI); + } + } + + + XmlNodeList SDINodes = xmlNode.SelectNodes("scl:SDI", nsManager); + + if (SDINodes != null) + { + foreach (XmlNode SDINode in SDINodes) + { + SclSDI SclSDI = new SclSDI(SclxmlDoc, SDINode, nsManager, objRef); + SclSDI.Parent = this; + sclSDIs.Add(SclSDI); + } + } + + } + + public XmlNode Node { get { return xmlNode; } set { xmlNode = value; } } + + public XmlDocument XmlDoc { get { return xmlDoc; } set { xmlDoc = value; } } + + public XmlNamespaceManager NsManager { get { return nsManager; } set { nsManager = value; } } + } + + public class SclSDI + { + private XmlNode xmlNode; + private XmlDocument xmlDoc; + private XmlNamespaceManager nsManager; + private object parent; + + public object Parent { get { return parent; } set { parent = value; } } + + + private List sclDAIs = new List(); + private List sclSDIs = new List(); + + public List SclSDIs { get { return sclSDIs; } set { sclSDIs = value; } } + public List SclDAIs { get { return sclDAIs; } set { sclDAIs = value; } } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "name", value); + } + + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "desc", value); + } + + } + + public string Ix + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "ix"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "ix", value); + } + + } + + public string SAddr + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "sAddr"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "sAddr", value); + } + + } + + public XmlNode Node { get { return xmlNode; } set { xmlNode = value; } } + + public XmlDocument XmlDoc { get { return xmlDoc; } set { xmlDoc = value; } } + + public XmlNamespaceManager NsManager { get { return nsManager; } set { nsManager = value; } } + + public SclSDI(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager, string objref = null) + { + xmlDoc = SclxmlDocument.XmlDocument; + this.xmlNode = xmlNode; + this.nsManager = nsManager; + + XmlAttribute SDIname = xmlNode.Attributes["name"]; + + if (SDIname == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "SDI has no name attribute", this, "MissingName"); + + if (SDIname != null && objref != null) + objref += "." + SDIname.Value; + + + XmlNodeList SDINodes = xmlNode.SelectNodes("scl:SDI", nsManager); + + if (SDINodes != null) + { + foreach (XmlNode SDINode in SDINodes) + { + SclSDI SclSDI = new SclSDI(SclxmlDocument, SDINode, nsManager, objref); + SclSDI.Parent = this; + sclSDIs.Add(SclSDI); + } + } + + XmlNodeList DAINodes = xmlNode.SelectNodes("scl:DAI", nsManager); + if (DAINodes != null) + { + foreach (XmlNode DAINode in DAINodes) + { + SclDAI SclDAI = new SclDAI(SclxmlDocument, DAINode, nsManager, objref); + SclDAI.Parent = this; + sclDAIs.Add(SclDAI); + } + //sclDAIs.Add(new SclDAI(xmlDocument, DAINode, nsManager)); + } + + } + + } + + public class Inputs + { + internal XmlNode xmlNode; + public XmlDocument xmlDocument; + public IEDModelNode Parent; + private List extRefs = new List(); + + public List ExtRefs + { + get { return extRefs; } + } + + public void Add(SclExtRef extRef) + { + xmlNode.AppendChild(extRef.xmlNode); + extRef.Parent = this; + extRefs.Add(extRef); + } + + public void RemoveAllExtRef() + { + foreach (XmlNode xmlNodes in xmlNode.ChildNodes) + xmlNode.RemoveChild(xmlNodes); + + extRefs.Clear(); + } + + public void Remove(SclExtRef extRef) + { + xmlNode.RemoveChild(extRef.xmlNode); + extRefs.Remove(extRef); + } + + public Inputs(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.xmlNode = xmlNode; + xmlDocument = SclxmlDocument.XmlDocument; + + XmlNodeList extRefNodes = xmlNode.SelectNodes("scl:ExtRef", nsManager); + foreach (XmlNode extRefNode in extRefNodes) + extRefs.Add(new SclExtRef(SclxmlDocument, extRefNode)); + } + + + public SclExtRef AddExtRef(SclExtRef extRef) + { + xmlNode.AppendChild(extRef.xmlNode); + extRef.Parent = this; + extRefs.Add(extRef); + + return extRef; + } + + + } + + public class SclLN + { + private string lnClass; + private string lnType; + private string inst; + private string desc = null; + private string prefix = null; + + + internal XmlNode xmlNode; + public XmlDocument xmlDocument; + private SclDocument sclDocument; + + private Inputs inputs = null; + private SclSettingControl settingControl = null; + private List dataSets = new List(); + private List logs = new List(); + private List reportControls = new List(); + private List gseControls = new List(); + private List logControls = new List(); + private List sclSMVControls = new List(); + private List dois = new List(); + + public XmlNode XmlNode + { + get + { + return xmlNode; + } + } + + + public Inputs Inputs + { + get { return inputs; } + set { inputs = value; } + } + + public SclSettingControl SettingControl + { + get { return settingControl; } + set { settingControl = value; } + } + + public List DataSets + { + get + { + return dataSets; + } + } + + public List Logs + { + get + { + return logs; + } + } + + public List DOIs + { + get + { + return dois; + } + } + + public List ReportControls + { + get + { + return reportControls; + } + } + + public List GSEControls + { + get + { + return gseControls; + } + } + + public List SclSMVControls + { + get + { + return sclSMVControls; + } + } + + public List LogControls + { + get + { + return logControls; + } + } + + public string InstanceName + { + get + { + return Prefix + LnClass + Inst; + + } + + } + + public string LnClass + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnClass"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnClass", value); + } + } + + public string LnType + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnType"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnType", value); + } + } + + public string Inst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "inst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "inst", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + public string Prefix + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "prefix"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "prefix", value); + } + } + + private XmlNamespaceManager nsManager; + + + public SclLN(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.xmlNode = xmlNode; + xmlDocument = SclxmlDocument.XmlDocument; + this.nsManager = nsManager; + sclDocument = SclxmlDocument; + + XmlAttribute lnClassAttr = xmlNode.Attributes["lnClass"]; + + if (lnClassAttr == null) + { + lnClass = null; + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "no lnClass attribute", this, "lnClass"); + } + else + { + lnClass = lnClassAttr.Value; + + } + + XmlAttribute lnTypeAttr = xmlNode.Attributes["lnType"]; + + if (lnTypeAttr == null) + { + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "no lnType attribute", this, "lnType"); + lnType = null; + } + else + lnType = lnTypeAttr.Value; + + + XmlAttribute instAttr = xmlNode.Attributes["inst"]; + + if (instAttr == null) + { + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "no inst attribute", this, "inst"); + inst = null; + } + else + inst = instAttr.Value; + + XmlAttribute descAttr = xmlNode.Attributes["desc"]; + + if (descAttr != null) + desc = descAttr.Value; + + XmlAttribute prefixAttr = xmlNode.Attributes["prefix"]; + + if (prefixAttr != null) + prefix = prefixAttr.Value; + + XmlNodeList dataSetNodes = xmlNode.SelectNodes("scl:DataSet", nsManager); + + foreach (XmlNode dataSetNode in dataSetNodes) + dataSets.Add(new SclDataSet(SclxmlDocument, dataSetNode, nsManager)); + + XmlNodeList reportControlNodes = xmlNode.SelectNodes("scl:ReportControl", nsManager); + + foreach (XmlNode reportControlNode in reportControlNodes) + reportControls.Add(new SclReportControl(SclxmlDocument, reportControlNode, nsManager)); + + XmlNodeList gseControlNodes = xmlNode.SelectNodes("scl:GSEControl", nsManager); + + foreach (XmlNode gseControlNode in gseControlNodes) + gseControls.Add(new SclGSEControl(SclxmlDocument, gseControlNode)); + + XmlNodeList smvControlNodes = xmlNode.SelectNodes("scl:SampledValueControl", nsManager); + + foreach (XmlNode smvControlNode in smvControlNodes) + sclSMVControls.Add(new SclSMVControl(SclxmlDocument, smvControlNode, nsManager)); + + XmlNodeList logControlNodes = xmlNode.SelectNodes("scl:LogControl", nsManager); + + foreach (XmlNode LogControlNode in logControlNodes) + logControls.Add(new SclLogControl(SclxmlDocument, LogControlNode, nsManager)); + + XmlNodeList DOINodes = xmlNode.SelectNodes("scl:DOI", nsManager); + + foreach (XmlNode DOINode in DOINodes) + dois.Add(new SclDOI(SclxmlDocument, DOINode, nsManager)); + + XmlNode inputs = xmlNode.SelectSingleNode("scl:Inputs", nsManager); + + if (inputs != null) + Inputs = new Inputs(SclxmlDocument, inputs, nsManager); + + XmlNode settingControlNode = xmlNode.SelectSingleNode("scl:SettingControl", nsManager); + + if (settingControlNode != null) + settingControl = new SclSettingControl(SclxmlDocument, settingControlNode); + + XmlNodeList logNodes = xmlNode.SelectNodes("scl:Log", nsManager); + + foreach (XmlNode logNode in logNodes) + logs.Add(new SclLog(SclxmlDocument, logNode, nsManager)); + + } + + } +} + diff --git a/tools/model_generator_dotnet/SCLParser/src/SclEquipment.cs b/tools/model_generator_dotnet/SCLParser/src/SclEquipment.cs new file mode 100644 index 00000000..425f4711 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclEquipment.cs @@ -0,0 +1,883 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System; +using System.Collections.Generic; +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclEquipment : SclPowerSystemResource + { + public bool Virtual + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "virtual", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "virtual", value); + } + } + + internal SclEquipment(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + + } + } + + public class SclSubEquipment : SclPowerSystemResource + { + public bool Virtual + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "virtual", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "virtual", value); + } + } + + public string Phase + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "phase"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "phase", value); + } + } + + private List sclEqFunctions; + + private void parseEqFunctions() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:EqFunction", nsManager); + + sclEqFunctions = new List(); + + foreach (XmlNode node in nodes) + { + SclEqFunction lNode = new SclEqFunction(xmlDocument, sclDocument, node, nsManager); + sclEqFunctions.Add(lNode); + } + } + + public List EqFunctions + { + get { return sclEqFunctions; } + } + + public bool RemoveEqFunction(SclEqFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + EqFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public SclEqFunction AddNewEqFunction() + { + SclEqFunction newControl = new SclEqFunction(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (EqFunctions.Count > 0) + { + int lastIndex = EqFunctions.Count - 1; + + SclEqFunction lastLNode = EqFunctions[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclEqFunction(xmlDocument, sclDocument, newNode, nsManager); + EqFunctions.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + internal SclSubEquipment(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + parseEqFunctions(); + } + + public SclSubEquipment(XmlDocument xmlDocument, SclDocument sclDocument, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlDocument.CreateElement("SubEquipment", SclDocument.SCL_XMLNS), nsManager) + { + + } + } + + public class SclAbstractConductingEquipment : SclEquipment + { + private List sclTerminals; + private List sclSubEquipments; + private void parseTerminal() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:Terminal", nsManager); + + sclTerminals = new List(); + + foreach (XmlNode node in nodes) + { + SclTerminal lNode = new SclTerminal(xmlDocument, sclDocument, node, nsManager); + sclTerminals.Add(lNode); + } + } + + private void parseSubEquipment() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:SubEquipment", nsManager); + + sclSubEquipments = new List(); + + foreach (XmlNode node in nodes) + { + SclSubEquipment lNode = new SclSubEquipment(xmlDocument, sclDocument, node, nsManager); + sclSubEquipments.Add(lNode); + } + } + + public List Terminals + { + get + { + return sclTerminals; + } + } + + public bool RemoveTerminal(SclTerminal node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + Terminals.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public SclTerminal AddNewTerminal() + { + SclTerminal newControl = new SclTerminal(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (Terminals.Count > 0) + { + int lastIndex = Terminals.Count - 1; + + SclTerminal lastLNode = Terminals[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclTerminal(xmlDocument, sclDocument, newNode, nsManager); + Terminals.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + public List SubEquipments + { + get + { + return sclSubEquipments; + } + } + + public bool RemoveSubEquipment(SclSubEquipment node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + SubEquipments.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public SclSubEquipment AddNewSubEquipment() + { + SclSubEquipment newControl = new SclSubEquipment(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (SubEquipments.Count > 0) + { + int lastIndex = SubEquipments.Count - 1; + + SclSubEquipment lastLNode = SubEquipments[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclSubEquipment(xmlDocument, sclDocument, newNode, nsManager); + SubEquipments.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + internal SclAbstractConductingEquipment(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + parseTerminal(); + + if (sclTerminals.Count > 2) + { + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "AbstractConductingEquipment contains " + sclTerminals.Count + " Terminals. Maximum is 2", this, "Terminal"); + } + + parseSubEquipment(); + } + } + + public class SclTerminal : SclBaseElement + { + private XmlDocument xmlDocument; + + public string BayName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "bayName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "bayName", value); + } + } + + public string CNodeName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "cNodeName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "cNodeName", value); + } + } + + public string ConnectivityNode + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "connectivityNode"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "connectivityNode", value); + } + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", value); + } + } + + public string NeutralPoint + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "neutralPoint"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "neutralPoint", value); + } + } + + public string PorcessName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "porcessName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "porcessName", value); + } + } + + public string SubstationName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "substationName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "substationName", value); + } + } + + public string VoltageLevelName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "voltageLevelName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "voltageLevelName", value); + } + } + + internal SclTerminal(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode) + { + this.xmlDocument = xmlDocument; + + } + + public SclTerminal(XmlDocument xmlDocument, SclDocument sclDocument, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlDocument.CreateElement("Terminal", SclDocument.SCL_XMLNS)) + { + + } + } + + public class SclTransformerWinding : SclAbstractConductingEquipment + { + public string Type + { + get + { + return "PTW"; + } + + } + + private List sclTapChangers; + + public bool RemoveTapChanger(SclTapChanger node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclTapChangers.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public SclTapChanger AddNewTapChanger() + { + SclTapChanger newControl = new SclTapChanger(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (sclTapChangers.Count > 0) + { + int lastIndex = sclTapChangers.Count - 1; + + SclTapChanger lastLNode = sclTapChangers[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclTapChanger(xmlDocument, sclDocument, newNode, nsManager); + sclTapChangers.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + private void parseTapChanger() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:TapChanger", nsManager); + + sclTapChangers = new List(); + + foreach (XmlNode node in nodes) + { + SclTapChanger tap = new SclTapChanger(xmlDocument, sclDocument, node, nsManager); + sclTapChangers.Add(tap); + } + } + + public List TapChangers + { + get { return sclTapChangers; } + } + + private List sclEqFunctions; + + public bool RemoveEqFunction(SclEqFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + EqFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public SclEqFunction AddNewEqFunction() + { + SclEqFunction newControl = new SclEqFunction(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (sclEqFunctions.Count > 0) + { + int lastIndex = sclEqFunctions.Count - 1; + + SclEqFunction lastLNode = sclEqFunctions[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclEqFunction(xmlDocument, sclDocument, newNode, nsManager); + sclEqFunctions.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + private void parseEqFunctions() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:EqFunction", nsManager); + + sclEqFunctions = new List(); + + foreach (XmlNode node in nodes) + { + SclEqFunction lNode = new SclEqFunction(xmlDocument, sclDocument, node, nsManager); + sclEqFunctions.Add(lNode); + } + } + + public List EqFunctions + { + get { return sclEqFunctions; } + } + + + internal SclTransformerWinding(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + if (Terminals.Count > 1) + { + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "TransformerWinding contains " + Terminals.Count + " Terminals. Maximum is 1", this, "Terminal"); + } + + parseTapChanger(); + + if (sclTapChangers.Count > 1) + { + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "TransformerWinding contains " + sclTapChangers.Count + " TapChangers. Maximum is 1", this, "Terminal"); + } + + parseEqFunctions(); + } + + public SclTransformerWinding(XmlDocument xmlDocument, SclDocument sclDocument, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlDocument.CreateElement("TransformerWinding", SclDocument.SCL_XMLNS), nsManager) + { + + } + } + + public class SclTapChanger : SclPowerSystemResource + { + public bool Virtual + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "virtual", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "virtual", value); + } + } + + public string Type + { + get + { + return "LTC"; + } + } + + private List sclSubEquipments; + + public bool RemoveSubEquipment(SclSubEquipment node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + SubEquipments.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public SclSubEquipment AddNewSubEquipment() + { + SclSubEquipment newControl = new SclSubEquipment(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (SubEquipments.Count > 0) + { + int lastIndex = SubEquipments.Count - 1; + + SclSubEquipment lastLNode = SubEquipments[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclSubEquipment(xmlDocument, sclDocument, newNode, nsManager); + SubEquipments.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + private void parseSubEquipment() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:SubEquipment", nsManager); + + sclSubEquipments = new List(); + + foreach (XmlNode node in nodes) + { + SclSubEquipment lNode = new SclSubEquipment(xmlDocument, sclDocument, node, nsManager); + sclSubEquipments.Add(lNode); + } + } + + public List SubEquipments + { + get + { + return sclSubEquipments; + } + } + + public SclEqFunction AddNewEqFunction() + { + SclEqFunction newControl = new SclEqFunction(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (sclEqFunctions.Count > 0) + { + int lastIndex = sclEqFunctions.Count - 1; + + SclEqFunction lastLNode = sclEqFunctions[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclEqFunction(xmlDocument, sclDocument, newNode, nsManager); + sclEqFunctions.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + public bool RemoveEqFunction(SclEqFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + EqFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + + private List sclEqFunctions; + + private void parseEqFunctions() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:EqFunction", nsManager); + + sclEqFunctions = new List(); + + foreach (XmlNode node in nodes) + { + SclEqFunction lNode = new SclEqFunction(xmlDocument, sclDocument, node, nsManager); + sclEqFunctions.Add(lNode); + } + } + + public List EqFunctions + { + get { return sclEqFunctions; } + } + + + internal SclTapChanger(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + parseSubEquipment(); + + parseEqFunctions(); + } + + public SclTapChanger(XmlDocument xmlDocument, SclDocument sclDocument, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlDocument.CreateElement("TapChanger", SclDocument.SCL_XMLNS), nsManager) + { + + } + } + +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclEquipmentFunctions.cs b/tools/model_generator_dotnet/SCLParser/src/SclEquipmentFunctions.cs new file mode 100644 index 00000000..e68d8c5d --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclEquipmentFunctions.cs @@ -0,0 +1,192 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System; +using System.Collections.Generic; +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclAbstractEqFuncSubFunc : SclPowerSystemResource + { + public string Type + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "type", value); + } + } + + private List sclEqSubFunctions; + private List sclGeneralEquipments; + + public bool RemoveEqSubFunction(SclEqSubFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclEqSubFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public bool RemoveGeneralEquipment(SclGeneralEquipment node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclGeneralEquipments.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + private void parseEqSubFunction() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:EqSubFunction", nsManager); + + sclEqSubFunctions = new List(); + + foreach (XmlNode node in nodes) + { + SclEqSubFunction lNode = new SclEqSubFunction(xmlDocument, sclDocument, node, nsManager); + sclEqSubFunctions.Add(lNode); + } + } + + private void parseGeneralEquipment() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:GeneralEquipment", nsManager); + + sclGeneralEquipments = new List(); + + foreach (XmlNode node in nodes) + { + SclGeneralEquipment lNode = new SclGeneralEquipment(xmlDocument, sclDocument, node, nsManager); + sclGeneralEquipments.Add(lNode); + } + } + + public List EqSubFunctions + { + get { return sclEqSubFunctions; } + } + + public SclEqSubFunction AddNewEqSubFunction() + { + SclEqSubFunction newgeneralEquipment = new SclEqSubFunction(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newgeneralEquipment.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newgeneralEquipment.xmlNode.CloneNode(true), true); + } + + if (EqSubFunctions.Count > 0) + { + int lastIndex = EqSubFunctions.Count - 1; + + SclEqSubFunction lastLNode = EqSubFunctions[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newgeneralEquipment = new SclEqSubFunction(xmlDocument, sclDocument, newNode, nsManager); + EqSubFunctions.Add(newgeneralEquipment); + + return newgeneralEquipment; + + } + catch (SclParserException e) + { + Console.WriteLine("Failed to add Substation"); + Console.WriteLine(e.ToString()); + + return null; + } + } + + + public List GeneralEquipments + { + get { return sclGeneralEquipments; } + } + + internal SclAbstractEqFuncSubFunc(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + parseEqSubFunction(); + + parseGeneralEquipment(); + } + } + + public class SclEqSubFunction : SclAbstractEqFuncSubFunc + { + internal SclEqSubFunction(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + } + + public SclEqSubFunction(XmlDocument xmlDocument, SclDocument sclDocument, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlDocument.CreateElement("EqSubFunction", SclDocument.SCL_XMLNS), nsManager) + { + + } + } + + public class SclEqFunction : SclAbstractEqFuncSubFunc + { + internal SclEqFunction(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + } + + public SclEqFunction(XmlDocument xmlDocument, SclDocument sclDocument, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlDocument.CreateElement("EqFunction", SclDocument.SCL_XMLNS), nsManager) + { + + } + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclGSEControl.cs b/tools/model_generator_dotnet/SCLParser/src/SclGSEControl.cs new file mode 100644 index 00000000..b181de33 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclGSEControl.cs @@ -0,0 +1,152 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System; +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclGSEControl + { + public XmlNode xmlNode; + private XmlDocument xmlDocument; + + public SclGSEControl(SclDocument SclxmlDocument, XmlNode xmlNode) + { + this.xmlNode = xmlNode; + xmlDocument = SclxmlDocument.XmlDocument; + + XmlAttribute nameAttr = xmlNode.Attributes["name"]; + + if (nameAttr == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "GSEControl has no name attribute", this, "MissingName"); + } + + public SclGSEControl(XmlDocument xmlDoc, string name) + { + xmlDocument = xmlDoc; + xmlNode = xmlDoc.CreateElement("GSEControl", SclDocument.SCL_XMLNS); + + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", name); + + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "appID", name); + } + + public SclGSEControl(XmlDocument xmlDocument) + { + this.xmlDocument = xmlDocument; + xmlNode = xmlDocument.CreateElement("scl:GSEControl"); + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + public string DatSet + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "datSet"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "datSet", value); + } + } + + public string AppID + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "appID"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "appID", value); + } + } + + public int ConfRev + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "confRev"); + + if (valStr != null) + { + int retVal = -1; + Int32.TryParse(valStr, out retVal); + + return (retVal); + } + else + return (-1); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "confRev", value.ToString()); + } + } + + public bool FixedOffs + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "fixedOffs", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "fixedOffs", value); + } + } + + public string Type + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "type", value); + } + } + + public string SecurityEnabled + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "securityEnabled"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "securityEnabled", value); + } + } + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclHeader.cs b/tools/model_generator_dotnet/SCLParser/src/SclHeader.cs new file mode 100644 index 00000000..3f94a79f --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclHeader.cs @@ -0,0 +1,339 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System; +using System.Collections.Generic; +using System.Xml; + +namespace IEC61850.SCL +{ + /// + /// Representation of the SCL Header.History.Hitem (history item) element + /// + public class SclHitem + { + public XmlNode XmlNode = null; + private XmlDocument xmlDocument; + + public string Version + { + get + { + return XmlHelper.GetAttributeValue(XmlNode, "version"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, XmlNode, "version", value); + } + } + + public string Revision + { + get + { + return XmlHelper.GetAttributeValue(XmlNode, "revision"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, XmlNode, "revision", value); + } + } + + public string What + { + get + { + return XmlHelper.GetAttributeValue(XmlNode, "what"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, XmlNode, "what", value); + } + } + + public string Who + { + get + { + return XmlHelper.GetAttributeValue(XmlNode, "who"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, XmlNode, "who", value); + } + } + + public string When + { + get + { + return XmlHelper.GetAttributeValue(XmlNode, "when"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, XmlNode, "when", value); + } + } + + public string Why + { + get + { + return XmlHelper.GetAttributeValue(XmlNode, "why"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, XmlNode, "why", value); + } + } + + public SclHitem(SclDocument SclxmlDocument, XmlNode xmlNode) + { + xmlDocument = SclxmlDocument.XmlDocument; + XmlNode = xmlNode; + + XmlAttribute version = xmlNode.Attributes["version"]; + if (version == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No version attribute on Hitem", this, "version"); + + XmlAttribute revision = xmlNode.Attributes["revision"]; + if (revision == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No revision attribute on Hitem", this, "revision"); + + XmlAttribute when = xmlNode.Attributes["when"]; + if (when == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No when attribute on Hitem", this, "when"); + } + + public SclHitem(XmlDocument xmlDocument) + { + this.xmlDocument = xmlDocument; + XmlNode = xmlDocument.CreateElement("Hitem", SclDocument.SCL_XMLNS); + + Version = ""; + Revision = ""; + When = ""; + } + } + + public class SclHistory + { + private XmlNode xmlNode = null; + private XmlDocument xmlDocument; + + private List hitems = new List(); + + public XmlNode XmlNode + { + get { return xmlNode; } + } + + public List HItems + { + get + { + return hitems; + } + } + + public SclHitem AddHitem() + { + SclHitem sclHitem = new SclHitem(xmlDocument); + hitems.Add(sclHitem); + + xmlNode.AppendChild(sclHitem.XmlNode); + + return sclHitem; + } + + public bool DeleteHitem(SclHitem sclHitem) + { + try + { + hitems.Remove(sclHitem); + + xmlNode.RemoveChild(sclHitem.XmlNode); + + return true; + } + catch (Exception) + { + return false; + } + + + + + } + + public SclHistory(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + xmlDocument = SclxmlDocument.XmlDocument; + this.xmlNode = xmlNode; + + XmlNodeList hitemNodes = xmlNode.SelectNodes("scl:Hitem", nsManager); + + foreach (XmlNode hitemNode in hitemNodes) + { + hitems.Add(new SclHitem(SclxmlDocument, hitemNode)); + } + } + + public SclHistory(XmlDocument xmlDocument) + { + this.xmlDocument = xmlDocument; + xmlNode = xmlDocument.CreateElement("History", SclDocument.SCL_XMLNS); + + SclHitem sclHitem = new SclHitem(xmlDocument); + xmlNode.AppendChild(sclHitem.XmlNode); + hitems.Add(sclHitem); + } + } + + public class SclHeader + { + private XmlNode xmlNode = null; + private XmlDocument xmlDocument; + + private SclHistory history = null; + + public string MyProperty + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "id"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "id", value); + } + } + + public XmlNode XmlNode + { + get + { + return xmlNode; + } + } + + public string Version + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "version"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "version", value); + } + } + + public string Revision + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "revision"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "revision", value); + } + } + + public string ToolID + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "toolID"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "toolID", value); + } + } + + public string NameStructure + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "nameStructure"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "nameStructure", value); + } + } + + public SclHistory History + { + get + { + return history; + } + } + + public bool DeleteHistory() + { + if (history != null) + { + xmlNode.RemoveChild(history.XmlNode); + history = null; + + return true; + } + + return false; + } + + public XmlNode Node + { + get { return xmlNode; } + } + + public SclHistory AddHistory() + { + if (history == null) + { + history = new SclHistory(xmlDocument); + xmlNode.AppendChild(history.XmlNode); + return history; + } + else + return null; + } + + public SclHeader(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + xmlDocument = SclxmlDocument.XmlDocument; + this.xmlNode = xmlNode; + + XmlAttribute idAttr = xmlNode.Attributes["id"]; + + if (idAttr == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No id attribute on Header", this, "id"); + + + XmlNode historyNode = xmlNode.SelectSingleNode("scl:History", nsManager); + + if (historyNode != null) + history = new SclHistory(SclxmlDocument, historyNode, nsManager); + } + + public SclHeader(SclDocument SclDocument, XmlNamespaceManager nsManager) + { + xmlDocument = SclDocument.XmlDocument; + xmlNode = SclDocument.XmlDocument.CreateElement("Header", SclDocument.SCL_XMLNS); + + MyProperty = ""; + + history = new SclHistory(SclDocument.XmlDocument); + xmlNode.AppendChild(history.XmlNode); + } + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclLogControl.cs b/tools/model_generator_dotnet/SCLParser/src/SclLogControl.cs new file mode 100644 index 00000000..ad48c9b8 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclLogControl.cs @@ -0,0 +1,177 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclLogControl + { + public XmlNode xmlNode; + private XmlDocument xmlDocument; + private SclTrgOps trgOps = null; + + public SclTrgOps TrgOps + { + get + { + return trgOps; + } + } + + + public SclLogControl(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.xmlNode = xmlNode; + xmlDocument = SclxmlDocument.XmlDocument; + + XmlAttribute nameAttr = xmlNode.Attributes["name"]; + + if (nameAttr == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "LogControl has no name attribute", this, "MissingName"); + + XmlNode trgOpsNode = xmlNode.SelectSingleNode("scl:TrgOps", nsManager); + + if (trgOpsNode != null) + trgOps = new SclTrgOps(xmlDocument, trgOpsNode); + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + public string DatSet + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "datSet"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "datSet", value); + } + } + + public string IntgPd + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "intgPd"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "intgPd", value); + } + } + + public string LdInst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "ldInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "ldInst", value); + } + } + + public string Prefix + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "prefix"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "prefix", value); + } + } + + public string LnClass + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnClass"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnClass", value); + } + } + + public string LnInst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnInst", value); + } + } + + public string LogName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "logName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "logName", value); + } + } + + public bool LogEna + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "logEna", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "logEna", value); + } + } + + public bool ReasonCode + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "reasonCode", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "reasonCode", value); + } + } + + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclPrivate.cs b/tools/model_generator_dotnet/SCLParser/src/SclPrivate.cs new file mode 100644 index 00000000..dea3cc33 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclPrivate.cs @@ -0,0 +1,32 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclPrivate : SclBaseElement + { + internal SclPrivate(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode) + : base(xmlDocument, sclDocument, xmlNode) + { + } + + public string Type + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, xmlNode, "type", value); + } + } + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclSMVControl.cs b/tools/model_generator_dotnet/SCLParser/src/SclSMVControl.cs new file mode 100644 index 00000000..20ba12e4 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclSMVControl.cs @@ -0,0 +1,309 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System; +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclSMVControl + { + internal XmlNode xmlNode; + private XmlDocument xmlDocument; + private SclSmvOpts smvOpts = null; + + public SclSMVControl(SclDocument SclxmlDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.xmlNode = xmlNode; + xmlDocument = SclxmlDocument.XmlDocument; + + XmlAttribute nameAttr = xmlNode.Attributes["name"]; + + if (nameAttr == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "SMVControl has no name attribute", this, "MissingName"); + + XmlNode smvOptsNode = xmlNode.SelectSingleNode("scl:SmvOpts", nsManager); + + if (smvOptsNode != null) + smvOpts = new SclSmvOpts(xmlDocument, smvOptsNode); + } + + + public SclSmvOpts SclSmvOpts + { + get + { + return smvOpts; + } + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + public string DataSet + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "datSet"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "datSet", value); + } + } + + + public int ConfRev + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "confRev"); + + if (valStr != null) + { + int retVal = -1; + Int32.TryParse(valStr, out retVal); + + return (retVal); + } + else + return (-1); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "confRev", value.ToString()); + } + } + + public string SmvID + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "smvID"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "smvID", value); + } + } + + public bool Multicast + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "multicast", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "multicast", value); + } + } + + public int SmpRate + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "smpRate"); + + if (valStr != null) + { + int retVal = -1; + Int32.TryParse(valStr, out retVal); + + return (retVal); + } + else + return (-1); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "smpRate", value.ToString()); + } + + } + + public int NofASDU + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "nofASDU"); + + if (valStr != null) + { + int retVal = -1; + Int32.TryParse(valStr, out retVal); + + return (retVal); + } + else + return (-1); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "nofASDU", value.ToString()); + } + } + + public string SmpMod + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "smpMod"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "smpMod", value); + } + } + + public string SecurityEnabled + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "securityEnabled"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "securityEnabled", value); + } + } + + } + + public class SclSmvOpts + { + internal XmlNode xmlNode = null; + private XmlDocument xmlDocument; + + public bool RefreshTime + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "refreshTime", false); ; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "refreshTime", value); + } + } + + public bool SampleRate + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "sampleRate", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "sampleRate", value); + } + } + + public bool DataSet + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "dataSet", false); ; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "dataSet", value); + } + } + + public bool Security + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "security", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "security", value); + } + } + + public bool SynchSourceId + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "synchSourceId", false); ; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "synchSourceId", value); + } + } + + public bool DataRef + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "dataRef", false); ; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "dataRef", value); + } + } + + public bool SampleSynchronized + { + get + { + return XmlHelper.ParseBooleanAttribute(xmlNode, "sampleSynchronized", false); ; + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "sampleSynchronized", value); + } + } + + public int GetIntValue() + { + int intValue = 0; + + if (RefreshTime) intValue += 1; + if (SampleSynchronized) intValue += 2; + if (SampleRate) intValue += 4; + if (DataSet) intValue += 8; + if (Security) intValue += 16; + + return intValue; + } + + + public SclSmvOpts(XmlDocument xmlDocument, XmlNode xmlNode) + { + this.xmlNode = xmlNode; + this.xmlDocument = xmlDocument; + } + } + +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclServices.cs b/tools/model_generator_dotnet/SCLParser/src/SclServices.cs new file mode 100644 index 00000000..b110fe7c --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclServices.cs @@ -0,0 +1,4797 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclServices + { + public enum BufMode + { + UNBUFFERED, + BUFFERED, + BOTH + } + + public XmlNode XmlNode = null; + + private XmlDocument xmlDocument = null; + + private SclDocument sclDocument = null; + + private bool dynAssociationExists = false; + private int dynAssociationMax = -1; /* -1 => not available */ + + private bool settingGroupsExists = false; + private bool sgEditExists = false; + private bool confSgExists = false; + private bool sgEditResvTms = false; + private bool confSgResvTms = false; + + private bool getDirectoryExists = false; + private bool getDataObjectDefinitionExists = false; + private bool getDataSetValueExists = false; + private bool setDataSetValueExists = false; + private bool dataSetDirectoryExists = false; + + private bool confDataSetExists = false; + private int confDataSetMax = 0; /* maximum number of data sets including the preconfigured ones */ + private int confDataSetMaxAttributes = -1; /* maximum number of data attributes in a data set */ + private bool confDataSetModify = true; /* preconfigured data sets may be modified */ + + private bool dynDataSetExists = false; + private int dynDataSetMax = -1; /* maximum number of dynamic data sets including the preconfigured ones */ + private int dynDataSetMaxAttributes = -1; /* maximum number of data attributes in a data set */ + + private bool readWriteExists = false; /* GetData, SetData, Operate */ + private bool timerActivatedControlExists; + + private bool confReportControlExists = false; /* Capability of static (by configuration via SCL) creation of report control blocks */ + private int confReportControlMax = 0; /* maximum number of RCBs including preconfigured ones */ + private int confReportControlMaxBuf = 0; /* he maximum number of instantiable buffered control blocks. If it is missing, its value is equal to the max value. If supplied, its value shall be smaller than the max value */ + private bool confReportControlBufConf = false; /* if the buffered attribute of a preconfigured report control block can be changed via SCL */ + private BufMode confReportControlBufMode = BufMode.BOTH; + private bool getCBValuesExists = false; + + private bool confLogControlExists = false; /* Capability of static creation of log control blocks */ + private int confLogControlMax = 0; + + private bool reportSettingsExists = false; /* Capability of online setting of RCB attributes */ + private string reportSettingsCbName = null; + private string reportSettingsDatSet = null; + private string reportSettingsRptID = null; + private string reportSettingsOptFields = null; + private string reportSettingsBufTime = null; + private string reportSettingsTrgOps = null; + private string reportSettingsIntgPd = null; + private bool reportSettingsResvTms = false; + private bool reportSettingsOwner = false; + + private bool logSettingsExists = false; /* Capability of online setting of LCB attributes */ + private string logSettingsCbName = null; + private string logSettingsDatSet = null; + private string logSettingsLogEna = null; + private string logSettingsTrgOps = null; + private string logSettingsIntgPd = null; + + private bool gseSettingsExists = false; /* Capability of online setting of GSE-CB attributes */ + private bool gseSettingsCbName = false; + private string gseCbName = null; + private string gseDataSet = null; + private string gseAppID = null; + private string gseDataLabel = null; + private bool gseSettingsDatSet = false; + private bool gseSettingsKdaParticipant = false; + private bool gseSettingsMcSecurity = false; + private bool gseSettingsAppId = false; + private bool gseSettingsDataLabel = false; /* only for GSSE control blocks */ + + private bool smvSettingsExists = false; /* Capability of online setting of SMV-CB attributes */ + private string smvSettingsCbName = null; + private string smvSettingsDatSet = null; + private string smvSettingsSvId = null; + private string smvSettingsOptFields = null; + private string smvSettingsSmpRate = null; + private string smvSettingsNofASDU = null; + private bool smvSettingsSamplesPerSec = false; + private bool smvSettingsSynchrSrcId = false; + private bool smvSettingsPdcTimeStamp = false; + private bool smvSettingsKdaParticipant = false; + private bool smvSettingsSmpRateElement = false; + private int smvSettingsSmpRateElementVal = 0; + private bool smvSettingsSamplesPerSecElement = false; + private int smvSettingsSamplesPerSecElementVal = 0; + private bool smvSettingsSecPerSamplesElement = false; + private int smvSettingsSecPerSamplesElementVal = 0; + + private bool confLNsExists = false; /* Defines what can be configured for LNs defined in an ICD file */ + private bool confLNsFixPrefix = true; + private bool confLNsFixLnInst = true; + + private bool confLdNameExists = false; + + private bool valueHandlingExists = false; + + private bool gseDirExists = false; + + private bool gooseExists = false; + private bool gooseFixedOffs = false; + private bool gooseGoose = false; + private bool gooseRGOOSE = false; + private int gooseMax = 0; /* max number of GOOSE CBs that are configurable for publishing; 0 = only client */ + + private bool gsseExists = false; + private int gsseMax = 0; /* max number of GSSE CBs that are configurable for publishing; 0 = only client */ + + private bool smvScExists = false; /* IED can be a SMV server or client */ + private bool smvScDeliveryConf = false; + private bool smvScSv = false; + private bool smvScRSV = false; + private int smvScMax = 0; /* max number of SMV CBs that are configurable for publishing; 0 = only client */ + + private bool fileHandlingExists = false; + private bool fileHandlingFtps = false; + private bool fileHandlingMms = false; + private bool fileHandlingFtp = false; + + private bool commProtExists = false; + private bool commProtIpv6 = false; + + private bool timeSyncProtExists = false; + private bool timeSyncProtOther = false; + private bool timeSyncProtIc61850_9_3 = false; + private bool timeSyncProtC37_238 = false; + private bool timeSyncProtSntp = false; + + private bool redProtExists = false; + private bool redProtRstp = false; + private bool redProtPrp = false; + private bool redProtHsr = false; + + private bool mcSecurityExists = false; + private bool mcSecurityEncryption = false; + private bool mcSecuritySignature = false; + + private bool dataObjectDirectoryExists = false; + + private bool supSubscriptionExists = false; /* Capability to supervise GOOSE or SMV subscriptions */ + //private int supSubscriptionMaxGO = 0; /* maximum number of subscription supervision LNs to be instantiated in the IED */ + private int supSubscriptionMaxGo = 0; + private int supSubscriptionMaxSv = 0; + + private bool confSigRefExists = false; /* Capability to include input references into logical nodes */ + private int confSigRefMax = 0; + + private int nameLength = 32; + + + public bool DynDataSetExists + { + get + { + return dynDataSetExists; + } + set + { + dynDataSetExists = value; + } + } + public DynDataSet DynDataSet + { + get { return dynDataSet; } + set { dynDataSet = value; } + } + public bool DeleteDynDataSetServices() + { + if (dynDataSet != null) + { + XmlNode.RemoveChild(dynDataSet.XmlNode); + dynDataSet = null; + DynDataSetExists = false; + + return true; + + } + + return false; + } + + public int DynDataSetMax + { + get + { + return dynDataSetMax; + } + set + { + dynDataSetMax = value; + } + } + public int DynDataSetMaxAttributes + { + get + { + return dynDataSetMaxAttributes; + } + set + { + dynDataSetMaxAttributes = value; + } + } + + + public bool ReadWriteExists + { + get + { + return readWriteExists; + } + set + { + readWriteExists = value; + } + } + public ReadWrite ReadWrite + { + get { return readWrite; } + set { readWrite = value; } + } + public bool DeleteReadWriteServices() + { + if (readWrite != null) + { + XmlNode.RemoveChild(readWrite.XmlNode); + readWrite = null; + ReadWriteExists = false; + + return true; + + } + + return false; + } + + public bool TimerActivatedControlExists + { + get + { + return timerActivatedControlExists; + } + set + { + timerActivatedControlExists = value; + } + } + public TimerActivatedControl TimerActivatedControl + { + get { return timerActivatedControl; } + set { timerActivatedControl = value; } + } + public bool DeleteTimerActivatedControlServices() + { + if (timerActivatedControl != null) + { + XmlNode.RemoveChild(timerActivatedControl.XmlNode); + timerActivatedControl = null; + TimerActivatedControlExists = false; + + return true; + + } + + return false; + } + + public bool ConfReportControlExists + { + get + { + return confReportControlExists; + } + set + { + confReportControlExists = value; + } + } + public ConfReportControl ConfReportControl + { + get { return confReportControl; } + set { confReportControl = value; } + } + public bool DeleteConfReportControlServices() + { + if (confReportControl != null) + { + XmlNode.RemoveChild(confReportControl.XmlNode); + confReportControl = null; + ConfReportControlExists = false; + + return true; + + } + + return false; + } + + public int ConfReportControlMax + { + get + { + return confReportControlMax; + } + set + { + confReportControlMax = value; + } + } + public int ConfReportControlMaxBuf + { + get + { + return confReportControlMaxBuf +; + } + set + { + confReportControlMaxBuf = value; + } + } + public BufMode ConfReportControlBufMode + { + get + { + return confReportControlBufMode; + } + set + { + confReportControlBufMode = value; + } + } + public bool ConfReportControlBufConf + { + get + { + return confReportControlBufConf; + } + set + { + confReportControlBufConf = value; + } + } + + + + public bool GetCBValuesExists + { + get + { + return getCBValuesExists; + } + set + { + getCBValuesExists = value; + } + } + public GetCBValues GetCBValues + { + get { return getCBValues; } + set { getCBValues = value; } + } + public bool DeleteGetCBValuesServices() + { + if (getCBValues != null) + { + XmlNode.RemoveChild(getCBValues.XmlNode); + getCBValues = null; + GetCBValuesExists = false; + + return true; + + } + + return false; + } + + public bool ConfLogControlExists + { + get + { + return confLogControlExists; + } + set + { + confLogControlExists = value; + } + } + public ConfLogControl ConfLogControl + { + get { return confLogControl; } + set { confLogControl = value; } + } + public bool DeleteConfLogControlServices() + { + if (confLogControl != null) + { + XmlNode.RemoveChild(confLogControl.XmlNode); + confLogControl = null; + ConfLogControlExists = false; + + return true; + + } + + return false; + } + + public int ConfLogControlMax + { + get + { + return confLogControlMax; + } + set + { + confLogControlMax = value; + } + } + + + + public bool ReportSettingsExists + { + get + { + return reportSettingsExists; + } + set + { + reportSettingsExists = value; + } + } + public ReportSettings ReportSettings + { + get { return reportSettings; } + set { reportSettings = value; } + } + public bool DeleteReportSettingsServices() + { + if (reportSettings != null) + { + XmlNode.RemoveChild(reportSettings.XmlNode); + reportSettings = null; + ReportSettingsExists = false; + + return true; + + } + + return false; + } + + public string ReportSettingsCbName + { + get + { + return reportSettingsCbName; + } + set + { + reportSettingsCbName = value; + } + } + public string ReportSettingsDatSet + { + get + { + return reportSettingsDatSet; + } + set + { + reportSettingsDatSet = value; + } + } + public string ReportSettingsRptID + { + get + { + return reportSettingsRptID; + } + set + { + reportSettingsRptID = value; + } + } + public string ReportSettingsOptFields + { + get + { + return reportSettingsOptFields; + } + set + { + reportSettingsOptFields = value; + } + } + public string ReportSettingsBufTime + { + get + { + return reportSettingsBufTime; + } + set + { + reportSettingsBufTime = value; + } + } + public string ReportSettingsTrgOps + { + get + { + return reportSettingsTrgOps; + } + set + { + reportSettingsTrgOps = value; + } + } + public string ReportSettingsIntgPd + { + get + { + return reportSettingsIntgPd; + } + set + { + reportSettingsIntgPd = value; + } + } + public bool ReportSettingsResvTms + { + get + { + return reportSettingsResvTms; + } + set + { + reportSettingsResvTms = value; + } + } + public bool ReportSettingsOwner + { + get + { + return reportSettingsOwner; + } + set + { + reportSettingsOwner = value; + } + } + + + + public bool LogSettingsExists + { + get + { + return logSettingsExists; + } + set + { + logSettingsExists = value; + } + } + public LogSettings LogSettings + { + get { return logSettings; } + set { logSettings = value; } + } + public bool DeleteLogSettingsServices() + { + if (logSettings != null) + { + XmlNode.RemoveChild(logSettings.XmlNode); + logSettings = null; + LogSettingsExists = false; + + return true; + + } + + return false; + } + + public string LogSettingsCbName + { + get + { + return logSettingsCbName; + } + set + { + logSettingsCbName = value; + } + } + public string LogSettingsDatSet + { + get + { + return logSettingsDatSet; + } + set + { + logSettingsDatSet = value; + } + } + public string LogSettingsLogEna + { + get + { + return logSettingsLogEna; + } + set + { + logSettingsLogEna = value; + } + } + public string LogSettingsTrgOps + { + get + { + return logSettingsTrgOps; + } + set + { + logSettingsTrgOps = value; + } + } + public string LogSettingsIntgPd + { + get + { + return logSettingsIntgPd; + } + set + { + logSettingsIntgPd = value; + } + } + + + + public bool GseSettingsExists + { + get + { + return gseSettingsExists; + } + set + { + gseSettingsExists = value; + } + } + public GSESettings GSESettings + { + get { return gseSettings; } + set { gseSettings = value; } + + } + public bool DeleteGSESettingsServices() + { + if (gseSettings != null) + { + XmlNode.RemoveChild(gseSettings.XmlNode); + gseSettings = null; + GseSettingsExists = false; + + return true; + + } + + return false; + } + + public string GseCbName + { + get + { + return gseCbName; + } + set + { + gseCbName = value; + } + } + public string GseDatSet + { + get + { + return gseDataSet; + } + set + { + gseDataSet = value; + } + } + public string GseAppID + { + get + { + return gseAppID; + } + set + { + gseAppID = value; + } + } + public string GseDataLabel + { + get + { + return gseDataLabel; + } + set + { + gseDataLabel = value; + } + } + public bool GseSettingsKdaParticipant + { + get + { + return gseSettingsKdaParticipant; + } + set + { + gseSettingsKdaParticipant = value; + } + } + public bool GseSettingsMcSecurity + { + get + { + return gseSettingsMcSecurity; + } + set + { + gseSettingsMcSecurity = value; + } + } + public bool GseSettingsCbName + { + get + { + return gseSettingsCbName; + } + set + { + gseSettingsCbName = value; + } + } + public bool GseSettingsDatSet + { + get + { + return gseSettingsDatSet; + } + set + { + gseSettingsDatSet = value; + } + } + public bool GseSettingsAppId + { + get + { + return gseSettingsAppId; + } + set + { + gseSettingsAppId = value; + } + } + public bool GseSettingsDataLabel + { + get + { + return gseSettingsDataLabel; + } + set + { + gseSettingsDataLabel = value; + } + } + + + + public bool SmvSettingsExists + { + get + { + return smvSettingsExists; + } + set + { + smvSettingsExists = value; + } + } + public SMVSettings SMVSettings + { + get { return smvSettings; } + set { smvSettings = value; } + } + public bool DeleteSMVSettingsServices() + { + if (smvSettings != null) + { + XmlNode.RemoveChild(smvSettings.XmlNode); + smvSettings = null; + SmvSettingsExists = false; + + return true; + + } + + return false; + } + + public string SmvSettingsCbName + { + get + { + return smvSettingsCbName; + } + set + { + smvSettingsCbName = value; + } + } + public string SmvSettingsDatSet + { + get + { + return smvSettingsDatSet; + } + set + { + smvSettingsDatSet = value; + } + } + public string SmvSettingsSvId + { + get + { + return smvSettingsSvId; + } + set + { + smvSettingsSvId = value; + } + } + public string SmvSettingsOptFields + { + get + { + return smvSettingsOptFields; + } + set + { + smvSettingsOptFields = value; + } + } + public string SmvSettingsSmpRate + { + get + { + return smvSettingsSmpRate; + } + set + { + smvSettingsSmpRate = value; + } + } + public string SmvSettingsNofASDU + { + get + { + return smvSettingsNofASDU; + } + set + { + smvSettingsNofASDU = value; + } + } + public bool SmvSettingsSamplesPerSec + { + get + { + return smvSettingsSamplesPerSec; + } + set + { + smvSettingsSamplesPerSec = value; + } + } + public bool SmvSettingsSynchrSrcId + { + get + { + return smvSettingsSynchrSrcId; + } + set + { + smvSettingsSynchrSrcId = value; + } + } + public bool SmvSettingsPdcTimeStamp + { + get + { + return smvSettingsPdcTimeStamp; + } + set + { + smvSettingsPdcTimeStamp = value; + } + } + public bool SmvSettingsKdaParticipant + { + get + { + return smvSettingsKdaParticipant; + } + set + { + smvSettingsKdaParticipant = value; + } + } + public bool SmvSettingsSamplesPerSecElement + { + get + { + return smvSettingsSamplesPerSecElement; + } + set + { + smvSettingsSamplesPerSecElement = value; + } + } + public int SmvSettingsSamplesPerSecElementVal + { + get + { + return smvSettingsSamplesPerSecElementVal; + } + set + { + smvSettingsSamplesPerSecElementVal = value; + } + } + public bool SmvSettingsSmpRateElement + { + get + { + return smvSettingsSmpRateElement; + } + set + { + smvSettingsSmpRateElement = value; + } + } + public int SmvSettingsSmpRateElementVal + { + get + { + return smvSettingsSmpRateElementVal; + } + set + { + smvSettingsSmpRateElementVal = value; + } + } + public bool SmvSettingsSecPerSamplesElement + { + get + { + return smvSettingsSecPerSamplesElement; + } + set + { + smvSettingsSecPerSamplesElement = value; + } + } + public int SmvSettingsSecPerSamplesElementVal + { + get + { + return smvSettingsSecPerSamplesElementVal; + } + set + { + smvSettingsSecPerSamplesElementVal = value; + } + } + + + public bool ConfLNsExists + { + get + { + return confLNsExists; + } + set + { + confLNsExists = value; + } + } + public ConfLNs ConfLNs + { + get { return confLNs; } + set { confLNs = value; } + } + public bool DeleteConfLNsServices() + { + if (confLNs != null) + { + XmlNode.RemoveChild(confLNs.XmlNode); + confLNs = null; + ConfLNsExists = false; + + return true; + + } + + return false; + } + + public bool ConfLNsFixPrefix + { + get + { + return confLNsFixPrefix; + } + set + { + confLNsFixPrefix = value; + } + } + public bool ConfLNsFixLnInst + { + get + { + return confLNsFixLnInst; + } + set + { + confLNsFixLnInst = value; + } + } + + + public bool ConfLdNameExists + { + get + { + return confLdNameExists; + } + set + { + confLdNameExists = value; + } + } + public ConfLdName ConfLdName + { + get { return confLdName; } + set { confLdName = value; } + } + public bool DeleteConfLdNameServices() + { + if (confLdName != null) + { + XmlNode.RemoveChild(confLdName.XmlNode); + confLdName = null; + ConfLdNameExists = false; + + return true; + + } + + return false; + } + + public bool GseDirExists + { + get + { + return gseDirExists; + } + set + { + gseDirExists = value; + } + + + } + public GSEDir GSEDir + { + get { return gseDir; } + set { gseDir = value; } + } + public bool DeleteGSEDirServices() + { + if (gseDir != null) + { + XmlNode.RemoveChild(gseDir.XmlNode); + gseDir = null; + GseDirExists = false; + + return true; + + } + + return false; + } + + public bool GooseExists + { + get + { + return gooseExists; + } + set + { + gooseExists = value; + } + } + public GOOSE GOOSE + { + get { return goose; } + set { goose = value; } + } + public bool DeleteGOOSEServices() + { + if (goose != null) + { + XmlNode.RemoveChild(goose.XmlNode); + goose = null; + GooseExists = false; + + return true; + + } + + return false; + } + + public bool GooseFixedOffs + { + get + { + return gooseFixedOffs; + } + set + { + gooseFixedOffs = value; + } + } + public bool GooseGoose + { + get + { + return gooseGoose; + } + set + { + gooseGoose = value; + } + } + public bool GooseRGOOSE + { + get + { + return gooseRGOOSE; + } + set + { + gooseRGOOSE = value; + } + } + public int GooseMax + { + get + { + return gooseMax; + } + set + { + gooseMax = value; + } + } + + + + public bool GsseExists + { + get + { + return gsseExists; + } + set + { + gsseExists = value; + } + } + public GSSE GSSE + { + get { return gsse; } + set { gsse = value; } + } + public bool DeleteGSSEServices() + { + if (gsse != null) + { + XmlNode.RemoveChild(gsse.XmlNode); + gsse = null; + GsseExists = false; + + return true; + + } + + return false; + } + + public int GsseMax + { + get + { + return gsseMax; + } + set + { + gsseMax = value; + } + } + + + + public bool SmvScExists + { + get + { + return smvScExists; + } + set + { + smvScExists = value; + } + } + public SMVsc SMVsc + { + get { return sMVsc; } + set { sMVsc = value; } + } + public bool DeleteSMVscServices() + { + if (sMVsc != null) + { + XmlNode.RemoveChild(sMVsc.XmlNode); + sMVsc = null; + SmvScExists = false; + + return true; + + } + + return false; + } + + public bool SmvScDeliveryConf + { + get + { + return smvScDeliveryConf; + } + set + { + smvScDeliveryConf = value; + } + } + public bool SmvScSv + { + get + { + return smvScSv; + } + set + { + smvScSv = value; + } + } + public bool SmvScRSV + { + get + { + return smvScRSV; + } + set + { + smvScRSV = value; + } + } + public int SmvScMax + { + get + { + return smvScMax; + } + set + { + smvScMax = value; + } + } + + + + public bool FileHandlingExists + { + get + { + return fileHandlingExists; + } + set + { + fileHandlingExists = value; + } + } + public FileHandling FileHandling + { + get { return fileHandling; } + set { fileHandling = value; } + } + public bool DeleteFileHandlingServices() + { + if (fileHandling != null) + { + XmlNode.RemoveChild(fileHandling.XmlNode); + fileHandling = null; + FileHandlingExists = false; + + return true; + + } + + return false; + } + + public bool FileHandlingFtps + { + get + { + return fileHandlingFtps; + } + set + { + fileHandlingFtps = value; + } + } + public bool FileHandlingMms + { + get + { + return fileHandlingMms; + } + set + { + fileHandlingMms = value; + } + } + public bool FileHandlingFtp + { + get + { + return fileHandlingFtp; + } + set + { + fileHandlingFtp = value; + } + } + + + + public bool SupSubscriptionExists + { + get + { + return supSubscriptionExists; + } + set + { + supSubscriptionExists = value; + } + } + public SupSubscription SupSubscription + { + get { return supSubscription; } + set { supSubscription = value; } + } + public bool DeleteSupSubscriptionServices() + { + if (supSubscription != null) + { + XmlNode.RemoveChild(supSubscription.XmlNode); + supSubscription = null; + SupSubscriptionExists = false; + + return true; + + } + + return false; + } + + public int SupSubscriptionMaxGo + { + get + { + return supSubscriptionMaxGo; + } + set + { + supSubscriptionMaxGo = value; + } + } + public int SupSubscriptionMaxSv + { + get + { + return supSubscriptionMaxSv; + } + set + { + supSubscriptionMaxSv = value; + } + } + + + + public bool ConfSigRefExists + { + get + { + return confSigRefExists; + } + set + { + confSigRefExists = value; + } + } + public ConfSigRef ConfSigRef + { + get { return confSigRef; } + set { confSigRef = value; } + } + public bool DeleteConfSigRefServices() + { + if (confSigRef != null) + { + XmlNode.RemoveChild(confSigRef.XmlNode); + confSigRef = null; + ConfSigRefExists = false; + + return true; + + } + + return false; + } + + public int ConfSigRefMax + { + get + { + return confSigRefMax; + } + set + { + confSigRefMax = value; + } + } + + + + public bool CommProtExists + { + get + { + return commProtExists; + } + set + { + commProtExists = value; + } + } + public CommProt CommProt + { + get { return commProt; } + set { commProt = value; } + } + public bool DeleteCommProtServices() + { + if (commProt != null) + { + XmlNode.RemoveChild(commProt.XmlNode); + commProt = null; + CommProtExists = false; + + return true; + + } + + return false; + } + public bool CommProtIpv6 + { + get + { + return commProtIpv6; + } + set + { + commProtIpv6 = value; + } + } + + + + public bool TimeSyncProtExists + { + get + { + return timeSyncProtExists; + } + set + { + timeSyncProtExists = value; + } + } + public TimeSyncProt TimeSyncProt + { + get { return timeSyncProt; } + set { timeSyncProt = value; } + } + public bool DeleteTimeSyncProtServices() + { + if (timeSyncProt != null) + { + XmlNode.RemoveChild(timeSyncProt.XmlNode); + timeSyncProt = null; + TimeSyncProtExists = false; + + return true; + + } + + return false; + } + + public bool TimeSyncProtC37_238 + { + get + { + return timeSyncProtC37_238; + } + set + { + timeSyncProtC37_238 = value; + } + } + public bool TimeSyncProtIc61850_9_3 + { + get + { + return timeSyncProtIc61850_9_3; + } + set + { + timeSyncProtIc61850_9_3 = value; + } + } + public bool TimeSyncProtOther + { + get + { + return timeSyncProtOther; + } + set + { + timeSyncProtOther = value; + } + } + public bool TimeSyncProtSntp + { + get + { + return timeSyncProtSntp; + } + set + { + timeSyncProtSntp = value; + } + } + + + + public bool RedProtExists + { + get + { + return redProtExists; + } + set + { + redProtExists = value; + } + } + public RedProt RedProt + { + get { return redProt; } + set { redProt = value; } + } + public bool DeleteRedProtServices() + { + if (redProt != null) + { + XmlNode.RemoveChild(redProt.XmlNode); + redProt = null; + RedProtExists = false; + + return true; + + } + + return false; + } + + public bool RedProtHsr + { + get + { + return redProtHsr; + } + set + { + redProtHsr = value; + } + } + public bool RedProtPrp + { + get + { + return redProtPrp; + } + set + { + redProtPrp = value; + } + } + public bool RedProtRstp + { + get + { + return redProtRstp; + } + set + { + redProtRstp = value; + } + } + + + public bool ValueHandlingExists + { + get + { + return valueHandlingExists; + } + set + { + valueHandlingExists = value; + } + } + public ValueHandling ValueHandling + { + get { return valueHandling; } + set { valueHandling = value; } + } + public bool DeleteValueHandlingServices() + { + if (valueHandling != null) + { + XmlNode.RemoveChild(valueHandling.XmlNode); + valueHandling = null; + ValueHandlingExists = false; + + return true; + + } + + return false; + } + + public bool McSecurityExists + { + get + { + return mcSecurityExists; + } + set + { + mcSecurityExists = value; + } + } + public McSecurity McSecurity + { + get { return mcSecurity; } + set { mcSecurity = value; } + } + public bool DeleteMcSecurityServices() + { + if (mcSecurity != null) + { + XmlNode.RemoveChild(mcSecurity.XmlNode); + mcSecurity = null; + McSecurityExists = false; + return true; + + } + + return false; + } + + public bool McSecurityEncryption + { + get + { + return mcSecurityEncryption; + } + set + { + mcSecurityEncryption = value; + } + } + public bool McSecuritySignature + { + get + { + return mcSecuritySignature; + } + set + { + mcSecuritySignature = value; + } + } + + + + + public bool DataObjectDirectoryExists + { + get + { + return dataObjectDirectoryExists; + } + set + { + dataObjectDirectoryExists = value; + } + } + public DataObjectDirectory DataObjectDirectory + { + get { return dataObjectDirectory; } + set { dataObjectDirectory = value; } + } + public bool DeleteDataObjectDirectoryServices() + { + if (dataObjectDirectory != null) + { + XmlNode.RemoveChild(dataObjectDirectory.XmlNode); + dataObjectDirectory = null; + DataObjectDirectoryExists = false; + return true; + + } + + return false; + } + + public int NameLength + { + get + { + return nameLength; + } + set + { + nameLength = value; + } + } + + + public ClientServices ClientServices + { + get + { + return clientServices; + } + set + { + clientServices = value; + } + + + } + public bool DeleteClientServices() + { + if (clientServices != null) + { + XmlNode.RemoveChild(clientServices.XmlNode); + clientServices = null; + + + return true; + + } + + return false; + } + + public bool DynAssociationExists + { + get + { + return dynAssociationExists; + } + set + { + dynAssociationExists = value; + } + } + public DynAssociation DynAssociation + { + get + { + return dynAssociation; + } + set + { + dynAssociation = value; + } + } + public bool DeleteDynAssociation() + { + if (dynAssociation != null) + { + XmlNode.RemoveChild(dynAssociation.XmlNode); + dynAssociation = null; + dynAssociationExists = false; + + return true; + + } + + return false; + } + + public int DynAssociationMax + { + get + { + return dynAssociationMax; + } + set + { + dynAssociationMax = value; + } + } + + + + public bool SettingGroupsExists + { + get + { + return settingGroupsExists; + } + set + { + settingGroupsExists = value; + } + } + public SettingGroups SettingGroups + { + get + { + return settingGroups; + } + set + { + settingGroups = value; + } + } + public bool SgEditExists + { + get + { + return sgEditExists; + } + set + { + sgEditExists = value; + } + } + public bool SgEditResvTms + { + get + { + return sgEditResvTms; + } + set + { + sgEditResvTms = value; + } + } + public bool ConfSgExists + { + get + { + return confSgExists; + } + set + { + confSgExists = value; + } + } + public bool ConfSgResvTms + { + get + { + return confSgResvTms; + } + set + { + confSgResvTms = value; + } + } + public bool DeleteSettingGroups() + { + if (settingGroups != null) + { + XmlNode.RemoveChild(settingGroups.XmlNode); + + settingGroups = null; + settingGroupsExists = false; + + return true; + + } + + return false; + } + + public bool GetDirectoryExists + { + get + { + return getDirectoryExists; + } + set + { + getDirectoryExists = value; + } + + + } + public GetDirectory GetDirectory + { + get { return getDirectory; } + set { getDirectory = value; } + } + public bool DeleteGetDirectoryServices() + { + if (getDirectory != null) + { + XmlNode.RemoveChild(getDirectory.XmlNode); + getDirectory = null; + getDirectoryExists = false; + return true; + + } + + return false; + } + + public bool GetDataObjectDefinitionExists + { + get + { + return getDataObjectDefinitionExists; + } + set + { + getDataObjectDefinitionExists = value; + } + + + } + public GetDataObjectDefinition GetDataObjectDefinition + { + get { return getDataObjectDefinition; } + set { getDataObjectDefinition = value; } + } + public bool DeleteGetDataObjectDefinitionServices() + { + if (getDataObjectDefinition != null) + { + XmlNode.RemoveChild(getDataObjectDefinition.XmlNode); + getDataObjectDefinition = null; + GetDataObjectDefinitionExists = false; + return true; + } + return false; + } + + public bool GetDataSetValueExists + { + get + { + return getDataSetValueExists; + } + set + { + getDataSetValueExists = value; + } + + + } + public GetDataSetValue GetDataSetValue + { + get { return getDataSetValue; } + set { getDataSetValue = value; } + } + public bool DeleteGetDataSetValueServices() + { + if (getDataSetValue != null) + { + XmlNode.RemoveChild(getDataSetValue.XmlNode); + getDataSetValue = null; + GetDataSetValueExists = false; + return true; + } + return false; + } + + public bool SetDataSetValueExists + { + get + { + return setDataSetValueExists; + } + set + { + setDataSetValueExists = value; + } + + } + public SetDataSetValue SetDataSetValue + { + get { return setDataSetValue; } + set { setDataSetValue = value; } + } + public bool DeleteSetDataSetValueServices() + { + if (setDataSetValue != null) + { + XmlNode.RemoveChild(setDataSetValue.XmlNode); + setDataSetValue = null; + SetDataSetValueExists = false; + return true; + } + return false; + } + + + public bool DataSetDirectoryExists + { + get + { + return dataSetDirectoryExists; + } + set + { + dataSetDirectoryExists = value; + } + + + } + public DataSetDirectory DataSetDirectory + { + get { return dataSetDirectory; } + set { dataSetDirectory = value; } + } + public bool DeleteDataSetDirectoryServices() + { + if (dataSetDirectory != null) + { + XmlNode.RemoveChild(dataSetDirectory.XmlNode); + dataSetDirectory = null; + DataSetDirectoryExists = false; + return true; + } + return false; + } + + public bool ConfDataSetExists + { + get + { + return confDataSetExists; + } + set + { + confDataSetExists = value; + } + } + public ConfDataSet ConfDataSet + { + get { return confDataSet; } + set { confDataSet = value; } + } + public bool DeleteConfDataSetServices() + { + if (confDataSet != null) + { + XmlNode.RemoveChild(confDataSet.XmlNode); + confDataSet = null; + ConfDataSetExists = false; + return true; + } + return false; + } + + public int ConfDataSetMax + { + get + { + return confDataSetMax; + } + set + { + confDataSetMax = value; + } + } + public int ConfDataSetMaxAttributes + { + get + { + return confDataSetMaxAttributes; + } + set + { + confDataSetMaxAttributes = value; + } + } + public bool ConfDataSetModify + { + get + { + return confDataSetModify; + } + set + { + confDataSetModify = value; + } + } + + + private ClientServices clientServices = null; + private TimeSyncProt timeSyncProt = null; + private McSecurity mcSecurity = null; + private DynAssociation dynAssociation = null; + private SettingGroups settingGroups = null; + private GetDirectory getDirectory = null; + private GetDataObjectDefinition getDataObjectDefinition = null; + private DataObjectDirectory dataObjectDirectory = null; + private GetDataSetValue getDataSetValue = null; + private SetDataSetValue setDataSetValue = null; + private DataSetDirectory dataSetDirectory = null; + private ConfDataSet confDataSet = null; + private DynDataSet dynDataSet = null; + private ReadWrite readWrite = null; + private TimerActivatedControl timerActivatedControl = null; + private ConfReportControl confReportControl = null; + private GetCBValues getCBValues = null; + private ConfLogControl confLogControl = null; + private ReportSettings reportSettings = null; + private LogSettings logSettings = null; + private GSESettings gseSettings = null; + private SMVSettings smvSettings = null; + private ConfLNs confLNs = null; + private ConfLdName confLdName = null; + private GSEDir gseDir = null; + private GOOSE goose = null; + private GSSE gsse = null; + private SMVsc sMVsc = null; + private FileHandling fileHandling = null; + private SupSubscription supSubscription = null; + private ConfSigRef confSigRef = null; + private CommProt commProt = null; + private RedProt redProt = null; + private ValueHandling valueHandling = null; + + + public SclServices(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + XmlNode = xmlNode; + xmlDocument = xmlDocument; + this.sclDocument = sclDocument; + + string nameLengthAttribute = XmlHelper.GetAttributeValue(xmlNode, "nameLength"); + if (nameLengthAttribute != null) + { + if (int.TryParse(nameLengthAttribute, out int intNameLength)) + { + if (intNameLength != 64 && intNameLength != 32) + { + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "NameLength attribute on IED services should be 32 default or 64. Value is " + nameLengthAttribute, this, "nameLength"); + nameLength = intNameLength; + } + } + else + { + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "NameLength attribute on IED services is not a integer. Value is " + nameLengthAttribute, this, "nameLength"); + } + + } + else + { + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "No nameLength attribute on IED services", this, "nameLength"); + } + + XmlNode clientServices = xmlNode.SelectSingleNode("scl:ClientServices", nsManager); + if (clientServices != null) + { + ClientServices = new ClientServices(sclDocument, clientServices, nsManager); + } + + + XmlNode DynAssociationNode = xmlNode.SelectSingleNode("scl:DynAssociation", nsManager); + if (DynAssociationNode != null) + { + DynAssociationExists = true; + DynAssociation = new DynAssociation(sclDocument, DynAssociationNode, nsManager); + + } + + + XmlNode SettingGroupsNode = xmlNode.SelectSingleNode("scl:SettingGroups", nsManager); + if (SettingGroupsNode != null) + { + SettingGroupsExists = true; + SettingGroups = new SettingGroups(sclDocument, SettingGroupsNode, nsManager); + + //XmlNode SGEditNode = SettingGroupsNode.SelectSingleNode("scl:SGEdit", nsManager); + //if (SGEditNode != null) + //{ + // SgEditExists = true; + + // string resvTms = XmlHelper.GetAttributeValue(SGEditNode, "resvTms"); + // if (resvTms != null) + // { + // if (resvTms == "true") + // SgEditResvTms = true; + // else + // SgEditResvTms = false; + + + // } + + + //} + //else + // SgEditExists = false; + + //XmlNode confSGNode = SettingGroupsNode.SelectSingleNode("scl:ConfSG", nsManager); + //if (confSGNode != null) + //{ + // ConfSgExists = true; + + // string resvTms = XmlHelper.GetAttributeValue(confSGNode, "resvTms"); + // if (resvTms != null) + // { + // if (resvTms == "true") + // ConfSgResvTms = true; + // else + // ConfSgResvTms = false; + + + // } + + + //} + //else + // ConfSgExists = false; + + } + + + XmlNode GetDirectoryNode = xmlNode.SelectSingleNode("scl:GetDirectory", nsManager); + if (GetDirectoryNode != null) + { + GetDirectoryExists = true; + GetDirectory = new GetDirectory(sclDocument, GetDirectoryNode, nsManager); + } + + + XmlNode GetDataObjectDefinitionNode = xmlNode.SelectSingleNode("scl:GetDataObjectDefinition", nsManager); + if (GetDataObjectDefinitionNode != null) + { + GetDataObjectDefinitionExists = true; + GetDataObjectDefinition = new GetDataObjectDefinition(sclDocument, GetDataObjectDefinitionNode, nsManager); + } + + + XmlNode DataObjectDirectoryNode = xmlNode.SelectSingleNode("scl:DataObjectDirectory", nsManager); + if (DataObjectDirectoryNode != null) + { + DataObjectDirectoryExists = true; + DataObjectDirectory = new DataObjectDirectory(sclDocument, DataObjectDirectoryNode, nsManager); + } + + + XmlNode GetDataSetValueNode = xmlNode.SelectSingleNode("scl:GetDataSetValue", nsManager); + if (GetDataSetValueNode != null) + { + GetDataSetValueExists = true; + GetDataSetValue = new GetDataSetValue(sclDocument, GetDataSetValueNode, nsManager); + } + + + XmlNode SetDataSetValueNode = xmlNode.SelectSingleNode("scl:SetDataSetValue", nsManager); + if (SetDataSetValueNode != null) + { + SetDataSetValueExists = true; + SetDataSetValue = new SetDataSetValue(sclDocument, SetDataSetValueNode, nsManager); + } + + + XmlNode DataSetDirectoryNode = xmlNode.SelectSingleNode("scl:DataSetDirectory", nsManager); + if (DataSetDirectoryNode != null) + { + DataSetDirectoryExists = true; + DataSetDirectory = new DataSetDirectory(sclDocument, DataSetDirectoryNode, nsManager); + } + + + XmlNode ConfDataSetNode = xmlNode.SelectSingleNode("scl:ConfDataSet", nsManager); + if (ConfDataSetNode != null) + { + ConfDataSetExists = true; + ConfDataSet = new ConfDataSet(sclDocument, ConfDataSetNode, nsManager); + + //string attribute = XmlHelper.GetAttributeValue(ConfDataSetNode, "max"); + //if (attribute != null) + // ConfDataSetMax = int.Parse(attribute); + + //string maxAttributes = XmlHelper.GetAttributeValue(ConfDataSetNode, "maxAttributes"); + //if (maxAttributes != null) + // ConfDataSetMaxAttributes = int.Parse(maxAttributes); + + //string modify = XmlHelper.GetAttributeValue(ConfDataSetNode, "modify"); + //if (modify != null) + //{ + // if (modify == "true") + // ConfDataSetModify = true; + + //} + + } + + + XmlNode DynDataSetNode = xmlNode.SelectSingleNode("scl:DynDataSet", nsManager); + if (DynDataSetNode != null) + { + DynDataSetExists = true; + DynDataSet = new DynDataSet(sclDocument, DynDataSetNode, nsManager); + + //string max = XmlHelper.GetAttributeValue(DynDataSetNode, "max"); + //if (max != null) + // DynDataSetMax = int.Parse(max); + + //string maxAttributes = XmlHelper.GetAttributeValue(DynDataSetNode, "maxAttributes"); + //if (maxAttributes != null) + // DynDataSetMaxAttributes = int.Parse(maxAttributes); + + } + + + XmlNode ReadWriteNode = xmlNode.SelectSingleNode("scl:ReadWrite", nsManager); + if (ReadWriteNode != null) + { + ReadWriteExists = true; + ReadWrite = new ReadWrite(sclDocument, ReadWriteNode, nsManager); + } + + + XmlNode TimerActivatedControlNode = xmlNode.SelectSingleNode("scl:TimerActivatedControl", nsManager); + if (TimerActivatedControlNode != null) + { + TimerActivatedControlExists = true; + TimerActivatedControl = new TimerActivatedControl(sclDocument, TimerActivatedControlNode, nsManager); + } + + + XmlNode ConfReportControlNode = xmlNode.SelectSingleNode("scl:ConfReportControl", nsManager); + if (ConfReportControlNode != null) + { + ConfReportControlExists = true; + ConfReportControl = new ConfReportControl(sclDocument, ConfReportControlNode, nsManager); + //string max = XmlHelper.GetAttributeValue(ConfReportControlNode, "max"); + //if (max != null) + // ConfReportControlMax = int.Parse(max); + + //string bufMode = XmlHelper.GetAttributeValue(ConfReportControlNode, "bufMode"); + //if (bufMode != null) + // if (bufMode == "UNBUFFERED") + // ConfReportControlBufMode = BufMode.UNBUFFERED; + // else if (bufMode == "BUFFERED") + // ConfReportControlBufMode = BufMode.BUFFERED; + // else + // ConfReportControlBufMode = BufMode.BOTH; + + //string bufConf = XmlHelper.GetAttributeValue(ConfReportControlNode, "bufConf"); + //if (bufConf != null) + // if (bufConf == "true") + // ConfReportControlBufConf = true; + + + //string maxBuf = XmlHelper.GetAttributeValue(ConfReportControlNode, "maxBuf"); + //if (maxBuf != null) + // ConfReportControlMaxBuf = int.Parse(maxBuf); + + + } + + + XmlNode GetCBValuesNode = xmlNode.SelectSingleNode("scl:GetCBValues", nsManager); + if (GetCBValuesNode != null) + { + GetCBValuesExists = true; + GetCBValues = new GetCBValues(sclDocument, GetCBValuesNode, nsManager); + } + + + XmlNode ConfLogControlNode = xmlNode.SelectSingleNode("scl:ConfLogControl", nsManager); + if (ConfLogControlNode != null) + { + ConfLogControlExists = true; + ConfLogControl = new ConfLogControl(sclDocument, ConfLogControlNode, nsManager); + + //string max = XmlHelper.GetAttributeValue(ConfLogControlNode, "max"); + + //if (max != null) + // ConfLogControlMax = int.Parse(max); + } + + + XmlNode ReportSettingsNode = xmlNode.SelectSingleNode("scl:ReportSettings", nsManager); + if (ReportSettingsNode != null) + { + ReportSettingsExists = true; + ReportSettings = new ReportSettings(sclDocument, ReportSettingsNode, nsManager); + + //string cbName = XmlHelper.GetAttributeValue(ReportSettingsNode, "cbName"); + //if (cbName != null) + // ReportSettingsCbName = cbName; + + //string datSet = XmlHelper.GetAttributeValue(ReportSettingsNode, "datSet"); + //if (datSet != null) + // ReportSettingsDatSet = datSet; + + //string rptID = XmlHelper.GetAttributeValue(ReportSettingsNode, "rptID"); + //if (rptID != null) + // ReportSettingsRptID = rptID; + + //string optFields = XmlHelper.GetAttributeValue(ReportSettingsNode, "optFields"); + //if (optFields != null) + // ReportSettingsOptFields = optFields; + + //string bufTime = XmlHelper.GetAttributeValue(ReportSettingsNode, "bufTime"); + //if (bufTime != null) + // ReportSettingsBufTime = bufTime; + + //string trgOps = XmlHelper.GetAttributeValue(ReportSettingsNode, "trgOps"); + //if (trgOps != null) + // ReportSettingsTrgOps = trgOps; + + //string intgPd = XmlHelper.GetAttributeValue(ReportSettingsNode, "intgPd"); + //if (intgPd != null) + // ReportSettingsIntgPd = intgPd; + + //string resvTms = XmlHelper.GetAttributeValue(ReportSettingsNode, "resvTms"); + //if (resvTms != null) + //{ + // if (resvTms == "true") + // ReportSettingsResvTms = true; + //} + + //string owner = XmlHelper.GetAttributeValue(ReportSettingsNode, "owner"); + //if (owner != null) + //{ + // if (owner == "true") + // ReportSettingsOwner = true; + //} + } + + + XmlNode LogSettingsNode = xmlNode.SelectSingleNode("scl:LogSettings", nsManager); + if (LogSettingsNode != null) + { + LogSettingsExists = true; + LogSettings = new LogSettings(sclDocument, LogSettingsNode, nsManager); + //string cbName = XmlHelper.GetAttributeValue(LogSettingsNode, "cbName"); + //if (cbName != null) + // LogSettingsCbName = cbName; + + //string datSet = XmlHelper.GetAttributeValue(LogSettingsNode, "datSet"); + //if (datSet != null) + // LogSettingsDatSet = datSet; + + //string logEna = XmlHelper.GetAttributeValue(LogSettingsNode, "logEna"); + //if (logEna != null) + // LogSettingsLogEna = logEna; + + //string trgOps = XmlHelper.GetAttributeValue(LogSettingsNode, "trgOps"); + //if (trgOps != null) + // LogSettingsTrgOps = trgOps; + + //string intgPd = XmlHelper.GetAttributeValue(LogSettingsNode, "intgPd"); + //if (intgPd != null) + // LogSettingsIntgPd = intgPd; + + } + + + XmlNode GSEControlNode = xmlNode.SelectSingleNode("scl:GSESettings", nsManager); + if (GSEControlNode != null) + { + GseSettingsExists = true; + GSESettings = new GSESettings(sclDocument, GSEControlNode, nsManager); + + //string cbName = XmlHelper.GetAttributeValue(GSEControlNode, "cbName"); + //if (cbName != null) + //{ + // GseCbName = cbName; + // GseSettingsCbName = true; + //} + + //string datSet = XmlHelper.GetAttributeValue(GSEControlNode, "datSet"); + //if (datSet != null) + //{ + // GseDatSet = datSet; + // GseSettingsDatSet = true; + //} + + //string appID = XmlHelper.GetAttributeValue(GSEControlNode, "appID"); + //if (datSet != null) + //{ + // GseAppID = appID; + // GseSettingsAppId = true; + //} + + //string dataLabel = XmlHelper.GetAttributeValue(GSEControlNode, "dataLabel"); + //if (dataLabel != null) + //{ + // GseDataLabel = dataLabel; + // GseSettingsDataLabel = true; + //} + + //string kdaParticipant = XmlHelper.GetAttributeValue(GSEControlNode, "kdaParticipant"); + //if (kdaParticipant != null) + //{ + // if (kdaParticipant == "true") + // GseSettingsKdaParticipant = true; + //} + + //XmlNode McSecurity = GSEControlNode.SelectSingleNode("scl:McSecurity", nsManager); + + //if(McSecurity != null) + //{ + // GseSettingsMcSecurity = true; + //} + } + + + XmlNode SMVSettingsNode = xmlNode.SelectSingleNode("scl:SMVSettings", nsManager); + if (SMVSettingsNode != null) + { + SmvSettingsExists = true; + SMVSettings = new SMVSettings(sclDocument, SMVSettingsNode, nsManager); + + //string cbName = XmlHelper.GetAttributeValue(SMVSettingsNode, "cbName"); + //if (cbName != null) + // SmvSettingsCbName = cbName; + + //string datSet = XmlHelper.GetAttributeValue(SMVSettingsNode, "datSet"); + //if (datSet != null) + // SmvSettingsDatSet = datSet; + + //string svID = XmlHelper.GetAttributeValue(SMVSettingsNode, "svID"); + //if (svID != null) + // SmvSettingsSvId = svID; + + //string optFields = XmlHelper.GetAttributeValue(SMVSettingsNode, "optFields"); + //if (optFields != null) + // SmvSettingsOptFields = optFields; + + //string smpRate = XmlHelper.GetAttributeValue(SMVSettingsNode, "smpRate"); + //if (smpRate != null) + // SmvSettingsSmpRate = smpRate; + + //string samplesPerSec = XmlHelper.GetAttributeValue(SMVSettingsNode, "samplesPerSec"); + //if (samplesPerSec != null) + //{ + // if (samplesPerSec == "true") + // SmvSettingsSamplesPerSec = true; + + //} + + //string synchrSrcId = XmlHelper.GetAttributeValue(SMVSettingsNode, "synchrSrcId"); + //if (synchrSrcId != null) + //{ + // if (synchrSrcId == "true") + // SmvSettingsSynchrSrcId = true; + + //} + + //string nofASDU = XmlHelper.GetAttributeValue(SMVSettingsNode, "nofASDU"); + //if (nofASDU != null) + // SmvSettingsNofASDU = nofASDU; + + //string pdcTimeStamp = XmlHelper.GetAttributeValue(SMVSettingsNode, "pdcTimeStamp"); + //if (pdcTimeStamp != null) + //{ + // if (pdcTimeStamp == "true") + // SmvSettingsPdcTimeStamp = true; + + //} + + //string kdaParticipant = XmlHelper.GetAttributeValue(SMVSettingsNode, "kdaParticipant"); + //if (kdaParticipant != null) + //{ + // if (kdaParticipant == "true") + // SmvSettingsKdaParticipant = true; + + //} + + //XmlNode SmpRate = SMVSettingsNode.SelectSingleNode("scl:SmpRate", nsManager); + //if (SmpRate != null) + //{ + // SmvSettingsSmpRateElement = true; + + // string val = SmpRate.InnerText; + // if (val != null) + // SmvSettingsSmpRateElementVal = int.Parse(val); + //} + + //XmlNode SamplesPerSec = SMVSettingsNode.SelectSingleNode("scl:SamplesPerSec", nsManager); + //if (SamplesPerSec != null) + //{ + // SmvSettingsSamplesPerSecElement = true; + + // string val = SamplesPerSec.InnerText; + // if (val != null) + // SmvSettingsSamplesPerSecElementVal = int.Parse(val); + //} + + //XmlNode SecPerSamples = SMVSettingsNode.SelectSingleNode("scl:SecPerSamples", nsManager); + //if (SecPerSamples != null) + //{ + // SmvSettingsSecPerSamplesElement = true; + + // string val = SecPerSamples.InnerText; + // if (val != null) + // SmvSettingsSecPerSamplesElementVal = int.Parse(val); + //} + } + + + XmlNode ConfLNsNode = xmlNode.SelectSingleNode("scl:ConfLNs", nsManager); + if (ConfLNsNode != null) + { + ConfLNsExists = true; + ConfLNs = new ConfLNs(sclDocument, ConfLNsNode, nsManager); + + //string fixPrefix = XmlHelper.GetAttributeValue(ConfLNsNode, "fixPrefix"); + //if (fixPrefix != null) + //{ + // if (fixPrefix == "true") + // ConfLNsFixPrefix = true; + + //} + + //string fixLnInst = XmlHelper.GetAttributeValue(ConfLNsNode, "fixLnInst"); + //if (fixLnInst != null) + //{ + // if (fixLnInst == "true") + // ConfLNsFixLnInst = true; + + //} + + } + + + XmlNode ConfLdNameNode = xmlNode.SelectSingleNode("scl:ConfLdName", nsManager); + if (ConfLdNameNode != null) + { + ConfLdNameExists = true; + ConfLdName = new ConfLdName(sclDocument, ConfLdNameNode, nsManager); + + } + + + XmlNode GSEDirNode = xmlNode.SelectSingleNode("scl:GSEDir", nsManager); + if (GSEDirNode != null) + { + GseDirExists = true; + GSEDir = new GSEDir(sclDocument, GSEDirNode, nsManager); + + } + + + XmlNode GOOSENode = xmlNode.SelectSingleNode("scl:GOOSE", nsManager); + if (GOOSENode != null) + { + GooseExists = true; + GOOSE = new GOOSE(sclDocument, GOOSENode, nsManager); + + //string max = XmlHelper.GetAttributeValue(GOOSENode, "max"); + //if (max != null) + //{ + // GooseMax = int.Parse(max); + //} + + //string fixedOffs = XmlHelper.GetAttributeValue(GOOSENode, "fixedOffs"); + //if (fixedOffs != null) + //{ + // if (fixedOffs == "true") + // GooseFixedOffs = true; + + //} + + //string goose = XmlHelper.GetAttributeValue(GOOSENode, "goose"); + //if (goose != null) + //{ + // if (goose == "true") + // GooseGoose = true; + + //} + + //string rGOOSE = XmlHelper.GetAttributeValue(GOOSENode, "rGOOSE"); + //if (rGOOSE != null) + //{ + // if (rGOOSE == "true") + // GooseRGOOSE = true; + + //} + + + } + + + XmlNode GSSENode = xmlNode.SelectSingleNode("scl:GSSE", nsManager); + if (GSSENode != null) + { + GsseExists = true; + GSSE = new GSSE(sclDocument, GSSENode, nsManager); + + //string max = XmlHelper.GetAttributeValue(GSSENode, "max"); + //if (max != null) + //{ + // GsseMax = int.Parse(max); + //} + + + } + + + XmlNode SMVscNode = xmlNode.SelectSingleNode("scl:SMVsc", nsManager); + if (SMVscNode != null) + { + SmvScExists = true; + SMVsc = new SMVsc(sclDocument, SMVscNode, nsManager); + + //string max = XmlHelper.GetAttributeValue(SMVscNode, "max"); + //if (max != null) + //{ + // SmvScMax = int.Parse(max); + //} + + //string deliveryConf = XmlHelper.GetAttributeValue(ConfLNsNode, "deliveryConf"); + //if (deliveryConf != null) + //{ + // if (deliveryConf == "true") + // SmvScDeliveryConf = true; + // else + // SmvScDeliveryConf = false; + //} + + //string sv = XmlHelper.GetAttributeValue(ConfLNsNode, "sv"); + //if (sv != null) + //{ + // if (sv == "true") + // SmvScSv = true; + // else + // SmvScSv = false; + //} + + //string rSV = XmlHelper.GetAttributeValue(ConfLNsNode, "rSV"); + //if (rSV != null) + //{ + // if (rSV == "true") + // SmvScRSV = true; + // else + // SmvScRSV = false; + //} + + + } + + + XmlNode FileHandlingNode = xmlNode.SelectSingleNode("scl:FileHandling", nsManager); + if (FileHandlingNode != null) + { + FileHandlingExists = true; + FileHandling = new FileHandling(sclDocument, FileHandlingNode, nsManager); + + //string mms = XmlHelper.GetAttributeValue(FileHandlingNode, "mms"); + //if (mms != null) + //{ + // if (mms == "true") + // FileHandlingMms = true; + // else + // FileHandlingMms = false; + //} + + //string ftp = XmlHelper.GetAttributeValue(FileHandlingNode, "ftp"); + //if (ftp != null) + //{ + // if (ftp == "true") + // FileHandlingFtp = true; + // else + // FileHandlingFtp = false; + //} + + //string ftps = XmlHelper.GetAttributeValue(FileHandlingNode, "ftps"); + //if (ftps != null) + //{ + // if (ftps == "true") + // FileHandlingFtps = true; + // else + // FileHandlingFtps = false; + //} + + + } + + + XmlNode SupSubscriptionNode = xmlNode.SelectSingleNode("scl:SupSubscription", nsManager); + if (SupSubscriptionNode != null) + { + SupSubscriptionExists = true; + SupSubscription = new SupSubscription(sclDocument, SupSubscriptionNode, nsManager); + + //string maxGo = XmlHelper.GetAttributeValue(SupSubscriptionNode, "maxGo"); + //if (maxGo != null) + //{ + // SupSubscriptionMaxGo = int.Parse(maxGo); + //} + + //string maxSv = XmlHelper.GetAttributeValue(SupSubscriptionNode, "maxSv"); + //if (maxSv != null) + //{ + // SupSubscriptionMaxSv = int.Parse(maxSv); + //} + + + } + + + XmlNode ConfSigRefNode = xmlNode.SelectSingleNode("scl:ConfSigRef", nsManager); + if (ConfSigRefNode != null) + { + ConfSigRefExists = true; + ConfSigRef = new ConfSigRef(sclDocument, ConfSigRefNode, nsManager); + + //string max = XmlHelper.GetAttributeValue(ConfSigRefNode, "max"); + //if (max != null) + //{ + // ConfSigRefMax = int.Parse(max); + //} + + } + + + XmlNode CommProtNode = xmlNode.SelectSingleNode("scl:CommProt", nsManager); + if (CommProtNode != null) + { + CommProtExists = true; + CommProt = new CommProt(sclDocument, CommProtNode, nsManager); + + //string ipv6 = XmlHelper.GetAttributeValue(FileHandlingNode, "ipv6"); + //if (ipv6 != null) + //{ + // if (ipv6 == "true") + // CommProtIpv6 = true; + // else + // CommProtIpv6 = false; + //} + + } + + + XmlNode TimeSyncProtNode = xmlNode.SelectSingleNode("scl:TimeSyncProt", nsManager); + if (TimeSyncProtNode != null) + { + TimeSyncProtExists = true; + TimeSyncProt = new TimeSyncProt(sclDocument, TimeSyncProtNode, nsManager); + //// + //string sntp = XmlHelper.GetAttributeValue(TimeSyncProtNode, "sntp"); + //if (sntp != null) + //{ + // if (sntp == "true") + // TimeSyncProtSntp = true; + // else + // TimeSyncProtSntp = false; + //} + + //string c37_238 = XmlHelper.GetAttributeValue(TimeSyncProtNode, "c37_238"); + //if (c37_238 != null) + //{ + // if (c37_238 == "true") + // TimeSyncProtC37_238 = true; + // else + // TimeSyncProtC37_238 = false; + //} + + //string iec61850_9_3 = XmlHelper.GetAttributeValue(TimeSyncProtNode, "iec61850_9_3"); + //if (iec61850_9_3 != null) + //{ + // if (iec61850_9_3 == "true") + // TimeSyncProtIc61850_9_3 = true; + // else + // TimeSyncProtIc61850_9_3 = false; + //} + + //string other = XmlHelper.GetAttributeValue(TimeSyncProtNode, "other"); + //if (other != null) + //{ + // if (other == "true") + // TimeSyncProtOther = true; + // else + // TimeSyncProtOther = false; + //} + + } + + + XmlNode RedProtNode = xmlNode.SelectSingleNode("scl:RedProt", nsManager); + if (RedProtNode != null) + { + RedProtExists = true; + RedProt = new RedProt(sclDocument, RedProtNode, nsManager); + + //string hsr = XmlHelper.GetAttributeValue(RedProtNode, "hsr"); + //if (hsr != null) + //{ + // if (hsr == "true") + // RedProtHsr = true; + // else + // RedProtHsr = false; + //} + + //string prp = XmlHelper.GetAttributeValue(RedProtNode, "prp"); + //if (prp != null) + //{ + // if (prp == "true") + // RedProtPrp = true; + // else + // RedProtPrp = false; + //} + + //string rstp = XmlHelper.GetAttributeValue(RedProtNode, "rstp"); + //if (rstp != null) + //{ + // if (rstp == "true") + // RedProtRstp = true; + // else + // RedProtRstp = false; + //} + + } + + + XmlNode ValueHandlingNode = xmlNode.SelectSingleNode("scl:ValueHandling", nsManager); + if (ValueHandlingNode != null) + { + ValueHandlingExists = true; + ValueHandling = new ValueHandling(sclDocument, ValueHandlingNode, nsManager); + } + + + XmlNode McSecurityNode = xmlNode.SelectSingleNode("scl:McSecurity", nsManager); + if (McSecurityNode != null) + { + McSecurityExists = true; + McSecurity = new McSecurity(sclDocument, McSecurityNode, nsManager); + //// + //string signature = XmlHelper.GetAttributeValue(McSecurityNode, "signature"); + //if (signature != null) + //{ + // if (signature == "true") + // McSecuritySignature = true; + // else + // McSecuritySignature = false; + //} + + //string encryption = XmlHelper.GetAttributeValue(McSecurityNode, "encryption"); + //if (encryption != null) + //{ + // if (encryption == "true") + // McSecurityEncryption = true; + // else + // McSecurityEncryption = false; + //} + } + + } + + } + + + + public class ClientServices + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + + public int MaxAttributes + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "maxAttributes"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "maxAttributes", value.ToString()); + + } + } + + public int MaxReports + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "maxReports"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "maxReports", value.ToString()); + + } + } + + public int MaxGOOSE + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "maxGOOSE"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "maxGOOSE", value.ToString()); + + } + } + + public int MaxSMV + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "maxSMV"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "maxSMV", value.ToString()); + + } + } + + public bool RGOOSE + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "rGOOSE", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "rGOOSE", value.ToString()); } + } + + public bool RSV + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "rSV", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "rSV", value.ToString()); } + } + + public bool NoIctBinding + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "noIctBinding", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "noIctBinding", value.ToString()); } + } + + public TimeSyncProt TimeSyncProt = null; + public McSecurity McSecurity = null; + + + public void DeleteMcSecurity() + { + if (McSecurity != null) + { + XmlNode.RemoveChild(McSecurity.XmlNode); + McSecurity = null; + } + + } + public void DeleteTimeSyncProt() + { + if (TimeSyncProt != null) + { + XmlNode.RemoveChild(TimeSyncProt.XmlNode); + TimeSyncProt = null; + } + + } + + public ClientServices(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + XmlNode timeSync = xmlNode.SelectSingleNode("scl:TimeSyncProt", nsManager); + + if (timeSync != null) + { + TimeSyncProt = new TimeSyncProt(sclDocument, timeSync, nsManager); + } + + XmlNode mcSecurity = xmlNode.SelectSingleNode("scl:McSecurity", nsManager); + + if (mcSecurity != null) + { + McSecurity = new McSecurity(sclDocument, mcSecurity, nsManager); + } + } + + } + public class TimeSyncProt + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public bool Sntp + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "sntp", true); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "sntp", value.ToString()); } + } + + public bool C37_238 + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "c37_238", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "c37_238", value.ToString()); } + } + + public bool Iec61850_9_3 + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "iec61850_9_3", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "iec61850_9_3", value.ToString()); } + } + + public bool Other + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "other", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "other", value.ToString()); } + } + + public XmlNode XmlNode + { + get { return xmlNode; } + } + + public TimeSyncProt(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class McSecurity + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public bool Signature + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "signature", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "signature", value.ToString()); } + } + + public bool Encryption + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "encryption", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "encryption", value.ToString()); } + } + + + public XmlNode XmlNode + { + get { return xmlNode; } + } + + public McSecurity(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + public class DynAssociation + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + public int Max + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "max"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "max", value.ToString()); + + } + } + + public DynAssociation(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + + } + + } + public class SettingGroups + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + bool sgEditExists = false; + bool confSgExists = false; + bool confSgResvTms = false; + bool sgEditResvTms = false; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public bool SgEditExists + { + get + { + return sgEditExists; + } + set + { + sgEditExists = value; + } + } + public bool ConfSgExists + { + get + { + return confSgExists; + } + set + { + confSgExists = value; + } + } + public bool SgEditResvTms + { + get + { + return sgEditResvTms; + } + set + { + sgEditResvTms = value; + } + } + public bool ConfSgResvTms + { + get + { + return confSgResvTms; + } + set + { + confSgResvTms = value; + } + } + + public SGEdit SGEdit = null; + public ConfSG ConfSG = null; + public SettingGroups(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + XmlNode sGEdit = xmlNode.SelectSingleNode("scl:SGEdit", nsManager); + + if (sGEdit != null) + { + SGEdit = new SGEdit(sclDocument, sGEdit, nsManager); + sgEditExists = true; + } + + XmlNode confSG = xmlNode.SelectSingleNode("scl:ConfSG", nsManager); + + if (confSG != null) + { + ConfSG = new ConfSG(sclDocument, confSG, nsManager); + confSgExists = true; + } + + } + } + + public class SGEdit + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public bool resvTms + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "resvTms", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "resvTms", value.ToString()); } + } + + public bool SGCB + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "SGCB", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "SGCB", value.ToString()); } + } + + public bool file + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "file", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "file", value.ToString()); } + } + + public XmlNode XmlNode { get => xmlNode; set => xmlNode = value; } + + public SGEdit(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + public class ConfSG + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode { get => xmlNode; set => xmlNode = value; } + + public bool resvTms + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "resvTms", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "resvTms", value.ToString()); } + } + + public bool SGCB + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "SGCB", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "SGCB", value.ToString()); } + } + + public bool file + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "file", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "file", value.ToString()); } + } + + public ConfSG(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + + public class GetDirectory + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + public GetDirectory(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + + } + + } + public class GetDataObjectDefinition + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + + + public GetDataObjectDefinition(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + + } + + } + public class DataObjectDirectory + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public DataObjectDirectory(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + + } + + } + public class GetDataSetValue + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + public GetDataSetValue(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + public class SetDataSetValue + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public SetDataSetValue(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class DataSetDirectory + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public DataSetDirectory(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class ConfDataSet + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public int Max + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "max"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "max", value.ToString()); + + } + } + public int MaxAttributes + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "maxAttributes"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "maxAttributes", value.ToString()); + + } + } + public bool Modify + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "modify", true); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "modify", value.ToString()); } + } + public ConfDataSet(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + + } + public class DynDataSet + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public int Max + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "max"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "max", value.ToString()); + + } + } + public int MaxAttributes + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "maxAttributes"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "maxAttributes", value.ToString()); + + } + } + + public DynDataSet(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class ReadWrite + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public ReadWrite(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class TimerActivatedControl + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public TimerActivatedControl(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class ConfReportControl + { + public enum BufMode + { + UNBUFFERED, + BUFFERED, + BOTH + } + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + + private BufMode confReportControlBufMode = BufMode.BOTH; + + public int Max + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "max"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "max", value.ToString()); + + } + } + public int MaxBuf + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "maxBuf"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "maxBuf", value.ToString()); + + } + + } + public bool bufConf + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "bufConf", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "bufConf", value.ToString()); } + } + public BufMode ConfReportControlBufMode + { + get + { + return confReportControlBufMode; + } + set + { + confReportControlBufMode = value; + } + } + + public ConfReportControl(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class GetCBValues + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public GetCBValues(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class ConfLogControl + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public int Max + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "max"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "max", value.ToString()); + + } + } + + public ConfLogControl(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class ReportSettings + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public enum CBName + { + Fix, + Conf + } + + public enum DATSet + { + Fix, + Conf, + Dyn + } + + public XmlNode XmlNode + { + get { return xmlNode; } + } + + private CBName cbName = CBName.Fix; + private DATSet datSet = DATSet.Fix; + + public CBName CbName + { + get { return cbName; } + set { cbName = value; } + } + + public DATSet DatSet + { + get { return datSet; } + set { datSet = value; } + } + + + public string RptID + { + get { return XmlHelper.GetAttributeValue(xmlNode, "rptID"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "rptID", value.ToString()); } + } + public string OptFields + { + get { return XmlHelper.GetAttributeValue(xmlNode, "optFields"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "optFields", value.ToString()); } + } + public string BufTime + { + get { return XmlHelper.GetAttributeValue(xmlNode, "bufTime"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "bufTime", value.ToString()); } + } + public string TrgOps + { + get { return XmlHelper.GetAttributeValue(xmlNode, "trgOps"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "trgOps", value.ToString()); } + } + public string IntgPd + { + get { return XmlHelper.GetAttributeValue(xmlNode, "intgPd"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "intgPd", value.ToString()); } + } + public bool ResvTms + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "resvTms", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "resvTms", value.ToString()); } + } + public bool Owner + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "owner", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "owner", value.ToString()); } + } + public ReportSettings(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + public class LogSettings + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public enum CBName + { + Fix, + Conf + } + public enum DATSet + { + Fix, + Conf, + Dyn + } + + private CBName cbName = CBName.Fix; + private DATSet datSet = DATSet.Fix; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + + public CBName CbName + { + get { return cbName; } + set { cbName = value; } + } + + public DATSet DatSet + { + get { return datSet; } + set { datSet = value; } + } + + public string LogEna + { + get { return XmlHelper.GetAttributeValue(xmlNode, "logEna"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "logEna", value.ToString()); } + } + public string TrgOps + { + get { return XmlHelper.GetAttributeValue(xmlNode, "trgOps"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "trgOps", value.ToString()); } + } + public string IntgPd + { + get { return XmlHelper.GetAttributeValue(xmlNode, "intgPd"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "intgPd", value.ToString()); } + } + + public LogSettings(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + + } + + } + public class GSESettings + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public enum CBName + { + Fix, + Conf + } + public enum DATSet + { + Fix, + Conf, + Dyn + } + + private CBName cbName = CBName.Fix; + private DATSet datSet = DATSet.Fix; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + public CBName CbName + { + get { return cbName; } + set { cbName = value; } + } + public DATSet DatSet + { + get { return datSet; } + set { datSet = value; } + } + public string AppID + { + get { return XmlHelper.GetAttributeValue(xmlNode, "appID"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "appID", value.ToString()); } + } + public string DataLabel + { + get { return XmlHelper.GetAttributeValue(xmlNode, "dataLabel"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "dataLabel", value.ToString()); } + } + public bool kdaParticipant + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "kdaParticipant", false); } + //set { XmlHelper.SetBooleanAttributeCreateIfNotExists(xmlDocument, xmlNode, "kdaParticipant", value); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "kdaParticipant", value.ToString()); } + } + + public McSecurity McSecurity = null; + + public void DeleteMcSecurity() + { + if (McSecurity != null) + { + XmlNode.RemoveChild(McSecurity.XmlNode); + McSecurity = null; + } + + } + public GSESettings(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + XmlNode mcSecurity = xmlNode.SelectSingleNode("scl:McSecurity", nsManager); + // + //this.XmlNode.InsertAfter(TimeSyncProt.XmlNode, this.XmlNode.FirstChild); + // + + if (mcSecurity != null) + { + McSecurity = new McSecurity(sclDocument, mcSecurity, nsManager); + } + + } + + } + public class SMVSettings + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public enum CBName + { + Fix, + Conf + } + public enum DATSet + { + Fix, + Conf, + Dyn + } + public enum SMPRate + { + Fix, + Conf, + Dyn + } + public enum NOFASDU + { + Fix, + Conf + } + + private CBName cbName = CBName.Fix; + private DATSet datSet = DATSet.Fix; + private SMPRate sMPRate = SMPRate.Fix; + private NOFASDU nOFASDU = NOFASDU.Fix; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + public CBName CbName + { + get { return cbName; } + set { cbName = value; } + } + public DATSet DatSet + { + get { return datSet; } + set { datSet = value; } + } + public SMPRate SmpRate + { + get { return sMPRate; } + set { sMPRate = value; } + } + public NOFASDU NofASDU + { + get { return nOFASDU; } + set { nOFASDU = value; } + } + public string SvID + { + get { return XmlHelper.GetAttributeValue(xmlNode, "svID"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "svID", value.ToString()); } + } + public string OptFields + { + get { return XmlHelper.GetAttributeValue(xmlNode, "optFields"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "optFields", value.ToString()); } + } + public string smpRate + { + get { return XmlHelper.GetAttributeValue(xmlNode, "smpRate"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "smpRate", value.ToString()); } + } + public int SamplesPerSec + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "samplesPerSec"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "samplesPerSec", value.ToString()); + + } + } + public bool SynchrSrcId + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "synchrSrcId", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "synchrSrcId", value.ToString()); } + } + + public bool PdcTimeStamp + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "pdcTimeStamp", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "pdcTimeStamp", value.ToString()); } + } + public bool KdaParticipant + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "kdaParticipant", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "kdaParticipant", value.ToString()); } + } + //SubElements + public int SmpRateValue + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "SmpRate"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "SmpRate", value.ToString()); + + } + } + public int SamplesPerSecValue + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "SamplesPerSec"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "SamplesPerSec", value.ToString()); + + } + } + public int SecPerSamplesValue + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "SecPerSamples"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "SecPerSamples", value.ToString()); + + } + } + // + public McSecurity McSecurity = null; + + + public void DeleteMcSecurity() + { + if (McSecurity != null) + { + XmlNode.RemoveChild(McSecurity.XmlNode); + McSecurity = null; + } + + } + public SMVSettings(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + + XmlNode mcSecurity = xmlNode.SelectSingleNode("scl:McSecurity", nsManager); + if (mcSecurity != null) + { + McSecurity = new McSecurity(sclDocument, mcSecurity, nsManager); + } + } + + } + public class ConfLNs + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + public bool FixPrefix + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "fixPrefix", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "fixPrefix", value.ToString()); } + } + public bool FixLnInst + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "fixLnInst", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "fixLnInst", value.ToString()); } + } + public ConfLNs(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + + public class ConfLdName + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + public ConfLdName(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + public class GSEDir + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + public GSEDir(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + public class GOOSE + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + public int Max + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "max"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "max", value.ToString()); + + } + } + public bool FixedOffs + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "fixedOffs", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "fixedOffs", value.ToString()); } + } + public bool Goose + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "goose", true); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "goose", value.ToString()); } + } + public bool RGOOSE + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "rGOOSE", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "rGOOSE", value.ToString()); } + } + public GOOSE(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + public class GSSE + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + public int Max + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "max"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "max", value.ToString()); + + } + } + public GSSE(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + public class SMVsc + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public int Max + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "max"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + return retVal; + } + else + return -1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "max", value.ToString()); + } + } + public bool DeliveryConf + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "deliveryConf", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "deliveryConf", value.ToString()); } + } + public bool Sv + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "sv", true); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "sv", value.ToString()); } + } + public bool RSV + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "rSV", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "rSV", value.ToString()); } + } + + public SMVsc(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class FileHandling + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public bool Mms + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "mms", true); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "mms", value.ToString()); } + } + public bool Ftp + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "ftp", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "ftp", value.ToString()); } + } + public bool Ftps + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "ftps", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "ftps", value.ToString()); } + } + public FileHandling(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class SupSubscription + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public int MaxGo + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "maxGo"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + return retVal; + } + else + return -1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "maxGo", value.ToString()); + } + } + public int MaxSv + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "maxSv"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + return retVal; + } + else + return -1; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "maxSv", value.ToString()); + } + } + public SupSubscription(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + + } + public class ConfSigRef + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + public int Max + { + get + { + string valueStr = XmlHelper.GetAttributeValue(xmlNode, "max"); + if (valueStr != null) + { + int retVal = -1; + int.TryParse(valueStr, out retVal); + + return retVal; + } + else + return -1; + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "max", value.ToString()); + + } + } + + + public ConfSigRef(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class CommProt + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + + public bool Ipv6 + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "ipv6", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "ipv6", value.ToString()); } + } + + public CommProt(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + } + + } + public class RedProt + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + public XmlNode XmlNode + { + get { return xmlNode; } + } + + public bool Hsr + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "hsr", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "hsr", value.ToString()); } + } + public bool Prp + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "prp", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "prp", value.ToString()); } + } + public bool Rstp + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "rstp", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "rstp", value.ToString()); } + } + + public RedProt(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + public class ValueHandling + { + private XmlDocument xmlDocument; + private XmlNode xmlNode; + private SclDocument sclDocument; + + public XmlNode XmlNode + { + get { return xmlNode; } + } + + public bool SetToRo + { + get { return XmlHelper.ParseBooleanAttribute(xmlNode, "setToRo", false); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "setToRo", value.ToString()); } + } + + public ValueHandling(SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + this.sclDocument = sclDocument; + xmlDocument = sclDocument.XmlDocument; + this.xmlNode = xmlNode; + + } + + } + +} + + + diff --git a/tools/model_generator_dotnet/SCLParser/src/SclSettingControl.cs b/tools/model_generator_dotnet/SCLParser/src/SclSettingControl.cs new file mode 100644 index 00000000..f8118783 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclSettingControl.cs @@ -0,0 +1,125 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using IEC61850.SCL.DataModel; +using System; +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclSettingControl + { + public XmlNode xmlNode; + private XmlDocument xmlDocument; + public IEDModelNode Parent; + + + public SclSettingControl(SclDocument SclxmlDocument, XmlNode xmlNode) + { + this.xmlNode = xmlNode; + xmlDocument = SclxmlDocument.XmlDocument; + + XmlAttribute nameAttr = xmlNode.Attributes["numOfSGs"]; + + if (nameAttr == null) + SclxmlDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "SettingControl has no numOfSGs attribute", this, "numOfSGs"); + + } + + public SclSettingControl(XmlDocument xmlDoc, string numOfSGs) + { + xmlDocument = xmlDoc; + xmlNode = xmlDoc.CreateElement("SettingControl", SclDocument.SCL_XMLNS); + + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "numOfSGs", numOfSGs); + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "actSG", "1"); + + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + public int NumOfSGs + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "numOfSGs"); + + if (valStr != null) + { + int retVal = -1; + Int32.TryParse(valStr, out retVal); + + return (retVal); + } + else + return (-1); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "numOfSGs", value.ToString()); + } + } + + public int ActSG + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "actSG"); + + if (valStr != null) + { + int retVal = -1; + Int32.TryParse(valStr, out retVal); + + return (retVal); + } + else + return (-1); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "actSG", value.ToString()); + } + + } + + public int ResvTms + { + get + { + string valStr = XmlHelper.GetAttributeValue(xmlNode, "resvTms"); + + if (valStr != null) + { + int retVal = -1; + Int32.TryParse(valStr, out retVal); + + return (retVal); + } + else + return (-1); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "resvTms", value.ToString()); + } + + } + + } +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclSubstation.cs b/tools/model_generator_dotnet/SCLParser/src/SclSubstation.cs new file mode 100644 index 00000000..5bf9fe61 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclSubstation.cs @@ -0,0 +1,1492 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; + +namespace IEC61850.SCL +{ + public class SclLNode : SclBaseElement + { + private XmlDocument xmlDocument; + + public string IedName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "iedName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "iedName", value); + } + } + + public string LdInst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "ldInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "ldInst", value); + } + } + + public string LnClass + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnClass"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnClass", value); + } + } + + public string LnInst + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnInst"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnInst", value); + } + } + + public string Prefix + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "prefix"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "prefix", value); + } + } + + public string LnType + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnType"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnType", value); + } + } + + public SclLNode(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode) + { + this.xmlNode = xmlNode; + this.xmlDocument = xmlDocument; + + if (LdInst == null) + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "ldInst is missing in LNode element!", this, "LdInst"); + + if (LnClass == null) + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "lnClass is missing in LNode element!", this, "LnClass"); + + } + + + public string GetObjectReference() + { + StringBuilder objRef = new StringBuilder(); + + if (IedName != null) + objRef.Append(IedName); + + objRef.Append(LdInst); + objRef.Append('/'); + + if (Prefix != null) + objRef.Append(Prefix); + + if (LnClass != null) + objRef.Append(LnClass); + + if (LnInst != null) + objRef.Append(LnInst); + + return objRef.ToString(); + } + } + + public class SclLNodeContainer : SclBaseElement + { + protected XmlDocument xmlDocument; + protected XmlNamespaceManager nsManager; + + private List lNodes; + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "name", value); + } + } + + public string Desc + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "desc", value); + } + } + + private void parseLNodes() + { + XmlNodeList lNodeNodes = xmlNode.SelectNodes("scl:LNode", nsManager); + + lNodes = new List(); + + foreach (XmlNode lNodeNode in lNodeNodes) + { + SclLNode lNode = new SclLNode(xmlDocument, sclDocument, lNodeNode, nsManager); + lNodes.Add(lNode); + } + } + + + internal SclLNodeContainer(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode) + { + this.xmlNode = xmlNode; + this.xmlDocument = xmlDocument; + this.nsManager = nsManager; + + parseLNodes(); + } + + public List LNodes + { + get + { + return lNodes; + } + } + } + + public class SclConnectivityNode : SclLNodeContainer + { + public string PathName + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "pathName"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "pathName", value); + } + } + + internal SclConnectivityNode(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + + } + + } + + public class SclPowerSystemResource : SclLNodeContainer + { + internal SclPowerSystemResource(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + + } + } + + public class SclSubFunction : SclPowerSystemResource + { + public string Type + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "type", value); + } + } + + private List sclSubFunctions; + private List sclGeneralEquipments; + private List sclConductingEquipments; + + public bool RemoveSubFunction(SclSubFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclSubFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + + public bool RemoveGeneralEquipment(SclGeneralEquipment node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclGeneralEquipments.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public bool RemoveConductingEquipment(SclConductingEquipment node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclConductingEquipments.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + private void parseSubFunction() + { + XmlNodeList lNodeNodes = xmlNode.SelectNodes("scl:SubFunction", nsManager); + + sclSubFunctions = new List(); + + foreach (XmlNode lNodeNode in lNodeNodes) + { + SclSubFunction subFunction = new SclSubFunction(xmlDocument, sclDocument, lNodeNode, nsManager); + sclSubFunctions.Add(subFunction); + } + } + + private void parseGeneralEquipment() + { + XmlNodeList lNodeNodes = xmlNode.SelectNodes("scl:GeneralEquipment", nsManager); + + sclGeneralEquipments = new List(); + + foreach (XmlNode lNodeNode in lNodeNodes) + { + SclGeneralEquipment generalEquipment = new SclGeneralEquipment(xmlDocument, sclDocument, lNodeNode, nsManager); + sclGeneralEquipments.Add(generalEquipment); + } + } + + private void parseConductingEquipment() + { + XmlNodeList lNodeNodes = xmlNode.SelectNodes("scl:ConductingEquipment", nsManager); + + sclConductingEquipments = new List(); + + foreach (XmlNode lNodeNode in lNodeNodes) + { + SclConductingEquipment conductingEquipment = new SclConductingEquipment(xmlDocument, sclDocument, lNodeNode, nsManager); + sclConductingEquipments.Add(conductingEquipment); + } + } + + public List ConductingEquipments + { + get + { + return sclConductingEquipments; + } + } + + public List GeneralEquipments + { + get + { + return sclGeneralEquipments; + } + } + + public List SubFunctions + { + get + { + return sclSubFunctions; + } + } + + internal SclSubFunction(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + parseSubFunction(); + + parseGeneralEquipment(); + + parseConductingEquipment(); + } + + + } + + public class SclFunction : SclPowerSystemResource + { + public string Type + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "type", value); + } + } + + private List sclSubFunctions; + private List sclGeneralEquipments; + private List sclConductingEquipments; + + public bool RemoveSubFunction(SclSubFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclSubFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public bool RemoveGeneralEquipment(SclGeneralEquipment node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclGeneralEquipments.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + private void parseSubFunction() + { + XmlNodeList lNodeNodes = xmlNode.SelectNodes("scl:SubFunction", nsManager); + + sclSubFunctions = new List(); + + foreach (XmlNode lNodeNode in lNodeNodes) + { + SclSubFunction subFunction = new SclSubFunction(xmlDocument, sclDocument, lNodeNode, nsManager); + sclSubFunctions.Add(subFunction); + } + } + + private void parseGeneralEquipment() + { + XmlNodeList lNodeNodes = xmlNode.SelectNodes("scl:GeneralEquipment", nsManager); + + sclGeneralEquipments = new List(); + + foreach (XmlNode lNodeNode in lNodeNodes) + { + SclGeneralEquipment generalEquipment = new SclGeneralEquipment(xmlDocument, sclDocument, lNodeNode, nsManager); + sclGeneralEquipments.Add(generalEquipment); + } + } + + private void parseConductingEquipment() + { + XmlNodeList lNodeNodes = xmlNode.SelectNodes("scl:ConductingEquipment", nsManager); + + sclConductingEquipments = new List(); + + foreach (XmlNode lNodeNode in lNodeNodes) + { + SclConductingEquipment conductingEquipment = new SclConductingEquipment(xmlDocument, sclDocument, lNodeNode, nsManager); + sclConductingEquipments.Add(conductingEquipment); + } + } + + public List ConductingEquipments + { + get + { + return sclConductingEquipments; + } + } + + public List GeneralEquipments + { + get + { + return sclGeneralEquipments; + } + } + + public List SubFunctions + { + get + { + return sclSubFunctions; + } + } + + internal SclFunction(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + parseGeneralEquipment(); + + parseSubFunction(); + + parseConductingEquipment(); + } + + + } + + public class SclEquipmentContainer : SclPowerSystemResource + { + private List sclPowerTransformers; + + public bool RemovePowerTransformer(SclPowerTransformer node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclPowerTransformers.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public List PowerTransformers + { + get + { + return sclPowerTransformers; + } + } + + private void parsePowerTransformer() + { + XmlNodeList lNodeNodes = xmlNode.SelectNodes("scl:PowerTransformer", nsManager); + + sclPowerTransformers = new List(); + + foreach (XmlNode lNodeNode in lNodeNodes) + { + SclPowerTransformer element = new SclPowerTransformer(xmlDocument, sclDocument, lNodeNode, nsManager); + sclPowerTransformers.Add(element); + } + } + + private List sclGeneralEquipments; + + public List GeneralEquipments + { + get + { + return sclGeneralEquipments; + } + } + + private void parseGeneralEquipment() + { + XmlNodeList lNodeNodes = xmlNode.SelectNodes("scl:GeneralEquipment", nsManager); + + sclGeneralEquipments = new List(); + + foreach (XmlNode lNodeNode in lNodeNodes) + { + SclGeneralEquipment element = new SclGeneralEquipment(xmlDocument, sclDocument, lNodeNode, nsManager); + sclGeneralEquipments.Add(element); + } + } + + + internal SclEquipmentContainer(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + parsePowerTransformer(); + + parseGeneralEquipment(); + } + } + + public class SclSubstation : SclEquipmentContainer + { + private List voltageLevels = new List(); + private List sclFunctions = new List(); + + public bool RemoveVoltageLevel(SclVoltageLevel node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + voltageLevels.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public bool RemoveFunction(SclFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + private void ParseVoltageLevels() + { + XmlNodeList voltageLevelNodes = xmlNode.SelectNodes("scl:VoltageLevel", nsManager); + + voltageLevels = new List(); + + foreach (XmlNode voltageLevelNode in voltageLevelNodes) + { + SclVoltageLevel voltageLevel = new SclVoltageLevel(xmlDocument, sclDocument, voltageLevelNode, nsManager); + + voltageLevels.Add(voltageLevel); + } + } + + private void ParseFunction() + { + XmlNodeList functionlNodes = xmlNode.SelectNodes("scl:Function", nsManager); + + sclFunctions = new List(); + + foreach (XmlNode functionlNode in functionlNodes) + { + SclFunction function = new SclFunction(xmlDocument, sclDocument, functionlNode, nsManager); + + sclFunctions.Add(function); + } + } + + public List VoltageLevels + { + get + { + return voltageLevels; + } + } + + public List Functions + { + get + { + return sclFunctions; + } + } + + internal SclSubstation(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + + ParseVoltageLevels(); + + if (voltageLevels.Count < 1) + { + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "Substation contains no Voltage Level. Minimum is 1", this, "VoltageLevel"); + } + + ParseFunction(); + } + + + } + + public class SclVoltageLevel : SclEquipmentContainer + { + private List sclBays; + private List sclFunctions; + private List sclVoltages; + + public bool RemoveVoltage(SclVoltage node) + { + try + { + XmlNode parent = node.XmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.XmlNode); + } + + sclVoltages.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + + public bool RemoveFunction(SclFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public bool RemoveBay(SclBay node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + Bays.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + private void ParseVoltage() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:Voltage", nsManager); + + sclVoltages = new List(); + + foreach (XmlNode node in nodes) + { + SclVoltage voltage = new SclVoltage(xmlDocument, sclDocument, node, nsManager); + + sclVoltages.Add(voltage); + } + } + private void ParseBay() + { + XmlNodeList Nodes = xmlNode.SelectNodes("scl:Bay", nsManager); + + sclBays = new List(); + + foreach (XmlNode Node in Nodes) + { + SclBay function = new SclBay(xmlDocument, sclDocument, Node, nsManager); + + sclBays.Add(function); + } + } + private void ParseFunction() + { + XmlNodeList functionlNodes = xmlNode.SelectNodes("scl:Function", nsManager); + + sclFunctions = new List(); + + foreach (XmlNode functionlNode in functionlNodes) + { + SclFunction function = new SclFunction(xmlDocument, sclDocument, functionlNode, nsManager); + + sclFunctions.Add(function); + } + } + + public List Bays + { + get + { + return sclBays; + } + } + + public List Functions + { + get + { + return sclFunctions; + } + } + + public List Voltages + { + get + { + return sclVoltages; + } + } + + internal SclVoltageLevel(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + ParseVoltage(); + + ParseBay(); + + if (sclBays.Count < 1) + { + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "VoltageLevel contains no Bay. Minimum is 1", this, "Bay"); + + } + + ParseFunction(); + } + + } + + public class SclBay : SclEquipmentContainer + { + private List sclConnectivityNodes; + private List sclFunctions; + private List sclConductingEquipments; + + public bool RemoveFunction(SclFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + sclFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + private void ParseConnectivityNode() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:ConnectivityNode", nsManager); + + sclConnectivityNodes = new List(); + + foreach (XmlNode node in nodes) + { + SclConnectivityNode connectivityNode = new SclConnectivityNode(xmlDocument, sclDocument, node, nsManager); + + sclConnectivityNodes.Add(connectivityNode); + } + } + + private void ParseConductingEquipment() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:ConductingEquipment", nsManager); + + sclConductingEquipments = new List(); + + foreach (XmlNode node in nodes) + { + SclConductingEquipment conductingEquipment = new SclConductingEquipment(xmlDocument, sclDocument, node, nsManager); + + sclConductingEquipments.Add(conductingEquipment); + } + } + + private void ParseFunction() + { + XmlNodeList functionlNodes = xmlNode.SelectNodes("scl:Function", nsManager); + + sclFunctions = new List(); + + foreach (XmlNode functionlNode in functionlNodes) + { + SclFunction function = new SclFunction(xmlDocument, sclDocument, functionlNode, nsManager); + + sclFunctions.Add(function); + } + } + + public List ConnectivityNodes + { + get + { + return sclConnectivityNodes; + } + } + + public List Functions + { + get + { + return sclFunctions; + } + } + + public List ConductingEquipments + { + get + { + return sclConductingEquipments; + } + } + internal SclBay(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + ParseConnectivityNode(); + + ParseFunction(); + + ParseConductingEquipment(); + } + + + } + + public class SclVoltage + { + public XmlNode XmlNode; + XmlDocument XmlDocument; + public string Type + { + get + { + return XmlHelper.GetAttributeValue(XmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(XmlDocument, XmlNode, "type", value); + } + } + + internal SclVoltage(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + { + XmlNode = xmlNode; + XmlDocument = xmlDocument; + } + + } + + public class SclPowerTransformer : SclEquipment + { + public string Type + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "type", value); + } + } + + private List sclSubEquipments; + private List sclTransformerwindings; + private List sclEqFunctions; + + private void parseSubEquipment() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:SubEquipment", nsManager); + + sclSubEquipments = new List(); + + foreach (XmlNode node in nodes) + { + SclSubEquipment lNode = new SclSubEquipment(xmlDocument, sclDocument, node, nsManager); + sclSubEquipments.Add(lNode); + } + } + + private void parseTransformerWinding() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:TransformerWinding", nsManager); + + sclTransformerwindings = new List(); + + foreach (XmlNode node in nodes) + { + SclTransformerWinding lNode = new SclTransformerWinding(xmlDocument, sclDocument, node, nsManager); + sclTransformerwindings.Add(lNode); + } + } + + private void parseEqFunctions() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:EqFunction", nsManager); + + sclEqFunctions = new List(); + + foreach (XmlNode node in nodes) + { + SclEqFunction lNode = new SclEqFunction(xmlDocument, sclDocument, node, nsManager); + sclEqFunctions.Add(lNode); + } + } + + public List SubEquipments + { + get + { + return sclSubEquipments; + } + } + + public List Transformerwindings + { + get + { + return sclTransformerwindings; + } + } + + public List EqFunctions + { + get { return sclEqFunctions; } + } + + public bool RemoveSubEquipment(SclSubEquipment node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + SubEquipments.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public SclSubEquipment AddNewSubEquipment() + { + SclSubEquipment newControl = new SclSubEquipment(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (SubEquipments.Count > 0) + { + int lastIndex = SubEquipments.Count - 1; + + SclSubEquipment lastLNode = SubEquipments[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclSubEquipment(xmlDocument, sclDocument, newNode, nsManager); + SubEquipments.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + public bool RemoveTransformerWinding(SclTransformerWinding node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + Transformerwindings.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + public SclTransformerWinding AddNewTransformerWinding() + { + SclTransformerWinding newControl = new SclTransformerWinding(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (Transformerwindings.Count > 0) + { + int lastIndex = Transformerwindings.Count - 1; + + SclTransformerWinding lastLNode = Transformerwindings[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclTransformerWinding(xmlDocument, sclDocument, newNode, nsManager); + Transformerwindings.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + public SclEqFunction AddNewEqFunction() + { + SclEqFunction newControl = new SclEqFunction(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (EqFunctions.Count > 0) + { + int lastIndex = EqFunctions.Count - 1; + + SclEqFunction lastLNode = EqFunctions[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclEqFunction(xmlDocument, sclDocument, newNode, nsManager); + EqFunctions.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + public bool RemoveEqFunction(SclEqFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + EqFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + internal SclPowerTransformer(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + parseSubEquipment(); + + parseTransformerWinding(); + + if (sclTransformerwindings.Count < 1) + { + sclDocument.AddIssue(xmlNode, "ERROR", "Model integrity", "PowerTransformer contains no TransformerWinding. Minimum is 1", this, "BTransformerWindingay"); + + } + + parseEqFunctions(); + } + } + + public class SclGeneralEquipment : SclEquipment + { + public string Type + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "type", value); + } + } + + private List sclEqFunctions; + + public SclEqFunction AddNewEqFunction() + { + SclEqFunction newControl = new SclEqFunction(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (EqFunctions.Count > 0) + { + int lastIndex = EqFunctions.Count - 1; + + SclEqFunction lastLNode = EqFunctions[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclEqFunction(xmlDocument, sclDocument, newNode, nsManager); + EqFunctions.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + public bool RemoveEqFunction(SclEqFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + EqFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + private void parceEqFunctions() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:EqFunction", nsManager); + + sclEqFunctions = new List(); + + foreach (XmlNode node in nodes) + { + SclEqFunction lNode = new SclEqFunction(xmlDocument, sclDocument, node, nsManager); + sclEqFunctions.Add(lNode); + } + } + + public List EqFunctions + { + get { return sclEqFunctions; } + } + + internal SclGeneralEquipment(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + parceEqFunctions(); + } + + } + + public class SclConductingEquipment : SclAbstractConductingEquipment + { + public string Type + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "type"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "type", value); + } + } + + private List sclEqFunctions; + + public SclEqFunction AddNewEqFunction() + { + SclEqFunction newControl = new SclEqFunction(xmlDocument, sclDocument, nsManager); + + XmlNode newNode = newControl.xmlNode; + + if (newNode.OwnerDocument != xmlDocument) + { + newNode = xmlDocument.ImportNode(newControl.xmlNode.CloneNode(true), true); + } + + if (EqFunctions.Count > 0) + { + int lastIndex = EqFunctions.Count - 1; + + SclEqFunction lastLNode = EqFunctions[lastIndex]; + + XmlNode parent = lastLNode.xmlNode.ParentNode; + + parent.InsertAfter(newNode, lastLNode.xmlNode); + } + else + { + XmlNode parent = XmlNode; + parent.AppendChild(newNode); + + } + + try + { + newControl = new SclEqFunction(xmlDocument, sclDocument, newNode, nsManager); + EqFunctions.Add(newControl); + + return newControl; + + } + catch (SclParserException e) + { + Console.WriteLine(e.ToString()); + + return null; + } + } + + public bool RemoveEqFunction(SclEqFunction node) + { + try + { + XmlNode parent = node.xmlNode.ParentNode; + + if (parent != null) + { + parent.RemoveChild(node.xmlNode); + } + + EqFunctions.Remove(node); + + return true; + } + catch (Exception) + { + return false; + } + } + + private void parseEqFunctions() + { + XmlNodeList nodes = xmlNode.SelectNodes("scl:EqFunction", nsManager); + + sclEqFunctions = new List(); + + foreach (XmlNode node in nodes) + { + SclEqFunction lNode = new SclEqFunction(xmlDocument, sclDocument, node, nsManager); + sclEqFunctions.Add(lNode); + } + } + + public List EqFunctions + { + get { return sclEqFunctions; } + } + + + internal SclConductingEquipment(XmlDocument xmlDocument, SclDocument sclDocument, XmlNode xmlNode, XmlNamespaceManager nsManager) + : base(xmlDocument, sclDocument, xmlNode, nsManager) + { + parseEqFunctions(); + } + + } + +} diff --git a/tools/model_generator_dotnet/SCLParser/src/SclType.cs b/tools/model_generator_dotnet/SCLParser/src/SclType.cs new file mode 100644 index 00000000..259cfaa4 --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclType.cs @@ -0,0 +1,1269 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + + +using IEC61850.SCL.DataModel; +using System; +using System.Collections.Generic; +using System.Xml; + + +namespace IEC61850 +{ + namespace SCL + { + + public enum AttributeType + { + BOOLEAN = 0, /* int */ + INT8 = 1, /* int8_t */ + INT16 = 2, /* int16_t */ + INT32 = 3, /* int32_t */ + INT64 = 4, /* int64_t */ + INT128 = 5, + INT8U = 6, /* uint8_t */ + INT16U = 7, /* uint16_t */ + INT24U = 8, /* uint32_t */ + INT32U = 9, /* uint32_t */ + FLOAT32 = 10, /* float */ + FLOAT64 = 11, /* double */ + ENUMERATED = 12, + OCTET_STRING_64 = 13, + OCTET_STRING_6 = 14, + OCTET_STRING_8 = 15, + VISIBLE_STRING_32 = 16, + VISIBLE_STRING_64 = 17, + VISIBLE_STRING_65 = 18, + VISIBLE_STRING_129 = 19, + VISIBLE_STRING_255 = 20, + UNICODE_STRING_255 = 21, + TIMESTAMP = 22, + QUALITY = 23, + CHECK = 24, + CODEDENUM = 25, + GENERIC_BITSTRING = 26, + CONSTRUCTED = 27, + ENTRY_TIME = 28, + PHYCOMADDR = 29, + CURRENCY = 30, + OBJECT_REFERENCE = 31, + OTHER = -1 + } + + public static class AttributeTypeExtensions + { + public static string ToSclString(AttributeType value) + { + switch (value) + { + case AttributeType.BOOLEAN: + return "BOOLEAN"; + case AttributeType.INT8: + return "INT8"; + case AttributeType.INT16: + return "INT16"; + case AttributeType.INT32: + return "INT32"; + case AttributeType.INT64: + return "INT64"; + case AttributeType.INT8U: + return "INT8U"; + case AttributeType.INT16U: + return "INT16U"; + case AttributeType.INT24U: + return "INT24U"; + case AttributeType.INT32U: + return "INT32U"; + case AttributeType.FLOAT32: + return "FLOAT32"; + case AttributeType.FLOAT64: + return "FLOAT64"; + case AttributeType.ENUMERATED: + return "Enum"; + case AttributeType.CODEDENUM: + return "Dbpos"; + case AttributeType.CHECK: + return "Check"; + case AttributeType.OCTET_STRING_64: + return "Octet64"; + case AttributeType.QUALITY: + return "Quality"; + case AttributeType.TIMESTAMP: + return "Timestamp"; + case AttributeType.VISIBLE_STRING_32: + return "VisString32"; + case AttributeType.VISIBLE_STRING_64: + return "VisString64"; + case AttributeType.VISIBLE_STRING_65: + return "VisString65"; + case AttributeType.VISIBLE_STRING_129: + return "VisString129"; + case AttributeType.VISIBLE_STRING_255: + return "VisString255"; + case AttributeType.GENERIC_BITSTRING: + return "OptFlds"; + case AttributeType.OBJECT_REFERENCE: + return "ObjRef"; + case AttributeType.ENTRY_TIME: + return "EntryTime"; + case AttributeType.PHYCOMADDR: + return "PhyComAddr"; + case AttributeType.CONSTRUCTED: + return "Struct"; + default: + return "null"; + } + } + + public static AttributeType CreateFromSclString(string typeString) + { + if (typeString.Equals("BOOLEAN")) + return AttributeType.BOOLEAN; + else if (typeString.Equals("INT8")) + return AttributeType.INT8; + else if (typeString.Equals("INT16")) + return AttributeType.INT16; + else if (typeString.Equals("INT32")) + return AttributeType.INT32; + else if (typeString.Equals("INT64")) + return AttributeType.INT64; + else if (typeString.Equals("INT128")) + return AttributeType.INT128; + else if (typeString.Equals("INT8U")) + return AttributeType.INT8U; + else if (typeString.Equals("INT16U")) + return AttributeType.INT16U; + else if (typeString.Equals("INT24U")) + return AttributeType.INT24U; + else if (typeString.Equals("INT32U")) + return AttributeType.INT32U; + else if (typeString.Equals("FLOAT32")) + return AttributeType.FLOAT32; + else if (typeString.Equals("FLOAT64")) + return AttributeType.FLOAT64; + else if (typeString.Equals("Enum")) + return AttributeType.ENUMERATED; + else if (typeString.Equals("Dbpos")) + return AttributeType.CODEDENUM; + else if (typeString.Equals("Check")) + return AttributeType.CHECK; + else if (typeString.Equals("Tcmd")) + return AttributeType.CODEDENUM; + else if (typeString.Equals("Octet64")) + return AttributeType.OCTET_STRING_64; + else if (typeString.Equals("Quality")) + return AttributeType.QUALITY; + else if (typeString.Equals("Timestamp")) + return AttributeType.TIMESTAMP; + else if (typeString.Equals("VisString32")) + return AttributeType.VISIBLE_STRING_32; + else if (typeString.Equals("VisString64")) + return AttributeType.VISIBLE_STRING_64; + else if (typeString.Equals("VisString65")) + return AttributeType.VISIBLE_STRING_65; + else if (typeString.Equals("VisString129")) + return AttributeType.VISIBLE_STRING_129; + else if (typeString.Equals("ObjRef")) + return AttributeType.OBJECT_REFERENCE; + else if (typeString.Equals("VisString255")) + return AttributeType.VISIBLE_STRING_255; + else if (typeString.Equals("Unicode255")) + return AttributeType.UNICODE_STRING_255; + else if (typeString.Equals("OptFlds")) + return AttributeType.GENERIC_BITSTRING; + else if (typeString.Equals("TrgOps")) + return AttributeType.GENERIC_BITSTRING; + else if (typeString.Equals("EntryID")) + return AttributeType.OCTET_STRING_8; + else if (typeString.Equals("EntryTime")) + return AttributeType.ENTRY_TIME; + else if (typeString.Equals("PhyComAddr")) + return AttributeType.PHYCOMADDR; + else if (typeString.Equals("Struct")) + return AttributeType.CONSTRUCTED; + else + return AttributeType.OTHER; + + } + } + + public enum ValKind + { + Spec = 0, + Conf = 1, + RO = 2, + Set = 3, + NONE = 4 + + } + + public enum SclFC + { + /** Status information */ + ST = 0, + /** Measurands - analog values */ + MX = 1, + /** Setpoint */ + SP = 2, + /** Substitution */ + SV = 3, + /** Configuration */ + CF = 4, + /** Description */ + DC = 5, + /** Setting group */ + SG = 6, + /** Setting group editable */ + SE = 7, + /** Service response / Service tracking */ + SR = 8, + /** Operate received */ + OR = 9, + /** Blocking */ + BL = 10, + /** Extended definition */ + EX = 11, + /** Control */ + CO = 12, + /** Unicast SV */ + US = 13, + /** Multicast SV */ + MS = 14, + /** Unbuffered report */ + RP = 15, + /** Buffered report */ + BR = 16, + /** Log control blocks */ + LG = 17, + + /** All FCs - wildcard value */ + ALL = 99, + NONE = -1 + } + + public class SclType : SclElementWithPrivate + { + private bool isUsed = false; + private bool isNSDCheckedType = false; + private List usedOn = new List(); + + public string Id + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "id"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, xmlNode, "id", value); + } + } + + public string Description + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "desc"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, xmlNode, "desc", value); + } + } + + public bool IsUsed + { + get + { + return isUsed; + } + set + { + isUsed = value; + } + } + + public bool IsNSDCheckedType + { + get + { + return isNSDCheckedType; + } + set + { + isNSDCheckedType = value; + } + } + + public List UsedOn { get => usedOn; set => usedOn = value; } + + public SclType(SclDocument sclDocument, XmlNode xmlNode) + : base(sclDocument, xmlNode) + { + XmlAttribute idAttr = xmlNode.Attributes["id"]; + + //if (idAttr == null) + // sclDocument.AddIssue(xmlNode, "ERROR", "SclType", "No id attribute", this, "MissingId"); + + //throw new SclParserException (xmlNode, "no id attribute"); + + + } + + public SclType Clone() + { + XmlNode newNode = xmlNode.CloneNode(true); + + SclType clone = new SclType(sclDocument, newNode); + + return clone; + } + } + + public class SclDataObjectDefinition + { + private string name; + private string type; + private int count = 0; + private bool trans = false; + + public XmlNode XmlNode; + private SclDocument sclDocument; + + public void SetType(String value) + { + type = value; + var attribute = XmlNode.Attributes["type"]; + attribute.Value = value; + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(XmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, XmlNode, "name", value.ToString()); + } + } + + public string Type + { + get + { + return type; + } + + set + { + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, XmlNode, "type", value); + } + } + + public int Count + { + get + { + return count; + } + set + { + count = value; + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, XmlNode, "count", value.ToString()); + } + } + + public bool IsTransient + { + get + { + return XmlHelper.ParseBooleanAttribute(XmlNode, "transient", false); + } + set + { + XmlHelper.SetBooleanAttributeCreateIfNotExists(sclDocument.XmlDocument, XmlNode, "transient", value); + } + } + + public string Desc + { + get + { + XmlAttribute descAttr = XmlNode.Attributes["desc"]; + + if (descAttr == null) + return null; + else + return descAttr.Value; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, XmlNode, "desc", value); + } + } + + public SclDataObjectDefinition(XmlNode xmlNode, SclDocument sclDocument) + { + XmlNode = xmlNode; + this.sclDocument = sclDocument; + + XmlAttribute nameAttr = xmlNode.Attributes["name"]; + + if (nameAttr == null) + throw new SclParserException(xmlNode, "DO is missing name attribute"); + + name = nameAttr.Value; + + + XmlAttribute typeAttr = xmlNode.Attributes["type"]; + + if (typeAttr == null) + throw new SclParserException(xmlNode, "DO is missing type attribute"); + + type = typeAttr.Value; + + XmlAttribute countAttr = xmlNode.Attributes["count"]; + + if (countAttr != null) + count = Convert.ToInt32(countAttr.Value); + } + } + + public class SclDO : SclDataObjectDefinition + { + public SclDO(XmlNode xmlNode, SclDocument sclDocument) : base(xmlNode, sclDocument) + { + } + } + + public class SclSDO : SclDataObjectDefinition + { + public SclSDO(XmlNode xmlNode, SclDocument sclDocument) : base(xmlNode, sclDocument) + { + } + } + + /// + /// Helper class to represent trigger conditions for SclDA and SclBDA classes + /// + public class SclTriggerOptions + { + private readonly bool dchg = false; /* 1 */ + private readonly bool qchg = false; /* 2 */ + private readonly bool dupd = false; /* 4 */ + private readonly bool period = false; /* 8 */ + private readonly bool gi = true; /* 16 */ + + public bool Dchg + { + get + { + return dchg; + } + } + + public bool Qchg + { + get + { + return qchg; + } + } + + public bool Dupd + { + get + { + return dupd; + } + } + + public bool Period + { + get + { + return period; + } + } + + public bool Gi + { + get + { + return gi; + } + } + + private bool ParseBooleanAttribute(XmlNode xmlNode, string attrName, bool defaultValue) + { + XmlAttribute attr = xmlNode.Attributes[attrName]; + + if (attr == null) + return defaultValue; + + string attrValue = attr.Value.ToUpper(); + + if (attrValue.Equals("TRUE")) + return true; + else if (attrValue.Equals("FALSE")) + return false; + else + throw new SclParserException(xmlNode, "Illegal value for boolean attribute \"" + attrName + "\""); + } + + public SclTriggerOptions(XmlNode xmlNode) + { + dchg = ParseBooleanAttribute(xmlNode, "dchg", false); + qchg = ParseBooleanAttribute(xmlNode, "qchg", false); + dupd = ParseBooleanAttribute(xmlNode, "dupd", false); + period = ParseBooleanAttribute(xmlNode, "period", false); + gi = ParseBooleanAttribute(xmlNode, "gi", true); + } + + public int GetIntValue() + { + int intValue = 0; + + if (dchg) intValue += 1; + if (qchg) intValue += 2; + if (dupd) intValue += 4; + if (period) intValue += 8; + if (gi) intValue += 16; + + return intValue; + } + } + + public class SclVal + { + private readonly XmlNode xmlNode; + private readonly XmlDocument xmlDoc; + private readonly XmlNamespaceManager nsManager; + private string value; + private int group; + + public XmlNode XmlNode + { + get + { + return xmlNode; + } + } + + public string Value + { + get + { + value = xmlNode.InnerText; + + if (value != null) + value.Trim(); + + return value; + } + set + { + xmlNode.InnerText = value; + } + } + + public int Group + { + get + { + XmlAttribute groupAttr = xmlNode.Attributes["sGroup"]; + + if (groupAttr != null) + group = Convert.ToInt32(groupAttr.Value); + else + group = 0; + + return group; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDoc, xmlNode, "sGroup", value.ToString()); + + } + } + + public SclVal(XmlNode xmlNode) + { + + this.xmlNode = xmlNode; + + value = xmlNode.InnerText; + + if (value != null) + value.Trim(); + + XmlAttribute groupAttr = xmlNode.Attributes["sGroup"]; + + if (groupAttr != null) + group = Convert.ToInt32(groupAttr.Value); + else + group = 0; + } + + public SclVal(XmlDocument xmlDocument, XmlNode xmlNode) + { + xmlDoc = xmlDocument; + this.xmlNode = xmlNode; + + value = xmlNode.InnerText; + + if (value != null) + value.Trim(); + + XmlAttribute groupAttr = xmlNode.Attributes["sGroup"]; + + if (groupAttr != null) + group = Convert.ToInt32(groupAttr.Value); + else + group = 0; + } + + + } + + public class SclDataAttributeDefinition + { + private readonly string name = null; + private string type = null; + private string desc = null; + private bool dchg = false; + private bool qchg = false; + private bool dupd = false; + private bool valImport = false; + private readonly ValKind valKind = ValKind.Set; + private int count = 0; + private readonly SclFC fc = SclFC.NONE; + private readonly AttributeType attributeType = AttributeType.OTHER; + public SclTriggerOptions triggerOptions = null; + private List values = null; + public XmlNode XmlNode; + private SclDocument sclDocument; + + + public string Desc + { + get + { + return desc; + } + } + public bool Dchg + { + get + { + return dchg; + } + } + public bool Qchg + { + get + { + return qchg; + } + } + public bool Dupd + { + get + { + return dupd; + } + } + public bool ValImport + { + get + { + return valImport; + } + } + public ValKind ValKind + { + get + { + return valKind; + } + } + + + public List GetValues() + { + return values; + } + + public SclVal GetVal() + { + if (values != null) + { + foreach (SclVal val in values) + return val; + } + + return null; + } + + public string Name + { + get + { + return XmlHelper.GetAttributeValue(XmlNode, "name"); + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, XmlNode, "name", value.ToString()); + } + } + + public string Type + { + get + { + return type; + } + } + + public int Count + { + get + { + return count; + } + set + { + count = value; + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, XmlNode, "count", value.ToString()); + } + } + + public SclFC Fc + { + get + { + return fc; + } + } + + public AttributeType AttributeType + { + get + { + return attributeType; + } + + } + + public SclTriggerOptions TriggerOptions + { + get + { + return triggerOptions; + } + } + + public string SAddr + { + get + { + return XmlHelper.GetAttributeValue(XmlNode, "sAddr"); + } + + } + + public void SetType(String value) + { + type = value; + var attribute = XmlNode.Attributes["type"]; + attribute.Value = value; + } + + private void ParseValNodes(XmlNode xmlNode, XmlNamespaceManager nsManager) + { + // There can be multiple "Val" nodes for setting groups FC=SG + XmlNodeList valNodes = xmlNode.SelectNodes("scl:Val", nsManager); + + foreach (XmlNode valNode in valNodes) + { + if (values == null) + values = new List(); + + SclVal val = new SclVal(valNode); + + values.Add(val); + } + } + + public SclDataAttributeDefinition(SclDocument sclDocument, XmlNode xmlNode) + { + XmlNode = xmlNode; + this.sclDocument = sclDocument; + + XmlAttribute nameAttr = xmlNode.Attributes["name"]; + + if (nameAttr == null) + throw new SclParserException(xmlNode, "DA is missing name attribute"); + + name = nameAttr.Value; + + + XmlAttribute bTypeAttr = xmlNode.Attributes["bType"]; + + if (bTypeAttr != null) + { + attributeType = AttributeTypeExtensions.CreateFromSclString(bTypeAttr.Value); + } + else + throw new SclParserException(xmlNode, "DA is missing bType attribute"); + + XmlAttribute typeAttr = xmlNode.Attributes["type"]; + + if (typeAttr != null) + type = typeAttr.Value; + + triggerOptions = new SclTriggerOptions(xmlNode); + + XmlAttribute countAttr = xmlNode.Attributes["count"]; + + if (countAttr != null) + count = Convert.ToInt32(countAttr.Value); + + XmlAttribute fcAttr = xmlNode.Attributes["fc"]; + + if (fcAttr != null) + fc = (SclFC)Enum.Parse(typeof(SclFC), fcAttr.Value); + else + fc = SclFC.NONE; + + XmlAttribute descAttr = xmlNode.Attributes["desc"]; + if (descAttr != null) + desc = descAttr.Value; + + XmlAttribute dchgAttr = xmlNode.Attributes["dchg"]; + if (dchgAttr != null) + if (dchgAttr.Value == "true") + dchg = true; + + XmlAttribute qchgAttr = xmlNode.Attributes["qchg"]; + if (qchgAttr != null) + if (qchgAttr.Value == "true") + qchg = true; + + XmlAttribute dupdAttr = xmlNode.Attributes["dupd"]; + if (dupdAttr != null) + if (dupdAttr.Value == "true") + dupd = true; + + XmlAttribute valImportAttr = xmlNode.Attributes["valImport"]; + if (valImportAttr != null) + if (valImportAttr.Value == "true") + valImport = true; + + XmlAttribute valKindAttr = xmlNode.Attributes["valKind"]; + if (valKindAttr != null) + valKind = (ValKind)Enum.Parse(typeof(ValKind), valKindAttr.Value); + else + valKind = ValKind.Set; + + //Valkind default is "set" + + ParseValNodes(xmlNode, sclDocument.NsManager); + } + } + + public class SclDA : SclDataAttributeDefinition + { + public SclDA(XmlNode xmlNode, SclDocument sclDocument) : base(sclDocument, xmlNode) + { + } + } + + public class SclBDA : SclDataAttributeDefinition + { + public SclBDA(XmlNode xmlNode, SclDocument sclDocument) : + base(sclDocument, xmlNode) + { + } + } + + public class SclLNodeType : SclType + { + private readonly string lnClass = null; + private readonly List dataObjects = new List(); + private readonly XmlDocument xmlDocument; + private readonly XmlNamespaceManager nsManager; + + public void RemoveType(SclDataObjectDefinition sclDataObjectDefinition) + { + dataObjects.Remove(sclDataObjectDefinition); + + xmlNode.RemoveChild(sclDataObjectDefinition.XmlNode); + } + + public XmlDocument XmlDocument + { + get + { + return xmlDocument; + } + } + + public XmlNamespaceManager XmlNamespaceManager + { + get + { + return nsManager; + } + } + + public string LnClass + { + get + { + return XmlHelper.GetAttributeValue(xmlNode, "lnClass"); + + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "lnClass", value); + } + } + + public List DataObjects + { + get + { + return dataObjects; + } + } + + public string IedType + { + get { return XmlHelper.GetAttributeValue(xmlNode, "iedType"); } + set { XmlHelper.SetAttributeCreateIfNotExists(xmlDocument, xmlNode, "iedType", value); } + } + + private void ParseDataObjectNodes() + { + XmlNodeList doNodes = xmlNode.SelectNodes("scl:DO", nsManager); + + foreach (XmlNode doNode in doNodes) + dataObjects.Add(new SclDO(doNode, sclDocument)); + } + + public SclLNodeType(SclDocument sclDocument, XmlNode xmlNode) + : base(sclDocument, xmlNode) + { + nsManager = sclDocument.NsManager; + + this.xmlNode = xmlNode; + + xmlDocument = sclDocument.XmlDocument; + + XmlAttribute lnClassAttr = xmlNode.Attributes["lnClass"]; + + if (lnClassAttr == null) + throw new SclParserException(xmlNode, "no lnClass attribute"); + + LnClass = lnClassAttr.Value; + + ParseDataObjectNodes(); + } + + } + + public class SclDOType : SclType + { + private string cdc = null; + private readonly string iedType = null; + private readonly List subDataObjects = new List(); + private readonly List dataAttributes = new List(); + + public void RemoveType(SclDataObjectDefinition sclDataObjectDefinition) + { + subDataObjects.Remove(sclDataObjectDefinition); + xmlNode.RemoveChild(sclDataObjectDefinition.XmlNode); + } + + public void RemoveType(SclDataAttributeDefinition sclDataAttributeDefinition) + { + dataAttributes.Remove(sclDataAttributeDefinition); + + xmlNode.RemoveChild(sclDataAttributeDefinition.XmlNode); + } + + public string Cdc + { + get + { + return cdc; + } + set + { + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, xmlNode, "cdc", value); + cdc = value; + + } + } + + public string IedType + { + get + { + return iedType; + } + } + + public List SubDataObjects + { + get + { + return subDataObjects; + } + } + + public SclDataObjectDefinition GetSDO(string name) + { + foreach (SclDataObjectDefinition sclSdo in subDataObjects) + { + if (sclSdo.Name != null && sclSdo.Name.Equals(name)) + return sclSdo; + } + + return null; + } + + public List DataAttributes + { + get + { + return dataAttributes; + } + } + + private void ParseSubDataObjectNodes() + { + XmlNodeList doNodes = xmlNode.SelectNodes("scl:SDO", sclDocument.NsManager); + + foreach (XmlNode doNode in doNodes) + subDataObjects.Add(new SclSDO(doNode, sclDocument)); + } + + + private void ParseDataAttributeNodes() + { + XmlNodeList daNodes = xmlNode.SelectNodes("scl:DA", sclDocument.NsManager); + + foreach (XmlNode daNode in daNodes) + dataAttributes.Add(new SclDA(daNode, sclDocument)); + + } + + public SclDOType(SclDocument sclDocument, XmlNode xmlNode) + : base(sclDocument, xmlNode) + { + XmlAttribute cdcAttr = xmlNode.Attributes["cdc"]; + + if (cdcAttr == null) + throw new SclParserException(xmlNode, "no cdc attribute"); + + + cdc = cdcAttr.Value; + + XmlAttribute iedType = xmlNode.Attributes["iedType"]; + if (iedType != null) + this.iedType = iedType.Value; + + ParseSubDataObjectNodes(); + + ParseDataAttributeNodes(); + } + + } + + public class SclDAType : SclType + { + private readonly List subDataAttributes = new List(); + + public void RemoveType(SclDataAttributeDefinition sclDataAttributeDefinition) + { + subDataAttributes.Remove(sclDataAttributeDefinition); + xmlNode.RemoveChild(sclDataAttributeDefinition.XmlNode); + } + + public List SubDataAttributes + { + get + { + return subDataAttributes; + } + } + + public SclDataAttributeDefinition GetBDA(string name) + { + foreach (SclDataAttributeDefinition bda in subDataAttributes) + { + if (bda.Name.Equals(name)) + return bda; + } + + return null; + } + + public SclDAType(SclDocument sclDocument, XmlNode xmlNode) + : base(sclDocument, xmlNode) + { + XmlNodeList bdaNodes = xmlNode.SelectNodes("scl:BDA", sclDocument.NsManager); + + foreach (XmlNode bdaNode in bdaNodes) + subDataAttributes.Add(new SclBDA(bdaNode, sclDocument)); + } + + + } + + public class SclEnumVal + { + private readonly int ord; + private /*readonly*/ string symbolicName = null; + public XmlNode XmlNode; + public SclDocument sclDocument; + + public int Ord + { + get + { + return ord; + } + } + + public string SymbolicName + { + get + { + if (XmlHelper.GetAttributeValue(XmlNode, "symbolicName") != null) + return XmlHelper.GetAttributeValue(XmlNode, "symbolicName"); + else + return symbolicName; + } + set + { + + //this.symbolicName = value; + XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, XmlNode, "symbolicName", value); + } + //get + //{ + // return this.symbolicName; + //} + //set + //{ + + // XmlHelper.SetAttributeCreateIfNotExists(sclDocument.XmlDocument, XmlNode, "id", value); + //} + } + + public SclEnumVal(XmlNode xmlNode) + { + XmlAttribute xmlAttr = xmlNode.Attributes["ord"]; + + if (xmlAttr == null) + throw new SclParserException(xmlNode, "EnumVal has no \"ord\" attribute"); + + ord = Convert.ToInt32(xmlAttr.Value); + + symbolicName = xmlNode.InnerXml; + + XmlNode = xmlNode; + } + + + + + public bool Equals(SclEnumVal other) + { + if (Ord == other.Ord) + { + if (SymbolicName.Equals(other.SymbolicName)) + return true; + else + return false; + } + else + return false; + } + } + + public class SclEnumType : SclType + { + private readonly List enumValues = new List(); + + public void RemoveType(SclEnumVal sclEnumVal) + { + enumValues.Remove(sclEnumVal); + + xmlNode.RemoveChild(sclEnumVal.XmlNode); + } + + public List EnumValues { get { return enumValues; } } + + public SclEnumType(SclDocument sclDocument, XmlNode xmlNode) + : base(sclDocument, xmlNode) + { + XmlNodeList enumValNodes = xmlNode.SelectNodes("scl:EnumVal", sclDocument.NsManager); + + foreach (XmlNode enumValNode in enumValNodes) + enumValues.Add(new SclEnumVal(enumValNode)); + } + + + public int GetOrdinalValue(string symbolicValue) + { + foreach (SclEnumVal enumValue in enumValues) + { + if (enumValue.SymbolicName == symbolicValue) + return enumValue.Ord; + } + + return -1; + } + + /// + /// Check if two EnumTypes are equal (have the same values) + /// + /// + /// + public bool Equals(SclEnumType other) + { + if (Id.Equals(other.Id)) + { + if (enumValues.Count == other.enumValues.Count) + { + + for (int i = 0; i < enumValues.Count; i++) + { + if (enumValues[i].Equals(other.enumValues[i]) == false) + return false; + } + + return true; + } + else + return false; + } + else + return false; + } + } + + } +} + diff --git a/tools/model_generator_dotnet/SCLParser/src/SclValidatorMessage.cs b/tools/model_generator_dotnet/SCLParser/src/SclValidatorMessage.cs new file mode 100644 index 00000000..ed71714e --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/SclValidatorMessage.cs @@ -0,0 +1,66 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System.Xml.Schema; + +namespace IEC61850.SCL +{ + public class SclValidatorMessage + { + private XmlSeverityType level; + private string message; + private int lineNo = -1; + private int linePos = -1; + + public XmlSeverityType Level + { + get + { + return level; + } + } + + public string Message + { + get + { + return message; + } + } + + public int LineNo + { + get + { + return lineNo; + } + } + + public int LinePos + { + get + { + return linePos; + } + } + + public SclValidatorMessage(XmlSeverityType level, string message) + { + this.level = level; + this.message = message; + } + + public SclValidatorMessage(XmlSeverityType level, string message, int lineNo, int linePos) + : this(level, message) + { + this.lineNo = lineNo; + this.linePos = linePos; + } + } + +} diff --git a/tools/model_generator_dotnet/SCLParser/src/XmlHelper.cs b/tools/model_generator_dotnet/SCLParser/src/XmlHelper.cs new file mode 100644 index 00000000..48637b1d --- /dev/null +++ b/tools/model_generator_dotnet/SCLParser/src/XmlHelper.cs @@ -0,0 +1,82 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using System; +using System.Xml; + +namespace IEC61850.SCL +{ + internal class XmlHelper + { + public static XmlAttribute GetAttributeCreateIfNotExist(XmlDocument xmlDoc, XmlNode node, string attrName) + { + XmlAttribute xmlAttr = node.Attributes[attrName]; + + if (xmlAttr == null) + { + xmlAttr = xmlDoc.CreateAttribute(attrName); + node.Attributes.Append(xmlAttr); + } + + return xmlAttr; + } + + public static void + SetAttributeCreateIfNotExists(XmlDocument xmlDoc, XmlNode node, string attrName, string value) + { + XmlAttribute xmlAttr = GetAttributeCreateIfNotExist(xmlDoc, node, attrName); + + xmlAttr.Value = value; + } + + public static void + SetBooleanAttributeCreateIfNotExists(XmlDocument xmlDoc, XmlNode node, string attrName, bool value) + { + string strVal; + + if (value) + strVal = "true"; + else + strVal = "false"; + + SetAttributeCreateIfNotExists(xmlDoc, node, attrName, strVal); + } + + + public static string GetAttributeValue(XmlNode node, string attrName) + { + string value = null; + + XmlAttribute xmlAttr = node.Attributes[attrName]; + + if (xmlAttr != null) + value = xmlAttr.Value; + + return value; + } + + + public static bool + ParseBooleanAttribute(XmlNode xmlNode, string attributeName, bool defaultValue) + { + XmlAttribute attr = xmlNode.Attributes[attributeName]; + + bool attrVal = defaultValue; + + if (attr != null) + { + if (Boolean.TryParse(attr.Value, out attrVal) == false) + throw new SclParserException(xmlNode, attributeName + ": failed to parse boolean attribute"); + } + + return attrVal; + } + } + +} + diff --git a/tools/model_generator_dotnet/StaticModelGenerator/StaticModelGenerator.csproj b/tools/model_generator_dotnet/StaticModelGenerator/StaticModelGenerator.csproj new file mode 100644 index 00000000..4e4c8ce8 --- /dev/null +++ b/tools/model_generator_dotnet/StaticModelGenerator/StaticModelGenerator.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.0 + + + + + + + diff --git a/tools/model_generator_dotnet/StaticModelGenerator/src/C_Structures.cs b/tools/model_generator_dotnet/StaticModelGenerator/src/C_Structures.cs new file mode 100644 index 00000000..cbb77c1a --- /dev/null +++ b/tools/model_generator_dotnet/StaticModelGenerator/src/C_Structures.cs @@ -0,0 +1,1129 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using IEC61850.SCL; +using IEC61850.SCL.DataModel; +using System; +using System.Collections.Generic; + +namespace StaticModelGenerator.C_Structures +{ + /** FCs (Functional constraints) according to IEC 61850-7-2 */ + public enum eFunctionalConstraint + { + /** Status information */ + IEC61850_FC_ST = 0, + /** Measurands - analog values */ + IEC61850_FC_MX = 1, + /** Setpoint */ + IEC61850_FC_SP = 2, + /** Substitution */ + IEC61850_FC_SV = 3, + /** Configuration */ + IEC61850_FC_CF = 4, + /** Description */ + IEC61850_FC_DC = 5, + /** Setting group */ + IEC61850_FC_SG = 6, + /** Setting group editable */ + IEC61850_FC_SE = 7, + /** Service response / Service tracking */ + IEC61850_FC_SR = 8, + /** Operate received */ + IEC61850_FC_OR = 9, + /** Blocking */ + IEC61850_FC_BL = 10, + /** Extended definition */ + IEC61850_FC_EX = 11, + /** Control */ + IEC61850_FC_CO = 12, + /** Unicast SV */ + IEC61850_FC_US = 13, + /** Multicast SV */ + IEC61850_FC_MS = 14, + /** Unbuffered report */ + IEC61850_FC_RP = 15, + /** Buffered report */ + IEC61850_FC_BR = 16, + /** Log control blocks */ + IEC61850_FC_LG = 17, + /** Goose control blocks */ + IEC61850_FC_GO = 18, + + /** All FCs - wildcard value */ + IEC61850_FC_ALL = 99, + IEC61850_FC_NONE = -1 + } + + public enum DataAttributeType + { + IEC61850_UNKNOWN_TYPE = -1, + IEC61850_BOOLEAN = 0,/* int */ + IEC61850_INT8 = 1, /* int8_t */ + IEC61850_INT16 = 2, /* int16_t */ + IEC61850_INT32 = 3, /* int32_t */ + IEC61850_INT64 = 4, /* int64_t */ + IEC61850_INT128 = 5, /* no native mapping! */ + IEC61850_INT8U = 6, /* uint8_t */ + IEC61850_INT16U = 7, /* uint16_t */ + IEC61850_INT24U = 8, /* uint32_t */ + IEC61850_INT32U = 9, /* uint32_t */ + IEC61850_FLOAT32 = 10, /* float */ + IEC61850_FLOAT64 = 11, /* double */ + IEC61850_ENUMERATED = 12, + IEC61850_OCTET_STRING_64 = 13, + IEC61850_OCTET_STRING_6 = 14, + IEC61850_OCTET_STRING_8 = 15, + IEC61850_VISIBLE_STRING_32 = 16, + IEC61850_VISIBLE_STRING_64 = 17, + IEC61850_VISIBLE_STRING_65 = 18, + IEC61850_VISIBLE_STRING_129 = 19, + IEC61850_VISIBLE_STRING_255 = 20, + IEC61850_UNICODE_STRING_255 = 21, + IEC61850_TIMESTAMP = 22, + IEC61850_QUALITY = 23, + IEC61850_CHECK = 24, + IEC61850_CODEDENUM = 25, + IEC61850_GENERIC_BITSTRING = 26, + IEC61850_CONSTRUCTED = 27, + IEC61850_ENTRY_TIME = 28, + IEC61850_PHYCOMADDR = 29, + IEC61850_CURRENCY = 30, + IEC61850_OPTFLDS = 31, /* bit-string(10) */ + IEC61850_TRGOPS = 32 /* bit-string(6) */ + } + + + public class C_InitializeValues + { + public string c_text; + public C_InitializeValues() + { + } + + } + + public class C_DO_DA_Structure + { + public string objRef; + + public C_DO_DA_Structure() + { + } + } + + public class C_DataAttributeStructure : C_DO_DA_Structure + { + public string ModelNodeType = "DataAttributeModelType"; + public string name; + public string parent; + public string sibling = "NULL"; + public string child = "NULL"; + public int elementCount = 0; /* value > 0 if this is an array */ + public int arrayIndex = -1; /* value > -1 when this is an array element */ + + public DataAttribute DataAttribute = null; + + public string triggerOptions; /* TRG_OPT_DATA_CHANGED | TRG_OPT_QUALITY_CHANGED | TRG_OPT_DATA_UPDATE */ + + public string mmsValue = "NULL"; + + public string sAddr = "0"; /* TODO remove in version 2.0 */ + + public string refName = null; + + public bool isTransient = false; + + public SclFC sclFC = SclFC.NONE; + + //public List c_DataAttributeStructures = new List(); + + public C_DataAttributeStructure() : base() + { + + } + + public string ExternNameToString() + { + return "extern DataAttribute " + objRef + ";"; + } + + private static DataAttributeType ConvertToDataAttributeType(AttributeType type) + { + switch (type) + { + case AttributeType.BOOLEAN: return DataAttributeType.IEC61850_BOOLEAN; + case AttributeType.INT8: return DataAttributeType.IEC61850_INT8; + case AttributeType.INT16: return DataAttributeType.IEC61850_INT16; + case AttributeType.INT32: return DataAttributeType.IEC61850_INT32; + case AttributeType.INT64: return DataAttributeType.IEC61850_INT64; + case AttributeType.INT128: return DataAttributeType.IEC61850_INT128; + case AttributeType.INT8U: return DataAttributeType.IEC61850_INT8U; + case AttributeType.INT16U: return DataAttributeType.IEC61850_INT16U; + case AttributeType.INT24U: return DataAttributeType.IEC61850_INT24U; + case AttributeType.INT32U: return DataAttributeType.IEC61850_INT32U; + case AttributeType.FLOAT32: return DataAttributeType.IEC61850_FLOAT32; + case AttributeType.FLOAT64: return DataAttributeType.IEC61850_FLOAT64; + case AttributeType.ENUMERATED: return DataAttributeType.IEC61850_ENUMERATED; + case AttributeType.OCTET_STRING_64: return DataAttributeType.IEC61850_OCTET_STRING_64; + case AttributeType.OCTET_STRING_6: return DataAttributeType.IEC61850_OCTET_STRING_6; + case AttributeType.OCTET_STRING_8: return DataAttributeType.IEC61850_OCTET_STRING_8; + case AttributeType.VISIBLE_STRING_32: return DataAttributeType.IEC61850_VISIBLE_STRING_32; + case AttributeType.VISIBLE_STRING_64: return DataAttributeType.IEC61850_VISIBLE_STRING_64; + case AttributeType.VISIBLE_STRING_65: return DataAttributeType.IEC61850_VISIBLE_STRING_65; + case AttributeType.VISIBLE_STRING_129: return DataAttributeType.IEC61850_VISIBLE_STRING_129; + case AttributeType.VISIBLE_STRING_255: return DataAttributeType.IEC61850_VISIBLE_STRING_255; + case AttributeType.UNICODE_STRING_255: return DataAttributeType.IEC61850_UNICODE_STRING_255; + case AttributeType.TIMESTAMP: return DataAttributeType.IEC61850_TIMESTAMP; + case AttributeType.QUALITY: return DataAttributeType.IEC61850_QUALITY; + case AttributeType.CHECK: return DataAttributeType.IEC61850_CHECK; + case AttributeType.CODEDENUM: return DataAttributeType.IEC61850_CODEDENUM; + case AttributeType.GENERIC_BITSTRING: return DataAttributeType.IEC61850_GENERIC_BITSTRING; + case AttributeType.CONSTRUCTED: return DataAttributeType.IEC61850_CONSTRUCTED; + case AttributeType.ENTRY_TIME: return DataAttributeType.IEC61850_ENTRY_TIME; + case AttributeType.PHYCOMADDR: return DataAttributeType.IEC61850_PHYCOMADDR; + case AttributeType.CURRENCY: return DataAttributeType.IEC61850_CURRENCY; + case AttributeType.OTHER: + default: + return DataAttributeType.IEC61850_UNKNOWN_TYPE; + } + } + + private static eFunctionalConstraint ConvertToFunctionalConstraint(SclFC sclFC) + { + switch (sclFC) + { + case SclFC.ST: return eFunctionalConstraint.IEC61850_FC_ST; + case SclFC.MX: return eFunctionalConstraint.IEC61850_FC_MX; + case SclFC.SP: return eFunctionalConstraint.IEC61850_FC_SP; + case SclFC.SV: return eFunctionalConstraint.IEC61850_FC_SV; + case SclFC.CF: return eFunctionalConstraint.IEC61850_FC_CF; + case SclFC.DC: return eFunctionalConstraint.IEC61850_FC_DC; + case SclFC.SG: return eFunctionalConstraint.IEC61850_FC_SG; + case SclFC.SE: return eFunctionalConstraint.IEC61850_FC_SE; + case SclFC.SR: return eFunctionalConstraint.IEC61850_FC_SR; + case SclFC.OR: return eFunctionalConstraint.IEC61850_FC_OR; + case SclFC.BL: return eFunctionalConstraint.IEC61850_FC_BL; + case SclFC.EX: return eFunctionalConstraint.IEC61850_FC_EX; + case SclFC.CO: return eFunctionalConstraint.IEC61850_FC_CO; + case SclFC.US: return eFunctionalConstraint.IEC61850_FC_US; + case SclFC.MS: return eFunctionalConstraint.IEC61850_FC_MS; + case SclFC.RP: return eFunctionalConstraint.IEC61850_FC_RP; + case SclFC.BR: return eFunctionalConstraint.IEC61850_FC_BR; + case SclFC.LG: return eFunctionalConstraint.IEC61850_FC_LG; + case SclFC.ALL: return eFunctionalConstraint.IEC61850_FC_ALL; + case SclFC.NONE: return eFunctionalConstraint.IEC61850_FC_NONE; + default: + throw new ArgumentOutOfRangeException(nameof(sclFC), $"Unhandled SclFC value: {sclFC}"); + } + } + + private string TrgOrtTotring(SclTriggerOptions trgOps) + { + string text = "0"; + + if (trgOps.Dchg) + text += " + TRG_OPT_DATA_CHANGED"; + + if (trgOps.Dchg) + text += " + TRG_OPT_DATA_UPDATE"; + + if (trgOps.Dchg) + text += " + TRG_OPT_QUALITY_CHANGED"; + + if (isTransient) + text += " + TRG_OPT_TRANSIENT"; + + return text; + } + + public override string ToString() + { + string daName = parent; + + //if (DataAttribute.Fc == SclFC.SE) + // daName += "_SE_" + name; + //else + daName += "_" + name; + + + string cText = "DataAttribute " + objRef + " = {\n"; + cText += " " + ModelNodeType + ",\n"; + cText += " \"" + name + "\",\n"; + cText += " (ModelNode*) &" + parent + ",\n"; + + if (sibling == "NULL") + cText += " " + sibling + ",\n"; + else + cText += " (ModelNode*) &" + sibling + ",\n"; + + + + if (child == "NULL") + cText += " " + child + ",\n"; + else + cText += " (ModelNode*) &" + child + ",\n"; + + cText += " " + elementCount + ",\n"; + cText += " " + arrayIndex + ",\n"; + cText += " " + ConvertToFunctionalConstraint(sclFC).ToString() + ",\n"; + cText += " " + ConvertToDataAttributeType(DataAttribute.AttributeType).ToString() + ",\n"; + cText += " " + TrgOrtTotring(DataAttribute.Definition.triggerOptions) + ",\n"; + cText += " " + mmsValue + ",\n"; + + //TODO -> Shot address -> ataAttribute.getShortAddress() + + cText += " " + sAddr.ToString() + "\n"; + + cText += "};"; + + return cText; + } + + } + + public class C_DataObjectStructure : C_DO_DA_Structure + { + public string ModelNodeType = "DataObjectModelType"; + public string name; + public string parent; + public string sibling = "NULL"; + public string child = "NULL"; + public int elementCount = 0; /* value > 0 if this is an array */ + public int arrayIndex = -1; /* value > -1 when this is an array element */ + //public List c_DO_DA_Structures = new List(); + public DataObject DataObject; + + public C_DataObjectStructure() : base() + { + + } + + public string ExternNameToString() + { + return "extern DataObject " + objRef + ";"; + } + + public override string ToString() + { + string cText = ""; + if(arrayIndex == -1) + cText = "DataObject " + parent + "_" + name + " = {\n"; + else + cText = "DataObject " + parent + "_" + name + "_" + arrayIndex + " = {\n"; + //cText = "DataObject " + parent + "_" + name + " = {\n"; + cText += " " + ModelNodeType + ",\n"; + cText += " \"" + name + "\",\n"; + + if(arrayIndex != -1) + cText += " (ModelNode*) &" + parent + "_" + name + ",\n"; + else + cText += " (ModelNode*) &" + parent + ",\n"; + + if (sibling == "NULL") + cText += " " + sibling + ",\n"; + else + cText += " (ModelNode*) &" + parent + "_" + sibling + ",\n"; + + if (child != "NULL") + cText += " (ModelNode*) &" + child + ",\n"; + else + cText += " NULL,\n"; + + cText += " " + elementCount + ",\n"; + + if(elementCount == 0) + cText += " " + arrayIndex + "\n"; + else + cText += " 0" + arrayIndex + "\n"; + cText += "};"; + + return cText; + } + + } + + public class C_LogicalNodeStructure + { + public string ModelNodeType = "LogicalNodeModelType"; + public string name; + public string parent; + public string sibling = "NULL"; + public string firstChild = "NULL"; + public string objRef; + public List c_DataObjectOrDataAttributeStructures = new List(); + + public C_LogicalNodeStructure() + { + + } + + public string ExternNameToString() + { + return "extern LogicalNode " + objRef + ";"; + } + + public override string ToString() + { + string cText = "LogicalNode " + parent + "_" + name + " = {\n"; + cText += " " + ModelNodeType + ",\n"; + cText += " \"" + name + "\",\n"; + cText += " (ModelNode*) &" + parent + ",\n"; + if (sibling == "NULL") + cText += " " + sibling + ",\n"; + else + cText += " (ModelNode*) &" + parent + "_" + sibling + ",\n"; + + if (firstChild == "NULL") + cText += " " + firstChild + "\n"; + else + cText += " (ModelNode*) &" + parent + "_" + name + "_" + firstChild + "\n"; + + cText += "};"; + + return cText; + } + + } + + public class C_LogicalDeviceStructure + { + public string ModelNodeType = "LogicalDeviceModelType"; + public string name; /* LD instance */ + public string parent; + public string sibling = "NULL"; + public string firstChild = "NULL"; + public string ldName = "NULL"; /* ldName (when using functional naming) */ + public List c_LogicalNodeStructures = new List(); + public string objRef; + + public C_LogicalDeviceStructure() + { + } + + public string ExternNameToString() + { + return "extern LogicalDevice " + objRef + ";"; + } + + public override string ToString() + { + string cText = "LogicalDevice " + objRef + " = {\n"; + cText += " " + ModelNodeType + ",\n"; + cText += " \"" + name + "\",\n"; + cText += " (ModelNode*) &" + parent + ",\n"; + if (sibling == "NULL") + cText += " " + sibling + ",\n"; + else + cText += " (ModelNode*) &" + sibling + ",\n"; + + if (firstChild == "NULL") + cText += " " + firstChild + ",\n"; + else + cText += " (ModelNode*) &" + parent + "_" + name + "_" + firstChild + ",\n"; + + if (ldName == "NULL") + cText += " " + ldName + "\n"; + else + cText += " \"" + ldName + "\"\n"; + + cText += "};"; + + return cText; + } + } + + public class C_LogStructure + { + public Log log; + public string externName; + public string sibling = "NULL"; + public string parent; + + public C_LogStructure() + { + } + + public string ExternNameToString() + { + return "extern Log " + externName + ";"; + } + + public override string ToString() + { + string cText = "Log " + externName + " = {\n"; + cText += " &" + parent + ",\n"; + + if (log.Name != null) + cText += " \"" + log.Name + "\",\n"; + else + cText += " NULL,\n"; + + if (sibling == "NULL") + cText += " " + sibling + "\n"; + else + cText += " &" + sibling + "\n"; + + cText += "};"; + + return cText; + } + } + + public class C_LogControlBlockStructure + { + public LogControl logControl; + public string externName; + public string sibling = "NULL"; + public string parent; + public string ldInst; + public bool hasOwner = false; + public string lnClass; + + + public C_LogControlBlockStructure() + { + } + + public string ExternNameToString() + { + return "extern LogControlBlock " + externName + ";"; + } + + string logRef() + { + string logRef; + string lcbString = " "; + + if (logControl.SclLogControl.LogName != null) + { + if (logControl.SclLogControl.LdInst == null) + logRef = ldInst + "/"; + else + logRef = logControl.SclLogControl.LdInst + "/"; + + if (logControl.SclLogControl.LnClass != null) + logRef += logControl.SclLogControl.LnClass + "$"; + else + logRef += lnClass + "$"; + + lcbString += "\"" + logRef + logControl.SclLogControl.LogName + "\",\n"; + } + + else + lcbString += " NULL,\n"; + + return lcbString; + } + + private int TrgOpsConvert() + { + int triggerOps = 0; + + if (logControl.SclLogControl.TrgOps != null) + triggerOps = logControl.SclLogControl.TrgOps.GetIntValue(); + + if (triggerOps >= 16) + triggerOps = triggerOps - 16; + + return triggerOps; + } + + public override string ToString() + { + string cText = "LogControlBlock " + externName + " = {\n"; + cText += " &" + parent + ",\n"; + cText += " \"" + logControl.Name + "\",\n"; + + if (logControl.SclLogControl.DatSet != null) + cText += " \"" + logControl.SclLogControl.DatSet + "\",\n"; + else + cText += " NULL,\n"; + + + cText += logRef(); + + cText += " " + TrgOpsConvert() + ",\n"; + + if (logControl.SclLogControl.IntgPd != null) + cText += " " + logControl.SclLogControl.IntgPd + ",\n"; + else + cText += " 0,\n"; + + + cText += " " + logControl.SclLogControl.LogEna.ToString().ToLower() + ",\n"; + cText += " " + logControl.SclLogControl.ReasonCode.ToString().ToLower() + ",\n"; + + + if (sibling == "NULL") + cText += " " + sibling + "\n"; + else + cText += " &" + sibling + "\n"; + + cText += "};"; + + return cText; + } + } + + public class C_SettingGroupStructure + { + public SclSettingControl settingControl; + public string parent; + public string externName; + + public C_SettingGroupStructure() + { + + } + + public string ExternNameToString() + { + return "extern SettingGroupControlBlock " + externName + ";"; + } + + public override string ToString() + { + string cText = "SettingGroupControlBlock " + externName + " = {\n"; + cText += " &" + parent + ",\n"; + cText += " " + settingControl.ActSG + ",\n"; + cText += " " + settingControl.NumOfSGs + ",\n"; + cText += " 0,\n"; + cText += " false,\n"; + cText += " 0,\n"; + cText += " 0,\n"; + cText += " NULL,\n"; + cText += "};"; + + return cText; + } + } + + public class C_GSEControlBlockStructure + { + public GSEControl GSEControl; + public SclGSE SclGSE; + public string lnPrefix; + public string parent; + public string rptId; + public string externName; + public int reportNumber = -1; + public string index; + public bool hasOwner = false; + public string sibling = "NULL"; + public string phyComAddrName = "NULL"; + private string gseString = ""; + private string min = "-1"; + private string max = "-1"; + + public C_GSEControlBlockStructure() + { + } + + public string ExternNameToString() + { + return "extern GSEControlBlock " + externName + ";"; + } + + private void LoadPhyComAddrName() + { + if (SclGSE != null) + { + if (SclGSE.Mintime != null) + if (SclGSE.Mintime != "") + min = SclGSE.Mintime; + if (SclGSE.Maxtime != null) + if (SclGSE.Maxtime != "") + max = SclGSE.Maxtime; + + if (SclGSE.SclAddress != null) + { + phyComAddrName = lnPrefix + "_gse" + reportNumber + "_address"; + + gseString += "\nstatic PhyComAddress " + phyComAddrName + " = {\n"; + gseString += " " + SclGSE.SclAddress.VlanPriority + ",\n"; + gseString += " " + SclGSE.SclAddress.VlanId + ",\n"; + gseString += " " + SclGSE.SclAddress.AppId + ",\n"; + gseString += " {"; + + for (int i = 0; i < 6; i++) + { + gseString += "0x" + (SclGSE.SclAddress.MacAddress[i]).ToString("x1"); + if (i == 5) + gseString += "}\n"; + else + gseString += ", "; + } + + gseString += "};\n\n"; + } + } + } + + public override string ToString() + { + LoadPhyComAddrName(); + + string cText = gseString; + cText += "GSEControlBlock " + externName + " = {\n"; + cText += " &" + parent + ",\n"; + cText += " \"" + GSEControl.Name + index + "\",\n"; + + if (GSEControl.SclGSEControl.AppID != null) + cText += " \"" + GSEControl.SclGSEControl.AppID + "\",\n"; + else + cText += " NULL,\n"; + + + if (GSEControl.SclGSEControl.DatSet != null) + cText += " \"" + GSEControl.SclGSEControl.DatSet + "\",\n"; + else + cText += " NULL,\n"; + + cText += " " + GSEControl.SclGSEControl.ConfRev + ",\n"; + cText += " " + GSEControl.SclGSEControl.FixedOffs.ToString().ToLower() + ",\n"; + + if (phyComAddrName == "NULL") + cText += " " + phyComAddrName + ",\n"; + else + cText += " &" + phyComAddrName + ",\n"; + + cText += " " + min + ",\n"; + cText += " " + max + ",\n"; + + + if (sibling == "NULL") + cText += " " + sibling + "\n"; + else + cText += " &" + sibling + "\n"; + + cText += "};"; + + return cText; + } + } + + public class C_SMVControlBlockStructure + { + public SMVControl SMVControl; + public SclSMV SclSMV; + public string lnPrefix; + public string parent; + public string externName; + public int reportNumber = -1; + public string index; + public bool hasOwner = false; + public string sibling = "NULL"; + public string phyComAddrName = "NULL"; + private string smvString = ""; + + + public C_SMVControlBlockStructure() + { + } + + public string ExternNameToString() + { + return "extern SVControlBlock " + externName + ";"; + } + + private void LoadPhyComAddrName() + { + if (SclSMV != null) + { + if (SclSMV.SclAddress != null) + { + phyComAddrName = lnPrefix + "_smv" + reportNumber + "_address"; + + smvString += "\nstatic PhyComAddress " + phyComAddrName + " = {\n"; + smvString += " " + SclSMV.SclAddress.VlanPriority + ",\n"; + smvString += " " + SclSMV.SclAddress.VlanId + ",\n"; + smvString += " " + SclSMV.SclAddress.AppId + ",\n"; + smvString += " {"; + + for (int i = 0; i < 6; i++) + { + smvString += "0x" + (SclSMV.SclAddress.MacAddress[i]).ToString("x1"); + if (i == 5) + smvString += "}\n"; + else + smvString += ", "; + } + + smvString += "};\n\n"; + } + } + } + + public override string ToString() + { + LoadPhyComAddrName(); + + string cText = smvString; + cText += "SVControlBlock " + externName + " = {\n"; + cText += " &" + parent + ",\n"; + + if(SMVControl.SclSMVControl.Name != null) + cText += " \"" + SMVControl.Name + index + "\",\n"; + else + cText += " NULL,\n"; + + //if (SMVControl.SclSMVControl.Desc!= null) + // cText += " \"" + SclSMV.SclAddress.AppId + "\",\n";9 + //else + // cText += " NULL,\n"; + + if (SMVControl.SclSMVControl.SmvID != null) + cText += " \"" + SMVControl.SclSMVControl.SmvID + "\",\n"; + else + cText += " NULL,\n"; + + if (SMVControl.SclSMVControl.DataSet != null) + cText += " \"" + SMVControl.SclSMVControl.DataSet + "\",\n"; + else + cText += " NULL,\n"; + + if (SMVControl.SclSMVControl.SclSmvOpts != null) + { + cText += " " + SMVControl.SclSMVControl.SclSmvOpts.GetIntValue() + ",\n"; + } + else + { + cText += " 0,\n"; + } + + if (SMVControl.SclSMVControl.SmpMod != null) + cText += " " + SMVControl.SclSMVControl.SmpMod + ",\n"; + else + cText += " NULL,\n"; + + cText += " " + SMVControl.SclSMVControl.SmpRate + ",\n"; + + cText += " " + SMVControl.SclSMVControl.ConfRev + ",\n"; + + if (phyComAddrName == "NULL") + cText += " " + phyComAddrName + ",\n"; + else + cText += " &" + phyComAddrName + ",\n"; + + + cText += " " + SMVControl.SclSMVControl.Multicast.ToString().ToLower() + ",\n"; + + cText += " " + SMVControl.SclSMVControl.NofASDU + ",\n"; + + //if(SMVControl.SclSMVControl.SecurityEnabled != null) + // cText += " " + SMVControl.SclSMVControl.SecurityEnabled + ",\n"; + + if (sibling == "NULL") + cText += " " + sibling + "\n"; + else + cText += " &" + sibling + "\n"; + + cText += "};"; + + return cText; + } + } + public class C_ReportControlBlockStructure + { + public ReportControl ReportControl; + public string parent; + public string rptId; + public string externName; + public byte[] clientIpAddr; + public int reportNumber = -1; + public int reportsCount = -1; + public string index; + public bool hasOwner = false; + + + /* type (first byte) and address of the pre-configured client + type can be one of (0 - no reservation, 4 - IPv4 client, 6 - IPv6 client) */ + //public int clientReservation[17]; + + public string sibling = "NULL"; + + public C_ReportControlBlockStructure() + { + } + + public string ExternNameToString() + { + return "extern ReportControlBlock " + externName + ";"; + } + + private int TrgOpsConvert(SclTrgOps sclTriggerOptions) + { + int triggerOps = 16; + + if (sclTriggerOptions != null) + triggerOps = sclTriggerOptions.GetIntValue(); + + if (hasOwner) + triggerOps += 64; + + return triggerOps; + } + + private int OptFieldsConvert(SclOptFields sclOptFields) + { + int options = 0; + + if (sclOptFields != null) + { + if (sclOptFields.SeqNum) + options += 1; + if (sclOptFields.TimeStamp) + options += 2; + if (sclOptFields.ReasonCode) + options += 4; + if (sclOptFields.DataSet) + options += 8; + if (sclOptFields.DataRef) + options += 16; + if (sclOptFields.BufOvfl) + options += 32; + if (sclOptFields.EntryID) + options += 64; + if (sclOptFields.ConfigRef) + options += 128; + } + else + options = 32; + + return options; + + } + + private string clientIpAddrConvert() + { + string value = " {"; + for (int i = 0; i < 17; i++) + { + value += "0x" + (clientIpAddr[i] & 0xff).ToString("X1"); + if (i == 16) + value += "},\n"; + else + value += ", "; + } + + return value; + } + + public override string ToString() + { + string cText = "ReportControlBlock " + externName + " = {\n"; + cText += " &" + parent + ",\n"; + cText += " \"" + ReportControl.Name + index + "\",\n"; + + if (ReportControl.SclReportControl.RptID != null) + cText += " \"" + ReportControl.SclReportControl.RptID + "\",\n"; + else + cText += " NULL,\n"; + + cText += " " + ReportControl.SclReportControl.Buffered.ToString().ToLower() + ",\n"; + + if (ReportControl.SclReportControl.DatSet != null) + cText += " \"" + ReportControl.SclReportControl.DatSet + "\",\n"; + else + cText += " NULL,\n"; + + if (ReportControl.SclReportControl.ConfRev != null) + cText += " " + ReportControl.SclReportControl.ConfRev + ",\n"; + else + cText += " NULL,\n"; + + cText += " " + TrgOpsConvert(ReportControl.SclReportControl.TrgOps) + ",\n"; + cText += " " + OptFieldsConvert(ReportControl.SclReportControl.OptFields) + ",\n"; + + if (ReportControl.SclReportControl.BufTime != null) + cText += " " + ReportControl.SclReportControl.BufTime + ",\n"; + else + cText += " NULL,\n"; + + if (ReportControl.SclReportControl.IntgPd != null) + cText += " " + ReportControl.SclReportControl.IntgPd + ",\n"; + else + cText += " 0,\n"; + + cText += clientIpAddrConvert(); + + if (sibling == "NULL") + cText += " " + sibling + "\n"; + else + cText += " &" + sibling + "\n"; + + cText += "};"; + + return cText; + } + } + + public class C_DataSetStructure + { + public DataSet DataSet { get; set; } + public string externDataSetName { get; set; } + public List externDataSetEntries { get; set; } + public string logicalDeviceName; /* logical device instance name */ + public string name; /* eg. MMXU1$dataset1 */ + public int elementCount = 0; + public string fcdas = "NULL"; + public string sibling = "NULL"; + + public C_DataSetStructure() + { + externDataSetEntries = new List(); + } + + public string ExternToString() + { + return "extern DataSet " + externDataSetName + ";"; + } + + public override string ToString() + { + string cText = "DataSet " + externDataSetName + " = {\n"; + cText += " \"" + logicalDeviceName + "\",\n"; + cText += " \"" + name + "\",\n"; + cText += " " + elementCount.ToString() + ",\n"; + + if (fcdas == "NULL") + cText += " " + fcdas + ",\n"; + else + cText += " &" + fcdas + ",\n"; + + if (sibling == "NULL") + cText += " " + sibling + "\n"; + else + cText += " &" + sibling + "\n"; + + cText += "};"; + + return cText; + + } + + } + + public class C_IEDModelStructure + { + public string name; + public string modelPrefix; + public string firstChild = "NULL"; + public string dataSets = "NULL"; + public string rcbs = "NULL"; + public string gseCBs = "NULL"; + public string svCBs = "NULL"; + public string sgcbs = "NULL"; + public string lcbs = "NULL"; + public string logs = "NULL"; + + public C_IEDModelStructure() + { + } + + public override string ToString() + { + string cText = "IedModel " + modelPrefix + " = {\n"; + + cText += " \"" + name + "\",\n"; + + if (firstChild == "NULL") + cText += " " + firstChild + ",\n"; + else + cText += " &" + firstChild + ",\n"; + + if (dataSets == "NULL") + cText += " " + dataSets + ",\n"; + else + cText += " &" + dataSets + ",\n"; + + if (rcbs == "NULL") + cText += " " + rcbs + ",\n"; + else + cText += " &" + rcbs + ",\n"; + + if (gseCBs == "NULL") + cText += " " + gseCBs + ",\n"; + else + cText += " &" + gseCBs + ",\n"; + + if (svCBs == "NULL") + cText += " " + svCBs + ",\n"; + else + cText += " &" + svCBs + ",\n"; + + if (sgcbs == "NULL") + cText += " " + sgcbs + ",\n"; + else + cText += " &" + sgcbs + ",\n"; + + if (lcbs == "NULL") + cText += " " + lcbs + ",\n"; + else + cText += " &" + lcbs + ",\n"; + + if (logs == "NULL") + cText += " " + logs + ",\n"; + else + cText += " &" + logs + ",\n"; + + cText += " initializeValues\n"; + + cText += "};"; + + + return cText; + + } + } + + public class C_DatasetEntry + { + public string externDataSetName = ""; + public string logicalDeviceName = ""; + public bool isLDNameDynamicallyAllocated; + public string variableName = ""; + public int index = -1; + public string componentName = "NULL"; + public string value = "NULL"; + public string sibling = "NULL"; + + public C_DatasetEntry() + { } + + public string externDataSetNameToString() + { + return "extern DataSetEntry " + externDataSetName + ";"; + } + + public override string ToString() + { + string cText = "DataSetEntry " + externDataSetName + " = {\n"; + cText += " \"" + logicalDeviceName + "\",\n"; + cText += " " + isLDNameDynamicallyAllocated.ToString().ToLower() + ",\n"; + cText += " \"" + variableName + "\",\n"; + cText += " " + index.ToString() + ",\n"; + if (componentName != "NULL") + cText += " " + componentName + ",\n"; + else + cText += " " + componentName + ",\n"; + + cText += " " + value + ",\n"; + if (sibling == "NULL") + cText += " " + sibling + "\n"; + else + cText += " &" + sibling + "\n"; + + cText += "};"; + + return cText; + } + } + +} diff --git a/tools/model_generator_dotnet/StaticModelGenerator/src/StaticModelGenerator.cs b/tools/model_generator_dotnet/StaticModelGenerator/src/StaticModelGenerator.cs new file mode 100644 index 00000000..e319bcba --- /dev/null +++ b/tools/model_generator_dotnet/StaticModelGenerator/src/StaticModelGenerator.cs @@ -0,0 +1,1254 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using IEC61850.SCL; +using IEC61850.SCL.DataModel; +using StaticModelGenerator.C_Structures; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Runtime.InteropServices.ComTypes; +using DataSet = IEC61850.SCL.DataModel.DataSet; + +namespace StaticModelGenerator +{ + + public class StaticModelGenerator + { + List c_DataSetStructures = new List(); + List c_LogicalDeviceStructures = new List(); + List c_ReportContorlBlockStructures = new List(); + List c_GSEControlBlockStructures = new List(); + List c_SMVControlBlockStructures = new List(); + C_SettingGroupStructure c_SettingGroupControlStructure = null; + List c_LogControlBlockStructures = new List(); + List c_LogStructures = new List(); + C_IEDModelStructure c_IEDModelStructure = new C_IEDModelStructure(); + List c_InitializeValues = new List(); + List c_DO_DA_Structures = new List(); + SclDocument sclParser; + bool initializeOnce = false; + bool hasOwner = false; + SclConnectedAP connectedAP = null; + string modelPrefix; + + + public StaticModelGenerator(string fileName, string icdFile, FileStream cOut, FileStream hOut, + string outputFileName, string iedName, string accessPointName, string modelPrefix, + bool initializeOnce) + { + this.modelPrefix = modelPrefix; + this.initializeOnce = initializeOnce; + + sclParser = new SclDocument(fileName); + + string hDefineName = outputFileName.ToUpper().Replace('.', '_').Replace('-', '_') + "_H_"; + + if (hDefineName.LastIndexOf('/') >= 0) + { + hDefineName = hDefineName.Substring(hDefineName.LastIndexOf('/') + 1); + } + + SclIED ied = null; + + if (iedName == null) + ied = sclParser.IEDs.First(); + else + ied = sclParser.IEDs.Find(x => x.Name == iedName); + + if (ied == null) + { + throw new Exception("IED model not found in SCL file! Exit."); + } + + SclServices services = ied.SclServices; + + if (services != null) + { + ReportSettings rptSettings = services.ReportSettings; + + if (rptSettings != null) + { + hasOwner = rptSettings.Owner; + } + } + + SclAccessPoint accessPoint = null; + + if (accessPointName == null) + accessPoint = ied.AccessPoints.First(); + else + accessPoint = ied.AccessPoints.Find(x => x.Name == accessPointName); + + if (accessPoint == null) + { + throw new Exception("AccessPoint not found in SCL file! Exit."); + } + + if (sclParser.Communication != null) + connectedAP = sclParser.Communication.GetConnectedAP(accessPoint.Name, ied.Name); + + IEDDataModel iedModel = sclParser.GetDataModel(ied.Name, accessPoint.Name); + + using (cOut) + { + using (hOut) + { + using (StreamWriter writerC = new StreamWriter(cOut)) + { + using (StreamWriter writerH = new StreamWriter(hOut)) + { + printCFileHeader(icdFile, outputFileName, writerC); + + printHeaderFileHeader(icdFile, outputFileName, hDefineName, writerH); + + createDataCStructure(iedModel, modelPrefix, false); + + printForwardDeclarations(iedModel, writerC, writerH, modelPrefix); + + printDeviceModelDefinitions(iedModel, writerC, writerH, modelPrefix); + + printInitializerFunction(writerC); + + printVariablePointerDefines(writerH, modelPrefix); + + printHeaderFileFooter(writerH, hDefineName); + } + } + } + } + } + + private void printVariablePointerDefines(StreamWriter hOut, string modelPrefix) + { + hOut.WriteLine("\n\n\n"); + foreach (C_LogicalDeviceStructure c_LogicalDeviceStructure in c_LogicalDeviceStructures) + { + string define = c_LogicalDeviceStructure.objRef.Remove(0, modelPrefix.Length); + hOut.WriteLine("#define " + modelPrefix.ToUpper() + define + " (&" + c_LogicalDeviceStructure.objRef + ")"); + + foreach (C_LogicalNodeStructure c_LogicalNodeStructure in c_LogicalDeviceStructure.c_LogicalNodeStructures) + { + define = c_LogicalNodeStructure.objRef.Remove(0, modelPrefix.Length); + hOut.WriteLine("#define " + modelPrefix.ToUpper() + define + " (&" + c_LogicalNodeStructure.objRef + ")"); + + foreach (C_DO_DA_Structure c_DataObjectStructure in c_LogicalNodeStructure.c_DataObjectOrDataAttributeStructures) + printVariablePointerDefines(hOut, modelPrefix, c_DataObjectStructure); + + } + } + } + + private void printVariablePointerDefines(StreamWriter hOut, string modelPrefix, C_DO_DA_Structure c_DataAttributeStructure) + { + string define = c_DataAttributeStructure.objRef.Remove(0, modelPrefix.Length); + hOut.WriteLine("#define " + modelPrefix.ToUpper() + define + " (&" + c_DataAttributeStructure.objRef + ")"); + + } + + private void printInitializerFunction(StreamWriter cOut) + { + cOut.WriteLine("\nstatic void\ninitializeValues()"); + cOut.WriteLine("{"); + + foreach (C_InitializeValues c_InitializeValue in c_InitializeValues) + cOut.WriteLine(c_InitializeValue.c_text); + cOut.WriteLine("}"); + + } + + private void printDeviceModelDefinitions(IEDDataModel iedModel, StreamWriter cOut, StreamWriter hOut, string modelPrefix) + { + cOut.WriteLine(); + + foreach (C_DataSetStructure c_DataSetStructure in c_DataSetStructures) + cOut.WriteLine(c_DataSetStructure.ExternToString()); + + cOut.WriteLine(); + + foreach (C_DataSetStructure c_DataSetStructure in c_DataSetStructures) + { + foreach (C_DatasetEntry c_DatasetEntry in c_DataSetStructure.externDataSetEntries) + cOut.WriteLine(c_DatasetEntry.externDataSetNameToString()); + + cOut.WriteLine(); + + foreach (C_DatasetEntry c_DatasetEntry in c_DataSetStructure.externDataSetEntries) + { + cOut.WriteLine(c_DatasetEntry.ToString()); + cOut.WriteLine(); + } + + cOut.WriteLine(c_DataSetStructure.ToString()); + + } + + cOut.WriteLine(); + + foreach (C_LogicalDeviceStructure c_LogicalDeviceStructure in c_LogicalDeviceStructures) + { + cOut.WriteLine(c_LogicalDeviceStructure.ToString()); + cOut.WriteLine(); + + foreach (C_LogicalNodeStructure c_LogicalNodeStructure in c_LogicalDeviceStructure.c_LogicalNodeStructures) + { + cOut.WriteLine(c_LogicalNodeStructure.ToString()); + cOut.WriteLine(); + + foreach (C_DO_DA_Structure c_DO_DA_Structure in c_LogicalNodeStructure.c_DataObjectOrDataAttributeStructures) + { + if (c_DO_DA_Structure is C_DataObjectStructure objectStructure) + cOut.WriteLine(objectStructure.ToString()); + else + cOut.WriteLine((c_DO_DA_Structure as C_DataAttributeStructure).ToString()); + } + } + + } + + foreach (C_ReportControlBlockStructure c_ReportContorlBlockStructure in c_ReportContorlBlockStructures) + { + cOut.WriteLine(c_ReportContorlBlockStructure.ExternNameToString()); + } + + cOut.WriteLine(); + + foreach (C_ReportControlBlockStructure c_ReportContorlBlockStructure in c_ReportContorlBlockStructures) + { + cOut.WriteLine(c_ReportContorlBlockStructure.ToString()); + } + + cOut.WriteLine(); + + foreach (C_GSEControlBlockStructure c_GSEContorlBlockStructure in c_GSEControlBlockStructures) + { + cOut.WriteLine(c_GSEContorlBlockStructure.ExternNameToString()); + } + + cOut.WriteLine(); + + foreach (C_GSEControlBlockStructure c_GSEContorlBlockStructure in c_GSEControlBlockStructures) + { + cOut.WriteLine(c_GSEContorlBlockStructure.ToString()); + } + + if (c_SettingGroupControlStructure != null) + { + cOut.WriteLine(c_SettingGroupControlStructure.ExternNameToString()); + cOut.WriteLine(); + cOut.WriteLine(c_SettingGroupControlStructure.ToString()); + } + + cOut.WriteLine(); + + foreach (C_SMVControlBlockStructure c_SMVContorlBlockStructure in c_SMVControlBlockStructures) + { + cOut.WriteLine(c_SMVContorlBlockStructure.ExternNameToString()); + } + + cOut.WriteLine(); + + foreach (C_SMVControlBlockStructure c_SMVContorlBlockStructure in c_SMVControlBlockStructures) + { + cOut.WriteLine(c_SMVContorlBlockStructure.ToString()); + } + + cOut.WriteLine(); + + foreach (C_LogControlBlockStructure c_LogControlBlockStructure in c_LogControlBlockStructures) + { + cOut.WriteLine(c_LogControlBlockStructure.ExternNameToString()); + } + + cOut.WriteLine(); + + foreach (C_LogControlBlockStructure c_LogControlBlockStructure in c_LogControlBlockStructures) + { + cOut.WriteLine(c_LogControlBlockStructure.ToString()); + } + + cOut.WriteLine(); + + foreach (C_LogStructure log in c_LogStructures) + { + cOut.WriteLine(log.ExternNameToString()); + } + + cOut.WriteLine(); + + foreach (C_LogStructure log in c_LogStructures) + { + cOut.WriteLine(log.ToString()); + } + + cOut.WriteLine(); + + cOut.WriteLine(c_IEDModelStructure.ToString()); + + } + + private void printForwardDeclarations(IEDDataModel iedModel, StreamWriter cOut, StreamWriter hOut, string modelPrefix) + { + + cOut.WriteLine("static void initializeValues();"); + hOut.WriteLine("extern IedModel " + modelPrefix + ";"); + + foreach (C_LogicalDeviceStructure logicalDevice in c_LogicalDeviceStructures) + { + hOut.WriteLine(logicalDevice.ExternNameToString()); + + foreach (C_LogicalNodeStructure logicalNode in logicalDevice.c_LogicalNodeStructures) + { + hOut.WriteLine(logicalNode.ExternNameToString()); + + foreach (C_DO_DA_Structure c_DODA in logicalNode.c_DataObjectOrDataAttributeStructures) + printDataObjectForwardDeclarations(c_DODA, hOut); + } + } + } + + private static string toMmsString(string iecString) + { + return iecString.Replace('.', '$'); + } + + private void createDataObjectCStructure(List c_DO_DA_Structures, string dataAttributeSibling, string lnRef, DataObject dataObject, object parent, bool isTransiente, object sclDOI, int arrayIdx) + { + C_DataObjectStructure c_DataObjectStructure = new C_DataObjectStructure(); + c_DO_DA_Structures.Add(c_DataObjectStructure); + + c_DataObjectStructure.DataObject = dataObject; + + c_DataObjectStructure.parent = lnRef; + + c_DataObjectStructure.name = dataObject.Name; + if(c_DataObjectStructure.arrayIndex != -1) + c_DataObjectStructure.name = dataObject.Name + "_" + c_DataObjectStructure.arrayIndex; + else + c_DataObjectStructure.objRef = lnRef + "_" + dataObject.Name; + + if (dataObject.DataObjectsAndAttributes.Count > 0) + c_DataObjectStructure.child = c_DataObjectStructure.objRef + "_" + dataObject.DataObjectsAndAttributes.First().Name; + + if (parent is LogicalNode ln) + { + if (ln.DataObjects.Last() != dataObject) + { + DataObject sibling = ln.DataObjects[ln.DataObjects.IndexOf(dataObject) + 1]; + c_DataObjectStructure.sibling = sibling.Name; + } + else if (dataAttributeSibling != null) + c_DataObjectStructure.sibling = dataAttributeSibling; + } + else if (parent is DataObject doObj) + { + if (doObj.DataObjectsAndAttributes.Last() != dataObject) + { + DataObjectOrAttribute sibling = doObj.DataObjectsAndAttributes[doObj.DataObjectsAndAttributes.IndexOf(dataObject) + 1]; + c_DataObjectStructure.sibling = sibling.Name; + } + else if (dataAttributeSibling != null) + c_DataObjectStructure.sibling = dataAttributeSibling; + } + + + + bool isDoTransient = false; + + if (isTransiente) + isDoTransient = true; + else + if (dataObject.IsTransiente) + isDoTransient = true; + + if (dataObject.Count > 0) + { + c_DataObjectStructure.child = c_DataObjectStructure.objRef + "_0"; + c_DataObjectStructure.elementCount = dataObject.Count; + c_DataObjectStructure.arrayIndex = arrayIdx; + + for (int idx = 0; idx < dataObject.Count; idx++) + { + C_DataObjectStructure c_ArrayDataObjectStructure = new C_DataObjectStructure(); + c_DO_DA_Structures.Add(c_ArrayDataObjectStructure); + + c_ArrayDataObjectStructure.DataObject = dataObject; + + //c_ArrayDataObjectStructure.parent = lnRef; + c_ArrayDataObjectStructure.parent = lnRef + "_" + dataObject.Name; + + c_ArrayDataObjectStructure.name = dataObject.Name; + c_ArrayDataObjectStructure.objRef = lnRef + "_" + dataObject.Name + "_" + idx; + + if (idx != dataObject.Count - 1) + c_ArrayDataObjectStructure.sibling = lnRef + "_" + dataObject.Name + "_" + (idx + 1); + + c_ArrayDataObjectStructure.arrayIndex = idx; + + if (dataObject.DataObjectsAndAttributes.Count > 0) + { + string firstDataAttributeName = "NULL"; + + DataObjectOrAttribute dataObjectOrAttribute1 = dataObject.DataObjectsAndAttributes.First(); + if (dataObjectOrAttribute1 is DataAttribute da) + firstDataAttributeName = da.Name; + + c_ArrayDataObjectStructure.child = c_ArrayDataObjectStructure.objRef + "_" + dataObject.DataObjectsAndAttributes.First().Name; + + foreach (DataObjectOrAttribute dataObjectOrAttribute in dataObject.DataObjectsAndAttributes) + { + if (dataObjectOrAttribute is DataObject doObj) + { + SclSDI sclSDO = getSDI(sclDOI, dataObject.Name); + + createDataObjectCStructure(c_DO_DA_Structures, c_DataObjectStructure.objRef, firstDataAttributeName, doObj, dataObject, isDoTransient, sclSDO, -1); + + } + else + { + + createDataAttributeCStructure(c_DO_DA_Structures, c_DataObjectStructure.objRef, dataObjectOrAttribute as DataAttribute, dataObject, isDoTransient, sclDOI, -1); + + } + } + } + } + } + else + { + c_DataObjectStructure.arrayIndex = arrayIdx; + + string firstDataAttributeName = "NULL"; + + DataObjectOrAttribute dataObjectOrAttribute1 = dataObject.DataObjectsAndAttributes.First(); + if (dataObjectOrAttribute1 is DataAttribute da) + firstDataAttributeName = da.Name; + + foreach (DataObjectOrAttribute dataObjectOrAttribute in dataObject.DataObjectsAndAttributes) + { + if (dataObjectOrAttribute is DataObject doObj) + { + SclSDI sclSDO = getSDI(sclDOI, dataObject.Name); + + createDataObjectCStructure(c_DO_DA_Structures, c_DataObjectStructure.objRef, firstDataAttributeName, doObj, dataObject, isDoTransient, sclSDO, -1); + + } + else + { + + createDataAttributeCStructure(c_DO_DA_Structures, c_DataObjectStructure.objRef, dataObjectOrAttribute as DataAttribute, dataObject, isDoTransient, sclDOI, -1); + + } + } + + } + + } + + private void createDataAttributeCStructure(List c_DO_DA_Structures, string doName, DataAttribute dataAttribute, DataObjectOrAttribute parent, bool isDoTransient, object daiObj, int arrayIdx) + { + C_DataAttributeStructure c_DataAttributeStructure = new C_DataAttributeStructure(); + c_DO_DA_Structures.Add(c_DataAttributeStructure); + + c_DataAttributeStructure.parent = doName; + c_DataAttributeStructure.isTransient = isDoTransient; + c_DataAttributeStructure.name = dataAttribute.Name; + c_DataAttributeStructure.sclFC = dataAttribute.Fc; + c_DataAttributeStructure.DataAttribute = dataAttribute; + + if (c_DataAttributeStructure.arrayIndex != -1) + c_DataAttributeStructure.name = dataAttribute.Name + "_" + c_DataAttributeStructure.arrayIndex; + else + c_DataAttributeStructure.objRef = doName + "_" + dataAttribute.Name; + + c_DataAttributeStructure.objRef = doName + "_" + dataAttribute.Name; + c_DataAttributeStructure.elementCount = dataAttribute.Count; + + + if (dataAttribute.Definition.SAddr != null) + c_DataAttributeStructure.sAddr = dataAttribute.Definition.SAddr; + + if (parent is DataObject doObj) + { + if (doObj.DataObjectsAndAttributes.Count > 0) + { + int i = doObj.DataObjectsAndAttributes.IndexOf(dataAttribute); + if (i < doObj.DataObjectsAndAttributes.Count - 1) + { + DataObjectOrAttribute sibling = doObj.DataObjectsAndAttributes[i + 1]; + string siblindDOName = doName + "_" + sibling.Name; + + if (sibling is DataAttribute da) + { + if (da.Fc == SclFC.SE) + if (!siblindDOName.StartsWith(modelPrefix + "_SE")) + siblindDOName = siblindDOName.Replace(modelPrefix, modelPrefix + "_SE"); + } + + c_DataAttributeStructure.sibling = siblindDOName; + + } + + } + } + else if (parent is DataAttribute da) + { + if (da.subDataAttributes.Count > 0) + { + int i = da.subDataAttributes.IndexOf(dataAttribute); + if (i < da.subDataAttributes.Count - 1) + { + DataAttribute sibling = da.subDataAttributes[i + 1]; + string siblindDOName = doName + "_" + sibling.Name; + + if (sibling.Fc == SclFC.SE) + if (!siblindDOName.StartsWith(modelPrefix + "_SE")) + siblindDOName = siblindDOName.Replace(modelPrefix, modelPrefix + "_SE"); + + c_DataAttributeStructure.sibling = siblindDOName; + + } + + } + } + + + if (dataAttribute.Fc == SclFC.SE) + { + C_DataAttributeStructure c_SEDataAttributeStructure = new C_DataAttributeStructure(); + c_DO_DA_Structures.Add(c_SEDataAttributeStructure); + + c_SEDataAttributeStructure.parent = doName; + c_SEDataAttributeStructure.isTransient = isDoTransient; + c_SEDataAttributeStructure.name = dataAttribute.Name; + c_SEDataAttributeStructure.sclFC = dataAttribute.Fc; + c_SEDataAttributeStructure.DataAttribute = dataAttribute; + c_SEDataAttributeStructure.objRef = doName + "_" + dataAttribute.Name; + c_SEDataAttributeStructure.elementCount = dataAttribute.Count; + + if (dataAttribute.Definition.SAddr != null) + c_SEDataAttributeStructure.sAddr = dataAttribute.Definition.SAddr; + + if (!c_SEDataAttributeStructure.objRef.StartsWith(modelPrefix + "_SE_")) + c_SEDataAttributeStructure.objRef = c_SEDataAttributeStructure.objRef.Replace(modelPrefix, modelPrefix + "_SE"); + + if (dataAttribute.subDataAttributes.Count > 0) + c_SEDataAttributeStructure.child = c_SEDataAttributeStructure.objRef + "_" + dataAttribute.subDataAttributes.First().Name; + + if (dataAttribute.subDataAttributes.Count > 0) + c_DataAttributeStructure.sibling = c_SEDataAttributeStructure.objRef; + + if (parent is DataAttribute data_attribute) + { + if (!c_SEDataAttributeStructure.parent.StartsWith(modelPrefix + "_SE")) + c_SEDataAttributeStructure.parent = c_SEDataAttributeStructure.parent.Replace(modelPrefix, modelPrefix + "_SE"); + } + + + c_DataAttributeStructure.sclFC = SclFC.SG; + } + + if (dataAttribute.subDataAttributes.Count > 0) + c_DataAttributeStructure.child = c_DataAttributeStructure.objRef + "_" + dataAttribute.subDataAttributes.First().Name; + + if (dataAttribute.Count > 0) + { + for (int idx = 0; idx < dataAttribute.Count; idx++) + { + C_DataAttributeStructure arrayElement = new C_DataAttributeStructure(); + c_DO_DA_Structures.Add(arrayElement); + arrayElement.name = "NULL"; + arrayElement.parent = c_DataAttributeStructure.objRef; + + arrayElement.objRef = doName + "_" + dataAttribute.Name + "_" + idx; + + if (idx != dataAttribute.Count - 1) + arrayElement.sibling = doName + "_" + dataAttribute.Name + "_" + (idx + 1); + + if (dataAttribute.subDataAttributes.Count > 0) + arrayElement.child = arrayElement.objRef + "_" + dataAttribute.subDataAttributes.First().Name; + + arrayElement.elementCount = 0; + arrayElement.arrayIndex = idx; + + arrayElement.DataAttribute = dataAttribute; + + + if (idx == 0) + c_DataAttributeStructure.child = arrayElement.objRef; + + foreach (DataAttribute dataObjectOrAttribute in dataAttribute.subDataAttributes) + { + SclSDI sclSDI = getSDI(daiObj, dataAttribute.Name); + + createDataAttributeCStructure(c_DO_DA_Structures, arrayElement.objRef, dataObjectOrAttribute, dataAttribute, isDoTransient, sclSDI, -1); + } + } + } + else + { + if (dataAttribute.subDataAttributes.Count > 0) + c_DataAttributeStructure.child = c_DataAttributeStructure.objRef + "_" + dataAttribute.subDataAttributes.First().Name; + + foreach (DataAttribute dataObjectOrAttribute in dataAttribute.subDataAttributes) + { + SclSDI sclSDI = getSDI(daiObj, dataAttribute.Name); + + createDataAttributeCStructure(c_DO_DA_Structures, c_DataAttributeStructure.objRef, dataObjectOrAttribute, dataAttribute, isDoTransient, sclSDI, -1); + } + } + + SclDAI sclDAI = getDAI(daiObj, dataAttribute.Name); + + if (sclDAI != null) + if (sclDAI.Val != null) + printValue(c_DataAttributeStructure, sclDAI.Val); + } + + SclDAI getDAI(object parent, string name) + { + if (parent == null) + return null; + + if (parent is SclDOI sclDOI) + return sclDOI.SclDAIs.Find(x => x.Name == name); + else if (parent is SclSDI sclSDI) + return sclSDI.SclDAIs.Find(x => x.Name == name); + else + return null; + } + + SclSDI getSDI(object parent, string name) + { + if (parent == null) + return null; + + if (parent is SclDOI sclDOI) + return sclDOI.SclSDIs.Find(x => x.Name == name); + else if (parent is SclSDI sclSDI) + return sclSDI.SclSDIs.Find(x => x.Name == name); + else + return null; + } + + private void printValue(C_DataAttributeStructure c_DataAttributeStructure, string value) + { + C_InitializeValues c_InitializeValue = new C_InitializeValues(); + + c_InitializeValue.c_text = "\n"; + if (initializeOnce) + { + c_InitializeValue.c_text += "if (!"; + c_InitializeValue.c_text += c_DataAttributeStructure.objRef; + c_InitializeValue.c_text += ".mmsValue)\n"; + } + c_InitializeValue.c_text += c_DataAttributeStructure.objRef; + c_InitializeValue.c_text += ".mmsValue = "; + + switch (c_DataAttributeStructure.DataAttribute.AttributeType) + { + case AttributeType.INT64: + c_InitializeValue.c_text += "MmsValue_newIntegerFromInt32(" + value + ");"; + break; + + case AttributeType.ENUMERATED: + + string EnumType = c_DataAttributeStructure.DataAttribute.Definition.Type; + if (EnumType != null) + { + SclEnumType sclEnumType = sclParser.DataTypeTemplates.GetEnumType(EnumType); + if (sclEnumType != null) + { + SclEnumVal sclEnumVal = sclEnumType.EnumValues.Find(x => x.SymbolicName == value); + if (sclEnumVal != null) + c_InitializeValue.c_text += "MmsValue_newIntegerFromInt32(" + sclEnumVal.Ord + ");"; + else + { + Console.WriteLine("ERROR", "Model integrity", "Value " + value + " in DAI " + c_DataAttributeStructure.objRef + + " does not exist in enumerated type " + EnumType + ". Reload the file after fixing the problem!", "DAI_DataAttributeMissing"); + + } + } + else + { + Console.WriteLine("ERROR", "Model integrity", "Wrong ENUMERATED type " + EnumType + " in DAI " + c_DataAttributeStructure.objRef + , "DAI_DataAttributeMissing"); + } + + } + else + { + Console.WriteLine("ERROR", "Model integrity", "Wrong ENUMERATED type in DAI " + c_DataAttributeStructure.objRef, "DAI_DataAttributeMissing"); + } + break; + + case AttributeType.INT32U: + c_InitializeValue.c_text += "MmsValue_newUnsignedFromUint32(" + value + ");"; + break; + case AttributeType.BOOLEAN: + c_InitializeValue.c_text += "MmsValue_newBoolean(" + value + ");"; + break; + + case AttributeType.OCTET_STRING_64: + { + string daValName = c_DataAttributeStructure.DataAttribute.Name + "__val"; + + c_InitializeValue.c_text += "MmsValue_newOctetString(0, 64);\n"; + c_InitializeValue.c_text += "uint8_t " + daValName + "[] = "; + c_InitializeValue.c_text += value; + c_InitializeValue.c_text += ";\n"; + c_InitializeValue.c_text += "MmsValue_setOctetString("; + c_InitializeValue.c_text += c_DataAttributeStructure.DataAttribute.Name; + c_InitializeValue.c_text += ".mmsValue, " + daValName + ", " + value.Length + ");\n"; + } + break; + + case AttributeType.CODEDENUM: + { + c_InitializeValue.c_text += "MmsValue_newBitString(2);\n"; + c_InitializeValue.c_text += "MmsValue_setBitStringFromIntegerBigEndian("; + c_InitializeValue.c_text += c_DataAttributeStructure.DataAttribute.Name; + c_InitializeValue.c_text += ".mmsValue, "; + c_InitializeValue.c_text += value; + c_InitializeValue.c_text += ");\n"; + } + break; + + case AttributeType.UNICODE_STRING_255: + c_InitializeValue.c_text += "MmsValue_newMmsString(\"" + value + "\");"; + break; + case AttributeType.CURRENCY: + c_InitializeValue.c_text += "MmsValue_newVisibleString(\"" + value + "\");"; + break; + case AttributeType.FLOAT32: + c_InitializeValue.c_text += "MmsValue_newFloat(" + float.Parse(value).ToString(".0").Replace(",", ".") + ");"; + break; + case AttributeType.FLOAT64: + c_InitializeValue.c_text += "MmsValue_newDouble(" + value + ");"; + break; + + case AttributeType.TIMESTAMP: + c_InitializeValue.c_text += "MmsValue_newUtcTimeByMsTime(" + value + ");"; + break; + + case AttributeType.VISIBLE_STRING_255: + c_InitializeValue.c_text += "MmsValue_newVisibleString(\"" + value + "\");"; + break; + + default: + Console.WriteLine("Unknown default value for " + c_DataAttributeStructure.objRef + " type: " + c_DataAttributeStructure.DataAttribute.AttributeType.ToString()); + c_InitializeValue.c_text += "NULL;"; + break; + } + + c_InitializeValues.Add(c_InitializeValue); + } + + private void addLogControlBlockInstance(string lnPrefix, LogControl logcontrol, int lcbNumber, LogicalDevice logicalDevice, string lnClass) + { + C_LogControlBlockStructure c_LogContorlBlockStructure = new C_LogControlBlockStructure(); + c_LogContorlBlockStructure.logControl = logcontrol; + c_LogContorlBlockStructure.externName = lnPrefix + "_lcb" + lcbNumber.ToString(); + c_LogContorlBlockStructure.parent = lnPrefix; + c_LogContorlBlockStructure.hasOwner = hasOwner; + c_LogContorlBlockStructure.lnClass = lnClass; + c_LogContorlBlockStructure.ldInst = logicalDevice.Inst; + + c_LogControlBlockStructures.Add(c_LogContorlBlockStructure); + } + + private void addLogInstance(string lnPrefix, Log log, int lcbNumber) + { + C_LogStructure c_LogStructure = new C_LogStructure(); + c_LogStructure.log = log; + c_LogStructure.externName = lnPrefix + "_log" + lcbNumber.ToString(); + c_LogStructure.parent = lnPrefix; + + c_LogStructures.Add(c_LogStructure); + } + + private void addReportControlBlockInstance(string lnPrefix, ReportControl reportControl, string index, int reportNumber, int reportsCount, byte[] clientIpAddr) + { + C_ReportControlBlockStructure c_ReportContorlBlockStructure = new C_ReportControlBlockStructure(); + c_ReportContorlBlockStructure.ReportControl = reportControl; + c_ReportContorlBlockStructure.externName = lnPrefix + "_report" + reportsCount.ToString(); + c_ReportContorlBlockStructure.parent = lnPrefix; + c_ReportContorlBlockStructure.clientIpAddr = clientIpAddr; + c_ReportContorlBlockStructure.index = index; + c_ReportContorlBlockStructure.reportNumber = reportNumber; + c_ReportContorlBlockStructure.reportsCount = reportsCount; + c_ReportContorlBlockStructure.hasOwner = hasOwner; + + c_ReportContorlBlockStructures.Add(c_ReportContorlBlockStructure); + } + + private void addGSEControlBlockInstance(string lnPrefix, GSEControl reportControl, SclGSE sclGSE, int gseNumber) + { + C_GSEControlBlockStructure c_GSEContorlBlockStructure = new C_GSEControlBlockStructure(); + c_GSEContorlBlockStructure.GSEControl = reportControl; + c_GSEContorlBlockStructure.externName = lnPrefix + "_gse" + gseNumber.ToString(); + c_GSEContorlBlockStructure.parent = lnPrefix; + c_GSEContorlBlockStructure.reportNumber = gseNumber; + c_GSEContorlBlockStructure.hasOwner = hasOwner; + c_GSEContorlBlockStructure.lnPrefix = lnPrefix; + c_GSEContorlBlockStructure.SclGSE = sclGSE; + + c_GSEControlBlockStructures.Add(c_GSEContorlBlockStructure); + } + + private void addSMVControlBlockInstance(string lnPrefix, SMVControl smvControl, SclSMV sclSMV, int smvNumber) + { + C_SMVControlBlockStructure c_SMVContorlBlockStructure = new C_SMVControlBlockStructure(); + c_SMVContorlBlockStructure.SMVControl = smvControl; + c_SMVContorlBlockStructure.externName = lnPrefix + "_smv" + smvNumber.ToString(); + c_SMVContorlBlockStructure.parent = lnPrefix; + c_SMVContorlBlockStructure.reportNumber = smvNumber; + c_SMVContorlBlockStructure.hasOwner = hasOwner; + c_SMVContorlBlockStructure.lnPrefix = lnPrefix; + c_SMVContorlBlockStructure.SclSMV = sclSMV; + + c_SMVControlBlockStructures.Add(c_SMVContorlBlockStructure); + } + private void addSettingGroulBlockInstance(string lnPrefix, SclSettingControl settingControl) + { + c_SettingGroupControlStructure = new C_SettingGroupStructure(); + c_SettingGroupControlStructure.settingControl = settingControl; + c_SettingGroupControlStructure.parent = lnPrefix; + c_SettingGroupControlStructure.externName = lnPrefix + "_sgcb"; + } + + private void createDataCStructure(IEDDataModel iedModel, string modelPrefix, bool isTransient) + { + c_IEDModelStructure = new C_IEDModelStructure(); + c_IEDModelStructure.name = iedModel.Name; + c_IEDModelStructure.modelPrefix = modelPrefix; + + foreach (LogicalDevice logicalDevice in iedModel.LogicalDevices) + { + C_LogicalDeviceStructure c_LogicalDeviceStructure = new C_LogicalDeviceStructure(); + c_LogicalDeviceStructure.parent = modelPrefix; + c_LogicalDeviceStructure.name = logicalDevice.Inst; + c_LogicalDeviceStructure.objRef = modelPrefix + "_" + logicalDevice.Inst; + + c_IEDModelStructure.firstChild = c_LogicalDeviceStructure.objRef; + + if (iedModel.LogicalDevices.Last() != logicalDevice) + { + LogicalDevice sibling = iedModel.LogicalDevices[iedModel.LogicalDevices.IndexOf(logicalDevice) + 1]; + c_LogicalDeviceStructure.sibling = sibling.Inst; + } + + c_LogicalDeviceStructure.firstChild = logicalDevice.LogicalNodes.First().Name; + + foreach (LogicalNode logicalNode in logicalDevice.LogicalNodes) + { + C_LogicalNodeStructure c_LogicalNodeStructure = new C_LogicalNodeStructure(); + c_LogicalNodeStructure.parent = c_LogicalDeviceStructure.objRef; + c_LogicalNodeStructure.name = logicalNode.Name; + c_LogicalNodeStructure.objRef = c_LogicalDeviceStructure.objRef + "_" + logicalNode.Name; + + if (logicalDevice.LogicalNodes.Last() != logicalNode) + { + LogicalNode sibling = logicalDevice.LogicalNodes[logicalDevice.LogicalNodes.IndexOf(logicalNode) + 1]; + c_LogicalNodeStructure.sibling = sibling.Name; + } + + c_LogicalNodeStructure.firstChild = logicalNode.DataObjects.First().Name; + + foreach (DataObject dataObject in logicalNode.DataObjects) + { + SclDOI sclDOI = logicalNode.SclElement.DOIs.Find(x => x.Name == dataObject.Name); + createDataObjectCStructure(c_LogicalNodeStructure.c_DataObjectOrDataAttributeStructures, null, c_LogicalNodeStructure.objRef, dataObject, logicalNode, isTransient, sclDOI, -1); + } + + if (connectedAP != null) + { + int gseNumber = 0; + foreach (GSEControl gSEControl in logicalNode.GSEControls) + { + SclGSE sclGSE = connectedAP.GSEs.Find(x => x.CbName == gSEControl.Name); + + if (sclGSE != null) + { + addGSEControlBlockInstance(c_LogicalNodeStructure.objRef, gSEControl, sclGSE, gseNumber); + + gseNumber++; + + } + else + { + Console.WriteLine("GSE not found for GoCB " + gSEControl.Name); + } + } + + int gseIndex = 0; + + if (c_GSEControlBlockStructures.Count > 0) + { + foreach (C_GSEControlBlockStructure c_GSEContorlBlockStructure in c_GSEControlBlockStructures) + { + if (c_GSEContorlBlockStructure != c_GSEControlBlockStructures.Last()) + { + c_GSEContorlBlockStructure.sibling = c_GSEControlBlockStructures[gseIndex + 1].externName; + } + + gseIndex++; + } + + c_IEDModelStructure.gseCBs = c_GSEControlBlockStructures.First().externName; + } + + int smvNumber = 0; + foreach (SMVControl sMVControl in logicalNode.SMVControls) + { + SclSMV sclSMV = connectedAP.SMVs.Find(x => x.CbName == sMVControl.Name); + + if (sclSMV != null) + { + addSMVControlBlockInstance(c_LogicalNodeStructure.objRef, sMVControl, sclSMV, smvNumber); + + gseNumber++; + + } + else + { + Console.WriteLine("GSE not found for GoCB " + sMVControl.Name); + } + } + + int smvIndex = 0; + + if (c_SMVControlBlockStructures.Count > 0) + { + foreach (C_SMVControlBlockStructure c_SMVContorlBlockStructure in c_SMVControlBlockStructures) + { + if (c_SMVContorlBlockStructure != c_SMVControlBlockStructures.Last()) + { + c_SMVContorlBlockStructure.sibling = c_SMVControlBlockStructures[gseIndex + 1].externName; + } + + smvIndex++; + } + + c_IEDModelStructure.svCBs = c_SMVControlBlockStructures.First().externName; + } + } + + int lcbNumber = 0; + + foreach (LogControl logControl in logicalNode.LogControls) + { + addLogControlBlockInstance(c_LogicalNodeStructure.objRef, logControl, lcbNumber, logicalDevice, logicalNode.LnClass); + + lcbNumber++; + } + + int logIndex = 0; + + if (c_LogControlBlockStructures.Count > 0) + { + foreach (C_LogControlBlockStructure c_LogContorlBlockStructure in c_LogControlBlockStructures) + { + if (c_LogContorlBlockStructure != c_LogControlBlockStructures.Last()) + { + c_LogContorlBlockStructure.sibling = c_LogControlBlockStructures[logIndex + 1].externName; + } + + logIndex++; + } + + c_IEDModelStructure.lcbs = c_LogControlBlockStructures.First().externName; + } + + int logNumber = 0; + + foreach (Log log in logicalNode.Logs) + { + addLogInstance(c_LogicalNodeStructure.objRef, log, logNumber); + + logNumber++; + } + + int log_Index = 0; + + if (c_LogStructures.Count > 0) + { + foreach (C_LogStructure c_logs in c_LogStructures) + { + if (c_logs != c_LogStructures.Last()) + { + c_logs.sibling = c_LogStructures[log_Index + 1].externName; + } + + log_Index++; + } + + c_IEDModelStructure.logs = c_LogStructures.First().externName; + } + + if (logicalNode.SettingControl != null) + { + addSettingGroulBlockInstance(c_LogicalNodeStructure.objRef, logicalNode.SettingControl); + + c_IEDModelStructure.sgcbs = c_SettingGroupControlStructure.externName; + } + + int reportsCount = 0; + + foreach (ReportControl reportControl in logicalNode.ReportControlBlocks) + { + if (reportControl.SclReportControl.Indexed) + { + int maxInstances = 1; + + List clientLNs = null; + + if (reportControl.SclReportControl.RptEna != null) + { + maxInstances = reportControl.SclReportControl.RptEna.Max; + + clientLNs = reportControl.SclReportControl.RptEna.ClientLNs; + } + + try + { + for (int i = 0; i < maxInstances; i++) + { + string index = (i + 1).ToString("00"); + Console.WriteLine("print report instance " + index); + + byte[] clientAddress = new byte[17]; + clientAddress[0] = 0; + + if (clientLNs != null) + { + if (i <= (clientLNs.Count - 1)) + { + SclClientLN sclClientLN = clientLNs[i]; + + string iedName = sclClientLN.IedName; + string apRef = sclClientLN.ApRef; + + string ipAddress = getIpAddressByIedName(iedName, apRef); + + IPAddress iPAddress = IPAddress.Parse(ipAddress); + + if (iPAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) + { + clientAddress[0] = 4; + for (int j = 0; j < 4; j++) + clientAddress[j + 1] = iPAddress.GetAddressBytes()[j]; + } + else if (iPAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) + { + clientAddress[0] = 6; + for (int j = 0; j < 16; j++) + clientAddress[j + 1] = iPAddress.GetAddressBytes()[j]; + } + } + } + + addReportControlBlockInstance(c_LogicalNodeStructure.objRef, reportControl, index, logicalNode.ReportControlBlocks.Count, reportsCount, clientAddress); + reportsCount++; + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + } + else + { + byte[] clientAddress = new byte[17]; + clientAddress[0] = 0; + addReportControlBlockInstance(c_LogicalNodeStructure.objRef, reportControl, "", logicalNode.ReportControlBlocks.Count, reportsCount, clientAddress); + reportsCount++; + } + + int rptIndex = 0; + + if (c_ReportContorlBlockStructures.Count > 0) + { + foreach (C_ReportControlBlockStructure c_ReportContorlBlockStructure in c_ReportContorlBlockStructures) + { + if (c_ReportContorlBlockStructure != c_ReportContorlBlockStructures.Last()) + { + c_ReportContorlBlockStructure.sibling = c_ReportContorlBlockStructures[rptIndex + 1].externName; + } + + rptIndex++; + } + + c_IEDModelStructure.rcbs = c_ReportContorlBlockStructures.First().externName; + } + } + + int datasetCOunt = 0; + foreach (DataSet dataSet in logicalNode.DataSets) + { + C_DataSetStructure c_DataSetStructure = new C_DataSetStructure(); + c_DataSetStructure.DataSet = dataSet; + c_DataSetStructure.externDataSetName = modelPrefix + "ds_" + logicalDevice.Inst + "_" + logicalNode.Name + "_" + dataSet.Name; + c_DataSetStructure.logicalDeviceName = logicalDevice.Inst; + c_DataSetStructure.name = logicalNode.Name + "$" + dataSet.Name; + c_DataSetStructure.elementCount = dataSet.SclDataSet.Fcdas.Count; + + if (datasetCOunt + 1 < logicalNode.DataSets.Count) + c_DataSetStructure.sibling = modelPrefix + "ds_" + logicalDevice.Inst + "_" + logicalNode.Name + "_" + logicalNode.DataSets[datasetCOunt + 1].Name; + + int fcdaCount = 0; + foreach (SclFCDA sclFCDA in dataSet.SclDataSet.Fcdas) + { + C_DatasetEntry c_DatasetEntry = new C_DatasetEntry(); + c_DatasetEntry.externDataSetName = c_DataSetStructure.externDataSetName + "_fcda" + fcdaCount.ToString(); + + if (fcdaCount == 0) + c_DataSetStructure.fcdas = c_DatasetEntry.externDataSetName; + + if (fcdaCount + 1 < dataSet.SclDataSet.Fcdas.Count) + c_DatasetEntry.sibling = c_DataSetStructure.externDataSetName + "_fcda" + (fcdaCount + 1).ToString(); + + c_DatasetEntry.logicalDeviceName = logicalDevice.Inst; + c_DatasetEntry.isLDNameDynamicallyAllocated = false; + + if (sclFCDA.Prefix != null) + c_DatasetEntry.variableName += sclFCDA.Prefix; + + c_DatasetEntry.variableName += sclFCDA.LnClass + sclFCDA.LnInst; + + c_DatasetEntry.variableName += "$" + sclFCDA.Fc.ToString(); + + c_DatasetEntry.variableName += "$" + toMmsString(sclFCDA.DoName); + + if (sclFCDA.DaName != null) + c_DatasetEntry.variableName += "$" + toMmsString(sclFCDA.DaName); + + /* check for array index and component */ + int arrayStart = c_DatasetEntry.variableName.IndexOf('('); + string componentName = ""; + if (arrayStart != -1) + { + string variableName = c_DatasetEntry.variableName.Substring(0, arrayStart); + + int arrayEnd = c_DatasetEntry.variableName.IndexOf(')'); + + string arrayIndexStr = c_DatasetEntry.variableName.Substring(arrayStart + 1, arrayEnd); + int arrayIndex = int.Parse(arrayIndexStr); + + string componentNamePart = c_DatasetEntry.variableName.Substring(arrayEnd + 1); + + if ((componentNamePart != null) && (componentNamePart.Length > 0)) + { + if (componentNamePart[0] == '$') + { + componentNamePart = componentNamePart.Substring(1); + } + + if ((componentNamePart != null) && (componentNamePart.Length > 0)) + componentName = componentNamePart; + } + } + + if (componentName != "") + c_DatasetEntry.componentName = componentName; + + c_DataSetStructure.externDataSetEntries.Add(c_DatasetEntry); + + fcdaCount++; + } + + datasetCOunt++; + + c_DataSetStructures.Add(c_DataSetStructure); + } + + if (c_DataSetStructures.Count > 0) + c_IEDModelStructure.dataSets = c_DataSetStructures.First().externDataSetName; + + c_LogicalDeviceStructure.c_LogicalNodeStructures.Add(c_LogicalNodeStructure); + } + + c_LogicalDeviceStructures.Add(c_LogicalDeviceStructure); + } + } + + private string getIpAddressByIedName(string iedName, string apName) + { + if (sclParser.Communication != null) + { + SclSubNetwork sclSubNetwork = sclParser.Communication.GetSubNetwork(apName, iedName); + + if (sclSubNetwork != null) + { + SclConnectedAP ap = sclSubNetwork.GetConnectedAPs().Find(x => x.IedName == iedName && x.ApName == apName); + + if (ap != null) + { + SclAddress sclAddress = ap.Address; + + if (sclAddress != null) + { + SclP ip = sclAddress.SclPs.Find(x => x.Type == "IP"); + if (ip != null) + return ip.Text; + } + } + } + } + + return null; + } + + private void printDataObjectForwardDeclarations(C_DO_DA_Structure c_DataObjectStructure, StreamWriter hOut) + { + if (c_DataObjectStructure is C_DataObjectStructure dataObject1) + hOut.WriteLine(dataObject1.ExternNameToString()); + else + hOut.WriteLine((c_DataObjectStructure as C_DataAttributeStructure).ExternNameToString()); + } + + private void printHeaderFileHeader(string filename, string outputFileName, string hDefineName, StreamWriter hOut) + { + hOut.WriteLine("/*"); + hOut.WriteLine(" * " + outputFileName + ".h"); + hOut.WriteLine(" *"); + hOut.WriteLine(" * automatically generated from " + filename); + hOut.WriteLine(" */\n"); + hOut.WriteLine("#ifndef " + hDefineName); + hOut.WriteLine("#define " + hDefineName + "\n"); + hOut.WriteLine("#include "); + hOut.WriteLine("#include \"iec61850_model.h\""); + hOut.WriteLine(); + } + + private void printHeaderFileFooter(StreamWriter hOut, string hDefineName) + { + hOut.WriteLine(); + hOut.WriteLine("#endif /* " + hDefineName + " */\n"); + } + + private void printCFileHeader(string filename, string outputFileName, StreamWriter cOut) + { + + string include = outputFileName + ".h\""; + if (include.LastIndexOf('/') >= 0) + { + include = include.Substring(include.LastIndexOf('/') + 1); + } + cOut.WriteLine("/*"); + cOut.WriteLine(" * " + outputFileName + ".c"); + cOut.WriteLine(" *"); + cOut.WriteLine(" * automatically generated from " + filename); + cOut.WriteLine(" */"); + cOut.WriteLine("#include \"" + include); + cOut.WriteLine(); + } + } +} diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/cid_example_deadband.cid b/tools/model_generator_dotnet/Tools/ICDFiles/cid_example_deadband.cid new file mode 100644 index 00000000..8f06eeb4 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/cid_example_deadband.cid @@ -0,0 +1,442 @@ + + +
+ + + +
+ + + +
+

1,1,1,999,1

+

12

+

00000001

+

0001

+

0001

+

0.0.0.0

+

255.255.255.0

+

0.0.0.0

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + + + + + + + + on + + + + + 10000 + + + 10 + + + 1000 + + + 10 + + + + + 1000 + + + 10 + + + 1000 + + + 10 + + + + + 10000 + + + 1000 + + + + + -5 + + + + + 5 + + + + + + + 1000 + + + 1000 + + + + + -100 + + + + + 100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + e1 + e2 + e3 + e4 + e5 + + + ExternalAreaClock + LocalAreaClock + GlobalAreaClock + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + operate-once + operate-many + + + none + m + kg + s + A + K + mol + cd + deg + rad + sr + Gy + q + °C + Sv + F + C + S + H + V + ohm + J + N + Hz + lx + Lm + Wb + T + W + Pa + + + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + W/m K + J/K + ppm + 1/s + rad/s + VA + Watts + VAr + theta + cos(theta) + Vs + + As + + A²t + VAh + Wh + VArh + V/Hz + + + Yocto + Zepto + Atto + Femto + Pico + Nano + Micro + Milli + Centi + Deci + zeroNoValue + Deca + Hecto + Kilo + Mega + Giga + Tera + Petra + Exa + Zetta + Yotta + + + normal + high + low + high-high + low-low + + + pulse + persistent + + + Ok + Warning + Alarm + + + on + blocked + test + test/blocked + off + + + on + blocked + test + test/blocked + off + + +
\ No newline at end of file diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/complexModel.icd b/tools/model_generator_dotnet/Tools/ICDFiles/complexModel.icd new file mode 100644 index 00000000..02d609a6 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/complexModel.icd @@ -0,0 +1,340 @@ + + +
+ + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + + + + + + + + + status-only + + + + + + + + + status-only + + + + + + + + status-only + + + + + + + status-only + + + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + + + rad + sr + m + Gy + q + °C + Sv + F + C + S + H + V + kg + ohm + J + N + Hz + Ix + Lm + Wb + T + W + Pa + s + m² + m³ + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + A + W/m K + J/K + ppm + 1/s + rad/s + K + VA + Watts + VAr + theta + cos(theta) + Vs + V² + As + A² + mol + A²t + VAh + Wh + VArh + V/Hz + cd + deg + + + Yocto + Zepto + Atto + Femto + Pico + Nano + Micro + Milli + Centi + Deci + zeroNoValue + Deca + Hecto + Kilo + Mega + Giga + Tera + Petra + Exa + Zetta + Yotta + + + normal + high + low + high-high + low-low + + + diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/genericIO.icd b/tools/model_generator_dotnet/Tools/ICDFiles/genericIO.icd new file mode 100644 index 00000000..87a59baa --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/genericIO.icd @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + status-only + + + + + status-only + + + + + status-only + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/inverter3ph.icd b/tools/model_generator_dotnet/Tools/ICDFiles/inverter3ph.icd new file mode 100644 index 00000000..bad02dd9 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/inverter3ph.icd @@ -0,0 +1,181 @@ + + +
+ + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + 3 + + + + + + + status-only + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/inverter_with_report.icd b/tools/model_generator_dotnet/Tools/ICDFiles/inverter_with_report.icd new file mode 100644 index 00000000..97f2f574 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/inverter_with_report.icd @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + MegaSolar + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + + + rad + sr + m + Gy + q + °C + Sv + F + C + S + H + V + kg + ohm + J + N + Hz + Ix + Lm + Wb + T + W + Pa + s + m² + m³ + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + A + W/m K + J/K + ppm + 1/s + rad/s + K + VA + Watts + VAr + theta + cos(theta) + Vs + V² + As + A² + mol + A²t + VAh + Wh + VArh + V/Hz + cd + deg + + + Yocto + Zepto + Atto + Femto + Pico + Nano + Micro + Milli + Centi + Deci + zeroNoValue + Deca + Hecto + Kilo + Mega + Giga + Tera + Petra + Exa + Zetta + Yotta + + + normal + high + low + high-high + low-low + + + diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/sampleModel.icd b/tools/model_generator_dotnet/Tools/ICDFiles/sampleModel.icd new file mode 100644 index 00000000..a2279f83 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/sampleModel.icd @@ -0,0 +1,171 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + + + status-only + + + + + + + status-only + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/sampleModel_errors.icd b/tools/model_generator_dotnet/Tools/ICDFiles/sampleModel_errors.icd new file mode 100644 index 00000000..a96e7f7a --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/sampleModel_errors.icd @@ -0,0 +1,171 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + + + status-only + + + + + + + status-only + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/sampleModel_with_dataset.icd b/tools/model_generator_dotnet/Tools/ICDFiles/sampleModel_with_dataset.icd new file mode 100644 index 00000000..82df99ec --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/sampleModel_with_dataset.icd @@ -0,0 +1,208 @@ + + +
+ + + + +
+

1,1,9999,1

+

12

+

00000001

+

0001

+

0001

+

127.0.0.1

+
+ +
+

111

+

4

+

01-0c-cd-01-00-01

+

1000

+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + + + status-only + + + + + + + status-only + + + + + + + status-only + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_control_tests.cid b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_control_tests.cid new file mode 100644 index 00000000..53fab583 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_control_tests.cid @@ -0,0 +1,332 @@ + + +
+
+ + + +
+

0.0.0.0

+

255.255.255.0

+

10.0.0.1

+

0001

+

00000001

+

0001

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + direct-with-normal-security + + + + + sbo-with-normal-security + + + 2000 + + + + + direct-with-enhanced-security + + + + + sbo-with-enhanced-security + + + + + direct-with-normal-security + + + + + sbo-with-normal-security + + + + + direct-with-enhanced-security + + + + + sbo-with-enhanced-security + + + + + direct-with-enhanced-security + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + operate-once + operate-many + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + +
diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control.cid b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control.cid new file mode 100644 index 00000000..7ab586fe --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control.cid @@ -0,0 +1,279 @@ + + +
+
+ + + +
+

10.0.0.2

+

255.255.255.0

+

10.0.0.1

+

0001

+

00000001

+

0001

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + MZ Automation + + + 0.7.3 + + + libiec61850 server example + + + + + + + + status-only + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + +
diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control.icd b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control.icd new file mode 100644 index 00000000..b0ac1475 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control.icd @@ -0,0 +1,307 @@ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + + + status-only + + + + + on + + + + + ok + + + + + + MZ Automation + + + 1.3.0 + + + libiec61850 server example + + + + + + + ok + + + + + + + on + + + status-only + + + + + on + + + + + ok + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + blocked + test + test/blocked + off + + + + ok + warning + alarm + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + +
diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control_goose.cid b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control_goose.cid new file mode 100644 index 00000000..e25303f7 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control_goose.cid @@ -0,0 +1,275 @@ + + +
+
+ + + +
+

10.0.0.2

+

255.255.255.0

+

10.0.0.1

+

0001

+

00000001

+

0001

+
+ +
+

1

+

4

+

01-0c-cd-01-00-01

+

1000

+
+ 1000 + 3000 +
+ +
+

1

+

4

+

01-0c-cd-01-00-01

+

1000

+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + +
diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control_goose.scd b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control_goose.scd new file mode 100644 index 00000000..90e58190 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_direct_control_goose.scd @@ -0,0 +1,252 @@ + + +
+
+ + + Station bus + 10 + +
+

10.0.0.2

+

255.255.255.0

+

10.0.0.1

+

0001

+

00000001

+

0001

+
+ +
+

111

+

4

+

01-0c-cd-01-00-01

+

1000

+
+
+ +
+

111

+

4

+

01-0c-cd-01-00-02

+

1000

+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + +
diff --git a/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_ltrk_tests.icd b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_ltrk_tests.icd new file mode 100644 index 00000000..127c3589 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/ICDFiles/simpleIO_ltrk_tests.icd @@ -0,0 +1,655 @@ + + +
+
+ + + Station bus + 10 + +
+

0.0.0.0

+

255.255.255.0

+

192.168.2.1

+

1,3,9999,33

+

33

+

00000001

+

0001

+

0001

+

102

+
+ +
+

1

+

4

+

01-0c-cd-01-00-01

+

1000

+
+ 1000 + 3000 +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + + + status-only + + + + + on + + + + + ok + + + + + MZ Automation + + + 1.3.0 + + + libiec61850 server example + + + + + + + ok + + + + + + + on + + + status-only + + + + + on + + + + + ok + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + direct-with-normal-security + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Unknown + Not-supported + Blocked-by-switching-hierarchy + Select-failed + Invalid-position + Position-reached + Parameter-change-in-execution + Step-limit + Blocked-by-Mode + Blocked-by-process + Blocked-by-interlocking + Blocked-by-synchrocheck + Command-already-in-execution + Blocked-by-health + 1-of-n-control + Abortion-by-cancel + Time-limit-over + Abortion-by-trip + Object-not-selected + Object-already-selected + No-access-authority + Ended-with-overshoot + Abortion-due-to-deviation + Abortion-by-communication-loss + Blocked-by-command + None + Inconsistent-parameters + Locked-by-other-client + + + on + blocked + test + test/blocked + off + + + ok + warning + alarm + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + no-error + instance-not-available + instance-in-use + access-violation + access-not-allowed-in-current-state + parameter-value-inappropriate + parameter-value-inconsistent + class-not-supported + instance-locked-by-other-client + control-must-be-selected + type-conflict + failed-due-to-communications-constraint + failed-due-to-server-constraint + + + Unknown + Associate + Abort + Release + GetServerDirectory + GetLogicalDeviceDirectory + GetAllDataValues + GetDataValues + SetDataValues + GetDataDirectory + GetDataDefinition + GetDataSetValues + SetDataSetValues + CreateDataSet + DeleteDataSet + GetDataSetDirectory + SelectActiveSG + SelectEditSG + SetEditSGValue + ConfirmEditSGValues + GetEditSGValue + GetSGCBValues + Report + GetBRCBValues + SetBRCBValues + GetURCBValues + SetURCBValues + GetLCBValues + SetLCBValues + QueryLogByTime + QueryLogAfter + GetLogStatus + SendGOOSEMessage + GetGoCBValues + SetGoCBValues + GetGoReference + GetGOOSEElementNumber + SendMSVMessage + GetMSVCBValues + SetMSVCBValues + SendUSVMessage + GetUSVCBValues + SetUSVCBValues + Select + SelectWithValue + Cancel + Operate + CommandTermination + TimeActivatedOperate + GetFile + SetFile + DeleteFile + GetFileAttributValues + TimeSynchronisation + InternalChange + + + unknown + forward + backward + both + + +
diff --git a/tools/model_generator_dotnet/Tools/Program.cs b/tools/model_generator_dotnet/Tools/Program.cs new file mode 100644 index 00000000..a0e417b8 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/Program.cs @@ -0,0 +1,132 @@ +/* + * Copyright 2013-2025 Michael Zillgith, MZ Automation GmbH + * + * This file is part of MZ Automation IEC 61850 SDK + * + * All rights reserved. + */ + +using StaticModelGenerator; + +namespace modeGenerator_example +{ + + /// + /// This example shows how to handle a large number of information objects + /// + class MainClass + { + public static void Main(string[] args) + { + Console.WriteLine("Usage: Static Model (1) \n Dynamic Model (2) \n [-ied ] [-ap ] [-out ] [-modelprefix ]"); + + if (args.Length == 0) + { + Console.WriteLine("Parse the arguments \n" + + "Usage: Static Model (1) \n Dynamic Model (2) \n [-ied ] [-ap ] [-out ] [-modelprefix ]"); + } + else + { + string accessPointName = null; + string iedName = null; + string icdFile = "ICDFiles//simpleIO_ltrk_tests.icd"; + string outputFileName = "static_model"; + string modelPrefix = "iedModel"; + bool initializeOnce = false; + icdFile = args[1]; + + + for (int i = 2; i < args.Count(); i++) + { + if (args[i] == ("-ap")) + { + accessPointName = args[i + 1]; + + Console.WriteLine("Select access point " + accessPointName); + + i++; + } + else if (args[i] == ("-ied")) + { + iedName = args[i + 1]; + + Console.WriteLine("Select IED " + iedName); + + i++; + + } + else if (args[i] == ("-out")) + { + outputFileName = args[i + 1]; + + Console.WriteLine("Select Output File " + outputFileName); + + i++; + + } + else if (args[i] == ("-modelprefix")) + { + modelPrefix = args[i + 1]; + + Console.WriteLine("Select Model Prefix " + modelPrefix); + + i++; + + } + else if (args[i] == ("-initializeonce")) + { + initializeOnce = true; + + Console.WriteLine("Select Initialize Once"); + + } + else + { + Console.WriteLine("Unknown option: \"" + args[i] + "\""); + } + } + + if (args[0] == "1") + { + Console.WriteLine("Generate Static Model"); + + FileStream cOutStream = new FileStream(outputFileName + ".c", FileMode.Create, FileAccess.Write); + FileStream hOutStream = new FileStream(outputFileName + ".h", FileMode.Create, FileAccess.Write); + + try + { + new StaticModelGenerator.StaticModelGenerator(icdFile, icdFile, cOutStream, hOutStream, outputFileName, iedName, accessPointName, modelPrefix, initializeOnce); + } + catch (Exception e) + { + Console.WriteLine("ERROR: " + e.ToString()); + } + + } + else if (args[0] == "2") + { + Console.WriteLine("Generate Dynamic Model"); + + try + { + FileStream stream = new FileStream(outputFileName + ".cfg", FileMode.Create, FileAccess.Write); + new DynamicModel.DynamicModel(icdFile, stream, iedName, accessPointName); + } + catch (Exception e) + { + Console.WriteLine("ERROR: " + e.ToString()); + } + } + else + { + Console.WriteLine("Wrong option, parse 1 or 2 \n" + + "Usage: Static Model (1) \n Dynamic Model (2) \n [-ied ] [-ap ] [-out ] [-modelprefix ]"); + } + + + + } + + } + } +} \ No newline at end of file diff --git a/tools/model_generator_dotnet/Tools/Tools.csproj b/tools/model_generator_dotnet/Tools/Tools.csproj new file mode 100644 index 00000000..09e31c57 --- /dev/null +++ b/tools/model_generator_dotnet/Tools/Tools.csproj @@ -0,0 +1,77 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + + diff --git a/tools/model_generator_dotnet/Tools_ModelGenerator.sln b/tools/model_generator_dotnet/Tools_ModelGenerator.sln new file mode 100644 index 00000000..c0fa1c13 --- /dev/null +++ b/tools/model_generator_dotnet/Tools_ModelGenerator.sln @@ -0,0 +1,43 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35327.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynamicModelGenerator", "DynamicModelGenerator\DynamicModelGenerator.csproj", "{3269555F-ECB9-4304-936A-8FC6153AB5BD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SCLParser", "SCLParser\SCLParser.csproj", "{AF771AA2-C3EB-4F0A-884A-6B79C9977BE2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StaticModelGenerator", "StaticModelGenerator\StaticModelGenerator.csproj", "{992389DE-80E6-422B-8536-6D39E864118B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tools", "Tools\Tools.csproj", "{8103E20D-0EE9-443B-B7B4-6641D4EF85C7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3269555F-ECB9-4304-936A-8FC6153AB5BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3269555F-ECB9-4304-936A-8FC6153AB5BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3269555F-ECB9-4304-936A-8FC6153AB5BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3269555F-ECB9-4304-936A-8FC6153AB5BD}.Release|Any CPU.Build.0 = Release|Any CPU + {AF771AA2-C3EB-4F0A-884A-6B79C9977BE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF771AA2-C3EB-4F0A-884A-6B79C9977BE2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF771AA2-C3EB-4F0A-884A-6B79C9977BE2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF771AA2-C3EB-4F0A-884A-6B79C9977BE2}.Release|Any CPU.Build.0 = Release|Any CPU + {992389DE-80E6-422B-8536-6D39E864118B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {992389DE-80E6-422B-8536-6D39E864118B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {992389DE-80E6-422B-8536-6D39E864118B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {992389DE-80E6-422B-8536-6D39E864118B}.Release|Any CPU.Build.0 = Release|Any CPU + {8103E20D-0EE9-443B-B7B4-6641D4EF85C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8103E20D-0EE9-443B-B7B4-6641D4EF85C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8103E20D-0EE9-443B-B7B4-6641D4EF85C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8103E20D-0EE9-443B-B7B4-6641D4EF85C7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4D5970CE-F389-4BCE-934E-F1E597AFEE22} + EndGlobalSection +EndGlobal