package com.ld.igds.protocol.modbus.command; import com.ld.igds.constant.BizType; import com.ld.igds.constant.RedisConst; import com.ld.igds.io.RemoteGasService; import com.ld.igds.io.constant.OrderRespEnum; import com.ld.igds.io.constant.ProtocolEnum; import com.ld.igds.io.request.CheckGasRequest; import com.ld.igds.io.response.DeviceControlResponse; import com.ld.igds.io.response.GasResponse; import com.ld.igds.modbus.service.HModbusService; import com.ld.igds.models.DeviceModbus; import com.ld.igds.models.GasModbus; import com.ld.igds.protocol.modbus.ModbusUtil2; import com.ld.igds.protocol.modbus.ServerUtil; import com.ld.igds.protocol.modbus.data.ModbusGasResult; import com.ld.igds.protocol.modbus.data.ModbusTcp; import com.ld.igds.util.RedisUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; /** * 当前协议针对标准Modbus-TCP协议 * * @Desc: * @author: andy.jia * @update-time: 2023/8/11 10:07 */ @Slf4j @Component(RemoteGasServiceImpl.BEAN_ID) public class RemoteGasServiceImpl implements RemoteGasService { public static final String BEAN_ID = "modbus.remoteGasService"; @Resource private HModbusService modbusService; @Resource private AnalysisService analysisService; @Resource private RedisUtil redisUtil; @Override public String getProtocol() { return ProtocolEnum.TCP_MODBUS.getCode(); } @Override public GasResponse checkGas(CheckGasRequest request) { boolean isRun = isRun(request); if (isRun) { return new GasResponse(OrderRespEnum.ORDER_ERROR.getCode(), "提醒:当前仓正在执行检测"); } String passCode = request.getDepotId(); try { //获取需要执行的设备配置 DeviceModbus deviceModbus = modbusService.getCacheDeviceModbus(request.getCompanyId(), passCode, BizType.GAS.getCode()); ModbusTcp modbusTcp = new ModbusTcp(deviceModbus); modbusTcp.setIp(request.getIp()); modbusTcp.setPort(request.getPort()); modbusTcp.setBizCode(passCode); modbusTcp.setSerId(request.getSerId()); modbusTcp.setCompanyId(request.getCompanyId()); modbusTcp.setAddrExe(ServerUtil.getAddrExe(deviceModbus.getOpen())); boolean exeResult = ModbusUtil2.writeCoilStatus(modbusTcp.getIp(), modbusTcp.getPort(), modbusTcp.getAddrExe(), true); if (exeResult) { addRun(request); //调用异步获取结果 progressGasResult(request, modbusTcp); log.debug("--------启动测气---{}-{}", modbusTcp.getSerId(), modbusTcp.getBizCode()); } } catch (Exception e) { return new GasResponse(OrderRespEnum.ORDER_ERROR.getCode(), "后台执行异常:" + e.getLocalizedMessage()); } return new GasResponse(OrderRespEnum.ORDER_SUCCESS); } private void addRun(CheckGasRequest request) { String key = RedisConst.buildKey(request.getCompanyId(), ServerUtil.RUN_TAG, request.getDepotId()); redisUtil.set(key, request, 6 * 60); } private void delRun(CheckGasRequest request) { String key = RedisConst.buildKey(request.getCompanyId(), ServerUtil.RUN_TAG, request.getDepotId()); redisUtil.del(key); } private boolean isRun(CheckGasRequest request) { String key = RedisConst.buildKey(request.getCompanyId(), ServerUtil.RUN_TAG, request.getDepotId()); Object obj = redisUtil.get(key); if (null == obj) return false; return true; } /** * 异步执行进度查询 * * @param modbusTcp */ @Async public void progressGasResult(CheckGasRequest request, ModbusTcp modbusTcp) { log.debug("--------------异步执行气体检测记过获取-------------"); try { List list = modbusService.listGasModBus(modbusTcp.getBizCode()); if (null == list || list.isEmpty()) { log.error("------------更新气体检测结果进度失败,没有获取到检测通道配置信息-----{}", modbusTcp.getBizCode()); return; } //根据通道数量线程等待,每个通道等待60秒 Thread.sleep(list.size() * 50 * 1000); log.debug("--------------等待时间完成,开始获取检测结果-------------{}", modbusTcp.getBizCode()); boolean isRun = isRun(request); if (!isRun) { log.info("--------------当前仓库检测已经停止,取消结果查询-------------{}", modbusTcp.getBizCode()); return; } ModbusTcp modbusTcpTemp = modbusTcp; List results = new ArrayList<>(); ModbusGasResult gasResult; Number check; for (GasModbus gasModbus : list) { gasResult = new ModbusGasResult(); gasResult.setPasscode(gasModbus.getPasscode()); //二氧化碳 modbusTcpTemp.setAddrExe(ServerUtil.getAddrExe(gasModbus.getCo2())); check = ModbusUtil2.readHoldingRegister(modbusTcpTemp.getIp(), modbusTcpTemp.getPort(), modbusTcpTemp.getAddrExe()); gasResult.setCo2(check); //氧气 modbusTcpTemp.setAddrExe(ServerUtil.getAddrExe(gasModbus.getO2())); check = ModbusUtil2.readHoldingRegister(modbusTcpTemp.getIp(), modbusTcpTemp.getPort(), modbusTcpTemp.getAddrExe()); gasResult.setO2(check); //磷化氢 modbusTcpTemp.setAddrExe(ServerUtil.getAddrExe(gasModbus.getPh3())); check = ModbusUtil2.readHoldingRegister(modbusTcpTemp.getIp(), modbusTcpTemp.getPort(), modbusTcpTemp.getAddrExe()); gasResult.setPh3(check); log.debug("----通道{},Co2={},O2={},Ph3={}", gasModbus.getPasscode(), gasResult.getCo2(), gasResult.getO2(), gasResult.getPh3()); results.add(gasResult); } //删除运行标记 delRun(request); log.debug("----获取的气体检测结果---{}--{}", request.getDepotId(), results.toString()); //通知解析 analysisService.analysisGas(request, results); } catch (Exception e) { log.error("------------更新气体检测结果进度失败,执行异常-----{}--{}", modbusTcp.getBizCode(), e); } } @Override public GasResponse checkGasByPoint(CheckGasRequest request) { return new GasResponse(OrderRespEnum.ORDER_ERROR.getCode(), "当前控制柜不支持选择点位采集"); } @Override public GasResponse stopCheckGas(CheckGasRequest request) { String passCode = request.getDepotId(); try { //获取需要执行的设备配置 DeviceModbus deviceModbus = modbusService.getCacheDeviceModbus(request.getCompanyId(), passCode, BizType.GAS.getCode()); ModbusTcp modbusTcp = new ModbusTcp(deviceModbus); modbusTcp.setIp(request.getIp()); modbusTcp.setPort(request.getPort()); modbusTcp.setBizCode(passCode); modbusTcp.setSerId(request.getSerId()); modbusTcp.setCompanyId(request.getCompanyId()); modbusTcp.setAddrExe(ServerUtil.getAddrExe(deviceModbus.getStop())); boolean exeResult = ModbusUtil2.writeCoilStatus(modbusTcp.getIp(), modbusTcp.getPort(), modbusTcp.getAddrExe(), true); if (exeResult) { log.debug("--------关闭测气---{}-{}", modbusTcp.getSerId(), modbusTcp.getBizCode()); //通知异步结束结果采集 delRun(request); } } catch (Exception e) { return new GasResponse(OrderRespEnum.ORDER_ERROR.getCode(), "后台执行异常:" + e.getLocalizedMessage()); } return new GasResponse(OrderRespEnum.ORDER_SUCCESS); } }