以UaExpert为客户端进行对照,下面的文章给出了对照表:OPC UA数据类型
在最近的项目中,我通过opcua的发布订阅的功能获取点位数值的变化,并在后续对其进行处理(如需要进行加减、以及true或false的判断)
客户端调试工具使用UaExpert,通过modbus发布点位,转储为opcua,类型为UInt16.
subscribeDataSet(OpcUaConstants.NAME_SPACE_INDEX, client, monitorOpenIdentifiers, (identifier, changedValue) -> {
System.out.println("检测modbus变化");
String modbusId = identifier;
Object modbusValue = changedValue;
});
Java中通过该回调函数接收点位id(String类型)和点位变化的值(Object类型)
若直接使用
int value = (int)modbusValue
进行强转,则会报如下的错误:
class org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort cannot be cast to class java.lang.Interger (org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort is in unnamed module of loader 'app'; java.lang.Interger is in module java.base of loader 'bootstrap')
由于Java中并不存在unsigned类型,无法以常规方式进行转换。
解决方案:
以UaExpert中的UInt16类型为例,它在milo库中的类型为UShort
进入UShort类查看,milo中的UShort类自带了很多转换为Java基本类型的方法
直接使用该方法就可以进行转换:
public void modbustest() {
String identifierTemp = "modbustest";
List<String> monitorOpenIdentifiers = new ArrayList<>();
monitorOpenIdentifiers.add(identifierTemp);
subscribeDataSet(OpcUaConstants.NAME_SPACE_INDEX, client, monitorOpenIdentifiers, (identifier, changedValue) -> {
System.out.println("检测modbus变化");
String modbusId = identifier;
Object modbusValue = changedValue;
//先确定类型
UShort tempValue = (UShort) modbusValue;
//intValue为Ushort类自带的方法
int intValue = tempValue.intValue();
System.out.println("modbusId:" + modbusId);
System.out.println("modbusValue:" + intValue);
});
}
在枚举类BuiltinDataType中,包含了milo库中所有的数据类型
同样的,在UInterger和ULong中也同样带有转换为Java基本类型的方法。
(ps:一开始没想到它会自带方法,查了很多麻烦的方法,包括什么无符号右移,感觉都没啥用)