该方法需要的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的方法? 我是否需要将包含持续时间,周期和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);
答案 0 :(得分:0)
我认为,因为现在没有代码生成支持,所以最好的办法是利用以下事实:客户端已经知道如何读取数据类型字典并将其转换为通用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)}
);