src/main/java/com/zy/asrs/controller/OpenController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/domain/NotifyDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/domain/enums/NotifyMsgType.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/task/NotifyScheduler.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/asrs/utils/NotifyUtils.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/core/MainProcess.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/zy/core/enums/RedisKeyType.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/zy/asrs/controller/OpenController.java
@@ -1,14 +1,20 @@ package com.zy.asrs.controller; import com.core.common.R; import com.zy.asrs.domain.NotifyDto; import com.zy.asrs.domain.enums.NotifyMsgType; import com.zy.asrs.domain.param.CancelTaskParam; import com.zy.asrs.domain.param.CompleteTaskParam; import com.zy.asrs.domain.param.CreateMoveTaskParam; import com.zy.asrs.utils.NotifyUtils; import com.zy.common.service.CommonService; import com.zy.core.dispatcher.ShuttleDispatchUtils; import com.zy.core.enums.SlaveType; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @Slf4j @RestController @@ -19,6 +25,8 @@ private CommonService commonService; @Autowired private ShuttleDispatchUtils shuttleDispatchUtils; @Autowired private NotifyUtils notifyUtils; @PostMapping("/createMoveTask") public R createMoveTask(@RequestBody CreateMoveTaskParam param) { @@ -56,4 +64,11 @@ return R.error("任务取消失败"); } @GetMapping("/test") public R test() { notifyUtils.notify(String.valueOf(SlaveType.Shuttle), 1, "9999", NotifyMsgType.SHUTTLE_MOVING); notifyUtils.notify(String.valueOf(SlaveType.Shuttle), 2, "9999", NotifyMsgType.SHUTTLE_MOVE_COMPLETE); return R.ok(); } } src/main/java/com/zy/asrs/domain/NotifyDto.java
New file @@ -0,0 +1,37 @@ package com.zy.asrs.domain; import lombok.Data; @Data public class NotifyDto { private Long id; //设备类型 private String deviceType; //设备号 private Integer device; //工作号 private String taskNo; //消息类型 private String msgType; //消息内容 private String content; //失败重试次数 private Integer failTimes = 3; //重试次数 private Integer retryTimes = 0; //重试间隔默认30s private Integer retryTime = 30; //上次重试时间 private Long lastRetryTime = 0L; } src/main/java/com/zy/asrs/domain/enums/NotifyMsgType.java
New file @@ -0,0 +1,47 @@ package com.zy.asrs.domain.enums; public enum NotifyMsgType { SHUTTLE_START_TAKE("shuttle_start_take", "小车开始取货"), SHUTTLE_TRANSPORT("shuttle_transport", "小车送货中"), SHUTTLE_DELIVERY("shuttle_delivery", "小车放货完成"), SHUTTLE_MOVING("shuttle_moving", "小车移动中"), SHUTTLE_MOVE_COMPLETE("shuttle_move_complete", "小车移动完成"), SHUTTLE_POWER_LOW("shuttle_power_low", "小车低电量"), SHUTTLE_POWER_START("shuttle_power_start", "小车开始充电"), SHUTTLE_POWER_COMPLETE("shuttle_power_complete", "小车充电完成"), SHUTTLE_ERROR("shuttle_error", "小车异常"), FORK_LIFT_ERROR("fork_lift_error", "货叉提升机异常"), ; public String flag; public String desc; NotifyMsgType(String flag, String desc) { this.flag = flag; this.desc = desc; } public static NotifyMsgType get(String flag) { if (null == flag) { return null; } for (NotifyMsgType type : NotifyMsgType.values()) { if (type.flag.equals(flag)) { return type; } } return null; } public static NotifyMsgType get(NotifyMsgType type) { if (null == type) { return null; } for (NotifyMsgType type2 : NotifyMsgType.values()) { if (type2 == type) { return type2; } } return null; } } src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -1,9 +1,11 @@ package com.zy.asrs.service.impl; import com.alibaba.fastjson.JSON; import com.zy.asrs.domain.enums.NotifyMsgType; import com.zy.asrs.entity.*; import com.zy.asrs.mapper.*; import com.zy.asrs.service.*; import com.zy.asrs.utils.NotifyUtils; import com.zy.asrs.utils.Utils; import com.zy.common.model.*; import com.zy.common.model.enums.NavigationMapType; @@ -82,6 +84,8 @@ private ShuttleAction shuttleAction; @Autowired private ForkLiftAction forkLiftAction; @Autowired private NotifyUtils notifyUtils; // /** @@ -851,10 +855,12 @@ //310.小车移动中 ==> 311.小车移动完成 wrkMast.setWrkSts(WrkStsType.COMPLETE_MOVE.sts); shuttleThread.setSyncTaskNo(0); notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), NotifyMsgType.SHUTTLE_MOVE_COMPLETE);//触发通知 } else if (wrkMast.getWrkSts() == WrkStsType.CHARGE_SHUTTLE_WORKING.sts) { //204.小车充电中 ==> 205.小车充电完成 wrkMast.setWrkSts(WrkStsType.CHARGE_SHUTTLE_COMPLETE.sts); shuttleThread.setSyncTaskNo(0); notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), NotifyMsgType.SHUTTLE_POWER_COMPLETE);//触发通知 }else { continue; } @@ -1561,206 +1567,6 @@ // } /** * 出库 ===>> 工作档信息写入led显示器 */ public void ledExecute() { // try { // for (LedSlave led : slaveProperties.getLed()) { // // 获取输送线plc线程 // DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, led.getDevpPlcId()); // // 命令集合 // List<LedCommand> commands = new ArrayList<>(); // // 工作档集合 // List<WrkMast> wrkMasts = new ArrayList<>(); // List<WrkMastLog> wrkMastLogs = new ArrayList<>(); // for (Integer staNo : led.getStaArr()) { // // 获取叉车站点 // StaProtocol staProtocol = devpThread.getStation().get(staNo); // if (null == staProtocol || null == staProtocol.getWorkNo() || 0 == staProtocol.getWorkNo() || !staProtocol.isLoading()) { // continue; // } else { // staProtocol = staProtocol.clone(); // } // // 获取工作档数据 // WrkMast wrkMast = wrkMastMapper.selectById(staProtocol.getWorkNo()); // Integer wrkNo = staProtocol.getWorkNo().intValue(); // Integer ioType = null; // String sourceLocNo = null; // String locNo = null; // Integer wrkStaNo = null; // String barcode = null; // if (wrkMast == null) { // //查询历史档 // WrkMastLog wrkMastLog = wrkMastLogMapper.selectLatestByWorkNo(staProtocol.getWorkNo().intValue()); // if (wrkMastLog == null) { // continue; // } // ioType = wrkMastLog.getIoType(); // sourceLocNo = wrkMastLog.getSourceLocNo(); // locNo = wrkMastLog.getLocNo(); // wrkStaNo = wrkMastLog.getStaNo(); // barcode = wrkMastLog.getBarcode(); // wrkMastLogs.add(wrkMastLog); // }else { // if (wrkMast.getWrkSts() < 14 || wrkMast.getIoType() < 100) { // continue; // } // ioType = wrkMast.getIoType(); // sourceLocNo = wrkMast.getSourceLocNo(); // locNo = wrkMast.getLocNo(); // wrkStaNo = wrkMast.getStaNo(); // barcode = wrkMast.getBarcode(); // wrkMasts.add(wrkMast); // } // // 组装命令 // LedCommand ledCommand = new LedCommand(); // ledCommand.setWorkNo(wrkNo); // ledCommand.setIoType(ioType); // // 出库模式 // switch (ioType) { // case 101: // ledCommand.setTitle("全板出库"); // break; // case 103: // ledCommand.setTitle("拣料出库"); // break; // case 104: // ledCommand.setTitle("并板出库"); // break; // case 107: // ledCommand.setTitle("盘点出库"); // break; // case 110: // ledCommand.setTitle("空板出库"); // ledCommand.setEmptyMk(true); // break; // default: // News.error("任务入出库类型错误!!![工作号:{}] [入出库类型:{}]", wrkNo, ioType); // break; // } // ledCommand.setSourceLocNo(sourceLocNo); // ledCommand.setLocNo(locNo); // ledCommand.setStaNo(wrkStaNo); // ledCommand.setBarcode(barcode); // if (ioType != 110 && ioType != 10) { // List<WrkDetl> wrkDetls = wrkDetlService.selectList(new EntityWrapper<WrkDetl>().eq("wrk_no", wrkNo)); // if (!wrkDetls.isEmpty()) { // wrkDetls.forEach(wrkDetl -> { // double remainNum = wrkDetl.getStock() - wrkDetl.getAnfme();//剩余数量 // if (remainNum < 0) { // remainNum = 0; // } // String matnr = wrkDetl.getMatnr(); // Mat mat = matService.selectByMatnr(wrkDetl.getMatnr()); // if (mat != null) { // if (!mat.getMatnr().equals(mat.getMatnr2())) { // matnr += " - " + mat.getMatnr2(); // } // } // ledCommand.getMatDtos().add(new MatDto(matnr, wrkDetl.getMaktx(), wrkDetl.getAnfme(), remainNum, wrkDetl.getSpecs(), wrkDetl.getSuppCode(), wrkDetl.getOrderNo())); // }); // }else { // List<WrkDetlLog> wrkDetlLogs = wrkDetlLogService.selectLatestByWorkNo(wrkNo, barcode); // for (WrkDetlLog wrkDetlLog : wrkDetlLogs) { // double remainNum = wrkDetlLog.getStock() - wrkDetlLog.getAnfme();//剩余数量 // if (remainNum < 0) { // remainNum = 0; // } // String matnr = wrkDetlLog.getMatnr(); // Mat mat = matService.selectByMatnr(wrkDetlLog.getMatnr()); // if (mat != null) { // if (!mat.getMatnr().equals(mat.getMatnr2())) { // matnr += " - " + mat.getMatnr2(); // } // } // ledCommand.getMatDtos().add(new MatDto(matnr, wrkDetlLog.getMaktx(), wrkDetlLog.getAnfme(), remainNum, wrkDetlLog.getSpecs(), wrkDetlLog.getSuppCode())); // } // } // commands.add(ledCommand); // } // Set<Integer> workNos = null; // if (!wrkMasts.isEmpty()) { // workNos = wrkMasts.stream().map(WrkMast::getWrkNo).collect(Collectors.toSet()); // }else { // workNos = wrkMastLogs.stream().map(WrkMastLog::getWrkNo).collect(Collectors.toSet()); // } // // 获取LED线程 // LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, led.getId()); // // 相同工作号集合则过滤 // if (CollectionUtils.equals(ledThread.getWorkNos(), workNos)) { // continue; // } // // 命令下发 ------------------------------------------------------------------------------- // if (!commands.isEmpty()) { // if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(1, commands))) { // log.error("{}号LED命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort()); // continue; // } else { // ledThread.setLedMk(false); // } // } // // try { // // 修改主档led标记 // for (WrkMast wrkMast : wrkMasts) { // wrkMast.setOveMk("Y"); // wrkMast.setModiTime(new Date()); // if (wrkMastMapper.updateById(wrkMast) == 0) { // throw new CoolException("更新工作档失败"); // } // } // // // 更新线程当前工作号集合 // ledThread.setWorkNos(workNos); // // } catch (Exception e) { // e.printStackTrace(); // TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); // } // // } // } catch (Exception e) { // e.printStackTrace(); // } } /** * 其他 ===>> LED显示器复位,显示默认信息 */ public void ledReset() { // try { // for (LedSlave led : slaveProperties.getLed()) { // // 获取输送线plc线程 // DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, led.getDevpPlcId()); // // 命令集合 // boolean reset = true; // for (Integer staNo : led.getStaArr()) { // // 获取叉车站点 // StaProtocol staProtocol = devpThread.getStation().get(staNo); // if (staProtocol == null) { // continue; // } // if (staProtocol.isLoading()) { // reset = false; // break; // } // } // // 获取led线程 // LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, led.getId()); // // led显示默认内容 // if (reset) { // ledThread.setLedMk(true); // if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(2, new ArrayList<>()))) { // log.error("{}号LED命令下发失败!!![ip:{}] [port:{}]", led.getId(), led.getIp(), led.getPort()); // } // } // } // } catch (Exception e) { // e.printStackTrace(); // } } /** * 四向穿梭车电量检测 ===>> 发起充电 */ public synchronized void loopShuttleCharge() { @@ -1988,6 +1794,8 @@ //下发任务 shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand); notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), NotifyMsgType.SHUTTLE_POWER_START);//触发通知 return false; } return true; @@ -2188,6 +1996,8 @@ if (wrkMastService.updateById(wrkMast)) { //下发任务 shuttleAction.assignWork(shuttleProtocol.getShuttleNo(), assignCommand); //触发通知 notifyUtils.notify(String.valueOf(SlaveType.Shuttle), shuttleProtocol.getShuttleNo(), String.valueOf(wrkMast.getWrkNo()), NotifyMsgType.SHUTTLE_MOVING); return false; } return false; @@ -2402,41 +2212,5 @@ } return true; } // //扫描设备PakMk标记是否超时 // public synchronized void scanDevicePakMk() { // try { // //扫描小车 // for (ShuttleSlave slave : slaveProperties.getShuttle()) { // NyShuttleThread shuttleThread = (NyShuttleThread) SlaveConnection.get(SlaveType.Shuttle, slave.getId()); // NyShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol(); // if (shuttleProtocol == null) { // continue; // } // // if ((System.currentTimeMillis() - shuttleProtocol.getSendTime() > (1000 * 60 * 5)) && shuttleProtocol.getPakMk()) { // //设备超过5分钟还没复位标记 // shuttleProtocol.setPakMk(false);//复位标记 // } // } // // //扫描提升机 // for (LiftSlave slave : slaveProperties.getLift()) { // LiftThread liftThread = (LiftThread) SlaveConnection.get(SlaveType.Lift, slave.getId()); // LiftProtocol liftProtocol = liftThread.getLiftProtocol(); // if (liftProtocol == null) { // continue; // } // // if ((System.currentTimeMillis() - liftProtocol.getSendTime() > (1000 * 60 * 5)) && liftProtocol.getPakMk()) { // //设备超过5分钟还没复位标记 // liftProtocol.setPakMk(false);//复位标记 // } // } // } catch (Exception e) { // e.printStackTrace(); // } // // } } src/main/java/com/zy/asrs/task/NotifyScheduler.java
New file @@ -0,0 +1,126 @@ package com.zy.asrs.task; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.zy.asrs.domain.NotifyDto; import com.zy.asrs.utils.NotifyUtils; import com.zy.common.utils.HttpHandler; import com.zy.common.utils.RedisUtil; import com.zy.core.enums.SlaveType; import com.zy.core.model.ForkLiftSlave; import com.zy.core.model.ShuttleSlave; import com.zy.core.properties.SlaveProperties; import com.zy.system.entity.Config; import com.zy.system.service.ConfigService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.List; @Component @Slf4j public class NotifyScheduler { @Autowired private RedisUtil redisUtil; @Autowired private NotifyUtils notifyUtils; @Autowired private SlaveProperties slaveProperties; @Autowired private ConfigService configService; @Scheduled(cron = "0/3 * * * * ? ") public synchronized void notifyShuttle(){ for (ShuttleSlave slave : slaveProperties.getShuttle()) { notifyMsg(String.valueOf(SlaveType.Shuttle), slave.getId()); } } @Scheduled(cron = "0/3 * * * * ? ") public synchronized void notifyForkLift(){ for (ForkLiftSlave slave : slaveProperties.getForkLift()) { notifyMsg(String.valueOf(SlaveType.ForkLift), slave.getId()); } } private synchronized void notifyMsg(String deviceType, Integer device) { Config notifyEnableConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "notifyEnable")); if(notifyEnableConfig == null){ return; } String notifyEnable = notifyEnableConfig.getValue(); if (!notifyEnable.equals("Y")) { return; } Config notifyUriConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "notifyUri")); if(notifyUriConfig == null){ return; } String notifyUri = notifyUriConfig.getValue(); Config notifyUriPathConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "notifyUriPath")); if(notifyUriPathConfig == null){ return; } String notifyUriPath = notifyUriPathConfig.getValue(); List<String> keys = notifyUtils.takeKeys(deviceType, device); if(keys == null){ return; } if (keys.isEmpty()) { return; } for (String key : keys) { Object object = redisUtil.get(key); if (object == null) { continue; } NotifyDto notifyDto = (NotifyDto) object; if (System.currentTimeMillis() - notifyDto.getLastRetryTime() < 1000 * notifyDto.getRetryTime()) { continue; } try { //触发通知 String response = new HttpHandler.Builder() .setUri(notifyUri) .setPath(notifyUriPath) .setJson(JSON.toJSONString(notifyDto)) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(response); Integer code = jsonObject.getInteger("code"); if(code == 200){ //通知成功 redisUtil.del(key); return; } }catch (Exception e){ e.printStackTrace(); } //通知失败 int times = notifyDto.getRetryTimes() + 1; if (times >= notifyDto.getFailTimes()) { //超过次数 redisUtil.del(key); return; } notifyDto.setLastRetryTime(System.currentTimeMillis()); notifyDto.setRetryTimes(times); redisUtil.set(key, notifyDto); return; } } } src/main/java/com/zy/asrs/utils/NotifyUtils.java
New file @@ -0,0 +1,113 @@ package com.zy.asrs.utils; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.SnowflakeIdWorker; import com.zy.asrs.domain.NotifyDto; import com.zy.asrs.domain.enums.NotifyMsgType; import com.zy.common.utils.RedisUtil; import com.zy.core.enums.RedisKeyType; import com.zy.core.enums.SlaveType; import com.zy.system.entity.Config; import com.zy.system.service.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Set; @Component public class NotifyUtils { @Autowired private RedisUtil redisUtil; @Autowired private SnowflakeIdWorker snowflakeIdWorker; @Autowired private ConfigService configService; public synchronized boolean notify(String deviceType, Integer device, String taskNo, NotifyMsgType msgType) { SlaveType type = SlaveType.findInstance(deviceType); if (type == null) { return false; } return append(type, device, taskNo, msgType); } public synchronized List<String> takeKeys(String deviceType, Integer device) { String key = getKey(deviceType, device); if(key == null){ return null; } Set keys = redisUtil.keys(key + "*"); if (keys == null) { return null; } List<String> list = new ArrayList<>(); for (Object object : keys) { list.add(object.toString()); } return list; } public String getKey(String deviceType, Integer device) { SlaveType type = SlaveType.findInstance(deviceType); if (type == null) { return null; } String key = null; switch (type) { case Shuttle: key = RedisKeyType.QUEUE_SHUTTLE.key + device; break; case ForkLift: key = RedisKeyType.QUEUE_FORK_LIFT.key + device; break; default: return null; } return key; } private boolean append(SlaveType deviceType, Integer device, String taskNo, NotifyMsgType msgType) { String key = null; switch (deviceType) { case Shuttle: key = RedisKeyType.QUEUE_SHUTTLE.key + device; break; case ForkLift: key = RedisKeyType.QUEUE_FORK_LIFT.key + device; break; default: return false; } NotifyDto dto = new NotifyDto(); dto.setId(snowflakeIdWorker.nextId()); dto.setDeviceType(String.valueOf(deviceType)); dto.setDevice(device); dto.setMsgType(msgType.flag); dto.setContent(msgType.desc); dto.setTaskNo(taskNo); //重试次数 Config notifyFailTimesConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "notifyFailTimes")); if (notifyFailTimesConfig != null) { dto.setFailTimes(Integer.parseInt(notifyFailTimesConfig.getValue())); } //重试间隔 Config notifyRetryTimeConfig = configService.selectOne(new EntityWrapper<Config>().eq("code", "notifyRetryTime")); if (notifyRetryTimeConfig != null) { dto.setRetryTime(Integer.parseInt(notifyRetryTimeConfig.getValue())); } redisUtil.set(key + "_" + dto.getId(), dto); return true; } } src/main/java/com/zy/core/MainProcess.java
@@ -66,16 +66,9 @@ mainService.recErr(); // // 入库 ===>> 空栈板初始化入库,叉车入库站放货 // mainService.storeEmptyPlt(); // // 出库 ===>> 工作档信息写入led显示器 // mainService.ledExecute(); // // 其他 ===>> LED显示器复位,显示默认信息 // mainService.ledReset(); // 穿梭车 ===>> 小车电量检测充电 mainService.loopShuttleCharge(); mainService.executeShuttleCharge(); // //扫描设备PakMk标记是否超时 // mainService.scanDevicePakMk(); // 间隔 Thread.sleep(200); src/main/java/com/zy/core/enums/RedisKeyType.java
@@ -8,6 +8,8 @@ FORK_LIFT_FLAG("fork_lift_"), MAP("realtimeBasMap_"), BASIC_MAP("basicMap_"), QUEUE_SHUTTLE("queue_shuttle_"), QUEUE_FORK_LIFT("queue_fork_lift_"), ; public String key;