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
- Get Data Type methods
Get Data Type methods
There is now a new build (5.21.175.1) available from the public download area. It contains an optimization for GetMultiplePropertyValues with OPC-DA Version 3.0. I hope it helps.
Best regards
Please Log in or Create an account to join the conversation.
// This example shows how to obtain data types of leaves in the OPC-DA address
// space by browsing and filtering, i.e. without the use of OPC properties.
// This technique allows determining the data types with servers that only
// support OPC-DA 1.0. It can also be more effective than the use of
// GetMultiplePropertyValues, if there is large number of leaves, and
// relatively small number of data types to be checked.
using System;
using System.Collections.Generic;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
namespace DocExamples
{
namespace _EasyDAClient
{
/*partial*/ class BrowseNodes
{
public static void DataTypes()
{
var easyDAClient = new EasyDAClient();
// Define the list of data types we will be checking for.
// Change as needed for your application.
// This technique is only usable if there is a known list of
// data types you are interested in. If you are interested in
// all leaves, even those that are of data types not explicitly
// listed, always include VarType.Empty as the first data type.
// The leaves of "unlisted" data types will have VarType.Empty
// associated with them.
var dataTypes = new VarType[] { VarType.Empty, VarType.I2, VarType.R4 };
// For each leaf found, this dictionary wil hold its associated data type.
var dataTypeDictionary = new Dictionary<DANodeElement, VarType>();
// For each data type, browse for leaves of this data type.
foreach (VarType dataType in dataTypes)
{
var nodeFilter = new DANodeFilter(DABrowseFilter.Leaves, "", "", dataType);
DANodeElementCollection nodeElements =
easyDAClient.BrowseNodes("", "OPCLabs.KitServer.2", "Greenhouse", nodeFilter);
// Store the leaf information into the dictionary, and
// associate the current data type with it.
foreach (var nodeElement in nodeElements)
dataTypeDictionary[nodeElement] = dataType;
}
// Display each leaf found, and its associated data type.
foreach (KeyValuePair<DANodeElement, VarType> pair in dataTypeDictionary)
{
DANodeElement nodeElement = pair.Key;
VarType dataType = pair.Value;
Console.WriteLine("{0}: {1}", nodeElement, dataType);
}
}
}
}
}
Please Log in or Create an account to join the conversation.
Please Log in or Create an account to join the conversation.
What you say got me thinking, and I have closely examined the code inside. The behavior is as follows:
1) We check if OPC-DA 3.0 is supported by the server. If so, we use the OPC-DA 3.0 interface to obtain the properties. The OPC-DA 3.0 allows properties from multiple items be collected using one call, which should be faster. Unfortunately, it appears that our current implementation still calls it per each item individually. This looks like something that we can fix.
2) If OPC-DA 3.0 is not supported, we use the OPC-DA 2.0 method for obtaining properties. In this case, we HAVE to go item by item, it is dictated by the OPC interface, so no performance gains can be achieved here.
3) If only OPC-DA 1.0 is supported, it is an error, as OPC-DA 1.0 does not have a concept of properties.
It is likely that your code is just fine. What I need to know at this moment is whether the OPC server supports OPC-DA 2.0, OPC-DA 3.0, or both. Can you find this out? Which server is it? Note that we also have this information available from the browsing methods and dialogs.
If you find that OPC-DA 3.0 is supported, we will make a code change inside the component to allow properties for multiple items be truly obtained at once, hoping for better performance, although the precise effect will depend on circumstances.
If you find that OPC-DA 3.0 is not supported, then there is no way to make obtainining the properties faster. As I wrote earlier, they were not intended for fast access, that is an intentional design decision of the OPC spec. But, I am thinking of one possible "trick" that can be tried in this case: If you just need the data type, then you cxan "indirectly" obtain via browsing, specifying a filter for a specific type. This might help if there are just a few specific datatypes that you need to work with. I can elaborate on this idea, but only after we know the OPC-DA specs that are provided by your server.
Best regards
Please Log in or Create an account to join the conversation.
Please Log in or Create an account to join the conversation.
The GetMultiplePropertyValues should work for any node directly.
The exception from browsing is not related to GetMultiplePropertyValues. It has to do with various versions of OPC specifications, and various level of support in OPC Server. The exception text tries to explain the situation:
Change browse position not feasible. This error occurs during browsing, if the OPC Server does not support OPC-DA 2.0 (OPC_BROWSE_TO value of dwBrowseDirection argument in IOPCBrowseServerAddressSpace::ChangeBrowsePosition) and the ItemID to browse into has not been previously encountered during browsing. If the OPC Server supports OPC-DA 2.0, this error means that the ItemID is invalid. If the OPC Server only supports OPC-DA 1.0, this is neither an error of the OPC Server nor the OPC Client, but rather an indication that in order to assure succesful browsing, the application code should start the browsing at the root and proceed gradually to subsequent levels. If the OPC Server only supports OPC-DA 3.0, the error indicates that the application should provide full ItemID instead of (or in addition to) the path sequence of branch ItemIDs.
This is quite lengthy text, in order to explain the complexity properly, but in short, in your case (when the ItemID is correct), it means that
- The OPC Server you are connecting to does not support really "random" browsing, starting from any node,
- but you can easily resolve it in your case, because in the original code you sent, you will be making a recursive browsing, starting from the root. This way, any node you browse into will already be a result of the previous call, and in this case, the error won't appear.
Please Log in or Create an account to join the conversation.
OpcLabs.EasyOpc.OpcException was unhandled
Message=OPC operation failure.
Source=OpcLabs.EasyOpcClassicRaw
ErrorCode=-1073442812
StackTrace:
at OpcLabs.EasyOpcRaw.DataAccess.RawEasyDAClient.CheckComResult(CHResult* hResult, IErrorInfo* pErrorInfo)
at OpcLabs.EasyOpcRaw.DataAccess.RawEasyDAClient.CheckComResult(CHResult* hResult)
at OpcLabs.EasyOpcRaw.DataAccess.RawEasyDAClient.BrowseNodes(ServerDescriptor serverDescriptor, NodeDescriptor parentNodeDescriptor, DANodeFilter nodeFilter)
at OpcLabs.EasyOpc.DataAccess.EasyDAClient.BrowseNodes(ServerDescriptor serverDescriptor, DANodeDescriptor parentNodeDescriptor, DANodeFilter nodeFilter)
at OpcLabs.EasyOpc.DataAccess.EasyDAClient.BrowseLeaves(ServerDescriptor serverDescriptor, DANodeDescriptor parentNodeDescriptor, String elementNameFilter, String vendorFilter)
at OpcLabs.EasyOpc.DataAccess.EasyDAClient.BrowseLeaves(ServerDescriptor serverDescriptor, DANodeDescriptor parentNodeDescriptor, String elementNameFilter)
at OpcLabs.EasyOpc.DataAccess.EasyDAClient.BrowseLeaves(ServerDescriptor serverDescriptor, DANodeDescriptor parentNodeDescriptor)
at ConsoleApplication3.Program.Main(String[] args) in F:\Visual Studio\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs:line 20
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Runtime.InteropServices.COMException
Message=Change browse position not feasible. This error occurs during browsing, if the OPC Server does not support OPC-DA 2.0 (OPC_BROWSE_TO value of dwBrowseDirection argument in IOPCBrowseServerAddressSpace::ChangeBrowsePosition) and the ItemID to browse into has not been previously encountered during browsing. If the OPC Server supports OPC-DA 2.0, this error means that the ItemID is invalid. If the OPC Server only supports OPC-DA 1.0, this is neither an error of the OPC Server nor the OPC Client, but rather an indication that in order to assure succesful browsing, the application code should start the browsing at the root and proceed gradually to subsequent levels. If the OPC Server only supports OPC-DA 3.0, the error indicates that the application should provide full ItemID instead of (or in addition to) the path sequence of branch ItemIDs.
Source=OpcLabs.EasyOpcRaw.DataAccess.RawEasyDAClient
ErrorCode=-1073442812
InnerException:
Please Log in or Create an account to join the conversation.
And, which OPC server are you connecting to? Is it a server from Rockwell?
Thank you
Please Log in or Create an account to join the conversation.
tags.tag1.int
tags.int
tags.float
tags.tag2.int
and use the code below with the parentnodedesc as "Tags" It will return the data typs for tags.int and tags.float but if I set the parentnodedesc as "tags.tag1" the program crashes likewise for "tags.tag2"
I have searched the class library but not finding anyway to go deeper than 1 branch
Please Log in or Create an account to join the conversation.
// This example shows how to obtain a data type of all OPC items under a branch.
using System;
using System.Linq;
using OpcLabs.BaseLib;
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
namespace DocExamples
{
namespace _EasyDAClient
{
class GetMultiplePropertyValues
{
public static void DataType()
{
var easyDAClient = new EasyDAClient();
ServerDescriptor serverDescriptor = "OPCLabs.KitServer.2";
// Browse for all leaves under the "Simulation" branch
DANodeElementCollection nodeElementCollection = easyDAClient.BrowseLeaves(serverDescriptor, "Simulation");
// Create list of property descriptors for the DataType property, one for each leaf obtained
DAPropertyDescriptor[] propertyDescriptorArray = nodeElementCollection
.Where(element => !element.IsHint) // filter out hint leafs that do not represent real OPC items (rare)
.Select(element => new DAPropertyDescriptor(element, DAPropertyId.DataType))
.ToArray();
// Get the value of DataType property; it is a 16-bit signed integer
ValueResult[] valueResultArray = easyDAClient.GetMultiplePropertyValues(serverDescriptor,
propertyDescriptorArray);
for (int i = 0; i < valueResultArray.Length; i++)
{
DAPropertyDescriptor propertyDescriptor = propertyDescriptorArray[i];
// Check if there has been an error getting the property value
ValueResult valueResult = valueResultArray[i];
if (valueResult.Exception != null)
{
Console.WriteLine("{0}: *** {1}", propertyDescriptor.ItemId, valueResult.Exception.Message);
continue;
}
// Convert the data type to VarType
var varType = (VarType)(short)valueResult.Value;
// Display the obtained data type
Console.WriteLine("{0}: {1}", propertyDescriptor.ItemId, varType);
}
}
}
}
}
Please Log in or Create an account to join the conversation.
- Forum
- Discussions
- QuickOPC-Classic in .NET
- Reading, Writing, Subscriptions, Property Access
- Get Data Type methods