前言
这是一个数据采集的项目,属于XX数据消防的一个数据采集,前面通过 modbus poll 读取过了,现在用java 代码去读取,需要注意的是这种方法封装好的,我们后来根据netty 自己去解析数据,因为其本质就是 二进制数据的解析,了解完modbus 就了解了如何处理,但是呢这个笔记我之前很早就记录了,以后估计也用不上了...
留着给用到的人做一点参考吧
工具类
java
import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.BatchResults;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;
/**
* Modbus TCP协议读取数据
*
*/
public class ModbusReadUtil {
/**
* 单列工厂。
*/
static ModbusFactory modbusFactory;
static {
if (modbusFactory == null) {
modbusFactory = new ModbusFactory();
}
}
/**
* 获取master
*
* @param host IP地址
* @param port 端口号
* @return
* @throws ModbusInitException
*/
public static ModbusMaster getMaster(String host, int port) throws ModbusInitException {
try {
IpParameters params = new IpParameters();
params.setHost(host);
params.setPort(port);
ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
master.init(); //master初始化
return master;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 批量读取使用寄存器数据
*
* @param master ModbusMaster对象
* @param batchRead 批量读取集合
* @throws ModbusTransportException
* @throws ErrorResponseException
* @throws ModbusInitException
*/
public static BatchResults<Integer> batchRead(ModbusMaster master, BatchRead<Integer> batchRead) throws Exception {
try {
batchRead.setContiguousRequests(false);
BatchResults<Integer> results = master.send(batchRead);
return results;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//测试
public static void main(String[] args) {
try {
ModbusMaster master = getMaster("192.168.1.88", 2001);
BatchRead<Integer> batch = new BatchRead<>();
batch.addLocator(0, BaseLocator.inputRegister(1, 0, DataType.FOUR_BYTE_FLOAT));
batch.addLocator(1, BaseLocator.inputRegister(1, 2, DataType.FOUR_BYTE_FLOAT));
batch.addLocator(2, BaseLocator.inputRegister(1, 4, DataType.FOUR_BYTE_FLOAT));
batch.addLocator(3, BaseLocator.inputRegister(1, 6, DataType.FOUR_BYTE_FLOAT));
batch.addLocator(4, BaseLocator.inputRegister(1, 8, DataType.FOUR_BYTE_FLOAT));
batch.addLocator(5, BaseLocator.inputRegister(1, 10, DataType.FOUR_BYTE_FLOAT));
BatchResults<Integer> batchRead = batchRead(master, batch);
System.out.println(batchRead.getValue(0));
System.out.println(batchRead.getValue(1));
System.out.println(batchRead.getValue(2));
System.out.println(batchRead.getValue(3));
System.out.println(batchRead.getValue(4));
System.out.println(batchRead.getValue(5));
} catch (Exception e) {
e.printStackTrace();
}
}
}
工具类
java
package com.zhuking.datacollection.common.utils;
import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.BatchResults;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.serotonin.modbus4j.msg.WriteCoilRequest;
import com.serotonin.modbus4j.msg.WriteCoilResponse;
import com.serotonin.modbus4j.msg.WriteCoilsRequest;
import com.serotonin.modbus4j.msg.WriteCoilsResponse;
/**
* modbus通讯工具类,采用modbus4j实现
*
* @website https://github.com/infiniteautomation/modbus4j
*/
public class Modbus4jUtils {
/**
* 工厂。
*/
static ModbusFactory modbusFactory;
static {
if (modbusFactory == null) {
modbusFactory = new ModbusFactory();
}
}
/**
* 获取master
*
* @return
* @throws ModbusInitException
*/
public static ModbusMaster getMaster() {
IpParameters params = new IpParameters();
params.setHost("192.168.1.88"); // 指定IP
params.setPort(2001);// 指定端口
// modbusFactory.createRtuMaster(wapper); //RTU 协议
// modbusFactory.createUdpMaster(params);//UDP 协议
// modbusFactory.createAsciiMaster(wrapper);//ASCII 协议
ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
try {
master.init();
} catch (ModbusInitException e) {
e.printStackTrace();
}
return master;
}
/**
* 读取[01 Coil Status 0x]类型 开关数据
*
* @param slaveId slaveId
* @param offset 位置
* @return 读取值
* @throws ModbusTransportException
* @throws ErrorResponseException
*/
public static Boolean readCoilStatus(int slaveId,
int offset) throws ModbusTransportException, ErrorResponseException {
// 读取 功能码 01 Coil status(0x) 数据类型
BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId, offset);
return getMaster().getValue(loc);
}
/**
* 往 功能码 01 Coil status(0x) 写数据
*
* @param slaveId
* @param writeOffset 位置
* @param writeValue 值
* @return
* @throws ModbusTransportException
*/
public boolean writeCoil(int slaveId, int writeOffset, boolean writeValue) throws ModbusTransportException {
ModbusMaster tcpMaster = getMaster();
WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);
WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request);
return !response.isException();
}
/**
* 往 功能码 01 Coil status(0x) 写数据
*
* @param slaveId
* @param startOffset 开始位
* @param data 数组,从开始位逐渐的将数组数据写入 例如:开始为是 5,传递的参数为 5 那就是从 5-10 的位置会被写入数据
* @return
* @throws ModbusTransportException
*/
public static boolean writeCoils(int slaveId, int startOffset, boolean[] data) throws ModbusTransportException {
ModbusMaster tcpMaster = getMaster();
WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, data);
WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request);
return !response.isException();
}
/**
* 读取[02 Input Status 1x]类型 开关数据
*
* @param slaveId
* @param offset
* @return
* @throws ModbusTransportException
* @throws ErrorResponseException
*/
public static Boolean readInputStatus(int slaveId,
int offset) throws ModbusTransportException, ErrorResponseException {
// 02 Input Status
BaseLocator<Boolean> loc = BaseLocator.inputStatus(slaveId, offset);
Boolean value = getMaster().getValue(loc);
return value;
}
/**
* 读取[03 Holding Register类型 2x]模拟量数据
*
* @param slaveId slave Id
* @param offset 位置
* @param dataType 数据类型,来自com.serotonin.modbus4j.code.DataType
* @return
* @throws ModbusTransportException 异常
* @throws ErrorResponseException 异常
*/
public static Number readHoldingRegister(int slaveId, int offset,
int dataType) throws ModbusTransportException, ErrorResponseException {
// 03 Holding Register类型数据读取
BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId, offset, dataType);
Number value = getMaster().getValue(loc);
return value;
}
/**
* 读取[04 Input Registers 3x]类型 模拟量数据
*
* @param slaveId slaveId
* @param offset 位置
* @param dataType 数据类型,来自com.serotonin.modbus4j.code.DataType
* @return 返回结果
* @throws ModbusTransportException 异常
* @throws ErrorResponseException 异常
*/
public static Number readInputRegisters(int slaveId, int offset,
int dataType) throws ModbusTransportException, ErrorResponseException {
// 04 Input Registers类型数据读取
BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId, offset, dataType);
Number value = getMaster().getValue(loc);
return value;
}
/**
* 批量读取使用方法
*
* @throws ModbusTransportException
* @throws ErrorResponseException
*/
public static void batchRead() throws ModbusTransportException, ErrorResponseException {
BatchRead<Integer> batch = new BatchRead<>();
batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.FOUR_BYTE_FLOAT));
batch.addLocator(1, BaseLocator.inputStatus(1, 0));
ModbusMaster master = getMaster();
batch.setContiguousRequests(false);
BatchResults<Integer> results = master.send(batch);
System.out.println(results.getValue(0));
System.out.println(results.getValue(1));
}
public static void main(String[] args) throws ModbusTransportException, ErrorResponseException {
// 0 代表了 寄存器的位 1和2 的值
// 2 代表了 寄存器位 2和2 的值
Number number = readInputRegisters(1, 0, DataType.FOUR_BYTE_FLOAT);
System.out.println(number.doubleValue());
}
/**
* 批量读取使用寄存器数据
*
* @param master ModbusMaster对象
* @param batchRead 批量读取集合
* @throws ModbusTransportException
* @throws ErrorResponseException
* @throws ModbusInitException
*/
public static BatchResults<Integer> batchRead(ModbusMaster master, BatchRead<Integer> batchRead) throws Exception {
try {
batchRead.setContiguousRequests(false);
BatchResults<Integer> results = master.send(batchRead);
return results;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}