Closed MuckersMate closed 7 years ago
To ensure the problem isn't with the method of debugging, have you tried having them write to a file instead of pausing the debugger? Each subscription is on a separate thread I believe. You might not be able to see the change after pausing the debugger
That's what I thought - I've experienced such behaviour in the past, so I built the executable and ran it outside the IDE, but it did exactly the same.
It may be worth while mentioning that I'm (unsurprisingly) building an OPC client that can access an OPC server using both DA and UA. The UA works lovely, the DA doesn't.
I'll give the file method a go...
So are you not using the H-Opc library?
Nothing relating to that tag is written to the file....
Yes, I am - I'm using the DA and UAClient
Btw, the tags that are not picking up a broadcast change, these OpcDa.Items can still write to the PLC (and even then they do not pick up on the datachange). If there are no rapidly updating tags AFTER them in the subscription list, they receive the datachange fine...
No I don't think #20 is related. I'm calling the AddItem as follows (note I'm using "object" between "_client.AddTag" and before "(groupHandle, tagHandle," (which for some reason is being stripped from my comment(?))....
`var result = _client.AddTag
(opcValue, groupID, tagID, goodQuality, stop) =>
{
long t = -1;
if (tagID != null)
{
t = (long)tagID;
}
if (StopMonitoring)
try
{
stop();
}
catch (Exception ex)
{
}
else
{
DoChange((long)groupID, tagID != null ? (long)tagID : -1, goodQuality, opcValue);
}
}`
The opcValue is being sent back to whatever client asked the class to add the tag to a subscription. And besides, the adding of the tag (whose value is fast changing) on its own is fine - it's when it is added in a group of other tags that the earlier added tags IMMEDIATELY stop receiving any datachange. If you add another tag AFTER the fast changing tag, the new tag behaves fine, with it and the fast changing tag receiving datachange events.
_client.AddTag is not part of h-opc. Are you creating a client from scratch?
No, I'm not. "AddTag" uses h-opc. "AddItem"...
For my purpose, it's important that the the DA/UA wrapper returns the tag handle, not the tag (which AddItem does)
Here's my code for AddTag..
public T AddTag<T>(long subscriptionHandle, long clientHandle, string tagName, Action<T, T, T, bool, Action> callback)
{
Opc.Da.Item tag = (Opc.Da.Item)((object)AddItem<T>(subscriptionHandle, clientHandle, tagName, callback));
return (T)tag.ClientHandle;
}
For multiline codeuse three of these: `
I modified your TestApplication to suit our purposes - i.e. a client that can accept OPC operations on either a DA or UA access type, without the consumers being aware of the Access type used. The implementation uses either a DA or UAClient, depending upon supplied Connect() parameters.
The AddItem
function is part of the Opc Foundation UA libraries
which is utilized by OPC. The equivalent function for DA is AddItems
I modified the IClient interface to expose the AddTag function. I then added this function to the DAClient and UAClient classes, with each calling their AddItem function.
The AddItem function is from the OPC UA library though
Yes, I'm using the same method as your test app is doing - choosing to use either the DAClient or UAClient class. This wrapper class also exposes a COM interface so it can be used by a VB6 DLL.
What is the test app? h-opc-cli or the unit test project
https://gitter.im/H-Opc Let's continue this here
[Test]
public void DaTestMonitorChangesAfterFastChanging()
{
var slowTag = "storage.numeric.reg01";
var fastTag = "numeric.sin.double";
var i = 0;
var j = 0;
// initialize it with value 0
_client.Write(slowTag, 0);
Thread.Sleep(100);
_client.Monitor<double>(slowTag, (newValue, unsub) =>
{
i++;
});
Thread.Sleep(100);
_client.Write(slowTag, 1);
Thread.Sleep(100);
_client.Monitor<double>(fastTag, (newValue, unsub) =>
{
j++;
});
System.Threading.SpinWait.SpinUntil(() => j >= 10, 2000);
_client.Write(slowTag, 0);
System.Threading.SpinWait.SpinUntil(() => i == 3, 1000);
Assert.AreEqual(3, i);
}
This test passes. Could not reproduce.
I have a situation where I have two tags, the latter is fast changing.
The client "sees" the change of the rapidly updating tag, but any change to the earlier added tag is not being broadcast (or sometimes only rarely) by the Subscription.
If I reverse the order in which the tags are added, changes in both tags are reported as expected.
Here is my code:
If I place a breakpoint inside the anonymous DataChange method, it is NOT called whenever the earlier (i.e. not the rapidly changing) tag is changed. It's almost as if quickly changing tag overrides the other tag's notification. This is not restricted to just two tags - whenever I have a group of tags followed by a rapidly changing one, these tags do not broadcast datachange events.