diff --git a/examples/iec61850_9_2_LE_example/CMakeLists.txt b/examples/iec61850_9_2_LE_example/CMakeLists.txt new file mode 100644 index 00000000..994caae3 --- /dev/null +++ b/examples/iec61850_9_2_LE_example/CMakeLists.txt @@ -0,0 +1,21 @@ +include_directories( + . +) + +set(server_example2_SRCS + server_example2.c + static_model.c +) + +IF(WIN32) +set_source_files_properties(${server_example2_SRCS} + PROPERTIES LANGUAGE CXX) +ENDIF(WIN32) + +add_executable(server_example2 + ${server_example2_SRCS} +) + +target_link_libraries(server_example2 + iec61850 +) diff --git a/examples/iec61850_9_2_LE_example/Makefile b/examples/iec61850_9_2_LE_example/Makefile new file mode 100644 index 00000000..3781758b --- /dev/null +++ b/examples/iec61850_9_2_LE_example/Makefile @@ -0,0 +1,24 @@ +LIBIEC_HOME=../.. + +PROJECT_BINARY_NAME = server_example2 +PROJECT_SOURCES = server_example2.c +PROJECT_SOURCES += static_model.c + +PROJECT_ICD_FILE = complexModel.icd + +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) $(LDFLAGS) $(LDLIBS) + +clean: + rm -f $(PROJECT_BINARY_NAME) + diff --git a/examples/iec61850_9_2_LE_example/server_example2.c b/examples/iec61850_9_2_LE_example/server_example2.c new file mode 100644 index 00000000..662cf501 --- /dev/null +++ b/examples/iec61850_9_2_LE_example/server_example2.c @@ -0,0 +1,86 @@ +/* + * server_example2.c + * + * Copyright 2013 Michael Zillgith + * + * This file is part of libIEC61850. + * + * libIEC61850 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libIEC61850 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with libIEC61850. If not, see . + * + * See COPYING file for the complete license text. + */ + +#include "iec61850_server.h" +#include "hal_thread.h" +#include +#include +#include + + +/* Include the generated header with the model access handles */ +#include "static_model.h" + +/* import IEC 61850 device model created from SCL-File */ +extern IedModel iedModel; + +static int running = 0; + +void sigint_handler(int signalId) +{ + running = 0; +} + +int +main(int argc, char** argv) +{ + IedServer iedServer = IedServer_create(&iedModel); + + // TODO get stored values from persistent storage + + // TODO set initial measurement and status values from process + + /* MMS server will be instructed to start listening to client connections. */ + IedServer_start(iedServer, 102); + + if (!IedServer_isRunning(iedServer)) { + printf("Starting server failed! Exit.\n"); + IedServer_destroy(iedServer); + exit(-1); + } + + running = 1; + + signal(SIGINT, sigint_handler); + + float power = 500.f; + + while (running) { + + uint64_t timeval = Hal_getTimeInMs(); + + IedServer_unlockDataModel(iedServer); + + power += 0.1f; + + Thread_sleep(500); + } + + /* 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/iec61850_9_2_LE_example/static_model.c b/examples/iec61850_9_2_LE_example/static_model.c new file mode 100644 index 00000000..ecc29bfb --- /dev/null +++ b/examples/iec61850_9_2_LE_example/static_model.c @@ -0,0 +1,1009 @@ +/* + * static_model.c + * + * automatically generated from sv.icd + */ +#include "static_model.h" + +static void initializeValues(); + +extern DataSet iedModelds_MUnn_LLN0_PhsMeas1; + + +extern DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda0; +extern DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda1; +extern DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda2; +extern DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda3; +extern DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda4; +extern DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda5; +extern DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda6; +extern DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda7; + +DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda0 = { + "1", + false, + "TCTR$MX$Amp", + -1, + NULL, + NULL, + &iedModelds_MUnn_LLN0_PhsMeas1_fcda1 +}; + +DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda1 = { + "2", + false, + "TCTR$MX$Amp", + -1, + NULL, + NULL, + &iedModelds_MUnn_LLN0_PhsMeas1_fcda2 +}; + +DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda2 = { + "3", + false, + "TCTR$MX$Amp", + -1, + NULL, + NULL, + &iedModelds_MUnn_LLN0_PhsMeas1_fcda3 +}; + +DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda3 = { + "4", + false, + "TCTR$MX$Amp", + -1, + NULL, + NULL, + &iedModelds_MUnn_LLN0_PhsMeas1_fcda4 +}; + +DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda4 = { + "1", + false, + "TVTR$MX$Vol", + -1, + NULL, + NULL, + &iedModelds_MUnn_LLN0_PhsMeas1_fcda5 +}; + +DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda5 = { + "2", + false, + "TVTR$MX$Vol", + -1, + NULL, + NULL, + &iedModelds_MUnn_LLN0_PhsMeas1_fcda6 +}; + +DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda6 = { + "3", + false, + "TVTR$MX$Vol", + -1, + NULL, + NULL, + &iedModelds_MUnn_LLN0_PhsMeas1_fcda7 +}; + +DataSetEntry iedModelds_MUnn_LLN0_PhsMeas1_fcda7 = { + "4", + false, + "TVTR$MX$Vol", + -1, + NULL, + NULL, + NULL +}; + +DataSet iedModelds_MUnn_LLN0_PhsMeas1 = { + "MUnn", + "LLN0$PhsMeas1", + 8, + &iedModelds_MUnn_LLN0_PhsMeas1_fcda0, + NULL +}; + +LogicalDevice iedModel_MUnn = { + LogicalDeviceModelType, + "MUnn", + (ModelNode*) &iedModel, + NULL, + (ModelNode*) &iedModel_MUnn_LLN0 +}; + +LogicalNode iedModel_MUnn_LLN0 = { + LogicalNodeModelType, + "LLN0", + (ModelNode*) &iedModel_MUnn, + (ModelNode*) &iedModel_MUnn_TCTR1, + (ModelNode*) &iedModel_MUnn_LLN0_Mod, +}; + +DataObject iedModel_MUnn_LLN0_Mod = { + DataObjectModelType, + "Mod", + (ModelNode*) &iedModel_MUnn_LLN0, + NULL, + (ModelNode*) &iedModel_MUnn_LLN0_Mod_ctlVal, + 0 +}; + +DataAttribute iedModel_MUnn_LLN0_Mod_ctlVal = { + DataAttributeModelType, + "ctlVal", + (ModelNode*) &iedModel_MUnn_LLN0_Mod, + (ModelNode*) &iedModel_MUnn_LLN0_Mod_stVal, + NULL, + 0, + IEC61850_FC_CO, + IEC61850_INT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_LLN0_Mod_stVal = { + DataAttributeModelType, + "stVal", + (ModelNode*) &iedModel_MUnn_LLN0_Mod, + (ModelNode*) &iedModel_MUnn_LLN0_Mod_q, + NULL, + 0, + IEC61850_FC_ST, + IEC61850_INT32, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_MUnn_LLN0_Mod_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_MUnn_LLN0_Mod, + (ModelNode*) &iedModel_MUnn_LLN0_Mod_t, + NULL, + 0, + IEC61850_FC_ST, + IEC61850_QUALITY, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +DataAttribute iedModel_MUnn_LLN0_Mod_t = { + DataAttributeModelType, + "t", + (ModelNode*) &iedModel_MUnn_LLN0_Mod, + NULL, + NULL, + 0, + IEC61850_FC_ST, + IEC61850_TIMESTAMP, + 0 + TRG_OPT_DATA_CHANGED, + NULL, + 0}; + +LogicalNode iedModel_MUnn_TCTR1 = { + LogicalNodeModelType, + "TCTR1", + (ModelNode*) &iedModel_MUnn, + (ModelNode*) &iedModel_MUnn_TCTR2, + (ModelNode*) &iedModel_MUnn_TCTR1_Amp, +}; + +DataObject iedModel_MUnn_TCTR1_Amp = { + DataObjectModelType, + "Amp", + (ModelNode*) &iedModel_MUnn_TCTR1, + NULL, + (ModelNode*) &iedModel_MUnn_TCTR1_Amp_instMag, + 0 +}; + +DataAttribute iedModel_MUnn_TCTR1_Amp_instMag = { + DataAttributeModelType, + "instMag", + (ModelNode*) &iedModel_MUnn_TCTR1_Amp, + (ModelNode*) &iedModel_MUnn_TCTR1_Amp_q, + (ModelNode*) &iedModel_MUnn_TCTR1_Amp_instMag_i, + 0, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR1_Amp_instMag_i = { + DataAttributeModelType, + "i", + (ModelNode*) &iedModel_MUnn_TCTR1_Amp_instMag, + NULL, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_INT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR1_Amp_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_MUnn_TCTR1_Amp, + (ModelNode*) &iedModel_MUnn_TCTR1_Amp_sVC, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR1_Amp_sVC = { + DataAttributeModelType, + "sVC", + (ModelNode*) &iedModel_MUnn_TCTR1_Amp, + NULL, + (ModelNode*) &iedModel_MUnn_TCTR1_Amp_sVC_scaleFactor, + 0, + IEC61850_FC_CF, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR1_Amp_sVC_scaleFactor = { + DataAttributeModelType, + "scaleFactor", + (ModelNode*) &iedModel_MUnn_TCTR1_Amp_sVC, + (ModelNode*) &iedModel_MUnn_TCTR1_Amp_sVC_offset, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR1_Amp_sVC_offset = { + DataAttributeModelType, + "offset", + (ModelNode*) &iedModel_MUnn_TCTR1_Amp_sVC, + NULL, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +LogicalNode iedModel_MUnn_TCTR2 = { + LogicalNodeModelType, + "TCTR2", + (ModelNode*) &iedModel_MUnn, + (ModelNode*) &iedModel_MUnn_TCTR3, + (ModelNode*) &iedModel_MUnn_TCTR2_Amp, +}; + +DataObject iedModel_MUnn_TCTR2_Amp = { + DataObjectModelType, + "Amp", + (ModelNode*) &iedModel_MUnn_TCTR2, + NULL, + (ModelNode*) &iedModel_MUnn_TCTR2_Amp_instMag, + 0 +}; + +DataAttribute iedModel_MUnn_TCTR2_Amp_instMag = { + DataAttributeModelType, + "instMag", + (ModelNode*) &iedModel_MUnn_TCTR2_Amp, + (ModelNode*) &iedModel_MUnn_TCTR2_Amp_q, + (ModelNode*) &iedModel_MUnn_TCTR2_Amp_instMag_i, + 0, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR2_Amp_instMag_i = { + DataAttributeModelType, + "i", + (ModelNode*) &iedModel_MUnn_TCTR2_Amp_instMag, + NULL, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_INT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR2_Amp_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_MUnn_TCTR2_Amp, + (ModelNode*) &iedModel_MUnn_TCTR2_Amp_sVC, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR2_Amp_sVC = { + DataAttributeModelType, + "sVC", + (ModelNode*) &iedModel_MUnn_TCTR2_Amp, + NULL, + (ModelNode*) &iedModel_MUnn_TCTR2_Amp_sVC_scaleFactor, + 0, + IEC61850_FC_CF, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR2_Amp_sVC_scaleFactor = { + DataAttributeModelType, + "scaleFactor", + (ModelNode*) &iedModel_MUnn_TCTR2_Amp_sVC, + (ModelNode*) &iedModel_MUnn_TCTR2_Amp_sVC_offset, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR2_Amp_sVC_offset = { + DataAttributeModelType, + "offset", + (ModelNode*) &iedModel_MUnn_TCTR2_Amp_sVC, + NULL, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +LogicalNode iedModel_MUnn_TCTR3 = { + LogicalNodeModelType, + "TCTR3", + (ModelNode*) &iedModel_MUnn, + (ModelNode*) &iedModel_MUnn_TCTR4, + (ModelNode*) &iedModel_MUnn_TCTR3_Amp, +}; + +DataObject iedModel_MUnn_TCTR3_Amp = { + DataObjectModelType, + "Amp", + (ModelNode*) &iedModel_MUnn_TCTR3, + NULL, + (ModelNode*) &iedModel_MUnn_TCTR3_Amp_instMag, + 0 +}; + +DataAttribute iedModel_MUnn_TCTR3_Amp_instMag = { + DataAttributeModelType, + "instMag", + (ModelNode*) &iedModel_MUnn_TCTR3_Amp, + (ModelNode*) &iedModel_MUnn_TCTR3_Amp_q, + (ModelNode*) &iedModel_MUnn_TCTR3_Amp_instMag_i, + 0, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR3_Amp_instMag_i = { + DataAttributeModelType, + "i", + (ModelNode*) &iedModel_MUnn_TCTR3_Amp_instMag, + NULL, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_INT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR3_Amp_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_MUnn_TCTR3_Amp, + (ModelNode*) &iedModel_MUnn_TCTR3_Amp_sVC, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR3_Amp_sVC = { + DataAttributeModelType, + "sVC", + (ModelNode*) &iedModel_MUnn_TCTR3_Amp, + NULL, + (ModelNode*) &iedModel_MUnn_TCTR3_Amp_sVC_scaleFactor, + 0, + IEC61850_FC_CF, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR3_Amp_sVC_scaleFactor = { + DataAttributeModelType, + "scaleFactor", + (ModelNode*) &iedModel_MUnn_TCTR3_Amp_sVC, + (ModelNode*) &iedModel_MUnn_TCTR3_Amp_sVC_offset, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR3_Amp_sVC_offset = { + DataAttributeModelType, + "offset", + (ModelNode*) &iedModel_MUnn_TCTR3_Amp_sVC, + NULL, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +LogicalNode iedModel_MUnn_TCTR4 = { + LogicalNodeModelType, + "TCTR4", + (ModelNode*) &iedModel_MUnn, + (ModelNode*) &iedModel_MUnn_TVTR1, + (ModelNode*) &iedModel_MUnn_TCTR4_Amp, +}; + +DataObject iedModel_MUnn_TCTR4_Amp = { + DataObjectModelType, + "Amp", + (ModelNode*) &iedModel_MUnn_TCTR4, + NULL, + (ModelNode*) &iedModel_MUnn_TCTR4_Amp_instMag, + 0 +}; + +DataAttribute iedModel_MUnn_TCTR4_Amp_instMag = { + DataAttributeModelType, + "instMag", + (ModelNode*) &iedModel_MUnn_TCTR4_Amp, + (ModelNode*) &iedModel_MUnn_TCTR4_Amp_q, + (ModelNode*) &iedModel_MUnn_TCTR4_Amp_instMag_i, + 0, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR4_Amp_instMag_i = { + DataAttributeModelType, + "i", + (ModelNode*) &iedModel_MUnn_TCTR4_Amp_instMag, + NULL, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_INT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR4_Amp_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_MUnn_TCTR4_Amp, + (ModelNode*) &iedModel_MUnn_TCTR4_Amp_sVC, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR4_Amp_sVC = { + DataAttributeModelType, + "sVC", + (ModelNode*) &iedModel_MUnn_TCTR4_Amp, + NULL, + (ModelNode*) &iedModel_MUnn_TCTR4_Amp_sVC_scaleFactor, + 0, + IEC61850_FC_CF, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR4_Amp_sVC_scaleFactor = { + DataAttributeModelType, + "scaleFactor", + (ModelNode*) &iedModel_MUnn_TCTR4_Amp_sVC, + (ModelNode*) &iedModel_MUnn_TCTR4_Amp_sVC_offset, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TCTR4_Amp_sVC_offset = { + DataAttributeModelType, + "offset", + (ModelNode*) &iedModel_MUnn_TCTR4_Amp_sVC, + NULL, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +LogicalNode iedModel_MUnn_TVTR1 = { + LogicalNodeModelType, + "TVTR1", + (ModelNode*) &iedModel_MUnn, + (ModelNode*) &iedModel_MUnn_TVTR2, + (ModelNode*) &iedModel_MUnn_TVTR1_Vol, +}; + +DataObject iedModel_MUnn_TVTR1_Vol = { + DataObjectModelType, + "Vol", + (ModelNode*) &iedModel_MUnn_TVTR1, + NULL, + (ModelNode*) &iedModel_MUnn_TVTR1_Vol_instMag, + 0 +}; + +DataAttribute iedModel_MUnn_TVTR1_Vol_instMag = { + DataAttributeModelType, + "instMag", + (ModelNode*) &iedModel_MUnn_TVTR1_Vol, + (ModelNode*) &iedModel_MUnn_TVTR1_Vol_q, + (ModelNode*) &iedModel_MUnn_TVTR1_Vol_instMag_i, + 0, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR1_Vol_instMag_i = { + DataAttributeModelType, + "i", + (ModelNode*) &iedModel_MUnn_TVTR1_Vol_instMag, + NULL, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_INT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR1_Vol_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_MUnn_TVTR1_Vol, + (ModelNode*) &iedModel_MUnn_TVTR1_Vol_sVC, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR1_Vol_sVC = { + DataAttributeModelType, + "sVC", + (ModelNode*) &iedModel_MUnn_TVTR1_Vol, + NULL, + (ModelNode*) &iedModel_MUnn_TVTR1_Vol_sVC_scaleFactor, + 0, + IEC61850_FC_CF, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR1_Vol_sVC_scaleFactor = { + DataAttributeModelType, + "scaleFactor", + (ModelNode*) &iedModel_MUnn_TVTR1_Vol_sVC, + (ModelNode*) &iedModel_MUnn_TVTR1_Vol_sVC_offset, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR1_Vol_sVC_offset = { + DataAttributeModelType, + "offset", + (ModelNode*) &iedModel_MUnn_TVTR1_Vol_sVC, + NULL, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +LogicalNode iedModel_MUnn_TVTR2 = { + LogicalNodeModelType, + "TVTR2", + (ModelNode*) &iedModel_MUnn, + (ModelNode*) &iedModel_MUnn_TVTR3, + (ModelNode*) &iedModel_MUnn_TVTR2_Vol, +}; + +DataObject iedModel_MUnn_TVTR2_Vol = { + DataObjectModelType, + "Vol", + (ModelNode*) &iedModel_MUnn_TVTR2, + NULL, + (ModelNode*) &iedModel_MUnn_TVTR2_Vol_instMag, + 0 +}; + +DataAttribute iedModel_MUnn_TVTR2_Vol_instMag = { + DataAttributeModelType, + "instMag", + (ModelNode*) &iedModel_MUnn_TVTR2_Vol, + (ModelNode*) &iedModel_MUnn_TVTR2_Vol_q, + (ModelNode*) &iedModel_MUnn_TVTR2_Vol_instMag_i, + 0, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR2_Vol_instMag_i = { + DataAttributeModelType, + "i", + (ModelNode*) &iedModel_MUnn_TVTR2_Vol_instMag, + NULL, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_INT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR2_Vol_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_MUnn_TVTR2_Vol, + (ModelNode*) &iedModel_MUnn_TVTR2_Vol_sVC, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR2_Vol_sVC = { + DataAttributeModelType, + "sVC", + (ModelNode*) &iedModel_MUnn_TVTR2_Vol, + NULL, + (ModelNode*) &iedModel_MUnn_TVTR2_Vol_sVC_scaleFactor, + 0, + IEC61850_FC_CF, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR2_Vol_sVC_scaleFactor = { + DataAttributeModelType, + "scaleFactor", + (ModelNode*) &iedModel_MUnn_TVTR2_Vol_sVC, + (ModelNode*) &iedModel_MUnn_TVTR2_Vol_sVC_offset, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR2_Vol_sVC_offset = { + DataAttributeModelType, + "offset", + (ModelNode*) &iedModel_MUnn_TVTR2_Vol_sVC, + NULL, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +LogicalNode iedModel_MUnn_TVTR3 = { + LogicalNodeModelType, + "TVTR3", + (ModelNode*) &iedModel_MUnn, + (ModelNode*) &iedModel_MUnn_TVTR4, + (ModelNode*) &iedModel_MUnn_TVTR3_Vol, +}; + +DataObject iedModel_MUnn_TVTR3_Vol = { + DataObjectModelType, + "Vol", + (ModelNode*) &iedModel_MUnn_TVTR3, + NULL, + (ModelNode*) &iedModel_MUnn_TVTR3_Vol_instMag, + 0 +}; + +DataAttribute iedModel_MUnn_TVTR3_Vol_instMag = { + DataAttributeModelType, + "instMag", + (ModelNode*) &iedModel_MUnn_TVTR3_Vol, + (ModelNode*) &iedModel_MUnn_TVTR3_Vol_q, + (ModelNode*) &iedModel_MUnn_TVTR3_Vol_instMag_i, + 0, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR3_Vol_instMag_i = { + DataAttributeModelType, + "i", + (ModelNode*) &iedModel_MUnn_TVTR3_Vol_instMag, + NULL, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_INT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR3_Vol_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_MUnn_TVTR3_Vol, + (ModelNode*) &iedModel_MUnn_TVTR3_Vol_sVC, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR3_Vol_sVC = { + DataAttributeModelType, + "sVC", + (ModelNode*) &iedModel_MUnn_TVTR3_Vol, + NULL, + (ModelNode*) &iedModel_MUnn_TVTR3_Vol_sVC_scaleFactor, + 0, + IEC61850_FC_CF, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR3_Vol_sVC_scaleFactor = { + DataAttributeModelType, + "scaleFactor", + (ModelNode*) &iedModel_MUnn_TVTR3_Vol_sVC, + (ModelNode*) &iedModel_MUnn_TVTR3_Vol_sVC_offset, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR3_Vol_sVC_offset = { + DataAttributeModelType, + "offset", + (ModelNode*) &iedModel_MUnn_TVTR3_Vol_sVC, + NULL, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +LogicalNode iedModel_MUnn_TVTR4 = { + LogicalNodeModelType, + "TVTR4", + (ModelNode*) &iedModel_MUnn, + NULL, + (ModelNode*) &iedModel_MUnn_TVTR4_Vol, +}; + +DataObject iedModel_MUnn_TVTR4_Vol = { + DataObjectModelType, + "Vol", + (ModelNode*) &iedModel_MUnn_TVTR4, + NULL, + (ModelNode*) &iedModel_MUnn_TVTR4_Vol_instMag, + 0 +}; + +DataAttribute iedModel_MUnn_TVTR4_Vol_instMag = { + DataAttributeModelType, + "instMag", + (ModelNode*) &iedModel_MUnn_TVTR4_Vol, + (ModelNode*) &iedModel_MUnn_TVTR4_Vol_q, + (ModelNode*) &iedModel_MUnn_TVTR4_Vol_instMag_i, + 0, + IEC61850_FC_MX, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR4_Vol_instMag_i = { + DataAttributeModelType, + "i", + (ModelNode*) &iedModel_MUnn_TVTR4_Vol_instMag, + NULL, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_INT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR4_Vol_q = { + DataAttributeModelType, + "q", + (ModelNode*) &iedModel_MUnn_TVTR4_Vol, + (ModelNode*) &iedModel_MUnn_TVTR4_Vol_sVC, + NULL, + 0, + IEC61850_FC_MX, + IEC61850_QUALITY, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR4_Vol_sVC = { + DataAttributeModelType, + "sVC", + (ModelNode*) &iedModel_MUnn_TVTR4_Vol, + NULL, + (ModelNode*) &iedModel_MUnn_TVTR4_Vol_sVC_scaleFactor, + 0, + IEC61850_FC_CF, + IEC61850_CONSTRUCTED, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR4_Vol_sVC_scaleFactor = { + DataAttributeModelType, + "scaleFactor", + (ModelNode*) &iedModel_MUnn_TVTR4_Vol_sVC, + (ModelNode*) &iedModel_MUnn_TVTR4_Vol_sVC_offset, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + +DataAttribute iedModel_MUnn_TVTR4_Vol_sVC_offset = { + DataAttributeModelType, + "offset", + (ModelNode*) &iedModel_MUnn_TVTR4_Vol_sVC, + NULL, + NULL, + 0, + IEC61850_FC_CF, + IEC61850_FLOAT32, + 0, + NULL, + 0}; + + + +extern SVControlBlock iedModel_MUnn_LLN0_smv0; + +static PhyComAddress iedModel_MUnn_LLN0_smv0_address = { + 4, + 1, + 4097, + {0x1, 0xc, 0xcd, 0x4, 0x0, 0x1} +}; + +SVControlBlock iedModel_MUnn_LLN0_smv0 = {&iedModel_MUnn_LLN0, "MSVCB01", "xxxxMUnn01", "PhsMeas1", 2, 0, 80, 1, &iedModel_MUnn_LLN0_smv0_address, true, 1, NULL}; + + + + +IedModel iedModel = { + "TEMPLATE", + &iedModel_MUnn, + &iedModelds_MUnn_LLN0_PhsMeas1, + NULL, + NULL, + &iedModel_MUnn_LLN0_smv0, + NULL, + initializeValues +}; + +static void +initializeValues() +{ + +iedModel_MUnn_TCTR1_Amp_sVC_scaleFactor.mmsValue = MmsValue_newFloat(0.001); + +iedModel_MUnn_TCTR1_Amp_sVC_offset.mmsValue = MmsValue_newFloat(0.0); + +iedModel_MUnn_TCTR2_Amp_sVC_scaleFactor.mmsValue = MmsValue_newFloat(0.001); + +iedModel_MUnn_TCTR2_Amp_sVC_offset.mmsValue = MmsValue_newFloat(0.0); + +iedModel_MUnn_TCTR3_Amp_sVC_scaleFactor.mmsValue = MmsValue_newFloat(0.001); + +iedModel_MUnn_TCTR3_Amp_sVC_offset.mmsValue = MmsValue_newFloat(0.0); + +iedModel_MUnn_TCTR4_Amp_sVC_scaleFactor.mmsValue = MmsValue_newFloat(0.001); + +iedModel_MUnn_TCTR4_Amp_sVC_offset.mmsValue = MmsValue_newFloat(0.0); + +iedModel_MUnn_TVTR1_Vol_sVC_scaleFactor.mmsValue = MmsValue_newFloat(0.01); + +iedModel_MUnn_TVTR1_Vol_sVC_offset.mmsValue = MmsValue_newFloat(0.0); + +iedModel_MUnn_TVTR2_Vol_sVC_scaleFactor.mmsValue = MmsValue_newFloat(0.01); + +iedModel_MUnn_TVTR2_Vol_sVC_offset.mmsValue = MmsValue_newFloat(0.0); + +iedModel_MUnn_TVTR3_Vol_sVC_scaleFactor.mmsValue = MmsValue_newFloat(0.01); + +iedModel_MUnn_TVTR3_Vol_sVC_offset.mmsValue = MmsValue_newFloat(0.0); + +iedModel_MUnn_TVTR4_Vol_sVC_scaleFactor.mmsValue = MmsValue_newFloat(0.01); + +iedModel_MUnn_TVTR4_Vol_sVC_offset.mmsValue = MmsValue_newFloat(0.0); +} diff --git a/examples/iec61850_9_2_LE_example/static_model.h b/examples/iec61850_9_2_LE_example/static_model.h new file mode 100644 index 00000000..f45de247 --- /dev/null +++ b/examples/iec61850_9_2_LE_example/static_model.h @@ -0,0 +1,161 @@ +/* + * static_model.h + * + * automatically generated from sv.icd + */ + +#ifndef STATIC_MODEL_H_ +#define STATIC_MODEL_H_ + +#include +#include "iec61850_model.h" + +extern IedModel iedModel; +extern LogicalDevice iedModel_MUnn; +extern LogicalNode iedModel_MUnn_LLN0; +extern DataObject iedModel_MUnn_LLN0_Mod; +extern DataAttribute iedModel_MUnn_LLN0_Mod_ctlVal; +extern DataAttribute iedModel_MUnn_LLN0_Mod_stVal; +extern DataAttribute iedModel_MUnn_LLN0_Mod_q; +extern DataAttribute iedModel_MUnn_LLN0_Mod_t; +extern LogicalNode iedModel_MUnn_TCTR1; +extern DataObject iedModel_MUnn_TCTR1_Amp; +extern DataAttribute iedModel_MUnn_TCTR1_Amp_instMag; +extern DataAttribute iedModel_MUnn_TCTR1_Amp_instMag_i; +extern DataAttribute iedModel_MUnn_TCTR1_Amp_q; +extern DataAttribute iedModel_MUnn_TCTR1_Amp_sVC; +extern DataAttribute iedModel_MUnn_TCTR1_Amp_sVC_scaleFactor; +extern DataAttribute iedModel_MUnn_TCTR1_Amp_sVC_offset; +extern LogicalNode iedModel_MUnn_TCTR2; +extern DataObject iedModel_MUnn_TCTR2_Amp; +extern DataAttribute iedModel_MUnn_TCTR2_Amp_instMag; +extern DataAttribute iedModel_MUnn_TCTR2_Amp_instMag_i; +extern DataAttribute iedModel_MUnn_TCTR2_Amp_q; +extern DataAttribute iedModel_MUnn_TCTR2_Amp_sVC; +extern DataAttribute iedModel_MUnn_TCTR2_Amp_sVC_scaleFactor; +extern DataAttribute iedModel_MUnn_TCTR2_Amp_sVC_offset; +extern LogicalNode iedModel_MUnn_TCTR3; +extern DataObject iedModel_MUnn_TCTR3_Amp; +extern DataAttribute iedModel_MUnn_TCTR3_Amp_instMag; +extern DataAttribute iedModel_MUnn_TCTR3_Amp_instMag_i; +extern DataAttribute iedModel_MUnn_TCTR3_Amp_q; +extern DataAttribute iedModel_MUnn_TCTR3_Amp_sVC; +extern DataAttribute iedModel_MUnn_TCTR3_Amp_sVC_scaleFactor; +extern DataAttribute iedModel_MUnn_TCTR3_Amp_sVC_offset; +extern LogicalNode iedModel_MUnn_TCTR4; +extern DataObject iedModel_MUnn_TCTR4_Amp; +extern DataAttribute iedModel_MUnn_TCTR4_Amp_instMag; +extern DataAttribute iedModel_MUnn_TCTR4_Amp_instMag_i; +extern DataAttribute iedModel_MUnn_TCTR4_Amp_q; +extern DataAttribute iedModel_MUnn_TCTR4_Amp_sVC; +extern DataAttribute iedModel_MUnn_TCTR4_Amp_sVC_scaleFactor; +extern DataAttribute iedModel_MUnn_TCTR4_Amp_sVC_offset; +extern LogicalNode iedModel_MUnn_TVTR1; +extern DataObject iedModel_MUnn_TVTR1_Vol; +extern DataAttribute iedModel_MUnn_TVTR1_Vol_instMag; +extern DataAttribute iedModel_MUnn_TVTR1_Vol_instMag_i; +extern DataAttribute iedModel_MUnn_TVTR1_Vol_q; +extern DataAttribute iedModel_MUnn_TVTR1_Vol_sVC; +extern DataAttribute iedModel_MUnn_TVTR1_Vol_sVC_scaleFactor; +extern DataAttribute iedModel_MUnn_TVTR1_Vol_sVC_offset; +extern LogicalNode iedModel_MUnn_TVTR2; +extern DataObject iedModel_MUnn_TVTR2_Vol; +extern DataAttribute iedModel_MUnn_TVTR2_Vol_instMag; +extern DataAttribute iedModel_MUnn_TVTR2_Vol_instMag_i; +extern DataAttribute iedModel_MUnn_TVTR2_Vol_q; +extern DataAttribute iedModel_MUnn_TVTR2_Vol_sVC; +extern DataAttribute iedModel_MUnn_TVTR2_Vol_sVC_scaleFactor; +extern DataAttribute iedModel_MUnn_TVTR2_Vol_sVC_offset; +extern LogicalNode iedModel_MUnn_TVTR3; +extern DataObject iedModel_MUnn_TVTR3_Vol; +extern DataAttribute iedModel_MUnn_TVTR3_Vol_instMag; +extern DataAttribute iedModel_MUnn_TVTR3_Vol_instMag_i; +extern DataAttribute iedModel_MUnn_TVTR3_Vol_q; +extern DataAttribute iedModel_MUnn_TVTR3_Vol_sVC; +extern DataAttribute iedModel_MUnn_TVTR3_Vol_sVC_scaleFactor; +extern DataAttribute iedModel_MUnn_TVTR3_Vol_sVC_offset; +extern LogicalNode iedModel_MUnn_TVTR4; +extern DataObject iedModel_MUnn_TVTR4_Vol; +extern DataAttribute iedModel_MUnn_TVTR4_Vol_instMag; +extern DataAttribute iedModel_MUnn_TVTR4_Vol_instMag_i; +extern DataAttribute iedModel_MUnn_TVTR4_Vol_q; +extern DataAttribute iedModel_MUnn_TVTR4_Vol_sVC; +extern DataAttribute iedModel_MUnn_TVTR4_Vol_sVC_scaleFactor; +extern DataAttribute iedModel_MUnn_TVTR4_Vol_sVC_offset; + + + +#define IEDMODEL_MUnn (&iedModel_MUnn) +#define IEDMODEL_MUnn_LLN0 (&iedModel_MUnn_LLN0) +#define IEDMODEL_MUnn_LLN0_Mod (&iedModel_MUnn_LLN0_Mod) +#define IEDMODEL_MUnn_LLN0_Mod_ctlVal (&iedModel_MUnn_LLN0_Mod_ctlVal) +#define IEDMODEL_MUnn_LLN0_Mod_stVal (&iedModel_MUnn_LLN0_Mod_stVal) +#define IEDMODEL_MUnn_LLN0_Mod_q (&iedModel_MUnn_LLN0_Mod_q) +#define IEDMODEL_MUnn_LLN0_Mod_t (&iedModel_MUnn_LLN0_Mod_t) +#define IEDMODEL_MUnn_TCTR1 (&iedModel_MUnn_TCTR1) +#define IEDMODEL_MUnn_TCTR1_Amp (&iedModel_MUnn_TCTR1_Amp) +#define IEDMODEL_MUnn_TCTR1_Amp_instMag (&iedModel_MUnn_TCTR1_Amp_instMag) +#define IEDMODEL_MUnn_TCTR1_Amp_instMag_i (&iedModel_MUnn_TCTR1_Amp_instMag_i) +#define IEDMODEL_MUnn_TCTR1_Amp_q (&iedModel_MUnn_TCTR1_Amp_q) +#define IEDMODEL_MUnn_TCTR1_Amp_sVC (&iedModel_MUnn_TCTR1_Amp_sVC) +#define IEDMODEL_MUnn_TCTR1_Amp_sVC_scaleFactor (&iedModel_MUnn_TCTR1_Amp_sVC_scaleFactor) +#define IEDMODEL_MUnn_TCTR1_Amp_sVC_offset (&iedModel_MUnn_TCTR1_Amp_sVC_offset) +#define IEDMODEL_MUnn_TCTR2 (&iedModel_MUnn_TCTR2) +#define IEDMODEL_MUnn_TCTR2_Amp (&iedModel_MUnn_TCTR2_Amp) +#define IEDMODEL_MUnn_TCTR2_Amp_instMag (&iedModel_MUnn_TCTR2_Amp_instMag) +#define IEDMODEL_MUnn_TCTR2_Amp_instMag_i (&iedModel_MUnn_TCTR2_Amp_instMag_i) +#define IEDMODEL_MUnn_TCTR2_Amp_q (&iedModel_MUnn_TCTR2_Amp_q) +#define IEDMODEL_MUnn_TCTR2_Amp_sVC (&iedModel_MUnn_TCTR2_Amp_sVC) +#define IEDMODEL_MUnn_TCTR2_Amp_sVC_scaleFactor (&iedModel_MUnn_TCTR2_Amp_sVC_scaleFactor) +#define IEDMODEL_MUnn_TCTR2_Amp_sVC_offset (&iedModel_MUnn_TCTR2_Amp_sVC_offset) +#define IEDMODEL_MUnn_TCTR3 (&iedModel_MUnn_TCTR3) +#define IEDMODEL_MUnn_TCTR3_Amp (&iedModel_MUnn_TCTR3_Amp) +#define IEDMODEL_MUnn_TCTR3_Amp_instMag (&iedModel_MUnn_TCTR3_Amp_instMag) +#define IEDMODEL_MUnn_TCTR3_Amp_instMag_i (&iedModel_MUnn_TCTR3_Amp_instMag_i) +#define IEDMODEL_MUnn_TCTR3_Amp_q (&iedModel_MUnn_TCTR3_Amp_q) +#define IEDMODEL_MUnn_TCTR3_Amp_sVC (&iedModel_MUnn_TCTR3_Amp_sVC) +#define IEDMODEL_MUnn_TCTR3_Amp_sVC_scaleFactor (&iedModel_MUnn_TCTR3_Amp_sVC_scaleFactor) +#define IEDMODEL_MUnn_TCTR3_Amp_sVC_offset (&iedModel_MUnn_TCTR3_Amp_sVC_offset) +#define IEDMODEL_MUnn_TCTR4 (&iedModel_MUnn_TCTR4) +#define IEDMODEL_MUnn_TCTR4_Amp (&iedModel_MUnn_TCTR4_Amp) +#define IEDMODEL_MUnn_TCTR4_Amp_instMag (&iedModel_MUnn_TCTR4_Amp_instMag) +#define IEDMODEL_MUnn_TCTR4_Amp_instMag_i (&iedModel_MUnn_TCTR4_Amp_instMag_i) +#define IEDMODEL_MUnn_TCTR4_Amp_q (&iedModel_MUnn_TCTR4_Amp_q) +#define IEDMODEL_MUnn_TCTR4_Amp_sVC (&iedModel_MUnn_TCTR4_Amp_sVC) +#define IEDMODEL_MUnn_TCTR4_Amp_sVC_scaleFactor (&iedModel_MUnn_TCTR4_Amp_sVC_scaleFactor) +#define IEDMODEL_MUnn_TCTR4_Amp_sVC_offset (&iedModel_MUnn_TCTR4_Amp_sVC_offset) +#define IEDMODEL_MUnn_TVTR1 (&iedModel_MUnn_TVTR1) +#define IEDMODEL_MUnn_TVTR1_Vol (&iedModel_MUnn_TVTR1_Vol) +#define IEDMODEL_MUnn_TVTR1_Vol_instMag (&iedModel_MUnn_TVTR1_Vol_instMag) +#define IEDMODEL_MUnn_TVTR1_Vol_instMag_i (&iedModel_MUnn_TVTR1_Vol_instMag_i) +#define IEDMODEL_MUnn_TVTR1_Vol_q (&iedModel_MUnn_TVTR1_Vol_q) +#define IEDMODEL_MUnn_TVTR1_Vol_sVC (&iedModel_MUnn_TVTR1_Vol_sVC) +#define IEDMODEL_MUnn_TVTR1_Vol_sVC_scaleFactor (&iedModel_MUnn_TVTR1_Vol_sVC_scaleFactor) +#define IEDMODEL_MUnn_TVTR1_Vol_sVC_offset (&iedModel_MUnn_TVTR1_Vol_sVC_offset) +#define IEDMODEL_MUnn_TVTR2 (&iedModel_MUnn_TVTR2) +#define IEDMODEL_MUnn_TVTR2_Vol (&iedModel_MUnn_TVTR2_Vol) +#define IEDMODEL_MUnn_TVTR2_Vol_instMag (&iedModel_MUnn_TVTR2_Vol_instMag) +#define IEDMODEL_MUnn_TVTR2_Vol_instMag_i (&iedModel_MUnn_TVTR2_Vol_instMag_i) +#define IEDMODEL_MUnn_TVTR2_Vol_q (&iedModel_MUnn_TVTR2_Vol_q) +#define IEDMODEL_MUnn_TVTR2_Vol_sVC (&iedModel_MUnn_TVTR2_Vol_sVC) +#define IEDMODEL_MUnn_TVTR2_Vol_sVC_scaleFactor (&iedModel_MUnn_TVTR2_Vol_sVC_scaleFactor) +#define IEDMODEL_MUnn_TVTR2_Vol_sVC_offset (&iedModel_MUnn_TVTR2_Vol_sVC_offset) +#define IEDMODEL_MUnn_TVTR3 (&iedModel_MUnn_TVTR3) +#define IEDMODEL_MUnn_TVTR3_Vol (&iedModel_MUnn_TVTR3_Vol) +#define IEDMODEL_MUnn_TVTR3_Vol_instMag (&iedModel_MUnn_TVTR3_Vol_instMag) +#define IEDMODEL_MUnn_TVTR3_Vol_instMag_i (&iedModel_MUnn_TVTR3_Vol_instMag_i) +#define IEDMODEL_MUnn_TVTR3_Vol_q (&iedModel_MUnn_TVTR3_Vol_q) +#define IEDMODEL_MUnn_TVTR3_Vol_sVC (&iedModel_MUnn_TVTR3_Vol_sVC) +#define IEDMODEL_MUnn_TVTR3_Vol_sVC_scaleFactor (&iedModel_MUnn_TVTR3_Vol_sVC_scaleFactor) +#define IEDMODEL_MUnn_TVTR3_Vol_sVC_offset (&iedModel_MUnn_TVTR3_Vol_sVC_offset) +#define IEDMODEL_MUnn_TVTR4 (&iedModel_MUnn_TVTR4) +#define IEDMODEL_MUnn_TVTR4_Vol (&iedModel_MUnn_TVTR4_Vol) +#define IEDMODEL_MUnn_TVTR4_Vol_instMag (&iedModel_MUnn_TVTR4_Vol_instMag) +#define IEDMODEL_MUnn_TVTR4_Vol_instMag_i (&iedModel_MUnn_TVTR4_Vol_instMag_i) +#define IEDMODEL_MUnn_TVTR4_Vol_q (&iedModel_MUnn_TVTR4_Vol_q) +#define IEDMODEL_MUnn_TVTR4_Vol_sVC (&iedModel_MUnn_TVTR4_Vol_sVC) +#define IEDMODEL_MUnn_TVTR4_Vol_sVC_scaleFactor (&iedModel_MUnn_TVTR4_Vol_sVC_scaleFactor) +#define IEDMODEL_MUnn_TVTR4_Vol_sVC_offset (&iedModel_MUnn_TVTR4_Vol_sVC_offset) + +#endif /* STATIC_MODEL_H_ */ + diff --git a/examples/iec61850_9_2_LE_example/sv.icd b/examples/iec61850_9_2_LE_example/sv.icd new file mode 100644 index 00000000..78ade53b --- /dev/null +++ b/examples/iec61850_9_2_LE_example/sv.icd @@ -0,0 +1,148 @@ + + + +
+ + + Station bus + 10 + +
+

10.0.0.2

+

255.255.255.0

+

10.0.0.1

+

0001

+

00000001

+

0001

+
+ + +
+

1

+

4

+

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

+

1001

+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0.001 + + +0 + + + + +0.01 + + +0 + + + + + diff --git a/examples/mms_utility/mms_utility.c b/examples/mms_utility/mms_utility.c index b59d3337..51976a6f 100644 --- a/examples/mms_utility/mms_utility.c +++ b/examples/mms_utility/mms_utility.c @@ -15,6 +15,8 @@ print_help() printf("-d show list of MMS domains\n"); printf("-i show server identity\n"); printf("-t show domain directory\n"); + printf("-r read domain variable\n"); + printf("-a specify domain for read or write command"); } int main(int argc, char** argv) { @@ -24,14 +26,18 @@ int main(int argc, char** argv) { int maxPduSize = 65000; char* domainName = NULL; + char* variableName = NULL; int readDeviceList = 0; int getDeviceDirectory = 0; int identifyDevice = 0; + int readWriteHasDomain = 0; + int readVariable = 0; + int c; - while ((c = getopt(argc, argv, "idh:p:l:t:")) != -1) + while ((c = getopt(argc, argv, "idh:p:l:t:a:r:")) != -1) switch (c) { case 'h': hostname = copyString(optarg); @@ -52,6 +58,15 @@ int main(int argc, char** argv) { getDeviceDirectory = 1; domainName = copyString(optarg); break; + case 'a': + readWriteHasDomain = 1; + domainName = copyString(optarg); + break; + case 'r': + readVariable = 1; + variableName = copyString(optarg); + break; + default: print_help(); return 0; @@ -103,12 +118,39 @@ int main(int argc, char** argv) { while ((element = LinkedList_getNext(element)) != NULL) { char* name = (char*) element->data; - if (strchr(name, '$') == NULL) - printf(" %s\n", name); + printf(" %s\n", name); } } + if (readVariable) { + if (readWriteHasDomain) { + MmsValue* result = MmsConnection_readVariable(con, &error, domainName, variableName); + + if (error != MMS_ERROR_NONE) { + printf("Reading variable failed: (ERROR %i)\n", error); + } + else { + printf("Read SUCCESS\n"); + + + if (result != NULL) { + char outbuf[1024]; + + MmsValue_printToBuffer(result, outbuf, 1024); + + printf("%s\n", outbuf); + } + else + printf("result: NULL\n"); + } + + } + else + printf("Reading VMD scope variable not yet supported!\n"); + } + + exit: MmsConnection_destroy(con); } diff --git a/src/iec61850/inc/iec61850_model.h b/src/iec61850/inc/iec61850_model.h index 258c9b10..376593b0 100644 --- a/src/iec61850/inc/iec61850_model.h +++ b/src/iec61850/inc/iec61850_model.h @@ -1,7 +1,7 @@ /* * model.h * - * Copyright 2013, 2014 Michael Zillgith + * Copyright 2013, 2014, 2015 Michael Zillgith * * This file is part of libIEC61850. * diff --git a/src/iec61850/inc_private/mms_sv.h b/src/iec61850/inc_private/mms_sv.h index 4af77fe5..6f59a374 100644 --- a/src/iec61850/inc_private/mms_sv.h +++ b/src/iec61850/inc_private/mms_sv.h @@ -24,8 +24,20 @@ #ifndef LIBIEC61850_SRC_IEC61850_INC_PRIVATE_MMS_SV_H_ #define LIBIEC61850_SRC_IEC61850_INC_PRIVATE_MMS_SV_H_ + +typedef struct sMmsSampledValueControlBlock* MmsSampledValueControlBlock; + +MmsSampledValueControlBlock +MmsSampledValueControlBlock_create(void); + +void +MmsSampledValueControlBlock_destroy(MmsSampledValueControlBlock self); + MmsVariableSpecification* LIBIEC61850_SV_createSVControlBlocks(MmsMapping* self, MmsDomain* domain, LogicalNode* logicalNode, int svCount, bool unicast); +MmsValue* +LIBIEC61850_SV_readAccessSampledValueControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig); + #endif /* LIBIEC61850_SRC_IEC61850_INC_PRIVATE_MMS_SV_H_ */ diff --git a/src/iec61850/server/impl/ied_server.c b/src/iec61850/server/impl/ied_server.c index 7652650a..83a3a9ef 100644 --- a/src/iec61850/server/impl/ied_server.c +++ b/src/iec61850/server/impl/ied_server.c @@ -188,7 +188,16 @@ createMmsServerCache(IedServer self) #endif /* (CONFIG_IEC61850_CONTROL_SERVICE == 1) */ if ((strcmp(fcName, "BR") != 0) && (strcmp(fcName, "RP") != 0) - && (strcmp(fcName, "GO") != 0)) + +#if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) + && (strcmp(fcName, "GO") != 0) +#endif + +#if (CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT == 1) + && (strcmp(fcName, "MS") != 0) && (strcmp(fcName, "US") != 0) +#endif + + ) { char* variableName = createString(3, lnName, "$", fcName); diff --git a/src/iec61850/server/mms_mapping/mms_mapping.c b/src/iec61850/server/mms_mapping/mms_mapping.c index 0a488866..7e873698 100644 --- a/src/iec61850/server/mms_mapping/mms_mapping.c +++ b/src/iec61850/server/mms_mapping/mms_mapping.c @@ -1,7 +1,7 @@ /* * mms_mapping.c * - * Copyright 2013, 2014 Michael Zillgith + * Copyright 2013, 2014, 2015 Michael Zillgith * * This file is part of libIEC61850. * @@ -28,6 +28,7 @@ #include "stack_config.h" #include "mms_goose.h" +#include "mms_sv.h" #include "reporting.h" #include "control.h" #include "ied_server_private.h" @@ -1008,14 +1009,14 @@ createNamedVariableFromLogicalNode(MmsMapping* self, MmsDomain* domain, /* Add MS and US named variables */ if (msvcbCount > 0) { namedVariable->typeSpec.structure.elements[currentComponent] = - LIBIEC61850_SV_creatSVControlBlocks(self, domain, logicalNode, msvcbCount, false); + LIBIEC61850_SV_createSVControlBlocks(self, domain, logicalNode, msvcbCount, false); currentComponent++; } if (usvcbCount > 0) { namedVariable->typeSpec.structure.elements[currentComponent] = - LIBIEC61850_SV_creatSVControlBlocks(self, domain, logicalNode, msvcbCount, true); + LIBIEC61850_SV_createSVControlBlocks(self, domain, logicalNode, msvcbCount, true); currentComponent++; } @@ -1243,7 +1244,7 @@ MmsMapping_destroy(MmsMapping* self) #endif #if (CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT == 1) - LinkedList_destroyDeep(self->svControls, (LinkedListValueDeleteFunction) MmsSvControlBlock_destroy); + LinkedList_destroyDeep(self->svControls, (LinkedListValueDeleteFunction) MmsSampledValueControlBlock_destroy); #endif #if (CONFIG_IEC61850_CONTROL_SERVICE == 1) @@ -1353,6 +1354,23 @@ isGooseControlBlock(char* separator) #endif /* (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) */ + +#if (CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT == 1) + +static bool +isSampledValueControlBlock(char* separator) +{ + if (strncmp(separator + 1, "MS", 2) == 0) + return true; + + if (strncmp(separator + 1, "US", 2) == 0) + return true; + + return false; +} + +#endif /* (CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT == 1) */ + char* MmsMapping_getNextNameElement(char* name) { @@ -1679,6 +1697,14 @@ mmsWriteHandler(void* parameter, MmsDomain* domain, } #endif /* (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) */ +#if (CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT == 1) + /* Sampled Value control block - MS/US */ + if (isSampledValueControlBlock(separator)) { + //TODO handle write access to SVCB + } +#endif /* (CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT == 1) */ + + #if (CONFIG_IEC61850_REPORT_SERVICE == 1) /* Report control blocks - BR, RP */ if (isReportControlBlock(separator)) { @@ -2075,6 +2101,7 @@ readAccessGooseControlBlock(MmsMapping* self, MmsDomain* domain, char* variableI #endif /* (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) */ + static MmsValue* mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerConnection connection) { @@ -2100,14 +2127,23 @@ mmsReadHandler(void* parameter, MmsDomain* domain, char* variableId, MmsServerCo } #endif - /* GOOSE control blocks - GO */ + #if (CONFIG_INCLUDE_GOOSE_SUPPORT == 1) + /* GOOSE control blocks - GO */ if (isGooseControlBlock(separator)) { retValue = readAccessGooseControlBlock(self, domain, variableId); goto exit_function; } #endif +#if (CONFIG_IEC61850_SAMPLED_VALUES_SUPPORT == 1) + /* Sampled Value control blocks - MS/US */ + if (isSampledValueControlBlock(separator)) { + retValue = LIBIEC61850_SV_readAccessSampledValueControlBlock(self, domain, variableId); + goto exit_function; + } +#endif + #if (CONFIG_IEC61850_REPORT_SERVICE == 1) /* Report control blocks - BR, RP */ if (isReportControlBlock(separator)) { diff --git a/src/iec61850/server/mms_mapping/mms_sv.c b/src/iec61850/server/mms_mapping/mms_sv.c index 56e8674b..c4f1c1ce 100644 --- a/src/iec61850/server/mms_mapping/mms_sv.c +++ b/src/iec61850/server/mms_mapping/mms_sv.c @@ -30,10 +30,109 @@ #include "linked_list.h" #include "array_list.h" +#include "mms_sv.h" + #include "mms_mapping_internal.h" +struct sMmsSampledValueControlBlock { + char* name; + bool svEna; + + char* dstAddress; + + MmsDomain* domain; + LogicalNode* logicalNode; + + MmsVariableSpecification* mmsType; + MmsValue* mmsValue; + + //MmsMapping* mmsMapping; +}; + +MmsSampledValueControlBlock +MmsSampledValueControlBlock_create() +{ + MmsSampledValueControlBlock self = (MmsSampledValueControlBlock) GLOBAL_CALLOC(1, sizeof(struct sMmsSampledValueControlBlock)); + + return self; +} + + +void +MmsSampledValueControlBlock_destroy(MmsSampledValueControlBlock self) +{ + MmsValue_delete(self->mmsValue); + + GLOBAL_FREEMEM(self); +} + +static MmsSampledValueControlBlock +lookupSVCB(MmsMapping* self, MmsDomain* domain, char* lnName, char* objectName) +{ + LinkedList element = LinkedList_getNext(self->svControls); + + while (element != NULL) { + MmsSampledValueControlBlock mmsSVCB = (MmsSampledValueControlBlock) element->data; + + if (mmsSVCB->domain == domain) { + if (strcmp(mmsSVCB->logicalNode->name, lnName) == 0) { + if (strcmp(mmsSVCB->name, objectName) == 0) { + return mmsSVCB; + } + } + } + + element = LinkedList_getNext(element); + } + + return NULL; +} + + +MmsValue* +LIBIEC61850_SV_readAccessSampledValueControlBlock(MmsMapping* self, MmsDomain* domain, char* variableIdOrig) +{ + MmsValue* value = NULL; + + char variableId[130]; + + strncpy(variableId, variableIdOrig, 129); + + char* separator = strchr(variableId, '$'); + + *separator = 0; + + char* lnName = variableId; + + if (lnName == NULL) + return NULL; + + char* objectName = MmsMapping_getNextNameElement(separator + 1); -static GSEControlBlock* + if (objectName == NULL) + return NULL; + + char* varName = MmsMapping_getNextNameElement(objectName); + + if (varName != NULL) + *(varName - 1) = 0; + + MmsSampledValueControlBlock mmsSVCB = lookupSVCB(self, domain, lnName, objectName); + + if (mmsSVCB != NULL) { + if (varName != NULL) { + value = MmsValue_getSubElement(mmsSVCB->mmsValue, mmsSVCB->mmsType, varName); + } + else { + value = mmsSVCB->mmsValue; + } + } + + return value; +} + + +static SVControlBlock* getSVCBForLogicalNodeWithIndex(MmsMapping* self, LogicalNode* logicalNode, int index, bool isUnicast) { int svCount = 0; @@ -88,6 +187,8 @@ createSVControlBlockMmsStructure(char* gcbName, bool isUnicast) namedVariable = (MmsVariableSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("Resv"); namedVariable->type = MMS_BOOLEAN; + + gcb->typeSpec.structure.elements[currentElement++] = namedVariable; } namedVariable = (MmsVariableSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableSpecification)); @@ -128,6 +229,13 @@ createSVControlBlockMmsStructure(char* gcbName, bool isUnicast) gcb->typeSpec.structure.elements[currentElement++] = namedVariable; + namedVariable = (MmsVariableSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableSpecification)); + namedVariable->name = copyString("SmpMod"); + namedVariable->type = MMS_INTEGER; + namedVariable->typeSpec.integer = 8; + + gcb->typeSpec.structure.elements[currentElement++] = namedVariable; + namedVariable = (MmsVariableSpecification*) GLOBAL_CALLOC(1, sizeof(MmsVariableSpecification)); namedVariable->name = copyString("DstAddress"); MmsMapping_createPhyComAddrStructure(namedVariable); @@ -205,7 +313,7 @@ LIBIEC61850_SV_createSVControlBlocks(MmsMapping* self, MmsDomain* domain, /* SmpMod */ MmsValue* smpMod = MmsValue_getElement(svValues, currentIndex++); - MmsValue_setInt32(smpRate, svControlBlock->smpMod); + MmsValue_setInt32(smpMod, svControlBlock->smpMod); /* Set communication parameters - DstAddress */ uint8_t priority = CONFIG_GOOSE_DEFAULT_PRIORITY; @@ -242,6 +350,16 @@ LIBIEC61850_SV_createSVControlBlocks(MmsMapping* self, MmsDomain* domain, MmsValue* noASDU = MmsValue_getElement(svValues, currentIndex++); MmsValue_setInt32(noASDU, svControlBlock->noASDU); + MmsSampledValueControlBlock mmsSvCb = MmsSampledValueControlBlock_create(); + + mmsSvCb->mmsValue = svValues; + mmsSvCb->mmsType = svTypeSpec; + mmsSvCb->domain = domain; + mmsSvCb->logicalNode = logicalNode; + mmsSvCb->name = svControlBlock->name; + + LinkedList_add(self->svControls, (void*) mmsSvCb); + currentSVCB++; } diff --git a/src/mms/inc/mms_client_connection.h b/src/mms/inc/mms_client_connection.h index d87667e2..621bbb51 100644 --- a/src/mms/inc/mms_client_connection.h +++ b/src/mms/inc/mms_client_connection.h @@ -292,7 +292,8 @@ MmsConnection_getVariableListNamesAssociationSpecific(MmsConnection self, MmsErr * \param itemId name of the variable to be read * * \return Returns a MmsValue object or NULL if the request failed. The MmsValue object can - * either be a simple value or a complex value or array. + * either be a simple value or a complex value or array. It is also possible that the return value is NULL + * even if mmsError = MMS_ERROR_NON. This is the case when the servers returns an empty result list. */ MmsValue* MmsConnection_readVariable(MmsConnection self, MmsError* mmsError, const char* domainId, const char* itemId); diff --git a/tools/model_generator/genconfig.jar b/tools/model_generator/genconfig.jar index 3a36f546..9e3e43d5 100644 Binary files a/tools/model_generator/genconfig.jar and b/tools/model_generator/genconfig.jar differ diff --git a/tools/model_generator/genmodel.jar b/tools/model_generator/genmodel.jar index 2fdd70a9..784ac0ac 100644 Binary files a/tools/model_generator/genmodel.jar and b/tools/model_generator/genmodel.jar differ diff --git a/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java b/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java index 2aceca49..bfa61d39 100644 --- a/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java +++ b/tools/model_generator/src/com/libiec61850/scl/communication/ConnectedAP.java @@ -48,17 +48,15 @@ public class ConnectedAP { List gseNodes = ParserUtils.getChildNodesWithTag(node, "GSE"); - for (Node gseNode : gseNodes) { + for (Node gseNode : gseNodes) gses.add(new GSE(gseNode)); - } - + smvs = new LinkedList(); List smvNodes = ParserUtils.getChildNodesWithTag(node, "SMV"); - for (Node smvNode : smvNodes) { - smvs.add(new SMV(smvNode)); - } + for (Node smvNode : smvNodes) + smvs.add(new SMV(smvNode)); } public String getIedName() { diff --git a/tools/model_generator/src/com/libiec61850/scl/model/LogicalNode.java b/tools/model_generator/src/com/libiec61850/scl/model/LogicalNode.java index 5d34675f..6033732f 100644 --- a/tools/model_generator/src/com/libiec61850/scl/model/LogicalNode.java +++ b/tools/model_generator/src/com/libiec61850/scl/model/LogicalNode.java @@ -116,7 +116,10 @@ public class LogicalNode implements DataModelNode { /* Parse Sampled Values (SV) control block definitions */ smvControlBlocks = new LinkedList(); - + + List svControlNodes = ParserUtils.getChildNodesWithTag(lnNode, "SampledValueControl"); + for (Node svControlNode : svControlNodes) + smvControlBlocks.add(new SampledValueControl(svControlNode)); /* Parse log control block definitions */ logControlBlocks = new LinkedList(); diff --git a/tools/model_generator/src/com/libiec61850/scl/model/SampledValueControl.java b/tools/model_generator/src/com/libiec61850/scl/model/SampledValueControl.java index 77993e77..f2f03b66 100644 --- a/tools/model_generator/src/com/libiec61850/scl/model/SampledValueControl.java +++ b/tools/model_generator/src/com/libiec61850/scl/model/SampledValueControl.java @@ -14,7 +14,7 @@ public class SampledValueControl { private String smvID; private int smpRate; private int nofASDU; - private boolean multicast; + private boolean multicast = false; private SmvOpts smvOpts; @@ -31,7 +31,10 @@ public class SampledValueControl { this.smvID = ParserUtils.parseAttribute(smvControlNode, "smvID"); - this.multicast = ParserUtils.parseBooleanAttribute(smvControlNode, "multicast"); + Boolean multicast = ParserUtils.parseBooleanAttribute(smvControlNode, "multicast"); + + if (multicast != null) + this.multicast = multicast; String smpRateString = ParserUtils.parseAttribute(smvControlNode, "smpRate"); diff --git a/tools/model_generator/src/com/libiec61850/scl/model/SmvOpts.java b/tools/model_generator/src/com/libiec61850/scl/model/SmvOpts.java index 1dcd59ad..02646af9 100644 --- a/tools/model_generator/src/com/libiec61850/scl/model/SmvOpts.java +++ b/tools/model_generator/src/com/libiec61850/scl/model/SmvOpts.java @@ -8,11 +8,12 @@ import com.libiec61850.scl.SclParserException; public class SmvOpts { - private boolean refreshTime = false; - private boolean sampleRate = false; - private boolean dataSet = false; - private boolean security = false; - private boolean sampleSynchronized = false; + private boolean refreshTime = false; /* 1 */ + private boolean sampleSynchronized = false; /* 2 */ + private boolean sampleRate = false; /* 4 */ + private boolean dataSet = false; /* 8 */ + private boolean security = false; /* 16 */ + public SmvOpts(Node smvOptsNode) throws SclParserException { @@ -38,4 +39,16 @@ public class SmvOpts { } + + 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; + } } diff --git a/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java b/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java index a7e3ff42..cad7d5ec 100644 --- a/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java +++ b/tools/model_generator/src/com/libiec61850/tools/StaticModelGenerator.java @@ -51,6 +51,7 @@ import com.libiec61850.scl.model.IED; import com.libiec61850.scl.model.LogicalDevice; import com.libiec61850.scl.model.LogicalNode; import com.libiec61850.scl.model.ReportControlBlock; +import com.libiec61850.scl.model.SampledValueControl; import com.libiec61850.scl.model.Server; import com.libiec61850.scl.model.SettingControl; import com.libiec61850.scl.model.TriggerOptions; @@ -71,6 +72,10 @@ public class StaticModelGenerator { private List gseVariableNames; private int currentGseVariableNumber = 0; + private StringBuffer smvControlBlocks; + private List smvVariableNames; + private int currentSvCBVariableNumber = 0; + private StringBuffer settingGroupControlBlocks; private List sgcbVariableNames; private int currentSGCBVariableNumber = 0; @@ -101,6 +106,9 @@ public class StaticModelGenerator { this.gseControlBlocks = new StringBuffer(); this.gseVariableNames = new LinkedList(); + this.smvControlBlocks = new StringBuffer(); + this.smvVariableNames = new LinkedList(); + this.settingGroupControlBlocks = new StringBuffer(); this.sgcbVariableNames = new LinkedList(); @@ -267,6 +275,8 @@ public class StaticModelGenerator { createGooseVariableList(logicalDevices); + createSmvVariableList(logicalDevices); + createSettingControlsVariableList(logicalDevices); for (int i = 0; i < logicalDevices.size(); i++) { @@ -308,6 +318,11 @@ public class StaticModelGenerator { cOut.println(reportControlBlocks); + for (String smv : smvVariableNames) + cOut.println("extern SVControlBlock " + smv + ";"); + + cOut.println(smvControlBlocks); + for (String gcb : gseVariableNames) cOut.println("extern GSEControlBlock " + gcb + ";"); @@ -338,6 +353,11 @@ public class StaticModelGenerator { else cOut.println(" NULL,"); + if (smvVariableNames.size() > 0) + cOut.println(" &" + smvVariableNames.get(0) + ","); + else + cOut.println(" NULL,"); + if (sgcbVariableNames.size() > 0) cOut.println(" &" + sgcbVariableNames.get(0) + ","); else @@ -366,6 +386,28 @@ public class StaticModelGenerator { } } + + private void createSmvVariableList(List logicalDevices) { + for (LogicalDevice ld : logicalDevices) { + List lnodes = ld.getLogicalNodes(); + + String ldName = ld.getInst(); + + + for (LogicalNode ln : lnodes) { + List svCBs = ln.getSampledValueControlBlocks(); + + int smvCount = 0; + + for (SampledValueControl smv : svCBs) { + String smvVariableName = modelPrefix + "_" + ldName + "_" + ln.getName() + "_smv" + smvCount; + smvVariableNames.add(smvVariableName); + smvCount++; + } + } + } + } + private void createReportVariableList(List logicalDevices) { for (LogicalDevice ld : logicalDevices) { @@ -445,6 +487,8 @@ public class StaticModelGenerator { printGSEControlBlocks(ldName, lnName, logicalNode); + printSVControlBlocks(ldName, lnName, logicalNode); + printSettingControlBlock(lnName, logicalNode); } } @@ -742,11 +786,100 @@ public class StaticModelGenerator { hOut.println("#endif /* " + hDefineName + " */\n"); } + private void printSVControlBlocks(String ldName, String lnPrefix, LogicalNode logicalNode) { + List svControlBlocks = logicalNode.getSampledValueControlBlocks(); + + /* strip "iedModel_" from ldName */ + String[] ldNameComponents = ldName.split("_"); + String logicalDeviceName = ldNameComponents[1]; + + int smvControlNumber = 0; + + for (SampledValueControl svCB : svControlBlocks) { + + System.out.println("SVCB: " + svCB.getName()); + + PhyComAddress svAddress = connectedAP.lookupSMVAddress(logicalDeviceName, svCB.getName()); + + String svString = ""; + + String phyComAddrName = ""; + + if (svAddress != null) { + phyComAddrName = lnPrefix + "_smv" + smvControlNumber + "_address"; + + svString += "\nstatic PhyComAddress " + phyComAddrName + " = {\n"; + svString += " " + svAddress.getVlanPriority() + ",\n"; + svString += " " + svAddress.getVlanId() + ",\n"; + svString += " " + svAddress.getAppId() + ",\n"; + svString += " {"; + + for (int i = 0; i < 6; i++) { + svString += "0x" + Integer.toHexString(svAddress.getMacAddress()[i]); + if (i == 5) + svString += "}\n"; + else + svString += ", "; + } + + svString += "};\n\n"; + } + + String smvVariableName = lnPrefix + "_smv" + smvControlNumber; + + svString += "SVControlBlock " + smvVariableName + " = {"; + svString += "&" + lnPrefix + ", "; + + svString += "\"" + svCB.getName() + "\", "; + + if (svCB.getSmvID() == null) + svString += "NULL, "; + else + svString += "\"" + svCB.getSmvID() + "\", "; + + if (svCB.getDatSet() != null) + svString += "\"" + svCB.getDatSet() + "\", "; + else + svString += "NULL, "; + + svString += svCB.getSmvOpts().getIntValue() + ", "; + + svString += "0, " + svCB.getSmpRate() + ", "; + + svString += svCB.getConfRev() + ", "; + + if (svAddress != null) + svString += "&" + phyComAddrName + ", "; + else + svString += "NULL, "; + + if (svCB.isMulticast()) + svString += "false, "; + else + svString += "true, "; + + svString += svCB.getNofASDI() + ", "; + + currentSvCBVariableNumber++; + + if (currentSvCBVariableNumber < smvVariableNames.size()) + svString += "&" + smvVariableNames.get(currentSvCBVariableNumber); + else + svString += "NULL"; + + svString += "};\n"; + + this.smvControlBlocks.append(svString); + + smvControlNumber++; + } + } + private void printGSEControlBlocks(String ldName, String lnPrefix, LogicalNode logicalNode) { List gseControlBlocks = logicalNode.getGSEControlBlocks(); + /* strip "iedModel_" from ldName */ String[] ldNameComponents = ldName.split("_"); - String logicalDeviceName = ldNameComponents[1]; int gseControlNumber = 0;