java—如何在milo opc ua中正确使用extensionobject和struct

kgsdhlau  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(744)

我想问一下,当我试图从opc ua服务器读取一些对象时,我应该如何正确地使用struct。我仔细研究了这个例子,我能够读取数据。
但现在我不知道如何正确地阅读它们。假设我正在读取一些数据结构,其中包含x和y值的两个数组。我试着这样做:

Float[] x = (Float[])struct.getMember("x").getValue()
 Float[] y = (Float[])struct.getMember("y").getValue()

但我收到异常“cannot cast'java.lang.object[]”to'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文件。要使某个类具有相同的命名asi,请使用“成员”和合适的类型,并执行以下操作:

OpcuaReader reader = ...
MyClass myClass = reader.read(struct, MyClass.class)

我可能完全错了,有人能建议我怎么解决这个问题吗?

r7s23pms

r7s23pms1#

非常感谢istibekesi,我们设法让它工作。对于有同样问题的人,你需要做的是:
1) 查找类型id
您需要找到要通过opc ua(例如uaexpert)读取的结构(对象)的数据类型的名称空间索引和标识符
如果您不确定它是哪种数据类型,只需找到一些表示此结构的变量,当您单击它时,您将在屏幕右侧看到数据类型信息。
2) 查找二进制编码\u id
要找到这个,您需要使用uaexpert搜索数据类型本身,它将是一些在类型/数据类型下。。。
当你找到它时,点击查看更多信息
然后在屏幕的右下角会出现“hasencoding | default binary”,您可以双击它
这样,您将收到名称空间索引和二进制编码的标识符
3) 遵循这个例子
要拥有milo的所有部分,您需要在依赖项中包含sdk客户机、字典阅读器、bsd解析器
创建类似于以下内容的类:

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()
        );
    }
zazmityj

zazmityj2#

首先,您不能像那样投射对象数组。相反,您可以使用流api来构造如下所示的浮点数:

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 然后重写你自己的解码方法。解码器还有一个内置的 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);
}

相关问题