Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

custom structs and enum server side. missing doc or example #10

Closed
oroulet opened this issue Dec 24, 2024 · 5 comments
Closed

custom structs and enum server side. missing doc or example #10

oroulet opened this issue Dec 24, 2024 · 5 comments

Comments

@oroulet
Copy link
Member

oroulet commented Dec 24, 2024

I want to define a custom struct. With the rust opcua API I am very unsure how to do that.

I can define the struct like that

#[derive(
    Debug, Clone, PartialEq, Default, opcua::types::BinaryEncodable, opcua::types::BinaryDecodable,
)]
pub struct ST_ErrorData {
    sErrorMessage: opcua::types::UAString,
    nErrorID: u32,
    eLastState: E_Axis,
}

the enum like

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
pub enum E_Axis {
    Disabled = 1i32,
    Enabled = 2i32,
}

But then I need to register the struct so it appears under BaseDataType
/Structure and Opc binary. Is there an API to do that?
DynamicStructure seems to be made to read data client side and DynamicTypeLoader to load the structs. I want to register it....

@oroulet
Copy link
Member Author

oroulet commented Dec 25, 2024

ok maybe the DataTypeTree struct can be used... but that seem very very low level. Even I who wrote an ua stack at some point do not remember everything that must be done to create a custom struct..

@einarmo
Copy link
Contributor

einarmo commented Dec 26, 2024

There are a few separate things here. First, you need to add nodes to the actual node hierarchy somehow to represent the data type in the node hierarchy. That'll depend on your node manager, but it's the same as adding any other node. You'll need to manually define the DataTypeDefinition. There is currently no way to define that automatically, maybe we'll create that in the future...

No nice feature to do this easily, though we could create one for the address space I suppose. Typically if you're implementing a companion standard this will all be generated based on XML files like in the samples/custom-codegen example.

As for the data type itself, you need to create the data type as you've already done, but you also need to inform the server about it. This is done by creating a type implementing TypeLoader, then adding it to the server when you build it using add_type_loader on the server builder.

You can see a (generated) example for how to create a simple type loader here.

If this seems needlessly complex, recall that OPC-UA does not have any form of reflection, so we need to cleverly dynamically map from node IDs to functions. To make things even more complicated, namespace indexes may be different on different servers for the same namespace...

There may be ways to make doing this manually a bit less annoying.

@einarmo
Copy link
Contributor

einarmo commented Dec 26, 2024

As for enums, they are just numbers in OPC-UA. There's no derive macro for implementing BinaryEncodable and BinaryDecodable for enums, but it's generally pretty easy to do, just encode them as i32.

You still need to create the data type node.

@oroulet
Copy link
Member Author

oroulet commented Dec 29, 2024

I wrote a MR to document how to do such things. still WIP https://github.com/FreeOpcUa/rust-opcua/pull/11/files

@oroulet
Copy link
Member Author

oroulet commented Jan 8, 2025

and client code here: #15

so we are done

@oroulet oroulet closed this as completed Jan 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants