package tunnelworker.slavers.iml; import container.ProtocolDataContainer; import entity.datapoint.SenderDataPoint; import enums.TunnelStatus; import exception.DataExchangeException; import slavertunnelinfo.SlaverModbusTcpTunnelInfo; import tunnelworker.BaseProtocolTunnel; import tunnelworker.slavers.SlaverInterface; import tunnelworker.workassist.SingleThreadPoolExecutorUtil; import wei.yigulu.modbus.domain.datatype.BooleanModbusDataInRegister; import wei.yigulu.modbus.domain.datatype.ModbusDataTypeEnum; import wei.yigulu.modbus.domain.datatype.NumericModbusData; import wei.yigulu.modbus.netty.ModbusTcpSlaverBuilder; import java.util.HashMap; import java.util.List; import java.util.Map; /** * modbus 转发数据通道 * * @author 修唯xiuwei * @version 3.0 */ public class ModbusTcpSlaver extends BaseProtocolTunnel implements SlaverInterface { /** * 通道点位 ---- 点位对象 */ Map dataPointMap; /** * 0: 线圈 1:寄存器 */ private int functionFlag; /** * 顶层的构造方法 * * @param tunnelInfo 通道信息 */ public ModbusTcpSlaver(SlaverModbusTcpTunnelInfo tunnelInfo) { super(tunnelInfo); } @Override protected ModbusTcpSlaver buildTunnel() throws DataExchangeException { return this; } @Override protected void parseDataPoint() throws DataExchangeException { this.log.info("解析该通道下所管理的点位"); List dataPoints = this.tunnelInfo.getDataPoints(); if (dataPoints == null || dataPoints.size() == 0) { return; } this.dataPointMap = new HashMap<>(); for (SenderDataPoint d : dataPoints) { this.dataPointMap.put(d.getProtocolPoint(), d); } this.log.info("解析该通道下所管理的点位完成"); } @Override public ModbusTcpSlaver startTunnel() throws DataExchangeException { log.info("modbus TCP slaver {} 通道开始连接", getTunnelInfo().getTunnelName()); protocolTunnelContainer.addUpdateDateTask(this); try { SingleThreadPoolExecutorUtil.executeBySingleThreadExecutor(() -> { try { this.protocolBuilder.create(); log.error("Modbus TCP slaver 创建通道失败"); setTunnelStatus(TunnelStatus.LISTENPORTFAIL); } catch (Exception e) { log.error("Modbus TCP slaver 创建通道失败", e); setTunnelStatus(TunnelStatus.LISTENPORTFAIL); } }); } catch (Exception e) { log.error("Modbus TCP slaver 创建通道失败", e); setTunnelStatus(TunnelStatus.LISTENPORTFAIL); throw new DataExchangeException(10007, "Modbus TCP slaver创建通道失败"); } if (!TunnelStatus.LISTENPORTFAIL.equals(getTunnelStatus())) { setTunnelStatus(TunnelStatus.LISTENPORTSUCCESS); } return this; } @Override public BaseProtocolTunnel tunnelStop() throws DataExchangeException { if (this.protocolBuilder != null) { this.protocolBuilder.stop(); } log.info("关闭 Modbus TCP slaver 通道 {}", this.tunnelInfo.getTunnelName()); return super.tunnelStop(); } @Override public void updateData2Protocol() throws DataExchangeException { ProtocolDataContainer dataContainer = ProtocolDataContainer.getInstance(); if (functionFlag == 1) { this.dataPointMap.forEach((k, v) -> { if (ModbusDataTypeEnum.A16.equals(v.getDataType().getModbusDataType())) { BooleanModbusDataInRegister booleanModbusDataInRegister = new BooleanModbusDataInRegister(); booleanModbusDataInRegister.setValue(0, dataContainer.getBoolean(v.getDataPointId())); this.protocolBuilder.getModbusSlaveDataContainer().setRegister(this.tunnelInfo.getSlaveId(), k, booleanModbusDataInRegister); } else { this.protocolBuilder.getModbusSlaveDataContainer().setRegister(this.tunnelInfo.getSlaveId(), k, ((NumericModbusData) (v.getDataType().getModbusDataType().getObject())).setValue(dataContainer.getNumber(v.getDataPointId()).multiply(v.getRatio()))); } }); } else { this.dataPointMap.forEach((k, v) -> this.protocolBuilder.getModbusSlaveDataContainer().setCoil(this.tunnelInfo.getSlaveId(), k, dataContainer.getBoolean(v.getDataPointId())) ); } } }