23:20, EEST
June 21, 2017
HI Team,
We are working on evaluation of prosys opc java client for one of our requirement where we are able to find the node id and can capture the corresponding data changes as well. However there is additional requirement to find the associated data type along with the data. Is there any way to do retrieve that easily.
Please let me know if any more details required.
Regards
Bijesh
14:28, EEST
April 3, 2012
Hi,
Please read OPC UA Specification (v1.03) Part 3, specifically section 5.6.2 on the Variable NodeClass. Also please read the tutorials in the doc folder of the downloaded SDK package.
The DataType Attribute defines the data type for the Value Attribute. Similarly like you can Read the Value Attribute, you can Read the DataType Attribute, with UaClient.readAttribute(NodeId, UnsignedInteger for the attribute id). AttributeIds are defined in the specification, however easiest is the use the org.opcfoundation.ua.core.Attributes.DataType constant. The returned DataValue.getValue().getValue() is a NodeId that points to a DataType node under Types/DataTypes. Usually you compare the returned NodeId to org.opcfoundation.ua.core.Identifiers constants for the standard namespace.
If you have obtained the UaNode instance for the given node via UaClient.getAddressSpace().getNode() and you know it is a UaVariable, you can cast it and call UaVariable.getDataType() or UaVariable.getDataTypeId(). Note that you most likely want to know the ValueRank (and maybe ArrayDimensions) in order to determine is the Value a scalar or (multidimensional) array. These are also explained in the specification and in the javadocs of mentioned methods.
– Bjarne
23:15, EEST
June 21, 2017
Hi Bjarne,
Thanks for your response. The reference that we are looking tor is a the type of data that is getting transmitted by a particular node(String,Boolean, Integer,Double etc). Node id is known to use and when we do a read attribute its returning an node Id only.
Sample code:
NodeId node=new NodeId(2,”iTestSimulator.Device1″);
DataValue value = client.readAttribute(node, Attributes.DataType);
System.out.println(“value=”+value.getValue()+ “Value1=”+value1.getValue())
Sample Output:
value=i=24
Now I am not sure how I can compare and retrieve the actual value associated with it. YOu told you compare the returned NodeId to org.opcfoundation.ua.core.Identifiers constants for the standard namespace”” however not sure what does this mean. Can you please help to understand this a bit clearly. If possible few lines of sample code will be a great help.
Regards
Bijesh
12:24, EEST
June 21, 2017
13:35, EEST
April 3, 2012
Hi,
In OPC UA the Types are also nodes, therefore the DataType Attribute returns the NodeId for the corresponding DataType node. For the standard types, these NodeIds are constants defined by the specification. For spec version 1.03, they and links to the csv files can be found in Part 6 Annex A, however in practice you only need to use the Identifiers class as the constants have been codegenerated to it. Therefore you can do e.g.:
NodeId dataTypeId = (NodeId) dv.getValue().getValue();
if(Identifiers.Boolean.equals(dataTypeId)){
//the Value attributes are of type Boolean
}
If you want to display the data type nodeid e.g. in an UI you can read the DisplayName of it (to clarify, you would read using the dataTypeId in the above example)
– Bjarne
18:35, EEST
June 21, 2017
19:48, EEST
June 21, 2017
12:06, EEST
December 20, 2016
Hi,
I currently have a very related question: We will do some code generation for our use case and for this, I need to know the name and datatype of a UaVariable. I use this at the moment and in general it works great:
UaDataType dataType = (UaDataType) variable.getValueNode()
.getDataType();
Class javaClass = dataType.getJavaClass();
but if I now do have an array. javaClass.isArray() gives me false, also it is one. I guess for you codegeneration you already have code to detect that this has to be e.g. converted into Double[]. Are there already any convenience methods for this, or do i have to read ValueRank etc. all myself? and anyway the isArray should give true?!
lg Manu
13:24, EEST
April 3, 2012
Hi,
The UaDataType interface models the nodes in the Types/DataTypes folder. Each type there is a scalar type (even e.g. ByteString which has array-like semantics). The Class object returned by getJavaClass therefore gives the java type that matches the scalar type of OPC UA. There are no separate nodes for array types as it would make no sense as there can be e.g. 3-dimensional arrays (and also the dimension might not be fixed at all, see ValueRanks 0, -2, -3). Therefore the only way is to check the ValueRank Attribute of the node.
During runtime you could also check the the class of the Variant.getValue() (assuming non-null value), however note that gives the value as it is encoded (per spec Part 6) e.g. Enumerations are encoded as UA Int32 (java Integer), therefore you need the DataType to separate those from normal Int32 values.
The codegen is a (completely) separate program, so unfortunately there is no convenience methods for this case in the SDK. However in practice you can: for ValueRanks > 0 you just add equal number of dimensions to the base type. For the Any -2, OneOrMoreDimensions 0, ScalarOrOneDimension -3 ValueRanks, you could ignore them probably at the moment as I have not seen them used in actual models.
If I may ask, what are you trying to generate? (i.e. is there a feature that could be implemented to the codegen as a newer version of it will be in the upcoming 3.0)
– Bjarne
14:54, EEST
December 20, 2016
Hi Bjarne,
thanks for the reply – that helped me a lot.
Actually we are trying to get some interface to the OPC UA programs features, and for adding this to our tool, we need code generation. So it is not really related to your code generater.
Nevertheless, if you are working on a new version of the codegenerator, we found, that the generator is not very useful for us at the moment,because it doesn’t follow Objects which are not itself new types. E.g.
MyType
– FolderType
—– elem1
—– elem2
The codegeneator would produce in MyType a method public FolderType getFolderType(). But no possibility to now access elem1, … This makes it difficult to use, because everyhting must be put in an own new type.
16:28, EEST
April 3, 2012
Generating more than 1-level deep accessors is problematic.
One of the problems is that e.g. in the above example the FolderType InstanceDeclaration is backed by FolderType(Node/Impl). Code of that class obviously cannot change. This would mean the only place where the accessor code could go is MyType(Node/Impl) class. However this gives new problems and questions:
1. How deep should the search go?
2. How to make obivious that the accessor is for not one level deep? Probably would needed to be prefixed by something to avoid clashing names if same node is on more levels deep. The method names would end up quite long after 2 levels..
3. Should accessors be created also for those nodes that are part of the TypeDefinition of the InstanceDeclaration? FolderType does not have any subnodes, but many ObjectTypes do.
I would recommend that e.g. in the above example a new subtype of FolderType would be created, lets say AType, then you could do e.g. getAInstanceDeclrationName().getElem1(). This might work if the number of types is not large.
Most Users Ever Online: 1919
Currently Online:
17 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Heikki Tahvanainen: 402
hbrackel: 144
rocket science: 88
pramanj: 86
Francesco Zambon: 83
Ibrahim: 78
Sabari: 62
kapsl: 57
gjevremovic: 49
Xavier: 43
Member Stats:
Guest Posters: 0
Members: 730
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1529
Posts: 6471
Newest Members:
toneylapham544, rondawolinski7, Marypof5711, roycedelargie91, kourtneyquisenbe, ellis87832073466, zkxwilliemae, gabriellabachus, Deakin, KTP25ZofModerators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1032, Jimmy Ni: 26, Matti Siponen: 349, Lusetti: 0
Administrators: admin: 1