| package com.zy.asrs.controller; | 
|   | 
| import com.baomidou.mybatisplus.mapper.EntityWrapper; | 
| import com.core.annotations.ManagerAuth; | 
| import com.core.common.R; | 
| import com.core.exception.CoolException; | 
| import com.zy.asrs.domain.enums.RgvStatusType; | 
| import com.zy.asrs.domain.param.CrnOperatorParam; | 
| import com.zy.asrs.domain.param.RgvOperatorParam; | 
| import com.zy.asrs.domain.vo.RgvMsgTableVo; | 
| import com.zy.asrs.domain.vo.RgvStateTableVo; | 
| import com.zy.asrs.entity.BasRgv; | 
| import com.zy.asrs.entity.BasRgvErr; | 
| import com.zy.asrs.entity.WrkMast; | 
| import com.zy.asrs.mapper.BasRgvErrMapper; | 
| import com.zy.asrs.service.BasRgvService; | 
| import com.zy.asrs.service.LocMastService; | 
| import com.zy.asrs.service.WrkMastService; | 
| import com.zy.asrs.service.impl.MainServiceImpl; | 
| import com.zy.core.cache.MessageQueue; | 
| import com.zy.core.cache.OutputQueue; | 
| import com.zy.core.cache.SlaveConnection; | 
| import com.zy.core.enums.RgvModeType; | 
| import com.zy.core.enums.RgvTaskModeType; | 
| import com.zy.core.enums.RgvTaskStatusType; | 
| import com.zy.core.enums.SlaveType; | 
| import com.zy.core.model.RgvSlave; | 
| import com.zy.core.model.Task; | 
| import com.zy.core.model.command.RgvCommand; | 
| import com.zy.core.model.protocol.RgvProtocol; | 
| import com.zy.core.properties.SlaveProperties; | 
| import com.zy.core.thread.RgvThread; | 
| import lombok.extern.slf4j.Slf4j; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.web.bind.annotation.PostMapping; | 
| import org.springframework.web.bind.annotation.RequestMapping; | 
| import org.springframework.web.bind.annotation.RestController; | 
|   | 
| import java.lang.reflect.Field; | 
| import java.util.ArrayList; | 
| import java.util.List; | 
| import java.util.Objects; | 
|   | 
| /** | 
|  * RGV接口 | 
|  * Created by vincent on 2020-06-01 | 
|  */ | 
| @Slf4j | 
| @RestController | 
| @RequestMapping("/rgv") | 
| public class RgvController { | 
|   | 
|     @Autowired | 
|     private SlaveProperties slaveProperties; | 
|     @Autowired | 
|     private WrkMastService wrkMastService; | 
|     @Autowired | 
|     private BasRgvErrMapper basRgvErrMapper; | 
|     @Autowired | 
|     private BasRgvService basRgvService; | 
|     @Autowired | 
|     private MainServiceImpl mainService; | 
|     @Autowired | 
|     private LocMastService locMastService; | 
|   | 
|     @ManagerAuth(memo = "解锁小车") | 
|     @PostMapping("/lock") | 
|     public R lock(CrnOperatorParam param){ | 
|         RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, param.getRgvNo()); | 
|         rgvThread.setPakMk(true); | 
|         return R.ok(); | 
|     } | 
|   | 
|     @PostMapping("/table/rgv/state") | 
|     @ManagerAuth(memo = "RGV信息表") | 
|     public R rgvStateTable() { | 
|         List<RgvStateTableVo> list = new ArrayList<>(); | 
|         List<BasRgv> rgvs = basRgvService.selectList(new EntityWrapper<BasRgv>().orderBy("rgv_no")); | 
|   | 
|         for (BasRgv basRgv : rgvs) { | 
|             RgvStateTableVo vo = new RgvStateTableVo(); | 
|             vo.setRgvNo(basRgv.getRgvNo());   //  RGV号 | 
|             list.add(vo); | 
|   | 
|             // 获取RGV信息 | 
|             RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basRgv.getRgvNo()); | 
|             if (rgvThread == null) continue; | 
|   | 
|             RgvProtocol rgvProtocol = rgvThread.getRgvProtocol(); | 
|             if (rgvProtocol == null) continue; | 
|   | 
|             vo.setStatusType(rgvProtocol.modeType.desc);   // 模式状态 | 
|             vo.setStatus(String.valueOf(rgvProtocol.getMode())); // 状态 | 
|             vo.setWorkNo1(rgvProtocol.getTaskNo1());      // 工位1任务号 | 
|             vo.setStatus1(rgvProtocol.getStatusType1().desc); // 工位1状态 | 
|             vo.setLoading1(rgvProtocol.getLoaded1() ? "有物" : "无物"); // 工位1有物 | 
|             vo.setRgvPos(rgvProtocol.getRgvPos()); | 
|             vo.setRgvPos1(rgvProtocol.getRgvPosI2()); | 
|             vo.setWalkPos(Objects.equals(rgvProtocol.getWalkPos(), 1) ? "在定位" : "不在定位"); | 
|             vo.setPakMk(rgvThread.isPakMk() ? "无锁" : "锁定"); | 
| //            vo.setPakIn(rgvThread.isPakIn() ? "可入" : "不可入"); | 
| //            vo.setPakOut(rgvThread.isPakOut() ? "可出" : "不可出"); | 
| //            vo.setPakRgv(rgvThread.isPakRgv() ? "无锁" : "锁定"); | 
|             vo.setPaking(rgvThread.isPaking()? "无锁" : "锁定"); | 
| //            vo.setPakAll(rgvThread.isPakAll() ? "无锁" : "锁定"); | 
| //            vo.setPakToCrn(rgvThread.isPakToCrn() ? "无锁" : "锁定"); | 
|   | 
|   | 
|             vo.setWorkNo2(rgvProtocol.getTaskNo2());      // 工位2任务号 | 
| //            vo.setStatus2(rgvProtocol.getStatusType2().desc); // 工位2状态 | 
|             vo.setLoading2(rgvProtocol.getLoaded2() ? "有物" : "无物"); // 工位2有物 | 
|   | 
|             // --- 遍历 errX 字段生成 warnCode 和 alarm --- | 
|             List<String> alarms = new ArrayList<>(); | 
|             List<String> warnCodes = new ArrayList<>(); | 
|             Field[] fields = rgvProtocol.getClass().getDeclaredFields(); | 
|             for (Field field : fields) { | 
|                 if (field.getName().startsWith("err") && field.getType().equals(Boolean.class)) { | 
|                     field.setAccessible(true); | 
|                     try { | 
|                         Boolean value = (Boolean) field.get(rgvProtocol); | 
|                         if (Boolean.TRUE.equals(value)) { | 
|                             String numPart = field.getName().substring(3); | 
|                             int errId = Integer.parseInt(numPart); | 
|                             warnCodes.add(String.valueOf(errId)); | 
|   | 
|                             BasRgvErr rgvErr = basRgvErrMapper.selectById(errId); | 
|                             alarms.add(rgvErr == null ? "未知异常(" + errId + ")" : rgvErr.getErrName()); | 
|                         } | 
|                     } catch (IllegalAccessException e) { | 
|                         e.printStackTrace(); | 
|                     } | 
|                 } | 
|             } | 
|   | 
|             vo.setWarnCode(String.join(",", warnCodes)); | 
|             vo.setAlarm(alarms.isEmpty() ? "" : String.join(",", alarms)); | 
|         } | 
|   | 
|         return R.ok().add(list); | 
|     } | 
|   | 
|   | 
|     @PostMapping("/table/rgv/msg") | 
|     @ManagerAuth(memo = "RGV数据表") | 
|     public R rgvMsgTable(){ | 
|         List<RgvMsgTableVo> list = new ArrayList<>(); | 
|         List<BasRgv> rgvs = basRgvService.selectList(new EntityWrapper<BasRgv>().orderBy("rgv_no")); | 
|         for (BasRgv basRgv : rgvs) { | 
|             // 表格行 | 
|             RgvMsgTableVo vo = new RgvMsgTableVo(); | 
|             vo.setRgvNo(basRgv.getRgvNo());   //  RGV号 | 
|             list.add(vo); | 
|             // 获取RGV信息 | 
|             RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, basRgv.getRgvNo()); | 
|             if (rgvThread == null) { | 
|                 continue; | 
|             } | 
|             RgvProtocol rgvProtocol = rgvThread.getRgvProtocol(); | 
|             if (rgvProtocol == null) { | 
|                 continue; | 
|             } | 
|   | 
|             vo.setWorkNo1(rgvProtocol.getTaskNo1());  //  工位1工作号 | 
|             vo.setWorkNo2(rgvProtocol.getTaskNo2()); //工位2 工作号 | 
|             vo.setStaNo(String.valueOf(rgvProtocol.getRgvPosDestination())); //小车目标站 | 
|             vo.setStatus(rgvProtocol.modeType.equals(RgvModeType.AUTO)? rgvProtocol.modeType.desc: RgvModeType.HAND.desc);   //  模式状态 | 
|   | 
|         } | 
|         return R.ok().add(list); | 
|     } | 
|   | 
|     @PostMapping("/output/site") | 
|     @ManagerAuth(memo = "RGV报文日志输出") | 
|     public R rgvOutput(){ | 
|         StringBuilder str = new StringBuilder(); | 
|         String s; | 
|         int i = 0; | 
|         while((s = OutputQueue.RGV.poll()) != null && i <=10) { | 
|             str.append("\n").append(s); | 
|             i++; | 
|         } | 
|         return R.ok().add(str.toString()); | 
|     } | 
|   | 
|     /****************************************************************/ | 
|     /************************** 手动操作 ******************************/ | 
|     /****************************************************************/ | 
|   | 
|     @ManagerAuth(memo = "取放货") | 
|     @PostMapping("/operator/put") | 
|     public R rgvFetchPut(RgvOperatorParam param){ | 
|         RgvCommand command = new RgvCommand(); | 
|         command.setRgvNo(param.getRgvNo()); // RGV编号 | 
|         command.setAckFinish1(false);  // 任务完成确认位 | 
|         command.setTaskNo(0); // 工作号 | 
|         command.setTaskMode1(RgvTaskModeType.FETCH_PUT); // 任务模式: 取放货 | 
|         command.setSourceStaNo1(param.getSourceStaNo1()); // 源站 | 
| //        command.setDestinationStaNo1(param.getStaNo1());  // 目标站 | 
|         command.setAckFinish2(false);  // 任务完成确认位 | 
|         command.setTaskNo2(0); // 工作号 | 
|         command.setTaskMode2(RgvTaskModeType.FETCH_PUT); // 任务模式: 取放货 | 
|         command.setSourceStaNo2(param.getSourceStaNo2()); // 源站 | 
| //        command.setDestinationStaNo2(param.getStaNo2());  // 目标站 | 
|         command.setCommand(true); | 
|   | 
|         return rgvControl(command)? R.ok(): R.error(); | 
|     } | 
|   | 
|     @ManagerAuth(memo = "取货") | 
|     @PostMapping("/operator/take") | 
|     public R rgvFetch(RgvOperatorParam param){ | 
|         RgvCommand command = new RgvCommand(); | 
|         command.setRgvNo(param.getRgvNo()); // RGV编号 | 
|         command.setWrkTaskPri(param.getWorkSta());  //执行工位 | 
|         command.setTaskNo(Math.toIntExact(param.getWorkNo())); // 工作号 | 
|         command.setTaskStatus(RgvTaskStatusType.FETCH); // 任务模式: 取货 | 
|         command.setTargetPosition(Integer.valueOf(param.getStaNo()));  // 目标站 | 
| //        command.setTaskMode2(RgvTaskModeType.FETCH); // 任务模式: 取放货 | 
| //        command.setAckFinish1(false);  // 任务完成确认位 | 
| //        command.setSourceStaNo1(param.getSourceStaNo1()); // 源站 | 
| //        command.setAckFinish2(false);  // 任务完成确认位 | 
| //        command.setTaskNo2( 0); // 工作号 | 
| //        command.setSourceStaNo2(param.getSourceStaNo2()); // 源站 | 
| //        command.setDestinationStaNo2(param.getStaNo2());  // 目标站 | 
|         command.setCommand(true); | 
|   | 
|         return rgvControl(command)? R.ok(): R.error(); | 
|     } | 
|   | 
|     @ManagerAuth(memo = "放货") | 
|     @PostMapping("/operator/stockMove") | 
|     public R rgvPut(RgvOperatorParam param){ | 
|         RgvCommand command = new RgvCommand(); | 
|         command.setRgvNo(param.getRgvNo()); // RGV编号 | 
|         command.setWrkTaskPri(param.getWorkSta());  //执行工位 | 
|         command.setTaskNo(Math.toIntExact(param.getWorkNo())); // 工作号 | 
|         command.setTaskStatus(RgvTaskStatusType.PUT); // 任务模式: 取货 | 
|         command.setTargetPosition(Integer.valueOf(param.getStaNo()));  // 目标站 | 
| //        command.setAckFinish1(false);  // 任务完成确认位 | 
| //        command.setSourceStaNo1(param.getSourceStaNo1()); // 源站 | 
| //        command.setAckFinish2(false);  // 任务完成确认位 | 
| //        command.setTaskNo2( 0); // 工作号 | 
| //        command.setTaskMode2(RgvTaskModeType.FETCH); // 任务模式: 取放货 | 
| //        command.setSourceStaNo2(param.getSourceStaNo2()); // 源站 | 
| //        command.setDestinationStaNo2(param.getStaNo2());  // 目标站 | 
|         command.setCommand(true); | 
|   | 
|         return rgvControl(command)? R.ok(): R.error(); | 
|     } | 
|   | 
|   | 
|   | 
|     @ManagerAuth(memo = "任务完成") | 
|     @PostMapping("/operator/taskComplete") | 
|     public R rgvTaskComplete(RgvOperatorParam param){ | 
|         RgvCommand command = new RgvCommand(); | 
|         command.setRgvNo(param.getRgvNo()); // RGV编号 | 
|         command.setAckFinish1(true);  // 任务完成确认位 | 
| //        command.setTaskNo1(0); // 工作号 | 
|         command.setTaskMode1(RgvTaskModeType.NONE); // 任务模式 | 
|         command.setSourceStaNo1((short) 0); // 源站 | 
|         command.setDestinationStaNo1((short) 0);  // 目标站 | 
|         command.setAckFinish2(true);  // 任务完成确认位 | 
|         command.setTaskNo2( 0); // 工作号 | 
|         command.setTaskMode2(RgvTaskModeType.NONE); // 任务模式 | 
|         command.setSourceStaNo2((short) 0); // 源站 | 
|         command.setDestinationStaNo2((short) 0);  // 目标站 | 
|         command.setCommand(true); | 
|   | 
|         return rgvControl(command)? R.ok(): R.error(); | 
|     } | 
|   | 
|     @ManagerAuth(memo = "清除命令") | 
|     @PostMapping("/operator/clearCommand") | 
|     public R rgvClearCommand(RgvOperatorParam param){ | 
|         if (param.getRgvNo() == null) { | 
|             throw new CoolException("请选择RGV号"); | 
|         } | 
|         RgvCommand command = new RgvCommand(); | 
|         command.setRgvNo(param.getRgvNo()); // RGV编号 | 
|         command.setWrkTaskPri(0);  //执行工位 | 
|         command.setTaskNo(Math.toIntExact(0)); // 工作号 | 
|         command.setTaskStatus((short)0); // 任务模式: 取货 | 
|         command.setTargetPosition(0);  // 目标站 | 
|   | 
|         return rgvClear(command)? R.ok(): R.error(); | 
|     } | 
|   | 
|     @ManagerAuth(memo = "手动复位") | 
|     @PostMapping("/operator/handleReset") | 
|     public R handleReset(RgvOperatorParam param) throws Exception { | 
|         if (param.getRgvNo() == null) { | 
|             throw new CoolException("请选择RGV"); | 
|         } | 
|         // 获取RGV缓存 | 
|         for (RgvSlave rgv : slaveProperties.getRgv()) { | 
|             // 获取RGV信息 | 
|             if (param.getRgvNo().equals(rgv.getId())) { | 
|                 RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId()); | 
|                 if (rgvThread == null) { | 
|                     throw new CoolException("RGV不在线"); | 
|                 } | 
|                 RgvProtocol rgvProtocol = rgvThread.getRgvProtocol(); | 
|                 if (rgvProtocol == null) { | 
|                     throw new CoolException("RGV不在线"); | 
|                 } | 
|                 RgvCommand Command = new RgvCommand(); | 
|                 Command.setRgvNo(rgv.getId()); // RGV编号 | 
|                 Command.setTaskMode1(RgvTaskModeType.NONE); | 
|                 Command.setAckFinish1(true);  // 任务完成确认位 | 
|                 Command.setAckFinish2(true);  // 任务完成确认位 | 
|                 Command.setCommand(true);  // 任务完成确认位 | 
|                 // 延时发送 | 
|                 Thread.sleep(1000L); | 
|                 if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(4, Command))) { | 
|                     return R.ok(); | 
|                 } else { | 
|                     throw new CoolException("命令下发失败"); | 
|                 } | 
|   | 
|             } | 
|         } | 
|         return R.error(); | 
|     } | 
|   | 
|     private boolean rgvControl(RgvCommand command){ | 
|         if (command.getRgvNo() == null) { | 
|             throw new CoolException("请选择RGV"); | 
|         } | 
|         for (RgvSlave rgv : slaveProperties.getRgv()) { | 
|             // 获取RGV信息 | 
|             if (command.getRgvNo().equals(rgv.getId())) { | 
|                 RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId()); | 
|                 if (rgvThread == null) { | 
|                     throw new CoolException("RGV不在线"); | 
|                 } | 
|                 RgvProtocol rgvProtocol = rgvThread.getRgvProtocol(); | 
|                 if (rgvProtocol == null) { | 
|                     throw new CoolException("RGV不在线"); | 
|                 } | 
|                 if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(2, command))) { | 
|                     return true; | 
|                 } else { | 
|                     throw new CoolException("命令下发失败"); | 
|                 } | 
|             } | 
|         } | 
|         return false; | 
|     } | 
|   | 
|     private boolean rgvClear(RgvCommand command){ | 
|         if (command.getRgvNo() == null) { | 
|             throw new CoolException("请选择RGV"); | 
|         } | 
|         for (RgvSlave rgv : slaveProperties.getRgv()) { | 
|             // 获取RGV信息 | 
|             if (command.getRgvNo().equals(rgv.getId())) { | 
|                 RgvThread rgvThread = (RgvThread) SlaveConnection.get(SlaveType.Rgv, rgv.getId()); | 
|                 if (rgvThread == null) { | 
|                     throw new CoolException("RGV不在线"); | 
|                 } | 
|                 RgvProtocol rgvProtocol = rgvThread.getRgvProtocol(); | 
|                 if (rgvProtocol == null) { | 
|                     throw new CoolException("RGV不在线"); | 
|                 } | 
|                 if (MessageQueue.offer(SlaveType.Rgv, rgv.getId(), new Task(3, command))) { | 
|                     return true; | 
|                 } else { | 
|                     throw new CoolException("命令下发失败"); | 
|                 } | 
|             } | 
|         } | 
|         return false; | 
|   | 
|     } | 
|   | 
| } |