Closed ChristophRuckstetter closed 3 years ago
At the moment, there are no specific attributes for interfaces, as in MachineTools, Interfaces are only used for TypeDefinitions, e.g. here, but it should work the same way. https://github.com/umati/Sample-Server/blob/7cd9a3f9a4ce04a52e930f147f0c84e0d1f9845f/TypeDefinition/MachineTool/MachineToolIdentification.hpp#L16
As for all acessable OPC UA Variable a C++ variable must be available, the State must use another type than ns0::BaseObject_t
(as this has no members).
E.g. (Unchecked, only as a demonstration)
struct IWWState_t {
BinableMember<ns0::StateVariable_t> CurrentState;
}
REFL_TYPE(
woodworking::IWWState_t ,
UmatiServerLib::attribute::UaObjectType(UmatiServerLib::constexp::NodeId(constants::NsWoodworkingUri, UA_WOODWORKINGID_IWWSTATE)))
REFL_FIELD(CurrentState)
Then this IWWState_t
should be fine for using in WwMachine_t
for State, if State is a mandatory member.
For optional members which ony use Interfaces, this will not work as expected because the instanciation will use the methods from open62541 to instanciate an object, which will result in an Object of the inteface type (without HasInterface Reference). In this case additional implementations are required.
In the Woodworking case the IWwStateType has two children of BaseObjectTypes, which a hasInterface Reference to another Type. And each of these BaseObjectTypes have again children of BaseObjectTypes with hasInterface references.
So I couldn't directly adapt your example.
I tried to implement the interface Types, and also dummy structs, that inherit from the interface types to use them. But i couldn't get it to work. Here is the complete code how i tried to implement the type definitions: https://github.com/ChristophRuckstetter/Sample-Server/commit/b695d3756fef241728931b62c58f656c3618389c
After investigation, I detected two issues:
I applied this patch (https://github.com/open62541/open62541/pull/4479) to my open62541 build and tried to bring up the State/Machine/Flags Object by defining the Flags as optional in the TypeDefinitions and calling InstantiateOptional() on Instantiation (https://github.com/ChristophRuckstetter/Sample-Server/commit/ab8187971669f5e5cc6f3bb6c1df727a61ff0633) .
This compiles fine, but on runtime it throws the following exception: "terminate called after throwing an instance of 'std::runtime_error' what(): Could not create optional node, Error: BadTypeDefinitionInvalid".
Is there something else that needs to be done to get the optional objects with hasinterface reference instantiated?
With #330 also in develop
On https://github.com/ccvca/Sample-Server/tree/ww_fix 9f9ac79f752b903421db5acc57a7fbfbc5a9be3a I fixed a bug, which causes the instanciation of abstract types. But I was not able to fully succeed in creating the optional Object, as I don't know a way to add the childs of that interface: https://github.com/ccvca/Sample-Server/blob/9f9ac79f752b903421db5acc57a7fbfbc5a9be3a/UmatiServerLib/Instantiation.cpp#L158
open62541/open62541#4479 only supports HasInterfaces on TypeDefinition, but in this case an Object of type BaseObjectType in created and the interfaces are added afterwards.
Optional children can also be added by implementing the optional child callback. Open62541 will then ask for every optional child if it should be added when an object is added to the server and adds it if the callback function returns true.
My pull request should also support HasInterface references on BaseObjectType objects, but in this case, the object creation must be done via the UA_Server_addNode_begin() and UA_Server_addNode_finish() functions.
@basyskom-jvoe I tried to create the object with UA_Server_addNode_begin() and UA_Server_addNode_finish() and the object was created properly with the HasInterface reference, but the mandatory children as defined by the interface type weren't created. I'm not sure if it should behave like that.
When I use UA_Server_addObjectNode (and the optional child callback returns true for the relevant object), the object is created properly with the HasInterface reference, and the mandatory children are also there.
I did an error on my side. With the UA_Server_addNode_begin() and UA_Server_addNode_finish() and the HasInterface reference it works just fine.
Hi,
we have a case where an Object should be of Type "BaseObjectType" and should have a HasInterface Reference to another type. What needs to be done in the TypeDefinition to achive this?
The concrete example currently looks this this. The State Object should have a HasInterface Reference to another Type