I'm using OPCSiemensDAAutomation dll with C# .NET to retrieve tag's value from OPC Server. I managed to retrieve the values using QueryAvailableProperties() and GetItemProperties(), but the objective is to retrieve 500k tags value per request.
I have tested with 100 tags and the code finished it in 45 seconds, with multi threading resulted in a small improvement of 30 seconds for 100 tags. It'll requires more than 4 hours to achieve the targeted tags volume with current speed. Is there any way that I can retrieve the tags value in bulk with better performance? Thanks.
var opcServer = new OPCSiemensDAAutomation.OPCServer();
opcServer.Connect("PCS7.OPCDAServer.1");
ConcurrentBag<DataRow> myBag = new ConcurrentBag<DataRow>(dt.AsEnumerable().ToList());
Parallel.ForEach(myBag, data =>
{
if (count <= num)
{
int cnt;
Array propertyIds, descriptions, dataTypes, errors, vals;
try
{
opcServer.QueryAvailableProperties(data[0].ToString(), out cnt, out propertyIds, out descriptions, out dataTypes);
opcServer.GetItemProperties(data[0].ToString(), cnt, propertyIds, out vals, out errors);
Tags tag = new Tags();
tag.Id = data[0].ToString();
tag.Value = vals.GetValue(2).ToString();
tags.Add(tag);
Interlocked.Increment(ref count);
}
catch
{ }
}
});
You can create OPC Groups:
OPCGroup myGroup = myServer.addGroup(groupName, isActive, isSubscribed, updateRate);
And then you can add tags to your group:
myGroup.OPCItems.AddItem("FullAddress", ClientHandle) //a unique number inside the group
The FullAddress
is composed of the OPCChannel name, the connection name and the complete address, ie: S7:[MyPLCName]DB1.dbx4
.
When you have the group fully populated, you can read all the variables at once.
int itemCount = myGroup.OPCItems.Count;
object qualities = null;
object timeStamps = null;
object errors = null;
int serverHandles[itemCount];
Array values = Array.CreateInstance(TypeOf(object), {itemCount },{1})
for (int i = 0; i < itemCount; i++){
serverHandles[i] = myGroup.OPCItems.Item(i + 1).ServerHandle;
values.SetValue("", i);
}
myGroup.SyncRead(OPCSiemensDAAutomation.OPCDataSource.OPCDevice, itemCount + 1, ServerHandles, values, errors, qualities, timeStamps);
Then you will have four new arrays related to the first one serverHandles
.
It is wise to check the qualities
array before using the data from the values
one.