Skip to content

Commit

Permalink
OPC DA Client: auto create tags.
Browse files Browse the repository at this point in the history
  • Loading branch information
riclolsen committed Jul 24, 2024
1 parent 5cc5bfb commit 0cc1812
Show file tree
Hide file tree
Showing 7 changed files with 326 additions and 252 deletions.
194 changes: 158 additions & 36 deletions src/opcdaaehda-client-solution-net/OPC-DA-Client/AsduReceiveHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,24 @@
*/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json;
using Technosoftware.DaAeHdaClient;
using Technosoftware.DaAeHdaClient.Da;

namespace OPCDAClientDriver
{
partial class MainClass
{
/// <summary>
/// A delegate to receive data change updates from the server.
/// </summary>
/// <param name="subscriptionHandle">
/// A unique identifier for the subscription assigned by the client. If the parameter
/// <see cref="TsCDaSubscriptionState.ClientHandle">ClientHandle</see> is not defined this
/// parameter is empty.</param>
/// <param name="requestHandle">
/// An identifier for the request assigned by the caller. This parameter is empty if
/// the corresponding parameter in the calls Read(), Write() or Refresh() is not defined.
/// Can be used to Cancel an outstanding operation.
/// </param>
/// <param name="values">
/// <para class="MsoBodyText" style="MARGIN: 1pt 0in">The set of changed values.</para>
/// <para class="MsoBodyText" style="MARGIN: 1pt 0in">Each value will always have
/// item’s ClientHandle field specified.</para>
/// </param>
public static void OnDataChangeEvent(object subscriptionHandle, object requestHandle, TsCDaItemValueResult[] values)
public static void OnDataChangeEvent(object subscriptionHandle, object requestHandle, TsCDaItemValueResult[] values, ref OPCDA_connection srv)
{
string connName= "Conn?";
if (values.Length > 0)
{
string strHandle = string.Format("{0}", values[0].ClientHandle);
connName = MapHandlerToConnName[strHandle];
}
string connName= srv.name;
Log(string.Format($"{connName} - DataChange: {values.Length} -----------------------------------------------------------"), 1);
if (requestHandle != null)
{
Log("DataChange() for requestHandle :" + requestHandle.GetHashCode().ToString());
}
//if (requestHandle != null)
//{
// Log("DataChange() for requestHandle :" + requestHandle.GetHashCode().ToString());
//}
for (var i = 0; i < values.Length; i++)
{
// Console.Write(" Client Handle : "); Console.WriteLine(values[i].ClientHandle);
Expand All @@ -64,13 +45,16 @@ public static void OnDataChangeEvent(object subscriptionHandle, object requestHa
{
for (var j = 0; j < values.Length; j++)
{
if (j < 33 * LogLevel)
Log($"{connName} - Change: {MapHandlerToItemName[strHandle]} Val[{j}]: " + string.Format("{0}", values[j].Value), 2);
if (LogLevel >= LogLevelDetailed && j < 33 * LogLevel)
Log($"{connName} - Change: {srv.MapHandlerToItemName[strHandle]} Val[{j}]: " + string.Format("{0}", values[j].Value), 2);
}
Log($"{connName} - Change: {MapHandlerToItemName[strHandle]} TS: " + values[i].Timestamp.ToString(CultureInfo.InvariantCulture), 2);
Log($"{connName} - Change: {MapHandlerToItemName[strHandle]} Q: " + values[i].Quality, 2);
}
else
if (LogLevel >= LogLevelDetailed)
{
Log($"{connName} - Change: {srv.MapHandlerToItemName[strHandle]} TS: " + values[i].Timestamp.ToString(CultureInfo.InvariantCulture), 2);
Log($"{connName} - Change: {srv.MapHandlerToItemName[strHandle]} Q: " + values[i].Quality, 2);
}
}
else
{
var valueResult = values[i];
//var quality = new TsCDaQuality(193);
Expand All @@ -82,13 +66,151 @@ public static void OnDataChangeEvent(object subscriptionHandle, object requestHa
// Log(message);
//}

if (i < 33 * LogLevel)
Log($"{connName} - Change: {MapHandlerToItemName[strHandle]} Val: {values[i].Value} Q: {values[i].Quality} TS: {values[i].Timestamp.ToString(CultureInfo.InvariantCulture)}", 2);
if (LogLevel >= LogLevelDetailed && i < 33 * LogLevel)
Log($"{connName} - Change: {srv.MapHandlerToItemName[strHandle]} Val: {values[i].Value} Q: {values[i].Quality} TS: {values[i].Timestamp.ToString(CultureInfo.InvariantCulture)}", 2);
}
}
//Console.Write(" Result : "); Console.WriteLine(values[i].Result.Description());
}
Log("----------------------------------------------------------- End", 2);
}
public static void convertItemValue(object iv, out double value, out string valueString, out string valueJson, out bool quality, out bool isDigital)
{
value = 0;
valueJson = string.Empty;
valueString = string.Empty;
quality = true;
isDigital = false;
try
{
if (iv.GetType().IsArray)
{
valueJson = JsonSerializer.Serialize(iv);
valueString = valueJson;
}
else
switch (iv.GetType().Name)
{
case "String":
valueString = Convert.ToString(iv);
valueJson = JsonSerializer.Serialize(iv);
break;
case "Boolean":
value = Convert.ToBoolean(iv) ? 1 : 0;
isDigital = true;
valueJson = JsonSerializer.Serialize(iv);
valueString = valueJson;
break;
case "SByte":
value = Convert.ToSByte(iv);
valueJson = JsonSerializer.Serialize(iv);
valueString = valueJson;
break;
case "Decimal":
value = Convert.ToDouble(Convert.ToDecimal(iv));
valueJson = JsonSerializer.Serialize(iv);
valueString = valueJson;
break;
case "Time":
case "DateTime":
value = Convert.ToDateTime(iv).Subtract(DateTime.UnixEpoch).TotalMilliseconds;
valueString = Convert.ToDateTime(iv).ToString();
valueJson = JsonSerializer.Serialize(iv);
break;
case "Single":
case "Double":
value = Convert.ToDouble(iv);
valueString = Convert.ToDouble(iv).ToString();
valueJson = JsonSerializer.Serialize(iv);
break;
case "Int64":
value = Convert.ToDouble(iv);
valueString = Convert.ToInt64(iv).ToString();
valueJson = JsonSerializer.Serialize(iv);
break;
case "UInt64":
value = Convert.ToDouble(iv);
valueString = Convert.ToUInt64(iv).ToString();
valueJson = JsonSerializer.Serialize(iv);
break;
case "Int32":
value = Convert.ToDouble(iv);
valueString = Convert.ToInt32(iv).ToString();
valueJson = JsonSerializer.Serialize(iv);
break;
case "UInt32":
value = Convert.ToDouble(iv);
valueString = Convert.ToUInt32(iv).ToString();
valueJson = JsonSerializer.Serialize(iv);
break;
case "Int16":
value = Convert.ToDouble(iv);
valueString = Convert.ToInt16(iv).ToString();
valueJson = JsonSerializer.Serialize(iv);
break;
case "UInt16":
value = Convert.ToDouble(iv);
valueString = Convert.ToUInt16(iv).ToString();
valueJson = JsonSerializer.Serialize(iv);
break;
default:
value = Convert.ToDouble(iv);
valueJson = JsonSerializer.Serialize(iv);
valueString = valueJson;
break;
}
}
catch
{
value = 0;
quality = false;
Log(iv.GetType().Name);
}
}

public static void BrowseServer(ref TsCDaServer daServer, OpcItem item, ref List<TsCDaItem> itemsForGroup, ref List<string> topics, ref OPCDA_connection srv)
{
TsCDaBrowsePosition position = null;
TsCDaBrowseFilters filters = new TsCDaBrowseFilters();
filters.BrowseFilter = TsCDaBrowseFilter.All;

TsCDaBrowseElement[] elements = daServer.Browse(item, filters, out position);
Console.WriteLine(position);

if (elements != null)
{
do
{
foreach (TsCDaBrowseElement elem in elements)
{
Console.WriteLine(elem.ItemName, elem.GetType().ToString());
item = new OpcItem(elem.ItemPath, elem.ItemName);
if (elem.GetType() == typeof(TsCDaBrowseElement) && elem.HasChildren && (topics.Count == 0 || topics.Contains(elem.Name)))
{
BrowseServer(ref daServer, item, ref itemsForGroup, ref topics, ref srv);
}

if (!elem.HasChildren)
{
Console.WriteLine("Add item to group - " + elem.ItemName);

var it = new TsCDaItem(item);
HandleCnt++;
it.ClientHandle = HandleCnt;
srv.MapHandlerToItemName[it.ClientHandle.ToString()] = it.ItemName;
srv.MapHandlerToConnName[it.ClientHandle.ToString()] = daServer.ClientName;

// MapNameToHandler[it.ItemName] = it.ClientHandle.ToString();
itemsForGroup.Add(it);
}
}
if (position != null)
{
elements = daServer.BrowseNext(ref position);
continue;
}
} while (position != null);
}
}
}
}
25 changes: 12 additions & 13 deletions src/opcdaaehda-client-solution-net/OPC-DA-Client/Common_srv_cli.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
using System.Net.Security;
using MongoDB.Driver;
using System.Security.Cryptography.X509Certificates;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Xml.Xsl;
using Technosoftware.DaAeHdaClient;
using Technosoftware.DaAeHdaClient.Da;

namespace OPCDAClientDriver
Expand All @@ -47,19 +44,15 @@ partial class MainClass
private static Mutex logMutex_ = new Mutex();
public static JSONSCADAConfig JSConfig = null;
public static protocolDriverInstancesClass DriverInstance = null;
public static string
ProtocolConnectionsCollectionName = "protocolConnections";
public static string
ProtocolDriverInstancesCollectionName = "protocolDriverInstances";
public static string ProtocolConnectionsCollectionName = "protocolConnections";
public static string ProtocolDriverInstancesCollectionName = "protocolDriverInstances";
public static string RealtimeDataCollectionName = "realtimeData";
public static string SoeDataCollectionName = "soeData";
public static string CommandsQueueCollectionName = "commandsQueue";
public static int ProtocolDriverInstanceNumber = 1;
public static string redundantIpAddress = "";
public static ConcurrentQueue<OPC_Value>
OPCDataQueue = new ConcurrentQueue<OPC_Value>(); // acquired values queue (to be updated in mongodb realtime data collection)
public static List<OPCUA_connection>
OPCUAconns = new List<OPCUA_connection>(); // list of RTU connections
public static ConcurrentQueue<OPC_Value> OPCDataQueue = new ConcurrentQueue<OPC_Value>(); // acquired values queue (to be updated in mongodb realtime data collection)
public static List<OPCDA_connection> OPCDAconns = new List<OPCDA_connection>(); // list of RTU connections

public class
JSONSCADAConfig // base configuration of the system (how to reach mongodb, etc.)
Expand All @@ -77,7 +70,7 @@ public class
}
[BsonIgnoreExtraElements]
public class
OPCUA_connection // protocol connection to RTU
OPCDA_connection // protocol connection to RTU
{
public ObjectId Id { get; set; }
[BsonDefaultValue("")]
Expand Down Expand Up @@ -116,7 +109,7 @@ public class
//public bool chainValidation { get; set; }
//[BsonDefaultValue("")]
//public string rootCertFilePath { get; set; }
[BsonDefaultValue("")]
[BsonDefaultValue("")]
public string localCertFilePath { get; set; }
[BsonDefaultValue("")]
public string peerCertFilePath { get; set; }
Expand All @@ -139,6 +132,12 @@ public class

public Double LastNewKeyCreated = -1;
public SortedSet<string> InsertedTags = new SortedSet<string>();
public SortedSet<string> InsertedAddresses = new SortedSet<string>();
// public static Dictionary<string, string> MapNameToHandler = new Dictionary<string, string>();
public Dictionary<string, string> MapHandlerToItemName = new Dictionary<string, string>();
public Dictionary<string, string> MapHandlerToConnName = new Dictionary<string, string>();
public Dictionary<string, string> MapItemNameToBranch = new Dictionary<string, string>();

public TsCDaServer connection = null;
public Thread thrOPCStack = null;
public int cntConnectRetries = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ await cursor
.protocolSourceConnectionNumber +
"...");
var found = false;
foreach (OPCUA_connection
foreach (OPCDA_connection
srv
in
OPCUAconns
OPCDAconns
)
{
if (
Expand Down
Loading

0 comments on commit 0cc1812

Please sign in to comment.