Avatar

Please consider registering
guest

sp_LogInOut Log In sp_Registration Register

Register | Lost password?
Advanced Search

— Forum Scope —




— Match —





— Forum Options —





Minimum search word length is 3 characters - maximum search word length is 84 characters

sp_Feed Topic RSS sp_TopicIcon
Enumeration Type
February 2, 2012
13:53, EET
Avatar
fred
Member
Members
Forum Posts: 41
Member Since:
January 27, 2012
sp_UserOfflineSmall Offline

Hello Support Team,

In my project I need several new DataTypes for Enumerations. What is the correct way to create such type and integrate it in an event?

For instance, MyCurrentStateType with possible values “OK”,”FAILURE”,”FAULT”, “ERROR”

At the moment I tried to create a new class extending UaDataTypeNode and put in an enum implementing Enumeration. Is this the correct way?

Thanks for any help.

February 2, 2012
14:09, EET
Avatar
fred
Member
Members
Forum Posts: 41
Member Since:
January 27, 2012
sp_UserOfflineSmall Offline

I found the answer. Please delete this topic.

Thank you.

February 2, 2012
16:11, EET
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1010
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

fred said

I found the answer. Please delete this topic.

Thank you.

We can leave it here. If you wish you can document your findings, to help other users in future, if they find this topic.

February 3, 2012
7:21, EET
Avatar
fred
Member
Members
Forum Posts: 41
Member Since:
January 27, 2012
sp_UserOfflineSmall Offline

Well, you’re right. I thought I found the complete solution to my problem, but all I have now is my DataType shown as subtype of Enumeration.

What have I done?

1. Created a class MyCurrentStateType extending UaDataTypeNode
2. Created a LocalizedText[] enumStrings with my 4 possible values as written in first post
3. registerReflectiveInstanceProperty(“EnumStrings”, enumStringsId, Identifiers.Enumeration_EnumStrings);
4. Create Getter and Setter for Array.

Complete class:

public class MyCurrentStateTypeNode extends UaDataTypeNode {
private boolean typeNodesCreated = false;
private LocalizedText[] enumStrings = {
new LocalizedText("OK",Locale.ENGLISH)
, new LocalizedText("FAULT",Locale.ENGLISH)
, new LocalizedText("ERROR",Locale.ENGLISH)
, new LocalizedText("FAILURE",Locale.ENGLISH)
};

public MyCurrentStateTypeNode(NodeManagerUaNode nmun, NodeId nodeid, String string, Locale locale) throws StatusException {
super(nmun, nodeid, string, locale);
initialize();
}

public MyCurrentStateTypeNode(NodeManagerUaNode nmun, NodeId nodeid, QualifiedName qn, LocalizedText lt) throws StatusException {
super(nmun, nodeid, qn, lt);
initialize();
}

private void createTypes() throws StatusException {
if(typeNodesCreated == false) {
typeNodesCreated = true;

NodeId enumStringsId = new NodeId(getNodeManager().getNamespaceIndex(), getNodeManager().getNextDataTypeNodeId());
registerReflectiveInstanceProperty("EnumStrings", enumStringsId, Identifiers.Enumeration_EnumStrings);
}
}

private void initialize() throws StatusException {
if(typeNodesCreated == false) {
createTypes();
}
}

public LocalizedText[] getEnumStrings() {
return enumStrings;
}

public void setEnumStrings(LocalizedText[] enumStrings) {
this.enumStrings = enumStrings;
}
}

Question is now, how do I use this type as field in an event?

My Event looks like this:

public class MyEventType extends BaseEventType {
private final NodeId myEventTypeId;

//Event fields
private MyCurrentStateTypeNode myState;

public MyEventType(NodeManagerUaNode nmun) throws StatusException {
super(nmun);
myEventTypeId = new NodeId(getNodeManager().getNamespaceIndex(), getNodeManager().getNextTypeNodeId());
}

@Override
protected NodeId getDefaultTypeDefinition() {
return myEventTypeId;
}

@Override
protected void initEventFields() throws StatusException, SecurityException, NoSuchMethodException {
super.initEventFields();

NodeId myStateId = new NodeId(getNodeManager().getNamespaceIndex(), getNodeManager().getNextObjectNodeId());
registerReflectiveInstanceProperty("MyState", myStateId, getNodeManager().getMyCurrentStateType().getNodeId());
}

public MyCurrentStateTypeNode getMyStatus() {
return myState;
}

public void setMyStatus(MyCurrentStateTypeNode state) {
this.myState = state;
}
}

February 3, 2012
12:10, EET
Avatar
Otso Palonen
Espoo, Finland
Moderator
Moderators
Forum Posts: 32
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

It looks like your enumeration class is OK, but you must use Int32 instead of MyCurrentStateTypeNode as the property type in MyEventType. For enumeration data types the actual value of the node is Int32, but it has a special semantic meaning as described by the EnumStrings property in the type node.

February 7, 2012
9:21, EET
Avatar
fred
Member
Members
Forum Posts: 41
Member Since:
January 27, 2012
sp_UserOfflineSmall Offline

Otso said

It looks like your enumeration class is OK, but you must use Int32 instead of MyCurrentStateTypeNode as the property type in MyEventType. For enumeration data types the actual value of the node is Int32, but it has a special semantic meaning as described by the EnumStrings property in the type node.

Thank you Otso. Does this mean the following:

1. Create MyCurrentStateTypeNode with the EnumStrings
2. Create the type node (MyEventType) for browsing in the address space and add the node called MyState and use MyCurrentStateNode as its DataType

//MyState
final NodeId stateId = new NodeId(nsIdx, getNextVariableNodeId());
CacheProperty state = new CacheProperty(this, stateId , "MyState", Locale.ENGLISH);
state.setDataType(MyCurrentStateType);
state.setValue(new DataValue(new Variant(0)));
state.setValueRank(ValueRanks.Scalar);
state.setAccessLevel(AccessLevel.READONLY);
state.setUserAccessLevel(AccessLevel.READONLY);
myEventType.addProperty(state);

3. In MyEventType I change the MyState property type to be Int32.

NodeId myStateId = new NodeId(getNodeManager().getNamespaceIndex(), getNodeManager().getNextObjectNodeId());
registerReflectiveInstanceProperty("MyState", myStateId, Identifiers.Int32);

So, from server side I will only set the Int32 value, which corresponds to the entry in MyCurrentStateTypeNode. This means, that the client has to browse the data type itself to get the array of LocalizedText and to show the correct entry/state for my Int32 value.

Is this correct?

Thanks.

February 7, 2012
10:06, EET
Avatar
fred
Member
Members
Forum Posts: 41
Member Since:
January 27, 2012
sp_UserOfflineSmall Offline

I think I found the answer in the book OPC Unified Architecture (Mahnke, Leitner, Damm) on page 63/64.

February 7, 2012
12:31, EET
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1010
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

fred said

I think I found the answer in the book OPC Unified Architecture (Mahnke, Leitner, Damm) on page 63/64.

Yes it should be fine otherwise, except that when you define the property, you should use your enumeration type, even though the value is an Int32. This gives the hint to the client how the value should be interpreted.

registerReflectiveInstanceProperty("MyState", myStateId, MyCurrentStateType);
February 7, 2012
13:12, EET
Avatar
fred
Member
Members
Forum Posts: 41
Member Since:
January 27, 2012
sp_UserOfflineSmall Offline

Thank you

January 16, 2013
9:51, EET
Avatar
jscheib
New Member
Members
Forum Posts: 2
Member Since:
January 16, 2013
sp_UserOfflineSmall Offline

Hello.

First thanks fred for posting your solution.

I still have some problems. I want to create a custom enum type to use as argument in a method.

I created my EnumString class similar to yours:

public class StatusTypeNode extends UaDataTypeNode{

private NodeManagerUaNode nodeManager;
private NodeId nodeId;
private String displayName;
private LocalizedText[] enumStrings = {
new LocalizedText("Run", Locale.ENGLISH),
new LocalizedText("Stop", Locale.ENGLISH)
};

public StatusTypeNode(NodeManagerUaNode arg0, NodeId arg1, String arg2,
Locale arg3) throws StatusException {
super(arg0, arg1, arg2, arg3);
this.nodeManager = arg0;
this.nodeId = arg1;
this.displayName = arg2;
init();
}

private void init() throws StatusException {
NodeId enumStringsId = new NodeId(nodeManager.getNamespaceIndex(), displayName+"_enumStrings");
registerReflectiveInstanceProperty("EnumStrings", enumStringsId, Identifiers.EnumStrings);
}

public LocalizedText[] getEnumStrings() {
return enumStrings;
}

public void setEnumStrings(LocalizedText[] enumStrings) {
this.enumStrings = enumStrings;
}

}

My question is how do i create the “StatusTypeNode” as SubType from “Enumeration”? So i can use it as setDataType(StatusType);?
I tried to create i like this:

NodeId nodeId = new NodeId(KPIFolder.getNodeId().getNamespaceIndex(), "StatusType");
StatusTypeNode DataTypeNode = new StatusTypeNode(nodeManager, nodeId, "StatusType", Locale.ENGLISH);
DataTypeNode.setSuperType(LocalServer.getNodeManagerRoot().getType(Identifiers.Enumeration));

But it fails with:

Exception in thread "main" java.lang.ClassCastException: com.prosysopc.ua.server.nodes.CacheProperty cannot be cast to com.prosysopc.ua.nodes.UaType
at com.prosysopc.ua.server.nodes.UaVariableNode.setDataTypeId(Unknown Source)
at com.prosysopc.ua.server.nodes.BaseNode.registerReflectiveProperty(Unknown Source)
at com.prosysopc.ua.server.nodes.BaseNode.registerReflectiveInstanceProperty(Unknown Source)
at de.smartfactory.ua.AggregatedServer.StatusTypeNode.init(StatusTypeNode.java:34)

Thanks.

January 16, 2013
15:45, EET
Avatar
Jouni Aro
Moderator
Moderators
Forum Posts: 1010
Member Since:
December 21, 2011
sp_UserOfflineSmall Offline

I wrote a new article that explains how to create the enum type properly. Check

http://www.prosysopc.com/blog/…..-java-sdk/

January 17, 2013
13:31, EET
Avatar
jscheib
New Member
Members
Forum Posts: 2
Member Since:
January 16, 2013
sp_UserOfflineSmall Offline

Thanks for your help.

Forum Timezone: Europe/Helsinki

Most Users Ever Online: 518

Currently Online:
13 Guest(s)

Currently Browsing this Page:
1 Guest(s)

Top Posters:

hbrackel: 135

pramanj: 86

Francesco Zambon: 81

rocket science: 77

Ibrahim: 76

Sabari: 62

kapsl: 57

gjevremovic: 49

Xavier: 43

TimK: 41

Member Stats:

Guest Posters: 0

Members: 681

Moderators: 16

Admins: 1

Forum Stats:

Groups: 3

Forums: 15

Topics: 1467

Posts: 6261

Newest Members:

graciela2073, sagarchau, elviralangwell4, Donnavek, Eddiefauth, DonaldPooma, fidelduke938316, Jan-Pfizer, DavidROunc, fen.pang@woodside.com

Moderators: Jouni Aro: 1010, Otso Palonen: 32, Tuomas Hiltunen: 5, Pyry: 1, Petri: 0, Bjarne Boström: 983, Heikki Tahvanainen: 402, Jukka Asikainen: 1, moldzh08: 0, Jimmy Ni: 26, Teppo Uimonen: 21, Markus Johansson: 42, Niklas Nurminen: 0, Matti Siponen: 321, Lusetti: 0, Ari-Pekka Soikkeli: 5

Administrators: admin: 1