Online Forums
Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.
Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.
Do not use the Contact page for technical issues.
- Forum
- Discussions
- QuickOPC-Classic in .NET
- Reading, Writing, Subscriptions, Property Access
- How to read all values in all branches.
How to read all values in all branches.
Not sure what you mean by "system data types". If you refer to output such as "System.Int32[]", then this is because the returned value is an array, and as such it does not have (in .NET) a pre-defined formatting to a string. In order to output the array value, you'd have to go through its elements and format the output string yourself. Similarly, there is no pre-defined formatting for certain other types as well. But the values are there, it's just a question of processing them further.
If you meant something different or need further help with it, let me know.
Please Log in or Create an account to join the conversation.
Wehn you have time to answer my question regarding the "types" of the returned values that would be great.
Thanks again.
Please Log in or Create an account to join the conversation.
Please Log in or Create an account to join the conversation.
My results are now exactly what I require.
Key: Data Type Examples.16 Bit Device.R Registers.WordArray Value: System.Int32[]
Key: Data Type Examples.16 Bit Device.R Registers.Boolean1 Value: False
Key: Data Type Examples.16 Bit Device.R Registers.Boolean2 Value: False
Key: Data Type Examples.16 Bit Device.R Registers.Long1 Value: 99391
Code:
int index = 0;
foreach (OpcLabs.EasyOpc.DataAccess.DAVtqResult tag in allTags)
{
ret += string.Format(
"Key: {0} Value: {1}\n",
itemIds.ToArray()[index++].ItemId,
tag.Vtq.Value.ToString()
);
}
Please Log in or Create an account to join the conversation.
With regard to key:value addressing the results by ItemId, this is something that you need to build "around" the method call. A suggested method would be to create a Dictionary, where the key is ItemID, and the value is an index into the array your are passing to ReadMultipleItems. It should be noted that the array returned by the method has the same precise order of elements (and therefore same element indices) as the input array. After the method returns, you can look up the ItemID in the dictionary, and then use the index to retrieve the DAVtqResult from the output array, at the position given by the index. It is not difficult to do; but if you do not manage to write it yourself, let me know and I will put together some example code for it.
Please Log in or Create an account to join the conversation.
Example:
Value: System.Int32[]
Value: False
Value: False
Value: 88016
Value: False
Value: 22482
Some return system data types. Is this because the item has no value?
Lastly I need to have the associated "DANodeElement.itemId " as a key to the value.
Example (key:value):
DANodeElement.itemId : DAVtqResult
Here is the relevant code:
string ret = null;
// itemId's is populated here
BrowseAndReadFromNode("");
OpcLabs.EasyOpc.DataAccess.DAVtqResult[] allTags =
opcClient.ReadMultipleItems(serverDescriptor, itemIds.ToArray())
;
foreach (OpcLabs.EasyOpc.DataAccess.DAVtqResult tag in allTags)
{
ret += string.Format("Value: {0}\n", tag.Vtq.Value.ToString());
}
The only way I see is to iterate over "itemId's" and read one at a time which could be an expensive operation?
Any help would be much appreciated.
Please Log in or Create an account to join the conversation.
"if you truly want to read many items, their ItemIds should be collected first, and then read using a single call."
The way to obtain better performance is to move the "read" out of the "foreach" loops, replace it by simply collecting the ItemIDs of items you want to read (into some data structure, such as List, Array or so), and then use a single call after the foreach loop to read them all in one go. You can do this on the innermost loops, or you can actually collect all ItemIds in first part of the algorithm, and then read them all in a single method call. The methods for reading multiple items are called ReadMultipleItems and ReadMultipleItemValues.
Please Log in or Create an account to join the conversation.
I have created a loop (3 levels deep) to return values like:
Data Type Examples._System._WriteOptimizationDutyCycle
Simulation Examples._System._WriteOptimizationDutyCycle
Simulation Examples._System._EnableDiagnostics
Simulation Examples.Functions.Ramp4
Simulation Examples.Functions.Sine3
Simulation Examples.Functions.Random1
The loop execution is VERY slow.
Here is the code:
string ret = null;
var nodeFilter = new OpcLabs.EasyOpc.DataAccess.DANodeFilter();
Dictionary<string, OpcLabs.EasyOpc.DataAccess.DANodeElement> nodeDictionary = opcClient.BrowseNodes("", server, "", nodeFilter);
foreach (OpcLabs.EasyOpc.DataAccess.DANodeElement nodeElement in nodeDictionary.Values)
{
if (nodeElement.IsLeaf)
{
object value = opcClient.ReadItemValue("", server, nodeElement.ItemId);
ret += value.ToString() + "\n";
}
else if (nodeElement.IsBranch)
{
Dictionary<string, OpcLabs.EasyOpc.DataAccess.DANodeElement> nodeDictionary2 = opcClient.BrowseNodes("", server, nodeElement.ItemId, nodeFilter);
foreach (OpcLabs.EasyOpc.DataAccess.DANodeElement nodeElement2 in nodeDictionary2.Values)
{
if (nodeElement2.IsLeaf)
{
object value = opcClient.ReadItemValue("", server, nodeElement2.ItemId);
ret += nodeElement2.ToString() + "\n";
}
else if (nodeElement2.IsBranch)
{
Dictionary<string, OpcLabs.EasyOpc.DataAccess.DANodeElement> nodeDictionary3 = opcClient.BrowseNodes("", server, nodeElement2.ItemId, nodeFilter);
foreach (OpcLabs.EasyOpc.DataAccess.DANodeElement nodeElement3 in nodeDictionary3.Values)
{
if (nodeElement3.IsLeaf)
{
object value = opcClient.ReadItemValue("", server, nodeElement3.ItemId);
ret += nodeElement3.ToString() + "\n";
}
else if (nodeElement3.IsBranch)
{
//ret += "branch\n";
}
}
}
}
}
This cannot be the best way? Any help would be much appreciated!
Please Log in or Create an account to join the conversation.
Under the installation folder of the product, navigate under ExamplesNet\CSharp\VS2008\Console\BrowseAndReadValues.
It is also here: www.opclabs.com/Support/Online...
You need to change the ProgId ("ServerClass" argument) to that of Kepware's server, of course.
The example is of course just an example - with some limitations because it has to be kept :imple. Beware that the "address space" can be large, and not all items may be readable without errors. Reading them one by one also isn't the best practice - if you truly want to read many items, their ItemIds should be collected first, and then read using a single call.
If this is not what you wanted, let me know.
Zbynek Zahradnik
Please Log in or Create an account to join the conversation.
Please Log in or Create an account to join the conversation.
- Forum
- Discussions
- QuickOPC-Classic in .NET
- Reading, Writing, Subscriptions, Property Access
- How to read all values in all branches.