[英]How to correctly work with ExtensionObject and Struct in milo opc ua
我想問一下當我試圖從 opc ua 服務器讀取一些對象時,我應該如何正確地使用 Struct。 我通過了這個例子,我能夠讀取數據。
但現在我不知道如何正確閱讀它們。 假設我正在讀取一些數據結構,包括 x 和 y 值的兩個數組。 我試圖做這樣的事情:
Float[] x = (Float[])struct.getMember("x").getValue()
Float[] y = (Float[])struct.getMember("y").getValue()
但我收到異常“無法將 '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++;
}
但我不認為這可能是對的。
無論如何,我想實現類似的東西,比如用 jackson 讀取 json 文件。 要擁有一些與“成員相同”的類,並且具有合適的類型,然后執行以下操作:
OpcuaReader reader = ...
MyClass myClass = reader.read(struct, MyClass.class)
我可能完全錯了,所以有人可以建議我應該如何解決這樣的問題嗎?
首先,你不能像這樣投射對象數組。 相反,您可以使用流 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);
關於 Milo 客戶端,在ReadWriteCustomDataTypeNodeExample 中有一個很好的讀取自定義數據類型的例子。
您可以創建自己的類似於CustomStructType
的類型並為自己覆蓋 decode 方法。 解碼器還有一個內置的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);
}
非常感謝istibekesi ,我們設法讓它工作。 對於在這里遇到同樣問題的人,您需要做的是:
1) 找到 TYPE_ID
2) 找到 BINARY_ENCODING_ID
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.