package com.ld.igds.protocol.modbus; 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.*; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.HashMap; /** * @Desc: 工具类 * @author: Andy * @update-time: 2023/8/11 */ @Slf4j public class ModbusUtil2 { //从机默认值 private static Integer slaveId = 1; private static HashMap masterMap = new HashMap<>(); /** * 工厂 */ static ModbusFactory modbusFactory; //static ModbusMaster modbusMaster; static { if (modbusFactory == null) { modbusFactory = new ModbusFactory(); } } /** * 获取master * * @return */ public static ModbusMaster getMaster(String ip, int port) throws ModbusInitException, InterruptedException { String key = ip; ModbusMaster modbusMaster = masterMap.get(key); if (modbusMaster == null || !modbusMaster.isConnected()) { IpParameters ipParameters = new IpParameters(); ipParameters.setHost(ip); ipParameters.setPort(port); modbusMaster = modbusFactory.createTcpMaster(ipParameters, true); modbusMaster.init(); //初始化之后等待,避免出现连接未创建 Thread.sleep(2500); masterMap.put(key, modbusMaster); return modbusMaster; } return modbusMaster; } /** * 读取线圈开关状态数据 0x01 * * @param offset * @return * @throws ModbusInitException * @throws ModbusTransportException * @throws ErrorResponseException */ public static Boolean readCoilStatus(String ip, int port, int offset) throws ModbusInitException, ModbusTransportException, ErrorResponseException, InterruptedException { BaseLocator coilStatus = BaseLocator.coilStatus(slaveId, offset); Boolean res = getMaster(ip, port).getValue(coilStatus); return res; } /** * 读离散输入寄存器状态数据 0x02 * * @param offset * @return * @throws ModbusInitException * @throws ModbusTransportException * @throws ErrorResponseException */ public static Boolean readInputStatus(String ip, int port, int offset) throws ModbusInitException, ModbusTransportException, ErrorResponseException, InterruptedException { BaseLocator inputStatus = BaseLocator.inputStatus(slaveId, offset); // Thread.sleep(3000); Boolean res = getMaster(ip, port).getValue(inputStatus); return res; } /** * 读保持寄存器数据 0x03 * * @param offset * @param dataType * @return * @throws ModbusInitException * @throws ModbusTransportException * @throws ErrorResponseException */ public static Number readHoldingRegister(String ip, int port, int offset, int dataType) throws ModbusInitException, ModbusTransportException, ErrorResponseException, InterruptedException { BaseLocator holdingRegister = BaseLocator.holdingRegister(slaveId, offset, dataType); Number value = getMaster(ip, port).getValue(holdingRegister); return value; } public static Number readHoldingRegister(String ip, int port, int offset) throws ModbusInitException, ModbusTransportException, ErrorResponseException, InterruptedException { int dataType = DataType.TWO_BYTE_INT_SIGNED; return readHoldingRegister(ip, port, offset, dataType); } /** * 读输入寄存器数据 0x04 * * @param offset * @param dataType * @return * @throws ModbusInitException * @throws ModbusTransportException * @throws ErrorResponseException */ public static Number readInputRegister(String ip, int port, int offset, int dataType) throws ModbusInitException, ModbusTransportException, ErrorResponseException, InterruptedException { BaseLocator inputRegister = BaseLocator.inputRegister(slaveId, offset, dataType); Number value = getMaster(ip, port).getValue(inputRegister); return value; } /** * 读输入寄存器数据 0x04 * * @param offset * @return * @throws ModbusInitException * @throws ModbusTransportException * @throws ErrorResponseException */ public static Number readInputRegister(String ip, int port, int offset) throws ModbusInitException, ModbusTransportException, ErrorResponseException, InterruptedException { int dataType = DataType.TWO_BYTE_INT_SIGNED; return readInputRegister(ip, port, offset, dataType); } /** * 写线圈开关状态数据 0x05 * * @param offset * @param status * @return * @throws ModbusTransportException * @throws ModbusInitException */ public static Boolean writeCoilStatus(String ip, int port, int offset, boolean status) throws ModbusTransportException, ModbusInitException, InterruptedException { WriteCoilRequest coilRequest = new WriteCoilRequest(slaveId, offset, status); WriteCoilResponse coilResponse = (WriteCoilResponse) getMaster(ip, port).send(coilRequest); return !coilResponse.isException(); } /** * 写单个保持寄存器数据 0x06 * * @param offset * @param value * @return * @throws ModbusTransportException * @throws ModbusInitException */ public static Boolean writeRegister(String ip, int port, int offset, int value) throws ModbusTransportException, ModbusInitException, InterruptedException { WriteRegisterRequest registerRequest = new WriteRegisterRequest(slaveId, offset, value); WriteRegisterResponse registerResponse = (WriteRegisterResponse) getMaster(ip, port).send(registerRequest); return !registerResponse.isException(); } /** * 写线圈开关状态数据【多】 0x0f * * @param offset * @param booleans * @return * @throws ModbusTransportException * @throws ModbusInitException */ public static Boolean writeCoils(String ip, int port, int offset, boolean[] booleans) throws ModbusTransportException, ModbusInitException, InterruptedException { WriteCoilsRequest writeCoils = new WriteCoilsRequest(slaveId, offset, booleans); WriteCoilsResponse coilsResponse = (WriteCoilsResponse) getMaster(ip, port).send(writeCoils); return !coilsResponse.isException(); } /** * 写保存寄存器数据【多】 0x10 * * @param offset * @param nums * @return * @throws ModbusTransportException * @throws ModbusInitException */ public static Boolean writeRegisters(String ip, int port, int offset, short[] nums) throws ModbusTransportException, ModbusInitException, InterruptedException { WriteRegistersRequest writeRegisters = new WriteRegistersRequest(slaveId, offset, nums); WriteRegistersResponse registersResponse = (WriteRegistersResponse) getMaster(ip, port).send(writeRegisters); return !registersResponse.isException(); } }