diff --git a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs
index 183df204..6d237e28 100644
--- a/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs
+++ b/dotnet/IEC61850forCSharp/IEC61850ServerAPI.cs
@@ -26,6 +26,7 @@ using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.Runtime.InteropServices;
+using System.Security.Cryptography;
using System.Xml.Linq;
using IEC61850.Client;
using IEC61850.Common;
@@ -927,6 +928,9 @@ namespace IEC61850
{
[DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr DataObject_create(string name, IntPtr parent, int arrayElements);
+
+ [DllImport("iec61850", CallingConvention = CallingConvention.Cdecl)]
+ static extern IntPtr ModelNode_getChildWithFc(IntPtr self, string objectReference, int fc);
internal DataObject(IntPtr self, ModelNode parent) : base(self)
{
@@ -944,6 +948,28 @@ namespace IEC61850
self = DataObject_create (name, parent.self, arrayElements);
}
+ ///
+ /// return a child model node with a given functional constraint
+ /// Sometimes the name is not enough to identify a model node.This is the case when
+ /// editable setting groups are used.In this case the setting group members have two different
+ /// model nodes associated that differ in their FC (SG and SE).
+ ///
+ /// the name of the child model node
+ /// the functional constraint of the model node
+ /// the model node instance or NULL if model node does not exist.
+ public DataAttribute GetChildWithFc(string objRef, FunctionalConstraint fc)
+ {
+ DataAttribute dataAttribute = null;
+ IntPtr da = ModelNode_getChildWithFc(this.self, objRef, (int)fc);
+
+ if (da != IntPtr.Zero)
+ {
+ dataAttribute = new DataAttribute(da, this);
+ }
+
+ return dataAttribute;
+ }
+
}
public class DataAttribute : ModelNode
diff --git a/dotnet/server_example_access_control/Program.cs b/dotnet/server_example_access_control/Program.cs
index 9b4a3c5a..7a01724f 100644
--- a/dotnet/server_example_access_control/Program.cs
+++ b/dotnet/server_example_access_control/Program.cs
@@ -247,20 +247,40 @@ namespace server_access_control
void LoadActiveSgValues(int actSG)
{
+
DataAttribute dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.StrVal.setMag.f");
iedServer.UpdateFloatAttributeValue(dataAttribute, ptoc1Settings[actSG - 1].strVal);
- dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.OpDlTmms.setVal");
+ dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.opDlTmms.setVal");
iedServer.UpdateInt32AttributeValue(dataAttribute, ptoc1Settings[actSG - 1].opDlTmms);
- dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.RsDlTmms.setVal");
+ dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.rsDlTmms.setVal");
iedServer.UpdateInt32AttributeValue(dataAttribute, ptoc1Settings[actSG - 1].rsDlTmms);
- dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.RstTms.setVal");
+ dataAttribute = (DataAttribute)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.rstTms.setVal");
iedServer.UpdateInt32AttributeValue(dataAttribute, ptoc1Settings[actSG - 1].rstTms);
}
+ void LoadEditSgValues(int actSG)
+ {
+ DataObject strVal = (DataObject)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.StrVal");
+ DataAttribute setMagF = strVal.GetChildWithFc("setMag.f", FunctionalConstraint.SE);
+ iedServer.UpdateFloatAttributeValue(setMagF, ptoc1Settings[actSG - 1].strVal);
+
+ DataObject opDlTmms = (DataObject)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.OpDlTmms");
+ DataAttribute setVal = opDlTmms.GetChildWithFc("setVal", FunctionalConstraint.SE);
+ iedServer.UpdateInt32AttributeValue(setVal, ptoc1Settings[actSG - 1].opDlTmms);
+
+ DataObject rsDlTmms = (DataObject)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.RsDlTmms");
+ DataAttribute rsDlTmms_setVal = rsDlTmms.GetChildWithFc("setVal", FunctionalConstraint.SE);
+ iedServer.UpdateInt32AttributeValue(rsDlTmms_setVal, ptoc1Settings[actSG - 1].rsDlTmms);
+
+ DataObject rstTms = (DataObject)iedModel.GetModelNodeByShortObjectReference("GenericIO/PTOC1.RstTms");
+ DataAttribute rstTms_setVal = rstTms.GetChildWithFc("setVal", FunctionalConstraint.SE);
+ iedServer.UpdateInt32AttributeValue(rstTms_setVal, ptoc1Settings[actSG - 1].rstTms);
+ }
+
bool activeSGChangedHandler(object parameter, SettingGroupControlBlock sgcb, uint newActSg, ClientConnection connection)
{
Console.WriteLine("Switch to setting group "+ newActSg +"\n");
- LoadActiveSgValues(Convert.ToInt32(newActSg));
+
return true;
}
@@ -268,6 +288,8 @@ namespace server_access_control
{
Console.WriteLine("Set edit setting group to " + newEditSg + "\n");
+ LoadEditSgValues(Convert.ToInt32(newEditSg));
+
return true;
}