野心家
2024-12-24 770d716304e32d4da8e74bb70c8907d7e0fd922b
完善wcs
18个文件已修改
1个文件已添加
2851 ■■■■ 已修改文件
pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ConsoleController.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/CrnController.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 597 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/News.java 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/MainProcess.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/ServerBootstrap.java 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/CrnModeType.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/CrnStatusType.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/DevpSlave.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/CrnProtocol.java 319 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/StaProtocol.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/SiemensCrnThread.java 506 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/SiemensDevpThread.java 293 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-prod.yml 164 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/wcs/js/common.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/wcs/js/console.map.js 661 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/wms/js/common.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -9,7 +9,7 @@
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.zy</groupId>
    <artifactId>jdzwcs</artifactId>
    <artifactId>dtwcs</artifactId>
    <version>1.0.0</version>
    <packaging>war</packaging>
@@ -200,7 +200,7 @@
    </dependencies>
    <build>
        <finalName>jdzwcs</finalName>
        <finalName>dtwcs</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
src/main/java/com/zy/asrs/controller/ConsoleController.java
@@ -147,7 +147,7 @@
            /**
             * 堆垛机状态判断
             */
            if (crnProtocol.getAlarm1() > 0) {
            if (crnProtocol.getAlarm() > 0) {
                vo.setCrnStatus(CrnStatusType.MACHINE_ERROR);
            } else {
                if (crnProtocol.getTaskNo()>0) {
@@ -223,7 +223,7 @@
            map.put("device", "堆垛机");
            map.put("deviceId", crn.getId());
            map.put("battery", "");
            map.put("error", crnProtocol.getFault());
            map.put("error", crnProtocol.getAlarm());
            map.put("status", crnProtocol.getStatusType().desc);
            list.add(map);
        }
@@ -324,8 +324,8 @@
                vo.setWorkNo(crnProtocol.getTaskNo());
                vo.setCrnStatus(crnProtocol.getStatusType().desc);
                if (crnProtocol.getAlarm1() > 0) {
                    BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm1());
                if (crnProtocol.getAlarm() > 0) {
                    BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm());
                    vo.setError(crnError == null ? "未知异常" : crnError.getErrName());
                }
src/main/java/com/zy/asrs/controller/CrnController.java
@@ -130,7 +130,7 @@
            vo.setForkOffset(crnProtocol.getForkPosType().desc);    // 货叉位置
            vo.setLiftPos(crnProtocol.getLiftPosType().desc);
            vo.setWalkPos(crnProtocol.getWalkPos()==1?"不在定位":"在定位");
            vo.setWarnCode(String.valueOf(crnProtocol.getAlarm1()));
            vo.setWarnCode(String.valueOf(crnProtocol.getAlarm()));
            if (crnProtocol.getAlarm() > 0) {
                BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm());
                vo.setAlarm(crnError==null?"未知异常":crnError.getErrName());
@@ -165,9 +165,9 @@
        vo.setForkOffset(crnProtocol.getForkPosType().desc);    // 货叉位置
        vo.setLiftPos(crnProtocol.getLiftPosType().desc);
        vo.setWalkPos(crnProtocol.getWalkPos()==1?"不在定位":"在定位");
        vo.setWarnCode(String.valueOf(crnProtocol.getAlarm1()));
        if (crnProtocol.getAlarm1() > 0) {
            BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm1());
        vo.setWarnCode(String.valueOf(crnProtocol.getAlarm()));
        if (crnProtocol.getAlarm() > 0) {
            BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm());
            vo.setAlarm(crnError==null?"未知异常":crnError.getErrName());
        }
        return R.ok().add(vo);
@@ -307,9 +307,9 @@
            vo.setForkOffset(crnProtocol.getForkPosType().desc);    // 货叉位置
            vo.setLiftPos(crnProtocol.getLiftPosType().desc);
            vo.setWalkPos(crnProtocol.getWalkPos()==1?"不在定位":"在定位");
            vo.setWarnCode(String.valueOf(crnProtocol.getAlarm1()));
            if (crnProtocol.getAlarm1() > 0) {
                BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm1());
            vo.setWarnCode(String.valueOf(crnProtocol.getAlarm()));
            if (crnProtocol.getAlarm() > 0) {
                BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm());
                vo.setAlarm(crnError==null?"未知异常":crnError.getErrName());
            }
            vo.setInEnable(basCrnp.getInEnable());
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -22,6 +22,7 @@
import com.zy.asrs.utils.Utils;
import com.zy.common.service.CommonService;
import com.zy.common.utils.HttpHandler;
import com.zy.common.utils.News;
import com.zy.core.CrnThread;
import com.zy.core.DevpThread;
import com.zy.core.cache.MessageQueue;
@@ -36,6 +37,7 @@
import com.zy.core.model.protocol.StaProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.BarcodeThread;
import com.zy.core.thread.LedThread;
import com.zy.core.thread.SiemensDevpThread;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
@@ -110,12 +112,14 @@
    public void generateStoreWrkFile1() throws IOException, InterruptedException {
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        try {
            // 根据输送线plc遍历
            for (DevpSlave devp : slaveProperties.getDevp()) {
                // 遍历入库口
                for (DevpSlave.Sta inSta : devp.getInSta()) {
                    StorageEscalationParam storageEscalationParam = new StorageEscalationParam();
                    LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, inSta.getLed());
                    // 获取入库站信息
                    DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                    StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
@@ -127,54 +131,39 @@
                    Short workNo = staProtocol.getWorkNo();
                    Short stano = staProtocol.getStaNo();
                    // 尺寸检测异常
                    boolean back = false;
                    String errMsg = "";
                    if (staProtocol.isFrontErr()) {
                        errMsg = "前超限";
                        back = true;
                    }
                    if (!back && staProtocol.isBackErr()) {
                        errMsg = "后超限";
                        back = true;
                    }
                    if (!back && staProtocol.isHighErr()) {
                        errMsg = "高超限";
                        back = true;
                    }
                    if (!back && staProtocol.isLeftErr()) {
                        errMsg = "左超限";
                        back = true;
                    }
                    if (!back && staProtocol.isRightErr()) {
                        errMsg = "右超限";
                        back = true;
                    }
                    if (!back && staProtocol.isWeightErr()) {
                        errMsg = "超重";
                        back = true;
                    }
                    if (!back && staProtocol.isBarcodeErr()) {
                        errMsg = "扫码失败";
                        back = true;
                    }
                    // 判断是否满足入库条件
                    if (staProtocol.isAutoing() && staProtocol.isLoading()
                            && staProtocol.isInEnable()
                            && !staProtocol.isEmptyMk() && workNo >= 9790
                            && staProtocol.isPakMk()) {
                    if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable() && !staProtocol.isEmptyMk() && workNo >= 9790 && staProtocol.isPakMk()) {
                        // 获取条码扫描仪信息
                        BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, inSta.getBarcode());
                        if (barcodeThread == null) {
                            continue;
                        }
                        String barcode = barcodeThread.getBarcode();
                        boolean back = false;
                        if (!Cools.isEmpty(barcode) && (staProtocol.getWorkNo() != 9998 || staProtocol.getWorkNo() != 9996)) {
                            log.info("{}号条码扫描器检测条码信息:{}", inSta.getBarcode(), barcode);
                            if ("NG".endsWith(barcode) || "NoRead".equals(barcode)) {
                                String errorMsg = "15站扫码失败,已退回14站";
                                staProtocol.setWorkNo((short) 9998);
                                staProtocol.setStaNo((short) 14);
                                devpThread.setPakMk(staProtocol.getSiteId(), false);
                                storageEscalationParam.setWCSStatus(1);
                                storageEscalationParam.setWCSErrorMessage(storageEscalationParam.getWCSErrorMessage() + errorMsg);
                                // led 异常显示
                                if (ledThread != null) {
                                    News.error(methodName + ":扫码失败,请重试");
                                    MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errorMsg));
                                }
                                back = true;
                            }
                        }
                        String BoxNo = barcodeThread.getBarcode();
                        TaskWrk taskWrk1 = taskWrkService.selectOne(new EntityWrapper<TaskWrk>().eq("barcode", BoxNo));
                        if (!Cools.isEmpty(taskWrk1)) {
                            log.info("托盘码:" + BoxNo + "任务档存在");
                            if (taskWrk1.getIoType() == 1 && taskWrk1.getStartPoint().equals(staProtocol.getSiteId().toString())) {
                                StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>()
                                        .eq("crn_no", taskWrk1.getCrnNo()).eq("type_no", 1).eq("stn_no", staProtocol.getSiteId()));
                                StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>().eq("crn_no", taskWrk1.getCrnNo()).eq("type_no", 1).eq("stn_no", staProtocol.getSiteId()));
                                if (Cools.isEmpty(staDesc)) {
                                    return;
                                } else {
@@ -182,36 +171,17 @@
                                }
                            }
                        }
                        if (back) {
                            storageEscalationParam.setWCSStatus(1);
                            storageEscalationParam.setWCSErrorMessage(storageEscalationParam.getWCSErrorMessage() + errMsg);
                        }
                        log.info("组托入库={}", storageEscalationParam);
                        storageEscalationParam.setBoxNo(BoxNo);
                        String response = "";
                        Boolean success = false;
                        try {
                            response = new HttpHandler.Builder()
                                    .setUri(wmsUrl)
                                    .setPath(inboundTaskApplyPath)
                                    .setJson(JSON.toJSONString(storageEscalationParam))
                                    .build()
                                    .doPost();
                            response = new HttpHandler.Builder().setUri(wmsUrl).setPath(inboundTaskApplyPath).setJson(JSON.toJSONString(storageEscalationParam)).build().doPost();
                            JSONObject jsonObject = JSON.parseObject(response);
                            if(back){
                                if(staProtocol.getWorkNo()>=9801&&staProtocol.getWorkNo()<=9825){
                                    staProtocol.setStaNo((short)105);
                                } else if (staProtocol.getWorkNo()>=9826&&staProtocol.getWorkNo()<=9850) {
                                    staProtocol.setStaNo((short)107);
                                }else if (staProtocol.getWorkNo()>=9851&&staProtocol.getWorkNo()<=9875) {
                                    staProtocol.setStaNo((short)109);
                                }else{
                                    staProtocol.setStaNo((short)110);
                                }
                                devpThread.setPakMk(staProtocol.getSiteId(), false);
                            if (back) {
                                MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                            }else{
                                if (!Cools.isEmpty(response)&&!Cools.isEmpty(jsonObject.get("ReturnStatus"))&&jsonObject.get("ReturnStatus").equals(0) && !Cools.isEmpty(jsonObject.get("Result").toString())) {
                            } else {
                                if (!Cools.isEmpty(response) && !Cools.isEmpty(jsonObject.get("ReturnStatus")) && jsonObject.get("ReturnStatus").equals(0) && !Cools.isEmpty(jsonObject.get("Result").toString())) {
                                    Result result = JSON.parseObject(jsonObject.get("Result").toString(), Result.class);
                                    // 创新一个入库工作档
                                    TaskWrk taskWrk = taskWrkService.selectByTaskNo(result.getTaskNo());
@@ -221,58 +191,43 @@
                                            log.error("库位异常,库位号:={}", taskWrk.getOriginTargetPoint());
                                        } else {
                                            taskWrkService.insert(taskWrk);
                                            StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>()
                                                    .eq("crn_no", taskWrk.getCrnNo()).eq("type_no", 1).eq("stn_no", staProtocol.getSiteId()));
                                            StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>().eq("crn_no", taskWrk.getCrnNo()).eq("type_no", 1).eq("stn_no", staProtocol.getSiteId()));
                                            staProtocol.setWorkNo(taskWrk.getWrkNo().shortValue());
                                            staProtocol.setStaNo(staDesc.getCrnStn().shortValue());
                                            MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                                            HashMap<String, Object> hashMap = new HashMap<>();
                                            hashMap.put("TaskNo",taskWrk.getTaskNo());
                                            hashMap.put("TaskNo", taskWrk.getTaskNo());
                                            try {
                                                //开始上报,任务开始时,WCS回调WMS
                                                response = new HttpHandler.Builder()
                                                        .setUri(wmsUrl)
                                                        .setPath(taskStatusFeedbackPath)
                                                        .setJson(JSON.toJSONString(hashMap))
                                                        .build()
                                                        .doPost();
                                                response = new HttpHandler.Builder().setUri(wmsUrl).setPath(taskStatusFeedbackPath).setJson(JSON.toJSONString(hashMap)).build().doPost();
                                                JSONObject jsonObject1 = JSON.parseObject(response);
                                                Boolean bool = false;
                                                if(jsonObject1.get("ReturnStatus").equals(0)){
                                                if (jsonObject1.get("ReturnStatus").equals(0)) {
                                                    bool = true;
                                                }
                                                apiLogService.save("wcs开始入库任务上报wms"
                                                        , wmsUrl + TaskExecCallback
                                                        , null
                                                        , "127.0.0.1"
                                                        , JSON.toJSONString(hashMap)
                                                        , response
                                                        , bool
                                                );
                                                apiLogService.save("wcs开始入库任务上报wms", wmsUrl + TaskExecCallback, null, "127.0.0.1", JSON.toJSONString(hashMap), response, bool);
                                            } catch (Exception e) {
                                            }
                                        }
                                    } else {
//                                    staProtocol.setWorkNo((short) 9991);
                                        if(staProtocol.getWorkNo()>=9801&&staProtocol.getWorkNo()<=9825){
                                            staProtocol.setStaNo((short)105);
                                        } else if (staProtocol.getWorkNo()>=9826&&staProtocol.getWorkNo()<=9850) {
                                            staProtocol.setStaNo((short)107);
                                        }else if (staProtocol.getWorkNo()>=9851&&staProtocol.getWorkNo()<=9875) {
                                            staProtocol.setStaNo((short)109);
                                        }else{
                                            staProtocol.setStaNo((short)110);
                                        }
                                        staProtocol.setWorkNo((short) 9998);
                                        staProtocol.setStaNo((short) 14);
                                        devpThread.setPakMk(staProtocol.getSiteId(), false);
                                        MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                                    }
                                } else {
//                                staProtocol.setWorkNo((short) 9991);
                                    staProtocol.setStaNo(inSta.getBackSta().shortValue());
                                    staProtocol.setWorkNo((short) 9998);
                                    staProtocol.setStaNo((short) 14);
                                    devpThread.setPakMk(staProtocol.getSiteId(), false);
                                    MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                                    if (ledThread != null) {
                                        String errorMsg = jsonObject.getString("msg");
                                        if (!Cools.isEmpty(errorMsg)) {
                                            MessageQueue.offer(SlaveType.Led, inSta.getLed(), new Task(3, errorMsg));
                                        }
                                    }
                                }
                            }
                        } catch (Exception e) {
@@ -291,14 +246,7 @@
                                log.error("扫码检测程序异常" + inSta.getStaNo() + "异常信息" + e1);
                            }
                        } finally {
                            apiLogService.save("wms请求入库货位接口"
                                    , wmsUrl + inboundTaskApplyPath
                                    , null
                                    , "127.0.0.1"
                                    , JSON.toJSONString(storageEscalationParam)
                                    , response
                                    , success
                            );
                            apiLogService.save("wms请求入库货位接口", wmsUrl + inboundTaskApplyPath, null, "127.0.0.1", JSON.toJSONString(storageEscalationParam), response, success);
                        }
                        log.info("入库请求参数=" + JSON.toJSONString(BoxNo));
                        log.info("入库请求返回参数=" + JSON.toJSONString(response));
@@ -383,10 +331,7 @@
                        continue;
                    }
                    // 判断是否满足入库条件
                    if (staProtocol.isAutoing() && staProtocol.isLoading()
                            && staProtocol.isInEnable()
                            && !staProtocol.isEmptyMk() && (workNo >= 9899)
                            && staProtocol.isPakMk()) {
                    if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable() && !staProtocol.isEmptyMk() && (workNo >= 9899) && staProtocol.isPakMk()) {
                        // 获取条码扫描仪信息
                        BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, inSta.getBarcode());
                        if (barcodeThread == null) {
@@ -400,8 +345,7 @@
                            if (!Cools.isEmpty(taskWrk1)) {
                                log.info("托盘码:" + barcode + "任务档存在");
                                if (taskWrk1.getIoType() == 1 && taskWrk1.getStartPoint().equals(staProtocol.getSiteId().toString())) {
                                    StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>()
                                            .eq("crn_no", taskWrk1.getCrnNo()).eq("type_no", 1).eq("stn_no", staProtocol.getSiteId()));
                                    StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>().eq("crn_no", taskWrk1.getCrnNo()).eq("type_no", 1).eq("stn_no", staProtocol.getSiteId()));
                                    if (Cools.isEmpty(staDesc)) {
                                        log.info("托盘码:" + barcode + "任务档存在");
                                        return;
@@ -420,11 +364,7 @@
                            try {
                                response = new HttpHandler.Builder()
                                        // .setHeaders(headParam)
                                        .setUri(wmsUrl)
                                        .setPath(inboundTaskApplyPath)
                                        .setJson(JSON.toJSONString(toWmsDTO))
                                        .build()
                                        .doPost();
                                        .setUri(wmsUrl).setPath(inboundTaskApplyPath).setJson(JSON.toJSONString(toWmsDTO)).build().doPost();
                            } catch (Exception e) {
                                log.error("请求入库调用接口失败");
                                log.error("异常信息打印:" + e);
@@ -470,9 +410,7 @@
                                        log.error("站点号异常2" + inSta.getStaNo());
                                        throw new CoolException("站点号异常2,站点号不存在" + inSta.getStaNo());
                                    } else {
                                        LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>()
                                                .eq("crn_no", staNoCrnNo.longValue())
                                                .eq("loc_no", getWmsDto.getLocNo()));
                                        LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("crn_no", staNoCrnNo.longValue()).eq("loc_no", getWmsDto.getLocNo()));
                                        if (Cools.isEmpty(locMast)) {
                                            basDevp.setStaErr(1);
                                            basDevpService.updateById(basDevp);
@@ -498,9 +436,7 @@
                                    continue;
                                }
                                //查看该库位是否为空库位
                                LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>()
                                        .eq("loc_sts", "O")
                                        .eq("loc_no", getWmsDto.getLocNo()));
                                LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_sts", "O").eq("loc_no", getWmsDto.getLocNo()));
                                if (Cools.isEmpty(locMast)) {
                                    try {
                                        HashMap<String, Object> headParam1 = new HashMap<>();
@@ -511,20 +447,9 @@
                                        String response2;
                                        response2 = new HttpHandler.Builder()
                                                // .setHeaders(headParam)
                                                .setUri(wmsUrl)
                                                .setPath(taskStatusFeedbackPath)
                                                .setJson(JSON.toJSONString(headParam1))
                                                .build()
                                                .doPost();
                                                .setUri(wmsUrl).setPath(taskStatusFeedbackPath).setJson(JSON.toJSONString(headParam1)).build().doPost();
                                        JSONObject jsonObject1 = JSON.parseObject(response2);
                                        apiLogService.save("wcs派发库位==》不为空《==上报wms"
                                                , wmsUrl + taskStatusFeedbackPath
                                                , null
                                                , "127.0.0.1"
                                                , JSON.toJSONString(headParam1)
                                                , response
                                                , true
                                        );
                                        apiLogService.save("wcs派发库位==》不为空《==上报wms", wmsUrl + taskStatusFeedbackPath, null, "127.0.0.1", JSON.toJSONString(headParam1), response, true);
                                    } catch (Exception e) {
                                        log.error("wcs派发库位==》不为空《==上报wms", getWmsDto.getWrkNo());
                                        throw new CoolException("wcs派发入库任务上报wms失败,派发库位==》不为空《==,异常信息:" + e);
@@ -539,8 +464,7 @@
                                        log.error("库位异常,库位号:{}", getWmsDto.getTargetLocationCode());
                                    } else {
                                        taskWrkService.insert(taskWrk);
                                        StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>()
                                                .eq("crn_no", taskWrk.getCrnNo()).eq("type_no", 1).eq("stn_no", staProtocol.getSiteId()));
                                        StaDesc staDesc = staDescService.selectOne(new EntityWrapper<StaDesc>().eq("crn_no", taskWrk.getCrnNo()).eq("type_no", 1).eq("stn_no", staProtocol.getSiteId()));
                                        staProtocol.setWorkNo(taskWrk.getWrkNo().shortValue());
                                        staProtocol.setStaNo(staDesc.getCrnStn().shortValue());
                                        MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
@@ -550,14 +474,7 @@
                            } else {
                                continue;
                            }
                            apiLogService.save("wms请求入库货位接口"
                                    , wmsUrl + inboundTaskApplyPath
                                    , null
                                    , "127.0.0.1"
                                    , JSON.toJSONString(toWmsDTO)
                                    , response
                                    , true
                            );
                            apiLogService.save("wms请求入库货位接口", wmsUrl + inboundTaskApplyPath, null, "127.0.0.1", JSON.toJSONString(toWmsDTO), response, true);
                        } else {
                            // 退回
@@ -603,33 +520,54 @@
                        } else {
                            staProtocol = staProtocol.clone();
                        }
                        if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == 0)) {
                        if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == null)) {
                            // 查询工作档
                            TaskWrk taskWrk = taskWrkMapper.selectCrnStaWorking(crnSlave.getId(), staDesc.getStnNo().toString());
                            if (taskWrk == null) {
                                continue;
                            }
                            log.info("下发输送线任务:taskWrk:" + JSON.toJSONString(taskWrk));
//                            R r = siteController.siteDetlUpdate(Integer.valueOf(taskWrk.getTargetPoint()), taskWrk.getWrkNo().shortValue(), (short) 0, "Y", false, false);
                            staProtocol.setWorkNo(taskWrk.getWrkNo().shortValue());
                            staProtocol.setStaNo(staDesc.getStnNo().shortValue());
                            boolean offer = false;
                            try {
                                offer = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol));
                            } catch (Exception e) {
                                log.error("下发输送线任务失败:异常:" + e);
                                log.error("下发输送线任务失败:异常:offer:" + offer);
                            }
//                            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(r));
                            if (offer) {
                                log.info("下发输送线任务成功:taskWrk:" + JSON.toJSONString(taskWrk));
                                taskWrk.setStatus(5);
                                taskWrk.setWrkSts(14);
                                taskWrkService.updateById(taskWrk);
                            } else {
                                log.error("下发输送线任务失败:taskWrk:" + JSON.toJSONString(taskWrk));
                            // 判断工作档条件
                            if (taskWrk.getIoType() < 100 || taskWrk.getTargetPoint() == null || taskWrk.getStartPoint() == null) {
                                continue;
                            }
                            // 判断吊车是否实际已完成,且电脑状态在move中,以备电脑进行更新工作档
                            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, taskWrk.getCrnNo());
                            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
                            if (crnProtocol.statusType == CrnStatusType.FETCHING || crnProtocol.statusType == CrnStatusType.PUTTING) {
                                // 移动中
                                continue;
                            }
                            //  判断堆垛机状态等待确认
                            if (crnProtocol.modeType == CrnModeType.AUTO && crnProtocol.getTaskNo().equals(taskWrk.getWrkNo().shortValue()) && crnProtocol.statusType == CrnStatusType.WAITING && crnProtocol.forkPosType == CrnForkPosType.HOME) {
                                // 命令下发区 --------------------------------------------------------------------------
                                log.info("下发输送线任务:taskWrk:" + JSON.toJSONString(taskWrk));
//                            R r = siteController.siteDetlUpdate(Integer.valueOf(taskWrk.getTargetPoint()), taskWrk.getWrkNo().shortValue(), (short) 0, "Y", false, false);
                                staProtocol.setWorkNo(taskWrk.getWrkNo().shortValue());
                                staProtocol.setStaNo((short) 11);
                                boolean offer = false;
                                try {
                                    offer = MessageQueue.offer(SlaveType.Devp, 1, new Task(2, staProtocol));
                                } catch (Exception e) {
                                    log.error("下发输送线任务失败:异常:" + e);
                                    log.error("下发输送线任务失败:异常:offer:" + offer);
                                }
//                            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(r));
                                if (offer) {
                                    log.info("下发输送线任务成功:taskWrk:" + JSON.toJSONString(taskWrk));
                                    taskWrk.setStatus(5);
                                    taskWrk.setWrkSts(14);
                                    taskWrkService.updateById(taskWrk);
                                    // 复位堆垛
                                    crnThread.setResetFlag(true);
                                } else {
                                    log.error("下发输送线任务失败:taskWrk:" + JSON.toJSONString(taskWrk));
//                                log.error("下发输送线任务失败:异常信息:"+JSON.toJSONString(r));
                                }
                            }
                        }
                    } catch (Exception e) {
@@ -660,8 +598,7 @@
            // 只有当堆垛机空闲 并且 无任务时才继续执行
            if (crnProtocol.getStatusType() == CrnStatusType.IDLE && crnProtocol.getTaskNo() == 0 && crnProtocol.getModeType() == CrnModeType.AUTO
                    && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0) {
            if (crnProtocol.getStatusType() == CrnStatusType.IDLE && crnProtocol.getTaskNo() == 0 && crnProtocol.getModeType() == CrnModeType.AUTO && crnProtocol.getLoaded() == 0 && crnProtocol.getForkPos() == 0) {
                // 如果最近一次是入库模式
                if (crnProtocol.getLastIo().equals("I")) {
                    if (basCrnp.getInEnable().equals("Y")) {
@@ -693,7 +630,7 @@
    /**
     * 入库  ===>>  堆垛机站到库位
     */
    public void crnStnToLoc(CrnSlave slave, CrnProtocol crnProtocol) throws IOException {
    public synchronized void crnStnToLoc(CrnSlave slave, CrnProtocol crnProtocol) throws IOException {
        for (CrnSlave.CrnStn crnStn : slave.getCrnInStn()) {
            List<StaDesc> staDescs = staDescMapper.selectList(new EntityWrapper<StaDesc>().eq("crn_no", slave.getId()).eq("crn_stn", crnStn.getStaNo()));
            for (StaDesc staDesc : staDescs) {
@@ -712,8 +649,7 @@
                    log.error("入库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo());
                    continue;
                }
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() > 0 && staProtocol.isInEnable()
                        && staDetl.getCanining() != null && staDetl.getCanining().equals("Y")) {
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() > 0 && staProtocol.isInEnable() && staDetl.getCanining() != null && staDetl.getCanining().equals("Y")) {
                    flag = true;
                }
                if (!flag) {
@@ -747,18 +683,18 @@
                // 命令下发区 --------------------------------------------------------------------------
                CrnCommand crnCommand = new CrnCommand();
                crnCommand.setCrnNo(staDesc.getCrnNo()); // 堆垛机编号
                crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
                crnCommand.setTaskNo(taskWrk.getWrkNo().shortValue()); // 工作号
                crnCommand.setAckFinish((short) 0);  // 任务完成确认位
                crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
                crnCommand.setSourcePosX(crnStn.getRow().shortValue());     // 源库位列
                crnCommand.setSourcePosY(crnStn.getBay().shortValue());     // 源库位层
                crnCommand.setSourcePosZ(crnStn.getLev().shortValue());     // 源库位排
                crnCommand.setSourcePosX(crnStn.getRow().shortValue());     // 源库位排
                crnCommand.setSourcePosY(crnStn.getBay().shortValue());     // 源库位列
                crnCommand.setSourcePosZ(crnStn.getLev().shortValue());     // 源库位层
                crnCommand.setDestinationPosX(Utils.getRowShort(taskWrk.getTargetPoint()));     // 目标库位列
                crnCommand.setDestinationPosY(Utils.getBayShort(taskWrk.getTargetPoint()));     // 目标库位层
                crnCommand.setDestinationPosZ(Utils.getLevShort(taskWrk.getTargetPoint()));     // 目标库位排
                crnCommand.setCommand((short) 1);
                log.info("堆垛机入库任务下发={}",crnCommand);
                log.info("堆垛机入库任务下发={}", crnCommand);
                if (!CommandUtils.offer(SlaveType.Crn, taskWrk.getCrnNo(), new Task(2, crnCommand), false)) {
                    log.error("堆垛机命令生成失败,堆垛机号={},任务数据={}", taskWrk.getCrnNo(), JSON.toJSON(crnCommand));
                    throw new CoolException("堆垛机命令生成失败");
@@ -778,7 +714,7 @@
     * 出库  ===>>  库位到堆垛机站
     * 2022-06-09 TQS修改,查询工作档LIST,遍历下发,防止第一个任务堵塞出库
     */
    public void locToCrnStn(CrnSlave slave, CrnProtocol crnProtocol) {
    public synchronized void locToCrnStn(CrnSlave slave, CrnProtocol crnProtocol) {
        List<TaskWrk> taskWrksInitial = taskWrkMapper.selectPakOut(slave.getId(), null);
        if (taskWrksInitial.size() == 0) {
            return;
@@ -798,24 +734,18 @@
                        continue;
                    }
                    LocMast locMast=locMastService.selectByLocNo(taskWrk.getStartPoint());
                    LocMast locMast = locMastService.selectByLocNo(taskWrk.getStartPoint());
                    //判断其库位是否为深库位,如果为深库位找其浅库位是都有货
                    if(locMast.getRow1()==1||locMast.getRow1()==5){
                        LocMast locMast1=locMastService.selectOne(new EntityWrapper<LocMast>()
                                .eq("row1", (locMast.getRow1()+1))
                                .eq("bay1",locMast.getBay1())
                                .eq("lev1",locMast.getLev1()).eq("loc_sts","F"));
                        if (!Cools.isEmpty(locMast1)){
                            log.info(locMast.getLocNo()+"出深库位,浅库位有货");
                    if (locMast.getRow1() == 1 || locMast.getRow1() == 5) {
                        LocMast locMast1 = locMastService.selectOne(new EntityWrapper<LocMast>().eq("row1", (locMast.getRow1() + 1)).eq("bay1", locMast.getBay1()).eq("lev1", locMast.getLev1()).eq("loc_sts", "F"));
                        if (!Cools.isEmpty(locMast1)) {
                            log.info(locMast.getLocNo() + "出深库位,浅库位有货");
                            continue;
                        }
                    }else if(locMast.getRow1()==4||locMast.getRow1()==8){
                        LocMast locMast1=locMastService.selectOne(new EntityWrapper<LocMast>()
                                .eq("row1", (locMast.getRow1()-1))
                                .eq("bay1",locMast.getBay1())
                                .eq("lev1",locMast.getLev1()).eq("loc_sts","F"));
                        if (!Cools.isEmpty(locMast1)){
                            log.info(locMast.getLocNo()+"出深库位,浅库位有货");
                    } else if (locMast.getRow1() == 4 || locMast.getRow1() == 8) {
                        LocMast locMast1 = locMastService.selectOne(new EntityWrapper<LocMast>().eq("row1", (locMast.getRow1() - 1)).eq("bay1", locMast.getBay1()).eq("lev1", locMast.getLev1()).eq("loc_sts", "F"));
                        if (!Cools.isEmpty(locMast1)) {
                            log.info(locMast.getLocNo() + "出深库位,浅库位有货");
                            continue;
                        }
                    }
@@ -837,8 +767,7 @@
                    }
                    // 判断堆垛机出库站状态
                    if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y")
                            && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) {
                    if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() != null && staDetl.getCanouting().equals("Y") && staProtocol.getWorkNo() == 0 && staProtocol.isOutEnable()) {
                        // 命令下发区 --------------------------------------------------------------------------
                        // 堆垛机控制过滤
@@ -854,7 +783,7 @@
                        command.setCrnNo(taskWrk.getCrnNo()); // 堆垛机编号
                        command.setTaskNo(taskWrk.getWrkNo().shortValue()); // 工作号
                        command.setAckFinish((short) 0);  // 任务完成确认位
                        command.setTaskMode(CrnTaskModeType.PAKIN); // 任务模式
                        command.setTaskMode(CrnTaskModeType.LOC_MOVE); // 任务模式:  库位移转
                        command.setSourcePosX(Utils.getRowShort(taskWrk.getStartPoint()));     // 源库位排
                        command.setSourcePosY(Utils.getBayShort(taskWrk.getStartPoint()));     // 源库位列
                        command.setSourcePosZ(Utils.getLevShort(taskWrk.getStartPoint()));     // 源库位层
@@ -863,32 +792,20 @@
                        command.setDestinationPosZ(crnStn.getLev().shortValue());     // 目标库位层
                        command.setCommand((short) 1);
                        if(Cools.isEmpty(taskWrk.getMarkStart())||taskWrk.getMarkStart()==0){
                        if (Cools.isEmpty(taskWrk.getMarkStart()) || taskWrk.getMarkStart() == 0) {
                            HashMap<String, Object> hashMap = new HashMap<>();
                            hashMap.put("TaskNo",taskWrk.getTaskNo());
                            hashMap.put("TaskNo", taskWrk.getTaskNo());
                            String response = "";
                            try {
                                //开始上报,出库任务开始时,WCS回调WMS
                                response = new HttpHandler.Builder()
                                        .setUri(wmsUrl)
                                        .setPath(taskStatusFeedbackPath)
                                        .setJson(JSON.toJSONString(hashMap))
                                        .build()
                                        .doPost();
                                response = new HttpHandler.Builder().setUri(wmsUrl).setPath(taskStatusFeedbackPath).setJson(JSON.toJSONString(hashMap)).build().doPost();
                                JSONObject jsonObject = JSON.parseObject(response);
                                Boolean bool = false;
                                if(jsonObject.get("ReturnStatus").equals(0)){
                                if (jsonObject.get("ReturnStatus").equals(0)) {
                                    bool = true;
                                    taskWrk.setMarkStart(1);
                                }
                                apiLogService.save("wcs开始任务上报wms"
                                        , wmsUrl + TaskExecCallback
                                        , null
                                        , "127.0.0.1"
                                        , JSON.toJSONString(hashMap)
                                        , response
                                        , bool
                                );
                                apiLogService.save("wcs开始任务上报wms", wmsUrl + TaskExecCallback, null, "127.0.0.1", JSON.toJSONString(hashMap), response, bool);
                            } catch (Exception e) {
                            }
                        }
@@ -950,11 +867,7 @@
    public void locToLoc(CrnSlave slave, CrnProtocol crnProtocol) {
        for (CrnSlave.CrnStn crnStn : slave.getCrnOutStn()) {
            // 获取工作状态为11(生成出库ID)的移库工作档
            List<TaskWrk> taskWrks = taskWrkMapper.selectList(new EntityWrapper<TaskWrk>()
                    .eq("crn_no", slave.getId())
                    .eq("wrk_sts", 11)
                    .eq("io_type", 3)
                    .orderBy("io_pri", false));
            List<TaskWrk> taskWrks = taskWrkMapper.selectList(new EntityWrapper<TaskWrk>().eq("crn_no", slave.getId()).eq("wrk_sts", 11).eq("io_type", 3).orderBy("io_pri", false));
            for (TaskWrk taskWrk : taskWrks) {
                // 双深库位且浅库位有货,则需先对浅库位进行库位移转
@@ -1017,20 +930,9 @@
                        String response;
                        response = new HttpHandler.Builder()
                                // .setHeaders(headParam)
                                .setUri(wmsUrl)
                                .setPath(taskStatusFeedbackPath)
                                .setJson(JSON.toJSONString(headParam))
                                .build()
                                .doPost();
                                .setUri(wmsUrl).setPath(taskStatusFeedbackPath).setJson(JSON.toJSONString(headParam)).build().doPost();
                        JSONObject jsonObject = JSON.parseObject(response);
                        apiLogService.save("wcs派发移库任务上报wms"
                                , wmsUrl + taskStatusFeedbackPath
                                , null
                                , "127.0.0.1"
                                , JSON.toJSONString(headParam)
                                , response
                                , true
                        );
                        apiLogService.save("wcs派发移库任务上报wms", wmsUrl + taskStatusFeedbackPath, null, "127.0.0.1", JSON.toJSONString(headParam), response, true);
                    } catch (Exception e) {
                        log.error("wcs派发移库库任务上报wms失败", taskWrk);
//                        throw new CoolException("wcs派发移库库任务上报wms失败");
@@ -1102,10 +1004,8 @@
            if (crnProtocol == null) {
                continue;
            }
            //  状态:等待确认 并且  任务完成位 = 1
            if (crnProtocol.getTaskFinish() == 0 && crnProtocol.statusType == CrnStatusType.HANDLING_COMPLETED && crnProtocol.getTaskNo() != 0) {
                //获取入库待确认工作档
            if (crnProtocol.statusType == CrnStatusType.WAITING && crnProtocol.getTaskNo() != 0) {                //获取入库待确认工作档
                TaskWrk taskWrk = taskWrkMapper.selectCrnNoInWorking(crn.getId(), crnProtocol.getTaskNo().intValue());
                if (Cools.isEmpty(taskWrk) && crnProtocol.getTaskNo() != 999) {
                    log.error("堆垛机处于等待确认且任务完成状态,但未找到工作档。堆垛机号={},工作号={}", crn.getId(), crnProtocol.getTaskNo());
@@ -1116,7 +1016,7 @@
                crnOperatorParam.setCrnNo(crn.getId());
                R r = crnController.crnTaskComplete(crnOperatorParam);
                Thread.sleep(1000);
                if(!r.get("code").equals(200)){
                if (!r.get("code").equals(200)) {
                    return;
                }
                if (!Cools.isEmpty(taskWrk)) {
@@ -1168,120 +1068,120 @@
    /**
     * 堆垛机异常信息记录
     */
    public void recCrnErr() {
        Date now = new Date();
        for (CrnSlave crn : slaveProperties.getCrn()) {
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                continue;
            }
            if (false) {
//            if (crnProtocol.getModeType() != CrnModeType.STOP) {
                // 有任务
                if (crnProtocol.getTaskNo() != 0) {
                    BasErrLog latest = basErrLogService.findLatestByTaskNo(crn.getId(), crnProtocol.getTaskNo().intValue());
                    // 有异常
                    if (latest == null) {
                        if (crnProtocol.getAlarm() != null && crnProtocol.getAlarm() > 0) {
                            WrkMast wrkMast = wrkMastMapper.selectById(crnProtocol.getTaskNo());
                            if (wrkMast == null) {
                                continue;
                            }
                            BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm());
                            String errName = crnError == null ? String.valueOf(crnProtocol.getAlarm()) : crnError.getErrName();
                            BasErrLog basErrLog = new BasErrLog(
                                    null,    // 编号
                                    wrkMast.getWrkNo(),    // 工作号
                                    now,    // 发生时间
                                    null,    // 结束时间
                                    wrkMast.getWrkSts(),    // 工作状态
                                    wrkMast.getIoType(),    // 入出库类型
                                    crn.getId(),    // 堆垛机
                                    null,    // plc
                                    wrkMast.getLocNo(),    // 目标库位
                                    wrkMast.getStaNo(),    // 目标站
                                    wrkMast.getSourceStaNo(),    // 源站
                                    wrkMast.getSourceLocNo(),    // 源库位
                                    wrkMast.getBarcode(),    // 条码
                                    (int) crnProtocol.getAlarm1(),    // 异常码
                                    errName,    // 异常
                                    1,    // 异常情况
                                    now,    // 添加时间
                                    null,    // 添加人员
                                    now,    // 修改时间
                                    null,    // 修改人员
                                    "任务中异常"    // 备注
                            );
                            if (!basErrLogService.insert(basErrLog)) {
                                log.error("堆垛机plc异常记录失败 ===>> [id:{}] [error:{}]", crn.getId(), errName);
                            }
                        }
                    } else {
                        // 异常修复
                        if (crnProtocol.getAlarm1() == null || crnProtocol.getAlarm1() == 0) {
                            latest.setEndTime(now);
                            latest.setUpdateTime(now);
                            latest.setStatus(2);
                            if (!basErrLogService.updateById(latest)) {
                                log.error("堆垛机plc异常记录修复失败 ===>> [id:{}] [errLogId:{}]", crn.getId(), latest.getId());
                            }
                        }
                    }
                    // 无任务
                } else {
                    BasErrLog latest = basErrLogService.findLatest(crn.getId());
                    // 有异常
                    if (crnProtocol.getAlarm1() != null && crnProtocol.getAlarm() > 0) {
                        // 记录新异常
                        if (latest == null || (latest.getErrCode() != crnProtocol.getAlarm().intValue())) {
                            BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm());
                            String errName = crnError == null ? String.valueOf(crnProtocol.getAlarm()) : crnError.getErrName();
                            BasErrLog basErrLog = new BasErrLog(
                                    null,    // 编号
                                    null,    // 工作号
                                    now,    // 发生时间
                                    null,    // 结束时间
                                    null,    // 工作状态
                                    null,    // 入出库类型
                                    crn.getId(),    // 堆垛机
                                    null,    // plc
                                    null,    // 目标库位
                                    null,    // 目标站
                                    null,    // 源站
                                    null,    // 源库位
                                    null,    // 条码
                                    (int) crnProtocol.getAlarm1(),    // 异常码
                                    errName,    // 异常
                                    1,    // 异常情况
                                    now,    // 添加时间
                                    null,    // 添加人员
                                    now,    // 修改时间
                                    null,    // 修改人员
                                    "无任务异常"    // 备注
                            );
                            if (!basErrLogService.insert(basErrLog)) {
                                log.error("堆垛机plc异常记录失败 ===>> [id:{}] [error:{}]", crn.getId(), errName);
                            }
                        }
                        // 无异常
                    } else {
                        // 异常修复
                        if (latest != null && latest.getStatus() == 1) {
                            latest.setEndTime(now);
                            latest.setUpdateTime(now);
                            latest.setStatus(2);
                            if (!basErrLogService.updateById(latest)) {
                                log.error("堆垛机plc异常记录修复失败 ===>> [id:{}] [errLogId:{}]", crn.getId(), latest.getId());
                            }
                        }
                    }
                }
            }
        }
    }
//    public void recCrnErr() {
//        Date now = new Date();
//        for (CrnSlave crn : slaveProperties.getCrn()) {
//            // 获取堆垛机信息
//            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
//            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
//            if (crnProtocol == null) {
//                continue;
//            }
//            if (false) {
////            if (crnProtocol.getModeType() != CrnModeType.STOP) {
//                // 有任务
//                if (crnProtocol.getTaskNo() != 0) {
//                    BasErrLog latest = basErrLogService.findLatestByTaskNo(crn.getId(), crnProtocol.getTaskNo().intValue());
//                    // 有异常
//                    if (latest == null) {
//                        if (crnProtocol.getAlarm() != null && crnProtocol.getAlarm() > 0) {
//                            WrkMast wrkMast = wrkMastMapper.selectById(crnProtocol.getTaskNo());
//                            if (wrkMast == null) {
//                                continue;
//                            }
//                            BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm());
//                            String errName = crnError == null ? String.valueOf(crnProtocol.getAlarm()) : crnError.getErrName();
//                            BasErrLog basErrLog = new BasErrLog(
//                                    null,    // 编号
//                                    wrkMast.getWrkNo(),    // 工作号
//                                    now,    // 发生时间
//                                    null,    // 结束时间
//                                    wrkMast.getWrkSts(),    // 工作状态
//                                    wrkMast.getIoType(),    // 入出库类型
//                                    crn.getId(),    // 堆垛机
//                                    null,    // plc
//                                    wrkMast.getLocNo(),    // 目标库位
//                                    wrkMast.getStaNo(),    // 目标站
//                                    wrkMast.getSourceStaNo(),    // 源站
//                                    wrkMast.getSourceLocNo(),    // 源库位
//                                    wrkMast.getBarcode(),    // 条码
//                                    (int) crnProtocol.getAlarm1(),    // 异常码
//                                    errName,    // 异常
//                                    1,    // 异常情况
//                                    now,    // 添加时间
//                                    null,    // 添加人员
//                                    now,    // 修改时间
//                                    null,    // 修改人员
//                                    "任务中异常"    // 备注
//                            );
//                            if (!basErrLogService.insert(basErrLog)) {
//                                log.error("堆垛机plc异常记录失败 ===>> [id:{}] [error:{}]", crn.getId(), errName);
//                            }
//                        }
//                    } else {
//                        // 异常修复
//                        if (crnProtocol.getAlarm1() == null || crnProtocol.getAlarm1() == 0) {
//                            latest.setEndTime(now);
//                            latest.setUpdateTime(now);
//                            latest.setStatus(2);
//                            if (!basErrLogService.updateById(latest)) {
//                                log.error("堆垛机plc异常记录修复失败 ===>> [id:{}] [errLogId:{}]", crn.getId(), latest.getId());
//                            }
//                        }
//                    }
//                    // 无任务
//                } else {
//                    BasErrLog latest = basErrLogService.findLatest(crn.getId());
//                    // 有异常
//                    if (crnProtocol.getAlarm1() != null && crnProtocol.getAlarm() > 0) {
//                        // 记录新异常
//                        if (latest == null || (latest.getErrCode() != crnProtocol.getAlarm().intValue())) {
//                            BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm());
//                            String errName = crnError == null ? String.valueOf(crnProtocol.getAlarm()) : crnError.getErrName();
//                            BasErrLog basErrLog = new BasErrLog(
//                                    null,    // 编号
//                                    null,    // 工作号
//                                    now,    // 发生时间
//                                    null,    // 结束时间
//                                    null,    // 工作状态
//                                    null,    // 入出库类型
//                                    crn.getId(),    // 堆垛机
//                                    null,    // plc
//                                    null,    // 目标库位
//                                    null,    // 目标站
//                                    null,    // 源站
//                                    null,    // 源库位
//                                    null,    // 条码
//                                    (int) crnProtocol.getAlarm1(),    // 异常码
//                                    errName,    // 异常
//                                    1,    // 异常情况
//                                    now,    // 添加时间
//                                    null,    // 添加人员
//                                    now,    // 修改时间
//                                    null,    // 修改人员
//                                    "无任务异常"    // 备注
//                            );
//                            if (!basErrLogService.insert(basErrLog)) {
//                                log.error("堆垛机plc异常记录失败 ===>> [id:{}] [error:{}]", crn.getId(), errName);
//                            }
//                        }
//                        // 无异常
//                    } else {
//                        // 异常修复
//                        if (latest != null && latest.getStatus() == 1) {
//                            latest.setEndTime(now);
//                            latest.setUpdateTime(now);
//                            latest.setStatus(2);
//                            if (!basErrLogService.updateById(latest)) {
//                                log.error("堆垛机plc异常记录修复失败 ===>> [id:{}] [errLogId:{}]", crn.getId(), latest.getId());
//                            }
//                        }
//                    }
//                }
//            }
//
//        }
//    }
    //自动派发任务
    public void autoDistribute() {
@@ -1456,24 +1356,11 @@
        taskOverToWms.setTaskStatus("executing"); //任务状态
        String response = null;
        try {
            response = new HttpHandler.Builder()
                    .setHeaders(map)
                    .setUri(wmsUrl)
                    .setPath("wcsManager/wcsInterface/taskStatusFeedback")
                    .setJson(JSON.toJSONString(taskOverToWms))
                    .build()
                    .doPost();
            response = new HttpHandler.Builder().setHeaders(map).setUri(wmsUrl).setPath("wcsManager/wcsInterface/taskStatusFeedback").setJson(JSON.toJSONString(taskOverToWms)).build().doPost();
        } catch (Exception e) {
            log.error("堆垛机任务完成,请求wms任务完成接口失败");
        }
        apiLogService.save("堆垛机开始运行"
                , wmsUrl + "wcsManager/wcsInterface/taskStatusFeedback"
                , null
                , "127.0.0.1"
                , JSON.toJSONString(taskOverToWms)
                , response
                , true
        );
        apiLogService.save("堆垛机开始运行", wmsUrl + "wcsManager/wcsInterface/taskStatusFeedback", null, "127.0.0.1", JSON.toJSONString(taskOverToWms), response, true);
        return response;
    }
src/main/java/com/zy/common/utils/News.java
New file
@@ -0,0 +1,183 @@
package com.zy.common.utils;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * news stories for zoneyung
 * Created by vincent on 2022/12/22
 */
@Slf4j
public class News {
    public static void main(String[] args) {
        News.info("info{}", 1);
        News.warn("warn{}", 2);
        News.error("error{}", 3);
        System.out.println(News.print());
    }
    interface NewsSupport<T> { boolean execute(T t); }
    private static final NewsQueue<NewsDomain> NEWS_QUEUE = new NewsQueue<>(NewsDomain.class, 1024);
    @SuppressWarnings({"unchecked"})
    static class NewsQueue<T> {
        private final transient Class<T> cls;
        private final T[] arr;
        private final int capacity;
        private int head;
        private int tail;
        { this.head = 0; this.tail = 0; }
        public NewsQueue(Class<T> cls, int capacity) {
            this.cls = cls;
            this.arr = (T[]) Array.newInstance(cls, capacity);
            this.capacity = capacity;
        }
        public synchronized boolean offer(T t) {
            if (this.tail == this.capacity) {
                this.peek();
            }
            this.reform();
            this.arr[this.tail] = t;
            this.tail ++;
            return true;
        }
        public synchronized boolean put(T t) {
            if (this.tail == this.capacity) {
                return false;
            } else {
                this.reform();
            }
            this.arr[this.tail] = t;
            this.tail ++;
            return true;
        }
        public synchronized T peek() {
            if (this.head == this.tail) {
                return null;
            }
            T t = this.arr[this.head];
            this.head ++;
            this.reform();
            return t;
        }
        private void reform() {
            for (int i = this.head; i < this.tail; i++) {
                this.arr[i-this.head] = this.arr[i];
            }
            this.tail -= this.head;
            this.head = 0;
        }
        public synchronized int size() {
            return this.tail - this.head;
        }
        public synchronized List<T> data() {
            T[] ts = (T[]) Array.newInstance(this.cls, size());
            if (this.tail - this.head >= 0) {
                System.arraycopy(this.arr, this.head, ts, 0, this.tail - this.head);
            }
            return Arrays.asList(ts);
        }
    }
    public static void info(String format, Object... arguments) {
        log.info(format, arguments);
        offer(NewsLevel.INFO, format, arguments);
    }
    public static void warn(String format, Object... arguments) {
        log.warn(format, arguments);
        offer(NewsLevel.WARN, format, arguments);
    }
    public static void error(String format, Object... arguments) {
        log.error(format, arguments);
        offer(NewsLevel.ERROR, format, arguments);
    }
    public static String printStr() {
        StringBuilder sb = new StringBuilder("[");
        List<NewsDomain> domains = NEWS_QUEUE.data();
        for (int i = 0; i < domains.size(); i++) {
            NewsDomain domain = domains.get(i);
            sb.append("{");
            sb.append("\"l\":").append(domain.level.idx).append(",");
            sb.append("\"v\":\"").append(domain.content).append("\"").append(",");
            sb.append("\"t\":\"").append(domain.date).append("\"");
            sb.append("}");
            if (i < domains.size() - 1) {
                sb.append(",");
            }
        }
        sb.append("]");
        return sb.toString();
    }
    public static List<Map<String, Object>> print() {
        List<Map<String, Object>> res = new ArrayList<>();
        for (NewsDomain datum : NEWS_QUEUE.data()) {
            Map<String, Object> map = new HashMap<>();
            map.put("l", datum.level.idx);
            map.put("v", datum.content);
            map.put("t", datum.date);
            res.add(map);
        }
        return res;
    }
    private static boolean offer(NewsLevel level, String msg, Object[] args) {
        return NEWS_QUEUE.offer(new NewsDomain(level, replace(msg, args), (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date())));
    }
    private static String replace(String str, Object[] objs){
        if (null == objs || objs.length == 0 || null == str || "".equals(str.trim())) {
            return str;
        } else {
            StringBuilder sb = new StringBuilder(str);
            for (Object obj : objs) {
                int idx = sb.indexOf("{}");
                if (idx == -1) { break; }
                sb.replace(idx, idx + 2, String.valueOf(obj));
            }
            return sb.toString();
        }
    }
    static class NewsDomain {
        public NewsLevel level;
        public String content;
        public String date;
        public NewsDomain(NewsLevel level, String content, String date) {
            this.level = level;
            this.content = content;
            this.date = date;
        }
    }
    enum NewsLevel {
        INFO(1),
        WARN(2),
        ERROR(3),
        ;
        public int idx;
        NewsLevel(int idx) {
            this.idx = idx;
        }
    }
}
src/main/java/com/zy/core/MainProcess.java
@@ -55,7 +55,7 @@
                    mainService.storeFinished();
                    // 堆垛机异常信息记录
                    mainService.recCrnErr();
//                    mainService.recCrnErr();
                    // 入库  ===>> 空栈板初始化入库,叉车入库站放货
//                    mainService.storeEmptyPlt();
src/main/java/com/zy/core/ServerBootstrap.java
@@ -1,5 +1,6 @@
package com.zy.core;
import com.zy.common.utils.News;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
@@ -75,39 +76,39 @@
    private void initThread(){
        // 初始化堆垛机线程
        log.info("初始化堆垛机线程...................................................");
        News.info("初始化堆垛机线程...................................................");
        for (CrnSlave crn : slaveProperties.getCrn()) {
            CrnThread crnThread = new SiemensCrnThread(crn);
            new Thread((Runnable) crnThread).start();
            SlaveConnection.put(SlaveType.Crn, crn.getId(), crnThread);
        }
        // 初始化输送线线程
        log.info("初始化输送线线程...................................................");
        News.info("初始化输送线线程...................................................");
        for (DevpSlave devp : slaveProperties.getDevp()) {
            DevpThread devpThread = new SiemensDevpThread(devp);
            new Thread((Runnable) devpThread).start();
            SlaveConnection.put(SlaveType.Devp, devp.getId(), devpThread);
        }
        // 初始化条码扫描仪线程
        log.info("初始化条码扫描仪线程...................................................");
        News.info("初始化条码扫描仪线程...................................................");
        for (Slave barcode : slaveProperties.getBarcode()) {
            BarcodeThread barcodeThread = new BarcodeThread(barcode);
//            new Thread(barcodeThread).start();
            SlaveConnection.put(SlaveType.Barcode, barcode.getId(), barcodeThread);
        }
//        // 初始化LED线程
//        log.info("初始化LED线程...................................................");
//        for (LedSlave led : slaveProperties.getLed()) {
//            LedThread ledThread = new LedThread(led);
//            new Thread(ledThread).start();
//            SlaveConnection.put(SlaveType.Led, led.getId(), ledThread);
//        }
//        // 初始化磅秤线程
//        log.info("初始化磅秤线程...................................................");
        // 初始化LED线程
        News.info("初始化LED线程...................................................");
        for (LedSlave led : slaveProperties.getLed()) {
            LedThread ledThread = new LedThread(led);
            new Thread(ledThread).start();
            SlaveConnection.put(SlaveType.Led, led.getId(), ledThread);
        }
        // 初始化磅秤线程
//        News.info("初始化磅秤线程...................................................");
//        for (Slave scale : slaveProperties.getScale()) {
//            ScaleThread scaleThread = new ScaleThread(scale);
//            new Thread(scaleThread).start();
//            SlaveConnection.put(SlaveType.Scale, scale.getId(), scaleThread);
//            ScaleThread barcodeThread = new ScaleThread(scale);
//            new Thread(barcodeThread).start();
//            SlaveConnection.put(SlaveType.Scale, scale.getId(), barcodeThread);
//        }
    }
src/main/java/com/zy/core/enums/CrnModeType.java
@@ -2,11 +2,11 @@
public enum CrnModeType {
    NONE(0, "关机"),
    AUTO(3, "自动"),
    HALF_AUTO(2, "半自动"),
    NONE(-1, "离线"),
    STOP(0, "维修"),
    HAND(1, "手动"),
    STOP(4, "维修"),
    HALF_AUTO(2, "半自动"),
    AUTO(3, "自动"),
    ;
    public Integer id;
src/main/java/com/zy/core/enums/CrnStatusType.java
@@ -2,36 +2,20 @@
public enum CrnStatusType {
//    NONE(-1, "离线"),
//    IDLE(0, "空闲"),
//    FETCH_MOVING(1, "取货行走"),
//    FETCH_WAITING(2, "取货等待"),
//    FETCHING(3, "取货中"),
//    PUT_MOVING(4, "放货走行"),
//    PUT_WAITING(5, "放货等待"),
//    PUTTING(6, "放货中"),
//    ORIGIN_GO(7, "回原点"),
//    ORIGIN_BACK(8, "回反原点"),
//    MOVING(9, "走行中"),
//    WAITING(10, "任务完成等待WCS确认"),
//    PAUSE(11, "任务暂停"),
//    SOS(99, "报警"),
//    ;
    IDLE(0, "空闲,无任务"),
    NONE_MOVING(1, "取货定位"),
    FETCHING(2, "取货等待"),
    MOVING(3, "取货中"),
    PUTTING(4, "放货走行"),
    HOMING(5, "放货等待"),
    ANTI_ORIGIN(6, "放货中"),
    PUT_COMPLETE(7, "回原点"),
//    MOVE_THE_SHIPPING_LOCATION(8, "移动到放货位置"),
//    PUTTING(9, "放货中"),
    HANDLING_COMPLETED(10, "搬运完成等待WCS确认"),
    EMPTY_AVOIDANCE(11, "空载避让"),
    NONE(-1, "离线"),
    IDLE(0, "空闲"),
    FETCH_MOVING(1, "取货行走"),
    FETCH_WAITING(2, "取货等待"),
    FETCHING(3, "取货中"),
    PUT_MOVING(4, "放货走行"),
    PUT_WAITING(5, "放货等待"),
    PUTTING(6, "放货中"),
    ORIGIN_GO(7, "回原点"),
    ORIGIN_BACK(8, "回反原点"),
    MOVING(9, "走行中"),
    WAITING(10, "任务完成等待WCS确认"),
    PAUSE(11, "任务暂停"),
    SOS(99, "报警"),
    OTHER(100, "其他"),
    ;
    public Integer id;
@@ -50,7 +34,7 @@
                return type;
            }
        }
        return null;
        return NONE;
    }
    public static CrnStatusType get(CrnStatusType type) {
src/main/java/com/zy/core/model/DevpSlave.java
@@ -37,6 +37,8 @@
        private Integer scale;
        private Integer backSta;
        private Integer led;
    }
}
src/main/java/com/zy/core/model/protocol/CrnProtocol.java
@@ -1,7 +1,10 @@
package com.zy.core.model.protocol;
import com.zy.asrs.entity.BasCrnp;
import com.zy.core.enums.*;
import com.zy.core.enums.CrnForkPosType;
import com.zy.core.enums.CrnLiftPosType;
import com.zy.core.enums.CrnModeType;
import com.zy.core.enums.CrnStatusType;
import lombok.Data;
/**
@@ -9,6 +12,8 @@
 */
@Data
public class CrnProtocol {
    private Integer crnNo;
    /**
     * 1 = 手动模式
@@ -20,19 +25,14 @@
    public CrnModeType modeType;
    /**
     * 堆垛机任务完成
     */
    public Short taskFinish;
    /**
     * 校验结果 1表示检验成功
     */
    public Short valid;
    /**
     * 1 = 急停
     */
    public Short eStop;
    /**
     * 异常码
     */
    public Short alarm;
    /**
     * 任务号
@@ -54,8 +54,6 @@
     */
    public Short status;
    public Short alarm = 0;
    /**
     * 状态枚举
     */
@@ -72,175 +70,45 @@
    public Short level;
    /**
     * 堆垛机当前排
     */
    public Short row;
    /**
     * 堆垛机当前巷道号
     */
    public Short lane;
    /**
     * 堆垛机通讯状态
     */
    public Boolean connStatus;
    /**
     * 申请入库修正
     */
    public Boolean correction;
    /**
     * 托盘号错
     */
    public Boolean tuError;
    /**
     * 取货无箱
     */
    public Boolean noneError;
    /**
     * 双重入库
     */
    public Boolean stockError;
    /**
     * 作业数据无效
     */
    public Boolean jobInvalid;
    /**
     * 空闲状态
     */
    public Boolean idle;
    /**
     * 控制柜使能
     */
    public Boolean control;
    /**
     * 停准
     */
    public Boolean stopQuasi;
    /**
     * 运行
     */
    public Boolean running;
    /**
     * 故障
     */
    public Boolean fault;
    /**
     * 货叉中位
     */
    public Boolean forkHome;
    /**
     * 单伸位货叉左位
     */
    public Boolean forkSingleLeft;
    /**
     * 单伸位货叉右位
     */
    public Boolean forkSingleRight;
    /**
     * 双伸位货叉左位
     */
    public Boolean forkDoubleLeft;
    /**
     * 双伸位货叉右位
     */
    public Boolean forkDoubleRight;
    /**
     * 单伸位高位
     */
    public Boolean singleHigh;
    /**
     * 单伸位低位
     */
    public Boolean singleLow;
    /**
     * 双伸位高位
     */
    public Boolean doubleHigh;
    /**
     * 双伸位低位
     */
    public Boolean doubleLow;
    /**
     * 站台高位
     */
    public Boolean platformHigh;
    /**
     * 站台低位
     */
    public Boolean platformLow;
    /**
     * 当前货叉位置
     * 0 = 货叉原位
     * 1 = 货叉在左侧
     * 2 = 货叉在右侧
     */
    public Short forkPos = -1;
    public Short forkPos;
    public CrnForkPosType forkPosType = CrnForkPosType.NONE;
    public CrnForkPosType forkPosType;
    /**
     * 当前载货台位置
     * 0 = 下定位
     * 1 = 上定位
     */
    public Short liftPos = -1;
    public Short liftPos;
    public CrnLiftPosType liftPosType = CrnLiftPosType.ERROR;
    public CrnLiftPosType liftPosType;
    /**
     * 走行在定位
     * 0 = 在定位
     * 1 = 不在定位
     */
    public Short walkPos = 0;
    /**
     * 拨指位置
     * 0 = 不在定位
     * 1 = 上定位
     * 2 = 下定位
     */
    public Short fingerPos;
    public CrnFingerPosType fingerPosType;
    public Short walkPos;
    /**
     * 载货台有物
     */
    public Short loaded;
    /**
     * 堆垛机垂直故障代码(数值显示)
     */
    private Integer alarm1 = 0;
    private Short temp1;
    /**
     * 堆垛机水平故障代码(数值显示)
     */
    private Integer alarm2 = 0;;
    private CrnTemp1 crnTemp1;
    /**
     * 堆垛机货叉故障代码(数值显示)
     */
    private Integer alarm3 = 0;;
    private Short temp2;
    /**
     * 堆垛机状态故障代码(数值显示)
     */
    private Integer alarm4 = 0;;
    private Short temp3;
    private Short temp4;
    /**
     * 异常1
@@ -271,42 +139,53 @@
    private CrnError4 crnError4;
    /**
     * 异常5
     */
    private boolean[] error5;
    private CrnError5 crnError5;
    /**
     * 异常6
     */
    private boolean[] error6;
    private CrnError6 crnError6;
    /**
     * X行走线速度m/min
     */
    private Float xSpeed = 0F;
    private Float xSpeed;
    /**
     * Y行走线速度m/min
     */
    private Float ySpeed = 0F;
    private Float ySpeed;
    /**
     * Z行走线速度m/min
     */
    private Float zSpeed = 0F;
    private Float zSpeed;
    /**
     * 堆垛机累计走行距离km
     */
    public Float xDistance = 0F;
    public Float xDistance;
    /**
     * 堆垛机累计升降距离km
     */
    public Float yDistance = 0F;
    public Float yDistance;
    /**
     * 堆垛机累计走行时长h
     */
    public Float xDuration = 0F;
    public Float xDuration;
    /**w
    /**
     * 堆垛机累计升降时长h
     */
    public Float yDuration = 0F;
    //指令ID
    private Integer commandId;
    public Float yDuration;
    public void setMode(Short mode) {
        this.mode = mode;
@@ -348,81 +227,12 @@
        this.status = CrnStatusType.get(type).id.shortValue();
    }
    public void setFingerPos(Short type) {
        this.fingerPos = type;
        this.fingerPosType = CrnFingerPosType.get(type);
    public Short getTemp1() {
        return temp1;
    }
    public void setError1(boolean[] error1){
        this.error1 = error1;
        this.crnError1 = new CrnError1();
        this.crnError1.remoteStop = error1[0];
        this.crnError1.mainStop = error1[1];
        this.crnError1.controlStop = error1[2];
        this.crnError1.xCoverErr = error1[3];
        this.crnError1.yCoverErr = error1[4];
        this.crnError1.zCoverErr = error1[5];
        this.crnError1.laserErr = error1[6];
        this.crnError1.barcodeErr = error1[7];
        this.crnError1.xFrontLimitErr = error1[8];
        this.crnError1.xBackLimitErr = error1[9];
        this.crnError1.yUpLimitErr = error1[10];
        this.crnError1.yDownLimitErr = error1[11];
        this.crnError1.zLeftLimitErr = error1[12];
        this.crnError1.zRightLimitErr = error1[13];
        this.crnError1.leftOverWidthErr1 = error1[14];
        this.crnError1.leftOverWidthErr2 = error1[15];
    }
    public void setError2(boolean[] error2){
        this.error2 = error2;
        this.crnError2 = new CrnError2();
        this.crnError2.leftOverLenErr1 = error2[0];
        this.crnError2.leftOverLenErr2 = error2[1];
        this.crnError2.leftOverHighErr = error2[2];
        this.crnError2.rightOverWidthErr1 = error2[3];
        this.crnError2.rightOverWidthErr2 = error2[4];
        this.crnError2.rightOverLenErr1 = error2[5];
        this.crnError2.rightOverLenErr2 = error2[6];
        this.crnError2.rightOverHighErr = error2[7];
        this.crnError2.leftLooseRopeErr = error2[8];
        this.crnError2.rightLooseRopeErr = error2[9];
        this.crnError2.frontDoorErr = error2[10];
        this.crnError2.backDoorErr = error2[11];
        this.crnError2.startupErr = error2[12];
        this.crnError2.xFrontLocaUpErr = error2[13];
        this.crnError2.xFrontLocaDownErr = error2[14];
        this.crnError2.xBackLocaUpErr = error2[15];
    }
    public void setError3(boolean[] error3) {
        this.error3 = error3;
        this.crnError3 = new CrnError3();
        this.crnError3.xBackLocaDownErr = error3[0];
        this.crnError3.yUpLocaUpErr = error3[1];
        this.crnError3.yUpLocaDownErr = error3[2];
        this.crnError3.yDownLocaUpErr = error3[3];
        this.crnError3.yDownLocaDownErr = error3[4];
        this.crnError3.zLeftLocaUpErr = error3[5];
        this.crnError3.zLeftLocaDownErr = error3[6];
        this.crnError3.zRightLocaUpErr = error3[7];
        this.crnError3.zRightLocaDownErr = error3[8];
        this.crnError3.leftTakeNoneErr = error3[9];
        this.crnError3.rightTakeNoneErr = error3[10];
        this.crnError3.leftTakeThenLoadErr = error3[11];
        this.crnError3.rightTakeThenLoadErr = error3[12];
        this.crnError3.leftPutAndLoadErr = error3[13];
        this.crnError3.rightPutAndLoadErr = error3[14];
        this.crnError3.leftPutThenNoneErr = error3[15];
    }
    public void setError4(boolean[] error4) {
        this.error4 = error4;
        this.crnError4 = new CrnError4();
        this.crnError4.rightPutThenNoneErr = error4[0];
        this.crnError4.xLooseBrakeTimeout = error4[1];
        this.crnError4.yLooseBrakeTimeout = error4[2];
        this.crnError4.zLooseBrakeTimeout = error4[3];
    public void setTemp1(Short temp1) {
        this.temp1 = temp1;
    }
    /**
@@ -434,8 +244,39 @@
    public BasCrnp toSqlModel(BasCrnp basCrnp){
        basCrnp.setCrnErr(alarm.longValue());
        if (alarm!=null) {
            basCrnp.setCrnErr(alarm.longValue());
        }
        basCrnp.setWrkNo(taskNo.intValue());
        return basCrnp;
    }
    public void setxSpeed(Short xSpeed) {
        this.xSpeed = Float.valueOf(xSpeed);
    }
    public void setySpeed(Short ySpeed) {
        this.ySpeed = Float.valueOf(ySpeed);
    }
    public void setzSpeed(Short zSpeed) {
        this.zSpeed = Float.valueOf(zSpeed);
    }
    public void setxDistance(Short xDistance) {
        this.xDistance = Float.valueOf(xDistance);
    }
    public void setyDistance(Short yDistance) {
        this.yDistance = Float.valueOf(yDistance);
    }
    public void setxDuration(Short xDuration) {
        this.xDuration = Float.valueOf(xDuration);
    }
    public void setyDuration(Short yDuration) {
        this.yDuration = Float.valueOf(yDuration);
    }
}
src/main/java/com/zy/core/model/protocol/StaProtocol.java
@@ -62,6 +62,9 @@
    // 隔壁站点(台车位置)
    private String nearbySta;
    //允许空托出库
    private String allowEmptyOut;
    //指令ID
    private Integer commandId;
@@ -118,6 +121,8 @@
    private List<Integer> alarm;
    public List<Integer> getAlarm(){
        List<Integer> alarm = new ArrayList<>();
        if (breakerErr){
src/main/java/com/zy/core/thread/SiemensCrnThread.java
@@ -14,6 +14,7 @@
import com.zy.asrs.entity.param.TaskOverToWms;
import com.zy.asrs.service.*;
import com.zy.common.utils.HttpHandler;
import com.zy.common.utils.News;
import com.zy.core.CrnThread;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
@@ -43,6 +44,11 @@
    private CrnSlave slave;
    private CrnProtocol crnProtocol;
    private boolean resetFlag = false;
    /**
     * 堆垛机是否在回原点运动中标记
     */
    private boolean backHpFlag = false;
    @Value("${wms.url}")
    private String wmsUrl;
@@ -124,16 +130,26 @@
     * 初始化堆垛机
     */
    private void initCrnProtocol(){
        crnProtocol = new CrnProtocol();
        crnProtocol.setMode((short) 0);
        crnProtocol.setStatus((short) 0);
        crnProtocol.setTaskNo((short) 0);
        crnProtocol.setTaskFinish((short) 0);
        crnProtocol.setValid((short) 0);
        crnProtocol.setBay((short) 0);
        crnProtocol.setLevel((short) 0);
        crnProtocol.setRow((short) 0);
        crnProtocol.setLane((short) 0);
        if (null == crnProtocol) {
            crnProtocol = new CrnProtocol();
        }
        crnProtocol.setMode((short) -1);
//        crnProtocol.setTaskNo((short)0);
        crnProtocol.setStatus((short)-1);
        crnProtocol.setBay((short)0);
        crnProtocol.setLevel((short)0);
        crnProtocol.setForkPos((short) -1);
        crnProtocol.setLiftPos((short) -1);
        crnProtocol.setWalkPos((short)0);
        crnProtocol.setLoaded((short)0);
        crnProtocol.setAlarm((short)0);
        crnProtocol.setxSpeed((short) 0);
        crnProtocol.setySpeed((short) 0);
        crnProtocol.setzSpeed((short) 0);
        crnProtocol.setxDistance((short) 0);
        crnProtocol.setyDistance((short) 0);
        crnProtocol.setxDuration((short) 0);
        crnProtocol.setyDuration((short) 0);
    }
    @Override
@@ -162,153 +178,74 @@
     * 读取状态
     */
    private void readStatus(){
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        OperateResultExOne<byte[]> result = siemensNet.Read("DB101.0", (short) 56);
        if (result.IsSuccess) {
            if (null == crnProtocol) {
                crnProtocol = new CrnProtocol();
            }
            crnProtocol.setMode(siemensNet.getByteTransform().TransInt16(result.Content, 0));
            crnProtocol.setTaskNo(siemensNet.getByteTransform().TransInt16(result.Content, 2));
            crnProtocol.setStatus(siemensNet.getByteTransform().TransInt16(result.Content, 4));
            crnProtocol.setBay(siemensNet.getByteTransform().TransInt16(result.Content, 6));
            crnProtocol.setLevel(siemensNet.getByteTransform().TransInt16(result.Content, 8));
            crnProtocol.setForkPos(siemensNet.getByteTransform().TransInt16(result.Content, 10));
            crnProtocol.setLiftPos(siemensNet.getByteTransform().TransInt16(result.Content, 12));
            crnProtocol.setWalkPos(siemensNet.getByteTransform().TransInt16(result.Content, 14));
            crnProtocol.setLoaded(siemensNet.getByteTransform().TransInt16(result.Content, 16));
            crnProtocol.setAlarm(siemensNet.getByteTransform().TransInt16(result.Content, 18));
//            crnProtocol.setTemp1(siemensNet.getByteTransform().TransInt16(result.Content, 20));
//            crnProtocol.setTemp2(siemensNet.getByteTransform().TransInt16(result.Content, 22));
//            crnProtocol.setTemp3(siemensNet.getByteTransform().TransInt16(result.Content, 24));
//            crnProtocol.setTemp4(siemensNet.getByteTransform().TransInt16(result.Content, 26));
            crnProtocol.setXSpeed(siemensNet.getByteTransform().TransSingle(result.Content, 28));
            crnProtocol.setYSpeed(siemensNet.getByteTransform().TransSingle(result.Content, 32));
            crnProtocol.setZSpeed(siemensNet.getByteTransform().TransSingle(result.Content, 36));
            crnProtocol.setXDistance(siemensNet.getByteTransform().TransSingle(result.Content, 40));
            crnProtocol.setYDistance(siemensNet.getByteTransform().TransSingle(result.Content, 44));
            crnProtocol.setXDuration(siemensNet.getByteTransform().TransSingle(result.Content, 48));
            crnProtocol.setYDuration(siemensNet.getByteTransform().TransSingle(result.Content, 52));
        try {
            OperateResultExOne<byte[]> result = siemensNet.Read("DB101.0", (short) 56);
            if (result.IsSuccess) {
                if (null == crnProtocol) {
                    crnProtocol = new CrnProtocol();
                    crnProtocol.setCrnNo(slave.getId());
                }
                crnProtocol.setMode(siemensNet.getByteTransform().TransInt16(result.Content, 0));
                crnProtocol.setTaskNo(siemensNet.getByteTransform().TransInt16(result.Content, 2));
                crnProtocol.setStatus(siemensNet.getByteTransform().TransInt16(result.Content, 4));
                crnProtocol.setBay(siemensNet.getByteTransform().TransInt16(result.Content, 6));
                crnProtocol.setLevel(siemensNet.getByteTransform().TransInt16(result.Content, 8));
                crnProtocol.setForkPos(siemensNet.getByteTransform().TransInt16(result.Content, 10));
                crnProtocol.setLiftPos(siemensNet.getByteTransform().TransInt16(result.Content, 12));
                crnProtocol.setWalkPos(siemensNet.getByteTransform().TransInt16(result.Content, 14));
                crnProtocol.setLoaded(siemensNet.getByteTransform().TransInt16(result.Content, 16));
                crnProtocol.setAlarm(siemensNet.getByteTransform().TransInt16(result.Content, 18));
                crnProtocol.setTemp1(siemensNet.getByteTransform().TransInt16(result.Content, 20));
                crnProtocol.setTemp2(siemensNet.getByteTransform().TransInt16(result.Content, 22));
                crnProtocol.setTemp3(siemensNet.getByteTransform().TransInt16(result.Content, 24));
                crnProtocol.setTemp4(siemensNet.getByteTransform().TransInt16(result.Content, 26));
                crnProtocol.setxSpeed(siemensNet.getByteTransform().TransInt16(result.Content, 28));
                crnProtocol.setySpeed(siemensNet.getByteTransform().TransInt16(result.Content, 32));
                crnProtocol.setzSpeed(siemensNet.getByteTransform().TransInt16(result.Content, 36));
                crnProtocol.setxDistance(siemensNet.getByteTransform().TransInt16(result.Content, 40));
                crnProtocol.setyDistance(siemensNet.getByteTransform().TransInt16(result.Content, 44));
                crnProtocol.setxDuration(siemensNet.getByteTransform().TransInt16(result.Content, 48));
                crnProtocol.setyDuration(siemensNet.getByteTransform().TransInt16(result.Content, 52));
                OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
            // 复位信号
            if (crnProtocol.getTaskFinish() == 0) {
                if (resetFlag) {
                    CrnCommand crnCommand = new CrnCommand();
                    crnCommand.setAckFinish((short)1);
                    if (write(crnCommand)) {
                        resetFlag = false;
                        //堆垛机任务完成后访问wms请求任务完成 locationDone 货位处理完成
                        TaskWrkService taskWrkService = SpringUtils.getBean(TaskWrkService.class);
                        TaskWrk taskWrk = taskWrkService.selectOne(new EntityWrapper<TaskWrk>().eq("wrk_no",crnProtocol.getTaskNo()));
                        String tasktype = null;
                        switch (taskWrk.getIoType()){
                            case 1:
                                tasktype= "RK";
                                break;
                            case 2:
                                tasktype= "CK";
                                break;
                            case 3:
                                tasktype= "YK";
                                break;
                            default:
                                tasktype= "未知";
                // 复位信号
                if (crnProtocol.getStatusType().equals(CrnStatusType.WAITING)) {
                    if (resetFlag) {
                        if(crnProtocol.getTaskNo()==9999){
                            backHpFlag = false;
                        }
                        Map<String, Object> map = new HashMap<>();
                        map.put("x-api-key","7a15b5db-29b6-552c-8cff-0cfec3756da2");
                        TaskOverToWms taskOverToWms = new TaskOverToWms();
                        taskOverToWms.setFeedbackFrom("WCS"); //来源
                        taskOverToWms.setWarehouseId("1688469798893297665"); //仓库标识
                        taskOverToWms.setTaskNo(taskWrk.getTaskNo()); //任务号
                        taskOverToWms.setTaskType(tasktype); // 任务类型
                        taskOverToWms.setContainerCode(taskWrk.getBarcode()); // 容器编码
                        if (taskWrk.getIoType() ==1){
                            taskOverToWms.setEquipmentCode(String.valueOf(taskWrk.getCrnNo())); //设备编码
                            taskOverToWms.setTargetLocationCode(taskWrk.getOriginTargetPoint()); //目标库位
                        }else if (taskWrk.getIoType() ==2){
                            Map<Integer,String> map1 = new HashMap<>();
                            map1.put(102,"J-1101");
                            map1.put(106,"J-1103");
                            map1.put(110,"J-1105");
                            map1.put(114,"J-1107");
                            map1.put(118,"J-1109");
                            map1.put(122,"J-1111");
                            map1.put(305,"H-1101");
                            map1.put(405,"G-1101");
                            taskOverToWms.setEquipmentCode(map1.get(taskWrk.getTargetPoint())); //设备编码
                            taskOverToWms.setSourceLocationCode(taskWrk.getOriginStartPoint()); //源库位
                        } else if (taskWrk.getIoType() == 3) {
                            taskOverToWms.setEquipmentCode(String.valueOf(taskWrk.getCrnNo())); //设备编码
                            taskOverToWms.setSourceLocationCode(taskWrk.getOriginStartPoint());
                            taskOverToWms.setTargetLocationCode(taskWrk.getOriginTargetPoint()); //目标库位
                        CrnCommand crnCommand = new CrnCommand();
                        crnCommand.setAckFinish((short)1);
                        if (write(crnCommand)) {
                            resetFlag = false;
                        }
                        taskOverToWms.setTaskStatus("location_done"); //任务状态
                        String response = null;
                        try {
                            response = new HttpHandler.Builder()
                                    .setHeaders(map)
                                    .setUri("10.32.53.195:8080")
                                    .setPath("wcsManager/wcsInterface/taskStatusFeedback")
                                    .setJson(JSON.toJSONString(taskOverToWms))
                                    .build()
                                    .doPost();
                        }catch (Exception e){
                            log.error("堆垛机任务完成,请求wms任务完成接口失败");
                        }
                        ApiLogService apiLogService = SpringUtils.getBean(ApiLogService.class);
                        apiLogService.save("Wms任务完成接口"
                                ,"10.32.53.195:8080"+"/wcsManager/wcsInterface/taskStatusFeedback"
                                ,null
                                ,"127.0.0.1"
                                ,JSON.toJSONString(taskOverToWms)
                                ,response
                                ,true
                        );
                        JSONObject jsonObject = JSON.parseObject(response);
                        if (jsonObject.getInteger("code").equals(200)){
                            if (taskWrk.getIoType() == 3){
                                taskWrk.setWrkSts(4);
                            }
                            taskWrk.setStatus(5);
                            if (!taskWrkService.update(taskWrk,new EntityWrapper<TaskWrk>().eq("wrk_no",crnProtocol.getTaskNo()))){
                                log.error("堆垛机任务完成,改变任务状态失败");
                            }
                            log.info("堆垛机任务完成,请求wms任务完成接口成功");
                        }else {
                            log.error("堆垛机任务完成,请求wms任务完成接口完成,但返回失败");
                        }
                    }
                }
                try {
                    // 根据实时信息更新数据库
                    BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class);
                    BasCrnp basCrnp = new BasCrnp();
                    basCrnp.setCrnNo(slave.getId());
                    basCrnp.setCrnSts((int)crnProtocol.getMode());
                    if (!basCrnpService.updateById(crnProtocol.toSqlModel(basCrnp))){
                        News.error(methodName + ":堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
                    }
                } catch (Exception ignore){}
            } else {
                initCrnProtocol();
                OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败 ===>> [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(methodName + ":读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            }
            try {
                // 根据实时信息更新数据库
                BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class);
                BasCrnp basCrnp = new BasCrnp();
                basCrnp.setCrnNo(slave.getId());
                basCrnp.setCrnSts((int)crnProtocol.getMode());
                if (!basCrnpService.updateById(crnProtocol.toSqlModel(basCrnp))){
                    log.error("堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
                }
            } catch (Exception ignore){}
            DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
            deviceErrorService.deleteDeviceError("crn", slave.getId());
        } else {
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.error("读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
            deviceErrorService.addDeviceError("crn", slave.getId(), "读取堆垛机plc状态信息失败");
        } catch (Exception e) {
            e.printStackTrace();
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            News.error(methodName + ":读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            initCrnProtocol();
        }
    }
@@ -374,7 +311,7 @@
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        if (null == command) {
            log.error("堆垛机写入命令为空");
            News.error("堆垛机写入命令为空");
            return false;
        }
//        convertRow(command);
@@ -392,38 +329,35 @@
//        array[9] = command.getSourceStaNo();
//        array[10] = command.getDestinationStaNo();
        array[9] = command.getCommand();
        OperateResult result = siemensNet.Write("DB100.0", array);
        int i=0;
        do{
            //堆垛机任务写入后,回读一次,看是否成功
            Thread.sleep(200);
            OperateResultExOne<byte[]> resultRead = siemensNet.Read("DB100.0", (short) 20);
            if (resultRead.IsSuccess) {
                CrnCommand one = new CrnCommand();
                one.setTaskNo(siemensNet.getByteTransform().TransInt16(resultRead.Content, 2));
                one.setTaskMode(siemensNet.getByteTransform().TransInt16(resultRead.Content, 4));
                one.setSourcePosX(siemensNet.getByteTransform().TransInt16(resultRead.Content, 6));
                one.setSourcePosY(siemensNet.getByteTransform().TransInt16(resultRead.Content, 8));
                one.setSourcePosZ(siemensNet.getByteTransform().TransInt16(resultRead.Content, 10));
                one.setDestinationPosX(siemensNet.getByteTransform().TransInt16(resultRead.Content, 12));
                one.setDestinationPosY(siemensNet.getByteTransform().TransInt16(resultRead.Content, 14));
                one.setDestinationPosZ(siemensNet.getByteTransform().TransInt16(resultRead.Content, 16));
                if (!command.getTaskNo().equals(one.getTaskNo()) || !command.getTaskMode().equals(one.getTaskMode())
                        || !command.getSourcePosX().equals(one.getSourcePosX()) || !command.getSourcePosY().equals(one.getSourcePosY())
                        || !command.getSourcePosZ().equals(one.getSourcePosZ()) || !command.getDestinationPosX().equals(one.getDestinationPosX())
                        || !command.getDestinationPosY().equals(one.getDestinationPosY()) || !command.getDestinationPosZ().equals(one.getDestinationPosZ())
                ){
                    i++;
                    log.error("堆垛机命令地址写入后回读失败[id:{}]>>>>重写[{}] >>>>> 写入[{}],===>>回读[{}]", slave.getId(), i,JSON.toJSON(command),JSON.toJSON(one));
                    result = siemensNet.Write("DB100.0", array);
                }else{
                    i=5;
                }
        //堆垛机任务写入后,回读一次,看是否成功
        Thread.sleep(200);
        OperateResultExOne<byte[]> resultRead = siemensNet.Read("DB100.0", (short) 20);
        if (resultRead.IsSuccess) {
            CrnCommand one = new CrnCommand();
            one.setTaskNo(siemensNet.getByteTransform().TransInt16(resultRead.Content, 2));
            one.setTaskMode(siemensNet.getByteTransform().TransInt16(resultRead.Content, 4));
            one.setSourcePosX(siemensNet.getByteTransform().TransInt16(resultRead.Content, 6));
            one.setSourcePosY(siemensNet.getByteTransform().TransInt16(resultRead.Content, 8));
            one.setSourcePosZ(siemensNet.getByteTransform().TransInt16(resultRead.Content, 10));
            one.setDestinationPosX(siemensNet.getByteTransform().TransInt16(resultRead.Content, 12));
            one.setDestinationPosY(siemensNet.getByteTransform().TransInt16(resultRead.Content, 14));
            one.setDestinationPosZ(siemensNet.getByteTransform().TransInt16(resultRead.Content, 16));
            if (!command.getTaskNo().equals(one.getTaskNo()) || !command.getTaskMode().equals(one.getTaskMode())
                    || !command.getSourcePosX().equals(one.getSourcePosX()) || !command.getSourcePosY().equals(one.getSourcePosY())
                    || !command.getSourcePosZ().equals(one.getSourcePosZ()) || !command.getDestinationPosX().equals(one.getDestinationPosX())
                    || !command.getDestinationPosY().equals(one.getDestinationPosY()) || !command.getDestinationPosZ().equals(one.getDestinationPosZ())
            ){
                News.error("堆垛机命令地址写入后回读失败[id:{}] >>>>> 写入[{}],===>>回读[{}]", slave.getId(), JSON.toJSON(command),JSON.toJSON(one));
            }
        }while(i<5);
        }
        if (command.getAckFinish() == 0) {
            short commandFinish = 1;
            Thread.sleep(100L);
            result = siemensNet.Write("DB100.18", commandFinish);
        }
        try {
            // 日志记录
@@ -451,12 +385,12 @@
        if (result != null && result.IsSuccess) {
            Thread.sleep(200);
            this.readStatus();
            log.info(methodName + ":堆垛机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            News.info(methodName + ":堆垛机命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            return true;
        } else {
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.error(methodName + ":写入堆垛机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            News.error(methodName + ":写入堆垛机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            return false;
        }
    }
@@ -464,112 +398,112 @@
    /**
     * 写入数据
     */
    private boolean write2(CrnCommand command){
        if (null == command) {
            log.error("堆垛机写入命令为空");
            return false;
        }
        //转换前克隆一份
        CrnCommand crnCommand = new CrnCommand();
        crnCommand.setCrnNo(command.getCrnNo());
        crnCommand.setAckFinish(command.getAckFinish());
        crnCommand.setTaskNo(command.getTaskNo());
        crnCommand.setTaskMode(command.getTaskMode());
        crnCommand.setSourcePosX(command.getSourcePosX());
        crnCommand.setSourcePosY(command.getSourcePosY());
        crnCommand.setSourcePosZ(command.getSourcePosZ());
        crnCommand.setDestinationPosX(command.getDestinationPosX());
        crnCommand.setDestinationPosY(command.getDestinationPosY());
        crnCommand.setDestinationPosZ(command.getDestinationPosZ());
//        crnCommand.setSourceStaNo(command.getSourceStaNo());
//        crnCommand.setDestinationStaNo(command.getDestinationStaNo());
        crnCommand.setCommand(command.getCommand());
        if (command.getTaskNo() == 0 && command.getAckFinish() == 0 && command.getAuto() != 1) {
            command.setTaskNo((short) 999);
        }
        command.setCrnNo(slave.getId());
        short[] array = new short[10];
        if (Cools.isEmpty(command.getAckFinish())) {
            array[0] = 5;
        } else {
            array[0] = command.getAckFinish();
        }
        array[1] = command.getTaskNo();
        array[2] = command.getTaskMode();
        array[3] = command.getSourcePosX();
        array[4] = command.getSourcePosY();
        array[5] = command.getSourcePosZ();
        array[6] = command.getDestinationPosX();
        array[7] = command.getDestinationPosY();
        array[8] = command.getDestinationPosZ();
        array[9] = command.getCommand();
        // 作业信息
        OperateResult result = siemensNet.Write("DB100.0", array);
        // 日志记录
            if (command.getAckFinish() != 1) {
                BasCrnOptService bean = SpringUtils.getBean(BasCrnOptService.class);
                BasCrnOpt basCrnOpt = new BasCrnOpt(
                        command.getTaskNo().intValue(),    // 任务号
                        command.getCrnNo(),    // 堆垛机[非空]
                        new Date(),    // 下发时间
                        command.getTaskModeType() == null ? null : command.getTaskModeType().toString(),    // 模式
                        command.getSourcePosX().intValue(),    // 源排
                        command.getSourcePosY().intValue(),    // 源列
                        command.getSourcePosZ().intValue(),    // 源层
                        null,    // 源站
                        command.getDestinationPosX().intValue(),    // 目标排
                        command.getDestinationPosY().intValue(),    // 目标列
                        command.getDestinationPosZ().intValue(),    // 目标层
                        null,    // 目标站
                        null,    // 响应结果
                        null,    // 修改时间
                        null    // 修改人员
                );
                bean.insert(basCrnOpt);
            }
//        } catch (Exception ignore) {}
        //更新命令日志
        CommandInfoLogService commandInfoLogService = SpringUtils.getBean(CommandInfoLogService.class);
        CommandInfoService commandInfoService = SpringUtils.getBean(CommandInfoService.class);
        CommandInfo commandInfo = commandInfoService.selectById(command.getCommandId());
        if (Cools.isEmpty(commandInfo)){
            commandInfo = commandInfoService.selectOne(new EntityWrapper<CommandInfo>()
                    .eq("wrk_no",crnProtocol.getTaskNo())
                    .eq("device","Crn"));
        }
        CommandInfoLog commandInfoLog = JSON.parseObject(JSON.toJSONString(commandInfo), CommandInfoLog.class);
        commandInfoLog.setId(null);
        if (result.IsSuccess) {
            Date now = new Date();
            //更新指令日志
            commandInfoLog.setDeviceLog("指令下发成功");
            commandInfoLogService.insert(commandInfoLog);
            //线程暂存指令ID
            crnProtocol.setCommandId(command.getCommandId());
            //更新指令状态
            commandInfo.setCommandStatus(CommandStatusType.EXECUTE.id);//执行中
            commandInfo.setExecuteTime(now);
            commandInfoService.updateById(commandInfo);
            //更新任务步序
            TaskWrkService taskWrkService = SpringUtils.getBean(TaskWrkService.class);
            TaskWrk taskWrk = taskWrkService.selectByWrkNo(command.getTaskNo().intValue());
            if (taskWrk != null) {
                taskWrk.setCommandStep(taskWrk.getCommandStep() + 1);//更新指令步序
                taskWrkService.updateById(taskWrk);
            }
        } else {
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.error("写入堆垛机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
        }
        return true;
    }
//    private boolean write2(CrnCommand command){
//        if (null == command) {
//            log.error("堆垛机写入命令为空");
//            return false;
//        }
//        //转换前克隆一份
//        CrnCommand crnCommand = new CrnCommand();
//        crnCommand.setCrnNo(command.getCrnNo());
//        crnCommand.setAckFinish(command.getAckFinish());
//        crnCommand.setTaskNo(command.getTaskNo());
//        crnCommand.setTaskMode(command.getTaskMode());
//        crnCommand.setSourcePosX(command.getSourcePosX());
//        crnCommand.setSourcePosY(command.getSourcePosY());
//        crnCommand.setSourcePosZ(command.getSourcePosZ());
//        crnCommand.setDestinationPosX(command.getDestinationPosX());
//        crnCommand.setDestinationPosY(command.getDestinationPosY());
//        crnCommand.setDestinationPosZ(command.getDestinationPosZ());
////        crnCommand.setSourceStaNo(command.getSourceStaNo());
////        crnCommand.setDestinationStaNo(command.getDestinationStaNo());
//        crnCommand.setCommand(command.getCommand());
//        if (command.getTaskNo() == 0 && command.getAckFinish() == 0 && command.getAuto() != 1) {
//            command.setTaskNo((short) 999);
//        }
//
//        command.setCrnNo(slave.getId());
//        short[] array = new short[10];
//        if (Cools.isEmpty(command.getAckFinish())) {
//            array[0] = 5;
//        } else {
//            array[0] = command.getAckFinish();
//        }
//        array[1] = command.getTaskNo();
//        array[2] = command.getTaskMode();
//        array[3] = command.getSourcePosX();
//        array[4] = command.getSourcePosY();
//        array[5] = command.getSourcePosZ();
//        array[6] = command.getDestinationPosX();
//        array[7] = command.getDestinationPosY();
//        array[8] = command.getDestinationPosZ();
//        array[9] = command.getCommand();
//        // 作业信息
//        OperateResult result = siemensNet.Write("DB100.0", array);
//        // 日志记录
//            if (command.getAckFinish() != 1) {
//                BasCrnOptService bean = SpringUtils.getBean(BasCrnOptService.class);
//                BasCrnOpt basCrnOpt = new BasCrnOpt(
//                        command.getTaskNo().intValue(),    // 任务号
//                        command.getCrnNo(),    // 堆垛机[非空]
//                        new Date(),    // 下发时间
//                        command.getTaskModeType() == null ? null : command.getTaskModeType().toString(),    // 模式
//                        command.getSourcePosX().intValue(),    // 源排
//                        command.getSourcePosY().intValue(),    // 源列
//                        command.getSourcePosZ().intValue(),    // 源层
//                        null,    // 源站
//                        command.getDestinationPosX().intValue(),    // 目标排
//                        command.getDestinationPosY().intValue(),    // 目标列
//                        command.getDestinationPosZ().intValue(),    // 目标层
//                        null,    // 目标站
//                        null,    // 响应结果
//                        null,    // 修改时间
//                        null    // 修改人员
//                );
//                bean.insert(basCrnOpt);
//            }
////        } catch (Exception ignore) {}
//
//        //更新命令日志
//        CommandInfoLogService commandInfoLogService = SpringUtils.getBean(CommandInfoLogService.class);
//        CommandInfoService commandInfoService = SpringUtils.getBean(CommandInfoService.class);
//        CommandInfo commandInfo = commandInfoService.selectById(command.getCommandId());
//        if (Cools.isEmpty(commandInfo)){
//            commandInfo = commandInfoService.selectOne(new EntityWrapper<CommandInfo>()
//                    .eq("wrk_no",crnProtocol.getTaskNo())
//                    .eq("device","Crn"));
//        }
//        CommandInfoLog commandInfoLog = JSON.parseObject(JSON.toJSONString(commandInfo), CommandInfoLog.class);
//        commandInfoLog.setId(null);
//        if (result.IsSuccess) {
//            Date now = new Date();
//            //更新指令日志
//            commandInfoLog.setDeviceLog("指令下发成功");
//            commandInfoLogService.insert(commandInfoLog);
//
//            //线程暂存指令ID
//            crnProtocol.setCommandId(command.getCommandId());
//
//            //更新指令状态
//            commandInfo.setCommandStatus(CommandStatusType.EXECUTE.id);//执行中
//            commandInfo.setExecuteTime(now);
//            commandInfoService.updateById(commandInfo);
//
//            //更新任务步序
//            TaskWrkService taskWrkService = SpringUtils.getBean(TaskWrkService.class);
//            TaskWrk taskWrk = taskWrkService.selectByWrkNo(command.getTaskNo().intValue());
//            if (taskWrk != null) {
//                taskWrk.setCommandStep(taskWrk.getCommandStep() + 1);//更新指令步序
//                taskWrkService.updateById(taskWrk);
//            }
//
//
//        } else {
//            OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
//            log.error("写入堆垛机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
//        }
//        return true;
//    }
    private boolean writeAuto(CrnCommand command){
        if (null == command) {
src/main/java/com/zy/core/thread/SiemensDevpThread.java
@@ -205,11 +205,13 @@
     * 读取状态 ====> 整块plc
     */
    private void read() throws InterruptedException {
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
//        // 更新入出库模式
//        updateIoMode();
        ArrayList<Integer> staNos = getStaNo();
        int staNoSize = staNos.size();
        OperateResultExOne<byte[]> result = siemensS7Net.Read("DB101.0", (short) (staNoSize*8));
        OperateResultExOne<byte[]> result = siemensS7Net.Read("DB100.0", (short) (staNoSize*4));
        if (result.IsSuccess) {
            for (int i = 0; i < staNoSize; i++) {
                Integer siteId = staNos.get(i); // 站点编号
@@ -219,11 +221,32 @@
                    staProtocol.setSiteId(siteId);
                    station.put(siteId, staProtocol);
                }
                staProtocol.setWorkNo((short)siemensS7Net.getByteTransform().TransInt32(result.Content, i*8));     // 工作号
                staProtocol.setWorkNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i*4));     // 工作号
                staProtocol.setStaNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i*8 + 4));   // 目标站
                boolean[] status = siemensS7Net.getByteTransform().TransBool(result.Content, i*8 + 6, 2);
                staProtocol.setStaNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i*4 + 2));   // 目标站
            }
        }
//        Thread.sleep(200);
//        OperateResultExOne<byte[]> result0 = siemensS7Net.Read("DB101.0", (short) 186);
//        if (result0.IsSuccess) {
//            for (int i = 0; i < 93; i++) {
//                Integer siteId = staNos.get(i); // 站点编号
//                StaProtocol staProtocol = station.get(siteId);
//                if (null == staProtocol) {
//                    staProtocol = new StaProtocol();
//                    staProtocol.setSiteId(siteId);
//                    station.put(siteId, staProtocol);
//                }
//                staProtocol.setStaNo(siemensS7Net.getByteTransform().TransInt16(result0.Content, i*2));   // 目标站
//            }
//        }
        Thread.sleep(200);
        OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB100.100", (short) (staNoSize * 2));
        if (result1.IsSuccess) {
            for (int i = 0; i < staNoSize; i++) {
                Integer siteId = staNos.get(i); // 站点编号
                boolean[] status = siemensS7Net.getByteTransform().TransBool(result1.Content, i*2, 1);
                StaProtocol staProtocol = station.get(siteId);
                staProtocol.setAutoing(status[0]);  // 自动
                staProtocol.setLoading(status[1]);  // 有物
                staProtocol.setInEnable(status[2]); // 可入
@@ -239,144 +262,52 @@
            }
        }
//        OperateResultExOne<byte[]> resultAgvAndPlc = siemensS7Net.Read("DB102.0", (short) 30);
//        if (resultAgvAndPlc.IsSuccess) {
//            for (int i = 0; i < staNoSize; i++) {
//                int sign =(i+2)/2-1;
//                if ((i+2)%2!=0){
//                    Integer siteId = staNos.get(i); // 站点编号
//                    StaProtocol staProtocol = station.get(siteId);
//                    if (null == staProtocol) {
//                        staProtocol = new StaProtocol();
//                        staProtocol.setSiteId(siteId);
//                        station.put(siteId, staProtocol);
//                    }
//                    staProtocol.setAgvStartPick(siemensS7Net.getByteTransform().TransInt16(resultAgvAndPlc.Content, sign*6+4));     // 允许取货
//                    staProtocol.setAgvStartPlace((short)0);   // 允许放货
//                    continue;
//                }
//                Integer siteId = staNos.get(i); // 站点编号
//                StaProtocol staProtocol = station.get(siteId);
//                if (null == staProtocol) {
//                    staProtocol = new StaProtocol();
//                    staProtocol.setSiteId(siteId);
//                    station.put(siteId, staProtocol);
//                }
//                staProtocol.setAgvStartPick(siemensS7Net.getByteTransform().TransInt16(resultAgvAndPlc.Content, sign*6));     // 允许取货
//                staProtocol.setAgvStartPlace(siemensS7Net.getByteTransform().TransInt16(resultAgvAndPlc.Content, sign*6 + 2));   // 允许放货
//            }
//        }
//        OperateResultExOne<byte[]> resultAgvAndPlcOk = siemensS7Net.Read("DB132.0", (short) 30);
//        if (resultAgvAndPlcOk.IsSuccess) {
//            for (int i = 0; i < staNoSize; i++) {
//                int sign =(i+2)/2-1;
//                if ((i+2)%2!=0){
//                    Integer siteId = staNos.get(i); // 站点编号
//                    StaProtocol staProtocol = station.get(siteId);
//                    if (null == staProtocol) {
//                        staProtocol = new StaProtocol();
//                        staProtocol.setSiteId(siteId);
//                        station.put(siteId, staProtocol);
//                    }
//                    staProtocol.setAgvTargetPick(siemensS7Net.getByteTransform().TransInt16(resultAgvAndPlcOk.Content, sign*6+4));     // 允许取货
//                    staProtocol.setAgvTargetPlace((short)0);   // 允许放货
//                    continue;
//                }
//                Integer siteId = staNos.get(i); // 站点编号
//                StaProtocol staProtocol = station.get(siteId);
//                if (null == staProtocol) {
//                    staProtocol = new StaProtocol();
//                    staProtocol.setSiteId(siteId);
//                    station.put(siteId, staProtocol);
//                }
//                try{
//                    staProtocol.setAgvTargetPick(siemensS7Net.getByteTransform().TransInt16(resultAgvAndPlcOk.Content, sign*6));     // 取货完成
//                    if (staProtocol.getAgvTargetPick()!=0){
//                        System.out.println(staProtocol.getAgvTargetPick());
//                    }
//                    staProtocol.setAgvTargetPlace(siemensS7Net.getByteTransform().TransInt16(resultAgvAndPlcOk.Content, sign*6 + 2));   // 放货完成
//                    if (staProtocol.getAgvTargetPlace()!=0){
//                        System.out.println(staProtocol.getAgvTargetPlace());
//                    }
//                }catch (Exception e){
//                    log.error(""+e);
//                }
//            }
//        }
        if (slave.getId() == 1) {
            //条码
            //Thread.sleep(200);
            OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB101.848.0", (short) 8);
            if (result2.IsSuccess) {
                for (int i = 0; i < 1; i++) {
                    String barcode = siemensS7Net.getByteTransform().TransString(result2.Content, i * 8, 8, "UTF-8");
                    BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, i + 1);
                    if (!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) {
                        barcodeThread.setBarcode(barcode);
                    }
                }
            }
            //外形检测
            OperateResultExOne<byte[]> resultErr1 = siemensS7Net.Read("DB101.810.0", (short) (barcodeSize*1));
            StaProtocol staProtocol1 = station.get(116);
            boolean[] status1 = siemensS7Net.getByteTransform().TransBool(resultErr1.Content, 0, 1);
            staProtocol1.setFrontErr(status1[0]);
            staProtocol1.setBackErr(status1[1]);
            staProtocol1.setHighErr(status1[2]);
            staProtocol1.setLeftErr(status1[3]);
            staProtocol1.setRightErr(status1[4]);
            staProtocol1.setWeightErr(status1[5]);
            staProtocol1.setBarcodeErr(status1[6]);
            OperateResultExOne<byte[]> resultErr = siemensS7Net.Read("DB101.922.0", (short) (staNoSize * 4));
            if (resultErr.IsSuccess) {
                for (int i = 0; i < staNoSize; i++) {
                    Integer siteId = staNos.get(i); // 站点编号
                    boolean[] status = siemensS7Net.getByteTransform().TransBool(resultErr.Content, i * 4, 1);
                    StaProtocol staProtocol = station.get(siteId);
                    staProtocol.setBreakerErr(status[0]);
                    staProtocol.setInfraredErr(status[1]);
                    staProtocol.setOutTimeErr(status[2]);
                    staProtocol.setSeizeSeatErr(status[3]);
                    staProtocol.setWrkYgoodsN(status[4]);
                    staProtocol.setInverterErr(status[5]);
                    staProtocol.setContactErr(status[6]);
                    staProtocol.setUpcontactErr(status[7]);
        //条码扫描器
        Thread.sleep(200);
        OperateResultExOne<byte[]> result2 = siemensS7Net.Read("DB100.150",(short)(barcodeSize*8));
        if (result2.IsSuccess) {
            for (int i = 0; i < barcodeSize; i++) {
                String barcode = siemensS7Net.getByteTransform().TransString(result2.Content,i*8,8, "UTF-8");
                BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, i + 1);
                if(!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) {
                    barcodeThread.setBarcode(barcode);
                }
            }
        }
        //RGV小车
        Thread.sleep(200);
        OperateResultExOne<byte[]> result3 = siemensS7Net.Read("DB100.160",(short)2);
        if (result3.IsSuccess) {
            Integer siteId = 16;
            StaProtocol staProtocol = station.get(siteId);
            if (null == staProtocol) {
                staProtocol = new StaProtocol();
                staProtocol.setSiteId(siteId);
                station.put(siteId, staProtocol);
            }
            staProtocol.setNearbySta(String.valueOf(siemensS7Net.getByteTransform().TransInt16(result3.Content, 0)));
        }
        /**
         * 母托盘出库
         */
        Thread.sleep(200);
        OperateResultExOne<byte[]> result4 = siemensS7Net.Read("DB100.172",(short)2);
        if (result4.IsSuccess) {
            Integer siteId = 12;
            StaProtocol staProtocol = station.get(siteId);
            if (null == staProtocol) {
                staProtocol = new StaProtocol();
                staProtocol.setSiteId(siteId);
                station.put(siteId, staProtocol);
            }
            staProtocol.setAllowEmptyOut(String.valueOf(siemensS7Net.getByteTransform().TransInt16(result4.Content, 0)));
        }
//        //RGV台车位置
//        Thread.sleep(200);
//        OperateResultExOne<byte[]> result3 = siemensS7Net.Read("DB100.0",(short)4);
//        if (result3.IsSuccess) {
//            for (int i = 0; i < 2; i++) {
//                Integer siteId = i==0 ? 1 : 2; // 站点编号
//                StaProtocol staProtocol = station.get(siteId);
//                if (null == staProtocol) {
//                    staProtocol = new StaProtocol();
//                    staProtocol.setSiteId(siteId);
//                    station.put(siteId, staProtocol);
//                }
//                staProtocol.setNearbySta(String.valueOf(siemensS7Net.getByteTransform().TransInt16(result3.Content, i*2)));
////                String aa = staProtocol.getNearbySta();
////                System.out.println(siteId + "===>>" + staProtocol.getNearbySta());
//            }
//        }
//        OperateResultExOne<Short> result2 = siemensS7Net.ReadInt16("DB200.0");
//        if (result2.IsSuccess) {
//            this.ioMode = IoModeType.get(result2.Content);
//        }
        if (result.IsSuccess ) {
        if (result.IsSuccess && result1.IsSuccess) {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
@@ -395,16 +326,12 @@
            } catch (Exception e) {
                e.printStackTrace();
                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()));
                log.error("更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
                log.error(methodName + ":更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            }
            DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
            deviceErrorService.deleteDeviceError("devp", slave.getId());
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】读取输送线plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
//            log.error("读取输送线plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            DeviceErrorService deviceErrorService = SpringUtils.getBean(DeviceErrorService.class);
            deviceErrorService.addDeviceError("devp", slave.getId(), "读取输送线plc状态信息失败");
//            News.error("读取输送线plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
        }
    }
@@ -412,85 +339,33 @@
     * 写入 ID+目标站 =====> 单站点写入
     */
    private void writeAgvOk(StaProtocol staProtocol) throws InterruptedException {
        String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
        if (null == staProtocol) {
            return;
        }
        ArrayList<Integer> staNos = getStaNo();
        int index = staNos.indexOf(staProtocol.getSiteId());
        if (staProtocol.getAgvTypeSign()==0 || staProtocol.getAgvTypeSign()==2 ){  //0取货
            switch (staProtocol.getSiteId()){
                case 100:
                    index=32;
                    break;
                case 101:
                    index=34;
                    break;
                case 102:
                    index=38;
                    break;
                case 103:
                    index=40;
                    break;
                case 104:
                    index=44;
                    break;
                case 105:
                    index=46;
                    break;
                case 106:
                    index=50;
                    break;
                case 107:
                    index=52;
                    break;
                default:
                    return;
            }
        }else {
            switch (staProtocol.getSiteId()){
                case 100:
                    index=30;
                    break;
                case 102:
                    index=36;
                    break;
                case 104:
                    index=42;
                    break;
                case 106:
                    index=48;
                    break;
                default:
                    return;
            }
        }
        short[] array = new short[2];
        array[0] = staProtocol.getWorkNo();
        array[1] = staProtocol.getStaNo();
        OperateResult write = siemensS7Net.Write("DB100." + index*4, array);
        OperateResult write = null;
        //任务下发次数
        int writeCount = 0;
        do {
            short textWrite = 1;// 任务完成
            if (staProtocol.getAgvTypeSign()>1){
                textWrite = 0;// 任务复位
            }
            write = siemensS7Net.Write("DB102." + index, textWrite);
            if(write.IsSuccess){
                writeCount=6;
            }else {
                writeCount++;
                log.error("写入输送线取放货完成命令后读取失败。输送线plc编号={},站点数据={},写入次数={}", slave.getId(), JSON.toJSON(staProtocol), writeCount);
            }
        }while (writeCount<5);
//        OperateResult write = siemensS7Net.Write("DB100." + index*2, staProtocol.getWorkNo());    // 工作号
//        Thread.sleep(500);
//        OperateResult write1 = siemensS7Net.Write("DB101." + index*2, staProtocol.getStaNo());    // 目标站
        if (!write.IsSuccess) {
            staProtocol = station.get(staProtocol.getSiteId());
            if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) {
                staProtocol.setPakMk(true);
            }
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol)));
            log.error("写入输送线取放货完成站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol));
            log.error(methodName + ":写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol));
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(staProtocol)));
            log.info("输送线取放货完成命令下发码垛完成  给输送线写任务完成 [id:{}] >>>>> 命令下发: {}",  slave.getId(), JSON.toJSON(staProtocol));
            log.info(methodName + ":输送线命令下发 [id:{}] >>>>> 命令下发: {}",  slave.getId(), JSON.toJSON(staProtocol));
        }
    }
    private void write(StaProtocol staProtocol) throws InterruptedException {
        if (null == staProtocol) {
src/main/resources/application-prod.yml
@@ -2,72 +2,144 @@
  doubleDeep: true #双深
  doubleLocs: 1,4,5,8 #双深库位排号 1,4,5,8
  groupCount: 4 #一个堆垛机负责的货架排数
  crn[0]: #堆垛机1
  # 堆垛机1
  crn[0]:
    id: 1
    ip: 10.10.10.110
    slot: 0
    demo: false
    rack: 0
    offset: 2  #偏移量,当堆垛机站点列号=1时,偏移量=2
    port: 102
    crnOutStn[0]: #堆垛机出库站点
      staNo: 125
    rack: 0
    slot: 0
    # 偏移量,当堆垛机站点列号=1时,偏移量=2
    offset: 2
    demo: false
    # 堆垛机入库站点
    crnInStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 007
      row: 3
      bay: 1
      lev: 2
      lev: 1
    # 堆垛机入库站点
    crnOutStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
    crnInStn[0]: #堆垛机入库站点1
      staNo: 100
      staNo: 008
      row: 2
      bay: 1
      lev: 2
      backSta: 102
      devpPlcId: ${wcs-slave.devp[0].id}
  crn[1]: #堆垛机2
      lev: 1
  # 堆垛机2
  crn[1]:
    id: 2
    ip: 10.10.10.120
    slot: 0
    demo: false
    rack: 0
    offset: 2  #偏移量,当堆垛机站点列号=1时,偏移量=2
    port: 102
    crnOutStn[0]: #堆垛机出库站点
      staNo: 115
    rack: 0
    slot: 0
    # 偏移量,当堆垛机站点列号=1时,偏移量=2
    offset: 2
    demo: false
    # 堆垛机入库站点
    crnInStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 005
      row: 7
      bay: 1
      lev: 2
      lev: 1
    # 堆垛机出库站点
    crnOutStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
    crnInStn[0]: #堆垛机入库站点1
      staNo: 120
      staNo: 006
      row: 6
      bay: 1
      lev: 2
      backSta: 106
      devpPlcId: ${wcs-slave.devp[0].id}
  devp[0]: #输送线
    id: 1
      lev: 1
  # 堆垛机3
  crn[2]:
    id: 3
    ip: 10.10.10.130
    rack: 0
    port: 102
    rack: 0
    slot: 0
    emptyInSta[0]: #空板入库口0
      staNo: 116
    inSta[0]: #入库口1
      staNo: 116
      backSta: 110
      barcode: ${wcs-slave.barcode[0].id}
    outSta[0]: #出库口1
      staNo: 105
    outSta[1]: #出库口2
      staNo: 107
    outSta[2]: #出库口2
      staNo: 109
    outSta[3]: #出库口1
      staNo: 110
  barcode[0]: #条码扫描仪
    port: 51236
    ip: 172.17.91.39
    # 偏移量,当堆垛机站点列号=1时,偏移量=2
    offset: 2
    demo: false
    # 堆垛机入库站点
    crnInStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 003
      row: 11
      bay: 1
      lev: 1
    # 堆垛机出库站点
    crnOutStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 004
      row: 10
      bay: 1
      lev: 1
  # 堆垛机4
  crn[3]:
    id: 4
    ip: 10.10.10.140
    port: 102
    rack: 0
    slot: 0
    # 偏移量,当堆垛机站点列号=1时,偏移量=2
    offset: 2
    demo: false
    # 堆垛机入库站点
    crnInStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 001
      row: 15
      bay: 1
      lev: 1
    # 堆垛机出库站点
    crnOutStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 002
      row: 14
      bay: 1
      lev: 1
  # 输送线
  devp[0]:
    id: 1
    ip: 10.10.10.30
    port: 102
    rack: 0
    slot: 0
    # 入库口1
    inSta[0]:
      staNo: 15
      barcode: ${wcs-slave.barcode[0].id}
      led: ${wcs-slave.led[0].id}
    # 空板入库口1
    emptyInSta[0]:
      staNo: 15
    # 出库口1
    outSta[0]:
      staNo: 11
    # 拣料入库口1
    pickSta[0]:
      staNo: 15
      barcode: ${wcs-slave.barcode[0].id}
  # 条码扫描仪
  barcode[0]:
    id: 1
    ip: 10.10.10.55
    port: 51236
    # LED1
  led[0]:
    id: 1
    ip: 10.10.10.81
    port: 5005
    devpPlcId: ${wcs-slave.devp[0].id}
    staArr: 15
  # LED2
  led[1]:
    id: 2
    ip: 10.10.10.202
    port: 5005
    devpPlcId: ${wcs-slave.devp[0].id}
    staArr: 11
#  crn[0]: #堆垛机1
#    rack: 0
#    offset: 2    #偏移量,当堆垛机站点列号=1时,偏移量=2
src/main/resources/application.yml
@@ -1,5 +1,5 @@
server:
  port: 8080
  port: 8081
  servlet:
    context-path: /@pom.build.finalName@
@@ -8,7 +8,7 @@
    name: @pom.build.finalName@
  datasource:
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    url: jdbc:sqlserver://127.0.0.1:1433;databasename=rywxasrs
    url: jdbc:sqlserver://127.0.0.1:1433;databasename=sxdtasrs
    username: sa
    password: sa@123
  mvc:
@@ -37,7 +37,7 @@
#License相关配置
license:
  subject: jdzwcs
  subject: dtwcs
  publicAlias: publicCert
  storePass: public_zhongyang_123456789
  licensePath: license.lic
src/main/webapp/static/wcs/js/common.js
@@ -1,4 +1,4 @@
var baseUrl = "/jdzwcs";
var baseUrl = "/dtwcs";
// 赋值
function setVal(el, val) {
src/main/webapp/static/wcs/js/console.map.js
@@ -1,382 +1,399 @@
mapInfo = {
    "mapName": "jdzwcs",
    "rackCount": 13,
    "mapName": "dtwcs",
    "rackCount": 16,
    "crnCount": 4,
    "stbCount": 4,
    "stbCount": 16,
    "hpPosition": 0,
    "minBayNo": 1,
    "minBayNo": 2,
    "floors": 1,
    "racks": [{
        "type": "rack",
        "id": "rack7",
        "top": 326,
        "left": 800,
        "width": 795,
        "height": 23,
        "minBayNo": 1,
        "maxBayNo": 22,
        "hiddenArr": [1,22]
    }, {
        "type": "rack",
        "id": "rack6",
        "top": 303,
        "left": 800,
        "width": 795,
        "height": 23,
        "minBayNo": 1,
        "maxBayNo": 22,
        "hiddenArr": [1,22]
    }, {
        "type": "rack",
        "id": "rack5",
        "top": 209,
        "left": 800,
        "width": 795,
        "height": 23,
        "minBayNo": 1,
        "maxBayNo": 22,
        "hiddenArr": [1,22]
    },{
        "type": "rack",
        "id": "rack4",
        "top": 232,
        "left": 800,
        "width": 795,
        "height": 23,
        "minBayNo": 1,
        "maxBayNo": 22,
        "hiddenArr": [1,22]
    }, {
        "type": "rack",
        "id": "rack3",
        "top": 182,
        "left": 800,
        "width": 795,
        "height": 23,
        "minBayNo": 1,
        "maxBayNo": 22,
        "hiddenArr": [1,22]
    }, {
        "type": "rack",
        "id": "rack2",
        "top": 159,
        "left": 800,
        "width": 795,
        "height": 23,
        "minBayNo": 1,
        "maxBayNo": 22,
        "hiddenArr": [1,22]
        "top": 547,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack1",
        "top": 98,
        "left": 800,
        "width": 795,
        "height": 23,
        "minBayNo": 1,
        "maxBayNo": 22,
        "hiddenArr": [1,22]
        "top": 639,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack0",
        "top": 75,
        "left": 800,
        "width": 795,
        "height": 23,
        "minBayNo": 1,
        "maxBayNo": 22,
        "hiddenArr": [1,22]
        "id": "rack2",
        "top": 617,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack3",
        "top": 569,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack8",
        "top": 433,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack5",
        "top": 525,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack6",
        "top": 503,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack7",
        "top": 455,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack12",
        "top": 320,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack9",
        "top": 411,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack10",
        "top": 389,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack11",
        "top": 342,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack16",
        "top": 204,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack13",
        "top": 298,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack15",
        "top": 226,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }, {
        "type": "rack",
        "id": "rack14",
        "top": 276,
        "left": 412,
        "width": 917,
        "height": 22,
        "minBayNo": 2,
        "maxBayNo": 31
    }],
    "rackDescs": [{
        "type": "rackDescs",
        "id": "lb_desc16",
        "text": "#1",
        "top": 663,
        "left": 1228,
        "width": 30,
        "height": 23
    }, {
        "type": "rackDescs",
        "id": "lb_desc1",
        "text": "#16",
        "top": 181,
        "left": 1217,
        "width": 41,
        "height": 23
    }],
    "crns": [{
        "type": "crane",
        "id": "crn-2",
        "text": "2",
        "top": 268,
        "left": 855,
        "id": "crn-1",
        "text": "1",
        "top": 252,
        "left": 501,
        "width": 93,
        "height": 22
    }, {
        "type": "track",
        "id": "lb_track1",
        "text": "",
        "top": 605,
        "left": 332,
        "width": 1042,
        "height": 2
    }, {
        "type": "crane",
        "id": "crn-1",
        "text": "1",
        "top": 132,
        "left": 855,
        "id": "crn-2",
        "text": "2",
        "top": 367,
        "left": 512,
        "width": 93,
        "height": 22
    }, {
        "type": "track",
        "id": "lb_track2",
        "text": "",
        "top": 278,
        "left": 769,
        "width": 850,
        "top": 489,
        "left": 332,
        "width": 1043,
        "height": 2
    }, {
        "type": "crane",
        "id": "crn-3",
        "text": "3",
        "top": 481,
        "left": 501,
        "width": 93,
        "height": 22
    }, {
        "type": "track",
        "id": "lb_track5",
        "text": "",
        "top": 376,
        "left": 333,
        "width": 1045,
        "height": 2
    }, {
        "type": "track",
        "id": "lb_track1",
        "id": "lb_track4",
        "text": "",
        "top": 143,
        "left": 769,
        "width": 850,
        "top": 260,
        "left": 335,
        "width": 1046,
        "height": 2
    }, {
        "type": "crane",
        "id": "crn-4",
        "text": "4",
        "top": 595,
        "left": 501,
        "width": 93,
        "height": 22
    }],
    "areas": [{
        "type": "Control_floor",
        "id": "tabControl_floor1",
        "text": "楼层",
        "top": 66,
        "left": 580,
        "width": 334,
        "height": 714,
        "top": 68,
        "left": 80,
        "width": 1400,
        "height": 680,
        "floors": [{
            "type": "floor",
            "id": "page_floor1",
            "text": "1F",
            "top": 4,
            "left": 422,
            "width": 308,
            "height": 706,
            "left": 22,
            "width": 1374,
            "height": 672,
            "stns": [{
                "type": "stn",
                "id": "site-100",
                "text": "100",
                "top": 99,
                "left": 771,
                "width": 62,
                "height": 23
            },{
                "id": "site-016",
                "text": "016",
                "top": 457,
                "left": 239,
                "width": 69,
                "height": 20
            }, {
                "type": "track",
                "id": "lb_trCart21",
                "text": "",
                "top": 93,
                "left": 243,
                "width": 6,
                "height": 569
            }, {
                "type": "track",
                "id": "lb_trCart22",
                "text": "",
                "top": 93,
                "left": 297,
                "width": 6,
                "height": 569
            }, {
                "type": "stn",
                "id": "site-101",
                "text": "101",
                "top": 99,
                "left": 707,
                "width": 62,
                "height": 23
            },{
                "id": "site-015",
                "text": "015",
                "top": 95,
                "left": 310,
                "width": 100,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-102",
                "text": "102",
                "top": 99,
                "left": 643,
                "width": 62,
                "height": 23
            },{
                "id": "site-014",
                "text": "014",
                "top": 95,
                "left": 412,
                "width": 92,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-103",
                "text": "103",
                "top": 99,
                "left": 579,
                "width": 62,
                "height": 23
            },{
                "id": "site-013",
                "text": "013",
                "top": 117,
                "left": 412,
                "width": 92,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-104",
                "text": "104",
                "top": 124,
                "left": 579,
                "width": 62,
                "height": 34
            },{
                "id": "site-012",
                "text": "012",
                "top": 139,
                "left": 412,
                "width": 92,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-125",
                "text": "125",
                "top": 160,
                "left": 771,
                "width": 62,
                "height": 23
            },{
                "id": "site-011",
                "text": "011",
                "top": 161,
                "left": 412,
                "width": 92,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-124",
                "text": "124",
                "top": 160,
                "left": 707,
                "width": 62,
                "height": 23
            },{
                "id": "site-010",
                "text": "010",
                "top": 183,
                "left": 412,
                "width": 92,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-123",
                "text": "123",
                "top": 160,
                "left": 643,
                "width": 62,
                "height": 23
            },{
                "id": "site-009",
                "text": "009",
                "top": 183,
                "left": 310,
                "width": 100,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-122",
                "text": "122",
                "top": 160,
                "left": 579,
                "width": 62,
                "height": 23
            },{
                "id": "site-008",
                "text": "008",
                "top": 228,
                "left": 310,
                "width": 100,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-121",
                "text": "121",
                "top": 186,
                "left": 579,
                "width": 62,
                "height": 42
            },{
                "id": "site-007",
                "text": "007",
                "top": 278,
                "left": 310,
                "width": 100,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-120",
                "text": "120",
                "top": 231,
                "left": 771,
                "width": 62,
                "height": 23
            },{
                "id": "site-006",
                "text": "006",
                "top": 344,
                "left": 310,
                "width": 100,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-119",
                "text": "119",
                "top": 231,
                "left": 707,
                "width": 62,
                "height": 23
            },{
                "id": "site-005",
                "text": "005",
                "top": 391,
                "left": 310,
                "width": 100,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-118",
                "text": "118",
                "top": 231,
                "left": 643,
                "width": 62,
                "height": 23
            },{
                "id": "site-004",
                "text": "004",
                "top": 457,
                "left": 310,
                "width": 100,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-117",
                "text": "117",
                "top": 231,
                "left": 579,
                "width": 62,
                "height": 23
            },{
                "id": "site-003",
                "text": "003",
                "top": 505,
                "left": 310,
                "width": 100,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-116",
                "text": "116",
                "top": 256,
                "left": 579,
                "width": 62,
                "height": 46
            },{
                "id": "site-002",
                "text": "002",
                "top": 571,
                "left": 310,
                "width": 100,
                "height": 20
            }, {
                "type": "stn",
                "id": "site-115",
                "text": "115",
                "top": 304,
                "left": 771,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-114",
                "text": "114",
                "top": 304,
                "left": 707,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-113",
                "text": "113",
                "top": 304,
                "left": 643,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-112",
                "text": "112",
                "top": 304,
                "left": 579,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-105",
                "text": "105",
                "top": 99,
                "left": 515,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-106",
                "text": "106",
                "top": 124,
                "left": 515,
                "width": 62,
                "height": 34
            },{
                "type": "stn",
                "id": "site-107",
                "text": "107",
                "top": 160,
                "left": 515,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-108",
                "text": "108",
                "top": 186,
                "left": 515,
                "width": 62,
                "height": 42
            },{
                "type": "stn",
                "id": "site-109",
                "text": "109",
                "top": 231,
                "left": 515,
                "width": 62,
                "height": 70
            },{
                "type": "stn",
                "id": "site-110",
                "text": "110",
                "top": 304,
                "left": 515,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-111",
                "text": "111",
                "top": 329,
                "left": 515,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-1001",
                "text": "1001",
                "top": 99,
                "left": 451,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-1002",
                "text": "1002",
                "top": 160,
                "left": 451,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-1003",
                "text": "1003",
                "top": 231,
                "left": 451,
                "width": 62,
                "height": 23
            },{
                "type": "stn",
                "id": "site-1004",
                "text": "1004",
                "top": 304,
                "left": 451,
                "width": 62,
                "height": 23
            } ]
                "id": "site-001",
                "text": "001",
                "top": 619,
                "left": 310,
                "width": 100,
                "height": 20
            }]
        }]
    }]
}
src/main/webapp/static/wms/js/common.js
@@ -1,4 +1,4 @@
var baseUrl = "/jdzwcs";
var baseUrl = "/dtwcs";
// 详情窗口-高度
var detailHeight = '80%';