[英]How to correctly work with ExtensionObject and Struct in milo opc ua
I would like to ask how should I work correctly with Struct when I am trying to read some object from opc ua server.我想问一下当我试图从 opc ua 服务器读取一些对象时,我应该如何正确地使用 Struct。 I went trough this example and I was able to read the data.我通过了这个例子,我能够读取数据。
But right now I don't know how to correctly read them.但现在我不知道如何正确阅读它们。 Let's imagine I am reading some datastructure including two arrays for x and y values.假设我正在读取一些数据结构,包括 x 和 y 值的两个数组。 I tried to do something like this:我试图做这样的事情:
Float[] x = (Float[])struct.getMember("x").getValue()
Float[] y = (Float[])struct.getMember("y").getValue()
but I receive exception "Cannot cast 'java.lang.Object[]' to 'java.lang.Float[]'" I am able to do it this way:但我收到异常“无法将 'java.lang.Object[]' 转换为 'java.lang.Float[]'” 我可以这样做:
float[] x = new float[100];
int i = 0;
for(Object o: (Object[])struct.getMember("x").getValue()){
x[i] = (Float)o;
i++;
}
but I don't think this could be right.但我不认为这可能是对的。
Anyway I would like to achieve something similar like reading json file with jackson.无论如何,我想实现类似的东西,比如用 jackson 读取 json 文件。 To have some class with same naming asi the "members are and with suitable types and do something like:要拥有一些与“成员相同”的类,并且具有合适的类型,然后执行以下操作:
OpcuaReader reader = ...
MyClass myClass = reader.read(struct, MyClass.class)
I could be totally wrong so could anyone suggest me how should I solve such problem?我可能完全错了,所以有人可以建议我应该如何解决这样的问题吗?
First of all, you cannot cast array of objects like that.首先,你不能像这样投射对象数组。 Instead, you could use the stream API to construct Floats like this:相反,您可以使用流 API 来构造 Floats,如下所示:
Object[] objectArray = { 1.0f, 2.0f, 3, 4, 5 };
Float floatArray[] = Arrays.stream(objectArray)
.map(Object::toString)
.map(Float::valueOf)
.toArray(Float[]::new);
About the Milo client, there is a great example of reading custom data types in ReadWriteCustomDataTypeNodeExample .关于 Milo 客户端,在ReadWriteCustomDataTypeNodeExample 中有一个很好的读取自定义数据类型的例子。
You can create your own type similar to CustomStructType
and override the decode method for yourself.您可以创建自己的类似于CustomStructType
的类型并为自己覆盖 decode 方法。 The decoder also has a built in readFloatArray
method in hand:解码器还有一个内置的readFloatArray
方法:
@Override
public CustomStructType decode(
SerializationContext context,
UaDecoder decoder) throws UaSerializationException {
String foo = decoder.readString("Foo");
UInteger bar = decoder.readUInt32("Bar");
boolean baz = decoder.readBoolean("Baz");
Float[] floatArray = decoder.readFloatArray("floatArray");
return new CustomStructType(foo, bar, baz);
}
Big thanks to istibekesi , we manage to get it working.非常感谢istibekesi ,我们设法让它工作。 For someone who would have same problem here is what you need to do:对于在这里遇到同样问题的人,您需要做的是:
1) Find the TYPE_ID 1) 找到 TYPE_ID
2) Find the BINARY_ENCODING_ID 2) 找到 BINARY_ENCODING_ID
3) Follow this example 3)按照这个例子
public class OpcuaCurve implements UaStructure {
public static final ExpandedNodeId TYPE_ID = ExpandedNodeId.parse("ns=3;s=DT_\"PrServo_typeRuntimeDriveDiagnosticsProcessValuesTrends\".\"hmiTrend\"");
public static final ExpandedNodeId BINARY_ENCODING_ID = ExpandedNodeId.parse("ns=3;s=TE_\"PrServo_typeRuntimeDriveDiagnosticsProcessValuesTrends\".\"hmiTrend\"");
private final Float[] torque;
private final Float[] speed;
public OpcuaCurve() {
this(null, null);
}
public OpcuaCurve(Float[] torque, Float[] speed) {
this.torque = torque;
this.speed = speed;
}
public Float[] getSpeed() {
return speed;
}
public Float[] getTorque() {
return torque;
}
@Override
public ExpandedNodeId getTypeId() {
return TYPE_ID;
}
@Override
public ExpandedNodeId getBinaryEncodingId() {
return BINARY_ENCODING_ID;
}
@Override
public ExpandedNodeId getXmlEncodingId() {
// XML encoding not supported
return ExpandedNodeId.NULL_VALUE;
}
public static class Codec extends GenericDataTypeCodec<OpcuaCurve> {
@Override
public Class<OpcuaCurve> getType() {
return OpcuaCurve.class;
}
@Override
public OpcuaCurve decode(
SerializationContext context,
UaDecoder decoder) throws UaSerializationException {
Float[] torqueArray = decoder.readFloatArray("motorTorque");
Float[] speedArray = decoder.readFloatArray("motorSpeed");
return new OpcuaCurve(torqueArray,speedArray);
}
@Override
public void encode(
SerializationContext context,
UaEncoder encoder, OpcuaCurve value) throws UaSerializationException {
encoder.writeFloatArray("motorTorque", value.torque);
encoder.writeFloatArray("motorTorque", value.speed);
}
}
}
private void registerCustomCodec(OpcUaClient client) {
NodeId binaryEncodingId = OpcuaCurve.BINARY_ENCODING_ID
.local(client.getNamespaceTable())
.orElseThrow(() -> new IllegalStateException("namespace not found"));
// Register codec with the client DataTypeManager instance
client.getDataTypeManager().registerCodec(
binaryEncodingId,
new OpcuaCurve.Codec().asBinaryCodec()
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.