#
Junjie
4 天以前 a3d44470b704e81d4f66399bed2f37529ddb31be
#
5个文件已添加
13个文件已修改
820 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/BasDualCrnpController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ConsoleController.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/DualCrnController.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/DualCrnStateTableVo.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/BasDualCrnp.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/DualCrnForkPosType.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/DualCrnLiftPosType.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/DualCrnModeType.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/DualCrnStatusType.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/DualCrnTaskModeType.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/DualCrnCommand.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/DualCrnProtocol.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/network/entity/ZyDualCrnStatusEntity.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/network/fake/ZyDualCrnFakeConnect.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/network/real/ZyDualCrnRealConnect.java 259 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/DualCrnThread.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/ZySiemensDualCrnThread.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/components/WatchDualCrnCard.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/BasDualCrnpController.java
@@ -1,6 +1,5 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
src/main/java/com/zy/asrs/controller/ConsoleController.java
@@ -20,11 +20,7 @@
import com.zy.common.CodeRes;
import com.zy.common.utils.RedisUtil;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.CrnModeType;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.RgvStatusType;
import com.zy.core.enums.SlaveType;
import com.zy.core.enums.WrkIoType;
import com.zy.core.enums.*;
import com.zy.core.model.protocol.CrnProtocol;
import com.zy.core.model.protocol.DualCrnProtocol;
import com.zy.core.model.protocol.StationProtocol;
@@ -230,9 +226,9 @@
                vo.setCrnStatus(CrnStatusType.MACHINE_ERROR);
            } else {
                if (taskNo != null && taskNo > 0) {
                    vo.setCrnStatus(p.getModeType() == CrnModeType.AUTO ? CrnStatusType.MACHINE_AUTO : CrnStatusType.MACHINE_UN_AUTO);
                    vo.setCrnStatus(p.getModeType() == DualCrnModeType.AUTO ? CrnStatusType.MACHINE_AUTO : CrnStatusType.MACHINE_UN_AUTO);
                } else {
                    vo.setCrnStatus(p.getModeType() == CrnModeType.AUTO ? CrnStatusType.MACHINE_AUTO : CrnStatusType.MACHINE_UN_AUTO);
                    vo.setCrnStatus(p.getModeType() == DualCrnModeType.AUTO ? CrnStatusType.MACHINE_AUTO : CrnStatusType.MACHINE_UN_AUTO);
                }
            }
            vos.add(vo);
src/main/java/com/zy/asrs/controller/DualCrnController.java
@@ -65,6 +65,8 @@
            vo.setLiftPosTwo(p.getLiftPosTypeTwo() == null ? "-" : p.getLiftPosTypeTwo().desc);
            vo.setWalkPos(p.getWalkPos() != null && p.getWalkPos() == 0 ? "在定位" : "不在定位");
            vo.setWalkPosTwo(p.getWalkPosTwo() != null && p.getWalkPosTwo() == 0 ? "在定位" : "不在定位");
            vo.setTaskReceive(p.getTaskReceive() != null && p.getTaskReceive() == 1 ? "接收" : "无任务");
            vo.setTaskReceiveTwo(p.getTaskReceiveTwo() != null && p.getTaskReceiveTwo() == 1 ? "接收" : "无任务");
            vo.setXspeed(p.getXSpeed());
            vo.setYspeed(p.getYSpeed());
            vo.setZspeed(p.getZSpeed());
@@ -105,6 +107,43 @@
        return R.ok();
    }
    @PostMapping("/dualcrn/command/pick")
    @ManagerAuth(memo = "双工位堆垛机取货命令")
    public R dualCrnCommandPick(@RequestBody DualCrnCommandParam param) {
        if (Cools.isEmpty(param)) {
            return R.error("缺少参数");
        }
        Integer crnNo = param.getCrnNo();
        String targetLocNo = param.getTargetLocNo();
        Integer station = param.getStation();
        DualCrnThread crnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, crnNo);
        if (crnThread == null) {
            return R.error("线程不存在");
        }
        DualCrnCommand command = crnThread.getPickCommand(targetLocNo, 9999, crnNo, station);
        MessageQueue.offer(SlaveType.DualCrn, crnNo, new Task(2, command));
        return R.ok();
    }
    @PostMapping("/dualcrn/command/put")
    @ManagerAuth(memo = "双工位堆垛机放货命令")
    public R dualCrnCommandPut(@RequestBody DualCrnCommandParam param) {
        if (Cools.isEmpty(param)) {
            return R.error("缺少参数");
        }
        Integer crnNo = param.getCrnNo();
        String targetLocNo = param.getTargetLocNo();
        Integer station = param.getStation();
        DualCrnThread crnThread = (DualCrnThread) SlaveConnection.get(SlaveType.DualCrn, crnNo);
        if (crnThread == null) {
            return R.error("线程不存在");
        }
        DualCrnCommand command = crnThread.getPutCommand(targetLocNo, 9999, crnNo, station);
        MessageQueue.offer(SlaveType.DualCrn, crnNo, new Task(2, command));
        return R.ok();
    }
    @PostMapping("/dualcrn/command/move")
    @ManagerAuth(memo = "双工位堆垛机移动命令")
    public R dualCrnCommandMove(@RequestBody DualCrnCommandParam param) {
src/main/java/com/zy/asrs/domain/vo/DualCrnStateTableVo.java
@@ -43,6 +43,10 @@
    private String walkPosTwo = "-";
    private String taskReceive = "-";
    private String taskReceiveTwo = "-";
    private Integer xspeed = 0;
    private Integer yspeed = 0;
src/main/java/com/zy/asrs/entity/BasDualCrnp.java
@@ -6,8 +6,6 @@
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
src/main/java/com/zy/core/enums/DualCrnForkPosType.java
New file
@@ -0,0 +1,43 @@
package com.zy.core.enums;
public enum DualCrnForkPosType {
    NONE(-1, "不在定位"),   // 货叉原位
    HOME(0, "货叉原位"),   // 货叉原位
    LEFT(1, "货叉在左侧"),  // 货叉在左侧
    RIGHT(2, "货叉在右侧"),   // 货叉在右侧
    _LEFT(3, "货叉在左侧远"),   // 货叉在右侧远
    _RIGHT(4, "货叉在右侧远"),   // 货叉在右侧远
    ;
    public Integer id;
    public String desc;
    DualCrnForkPosType(Integer id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static DualCrnForkPosType get(Integer id) {
        if (null == id) {
            return null;
        }
        for (DualCrnForkPosType type : DualCrnForkPosType.values()) {
            if (type.id.equals(id)) {
                return type;
            }
        }
        return null;
    }
    public static DualCrnForkPosType get(DualCrnForkPosType type) {
        if (null == type) {
            return null;
        }
        for (DualCrnForkPosType crnForkPosType : DualCrnForkPosType.values()) {
            if (crnForkPosType == type) {
                return crnForkPosType;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/DualCrnLiftPosType.java
New file
@@ -0,0 +1,44 @@
package com.zy.core.enums;
public enum DualCrnLiftPosType {
    ERROR(-1, "未知"),   // 不在定位
    NONE(0, "不在定位"),   // 不在定位
    _DOWN(1, "双深低位"),  //
    DOWN(2, "单深低位"),  //
    _UP(3, "单深高位"),   //
    UP(4, "双深高位"),   //
    ;
    public Integer id;
    public String desc;
    DualCrnLiftPosType(Integer id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static DualCrnLiftPosType get(Integer id) {
        if (null == id) {
            return null;
        }
        for (DualCrnLiftPosType type : DualCrnLiftPosType.values()) {
            if (type.id.equals(id)) {
                return type;
            }
        }
        return null;
    }
    public static DualCrnLiftPosType get(DualCrnLiftPosType type) {
        if (null == type) {
            return null;
        }
        for (DualCrnLiftPosType crnLiftPosType : DualCrnLiftPosType.values()) {
            if (crnLiftPosType == type) {
                return crnLiftPosType;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/DualCrnModeType.java
New file
@@ -0,0 +1,42 @@
package com.zy.core.enums;
public enum DualCrnModeType {
    NONE(-1, "离线"),
    STOP(0, "维修"),
    HAND(1, "手动"),
    HALF_AUTO(2, "半自动"),
    AUTO(3, "自动"),
    ;
    public Integer id;
    public String desc;
    DualCrnModeType(Integer id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static DualCrnModeType get(Integer id) {
        if (null == id) {
            return null;
        }
        for (DualCrnModeType type : DualCrnModeType.values()) {
            if (type.id.equals(id)) {
                return type;
            }
        }
        return null;
    }
    public static DualCrnModeType get(DualCrnModeType type) {
        if (null == type) {
            return null;
        }
        for (DualCrnModeType crnModeType : DualCrnModeType.values()) {
            if (crnModeType == type) {
                return crnModeType;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/DualCrnStatusType.java
New file
@@ -0,0 +1,52 @@
package com.zy.core.enums;
public enum DualCrnStatusType {
    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(90, "任务完成等待WCS确认"),
    PAUSE(11, "任务暂停"),
    SOS(99, "报警"),
    UNKNOW(100, "其他"),
    ;
    public Integer id;
    public String desc;
    DualCrnStatusType(Integer id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static DualCrnStatusType get(Integer id) {
        if (null == id) {
            return null;
        }
        for (DualCrnStatusType type : DualCrnStatusType.values()) {
            if (type.id.equals(id)) {
                return type;
            }
        }
        return NONE;
    }
    public static DualCrnStatusType get(DualCrnStatusType type) {
        if (null == type) {
            return null;
        }
        for (DualCrnStatusType crnStatusType : DualCrnStatusType.values()) {
            if (crnStatusType == type) {
                return crnStatusType;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/DualCrnTaskModeType.java
New file
@@ -0,0 +1,42 @@
package com.zy.core.enums;
public enum DualCrnTaskModeType {
    NONE(0),    // 无
    PICK(1),    // 取货
    PUT(2),    // 放货
    TRANSFER(3),    // 取放货
    MOVE(4),    // 移动
    CONFIRM(5),    // 确认
    ;
    public Integer id;
    DualCrnTaskModeType(Integer id) {
        this.id = id;
    }
    public static DualCrnTaskModeType get(Integer id) {
        if (null == id) {
            return null;
        }
        for (DualCrnTaskModeType type : DualCrnTaskModeType.values()) {
            if (type.id.equals(id)) {
                return type;
            }
        }
        return null;
    }
    public static DualCrnTaskModeType get(DualCrnTaskModeType type) {
        if (null == type) {
            return null;
        }
        for (DualCrnTaskModeType crnTaskModeType : DualCrnTaskModeType.values()) {
            if (crnTaskModeType == type) {
                return crnTaskModeType;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/model/command/DualCrnCommand.java
@@ -11,24 +11,11 @@
    // 堆垛机号
    private Integer crnNo = 0;
    // 任务完成确认位
    private Short ackFinish = 0;
    // 任务号
    private Short taskNo = 0;
    /**
     * 任务模式:
     * 0 = 无
     * 1 = 入库   源和目标都发
     * 2 = 出库   源和目标都发
     * 3 = 库位移转 源和目标都发
     * 4 = 站位移转 源和目标都发
     * 5 = 回原点  不用发
     * 6 = 去反原点 目标发
     * 7 = 坐标移行 取货发
     * 90 = 设置时间
     * 99 = 取消当前任务
     */
    private Short taskMode = 0;
src/main/java/com/zy/core/model/protocol/DualCrnProtocol.java
@@ -1,9 +1,10 @@
package com.zy.core.model.protocol;
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 com.zy.core.enums.DualCrnForkPosType;
import com.zy.core.enums.DualCrnLiftPosType;
import com.zy.core.enums.DualCrnModeType;
import com.zy.core.enums.DualCrnStatusType;
import lombok.Data;
import java.util.Map;
@@ -20,7 +21,7 @@
     */
    public Integer mode;
    public CrnModeType modeType;
    public DualCrnModeType modeType;
    /**
     * 异常码
@@ -60,12 +61,12 @@
    /**
     * 工位1状态枚举
     */
    public CrnStatusType statusType;
    public DualCrnStatusType statusType;
    /**
     * 工位2状态枚举
     */
    public CrnStatusType statusTypeTwo;
    public DualCrnStatusType statusTypeTwo;
    /**
     * 工位1堆垛机当前列号
@@ -103,9 +104,9 @@
     */
    public Integer forkPosTwo;
    public CrnForkPosType forkPosType;
    public DualCrnForkPosType forkPosType;
    public CrnForkPosType forkPosTypeTwo;
    public DualCrnForkPosType forkPosTypeTwo;
    /**
     * 当前载货台位置
@@ -116,9 +117,9 @@
    public Integer liftPosTwo;
    public CrnLiftPosType liftPosType;
    public DualCrnLiftPosType liftPosType;
    public CrnLiftPosType liftPosTypeTwo;
    public DualCrnLiftPosType liftPosTypeTwo;
    /**
     * 走行在定位
@@ -135,6 +136,15 @@
    public Integer loaded;
    public Integer loadedTwo;
    /**
     * 任务接收状态
     * 0 = 未接收
     * 1 = 已接收
     */
    public Integer taskReceive;
    public Integer taskReceiveTwo;
    private Integer temp1;
@@ -208,72 +218,72 @@
    public void setMode(Integer mode) {
        this.mode = mode;
        this.modeType = CrnModeType.get(mode);
        this.modeType = DualCrnModeType.get(mode);
    }
    public void setMode(CrnModeType type) {
    public void setMode(DualCrnModeType type) {
        this.modeType = type;
        this.mode = CrnModeType.get(type).id;
        this.mode = DualCrnModeType.get(type).id;
    }
    public void setForkPos(Integer forkPos) {
        this.forkPos = forkPos;
        this.forkPosType = CrnForkPosType.get(forkPos);
        this.forkPosType = DualCrnForkPosType.get(forkPos);
    }
    public void setForkPosTwo(Integer forkPosTwo) {
        this.forkPosTwo = forkPosTwo;
        this.forkPosTypeTwo = CrnForkPosType.get(forkPosTwo);
        this.forkPosTypeTwo = DualCrnForkPosType.get(forkPosTwo);
    }
    public void setForkPos(CrnForkPosType type) {
    public void setForkPos(DualCrnForkPosType type) {
        this.forkPosType = type;
        this.forkPos = CrnForkPosType.get(type).id;
        this.forkPos = DualCrnForkPosType.get(type).id;
    }
    public void setForkPosTwo(CrnForkPosType type) {
    public void setForkPosTwo(DualCrnForkPosType type) {
        this.forkPosTypeTwo = type;
        this.forkPosTwo = CrnForkPosType.get(type).id;
        this.forkPosTwo = DualCrnForkPosType.get(type).id;
    }
    public void setLiftPos(Integer liftPos) {
        this.liftPos = liftPos;
        this.liftPosType = CrnLiftPosType.get(liftPos);
        this.liftPosType = DualCrnLiftPosType.get(liftPos);
    }
    public void setLiftPosTwo(Integer liftPosTwo) {
        this.liftPosTwo = liftPosTwo;
        this.liftPosTypeTwo = CrnLiftPosType.get(liftPosTwo);
        this.liftPosTypeTwo = DualCrnLiftPosType.get(liftPosTwo);
    }
    public void setLiftPos(CrnLiftPosType type) {
    public void setLiftPos(DualCrnLiftPosType type) {
        this.liftPosType = type;
        this.liftPos = CrnLiftPosType.get(type).id;
        this.liftPos = DualCrnLiftPosType.get(type).id;
    }
    public void setLiftPosTwo(CrnLiftPosType type) {
    public void setLiftPosTwo(DualCrnLiftPosType type) {
        this.liftPosTypeTwo = type;
        this.liftPosTwo = CrnLiftPosType.get(type).id;
        this.liftPosTwo = DualCrnLiftPosType.get(type).id;
    }
    public void setStatus(Integer status){
        this.status = status;
        this.statusType = CrnStatusType.get(status);
        this.statusType = DualCrnStatusType.get(status);
    }
    public void setStatus(CrnStatusType type){
    public void setStatus(DualCrnStatusType type){
        this.statusType = type;
        this.status = CrnStatusType.get(type).id;
        this.status = DualCrnStatusType.get(type).id;
    }
    public void setStatusTwo(Integer statusTwo){
        this.statusTwo = statusTwo;
        this.statusTypeTwo = CrnStatusType.get(statusTwo);
        this.statusTypeTwo = DualCrnStatusType.get(statusTwo);
    }
    public void setStatusTwo(CrnStatusType type){
    public void setStatusTwo(DualCrnStatusType type){
        this.statusTypeTwo = type;
        this.statusTwo = CrnStatusType.get(type).id;
        this.statusTwo = DualCrnStatusType.get(type).id;
    }
}
src/main/java/com/zy/core/network/entity/ZyDualCrnStatusEntity.java
@@ -96,6 +96,15 @@
    public Integer loadedTwo;
    /**
     * 任务接收状态
     * 0 = 未接收
     * 1 = 已接收
     */
    public Integer taskReceive;
    public Integer taskReceiveTwo;
    /**
     * X行走线速度m/min
     */
    private Integer xSpeed;
src/main/java/com/zy/core/network/fake/ZyDualCrnFakeConnect.java
@@ -3,7 +3,7 @@
import com.alibaba.fastjson.JSON;
import com.zy.asrs.entity.DeviceConfig;
import com.zy.core.enums.CrnStatusType;
import com.zy.core.enums.CrnTaskModeType;
import com.zy.core.enums.DualCrnTaskModeType;
import com.zy.core.model.CommandResponse;
import com.zy.core.model.command.DualCrnCommand;
import com.zy.core.network.api.ZyDualCrnConnectApi;
@@ -42,13 +42,19 @@
    @Override
    public CommandResponse sendCommand(DualCrnCommand command) {
        CommandResponse response = new CommandResponse(false);
        if (command.getTaskMode().intValue() == CrnTaskModeType.LOC_MOVE.id) {
        if (command.getTaskMode().intValue() == DualCrnTaskModeType.TRANSFER.id) {
            //取放货
            executor.submit(() -> commandTake(command));
        } else if (command.getTaskMode().intValue() == CrnTaskModeType.CRN_MOVE.id) {
        } else if (command.getTaskMode().intValue() == DualCrnTaskModeType.PICK.id) {
            //取货
            executor.submit(() -> commandPick(command));
        } else if (command.getTaskMode().intValue() == DualCrnTaskModeType.PUT.id) {
            //放货
            executor.submit(() -> commandPut(command));
        } else if (command.getTaskMode().intValue() == DualCrnTaskModeType.MOVE.id) {
            //移动
            executor.submit(() -> commandMove(command));
        } else if (command.getTaskMode().intValue() == CrnTaskModeType.NONE.id) {
        } else if (command.getTaskMode().intValue() == DualCrnTaskModeType.CONFIRM.id) {
            //复位
            executor.submit(() -> commandTaskComplete(command));
        }
@@ -148,6 +154,80 @@
        }
    }
    private void commandPick(DualCrnCommand command) {
        int destinationPosX = command.getDestinationPosX().intValue();
        int destinationPosY = command.getDestinationPosY().intValue();
        int destinationPosZ = command.getDestinationPosZ().intValue();
        int taskMode = command.getTaskMode().intValue();
        int taskNo = command.getTaskNo().intValue();
        this.crnStatus.setMode(taskMode);
        if(command.getStation() == 1) {
            this.crnStatus.setTaskNo(taskNo);
            this.crnStatus.setStatus(CrnStatusType.FETCH_MOVING.id);
            moveY(this.crnStatus.getBay(), destinationPosY, command.getStation().intValue());
            moveZ(this.crnStatus.getLevel(), destinationPosZ, command.getStation().intValue());
            this.crnStatus.setStatus(CrnStatusType.FETCHING.id);
            sleep(2000);
            if (Thread.currentThread().isInterrupted()) {
                return;
            }
            this.crnStatus.setLoaded(1);
            this.crnStatus.setStatus(CrnStatusType.WAITING.id);
        }else {
            this.crnStatus.setTaskNoTwo(taskNo);
            this.crnStatus.setStatusTwo(CrnStatusType.FETCH_MOVING.id);
            moveY(this.crnStatus.getBayTwo(), destinationPosY, command.getStation().intValue());
            moveZ(this.crnStatus.getLevelTwo(), destinationPosZ, command.getStation().intValue());
            this.crnStatus.setStatusTwo(CrnStatusType.FETCHING.id);
            sleep(2000);
            if (Thread.currentThread().isInterrupted()) {
                return;
            }
            this.crnStatus.setLoadedTwo(1);
            this.crnStatus.setStatusTwo(CrnStatusType.WAITING.id);
        }
    }
    private void commandPut(DualCrnCommand command) {
        int destinationPosX = command.getDestinationPosX().intValue();
        int destinationPosY = command.getDestinationPosY().intValue();
        int destinationPosZ = command.getDestinationPosZ().intValue();
        int taskMode = command.getTaskMode().intValue();
        int taskNo = command.getTaskNo().intValue();
        this.crnStatus.setMode(taskMode);
        if(command.getStation() == 1) {
            this.crnStatus.setTaskNo(taskNo);
            this.crnStatus.setStatus(CrnStatusType.PUT_MOVING.id);
            moveY(this.crnStatus.getBay(), destinationPosY, command.getStation().intValue());
            moveZ(this.crnStatus.getLevel(), destinationPosZ, command.getStation().intValue());
            this.crnStatus.setStatus(CrnStatusType.PUTTING.id);
            sleep(2000);
            if (Thread.currentThread().isInterrupted()) {
                return;
            }
            this.crnStatus.setLoaded(0);
            this.crnStatus.setStatus(CrnStatusType.WAITING.id);
        }else {
            this.crnStatus.setTaskNoTwo(taskNo);
            this.crnStatus.setStatusTwo(CrnStatusType.PUT_MOVING.id);
            moveY(this.crnStatus.getBayTwo(), destinationPosY, command.getStation().intValue());
            moveZ(this.crnStatus.getLevelTwo(), destinationPosZ, command.getStation().intValue());
            this.crnStatus.setStatusTwo(CrnStatusType.PUTTING.id);
            sleep(2000);
            if (Thread.currentThread().isInterrupted()) {
                return;
            }
            this.crnStatus.setLoadedTwo(0);
            this.crnStatus.setStatusTwo(CrnStatusType.WAITING.id);
        }
    }
    private void moveZ(int sourcePosZ, int destinationPosZ, int station) {
        if(destinationPosZ - sourcePosZ > 0) {
            int moveLength = destinationPosZ - sourcePosZ;
src/main/java/com/zy/core/network/real/ZyDualCrnRealConnect.java
@@ -108,145 +108,144 @@
    @Override
    public CommandResponse sendCommand(DualCrnCommand command) {
        CommandResponse response = new CommandResponse(false);
        try {
            if (null == command) {
                News.error("双工位堆垛机写入命令为空");
                response.setMessage("双工位堆垛机写入命令为空");
                return response;
            }
        // try {
        //     if (null == command) {
        //         News.error("双工位堆垛机写入命令为空");
        //         response.setMessage("双工位堆垛机写入命令为空");
        //         return response;
        //     }
            String address = "DB100.0";
            if (command.getStation() == 1) {
                //工位1
                address = "DB100.0";
            }else {
                //工位2
                address = "DB100.20";
            }
        //     String address = "DB100.0";
        //     if (command.getStation() == 1) {
        //         //工位1
        //         address = "DB100.0";
        //     }else {
        //         //工位2
        //         address = "DB100.20";
        //     }
            int writeAck = 0;
            boolean ackResult = false;
            do {
                OperateResult resultAck = siemensNet.Write(address, (short) 0);
                if (resultAck.IsSuccess) {
                    Thread.sleep(200);
                    OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 2);
                    short ack = siemensNet.getByteTransform().TransInt16(resultRead.Content, 0);
                    if (ack != 0) {
                        writeAck++;
                    } else {
                        News.info("双工位堆垛机命令下发[id:{}] >>>>> {}", command.getCrnNo(), "ack复位完成");
                        ackResult = true;
                        break;
                    }
                }
            } while (writeAck < 5);
        //     int writeAck = 0;
        //     boolean ackResult = false;
        //     do {
        //         OperateResult resultAck = siemensNet.Write(address, (short) 0);
        //         if (resultAck.IsSuccess) {
        //             Thread.sleep(200);
        //             OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 2);
        //             short ack = siemensNet.getByteTransform().TransInt16(resultRead.Content, 0);
        //             if (ack != 0) {
        //                 writeAck++;
        //             } else {
        //                 News.info("双工位堆垛机命令下发[id:{}] >>>>> {}", command.getCrnNo(), "ack复位完成");
        //                 ackResult = true;
        //                 break;
        //             }
        //         }
        //     } while (writeAck < 5);
            if (!ackResult) {
                response.setMessage("双工位堆垛机命令下发[id:{}] >>>>> {}" + command.getCrnNo() + "ack复位失败");
                return response;
            }
        //     if (!ackResult) {
        //         response.setMessage("双工位堆垛机命令下发[id:{}] >>>>> {}" + command.getCrnNo() + "ack复位失败");
        //         return response;
        //     }
            short[] array = new short[10];
            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();
        //     short[] array = new short[10];
        //     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 = null;
            int idx = 0;
            do {
                OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 20);
                if (resultRead.IsSuccess) {
                    if (command.getAckFinish() == 0) {
                        short taskNo = siemensNet.getByteTransform().TransInt16(resultRead.Content, 2);
                        short taskMode = siemensNet.getByteTransform().TransInt16(resultRead.Content, 4);
                        short sourcePosX = siemensNet.getByteTransform().TransInt16(resultRead.Content, 6);
                        short sourcePosY = siemensNet.getByteTransform().TransInt16(resultRead.Content, 8);
                        short sourcePosZ = siemensNet.getByteTransform().TransInt16(resultRead.Content, 10);
                        short destinationPosX = siemensNet.getByteTransform().TransInt16(resultRead.Content, 12);
                        short destinationPosY = siemensNet.getByteTransform().TransInt16(resultRead.Content, 14);
                        short destinationPosZ = siemensNet.getByteTransform().TransInt16(resultRead.Content, 16);
                        if (taskNo == 0 || taskMode == 0 || sourcePosX == 0 || sourcePosY == 0 || sourcePosZ == 0 || destinationPosX == 0 || destinationPosY == 0 || destinationPosZ == 0) {
                            result = siemensNet.Write(address, array);
                        } else {
                            break;
                        }
                    } else {
                        short ackFinish = siemensNet.getByteTransform().TransInt16(resultRead.Content, 0);
                        if (ackFinish != command.getAckFinish()) {
                            result = siemensNet.Write(address, array);
                        } else {
                            break;
                        }
                    }
                }
                idx++;
                Thread.sleep(500);
            } while (idx < 5);
        //     OperateResult result = null;
        //     int idx = 0;
        //     do {
        //         OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 20);
        //         if (resultRead.IsSuccess) {
        //             if (command.getAckFinish() == 0) {
        //                 short taskNo = siemensNet.getByteTransform().TransInt16(resultRead.Content, 2);
        //                 short taskMode = siemensNet.getByteTransform().TransInt16(resultRead.Content, 4);
        //                 short sourcePosX = siemensNet.getByteTransform().TransInt16(resultRead.Content, 6);
        //                 short sourcePosY = siemensNet.getByteTransform().TransInt16(resultRead.Content, 8);
        //                 short sourcePosZ = siemensNet.getByteTransform().TransInt16(resultRead.Content, 10);
        //                 short destinationPosX = siemensNet.getByteTransform().TransInt16(resultRead.Content, 12);
        //                 short destinationPosY = siemensNet.getByteTransform().TransInt16(resultRead.Content, 14);
        //                 short destinationPosZ = siemensNet.getByteTransform().TransInt16(resultRead.Content, 16);
        //                 if (taskNo == 0 || taskMode == 0 || sourcePosX == 0 || sourcePosY == 0 || sourcePosZ == 0 || destinationPosX == 0 || destinationPosY == 0 || destinationPosZ == 0) {
        //                     result = siemensNet.Write(address, array);
        //                 } else {
        //                     break;
        //                 }
        //             } else {
        //                 short ackFinish = siemensNet.getByteTransform().TransInt16(resultRead.Content, 0);
        //                 if (ackFinish != command.getAckFinish()) {
        //                     result = siemensNet.Write(address, array);
        //                 } else {
        //                     break;
        //                 }
        //             }
        //         }
        //         idx++;
        //         Thread.sleep(500);
        //     } while (idx < 5);
            if (command.getAckFinish() == 0) {
                short commandFinish = 1;
                int i = 0;
                do {
                    OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 4);
                    OperateResultExOne<byte[]> resultReadConfirm = siemensNet.Read(address + 18, (short) 2);
                    if (resultRead.IsSuccess && resultReadConfirm.IsSuccess) {
                        short taskNo = siemensNet.getByteTransform().TransInt16(resultRead.Content, 2);
                        short confirm = siemensNet.getByteTransform().TransInt16(resultReadConfirm.Content, 0);
                        if (taskNo != 0 && confirm == 0) {
                            result = siemensNet.Write(address + 18, commandFinish);
                        }
                    }
                    i++;
                    Thread.sleep(500);
                } while (i < 5);
            }
        //     if (command.getAckFinish() == 0) {
        //         short commandFinish = 1;
        //         int i = 0;
        //         do {
        //             OperateResultExOne<byte[]> resultRead = siemensNet.Read(address, (short) 4);
        //             OperateResultExOne<byte[]> resultReadConfirm = siemensNet.Read(address + 18, (short) 2);
        //             if (resultRead.IsSuccess && resultReadConfirm.IsSuccess) {
        //                 short taskNo = siemensNet.getByteTransform().TransInt16(resultRead.Content, 2);
        //                 short confirm = siemensNet.getByteTransform().TransInt16(resultReadConfirm.Content, 0);
        //                 if (taskNo != 0 && confirm == 0) {
        //                     result = siemensNet.Write(address + 18, commandFinish);
        //                 }
        //             }
        //             i++;
        //             Thread.sleep(500);
        //         } while (i < 5);
        //     }
            if (result != null && result.IsSuccess) {
                News.info("SiemensDualCrn 双工位堆垛机命令下发[id:{}] >>>>> {}", command.getCrnNo(), JSON.toJSON(command));
                OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), command.getCrnNo(), JSON.toJSON(command)));
                response.setResult(true);
                response.setMessage("命令下发成功");
            } else {
                News.error("SiemensDualCrn 双工位堆垛机写入堆垛机plc数据失败 ===>> [id:{}]", command.getCrnNo());
                OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}]", DateUtils.convert(new Date()), command.getCrnNo()));
                response.setResult(false);
                response.setMessage("命令下发失败");
            }
        //     if (result != null && result.IsSuccess) {
        //         News.info("SiemensDualCrn 双工位堆垛机命令下发[id:{}] >>>>> {}", command.getCrnNo(), JSON.toJSON(command));
        //         OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), command.getCrnNo(), JSON.toJSON(command)));
        //         response.setResult(true);
        //         response.setMessage("命令下发成功");
        //     } else {
        //         News.error("SiemensDualCrn 双工位堆垛机写入堆垛机plc数据失败 ===>> [id:{}]", command.getCrnNo());
        //         OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}]", DateUtils.convert(new Date()), command.getCrnNo()));
        //         response.setResult(false);
        //         response.setMessage("命令下发失败");
        //     }
            return response;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            String sourceLocNo = Utils.getLocNo(command.getSourcePosX(), command.getSourcePosY(), command.getSourcePosZ());
            String targetLocNo = Utils.getLocNo(command.getDestinationPosX(), command.getDestinationPosY(), command.getDestinationPosZ());
        //     return response;
        // } catch (Exception e) {
        //     e.printStackTrace();
        // }finally {
        //     String sourceLocNo = Utils.getLocNo(command.getSourcePosX(), command.getSourcePosY(), command.getSourcePosZ());
        //     String targetLocNo = Utils.getLocNo(command.getDestinationPosX(), command.getDestinationPosY(), command.getDestinationPosZ());
            // 日志记录
            BasCrnpOptService bean = SpringUtils.getBean(BasCrnpOptService.class);
            BasCrnpOpt basCrnpOpt = new BasCrnpOpt(
                    command.getTaskNo().intValue(),    // 任务号
                    command.getCrnNo(),    // 堆垛机[非空]
                    new Date(),    // 下发时间
                    String.valueOf(command.getTaskMode()),    // 模式
                    sourceLocNo, //源库位
                    targetLocNo, //目标库位
                    null,    // 修改时间
                    null,    // 修改人员
                    null,    // 备注
                    JSON.toJSONString(command),    // 指令
                    JSON.toJSONString(getStatus()),    // 系统状态
                    1,    // 下发状态{0:未下发,1:已下发}
                    JSON.toJSONString(response)    // 响应
            );
            bean.insert(basCrnpOpt);
        }
        //     // 日志记录
        //     BasCrnpOptService bean = SpringUtils.getBean(BasCrnpOptService.class);
        //     BasCrnpOpt basCrnpOpt = new BasCrnpOpt(
        //             command.getTaskNo().intValue(),    // 任务号
        //             command.getCrnNo(),    // 堆垛机[非空]
        //             new Date(),    // 下发时间
        //             String.valueOf(command.getTaskMode()),    // 模式
        //             sourceLocNo, //源库位
        //             targetLocNo, //目标库位
        //             null,    // 修改时间
        //             null,    // 修改人员
        //             null,    // 备注
        //             JSON.toJSONString(command),    // 指令
        //             JSON.toJSONString(getStatus()),    // 系统状态
        //             1,    // 下发状态{0:未下发,1:已下发}
        //             JSON.toJSONString(response)    // 响应
        //     );
        //     bean.insert(basCrnpOpt);
        // }
        return response;
    }
}
src/main/java/com/zy/core/thread/DualCrnThread.java
@@ -11,6 +11,10 @@
    DualCrnCommand getPickAndPutCommand(String sourceLocNo, String targetLocNo, Integer taskNo, Integer crnNo, Integer station);//取放货
    DualCrnCommand getPickCommand(String targetLocNo, Integer taskNo, Integer crnNo, Integer station);//取货
    DualCrnCommand getPutCommand(String targetLocNo, Integer taskNo, Integer crnNo, Integer station);//放货
    DualCrnCommand getMoveCommand(String targetLocNo, Integer taskNo, Integer crnNo);//移动
    DualCrnCommand getResetCommand(Integer crnNo, Integer station);//复位
src/main/java/com/zy/core/thread/impl/ZySiemensDualCrnThread.java
@@ -15,6 +15,7 @@
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
import com.zy.core.enums.CrnTaskModeType;
import com.zy.core.enums.DualCrnTaskModeType;
import com.zy.core.enums.RedisKeyType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.CommandResponse;
@@ -168,7 +169,6 @@
            OutputQueue.DUAL_CRN.offer(MessageFormat.format("【{0}】读取双工位堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), deviceConfig.getDeviceNo(), deviceConfig.getIp(), deviceConfig.getPort()));
            return;
        }
        crnProtocol.setMode(crnStatus.getMode());
        //工位1
@@ -180,6 +180,7 @@
        crnProtocol.setLoaded(crnStatus.getLoaded());
        crnProtocol.setWalkPos(crnStatus.getWalkPos());
        crnProtocol.setLiftPos(crnStatus.getLiftPos());
        crnProtocol.setTaskReceive(crnStatus.getTaskReceive());
        //工位2
        crnProtocol.setTaskNoTwo(crnStatus.getTaskNoTwo());
@@ -190,6 +191,7 @@
        crnProtocol.setLoadedTwo(crnStatus.getLoadedTwo());
        crnProtocol.setWalkPosTwo(crnStatus.getWalkPosTwo());
        crnProtocol.setLiftPosTwo(crnStatus.getLiftPosTwo());
        crnProtocol.setTaskReceiveTwo(crnStatus.getTaskReceiveTwo());
        crnProtocol.setAlarm(crnStatus.getAlarm());
        crnProtocol.setTemp1(crnStatus.getTemp1());
@@ -276,10 +278,38 @@
        DualCrnCommand crnCommand = new DualCrnCommand();
        crnCommand.setCrnNo(crnNo); // 堆垛机编号
        crnCommand.setTaskNo(taskNo.shortValue()); // 工作号
        crnCommand.setTaskMode(CrnTaskModeType.LOC_MOVE.id.shortValue()); // 任务模式:  库位移转
        crnCommand.setTaskMode(DualCrnTaskModeType.TRANSFER.id.shortValue()); // 任务模式:  取放货
        crnCommand.setSourcePosX((short) Utils.getRow(sourceLocNo));     // 源库位排
        crnCommand.setSourcePosY((short) Utils.getBay(sourceLocNo));     // 源库位列
        crnCommand.setSourcePosZ((short) Utils.getLev(sourceLocNo));     // 源库位层
        crnCommand.setDestinationPosX((short) Utils.getRow(targetLocNo));     // 目标库位排
        crnCommand.setDestinationPosY((short) Utils.getBay(targetLocNo));     // 目标库位列
        crnCommand.setDestinationPosZ((short) Utils.getLev(targetLocNo));     // 目标库位层
        crnCommand.setStation(station.shortValue());//工位
        crnCommand.setCommand((short) 1);     // 任务确认
        return crnCommand;
    }
    @Override
    public DualCrnCommand getPickCommand(String targetLocNo, Integer taskNo, Integer crnNo, Integer station) {
        DualCrnCommand crnCommand = new DualCrnCommand();
        crnCommand.setCrnNo(crnNo); // 堆垛机编号
        crnCommand.setTaskNo(taskNo.shortValue()); // 工作号
        crnCommand.setTaskMode(DualCrnTaskModeType.PICK.id.shortValue()); // 任务模式:  取货
        crnCommand.setDestinationPosX((short) Utils.getRow(targetLocNo));     // 目标库位排
        crnCommand.setDestinationPosY((short) Utils.getBay(targetLocNo));     // 目标库位列
        crnCommand.setDestinationPosZ((short) Utils.getLev(targetLocNo));     // 目标库位层
        crnCommand.setStation(station.shortValue());//工位
        crnCommand.setCommand((short) 1);     // 任务确认
        return crnCommand;
    }
    @Override
    public DualCrnCommand getPutCommand(String targetLocNo, Integer taskNo, Integer crnNo, Integer station) {
        DualCrnCommand crnCommand = new DualCrnCommand();
        crnCommand.setCrnNo(crnNo); // 堆垛机编号
        crnCommand.setTaskNo(taskNo.shortValue()); // 工作号
        crnCommand.setTaskMode(DualCrnTaskModeType.PUT.id.shortValue()); // 任务模式:  放货
        crnCommand.setDestinationPosX((short) Utils.getRow(targetLocNo));     // 目标库位排
        crnCommand.setDestinationPosY((short) Utils.getBay(targetLocNo));     // 目标库位列
        crnCommand.setDestinationPosZ((short) Utils.getLev(targetLocNo));     // 目标库位层
@@ -293,8 +323,7 @@
        DualCrnCommand crnCommand = new DualCrnCommand();
        crnCommand.setCrnNo(crnNo); // 堆垛机编号
        crnCommand.setTaskNo(taskNo.shortValue()); // 工作号
        crnCommand.setAckFinish((short) 0);  // 任务完成确认位
        crnCommand.setTaskMode(CrnTaskModeType.CRN_MOVE.id.shortValue()); // 任务模式:  堆垛机移动
        crnCommand.setTaskMode(DualCrnTaskModeType.MOVE.id.shortValue()); // 任务模式:  堆垛机移动
        crnCommand.setDestinationPosX((short) Utils.getRow(targetLocNo));     // 目标库位排
        crnCommand.setDestinationPosY((short) Utils.getBay(targetLocNo));     // 目标库位列
        crnCommand.setDestinationPosZ((short) Utils.getLev(targetLocNo));     // 目标库位层
@@ -307,8 +336,7 @@
        DualCrnCommand crnCommand = new DualCrnCommand();
        crnCommand.setCrnNo(crnNo); // 堆垛机编号
        crnCommand.setTaskNo((short) 0); // 工作号
        crnCommand.setAckFinish((short) 1);  // 任务完成确认位
        crnCommand.setTaskMode(CrnTaskModeType.NONE.id.shortValue()); // 任务模式
        crnCommand.setTaskMode(DualCrnTaskModeType.CONFIRM.id.shortValue()); // 任务模式:  确认
        crnCommand.setSourcePosX((short)0);     // 源库位排
        crnCommand.setSourcePosY((short)0);     // 源库位列
        crnCommand.setSourcePosZ((short)0);     // 源库位层
src/main/webapp/components/WatchDualCrnCard.js
@@ -24,6 +24,8 @@
              </el-select>
            </div>
            <div style="margin-bottom: 10px;"><el-button @click="controlCommandTransport()" size="mini">取放货</el-button></div>
            <div style="margin-bottom: 10px;"><el-button @click="controlCommandPickup()" size="mini">取货</el-button></div>
            <div style="margin-bottom: 10px;"><el-button @click="controlCommandPutdown()" size="mini">放货</el-button></div>
            <div style="margin-bottom: 10px;"><el-button @click="controlCommandMove()" size="mini">移动</el-button></div>
            <div style="margin-bottom: 10px;"><el-button @click="controlCommandTaskComplete()" size="mini">任务完成</el-button></div>
          </div>
@@ -61,6 +63,8 @@
                <el-descriptions-item label="工位2载货台定位">{{ item.liftPosTwo }}</el-descriptions-item>
                <el-descriptions-item label="工位1走行在定位">{{ item.walkPos }}</el-descriptions-item>
                <el-descriptions-item label="工位2走行在定位">{{ item.walkPosTwo }}</el-descriptions-item>
                <el-descriptions-item label="工位1任务接收">{{ item.taskReceive }}</el-descriptions-item>
                <el-descriptions-item label="工位2任务接收">{{ item.taskReceiveTwo }}</el-descriptions-item>
                <el-descriptions-item label="走行速度(m/min)">{{ item.xspeed }}</el-descriptions-item>
                <el-descriptions-item label="升降速度(m/min)">{{ item.yspeed }}</el-descriptions-item>
                <el-descriptions-item label="叉牙速度(m/min)">{{ item.zspeed }}</el-descriptions-item>
@@ -173,6 +177,56 @@
        },
      });
    },
    controlCommandPickup() {
      let that = this;
      $.ajax({
        url: baseUrl + "/dualcrn/command/pick",
        headers: {
          token: localStorage.getItem("token"),
        },
        contentType: "application/json",
        method: "post",
        data: JSON.stringify(that.controlParam),
        success: (res) => {
          if (res.code == 200) {
            that.$message({
              message: res.msg,
              type: "success",
            });
          } else {
            that.$message({
              message: res.msg,
              type: "warning",
            });
          }
        },
      });
    },
    controlCommandPutdown() {
      let that = this;
      $.ajax({
        url: baseUrl + "/dualcrn/command/put",
        headers: {
          token: localStorage.getItem("token"),
        },
        contentType: "application/json",
        method: "post",
        data: JSON.stringify(that.controlParam),
        success: (res) => {
          if (res.code == 200) {
            that.$message({
              message: res.msg,
              type: "success",
            });
          } else {
            that.$message({
              message: res.msg,
              type: "warning",
            });
          }
        },
      });
    },
    controlCommandMove() {
      let that = this;
      $.ajax({