From ae07c77d39c9f3e27027ff5e9f37830efaf47cc8 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Sat, 7 Mar 2020 15:05:11 +0100 Subject: [PATCH] - CDC helpers: added functions to create ISC and BAC CDCs --- src/iec61850/inc/iec61850_cdc.h | 44 +++++++++++++++++++ src/iec61850/server/model/cdc.c | 78 +++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/src/iec61850/inc/iec61850_cdc.h b/src/iec61850/inc/iec61850_cdc.h index 8615af13..04a077bf 100644 --- a/src/iec61850/inc/iec61850_cdc.h +++ b/src/iec61850/inc/iec61850_cdc.h @@ -496,11 +496,33 @@ CDC_ENC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, LIB61850_API DataObject* CDC_BSC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool hasTransientIndicator); +/** + * \brief Integer controlled step position information (ISC) + * + * CDC_OPTION_IS_TIME_ACTICATED + * + * substitution options + * CDC_OPTION_BLK_ENA + * standard description and namespace options + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param controlOptions specify which control model to set as default and other control specific options + * \param hasTransientIndicator specifies if the step position information contains the transient indicator + * + */ +LIB61850_API DataObject* +CDC_ISC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool hasTransientIndicator); + /** * \brief Controllable analogue process value (APC) * * CDC_OPTION_IS_TIME_ACTICATED * + * CDC_OPTION_MIN + * CDC_OPTION_MAX + * * substitution options * CDC_OPTION_BLK_ENA * standard description and namespace options @@ -514,6 +536,28 @@ CDC_BSC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, LIB61850_API DataObject* CDC_APC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool isIntegerNotFloat); +/** + * \brief Binary controlled ananlogue process value (BAC) + * + * CDC_OPTION_IS_TIME_ACTICATED + * + * CDC_OPTION_MIN + * CDC_OPTION_MAX + * CDC_OPTION_STEP_SIZE + * + * substitution options + * CDC_OPTION_BLK_ENA + * standard description and namespace options + * + * \param dataObjectName the name of the new object + * \param parent the parent of the new data object (either a LogicalNode or another DataObject) + * \param options bit mask to encode required optional elements + * \param controlOptions specify which control model to set as default and other control specific options + * \param isIntegerNotFloat + */ +LIB61850_API DataObject* +CDC_BAC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool isIntegerNotFloat); + /** Minimum measured value */ #define CDC_OPTION_61400_MIN_MX_VAL (1 << 10) diff --git a/src/iec61850/server/model/cdc.c b/src/iec61850/server/model/cdc.c index a5293970..f3f27f11 100644 --- a/src/iec61850/server/model/cdc.c +++ b/src/iec61850/server/model/cdc.c @@ -820,6 +820,84 @@ CDC_BSC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, return newBSC; } +DataObject* +CDC_ISC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool hasTransientIndicator) +{ + DataObject* newISC = DataObject_create(dataObjectName, parent, 0); + + addOriginatorAndCtlNumOptions((ModelNode*) newISC, controlOptions); + + CAC_ValWithTrans_create("valWTr", (ModelNode*) newISC, IEC61850_FC_ST, TRG_OPT_DATA_CHANGED, hasTransientIndicator); + CDC_addTimeQuality(newISC, IEC61850_FC_ST); + + addControls(newISC, IEC61850_INT8, controlOptions); + + if (controlOptions & CDC_CTL_OPTION_ST_SELD) + DataAttribute_create("stSeld", (ModelNode*) newISC, IEC61850_BOOLEAN, IEC61850_FC_ST, TRG_OPT_DATA_CHANGED, 0, 0); + + addCommonControlAttributes(newISC, controlOptions); + + if (options & CDC_OPTION_PICS_SUBST) + CDC_addOptionPicsSubstValWithTrans(newISC, hasTransientIndicator); + + if (options & CDC_OPTION_BLK_ENA) + DataAttribute_create("blkEna", (ModelNode*) newISC, IEC61850_BOOLEAN, IEC61850_FC_BL, 0, 0, 0); + + if (options & CDC_OPTION_MIN) + DataAttribute_create("minVal", (ModelNode*) newISC, IEC61850_INT32, IEC61850_FC_CF, 0, 0, 0); + + if (options & CDC_OPTION_MAX) + DataAttribute_create("maxVal", (ModelNode*) newISC, IEC61850_INT32, IEC61850_FC_CF, 0, 0, 0); + + CDC_addStandardOptions(newISC, options); + + return newISC; +} + +DataObject* +CDC_BAC_create(const char* dataObjectName, ModelNode* parent, uint32_t options, uint32_t controlOptions, bool isIntegerNotFloat) +{ + DataObject* newBAC = DataObject_create(dataObjectName, parent, 0); + + addControlStatusAttributesForAnalogControl(newBAC, controlOptions); + + CAC_AnalogueValue_create("mxVal", (ModelNode*) newBAC, IEC61850_FC_MX, TRG_OPT_DATA_CHANGED, isIntegerNotFloat); + + CDC_addTimeQuality(newBAC, IEC61850_FC_MX); + + if (controlOptions & CDC_CTL_OPTION_ST_SELD) + DataAttribute_create("stSeld", (ModelNode*) newBAC, IEC61850_BOOLEAN, IEC61850_FC_MX, TRG_OPT_DATA_CHANGED, 0, 0); + + addControls(newBAC, IEC61850_INT8, controlOptions); + + if (options & CDC_OPTION_PICS_SUBST) { + DataAttribute_create("subEna", (ModelNode*) newBAC, IEC61850_BOOLEAN, IEC61850_FC_SV, 0, 0, 0); + CAC_AnalogueValue_create("subVal", (ModelNode*) newBAC, IEC61850_FC_SV, 0, isIntegerNotFloat); + DataAttribute_create("subQ", (ModelNode*) newBAC, IEC61850_QUALITY, IEC61850_FC_SV, 0, 0, 0); + DataAttribute_create("subID", (ModelNode*) newBAC, IEC61850_VISIBLE_STRING_64, IEC61850_FC_SV, 0, 0, 0); + } + + if (options & CDC_OPTION_BLK_ENA) + DataAttribute_create("blkEna", (ModelNode*) newBAC, IEC61850_BOOLEAN, IEC61850_FC_BL, 0, 0, 0); + + DataAttribute_create("persistent", (ModelNode*) newBAC, IEC61850_BOOLEAN, IEC61850_FC_CF, TRG_OPT_DATA_CHANGED, 0, 0); + + addAnalogControls(newBAC, controlOptions, isIntegerNotFloat); + + if (options & CDC_OPTION_MIN) + CAC_AnalogueValue_create("minVal", (ModelNode*) newBAC, IEC61850_FC_CF, 0, isIntegerNotFloat); + + if (options & CDC_OPTION_MAX) + CAC_AnalogueValue_create("maxVal", (ModelNode*) newBAC, IEC61850_FC_CF, 0, isIntegerNotFloat); + + if (options & CDC_OPTION_STEP_SIZE) + CAC_AnalogueValue_create("stepSize", (ModelNode*) newBAC, IEC61850_FC_CF, 0, isIntegerNotFloat); + + CDC_addStandardOptions(newBAC, options); + + return newBAC; +} + DataObject* CDC_LPL_create(const char* dataObjectName, ModelNode* parent, uint32_t options) {