package com.ld.igds.protocol.modbus; import com.serotonin.modbus4j.BatchRead; import com.serotonin.modbus4j.BatchResults; import com.serotonin.modbus4j.ModbusMaster; import com.serotonin.modbus4j.code.DataType; import com.serotonin.modbus4j.exception.ModbusInitException; import com.serotonin.modbus4j.exception.ModbusTransportException; import com.serotonin.modbus4j.locator.BaseLocator; import com.serotonin.modbus4j.msg.ReadCoilsRequest; import com.serotonin.modbus4j.msg.ReadCoilsResponse; import com.serotonin.modbus4j.msg.ReadDiscreteInputsRequest; import com.serotonin.modbus4j.msg.ReadDiscreteInputsResponse; import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest; import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse; import com.serotonin.modbus4j.msg.ReadInputRegistersRequest; import com.serotonin.modbus4j.msg.ReadInputRegistersResponse; import com.serotonin.modbus4j.msg.WriteCoilRequest; import com.serotonin.modbus4j.msg.WriteCoilResponse; import com.serotonin.modbus4j.msg.WriteCoilsRequest; import com.serotonin.modbus4j.msg.WriteCoilsResponse; import com.serotonin.modbus4j.msg.WriteRegisterRequest; import com.serotonin.modbus4j.msg.WriteRegisterResponse; import com.serotonin.modbus4j.msg.WriteRegistersRequest; import com.serotonin.modbus4j.msg.WriteRegistersResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * @Desc: 工具类 * @author: Andy * @update-time: 2023/8/11 */ @Slf4j @Component public class ModbusUtil { //从机默认值 private Integer slaveId = 1; @Autowired private ModbusConfig modbusConfig; /** * 读线圈--01 * * @param ip * @param port * @param offset * @param numberOfRegister */ public boolean[] readStatus01(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException { ModbusMaster master = modbusConfig.getMaster(ip, port); ReadCoilsRequest request = new ReadCoilsRequest(slaveId, offset, numberOfRegister); ReadCoilsResponse response = (ReadCoilsResponse) master.send(request); boolean[] booleans = response.getBooleanData(); return valueRegroup(numberOfRegister, booleans); } /** * @Description: 02H-读离散输入量 * @Param: [ip, offset, numberOfRegister] * @return: boolean[] * @throws: */ public boolean[] readStatus02(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException { ModbusMaster master = modbusConfig.getMaster(ip, port); ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, offset, numberOfRegister); ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request); boolean[] booleans = response.getBooleanData(); return valueRegroup(numberOfRegister, booleans); } /** * @Description: 03H-读保持寄存器 * @Param: [ip, offset, numberOfRegister] * @return: short[] * @throws: */ public short[] readStatus03(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException { ModbusMaster master = modbusConfig.getMaster(ip, port); ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, offset, numberOfRegister); ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request); return response.getShortData(); } /** * @Description: 04H-读输入寄存器 * @Param: [ip, offset, numberOfRegister] * @return: short[] * @throws: */ public short[] readStatus04(String ip, int port, int offset, int numberOfRegister) throws ModbusTransportException { ModbusMaster master = modbusConfig.getMaster(ip, port); ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, offset, numberOfRegister); ReadInputRegistersResponse response = (ReadInputRegistersResponse) master.send(request); return response.getShortData(); } public BatchResults readBatch(String ip, int port) throws Exception { ModbusMaster master = modbusConfig.getMaster(ip, port); if (null == master) return null; return readBatch(master); } /** * 批量读取多个 * * @param master * @throws ModbusTransportException */ public BatchResults readBatch(ModbusMaster master) throws Exception { BatchRead batch = new BatchRead<>(); batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.TWO_BYTE_INT_SIGNED)); batch.addLocator(1, BaseLocator.inputStatus(1, 0)); batch.setContiguousRequests(true); BatchResults results = master.send(batch); log.info("batchRead:" + results.getValue(0)); log.info("batchRead:" + results.getValue(1)); return results; } /** * @Description: 写单个(线圈)开关量数据,相当于功能码:05H-写单个线圈 * @Param: [ip, writeOffset, writeValue] * @return: boolean * @throws: */ public boolean writeValue05(String ip, int port, int writeOffset, boolean writeValue) throws ModbusTransportException { ModbusMaster tcpMaster = modbusConfig.getMaster(ip, port); WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue); WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request); return !response.isException(); } /** * @Description: 写多个开关量数据(线圈),相当于功能码:0FH-写多个线圈 * @Param: [ip, startOffset, data] * @return: boolean * @throws: */ public boolean writeValues15(String ip, int port, int startOffset, boolean[] data) throws ModbusTransportException { ModbusMaster tcpMaster = modbusConfig.getMaster(ip, port); WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, data); WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request); return !response.isException(); } /** * @Description: 写单个保持寄存器,相当于功能码:06H-写单个保持寄存器 * @Param: [ip, writeOffset, writeValue] * @return: boolean * @throws: */ public boolean writeValue06(String ip, int port, int writeOffset, short writeValue) throws ModbusTransportException, ModbusInitException { ModbusMaster tcpMaster = modbusConfig.getMaster(ip, port); WriteRegisterRequest request = new WriteRegisterRequest(slaveId, writeOffset, writeValue); WriteRegisterResponse response = (WriteRegisterResponse) tcpMaster.send(request); return !response.isException(); } /** * @Description: 写多个保持寄存器,相当于功能码:10H-写多个保持寄存器 * @Param: [ip, startOffset, data] * @return: boolean * @throws: */ public boolean writeValues16(String ip, int port, int startOffset, short[] data) throws ModbusTransportException, ModbusInitException { ModbusMaster tcpMaster = modbusConfig.getMaster(ip, port); WriteRegistersRequest request = new WriteRegistersRequest(slaveId, startOffset, data); WriteRegistersResponse response = (WriteRegistersResponse) tcpMaster.send(request); return !response.isException(); } /** * @Description: 转换工具,将Boolean转换成0,1 * @Param: [numberOfBits, values] * @return: boolean[] * @throws: */ private boolean[] valueRegroup(int numberOfBits, boolean[] values) { boolean[] bs = new boolean[numberOfBits]; int temp = 1; for (boolean b : values) { bs[temp - 1] = b; temp++; if (temp > numberOfBits) { break; } } return bs; } }