src/main/java/com/zy/asrs/controller/ForkLiftController.java
@@ -1,21 +1,33 @@ package com.zy.asrs.controller; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.core.annotations.ManagerAuth; import com.core.common.BaseRes; import com.core.common.Cools; import com.core.common.R; import com.core.exception.CoolException; import com.zy.asrs.domain.param.LiftOperatorParam; import com.zy.asrs.domain.vo.*; import com.zy.asrs.entity.BasLift; import com.zy.asrs.service.BasLiftService; import com.zy.common.service.CommonService; import com.zy.common.utils.ForkLiftUtils; import com.zy.common.utils.RedisUtil; import com.zy.core.action.ForkLiftAction; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.OutputQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.ForkLiftProtocolStatusType; import com.zy.core.enums.ForkLiftTaskModeType; import com.zy.core.enums.RedisKeyType; import com.zy.core.enums.SlaveType; import com.zy.core.model.ForkLiftSlave; import com.zy.core.model.LiftSlave; import com.zy.core.model.Task; import com.zy.core.model.command.*; import com.zy.core.model.protocol.ForkLiftProtocol; import com.zy.core.model.protocol.LiftStaProtocol; import com.zy.core.properties.SlaveProperties; import com.zy.core.thread.ForkLiftThread; import lombok.extern.slf4j.Slf4j; @@ -26,41 +38,44 @@ import java.util.List; /** * 提升机接口 * 货叉提升机接口 */ @Slf4j @RestController @RequestMapping("/lift") @RequestMapping("/forkLift") public class ForkLiftController { @Autowired private CommonService commonService; @Autowired private SlaveProperties slaveProperties; @Autowired private BasLiftService basLiftService; @Autowired private RedisUtil redisUtil; @Autowired private ForkLiftAction forkLiftAction; @PostMapping("/table/lift/state") @ManagerAuth(memo = "提升机信息表") public R liftStateTable(){ List<LiftStateTableVo> list = new ArrayList<>(); ArrayList<JSONObject> list = new ArrayList<>(); for (ForkLiftSlave slave : slaveProperties.getForkLift()) { // 表格行 LiftStateTableVo vo = new LiftStateTableVo(); vo.setLiftNo(slave.getId()); //提升机号 list.add(vo); JSONObject baseObj = new JSONObject(); baseObj.put("shuttleNo", slave.getId()); list.add(baseObj); // 获取提升机信息 ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, slave.getId()); if (forkLiftThread == null) { vo.setProtocolStatus(ForkLiftProtocolStatusType.NONE.id);//离线 continue; } ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus(); if (forkLiftProtocol == null || forkLiftProtocol.getLiftNo()==null) { if (forkLiftProtocol == null) { continue; } vo.setTaskNo(forkLiftProtocol.getTaskNo().shortValue()); // 任务号 vo.setProtocolStatus(forkLiftProtocol.getProtocolStatusType().id); JSONObject data = JSON.parseObject(JSON.toJSONString(forkLiftProtocol)); baseObj.putAll(data); } return R.ok().add(list); } @@ -240,4 +255,78 @@ return R.ok(); } /****************************************************************/ /************************** 手动操作 ******************************/ /****************************************************************/ @ManagerAuth(memo = "手动操作") @PostMapping("/operator/lift") public R liftOperator(LiftOperatorParam param){ if (Cools.isEmpty(param.getLiftNo())) { return R.parse(BaseRes.PARAM); } ForkLiftThread forkLiftThread = (ForkLiftThread) SlaveConnection.get(SlaveType.ForkLift, param.getLiftNo()); if (forkLiftThread == null) { throw new CoolException("提升机不在线"); } ForkLiftProtocol forkLiftProtocol = forkLiftThread.getStatus(); if (forkLiftProtocol == null) { throw new CoolException("提升机不在线"); } if (param.getLiftTaskMode() == 1) { //小车换层 int workNo = commonService.getWorkNo(99);//获取任务号 Integer startSta = param.getSourceStaNo(); Integer targetSta = param.getStaNo(); //获取提升机命令 List<ForkLiftCommand> liftCommand = forkLiftThread.getShuttleSwitchCommand(workNo, startSta, targetSta); ArrayList<ForkLiftCommand> commands = new ArrayList<>(); commands.addAll(liftCommand); //提交到线程去工作 LiftAssignCommand assignCommand = new LiftAssignCommand(); assignCommand.setCommands(commands); assignCommand.setLiftNo(forkLiftProtocol.getLiftNo().shortValue()); assignCommand.setTaskNo((short) workNo); assignCommand.setAuto(false);//手动模式 assignCommand.setTaskMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id.shortValue()); forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand); return R.ok(); } else if (param.getLiftTaskMode() == 2) { //移动托盘 int workNo = commonService.getWorkNo(99);//获取任务号 Integer startSta = param.getSourceStaNo(); Integer targetSta = param.getStaNo(); //获取提升机命令 List<ForkLiftCommand> liftCommand = forkLiftThread.getPickAndPutCommand(workNo, startSta, targetSta); ArrayList<ForkLiftCommand> commands = new ArrayList<>(); commands.addAll(liftCommand); //提交到线程去工作 LiftAssignCommand assignCommand = new LiftAssignCommand(); assignCommand.setCommands(commands); assignCommand.setLiftNo(forkLiftProtocol.getLiftNo().shortValue()); assignCommand.setTaskNo((short) workNo); assignCommand.setAuto(false);//手动模式 assignCommand.setTaskMode(ForkLiftTaskModeType.PICK_PUT.id.shortValue()); forkLiftAction.assignWork(forkLiftProtocol.getLiftNo(), assignCommand); return R.ok(); } else if (param.getLiftTaskMode() == 0) { //提升机复位 forkLiftThread.setSyncTaskNo(0); forkLiftThread.setProtocolStatus(ForkLiftProtocolStatusType.IDLE); return R.ok(); } else { throw new CoolException("未知命令"); } } } src/main/java/com/zy/asrs/controller/ShuttleController.java
@@ -15,6 +15,7 @@ import com.zy.asrs.service.LocMastService; import com.zy.asrs.service.WrkMastService; import com.zy.asrs.utils.Utils; import com.zy.common.model.NavigateNode; import com.zy.common.model.enums.NavigationMapType; import com.zy.common.service.CommonService; import com.zy.common.utils.NavigateMapUtils; @@ -39,6 +40,7 @@ import org.springframework.web.bind.annotation.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** @@ -185,7 +187,16 @@ return R.error("指令不存在"); } ShuttleRedisCommand redisCommand = JSON.parseObject(o.toString(), ShuttleRedisCommand.class); return R.ok().add(redisCommand); ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand(); List<ShuttleCommand> commands = assignCommand.getCommands(); HashMap<String, Object> map = new HashMap<>(); map.put("commands", commands); map.put("shuttleNo", redisCommand.getShuttleNo()); map.put("commandStep", redisCommand.getCommandStep()); map.put("wrkNo", redisCommand.getWrkNo()); return R.ok().add(map); } //回退命令 @@ -367,7 +378,7 @@ return R.error("plc已掉线"); } if (workNo != null) { shuttleThread.setTaskNo(workNo); shuttleThread.setSyncTaskNo(workNo); } if (pakMk != null) { shuttleThread.setPakMk(pakMk.equals("Y")); src/main/java/com/zy/asrs/domain/vo/LiftStateTableVo.java
@@ -24,138 +24,6 @@ */ private Integer protocolStatus; /** * 模式 */ private Boolean model; /** * 忙闲 */ private Boolean busy; /** * 有托盘 */ private Boolean hasTray; /** * 有小车 */ private Boolean hasCar; /** * 设备故障 */ private Boolean deviceError; /** * 前超限 */ private Boolean frontOverrun; /** * 后超限 */ private Boolean backOverrun; /** * 左超限 */ private Boolean leftOverrun; /** * 右超限 */ private Boolean rightOverrun; /** * 超高 */ private Boolean overHeight; /** * 超重 */ private Boolean overWeight; public String getModel$() { if (this.model == null) { return "离线"; } return this.model ? "自动" : "手动"; } public String getBusy$() { if (this.busy == null) { return "-"; } return this.busy ? "忙碌" : "空闲"; } public String getHasTray$() { if (this.hasTray == null) { return "-"; } return this.hasTray ? "Y" : "N"; } public String getHasCar$() { if (this.hasCar == null) { return "N"; } return this.hasCar ? "Y" : "N"; } public String getDeviceError$() { if (this.deviceError == null) { return "N"; } return this.deviceError ? "Y" : "N"; } public String getFrontOverrun$() { if (this.frontOverrun == null) { return "N"; } return this.frontOverrun ? "Y" : "N"; } public String getBackOverrun$() { if (this.backOverrun == null) { return "N"; } return this.backOverrun ? "Y" : "N"; } public String getLeftOverrun$() { if (this.leftOverrun == null) { return "N"; } return this.leftOverrun ? "Y" : "N"; } public String getRightOverrun$() { if (this.rightOverrun == null) { return "N"; } return this.rightOverrun ? "Y" : "N"; } public String getOverHeight$() { if (this.overHeight == null) { return "N"; } return this.overHeight ? "Y" : "N"; } public String getOverWeight$() { if (this.overWeight == null) { return "N"; } return this.overWeight ? "Y" : "N"; } public String getProtocolStatus$() { if (this.protocolStatus == null) { return ForkLiftProtocolStatusType.NONE.desc; src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -839,32 +839,44 @@ //将任务档标记为完成 WrkMast wrkMast = wrkMastService.selectByWorkNo(shuttleProtocol.getTaskNo()); if (wrkMast != null) { switch (wrkMast.getWrkSts().intValue()) { // case 5://5.小车搬运中 ==> 9.入库完成 // wrkMast.setWrkSts(9L); // shuttleProtocol.setTaskNo(0); // if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) { // //释放小车令牌 // shuttleProtocol.setToken(0); // } // break; // case 22://22.小车搬运中 ==> 23.小车搬运完成 // wrkMast.setWrkSts(23L); // shuttleProtocol.setTaskNo(0); // if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) { // //释放小车令牌 // shuttleProtocol.setToken(0); // } // break; case 302://302.小车移动至站点 ==> 303.小车移动至站点完成 wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts); break; case 110://310.小车移动中 ==> 311.小车移动完成 wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.sts); shuttleThread.setTaskNo(0); break; default: if (wrkMast.getWrkSts() == WrkStsType.MOVE_SITE.sts) { //302.小车移动至站点 ==> 303.小车移动至站点完成 wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts); } else if (wrkMast.getWrkSts() == WrkStsType.MOVE_SHUTTLE.sts) { //310.小车移动中 ==> 311.小车移动完成 wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.sts); shuttleThread.setSyncTaskNo(0); } else if (wrkMast.getWrkSts() == WrkStsType.CHARGE_SHUTTLE_WORKING.sts) { //204.小车充电中 ==> 205.小车充电完成 wrkMast.setWrkSts(WrkStsType.CHARGE_SHUTTLE_COMPLETE.sts); shuttleThread.setSyncTaskNo(0); } // switch (wrkMast.getWrkSts().intValue()) { //// case 5://5.小车搬运中 ==> 9.入库完成 //// wrkMast.setWrkSts(9L); //// shuttleProtocol.setTaskNo(0); //// if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) { //// //释放小车令牌 //// shuttleProtocol.setToken(0); //// } //// break; //// case 22://22.小车搬运中 ==> 23.小车搬运完成 //// wrkMast.setWrkSts(23L); //// shuttleProtocol.setTaskNo(0); //// if (shuttleProtocol.getToken().equals(wrkMast.getWrkNo())) { //// //释放小车令牌 //// shuttleProtocol.setToken(0); //// } //// break; // case 302: // wrkMast.setWrkSts(WrkStsType.MOVE_SITE_COMPLETE.sts); // break; // case WrkStsType.MOVE_SHUTTLE.sts: // wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.sts); // shuttleThread.setSyncTaskNo(0); // break; // default: // } if (wrkMastService.updateById(wrkMast)) { //设置四向穿梭车为空闲状态 @@ -1833,7 +1845,7 @@ */ public synchronized void executeShuttleCharge() { try { //查询小车移库任务 //查询小车充电任务 for (ShuttleSlave shuttle : slaveProperties.getShuttle()) { WrkMast wrkMast = wrkMastService.selectChargeWorking(shuttle.getId()); if(wrkMast == null) { @@ -2001,12 +2013,6 @@ List<ShuttleCommand> commands = shuttleOperaUtils.getShuttleChargeCommand(assignCommand, shuttleThread, false); assignCommand.setCommands(commands);//运行命令 wrkMast.setWrkSts(WrkStsType.CHARGE_SHUTTLE_COMPLETE.sts); wrkMast.setModiTime(new Date()); if (!wrkMastService.updateById(wrkMast)) { return false; } //下发任务 shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand); return false; @@ -2026,22 +2032,22 @@ return false; } ShuttleChargeType chargeType = ShuttleChargeType.get(wrkMast.getMk()); ShuttleChargeType chargeType = ShuttleChargeType.get(Integer.parseInt(wrkMast.getMk())); if(chargeType == null) { return false; } //调度小车去待机位 boolean dispatched = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), chargeType.waitLocNo, wrkMast.getShuttleNo()); if (!dispatched) { return false; } wrkMast.setWrkSts(WrkStsType.COMPLETE_CHARGE.sts); wrkMast.setModiTime(new Date()); if (wrkMastService.updateById(wrkMast)) { //调度小车去待机位 boolean dispatched = shuttleDispatchUtils.dispatchShuttle(wrkMast.getWrkNo(), chargeType.waitLocNo, wrkMast.getShuttleNo()); if (!dispatched) { return false; } return false; } return false; } return true; @@ -2142,23 +2148,23 @@ assignCommand.setCommands(commands); //*************尝试锁定目标站路径*************** List<NavigateNode> targetNodes = ForkLiftUtils.getLiftStaNodes(wrkMast.getStaNo()); if (targetNodes == null) { return false;//未获取到节点 } boolean checkPathIsAvailable = navigateUtils.checkPathIsAvailable(targetNodes, shuttleProtocol.getShuttleNo(), Utils.getLev(wrkMast.getLocNo())); if (!checkPathIsAvailable) { News.info("{}任务,{}小车,目标站点路径被占用,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo()); return false;//检测目标站点路径是否未被占用 } //尝试锁定目标站路径 boolean result2 = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(wrkMast.getLocNo()), shuttleProtocol.getShuttleNo(), targetNodes, true);//所使用的路径进行锁定禁用 if (!result2) { News.info("{}任务,{}小车,路径锁定失败,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo()); return false;//路径锁定失败 } //*************尝试锁定目标站路径*************** // //*************尝试锁定目标站路径*************** // List<NavigateNode> targetNodes = ForkLiftUtils.getLiftStaNodes(wrkMast.getStaNo()); // if (targetNodes == null) { // return false;//未获取到节点 // } // boolean checkPathIsAvailable = navigateUtils.checkPathIsAvailable(targetNodes, shuttleProtocol.getShuttleNo(), Utils.getLev(wrkMast.getLocNo())); // if (!checkPathIsAvailable) { // News.info("{}任务,{}小车,目标站点路径被占用,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo()); // return false;//检测目标站点路径是否未被占用 // } // //尝试锁定目标站路径 // boolean result2 = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(wrkMast.getLocNo()), shuttleProtocol.getShuttleNo(), targetNodes, true);//所使用的路径进行锁定禁用 // if (!result2) { // News.info("{}任务,{}小车,路径锁定失败,禁止派发", wrkMast.getWrkNo(), shuttleProtocol.getShuttleNo()); // return false;//路径锁定失败 // } // //*************尝试锁定目标站路径*************** wrkMast.setWrkSts(WrkStsType.MOVE_SITE.sts);//小车移动到提升机中 301.生成小车移库任务 ==> 302.小车移动至站点 wrkMast.setModiTime(now); src/main/java/com/zy/common/utils/ShuttleOperaUtils.java
@@ -78,6 +78,11 @@ assignCommand.setNodes(allNode);//当前任务所占用的节点list boolean result = navigateMapUtils.writeNavigateNodeToRedisMap(Utils.getLev(startLocNo), shuttleNo, allNode, true);//锁定路径 if (!result) { News.error("{} dash {} can't lock path!", startLocNo, endLocNo); return null;//路径锁定失败 } return commands; } src/main/java/com/zy/core/action/ForkLiftAction.java
@@ -63,10 +63,10 @@ return false; } WrkMast wrkMast = wrkMastService.selectByWorkNo(taskNo); if (wrkMast == null) { return false; } // WrkMast wrkMast = wrkMastService.selectByWorkNo(taskNo); // if (wrkMast == null) { // return false; // } LiftRedisCommand redisCommand = JSON.parseObject(obj.toString(), LiftRedisCommand.class); if (redisCommand == null) { @@ -96,7 +96,7 @@ ForkLiftCommand command = commands.get(commandStep); //判断提升机是否空闲 if (!forkLiftThread.isIdle()) { if (!forkLiftThread.isDeviceIdle()) { return false; } src/main/java/com/zy/core/model/command/ShuttleCommand.java
@@ -46,4 +46,11 @@ */ private List<NavigateNode> nodes; public String getMode$() { if (this.mode == null) { return null; } return ShuttleCommandModeType.get(this.mode).desc; } } src/main/java/com/zy/core/model/protocol/ForkLiftProtocol.java
@@ -25,7 +25,7 @@ private Integer liftNo; /** * 模式0单机 1联机 * 模式0手动 1单机 2联机 */ private Integer model; @@ -52,7 +52,7 @@ /** * 任务模式 */ private Integer mode = ForkLiftTaskModeType.NONE.id; private Integer taskMode = ForkLiftTaskModeType.NONE.id; /** * 任务模式枚举 @@ -123,17 +123,17 @@ /** * 设置任务模式 */ public void setMode(Integer mode) { this.mode = mode; this.modeType = ForkLiftTaskModeType.get(mode); public void setTaskMode(Integer taskMode) { this.taskMode = taskMode; this.modeType = ForkLiftTaskModeType.get(taskMode); } /** * 设置任务模式 */ public void setMode(ForkLiftTaskModeType mode) { this.mode = mode.id; this.modeType = mode; public void setMode(ForkLiftTaskModeType taskMode) { this.taskMode = taskMode.id; this.modeType = taskMode; } /** @@ -186,6 +186,46 @@ } } public String getModel$() { if (this.model == null) { return ""; } String name = ""; if (this.model == 0) { name = "手动"; } else if (this.model == 1) { name = "单机"; }else if (this.model == 2) { name = "联机"; } return name; } public String getProtocolStatus$() { if (this.protocolStatus == null) { return ""; } return ForkLiftProtocolStatusType.get(this.protocolStatus).desc; } public String getTaskMode$() { if (this.taskMode == null) { return ""; } return ForkLiftTaskModeType.get(this.taskMode).desc; } public String getIOMode$() { if (this.iOMode == null) { return ""; } return ForkLiftIoModeType.get(this.iOMode).desc; } @Override public ForkLiftProtocol clone() { try { src/main/java/com/zy/core/thread/impl/NyShuttleThread.java
@@ -569,6 +569,7 @@ && this.shuttleProtocol.getMode() == 1 && this.shuttleProtocol.getPakMk() && this.shuttleProtocol.getErrorCode().equals("0") && this.shuttleProtocol.getTaskNo() == 0 && (this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.IDLE.id || this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.WAITING.id || this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.CHARGING_WAITING.id) src/main/java/com/zy/core/thread/impl/ZyForkLiftThread.java
@@ -62,16 +62,16 @@ @Override public boolean connect() { boolean result = false; siemensS7Net = new SiemensS7Net(SiemensPLCS.S1500, slave.getIp()); siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, slave.getIp()); siemensS7Net.setRack(slave.getRack().byteValue()); siemensS7Net.setSlot(slave.getSlot().byteValue()); OperateResult connect = siemensS7Net.ConnectServer(); if(connect.IsSuccess){ result = true; OutputQueue.DEVP.offer(MessageFormat.format( "【{0}】货叉提升机连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); OutputQueue.FORKLIFT.offer(MessageFormat.format( "【{0}】货叉提升机连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); News.info("货叉提升机连接成功 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); } else { OutputQueue.DEVP.offer(MessageFormat.format( "【{0}】货叉提升机连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); OutputQueue.FORKLIFT.offer(MessageFormat.format( "【{0}】货叉提升机连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot())); News.error("货叉提升机连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort()); } // siemensS7Net.ConnectClose(); @@ -134,7 +134,7 @@ private void readStatus() { try { //获取提升机数据 OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB101.0", (short) 32); OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB101.0", (short) 16); if (result1.IsSuccess) { if (null == forkLiftProtocol) { forkLiftProtocol = new ForkLiftProtocol(); @@ -148,19 +148,19 @@ //模式 forkLiftProtocol.setModel((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 0)); //PLC任务号 forkLiftProtocol.setWrkNo((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 4)); forkLiftProtocol.setWrkNo((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 2)); //任务状态 forkLiftProtocol.setProtocolStatus((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 8)); forkLiftProtocol.setProtocolStatus((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 4)); //任务模式 forkLiftProtocol.setModel((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 12)); forkLiftProtocol.setTaskMode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 6)); //取货数据 forkLiftProtocol.setPick((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 16)); forkLiftProtocol.setPick((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 8)); //放货数据 forkLiftProtocol.setPut((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 20)); forkLiftProtocol.setPut((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 10)); //出入库模式 forkLiftProtocol.setIOMode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 24)); forkLiftProtocol.setIOMode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 12)); //故障码 forkLiftProtocol.setErrorCode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 28)); forkLiftProtocol.setErrorCode((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 14)); //************补充扩展字段************* InnerForkLiftExtend forkLiftExtend = (InnerForkLiftExtend) forkLiftProtocol.getExtend(); @@ -260,7 +260,7 @@ array[3] = command.getPut();//放货数据 OperateResult result = siemensS7Net.Write("DB103.0", array); if (result.IsSuccess) { OperateResult result2 = siemensS7Net.Write("DB103.16", command.getConfirm()); OperateResult result2 = siemensS7Net.Write("DB103.8", command.getConfirm()); if (result2.IsSuccess) { response.setResult(true); } @@ -282,23 +282,43 @@ public boolean isIdle() { if (this.forkLiftProtocol.getTaskNo() == null || this.forkLiftProtocol.getProtocolStatus() == null || this.forkLiftProtocol.getModel() == null ) { return false; } boolean res = this.forkLiftProtocol.getProtocolStatus() == ForkLiftProtocolStatusType.IDLE.id && this.forkLiftProtocol.getTaskNo() == 0; && this.forkLiftProtocol.getWrkNo() == 0 && this.forkLiftProtocol.getTaskNo() == 0 && this.forkLiftProtocol.getModel() == 2; return res; } @Override public boolean isDeviceIdle() { return false; return isDeviceIdle(null); } @Override public boolean isDeviceIdle(ExecuteSupport support) { return false; if (null != support) { Boolean judgement = support.judgement(); if (judgement != null && !judgement) { return true; } } if (this.forkLiftProtocol.getTaskNo() == null || this.forkLiftProtocol.getProtocolStatus() == null || this.forkLiftProtocol.getModel() == null ) { return false; } boolean res = this.forkLiftProtocol.getProtocolStatus() == ForkLiftProtocolStatusType.IDLE.id && this.forkLiftProtocol.getWrkNo() == 0 && this.forkLiftProtocol.getModel() == 2; return res; } @Override src/main/resources/application.yml
@@ -140,7 +140,7 @@ # 货叉提升机1 forkLift[0]: id: 1 ip: 10.10.10.131 ip: 10.10.20.20 port: 102 rack: 0 slot: 0 src/main/resources/mapper/WrkMastMapper.xml
@@ -139,7 +139,7 @@ where 1=1 and shuttle_no = #{shuttleNo} and wrk_sts not in (9,10,109,110,210) and io_type not in (200) and io_type not in (200,300) order by io_pri desc,io_time,wrk_no asc limit 0,1 </select> @@ -163,7 +163,7 @@ <select id="selectChargeWorking" resultMap="BaseResultMap"> select * from asr_wrk_mast where wrk_sts in (201,202,203) where io_type in (300) and shuttle_no = #{shuttleNo} order by io_pri desc,io_time,wrk_no asc </select> src/main/webapp/views/forklift.html
New file @@ -0,0 +1,467 @@ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>提升机监控管理</title> <link rel="stylesheet" type="text/css" href="../static/css/normalize.css"> <link rel="stylesheet" type="text/css" href="../static/css/common.css"> <link rel="stylesheet" type="text/css" href="../static/layui/css/layui.css"> <link rel="stylesheet" href="../static/css/lift.css"> <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> <script type="text/javascript" src="../static/js/layer/layer.js"></script> <script type="text/javascript" src="../static/layui/layui.js"></script> <script type="text/javascript" src="../static/js/common.js"></script> </head> <body> <div style="padding: 10px;height: 100%;float: left;width: 6%"> <div class="button-window"></div> </div> <div style="height: 100%;padding-left: 6%"> <div style="padding: 10px;height: 100%"> <!-- 日志监控板 --> <div class="log-board"> <div class="command-log" id="commandLogId" style="width: 10%;"> </div> <div class="lift-state" style="width: 90%;"> <table id="lift-state-table"> <thead> <tr> <th>提升机</th> <th>工作号</th> <th>PLC任务号</th> <th>模式</th> <th>任务状态</th> <th>任务模式</th> <th>取货数据</th> <th>放货数据</th> <th>出入库模式</th> <th>故障码</th> </tr> </thead> <tbody> </tbody> </table> </div> </div> <!-- 提升机状态 --> <div class="lift-msg"> <table id="lift-msg-table"> <thead> <tr> <th>提升机</th> <th>工作号</th> <th>任务地址</th> <th>目的地址</th> <th>已完成的任务号</th> <th>层</th> <th>作业标记</th> <th>穿梭车号</th> </tr> </thead> <tbody> </tbody> </table> </div> <!-- 手动操作 --> <div class="lift-operation"> <!-- 遮罩层 --> <div class="lift-operation-shade"> <span class="lift-operation-shade-span"> WCS 系统运行中,请停止后操作 </span> </div> <!-- 设备任务选择 --> <div class="task-select"> <!-- 选择 --> <div id="lift-select" class="operator-item"> <span class="select-title">提升机号</span> <div class="select-container" id="liftRadioBoxId"> <!-- <label><input type="radio" name="liftSelect" value="1" checked> 1号提升机</label>--> </div> </div> </div> <!-- 设备任务操作 --> <div class="task-operator"> <fieldset> <legend>手动操作</legend> <div class="button-group"> <div class="select-container-item"> <span>源站</span> <label><input id="sourceStaNo" type="text" name="sourceStaNo" /></label> </div> <div class="select-container-item"> <span>目标站</span> <label><input id="staNo" type="text" name="staNo" /></label> </div> <button class="item" onclick="liftOperator(1)">小车换层</button> <button class="item" onclick="liftOperator(2)">移动托盘</button> <button class="item" onclick="liftOperator(0)">复位</button> </div> </fieldset> </div> </div> <!-- 提升机日志输出 --> <div class="lift-output-board"> <textarea id="lift-output"></textarea> </div> <div id="lift-detl" style="display: none"> <div> <div class="form-item"> <label class="form-label">站号:</label> <div class="form-input"> <input id="liftNo" name="liftNo" class="layui-input" lay-verify="required|number" autocomplete="off" disabled="disabled"> </div> </div> <div class="form-item"> <label class="form-label">工作号:</label> <div class="form-input"> <input id="workNo" name="workNo" type="number" class="layui-input" lay-verify="number" autocomplete="off"> </div> </div> <div class="form-item"> <label class="form-label">作业标记:</label> <div class="form-input"> <input id="pakMk" name="pakMk" type="text" class="layui-input" autocomplete="off"> </div> </div> <div class="form-item form-button-container"> <button class="form-button" id="save">保存</button> <button class="form-button" id="cancel" style="background-color: #D0D0D0">取消</button> </div> </div> </div> </div> </div> </body> </html> <script> // 空白行数 var liftStateTableBlankRows = 0; var liftMsgTableBlankRows = 0; // 实际行数 var liftStateTableFullRows = 0; var liftMsgTableFullRows = 0; // 初始化 var liftOutputDom = document.getElementById("lift-output"); $(document).ready(function() { initliftStateTable(); getliftStateInfo(); initliftMsgTable(); getliftMsgInfo(); operatorBlockShow(); setliftRadio(); }); setInterval(function () { getliftStateInfo() getliftMsgInfo(); },1000) setInterval(function () { getliftOutput(); operatorBlockShow(); },500); // 判断手动操作模块是否可用 function operatorBlockShow() { if (parent.systemRunning) { $('.lift-operation').css("opacity", "0.5"); $('.lift-operation-shade').show(); $('.lift-operation-shade-span').show(); } else { $('.lift-operation').css("opacity", "1"); $('.lift-operation-shade').hide(); $('.lift-operation-shade-span').hide(); } } $(document).on('click ','#save', function () { http.post(baseUrl+ "/forkLift/detl/update", { liftNo: $('#liftNo').val(), workNo: $('#workNo').val(), pakMk: $('#pakMk').val(), token: $('#token').val(), }, function (res) { layer.msg("修改成功", {icon: 1,}); layer.close(layerDetl); }) }) function setliftRadio() { $.ajax({ url: baseUrl+ "/forkLift/table/lift/state", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { if (res.code === 200){ let table = res.data; for (let i=1;i<=table.length;i++){ //渲染提升机选项html let liftRadioBox = '<label><input type="radio" name="liftSelect" '; if (i === 1) { liftRadioBox += 'checked ' } liftRadioBox += 'value="' + table[i - 1].liftNo + '"> ' + table[i - 1].liftNo + '号提升机</label>' $("#liftRadioBoxId").append(liftRadioBox) //渲染提升机数据维护和设备信息html let liftCommandLogBox = '<div class="lift-command-item" data-liftNo="' + table[i - 1].liftNo + '">\n' + '<label>' + table[i - 1].liftNo + '#</label>\n' + '</div>' $("#commandLogId").append(liftCommandLogBox); } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; } else { console.log(res.msg); } } }); } // 提升机信息表获取 ---- 表一 function getliftStateInfo() { let tableEl = $('#lift-state-table'); $.ajax({ url: baseUrl+ "/forkLift/table/lift/state", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { if (res.code === 200){ let table = res.data; if (table.length > liftStateTableBlankRows && table.length !== liftStateTableFullRows) { initliftStateTable(table.length-liftStateTableBlankRows); liftStateTableFullRows = table.length; } for (let i=1;i<=table.length;i++){ // $("#mode-"+table[i-1].liftNo).html(table[i-1].statusVal===0?'联机':'脱机'); let tr = tableEl.find("tr").eq(i); setVal(tr.children("td").eq(0), table[i-1].liftNo); setVal(tr.children("td").eq(1), table[i-1].taskNo); setVal(tr.children("td").eq(2), table[i-1].wrkNo); setVal(tr.children("td").eq(3), table[i-1].model$); setVal(tr.children("td").eq(4), table[i-1].protocolStatus$); setVal(tr.children("td").eq(5), table[i-1].taskMode$); setVal(tr.children("td").eq(6), table[i-1].pick); setVal(tr.children("td").eq(7), table[i-1].put); setVal(tr.children("td").eq(8), table[i-1].iOMode$); setVal(tr.children("td").eq(9), table[i-1].errorCode); } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; } else { console.log(res.msg); } } }); } // 提升机数据表获取 ---- 表二 function getliftMsgInfo() { let tableEl = $('#lift-msg-table'); $.ajax({ url: baseUrl+ "/forkLift/table/lift/msg", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { if (res.code === 200){ var table = res.data; if (table.length > liftMsgTableBlankRows && table.length !== liftMsgTableFullRows) { initliftMsgTable(table.length-liftMsgTableBlankRows); liftMsgTableFullRows = table.length; } for (var i=1;i<=table.length;i++){ var tr = tableEl.find("tr").eq(i); setVal(tr.children("td").eq(0), table[i-1].liftNo); setVal(tr.children("td").eq(1), table[i-1].workNo); setVal(tr.children("td").eq(2), table[i-1].taskAddress); setVal(tr.children("td").eq(3), table[i-1].distAddress); setVal(tr.children("td").eq(4), table[i-1].completeTaskNo); setVal(tr.children("td").eq(5), table[i-1].lev); setVal(tr.children("td").eq(6), table[i-1].pakMk); setVal(tr.children("td").eq(7), table[i-1].shuttleNo); } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; } else { console.log(res.msg); } } }); } // 提升机日志输出 ----------------------------------------------------------------------- function getliftOutput() { $.ajax({ url: baseUrl + "/forkLift/output/lift", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { if (res.code === 200) { liftOutput(res.data); } else if (res.code === 403) { window.location.href = baseUrl + "/login"; } else { console.log(res.msg); } } }) } // 任务指令下发 function liftOperator(liftTaskMode) { http.post(baseUrl+"/forkLift/operator/lift", { liftNo: $('input[name="liftSelect"]:checked').val(), liftTaskMode: liftTaskMode, lev: $("#liftLev").val(), sourceStaNo: $("#sourceStaNo").val(), staNo: $("#staNo").val() }, function (res) { layer.msg(res.msg, {icon: 1}); }); } // ------------------------------------------------------------------------------------------------ // 提升机信息表获取 ----- 表一 function initliftStateTable(row) { let line; if (row === undefined){ let one = $('#lift-state-table thead').height(); let total = $('.lift-state').height(); let count = total / one; count = parseInt(count) - 1; liftStateTableBlankRows = count; line = count; } else { line = row; } let html = ""; for (let i = 0; i < line; i ++){ html += " <tr>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " </tr>\n"; } $('#lift-state-table tbody').after(html); } // 提升机数据表获取 ----- 表二 function initliftMsgTable(row) { let line; if (row === undefined){ let one = $('#lift-msg-table thead').height(); let total = $('.lift-msg').height(); let count = total / one; count = parseInt(count) - 1; liftMsgTableBlankRows = count; line = count; } else { line = row; } let html = ""; for (let i = 0; i < line; i ++){ html += " <tr>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " <td></td>\n" + " </tr>\n"; } $('#lift-msg-table tbody').after(html); } // 日志输出框 function liftOutput(content){ liftOutputDom.value += content; liftOutputDom.scrollTop = liftOutputDom.scrollHeight; } // 详情操作 ------------------------------------------------------------------------- var layerDetl; $(document).on('dblclick ','#lift-msg-table tr', function () { var liftNo = $(this).children("td").eq(0).html(); if (liftNo !== null && liftNo !== "") { layerDetl = layer.open({ type: 1, title: false, shadeClose: true, offset: 'rt', anim: 5, shade: [0], area: ['340px', '255px'], closeBtn: 0, content: $("#lift-detl"), success: function(layero, index){ $.ajax({ url: baseUrl+ "/forkLift/table/lift/msg", headers: {'token': localStorage.getItem('token')}, method: 'POST', success: function (res) { if (res.code === 200){ var table = res.data; for (var i=1;i<=table.length;i++){ if (liftNo == table[i-1].liftNo) { $('#liftNo').val(liftNo); $('#workNo').val(table[i-1].workNo); $('#pakMk').val(table[i-1].pakMk); $('#token').val(table[i-1].token); } } } else if (res.code === 403){ window.location.href = baseUrl+"/login"; } else { console.log(res.msg); } } }); }, end: function () { $('#liftNo').val(""); $('#workNo').val(""); $('#pakMk').val(""); $('#token').val(""); } }) } }); $(document).on('click ','#cancel', function () { $('#liftNo').val(""); $('#workNo').val(""); $('#pakMk').val(""); $('#token').val(""); layer.close(layerDetl); }) </script> src/main/webapp/views/index.html
@@ -20,7 +20,7 @@ <ul class="cl-effect-4"> <li><a id="console" onclick="nav(this.id)" class="nav-select" href="#">主控图</a></li> <li><a id="pipeline" onclick="nav(this.id)" class="nav-unselect" href="#">输送设备</a></li> <li><a id="lift" onclick="nav(this.id)" class="nav-unselect" href="#">提升机</a></li> <li><a id="forklift" onclick="nav(this.id)" class="nav-unselect" href="#">提升机</a></li> <!-- <li><a id="ste" onclick="nav(this.id)" class="nav-unselect" href="#">穿梭车</a></li>--> <li><a id="shuttle" onclick="nav(this.id)" class="nav-unselect" href="#">四向穿梭车</a></li> <li><a id="task" onclick="nav(this.id)" class="nav-unselect" href="#">任务管理</a></li> src/main/webapp/views/task.html
@@ -80,18 +80,39 @@ </div> <el-dialog :title="shuttleCommandTitle" :visible.sync="shuttleCommandVisible"> <el-table ref="singleTable" :data="shuttleCommandData.assignCommand.commands" style="width: 100%;" :row-class-name="tableRowClassName"> <el-table-column property="mode" label="命令类型"> <el-table ref="singleTable" :data="shuttleCommandData.commands" style="width: 100%;" :row-class-name="tableRowClassName"> <el-table-column property="mode$" label="命令类型"> </el-table-column> <el-table-column property="start" label="起点"> <template slot-scope="scope"> <div v-if="scope.row.nodes"> x:{{ scope.row.nodes[0].x }} y:{{ scope.row.nodes[0].y }} z:{{ scope.row.nodes[0].z }} </div> </template> </el-table-column> <el-table-column property="target" label="终点"> <template slot-scope="scope"> <div v-if="scope.row.nodes"> x:{{ scope.row.nodes[scope.row.nodes.length-1].x }} y:{{ scope.row.nodes[scope.row.nodes.length-1].y }} z:{{ scope.row.nodes[scope.row.nodes.length-1].z }} </div> </template> </el-table-column> <el-table-column property="taskId" label="taskId"> <el-table-column property="taskNo" label="任务号"> </el-table-column> <el-table-column property="robotId" label="robotId"> <el-table-column property="shuttleNo" label="穿梭车"> </el-table-column> <el-table-column property="complete" label="是否完成"> <template slot-scope="scope"> <el-switch v-model="scope.row.complete" active-color="#13ce66" @change="changeComplete(scope)"> </el-switch> </template> </el-table-column> <el-table-column label="操作" width="100"> <template slot-scope="scope"> @@ -345,6 +366,34 @@ } } }); }, changeComplete(scope) { let that = this; let idx = scope.$index; $.ajax({ url: baseUrl + "/shuttle/command/completeSwitch", headers: { 'token': localStorage.getItem('token') }, data: { wrkNo: that.shuttleCommandWrkNo, commandStep: idx, complete: scope.row.complete ? 1 : 0 }, method: 'GET', success: function(res) { if (res.code == 200) { that.showShuttleCommand(that.shuttleCommandWrkNo) } else if (res.code === 403) { top.location.href = baseUrl + "/"; } else { that.$message({ message: res.msg, type: 'error' }); } } }); } }, })