Eclipse Milo: Как вызвать метод, который принимает в качестве аргумента customDataType? - PullRequest
0 голосов
/ 20 ноября 2018

CustomDataType метод требует:

<UADataType NodeId="ns=1;i=3010" BrowseName="1:ScanSettings">
<DisplayName>ScanSettings</DisplayName>
<References>
<Reference ReferenceType="HasEncoding">ns=1;i=5015</Reference>
<Reference ReferenceType="HasEncoding">ns=1;i=5016</Reference>
<Reference ReferenceType="HasSubtype" IsForward="false">i=22</Reference>
</References>
<Definition Name="1:ScanSettings">
<Field DataType="Duration" Name="Duration"/>
<Field DataType="Int32" Name="Cycles"/>
<Field DataType="Boolean" Name="DataAvailable"/>
<Field IsOptional="true" DataType="LocationTypeEnumeration" Name="LocationType"/>
</Definition>
</UADataType>

MethodCall:

CallMethodRequest tCallMethodRequest = new CallMethodRequest(tObjectId, tMethodId, new Variant[]{});
CallMethodResult tCallMethodResult = pOpcUaClient.call(tCallMethodRequest).get();
System.out.println(tCallMethodResult.getStatusCode());

Как вызвать метод, который требует ScanSettings?Нужно ли передавать массив Variant с тремя вариантами, содержащими Duration, Cycles и DataAvailable?

или

мне нужно сделать что-то вроде this ?

РЕДАКТИРОВАТЬ:

Попробовал с помощью класса ScanSettings и получил ошибку:

10:08:52.655 [ua-shared-pool-2] WARN org.eclipse.milo.opcua.stack.core.serialization.OpcUaBinaryStreamEncoder - Not a built-in type: class ScanSettings

Мой класс ScanSettings:

public class ScanSettings {

private final double duration;
private final int cycles;
private final boolean dataAvailable;

public ScanSettings() {
    this(1000.0, 1, true);
}

public ScanSettings(double pDuration, int pCycles, boolean pDataAvailable) {
    duration = pDuration;
    cycles = pCycles;
    dataAvailable = pDataAvailable;
}

public double getDuration() {
    return duration;
}

public int getCycles() {
    return cycles;
}

public boolean isDataAvailable() {
    return dataAvailable;
}

@Override
public int hashCode() {
    return Objects.hashCode(duration);
}

@Override
public boolean equals(final Object obj) {
    return super.equals(obj);
}

@Override
public String toString() {
    return duration + " " + cycles + " " + dataAvailable;
}

public static class Codec extends GenericDataTypeCodec<ScanSettings> {

    @Override
    public Class<ScanSettings> getType() {
        return ScanSettings.class;
    }

    @Override
    public ScanSettings decode(final SerializationContext context, final UaDecoder reader) throws UaSerializationException {
        double tDuration = reader.readDouble("Duration");
        int tCycle = reader.readInt32("Cycle");
        boolean tDataAvalible = reader.readBoolean("DataAvailable");

        return new ScanSettings(tDuration, tCycle, tDataAvalible);
    }

    @Override
    public void encode(final SerializationContext context, final ScanSettings pScanSettings, final UaEncoder writer) throws UaSerializationException {
        writer.writeDouble("Duration", pScanSettings.duration);
        writer.writeInt32("Cycle", pScanSettings.cycles);
        writer.writeBoolean("DataAvailable", pScanSettings.dataAvailable);
    }
}

}

Регистрация с:

OpcUaBinaryDataTypeDictionary tOpcUaBinaryDataTypeDictionary = new OpcUaBinaryDataTypeDictionary("urn:ScanSettings");

            NodeId binaryEncodingId = new NodeId(2, "DataType.ScanSettings.BinaryEncoding");

            tOpcUaBinaryDataTypeDictionary.registerStructCodec(new ScanSettings.Codec().asBinaryCodec(), "ScanSettings", binaryEncodingId);

            OpcUaDataTypeManager.getInstance().registerTypeDictionary(tOpcUaBinaryDataTypeDictionary);

1 Ответ

0 голосов
/ 13 декабря 2018

Я думаю, потому что сейчас нет поддержки генерации кода, лучше всего воспользоваться тем, что клиент уже знает, как читать словари типов данных и превращать их в универсальные объекты Struct, а также получать эти объекты Struct.и закодировать их при необходимости.

Ваш вызов метода будет выглядеть примерно так:

Struct scanSettings = Struct.builder("ScanSettings")
    .addMember("LocationTypeSpecified", 0)
    .addMember("Reserved1", 0)
    .addMember("Duration", 3.14)
    .addMember("Cycles", 1)
    .addMember("DataAvailable", false)
    .build();

ExtensionObject xo = ExtensionObject.encodeAsByteString(
    scanSettings,
    new NodeId(1, 3010),
    client.getDataTypeManager()
);

CallMethodRequest request = new CallMethodRequest(
    objectId,
    methodId,
    new Variant[]{new Variant(xo)}
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...