package com.ld.igds.protocol.modbus; import com.serotonin.modbus4j.ModbusMaster; import com.serotonin.modbus4j.exception.ModbusInitException; import com.serotonin.modbus4j.exception.ModbusTransportException; 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 org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * @Desc: 工具类 * @author: Andy * @update-time: 2023/8/11 */ @Component public class ModbusUtil { //从机默认值 private Integer slaveId = 1; @Autowired private ModbusConfig modbusConfig; public boolean[] readCoilStatus(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: * @Author: Ricardo.Liu * @Date: 2020/5/8 */ public boolean[] readInputStatus(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: * @Author: Ricardo.Liu * @Date: 2020/5/8 */ public short[] readHoldingRegister(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: * @Author: Ricardo.Liu * @Date: 2020/5/8 */ public short[] readInputRegisters(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(); } /** * @Description: 写单个(线圈)开关量数据,相当于功能码:05H-写单个线圈 * @Param: [ip, writeOffset, writeValue] * @return: boolean * @throws: * @Author: Ricardo.Liu * @Date: 2020/5/8 */ public boolean writeCoil(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: * @Author: Ricardo.Liu * @Date: 2020/5/8 */ public boolean writeCoils(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: * @Author: Ricardo.Liu * @Date: 2020/5/8 */ public boolean writeHoldingRegister(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: * @Author: Ricardo.Liu * @Date: 2020/5/8 */ public boolean writeHoldingRegisters(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: * @Author: Ricardo.Liu * @Date: 2020/5/8 */ 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; } }