apache/plc4x

[Bug]: OpcUA WORD Tag writing error

isAlreadyInUse opened this issue · 1 comments

What happened?

Trying to write a WORD plc variable it fails cause DATA TYPE NOT VALID

CASE 1 :

Using

PlcWriteRequest.Builder wbuilder1 = plcConnection.writeRequestBuilder();
wbuilder1.addTagAddress("value1", var12, 10);

when code goes in calss

OpcuaProtocolLogic

function

private Variant fromPlcValue(String tagName, OpcuaTag tag, PlcWriteRequest request) {
        PlcList valueObject;
        if (request.getPlcValue(tagName).getObject() instanceof ArrayList) {
            valueObject = (PlcList) request.getPlcValue(tagName);
        } else {
            ArrayList<PlcValue> list = new ArrayList<>();
            list.add(request.getPlcValue(tagName));
            valueObject = new PlcList(list);
        }

        List<PlcValue> plcValueList = valueObject.getList();
        PlcValueType dataType = tag.getPlcValueType();
        if (dataType.equals(PlcValueType.NULL)) {
            if (plcValueList.get(0).getObject() instanceof Boolean) {
                dataType = PlcValueType.BOOL;
            } else if (plcValueList.get(0).getObject() instanceof Byte) {
                dataType = PlcValueType.SINT;
            } else if (plcValueList.get(0).getObject() instanceof Short) {
                dataType = PlcValueType.INT;
            } else if (plcValueList.get(0).getObject() instanceof Integer) {
                dataType = PlcValueType.DINT; // ORIGINAL SOURCE CODE NOT WORKS
                dataType=PlcValueType.UINT; //ADDED MANUALLY BY ME AND IT WORKS
            } else if (plcValueList.get(0).getObject() instanceof Long) {
                dataType = PlcValueType.LINT;
            } else if (plcValueList.get(0).getObject() instanceof Float) {
                dataType = PlcValueType.REAL;
            } else if (plcValueList.get(0).getObject() instanceof Double) {
                dataType = PlcValueType.LREAL;
            } else if (plcValueList.get(0).getObject() instanceof String) {
                dataType = PlcValueType.STRING;
            }
        }
...

CASE 2 :

Using

PlcWriteRequest.Builder wbuilder1 = plcConnection.writeRequestBuilder();
PlcUINT plcValue = new PlcUINT(70);
wbuilder1.addTagAddress("value1", var12, plcValue);            

when execution arrive to class

PlcValueHandler

function

 public static PlcValue of(PlcTag tag, Object[] values) {
        if (values.length == 1) {
            
            Object value = values[0];
            
            if(tag.getPlcValueType() == null) {
                // TODO: This is a hacky shortcut ..
                if(value instanceof PlcValue) {
                    return (PlcValue) value;
                }
                return new PlcNull();
            }
           
            if (value instanceof PlcValue) {
                PlcValue plcValue = (PlcValue) value;
                if (plcValue.getPlcValueType() == tag.getPlcValueType()) {
                    return (PlcValue) value;
                } else {
                    throw new PlcRuntimeException("Expected PlcValue of type " + tag.getPlcValueType().name() + " but got " + plcValue.getPlcValueType().name());
                }
            }
...

PlcRuntimeException is throwed

org.apache.plc4x.java.api.exceptions.PlcRuntimeException: Expected PlcValue of type NULL but got UINT

if I baypass this check changing == to !=

if (value instanceof PlcValue) {
                PlcValue plcValue = (PlcValue) value;
                if (plcValue.getPlcValueType() != tag.getPlcValueType()) {
                    return (PlcValue) value;
                } else {
                    throw new PlcRuntimeException("Expected PlcValue of type " + tag.getPlcValueType().name() + " but got " + plcValue.getPlcValueType().name());
                }
            }

it works

Version

v0.11.0

Programming Languages

  • plc4j
  • plc4go
  • plc4c
  • plc4net

Protocols

  • AB-Ethernet
  • ADS /AMS
  • BACnet/IP
  • CANopen
  • DeltaV
  • DF1
  • EtherNet/IP
  • Firmata
  • KNXnet/IP
  • Modbus
  • OPC-UA
  • S7

Problem is solved using datatype parameter in tag address

ns=2;s=[variable name];UINT