/**
* 从字节数组解析值
* @param data 字节数组
* @param dataType 数据类型
* @param bitOffset 位偏移
*/
public Object parseValue(byte[] data, String dataType, int bitOffset) {
if (data == null || data.length == 0) return null;
switch (dataType.toUpperCase()) {
case "BOOL":
// 从指定字节的指定位提取布尔值
int byteIndex = bitOffset / 8;
int bitIndex = bitOffset % 8;
if (byteIndex < data.length) {
return (data[byteIndex] & (1 << bitIndex)) != 0;
}
return null;
case "BYTE":
return data[0] & 0xFF;
case "INT":
// 西门子PLC使用大端序
return (short) ((data[0] << 8) | (data[1] & 0xFF));
case "WORD":
return ((data[0] & 0xFF) << 8) | (data[1] & 0xFF);
case "DINT":
return (data[0] << 24) | ((data[1] & 0xFF) << 16) |
((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
case "DWORD":
return ((long) (data[0] & 0xFF) << 24) | ((data[1] & 0xFF) << 16) |
((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
case "REAL":
case "FLOAT":
int intBits = (data[0] << 24) | ((data[1] & 0xFF) << 16) |
((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
return Float.intBitsToFloat(intBits);
case "LREAL":
case "DOUBLE":
long longBits = ((long) data[0] << 56) | ((long) (data[1] & 0xFF) << 48) |
((long) (data[2] & 0xFF) << 40) | ((long) (data[3] & 0xFF) << 32) |
((long) (data[4] & 0xFF) << 24) | ((data[5] & 0xFF) << 16) |
((data[6] & 0xFF) << 8) | (data[7] & 0xFF);
return Double.longBitsToDouble(longBits);
default:
// 默认作为字节数组返回
return bytesToHex(data);
}
}
/**
* 字节数组转16进制字符串
*/
private String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
}
return sb.toString();
}