package com.iailab.module.data.channel.modbus.collector; import com.iailab.module.data.common.enums.CommonConstant; import com.iailab.module.data.common.enums.DataSourceType; import com.iailab.framework.common.util.object.ConvertUtils; import com.iailab.module.data.common.utils.TagUtils; import com.iailab.module.data.channel.modbus.dto.ChannelModBusDeviceDTO; import com.iailab.module.data.channel.modbus.entity.ChannelModBusDeviceEntity; import com.iailab.module.data.channel.modbus.service.ChannelModbusDeviceService; import com.serotonin.modbus4j.ModbusMaster; import com.serotonin.modbus4j.code.DataType; import lombok.extern.slf4j.Slf4j; import javax.annotation.Resource; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author PanZhibao * @Description * @createTime 2024年05月12日 */ @Slf4j @Component public class ModBusCollector { @Resource private ChannelModbusDeviceService channelModbusDeviceService; private Map clientMap = new ConcurrentHashMap<>(); private Map deviceMap = new HashMap<>(); private synchronized ModbusMaster getMaster(String sourceId) throws Exception { log.info("=========Modbus============"); try { if (!clientMap.containsKey(sourceId)) { ChannelModBusDeviceEntity entity = channelModbusDeviceService.info(sourceId); ChannelModBusDeviceDTO tModbusDTO = ConvertUtils.sourceToTarget(entity, ChannelModBusDeviceDTO.class); ModbusMaster modbusMaster = ModbusUtils.getMaster(tModbusDTO); if (modbusMaster != null) { clientMap.put(sourceId, modbusMaster); } } } catch (Exception ex) { log.error("=========Modbus Exception============"); log.error("ex.message+" + ex.getMessage()); throw new Exception(ex.getMessage()); } return clientMap.get(sourceId); } public Double getTagValue(String sourceId, String tagNo) { Double result = CommonConstant.BAD_VALUE.doubleValue(); try { ModbusMaster modbusMaster = this.getMaster(sourceId); // 获取寄存器类型 String type = tagNo.substring(0, 1); int slaveId = 1; int offset = Integer.parseInt(tagNo.substring(1)) - 1; switch (type) { case "0": // 读线圈寄存器 result = ModbusUtils.readCoilStatus(modbusMaster, slaveId, offset) ? 1d : 0; break; case "1": // 读离散输入寄存器 result = ModbusUtils.inputStatus(modbusMaster, slaveId, offset) ? 1d : 0; break; case "3": // 读输入寄存器 result = ModbusUtils.inputRegister(modbusMaster, slaveId, offset, DataType.TWO_BYTE_INT_SIGNED) .doubleValue(); break; case "4": // 读输入寄存器数据 result = ModbusUtils.holdingRegister(modbusMaster, slaveId, offset, DataType.TWO_BYTE_INT_SIGNED) .doubleValue(); break; default: break; } return result; } catch (Exception ex) { log.error("TagNo========" + tagNo); ex.printStackTrace(); } return result; } public void setTagValue(String sourceId, String tagNo, String newValue) { try { ModbusMaster modbusMaster = this.getMaster(sourceId); // 获取寄存器类型 String type = tagNo.substring(0, 1); int slaveId = 1; int offset = Integer.parseInt(tagNo.substring(1)) - 1; switch (type) { case "0": // 写单个线圈寄存器 ModbusUtils.writeCoilStatus(modbusMaster, slaveId, offset, Integer.parseInt(newValue) > 0 ); break; case "4": // 写单个保持寄存器 ModbusUtils.writeRegister(modbusMaster, slaveId, offset, Integer.parseInt(newValue)); break; default: break; } } catch (Exception ex) { ex.printStackTrace(); } } public Map getTagValues(List params) { if (CollectionUtils.isEmpty(params)) { return new HashMap<>(); } Map result = new HashMap<>(params.size()); params.forEach(item -> { try { Double value = this.getTagValue(item[0], item[1]); result.put(TagUtils.genTagId(DataSourceType.ModBus.getCode(), deviceMap.get(item[0]).getName(), item[1]), value); } catch (Exception ex) { ex.printStackTrace(); result.put(TagUtils.genTagId(DataSourceType.ModBus.getCode(), deviceMap.get(item[0]).getName(), item[1]), CommonConstant.BAD_VALUE); } }); return result; } }