Saturday, March 28, 2009

Retrieving tag information with Kepware & C# using asynchronous callbacks

 

In my previous post I managed to retrieve information out of production machines using the Kepware EX OPC server. In this post I’ll make a slightly more dynamic retrieval of the data. I will create again a retrieval for two tags, but the application should be “warned” whenever the tag value changes.

 

class Tester
{
private Opc.Da.Server m_server = null;
private Opc.Da.Subscription m_subscription = null;
private Opc.Da.SubscriptionState m_state = null;
private Opc.Da.Item[] m_items = null;

public void Initialize()
{
Opc.URL m_url = new Opc.URL("opcda://localhost/KEPware.KEPServerEx.V4");
m_server = new Opc.Da.Server(new OpcCom.Factory(), m_url) ;
try
{
if (m_server != null)
m_server.Connect();
}
catch (Opc.ConnectFailedException connectionFailure)
{
Console.WriteLine("Connection failure : " + connectionFailure.Message);
}
Console.WriteLine(String.Format("Connection with {0} successfull", m_server.Name));
}

public void QueryUsingDataChangedCallback()
{
m_state = new Opc.Da.SubscriptionState();
m_state.Name = "Data collector";
m_state.ServerHandle = null;
m_state.ClientHandle = Guid.NewGuid().ToString();
m_state.Active = true;
m_state.UpdateRate = 250; // Query every 250 ms
m_state.Deadband = 0;
m_state.Locale = null;

m_subscription = (Opc.Da.Subscription)m_server.CreateSubscription(m_state);
// Create room to observe 2 tags ...
m_items = new Item[2];
Opc.Da.Item m_item = new Item();
m_item.ClientHandle = Guid.NewGuid().ToString();
m_item.Active = true;
m_item.ItemName = "Channel_0_User_Defined.Ramp.Ramp4";
m_item.ItemPath = "";
m_item.ServerHandle = m_state.ClientHandle;
m_items[0] = m_item;
m_item = new Item();
m_item.ClientHandle = Guid.NewGuid().ToString();
m_item.Active = true;
m_item.ItemName = "Channel_1.Device_1.Tag_1";
m_item.ItemPath = "";
m_item.ServerHandle = m_state.ClientHandle;
m_items[1] = m_item; //Insert item
m_items = m_subscription.AddItems(m_items);
// Set the async callback event listener
m_subscription.DataChanged += new Opc.Da.DataChangedEventHandler(OnDataChange);
}


//DataChange event
public void OnDataChange(object subscriptionHandle, object requestHandle, ItemValueResult[] values)
{
foreach (ItemValueResult item in values)
{
Console.WriteLine("The observed data has changed ...");
Console.WriteLine("Item : {0} \nValue : {1}", item.ItemName, item.Value);
Console.WriteLine("Quality: {0}\nTime (HH:MM:SS mmmm) : {1}", item.Quality, item.Timestamp.ToString("HH:mm:ss ffff"));
}
}

static void Main(string[] args)
{
Tester tst = new Tester();
tst.Initialize();
tst.QueryUsingDataChangedCallback();
Console.ReadLine();
}
}
}


The QueryUsingDataChangeCallback method creates the tag group (subscription) and then creates the event handler to listen whenever values have changed. When ever the event occurs some message is printed.



KepwareCallbackOutput



Besites the milisecond time that’s a bit weird, the output shows that the tag values are observed and changes are shown. If we imagine that a some event control would be bound to this changes, we could create a windows WPF or Silverlight application that shows warning messages on to a display. Although that the code would fit for some major refactoring, I would like to dig in first to decouple this application from any other listening application or module. A tool that I assume can help me with the decoupling is the open source ESB nServiceBus. In a very schematic view it is shown in the next picture:



PublishSubscribeESB



Our previously build application would be re-factured to a messaging endpoint that publishes any tag value changes onto the service bus. All other clients that are interested in the information subscribe to the message and retreive the information from the service bus.

1 comment:

  1. Dear Sir/madam,

    May I know which dll you have used to implement OPC Client..

    I have used opcdaauto.dll..its working fine and it is notifying only 5 changes in tag values.Further changes ,it is not intimating..

    let me know

    my mail id :
    revanayya.h@aplusintellitech.com

    ReplyDelete