user3424002
user3424002

Reputation: 43

OPC dll - How to retrieve tags value in bulk

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
        { }
    }
});

Upvotes: 4

Views: 652

Answers (1)

Cleber Machado
Cleber Machado

Reputation: 316

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.

Upvotes: 1

Related Questions