15:22, EET
March 26, 2014
Hi,
I’m using SDK 4 and I would like to create my own type of Alarm but also to use your implementation of the optionnal Shelve treatment (ShelvedStateMachineTypeNode). This is working fine but now I need to extend your implementation of some methods in ShelvedStateMachineTypeNode and I don’t know how to proceed.
I’ve seen that I can set a static implementation of the method but then I won’t be able to use your implementation. And I don’t see how I could tell the SDK to use my extension of ShelvedStateMachineTypeNode…
Thank you 🙂
17:47, EET
April 3, 2012
Hi,
Good Question…
(Sorry for the long post)
Assuming I understood you correctly, the answer depends a bit on does your Alarm type actually enhance the statemachine (information-model-wise) or do you just which to do something to our existing implementation. Because if you model your alarm you could override the ShelvingState InstanceDeclaration to a subtype of ShelvingStateMachineType, and then when you codegenerate you would get a XXXTypeNode for that (which would then extend our implementation).
If modeling is not the option, alternatively maybe you could do that via a listener like MyMethodManagerListener in the SampleConsoleServer?
As a last resort assuming you would want do the following (so that the “PING!” would show up in logs, just as an example), you could do:
@TypeDefinitionId("nsu=http://opcfoundation.org/UA/;i=2929") // IMPORTANT! this must be like this public class MyShelvedStateMachineTypeNode extends ShelvedStateMachineTypeNode { private static final Logger logger = LoggerFactory.getLogger(MyShelvedStateMachineTypeNode.class); protected MyShelvedStateMachineTypeNode(NodeManagerUaNode nodeManager, NodeId nodeId, QualifiedName browseName, LocalizedText displayName) { super(nodeManager, nodeId, browseName, displayName); } @Override protected void onTimedShelve(ServiceContext serviceContext, Double shelvingTime) throws StatusException { super.onTimedShelve(serviceContext, shelvingTime); logger.info("PING!"); } }
And then do the following (tested within MyNodeManager of the SampleConsoleServer example):
private void createMyOwnAlarm() throws Exception { // Configuration for NodeBuilder as we need Optional nodes TypeDefinitionBasedNodeBuilderConfiguration.Builder conf = TypeDefinitionBasedNodeBuilderConfiguration.builder(); conf.addOptional(UaQualifiedName.standard(ShelvedStateMachineType.LAST_TRANSITION)); conf.addOptional(UaQualifiedName.standard(AlarmConditionType.SHELVING_STATE)); // Override TypeDefinition linking of the class getServer().getRegisteredClasses().registerClass(MyShelvedStateMachineTypeNode.class); NodeBuilder nb = createNodeBuilder(AlarmConditionTypeNode.class, conf.build()); nb.setName("INSTANCE"); AlarmConditionTypeNode node = nb.build(); // Return TypeDefinition linking back to the original one getServer().getRegisteredClasses().registerClass(ShelvedStateMachineTypeNode.class); // Link the instance somewhere to the existing address space (just an example) getNodeManagerTable().getNodeManagerRoot().getObjectsFolder().addReference(node, ReferenceTypeIdentifiers.Organizes, false); }
.. and it should work. However note that it is a bit hacky solution, since the registered classes (from codegen) are not really designed for re-registering, thus we output warnings from that as typically that would be an error. Preferably we should find a better solution, but that should work in the meantime.
Let me know if that helped.
P.S. Generally we don’t yet have a “best way” to implement stuff to generated classes. Current ones are sort of best-effort solutions. The problem is that the subtyping only works of the leaf (UA) types (e.g. your MyXXX cannot be intersected to the inheritance tree after it is done), therefore it works only in some cases (e.g. here). The generated XXXTypeNode classes are designed that the method implementation could be put there, however as seen here they are then pretty much locked up (unless you buy the source edition). The static setters were added to help with this, however they would only work here if the SDK’s internal implementation would use them (which they normally don’t; but if yes you could delegate them), so mainly for the Standard model they could be used to implement a Method we have not yet implemented or completely override an implementation. Let’s see if we can make this better in the future.
Most Users Ever Online: 1919
Currently Online:
22 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: 735
Moderators: 7
Admins: 1
Forum Stats:
Groups: 3
Forums: 15
Topics: 1524
Posts: 6450
Newest Members:
kristiewinkle8, rust, christamcdowall, redaahern07571, nigelbdhmp, travistimmons, AnnelCib, dalenegettinger, howardkennerley, ThomassnismModerators: Jouni Aro: 1026, Pyry: 1, Petri: 0, Bjarne Boström: 1026, Jimmy Ni: 26, Matti Siponen: 346, Lusetti: 0
Administrators: admin: 1