#
zjj
2024-07-22 3c7c81ce7f573322c46618aabd455a2d06fe879a
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java
@@ -15,9 +15,7 @@
import com.zy.asrs.wcs.core.entity.*;
import com.zy.asrs.wcs.core.kernel.AnalyzeService;
import com.zy.asrs.wcs.core.model.MapNode;
import com.zy.asrs.wcs.core.model.enums.DeviceCtgType;
import com.zy.asrs.wcs.core.model.enums.MotionStsType;
import com.zy.asrs.wcs.core.model.enums.TaskStsType;
import com.zy.asrs.wcs.core.model.enums.*;
import com.zy.asrs.wcs.core.service.*;
import com.zy.asrs.wcs.core.utils.RedisUtil;
import com.zy.asrs.wcs.core.utils.ShuttleDispatcher;
@@ -79,7 +77,13 @@
    @Autowired
    private BasConveyorService basConveyorService;
    @Autowired
    private BasConveyorStaService basConveyorStaService;
    @Autowired
    private BasConveyorPathService basConveyorPathService;
    @Autowired
    private BasLedService basLedService;
    @Autowired
    private DeviceBarcodeService deviceBarcodeService;
    /**
     * 组托
@@ -177,7 +181,7 @@
                        //获取入库任务类型
                        TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>()
                                .eq(TaskCtg::getFlag, "IN")
                                .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.IN))
                                .eq(TaskCtg::getStatus, 1));
                        // 判断重复工作档
@@ -216,10 +220,19 @@
                            Integer code = jsonObject.getInteger("code");
                            if (code.equals(200)) {
                                StartupDto dto = jsonObject.getObject("data", StartupDto.class);
                                devpThread.writeWorkSta(staProtocol.getSiteId(), dto.getWorkNo().shortValue(), dto.getStaNo().shortValue());
                                devpThread.setPakMk(staProtocol.getSiteId(), false);
                            } else if (code == 500) {
                                //获取输送路径
                                BasConveyorPath conveyorPath = basConveyorPathService.getOne(new LambdaQueryWrapper<BasConveyorPath>()
                                        .eq(BasConveyorPath::getTypeNo, TaskCtgType.IN.val())
                                        .eq(BasConveyorPath::getDeviceId, devp.getId())
                                        .eq(BasConveyorPath::getStnNo, staProtocol.getSiteId()));
                                if (conveyorPath == null) {
                                    News.error("输送路径不存在");
                                }else {
                                    devpThread.writeWorkSta(staProtocol.getSiteId(), dto.getWorkNo().shortValue(), conveyorPath.getDeviceStn().shortValue());
                                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                                }
                            }else {
                                if (ledThread != null) {
                                    String errorMsg = jsonObject.getString("msg");
                                    if (!Cools.isEmpty(errorMsg)) {
@@ -228,18 +241,6 @@
                                    }
                                }
                                News.error("请求接口失败!!!url:{};request:{};response:{}", wmsUrl + "/rpc/pakin/loc/v2", JSON.toJSONString(param), response);
                            } else if (code == 700) {
//                            staProtocol.setWorkNo((short) 32002);
//                            staProtocol.setRollback102(1);//102站回退信号
//                            devpThread.setPakMk(staProtocol.getSiteId(), false);
//                            MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(5, staProtocol));
                                // led 异常显示
                                if (ledThread != null) {
                                    String errorMsg = barcode + "托盘识别异常,请先进行组托!";
                                    ledThread.error(errorMsg);
                                    ledThread.setLedMk(false);
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
@@ -266,6 +267,11 @@
            for (Dict dict : dicts) {
                String[] split = dict.getFlag().split("-");
                int lev = Integer.parseInt(split[1]);
                Object data = redisUtil.get(DeviceRedisConstant.MAP + lev);
                if (data != null) {
                    continue;
                }
                TreeMap<Integer, List<JSONObject>> rows = new TreeMap<>();
                //排序Row
@@ -372,6 +378,19 @@
                    list.add(mapNode.clone());
                }
                //最后一次检测地图节点是否完整,地图矩阵row均要达到最长row
                for (ArrayList<MapNode> list : lists) {
                    int len = (row + 2);//row+2是因为头节点和尾节点存在人为添加的-1节点
                    if (list.size() == len) {
                        continue;
                    }
                    //节点长度不满足,进行补足
                    for (int i = list.size(); i < len; i++) {
                        list.add(mapNode.clone());
                    }
                }
                ArrayList<MapNode> headNodes = new ArrayList<>();
                ArrayList<MapNode> footerNodes = new ArrayList<>();
                for (int i = 0; i < row+2; i++) {
@@ -390,11 +409,8 @@
                map.setUpdateTime(now);
                map.setLev(lev);
                Object data = redisUtil.get(DeviceRedisConstant.MAP + lev);
                if (data == null) {
                    //将地图数据存入redis
                    redisUtil.set(DeviceRedisConstant.MAP + lev, JSON.toJSONString(map));
                }
                //将地图数据存入redis
                redisUtil.set(DeviceRedisConstant.MAP + lev, JSON.toJSONString(map));
            }
        } catch (Exception e) {
            e.printStackTrace();
@@ -404,18 +420,113 @@
    // 解析入库工作档
    public synchronized void analyzeInBoundTask() {
        for (Task task : taskService.selectWaitAnalyzeInBoundTask()) {
            // generate motion list
            List<Motion> motionList = analyzeService.generateMotion(task);
            if (motionList.isEmpty()) {
            BasConveyorSta basConveyorSta = basConveyorStaService.getOne(new LambdaQueryWrapper<BasConveyorSta>().eq(BasConveyorSta::getSiteNo, task.getDestSite()));
            if (basConveyorSta == null) {
                log.error("解析入库任务退出,输送");
                continue;
            }
            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()));
            BasConveyor basConveyor = basConveyorService.getById(basConveyorSta.getConveyorId());
            if (basConveyor == null) {
                log.error("解析入库任务退出,输送2");
                continue;
            }
            DeviceBarcode deviceBarcode = deviceBarcodeService.getById(basConveyorSta.getBarcodeId());
            if (deviceBarcode == null) {
                log.error("解析入库任务退出,条码");
                continue;
            }
            BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, Integer.parseInt(deviceBarcode.getDeviceId()));
            if (barcodeThread == null) {
                log.error("解析入库任务退出,条码线程");
                continue;
            }
            if (!barcodeThread.getBarcode().equals(task.getZpallet())) {
                log.error("解析入库任务退出,条码不符合");
                continue;
            }
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue());
            if (devpThread == null) {
                log.error("解析入库任务退出,输送线程");
                continue;
            }
            StaProtocol staProtocol = devpThread.getStation().get(basConveyorSta.getSiteNo());
            if (staProtocol == null) {
                log.error("解析入库任务退出,输送站点");
                continue;
            }
            if (!(staProtocol.isAutoing()
                    && staProtocol.isLoading()
                    && staProtocol.isInEnable())) {
                log.error("解析入库任务退出,输送信号不符合:"+staProtocol.isAutoing()+","+staProtocol.isLoading()+","+staProtocol.isInEnable());
                continue;
            }
            if (Cools.isEmpty(task.getShuttleNo())) {
                //分配小车
                //搜索空闲车
                ShuttleThread shuttleThread = shuttleDispatcher.searchIdleShuttle(task);
                if (shuttleThread == null) {
                    News.info("{}任务未找到空闲穿梭车", task.getTaskNo());
                    continue;
                }
                task.setShuttleNo(Integer.valueOf(shuttleThread.getDevice().getDeviceNo()));//保存穿梭车号
                task.setUpdateTime(new Date());
                if (!taskService.updateById(task)) {
                    News.info("{}任务更新穿梭车号失败", task.getTaskNo());
                }
                continue;
            }
            // generate motion list
            List<Motion> motionList = null;
            try {
                motionList = analyzeService.generateMotion(task);
            }catch (Exception e) {
                log.error("motion解析出错:"+e.getMessage());
                continue;
            }
            if (motionList.isEmpty()) {
                log.error("motion为空退出");
                continue;
            }
            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()), task.getHostId());
            // 更新工作主档
            task.setTaskSts(TaskStsType.ANALYZE_INBOUND.sts); // 工作状态
            task.setUpdateTime(new Date());
            if (!taskService.updateById(task)) {
                News.error("更新工作档失败!!! [工作号:{}]", task.getTaskNo());
            }else {
                if ("0601".equals(task.getMemo().substring(0,4))){
                    String response = "";
                    Map<String, Object> headers = new HashMap<>();
                    headers.put("Content-Type", "application/json;charset=UTF-8");
                    headers.put("X-lr-request-id", task.getWmsTaskNo());
                    headers.put("X-lr-version", 4.1);
                    headers.put("X-lr-trace-id", "{{$guid}}");
                    Map<String, Object> map = new HashMap<>();
                    map.put("carrierCode",task.getZpallet());
                    map.put("siteCode","06YZ0001");
                    map.put("extra",null);
                    try {
                        response = new HttpHandler.Builder()
                                .setHeaders(headers)
                                .setUri("172.18.16.248:443")
                                .setHttps(true)
                                .setPath("/rcs/rtas/api/robot/controller/carrier/unbind")
                                .setJson(JSONObject.toJSONString(map))
                                .build()
                                .doPost();
                        JSONObject jsonObject = JSON.parseObject(response);
                        log.info("agv解绑箱号,请求体:"+JSONObject.toJSONString(map)+",返回:"+response);
                    }catch (Exception e){
                        log.info("agv解绑箱号请求报错"+e.getMessage());
                    }
                }
            }
        }
    }
@@ -423,35 +534,38 @@
    /**
     * 出库 ====>> 同一时间一台穿梭车只能有一个出库任务
     */
    public synchronized void generateOutboundWrkMast() {
    public synchronized void analyzeOutBoundTask() {
        List<Task> tasks = taskService.selectPakOut();
        if (tasks.isEmpty()) {
            return;
        }
        for (Task task : tasks) {
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, 1);
            BasConveyorSta originStaObj = basConveyorStaService.selectBySiteNo(task.getOriginSite());//获取源站
            if (originStaObj == null) {
                continue;
            }
            BasConveyor basConveyor = basConveyorService.getById(originStaObj.getConveyorId());
            if(basConveyor == null) {
                continue;
            }
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue());
            StaProtocol staProtocol = devpThread.getStation().get(Integer.parseInt(task.getOriginSite()));//源站
            StaProtocol staProtocol1 = devpThread.getStation().get(Integer.parseInt(task.getDestSite()));//目标站
            if (staProtocol == null || staProtocol1 == null) {
//            StaProtocol staProtocol1 = devpThread.getStation().get(Integer.parseInt(task.getDestSite()));//目标站
            if (staProtocol == null) {
                continue;
            } else {
                staProtocol = staProtocol.clone();
                staProtocol1 = staProtocol1.clone();
//                staProtocol1 = staProtocol1.clone();
            }
//            // 查询站点详细信息
//            BasDevp staDetl = basDevpService.selectById(outSta.getStaNo());
//            if (staDetl == null) {
//                log.error("出库 ===>> 站点在数据库不存在, 站点编号={}", outSta.getStaNo());
//                continue;
//            }
            // 判断堆垛机出库站状态
            if (staProtocol.isAutoing() && !staProtocol.isLoading() && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) {
                if (!(staProtocol1.isAutoing() && !staProtocol1.isLoading() && staProtocol1.getWorkNo() == 0 && staProtocol1.isOutEnable())) {
                    continue;
                }
//                if (!(staProtocol1.isAutoing() && !staProtocol1.isLoading() && staProtocol1.getWorkNo() == 0 && staProtocol1.isOutEnable())) {
//                    continue;
//                }
//                //同库位组校验
//                List<String> outerLoc = Utils.getGroupOuterLoc(wrkMast.getSourceLocNo());
@@ -461,13 +575,30 @@
//                    continue;//浅库位存在未执行任务
//                }
                if (Cools.isEmpty(task.getShuttleNo())) {
                    //分配小车
                    //搜索空闲车
                    ShuttleThread shuttleThread = shuttleDispatcher.searchIdleShuttle(task);
                    if (shuttleThread == null) {
                        News.info("{}任务未找到空闲穿梭车", task.getTaskNo());
                        continue;
                    }
                    task.setShuttleNo(Integer.valueOf(shuttleThread.getDevice().getDeviceNo()));//保存穿梭车号
                    task.setUpdateTime(new Date());
                    if (!taskService.updateById(task)) {
                        News.info("{}任务更新穿梭车号失败", task.getTaskNo());
                    }
                    continue;
                }
                // generate motion list
                List<Motion> motionList = analyzeService.generateMotion(task);
                if (Cools.isEmpty(motionList)) {
                    log.error("出库 ===>> 暂时没有空闲小车, 任务号={}", task.getTaskNo());
                    continue;
                }
                motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()));
                motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()), task.getHostId());
                // 更新工作主档
                task.setTaskSts(TaskStsType.ANALYZE_OUTBOUND.sts); // 工作状态
@@ -480,21 +611,85 @@
        }
    }
    // 解析小车移动工作档
    public synchronized void analyzeMoveTask() {
        for (Task task : taskService.selectWaitAnalyzeMoveTask()) {
            if (Cools.isEmpty(task.getShuttleNo())) {
                //分配小车
                //搜索空闲车
                ShuttleThread shuttleThread = shuttleDispatcher.searchIdleShuttle(task);
                if (shuttleThread == null) {
                    News.info("{}任务未找到空闲穿梭车", task.getTaskNo());
                    continue;
                }
                task.setShuttleNo(Integer.valueOf(shuttleThread.getDevice().getDeviceNo()));//保存穿梭车号
                task.setUpdateTime(new Date());
                if (!taskService.updateById(task)) {
                    News.info("{}任务更新穿梭车号失败", task.getTaskNo());
                }
                continue;
            }
            // generate motion list
            List<Motion> motionList = analyzeService.generateShuttleMoveMotion(task);
            if (motionList.isEmpty()) {
                continue;
            }
            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()), task.getHostId());
            // 更新工作主档
            task.setTaskSts(TaskStsType.ANALYZE_MOVE.sts); // 工作状态
            task.setUpdateTime(new Date());
            if (!taskService.updateById(task)) {
                News.error("更新工作档失败!!! [工作号:{}]", task.getTaskNo());
            }
        }
    }
    // 解析小车载货移动工作档
    public synchronized void analyzeLadenMoveTask() {
        for (Task task : taskService.selectWaitAnalyzeLadenMoveTask()) {
            if (Cools.isEmpty(task.getShuttleNo())) {
                //分配小车
                //搜索空闲车
                ShuttleThread shuttleThread = shuttleDispatcher.searchIdleShuttle(task);
                if (shuttleThread == null) {
                    News.info("{}任务未找到空闲穿梭车", task.getTaskNo());
                    continue;
                }
                task.setShuttleNo(Integer.valueOf(shuttleThread.getDevice().getDeviceNo()));//保存穿梭车号
                task.setUpdateTime(new Date());
                if (!taskService.updateById(task)) {
                    News.info("{}任务更新穿梭车号失败", task.getTaskNo());
                }
                continue;
            }
            // generate motion list
            List<Motion> motionList = analyzeService.generateShuttleLadenMoveMotion(task);
            if (motionList.isEmpty()) {
                continue;
            }
            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()), task.getHostId());
            // 更新工作主档
            task.setTaskSts(TaskStsType.ANALYZE_LADEN_MOVE.sts); // 工作状态
            task.setUpdateTime(new Date());
            if (!taskService.updateById(task)) {
                News.error("更新工作档失败!!! [工作号:{}]", task.getTaskNo());
            }
        }
    }
    /**
     * 四向穿梭车电量检测 ===>> 发起充电
     */
    public synchronized void loopShuttleCharge() {
        // 获取充电桩库位类型
        LocCtg locCtg = locCtgService.getOne(new LambdaQueryWrapper<LocCtg>()
                .eq(LocCtg::getFlag, "CHARGE")
                .eq(LocCtg::getStatus, 1));
        if (locCtg == null) {
            return;
        }
        //获取充电任务类型
        TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>()
                .eq(TaskCtg::getFlag, "CHARGE")
                .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.CHARGE))
                .eq(TaskCtg::getStatus, 1));
        if (taskCtg == null) {
            return;
@@ -528,7 +723,7 @@
            //搜索小车当前楼层充电桩
            ArrayList<Loc> allChargeLoc = new ArrayList<>();
            List<Loc> list1 = locService.list(new LambdaQueryWrapper<Loc>()
                    .eq(Loc::getLocCtg, locCtg.getId())
                    .eq(Loc::getLocSts, LocStsType.C.val())
                    .eq(Loc::getStatus, 1)
                    .eq(Loc::getLev, lev));
            if (!list1.isEmpty()) {
@@ -537,7 +732,7 @@
            //搜索其他楼层充电桩
            List<Loc> list2 = locService.list(new LambdaQueryWrapper<Loc>()
                    .eq(Loc::getLocCtg, locCtg.getId())
                    .eq(Loc::getLocSts, LocStsType.C.val())
                    .eq(Loc::getStatus, 1)
                    .notIn(Loc::getLev, lev));
            if (!list2.isEmpty()) {
@@ -612,7 +807,7 @@
                News.error("保存{}号四向穿梭车充电任务失败!!!", device.getDeviceNo());
                continue;
            }
            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()));
            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()), task.getHostId());
            task.setTaskSts(TaskStsType.ANALYZE_CHARGE.sts);
            if (!taskService.save(task)) {
@@ -638,7 +833,7 @@
        //获取迁移任务类型
        TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>()
                .eq(TaskCtg::getFlag, "MOVE")
                .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.MOVE))
                .eq(TaskCtg::getStatus, 1));
        if (taskCtg == null) {
            return;
@@ -707,7 +902,7 @@
                News.error("保存{}号四向穿梭车迁移任务失败!!!", device.getDeviceNo());
                continue;
            }
            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()));
            motionService.batchInsert(motionList, task.getUuid(), Integer.valueOf(task.getTaskNo()), task.getHostId());
            task.setTaskSts(TaskStsType.ANALYZE_MOVE.sts);
@@ -736,8 +931,13 @@
                    .eq(BasLed::getDeviceId, ledDevice.getId()));
            List<Integer> staArr = JSON.parseArray(led.getSta(), Integer.class);
            BasConveyor basConveyor = basConveyorService.getById(led.getConveyorId().intValue());
            if (basConveyor == null) {
                continue;
            }
            // 获取输送线plc线程
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, led.getConveyorId().intValue());
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue());
            // 命令集合
            List<LedCommand> commands = new ArrayList<>();
            // 工作档集合
@@ -817,8 +1017,13 @@
                    .eq(BasLed::getDeviceId, ledDevice.getId()));
            List<Integer> staArr = JSON.parseArray(led.getSta(), Integer.class);
            BasConveyor basConveyor = basConveyorService.getById(led.getConveyorId().intValue());
            if (basConveyor == null) {
                continue;
            }
            // 获取输送线plc线程
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, led.getConveyorId().intValue());
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue());
            // 命令集合
            boolean reset = true;
            for (Integer staNo : staArr) {
@@ -847,8 +1052,13 @@
                    .eq(BasLed::getDeviceId, ledDevice.getId()));
            List<Integer> staArr = JSON.parseArray(led.getSta(), Integer.class);
            BasConveyor basConveyor = basConveyorService.getById(led.getConveyorId());
            if (basConveyor == null) {
                continue;
            }
            // 获取输送线plc线程
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, led.getConveyorId().intValue());
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue());
            // 命令集合
            boolean reset = true;
            for (Integer staNo : staArr) {