Junjie
2023-03-24 a2c563572181cf54946020db619b6867f11f088a
四向穿梭车
9个文件已修改
22个文件已添加
3014 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/ShuttleController.java 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/param/ShuttleOperatorParam.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/ShuttleDataVo.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/ShuttleMsgTableVo.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/ShuttleSensorDataVo.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/ShuttleStateTableVo.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/BasShuttle.java 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/BasShuttleMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/BasShuttleService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/BasShuttleServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/MainProcess.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/ServerBootstrap.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/MessageQueue.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/OutputQueue.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/ShuttleErrorCodeType.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/ShuttlePlcInputStatusType.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/ShuttlePlcOutputStatusType.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/ShuttleStatusType.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/ShuttleTaskModeType.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/SlaveType.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/ShuttleSlave.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/ShuttleCommand.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/properties/SlaveProperties.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/ShuttleThread.java 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/BasShuttleMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/css/shuttle.css 334 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/map.json 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/index.html 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/shuttle.html 786 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ShuttleController.java
New file
@@ -0,0 +1,294 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.annotations.ManagerAuth;
import com.core.common.BaseRes;
import com.core.common.Cools;
import com.core.common.R;
import com.core.exception.CoolException;
import com.zy.asrs.domain.enums.CrnStatusType;
import com.zy.asrs.domain.param.ShuttleOperatorParam;
import com.zy.asrs.domain.param.SteModeParam;
import com.zy.asrs.domain.param.SteOperatorParam;
import com.zy.asrs.domain.vo.*;
import com.zy.asrs.entity.BasShuttle;
import com.zy.asrs.entity.BasSte;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasShuttleService;
import com.zy.asrs.service.WrkMastService;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.*;
import com.zy.core.model.ShuttleSlave;
import com.zy.core.model.SteSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.command.SteCommand;
import com.zy.core.model.protocol.ShuttleProtocol;
import com.zy.core.model.protocol.SteProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.properties.SystemProperties;
import com.zy.core.thread.ShuttleThread;
import com.zy.core.thread.SteThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * 四向穿梭车接口
 */
@Slf4j
@RestController
@RequestMapping("/shuttle")
public class ShuttleController {
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private BasShuttleService basShuttleService;
    @Autowired
    private WrkMastService wrkMastService;
    @PostMapping("/table/shuttle/state")
    @ManagerAuth(memo = "四向穿梭车信息表")
    public R steStateTable(){
        List<ShuttleStateTableVo> list = new ArrayList<>();
        List<BasShuttle> shuttles = basShuttleService.selectList(new EntityWrapper<BasShuttle>().orderBy("shuttle_no"));
        for (BasShuttle basShuttle : shuttles) {
            // 表格行
            ShuttleStateTableVo vo = new ShuttleStateTableVo();
            vo.setShuttleNo(basShuttle.getShuttleNo());   //四向穿梭车号
            list.add(vo);
            // 获取四向穿梭车信息
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, basShuttle.getShuttleNo());
            if (shuttleThread == null) {
                continue;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
            if (shuttleProtocol == null) {
                continue;
            }
            vo.setTaskNo(shuttleProtocol.getTaskNo().intValue());  //  任务号
            if (!Cools.isEmpty(shuttleProtocol.getBusyStatus())) {
                vo.setStatus(shuttleProtocol.getBusyStatusType().desc); //  状态
            }
            vo.setRow(shuttleProtocol.getRow());
            vo.setBay(shuttleProtocol.getBay());
            vo.setLev(shuttleProtocol.getLev());
            vo.setBatteryPower(shuttleProtocol.getBatteryPower() + "%");
            vo.setSpeed(shuttleProtocol.getCurrentMoveServoSpeed());
            if (!Cools.isEmpty(shuttleProtocol.getErrorCode())) {
                vo.setAlarm1(String.valueOf(shuttleProtocol.getErrorCode()));
            }
            if (!Cools.isEmpty(shuttleProtocol.getStatusErrorCode())) {
                vo.setAlarm2(String.valueOf(shuttleProtocol.getStatusErrorCode()));
            }
        }
        return R.ok().add(list);
    }
    @PostMapping("/table/shuttle/msg")
    @ManagerAuth(memo = "四向穿梭车数据表")
    public R steMsgTable(){
        List<ShuttleMsgTableVo> list = new ArrayList<>();
        List<BasShuttle> shuttles = basShuttleService.selectList(new EntityWrapper<BasShuttle>().orderBy("shuttle_no"));
        for (BasShuttle basShuttle : shuttles) {
            // 表格行
            ShuttleMsgTableVo vo = new ShuttleMsgTableVo();
            vo.setShuttleNo(basShuttle.getShuttleNo());   //  四向穿梭车号
            list.add(vo);
            // 获取穿梭车信息
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, basShuttle.getShuttleNo());
            if (shuttleThread == null) {
                continue;
            }
            ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
            if (shuttleProtocol == null) {
                continue;
            }
            vo.setWorkNo(shuttleProtocol.getTaskNo().intValue());  //  任务号
            if (shuttleProtocol.getTaskNo() > 0) {
                WrkMast wrkMast = wrkMastService.selectById(shuttleProtocol.getTaskNo());
                if (wrkMast != null) {
                    //vo.setStatus(CrnStatusType.process(wrkMast.getIoType()).getDesc());   //  模式状态
                    vo.setSourceStaNo(wrkMast.getSourceStaNo$());    //  源站
                    vo.setStaNo(wrkMast.getStaNo$());   //  目标站
                    vo.setSourceLocNo(wrkMast.getSourceLocNo());    //  源库位
                    vo.setLocNo(wrkMast.getLocNo());    //  目标库位
                }
            }
            vo.setSpeed(shuttleProtocol.getCurrentMoveServoSpeed());  // 速度
            vo.setPakMk(shuttleProtocol.getPakMk());    // 作业标记
        }
        return R.ok().add(list);
    }
    @PostMapping("/output/shuttle")
    @ManagerAuth
    public R steOutput(){
        StringBuilder str = new StringBuilder();
        String s;
        int i = 0;
        while((s = OutputQueue.SHUTTLE.poll()) != null && i <=10) {
            str.append("\n").append(s);
            i++;
        }
        return R.ok().add(str.toString());
    }
    @GetMapping("/detl/{shuttleNo}")
    public R steDetl(@PathVariable("shuttleNo") Integer shuttleNo){
        ShuttleDataVo vo = new ShuttleDataVo();
        for (ShuttleSlave shuttleSlave : slaveProperties.getShuttle()) {
            if (shuttleNo.equals(shuttleSlave.getId())) {
                vo.setShuttleNo(shuttleSlave.getId());
                BasShuttle basShuttle = basShuttleService.selectById(shuttleSlave.getId());
                if (!Cools.isEmpty(basShuttle)) {
                    vo.setRow(basShuttle.getRow());
                    vo.setBay(basShuttle.getBay());
                    vo.setLev(basShuttle.getLev());
                    vo.setWorkNo(basShuttle.getWrkNo());
                    vo.setPakMk(basShuttle.getPakMk());
                }
                break;
            }
        }
        return R.ok().add(vo);
    }
    @GetMapping("/sensor/detl/{shuttleNo}")
    public R shuttleSensorDetl(@PathVariable("shuttleNo") Integer shuttleNo){
        ShuttleSensorDataVo vo = new ShuttleSensorDataVo();
        for (ShuttleSlave shuttleSlave : slaveProperties.getShuttle()) {
            if (shuttleNo.equals(shuttleSlave.getId())) {
                vo.setShuttleNo(shuttleSlave.getId());
                // 获取穿梭车信息
                ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleSlave.getId());
                if (shuttleThread == null) {
                    return R.error("设备不在线");
                }
                ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
                if (shuttleProtocol == null) {
                    return R.error("设备不在线");
                }
                // 穿梭车异常 -----------
                // 穿梭车提示信息 ----------------------
                // 任务信息 ----------------
                vo.setPakInTask(shuttleProtocol.isPakInTask());
                vo.setPakOutTask(shuttleProtocol.isPakOutTask());
                vo.setPakMoveTask(shuttleProtocol.isPakMoveTask());
                vo.setGoHpTask(shuttleProtocol.isGoHpTask());
                vo.setGoOHpTask(shuttleProtocol.isGoOHpTask());
                vo.setGoHpAvoid(shuttleProtocol.isGoHpAvoid());
                vo.setGoOHpAvoid(shuttleProtocol.isGoOHpAvoid());
                vo.setPakInEmpty(shuttleProtocol.isPakInEmpty());
                vo.setPakInFinish(shuttleProtocol.isPakInFinish());
                vo.setPakOutEmpty(shuttleProtocol.isPakOutEmpty());
                vo.setPakOutFinish(shuttleProtocol.isPakOutFinish());
                vo.setGoHpAvoidFinish(shuttleProtocol.isGoHpAvoidFinish());
                vo.setGoOHpAvoidFinish(shuttleProtocol.isGoOHpAvoidFinish());
                vo.setGoHpAvoidErr(shuttleProtocol.isGoHpAvoidErr());
                vo.setGoOHpAvoidErr(shuttleProtocol.isGoOHpAvoidErr());
                // 状态信息 -------------
                break;
            }
        }
        return R.ok().add(vo);
    }
    @PostMapping("/detl/update")
    @ManagerAuth
    public R steUpdate(ShuttleDataVo vo){
        BasShuttle basShuttle = basShuttleService.selectById(vo.getShuttleNo());
        if (basShuttle == null) {
            return R.error();
        }
        // 获取四向穿梭车信息
        ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, vo.getShuttleNo());
        ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
        if (shuttleProtocol == null) {
            throw new CoolException(vo.getShuttleNo() + "号四向穿梭车不在线,无法保存");
        }
//        if (!Cools.isEmpty(vo.getRow(), vo.getBay(), vo.getLev())) {
//            if (!shuttleThread.modifyPosHandle(vo.getRow(), vo.getBay(), vo.getLev())) {
//                throw new CoolException("服务器错误");
//            }
//        }
        ShuttleCommand shuttleCommand = new ShuttleCommand();
        shuttleCommand.setTaskNo(vo.getWorkNo());
        if (MessageQueue.offer(SlaveType.Shuttle, vo.getShuttleNo(), new Task(2, shuttleCommand))) {
        } else {
            throw new CoolException("命令下发失败");
        }
        basShuttle.setRow(vo.getRow());
        basShuttle.setBay(vo.getBay());
        basShuttle.setLev(vo.getLev());
        basShuttle.setPakMk(vo.getPakMk());
        basShuttle.setWrkNo(vo.getWorkNo());
        basShuttle.setUpdateTime(new Date());
        if (!basShuttleService.updateById(basShuttle)) {
            throw new CoolException("修改失败");
        }
        return R.ok();
    }
    /****************************************************************/
    /************************** 手动操作 ******************************/
    /****************************************************************/
    @ManagerAuth(memo = "手动操作")
    @PostMapping("/operator/shuttle")
    public R shuttleOperator(ShuttleOperatorParam param){
        if (Cools.isEmpty(param.getShuttleNo(), param.getShuttleTaskMode())) {
            return R.parse(BaseRes.PARAM);
        }
        for (ShuttleSlave shuttleSlave : slaveProperties.getShuttle()) {
            if (param.getShuttleNo().equals(shuttleSlave.getId())) {
                ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttleSlave.getId());
                if (shuttleThread == null) {
                    throw new CoolException("四向穿梭车不在线");
                }
                ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
                if (shuttleProtocol == null) {
                    throw new CoolException("四向穿梭车不在线");
                }
                ShuttleTaskModeType shuttleTaskModeType = ShuttleTaskModeType.get(param.getShuttleTaskMode());
                ShuttleCommand shuttleCommand = new ShuttleCommand();
                shuttleCommand.setShuttleNo(shuttleSlave.getId()); // 四向穿梭车编号
//                if (param.getShuttleTaskMode() == 16) {
//                    steCommand.setComplete(true);
//                } else if (param.getSteTaskMode() == 99) {
//                    steCommand.setControlMode((short) 1);
//                } else if (param.getSteTaskMode() == 100) {
//                    steCommand.setControlMode((short) 0);
//                } else {
//                    if (steTaskModeType == null) {
//                        throw new CoolException("任务类型错误");
//                    }
//                    steCommand.setTaskNo(param.getTaskNo()); // 工作号
//                    steCommand.setTaskMode(steTaskModeType);
//                }
                if (MessageQueue.offer(SlaveType.Shuttle, shuttleSlave.getId(), new Task(2, shuttleCommand))) {
                    return R.ok();
                } else {
                    throw new CoolException("命令下发失败");
                }
            }
        }
        return R.error();
    }
}
src/main/java/com/zy/asrs/domain/param/ShuttleOperatorParam.java
New file
@@ -0,0 +1,26 @@
package com.zy.asrs.domain.param;
import lombok.Data;
@Data
public class ShuttleOperatorParam {
    // 四向穿梭车号
    private Integer shuttleNo;
    // 命令类型
    private Short shuttleTaskMode;
    // 任务号
    private Integer taskNo = 0;
    // 目标库位-排
    private Short row;
    // 目标库位-列
    private Short bay;
    // 目标库位-层
    private Short lev;
}
src/main/java/com/zy/asrs/domain/vo/ShuttleDataVo.java
New file
@@ -0,0 +1,22 @@
package com.zy.asrs.domain.vo;
import lombok.Data;
@Data
public class ShuttleDataVo {
    // 四向穿梭车号
    private Integer shuttleNo;
    // 工作号
    private Integer workNo;
    private Integer row;
    private Integer bay;
    private Integer lev;
    private String pakMk;
}
src/main/java/com/zy/asrs/domain/vo/ShuttleMsgTableVo.java
New file
@@ -0,0 +1,44 @@
package com.zy.asrs.domain.vo;
import lombok.Data;
@Data
public class ShuttleMsgTableVo {
    // 四向穿梭车号
    private Integer shuttleNo;
    // 工作号
    private Integer workNo = 0;
    // 状态
    private String status = "-";
    // 源站
    private String sourceStaNo = "-";
    // 目标站
    private String staNo = "-";
    // 源库位
    private String sourceLocNo = "-";
    // 目标库位
    private String locNo = "-";
    // 异常
    private String error = "";
    // 原点
    private String origin = "";
    // 命令
    private String command = "";
    // 速度
    private Double speed = 0.0D;
    // 作业标记
    private String pakMk = "-";
}
src/main/java/com/zy/asrs/domain/vo/ShuttleSensorDataVo.java
New file
@@ -0,0 +1,90 @@
package com.zy.asrs.domain.vo;
import lombok.Data;
@Data
public class ShuttleSensorDataVo {
    /**
     * 四向穿梭车号
     */
    private Integer shuttleNo;
    // 任务信息 ---------------------------------------------------------
    /**
     * 96.入库任务中
     */
    private boolean pakInTask;
    /**
     * 97. 出库任务中
     */
    private boolean pakOutTask;
    /**
     * 98. 移库任务中
     */
    private boolean pakMoveTask;
    /**
     * 99. 回原点任务中
     */
    private boolean goHpTask;
    /**
     * 100. 去反原点任务中
     */
    private boolean goOHpTask;
    /**
     * 101. 去原点避让位
     */
    private boolean goHpAvoid;
    /**
     * 102. 去反原点避让位
     */
    private boolean goOHpAvoid;
    /**
     * 104. 入库取空结束
     */
    private boolean pakInEmpty;
    /**
     * 105. 入库正常结束
     */
    private boolean pakInFinish;
    /**
     * 106. 出库取空结束
     */
    private boolean pakOutEmpty;
    /**
     * 107. 出库正常结束
     */
    private boolean pakOutFinish;
    /**
     * 108. 去原点避让完成
     */
    private boolean goHpAvoidFinish;
    /**
     * 109. 去反原点避让完成
     */
    private boolean goOHpAvoidFinish;
    /**
     * 110. 去原点避让完成
     */
    private boolean goHpAvoidErr;
    /**
     * 111. 去反原点避让完成
     */
    private boolean goOHpAvoidErr;
}
src/main/java/com/zy/asrs/domain/vo/ShuttleStateTableVo.java
New file
@@ -0,0 +1,63 @@
package com.zy.asrs.domain.vo;
import lombok.Data;
@Data
public class ShuttleStateTableVo {
    // 四向穿梭车号
    private Integer shuttleNo;
    // 状态
    private String status = "-";
    // 有物
    private String loading = "-";
    /**
     * 任务号
     */
    public Integer taskNo;
    // 正在执行任务
    private String execute;
    // 任务完成,等待WCS确认
    private String waiting;
    // 排
    private Short row;
    // 列
    private Short bay;
    // 层
    private Short lev;
    // 异常码1
    private String alarm1 = "-";
    // 异常码2
    private String alarm2 = "-";
    /**
     * 电池电量
     */
    public String batteryPower = "-";
    /**
     * 当前速度
     */
    public Double speed;
    /**
     * 充电状态
     */
    public String chargeStatus = "-";
    /**
     * 当前位置
     */
    public String loca = "-";
}
src/main/java/com/zy/asrs/entity/BasShuttle.java
New file
@@ -0,0 +1,258 @@
package com.zy.asrs.entity;
import com.core.common.Cools;import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.enums.IdType;
import com.baomidou.mybatisplus.annotations.TableField;
import com.core.common.SpringUtils;
import com.zy.system.service.UserService;
import com.zy.system.entity.User;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import com.core.common.SpringUtils;
import com.zy.system.service.UserService;
import com.zy.system.entity.User;
import java.text.SimpleDateFormat;
import java.util.Date;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import com.baomidou.mybatisplus.annotations.TableName;
import java.io.Serializable;
@Data
@TableName("asr_bas_shuttle")
public class BasShuttle implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 四向穿梭车号
     */
    @ApiModelProperty(value= "四向穿梭车号")
    @TableId(value = "shuttle_no", type = IdType.INPUT)
    @TableField("shuttle_no")
    private Integer shuttleNo;
    /**
     * 状态 1: 正常  0: 禁用
     */
    @ApiModelProperty(value= "状态 1: 正常  0: 禁用  ")
    private Integer status;
    /**
     * 作业态
     */
    @ApiModelProperty(value= "作业态")
    @TableField("shuttle_status")
    private Integer shuttleStatus;
    /**
     * 任务号
     */
    @ApiModelProperty(value= "任务号")
    @TableField("wrk_no")
    private Integer wrkNo;
    /**
     * 排
     */
    @ApiModelProperty(value= "排")
    private Integer row;
    /**
     * 列
     */
    @ApiModelProperty(value= "列")
    private Integer bay;
    /**
     * 层
     */
    @ApiModelProperty(value= "层")
    private Integer lev;
    /**
     * 历史排
     */
    @ApiModelProperty(value= "历史排")
    @TableField("his_row")
    private Integer hisRow;
    /**
     * 历史列
     */
    @ApiModelProperty(value= "历史列")
    @TableField("his_bay")
    private Integer hisBay;
    /**
     * 历史层
     */
    @ApiModelProperty(value= "历史层")
    @TableField("his_lev")
    private Integer hisLev;
    /**
     * 暂存库位
     */
    @ApiModelProperty(value= "暂存库位")
    @TableField("idle_loc")
    private String idleLoc;
    /**
     * 自动充电
     */
    @ApiModelProperty(value= "自动充电")
    @TableField("auto_charge")
    private Integer autoCharge;
    /**
     * 电量线
     */
    @ApiModelProperty(value= "电量线")
    @TableField("charge_line")
    private Integer chargeLine;
    /**
     * 添加人员
     */
    @ApiModelProperty(value= "添加人员")
    @TableField("create_by")
    private Long createBy;
    /**
     * 添加时间
     */
    @ApiModelProperty(value= "添加时间")
    @TableField("create_time")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    /**
     * 修改人员
     */
    @ApiModelProperty(value= "修改人员")
    @TableField("update_by")
    private Long updateBy;
    /**
     * 修改时间
     */
    @ApiModelProperty(value= "修改时间")
    @TableField("update_time")
    @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
    /**
     * 备注
     */
    @ApiModelProperty(value= "备注")
    private String memo;
    /**
     * 提升机号
     */
    @ApiModelProperty(value= "提升机号")
    @TableField("lift_no")
    private Integer liftNo;
    /**
     * 标记
     */
    @ApiModelProperty(value= "标记")
    @TableField("pak_mk")
    private String pakMk;
    public BasShuttle() {}
    public BasShuttle(Integer shuttleNo,Integer status,Integer shuttleStatus,Integer wrkNo,Integer row,Integer bay,Integer lev,Integer hisRow,Integer hisBay,Integer hisLev,String idleLoc,Integer autoCharge,Integer chargeLine,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo,Integer liftNo) {
        this.shuttleNo = shuttleNo;
        this.status = status;
        this.shuttleStatus = shuttleStatus;
        this.wrkNo = wrkNo;
        this.row = row;
        this.bay = bay;
        this.lev = lev;
        this.hisRow = hisRow;
        this.hisBay = hisBay;
        this.hisLev = hisLev;
        this.idleLoc = idleLoc;
        this.autoCharge = autoCharge;
        this.chargeLine = chargeLine;
        this.createBy = createBy;
        this.createTime = createTime;
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
        this.liftNo = liftNo;
    }
//    BasShuttle basShuttle = new BasShuttle(
//            null,    // 四向穿梭车号[非空]
//            null,    // 状态
//            null,    // 作业态
//            null,    // 任务号
//            null,    // 排
//            null,    // 列
//            null,    // 层
//            null,    // 历史排
//            null,    // 历史列
//            null,    // 历史层
//            null,    // 暂存库位
//            null,    // 自动充电
//            null,    // 电量线
//            null,    // 添加人员
//            null,    // 添加时间
//            null,    // 修改人员
//            null,    // 修改时间
//            null,    // 备注
//            null    // 提升机号
//    );
    public String getStatus$(){
        if (null == this.status){ return null; }
        switch (this.status){
            case 1:
                return "正常";
            case 0:
                return "禁用";
            default:
                return String.valueOf(this.status);
        }
    }
    public String getCreateBy$(){
        UserService service = SpringUtils.getBean(UserService.class);
        User user = service.selectById(this.createBy);
        if (!Cools.isEmpty(user)){
            return String.valueOf(user.getUsername());
        }
        return null;
    }
    public String getCreateTime$(){
        if (Cools.isEmpty(this.createTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.createTime);
    }
    public String getUpdateBy$(){
        UserService service = SpringUtils.getBean(UserService.class);
        User user = service.selectById(this.updateBy);
        if (!Cools.isEmpty(user)){
            return String.valueOf(user.getUsername());
        }
        return null;
    }
    public String getUpdateTime$(){
        if (Cools.isEmpty(this.updateTime)){
            return "";
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
}
src/main/java/com/zy/asrs/mapper/BasShuttleMapper.java
New file
@@ -0,0 +1,12 @@
package com.zy.asrs.mapper;
import com.zy.asrs.entity.BasShuttle;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@Mapper
@Repository
public interface BasShuttleMapper extends BaseMapper<BasShuttle> {
}
src/main/java/com/zy/asrs/service/BasShuttleService.java
New file
@@ -0,0 +1,8 @@
package com.zy.asrs.service;
import com.zy.asrs.entity.BasShuttle;
import com.baomidou.mybatisplus.service.IService;
public interface BasShuttleService extends IService<BasShuttle> {
}
src/main/java/com/zy/asrs/service/impl/BasShuttleServiceImpl.java
New file
@@ -0,0 +1,12 @@
package com.zy.asrs.service.impl;
import com.zy.asrs.mapper.BasShuttleMapper;
import com.zy.asrs.entity.BasShuttle;
import com.zy.asrs.service.BasShuttleService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service("basShuttleService")
public class BasShuttleServiceImpl extends ServiceImpl<BasShuttleMapper, BasShuttle> implements BasShuttleService {
}
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -30,13 +30,11 @@
import com.zy.core.model.command.LedCommand;
import com.zy.core.model.command.SteCommand;
import com.zy.core.model.protocol.CrnProtocol;
import com.zy.core.model.protocol.ShuttleProtocol;
import com.zy.core.model.protocol.StaProtocol;
import com.zy.core.model.protocol.SteProtocol;
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.core.thread.SteThread;
import com.zy.core.thread.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -612,6 +610,27 @@
    }
    /**
     * 入出库  ===>>  四向穿梭车入出库作业下发
     */
    public synchronized void shuttleIoExecute() {
        for (ShuttleSlave shuttle : slaveProperties.getShuttle()) {
            //获取四向穿梭车信息
            ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, shuttle.getId());
            ShuttleProtocol shuttleProtocol = shuttleThread.getShuttleProtocol();
            if (shuttleProtocol == null) {
                continue;
            }
            // 只有当四向穿梭车空闲 并且无任务时才继续执行
            if (shuttleProtocol.getBusyStatusType() == ShuttleStatusType.IDLE && shuttleProtocol.getTaskNo() == 0) {
                //入出库逻辑
                //.....
            }
        }
    }
    /**
     * 入出库  ===>>  堆垛机入出库作业下发
     */
    public synchronized void crnIoExecute(){
src/main/java/com/zy/core/MainProcess.java
@@ -57,6 +57,8 @@
                    mainService.crnStnToOutStn();
                    // 入出库  ===>>  堆垛机入出库作业下发
                    mainService.crnIoExecute();
                    // 入出库  ===>>  四向穿梭车入出库作业下发
                    mainService.shuttleIoExecute();
                    // 入库  ===>> 执行堆垛机对工作档的完成操作
                    mainService.storeFinished();
                    // 入库 ===>> 执行穿梭车对工作档的完成操作
src/main/java/com/zy/core/ServerBootstrap.java
@@ -3,10 +3,7 @@
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.CrnSlave;
import com.zy.core.model.DevpSlave;
import com.zy.core.model.LedSlave;
import com.zy.core.model.SteSlave;
import com.zy.core.model.*;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.*;
import lombok.extern.slf4j.Slf4j;
@@ -73,6 +70,10 @@
        for (Slave ste : slaveProperties.getSte()) {
            MessageQueue.init(SlaveType.Ste, ste);
        }
        // 初始化四向穿梭车mq
        for (Slave shuttle : slaveProperties.getShuttle()) {
            MessageQueue.init(SlaveType.Shuttle, shuttle);
        }
    }
    private void initThread(){
@@ -97,6 +98,13 @@
            new Thread((Runnable) devpThread).start();
            SlaveConnection.put(SlaveType.Devp, devp.getId(), devpThread);
        }
        // 初始化四向穿梭车
        News.info("初始化四向穿梭车......................................................");
        for (ShuttleSlave shuttleSlave : slaveProperties.getShuttle()) {
            ShuttleThread shuttleThread = new ShuttleThread(shuttleSlave);
            new Thread(shuttleThread).start();
            SlaveConnection.put(SlaveType.Shuttle, shuttleSlave.getId(), shuttleThread);
        }
        // 初始化条码扫描仪线程
        News.info("初始化条码扫描仪线程...................................................");
        for (Slave barcode : slaveProperties.getBarcode()) {
src/main/java/com/zy/core/cache/MessageQueue.java
@@ -29,6 +29,8 @@
    private static final Map<Integer, ConcurrentLinkedQueue<Task>> SCALE_EXCHANGE = new ConcurrentHashMap<>();
    // 台车mq交换机
    private static final Map<Integer, ConcurrentLinkedQueue<Task>> CAR_EXCHANGE = new ConcurrentHashMap<>();
    //四向穿梭车mq交换机
    private static final Map<Integer, ConcurrentLinkedQueue<Task>> SHUTTLE_EXCHANGE = new ConcurrentHashMap<>();
    /**
     * mq 交换机初始化
@@ -56,6 +58,9 @@
            case Car:
                CAR_EXCHANGE.put(slave.getId(), new ConcurrentLinkedQueue<>());
                break;
            case Shuttle:
                SHUTTLE_EXCHANGE.put(slave.getId(), new ConcurrentLinkedQueue<>());
                break;
            default:
                break;
        }
@@ -81,6 +86,8 @@
                return SCALE_EXCHANGE.get(id).offer(task);
            case Car:
                return CAR_EXCHANGE.get(id).offer(task);
            case Shuttle:
                return SHUTTLE_EXCHANGE.get(id).offer(task);
            default:
                return false;
        }
@@ -106,6 +113,8 @@
                return SCALE_EXCHANGE.get(id).poll();
            case Car:
                return CAR_EXCHANGE.get(id).poll();
            case Shuttle:
                return SHUTTLE_EXCHANGE.get(id).poll();
            default:
                return null;
        }
@@ -130,6 +139,8 @@
                return SCALE_EXCHANGE.get(id).peek();
            case Car:
                return CAR_EXCHANGE.get(id).peek();
            case Shuttle:
                return SHUTTLE_EXCHANGE.get(id).peek();
            default:
                return null;
        }
@@ -158,6 +169,9 @@
            case Car:
                CAR_EXCHANGE.get(id).clear();
                break;
            case Shuttle:
                SHUTTLE_EXCHANGE.get(id).clear();
                break;
            default:
                break;
        }
src/main/java/com/zy/core/cache/OutputQueue.java
@@ -17,5 +17,7 @@
    public static ArrayBlockingQueue<JSONObject> BARCODE = new ArrayBlockingQueue<>(32);
    // 穿梭车输出日志
    public static ArrayBlockingQueue<String> STE = new ArrayBlockingQueue<>(32);
    //四向穿梭车输出日志
    public static ArrayBlockingQueue<String> SHUTTLE = new ArrayBlockingQueue<>(32);
}
src/main/java/com/zy/core/enums/ShuttleErrorCodeType.java
New file
@@ -0,0 +1,50 @@
package com.zy.core.enums;
/**
 * 四向穿梭车
 * Wm204 错误编号
 */
public enum ShuttleErrorCodeType {
    NORMAL(0, "无错误"),
    PCB_SUBMODULE(1, "PCB子模块"),
    PCB_PLATE(2, "PCB板"),
    SERVO(10, "伺服"),
    CANOPEN(11, "canopen"),
    RUN_ERROR(14, "运行错误"),
    SYSTEM_ERROR(16, "系统错误")
    ;
    public Integer id;
    public String desc;
    ShuttleErrorCodeType(Integer id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static ShuttleErrorCodeType get(Integer id) {
        if (null == id) {
            return null;
        }
        for (ShuttleErrorCodeType type : ShuttleErrorCodeType.values()) {
            if (type.id.equals(id.intValue())) {
                return type;
            }
        }
        return null;
    }
    public static ShuttleErrorCodeType get(ShuttleErrorCodeType type) {
        if (null == type) {
            return null;
        }
        for (ShuttleErrorCodeType shuttleErrorCodeType : ShuttleErrorCodeType.values()) {
            if (shuttleErrorCodeType == type) {
                return shuttleErrorCodeType;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/ShuttlePlcInputStatusType.java
New file
@@ -0,0 +1,41 @@
package com.zy.core.enums;
/**
 * 四向穿梭车
 * Wm207  PLC输入状态
 */
public enum ShuttlePlcInputStatusType {
    LIFT_STATUS(Byte.parseByte("6"), "托盘顶部传感器状态")
    ;
    public byte id;
    public String desc;
    ShuttlePlcInputStatusType(byte id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static ShuttlePlcInputStatusType get(byte id) {
        for (ShuttlePlcInputStatusType type : ShuttlePlcInputStatusType.values()) {
            if (type.id == id) {
                return type;
            }
        }
        return null;
    }
    public static ShuttlePlcInputStatusType get(ShuttlePlcInputStatusType type) {
        if (null == type) {
            return null;
        }
        for (ShuttlePlcInputStatusType shuttlePlcInputStatusType : ShuttlePlcInputStatusType.values()) {
            if (shuttlePlcInputStatusType == type) {
                return shuttlePlcInputStatusType;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/ShuttlePlcOutputStatusType.java
New file
@@ -0,0 +1,45 @@
package com.zy.core.enums;
/**
 * 四向穿梭车
 * WM205 Plc输出状态IO
 */
public enum ShuttlePlcOutputStatusType {
    NULL(Byte.parseByte("0"), "空"),
    LIFT(Byte.parseByte("1"), "顶升位"),
    TURN(Byte.parseByte("2"), "转向位"),
    BRAKE(Byte.parseByte("3"), "抱闸位"),
    CHARGE(Byte.parseByte("4"), "冲电位")
    ;
    public byte id;
    public String desc;
    ShuttlePlcOutputStatusType(byte id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static ShuttlePlcOutputStatusType get(byte id) {
        for (ShuttlePlcOutputStatusType type : ShuttlePlcOutputStatusType.values()) {
            if (type.id == id) {
                return type;
            }
        }
        return null;
    }
    public static ShuttlePlcOutputStatusType get(ShuttlePlcOutputStatusType type) {
        if (null == type) {
            return null;
        }
        for (ShuttlePlcOutputStatusType shuttlePlcOutputStatusType : ShuttlePlcOutputStatusType.values()) {
            if (shuttlePlcOutputStatusType == type) {
                return shuttlePlcOutputStatusType;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/ShuttleStatusType.java
New file
@@ -0,0 +1,45 @@
package com.zy.core.enums;
/**
 * 四向穿梭车
 * Wm200 小车忙状态位
 */
public enum ShuttleStatusType {
    IDLE(false, "空闲"),
    BUSY(true, "忙"),
    ;
    public Boolean id;
    public String desc;
    ShuttleStatusType(Boolean id,String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static ShuttleStatusType get(Boolean id) {
        if (null == id) {
            return null;
        }
        for (ShuttleStatusType type : ShuttleStatusType.values()) {
            if (type.id.equals(id.booleanValue())) {
                return type;
            }
        }
        return BUSY;
    }
    public static ShuttleStatusType get(ShuttleStatusType type) {
        if (null == type) {
            return null;
        }
        for (ShuttleStatusType shuttleStatusType : ShuttleStatusType.values()) {
            if (shuttleStatusType == type) {
                return shuttleStatusType;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/ShuttleTaskModeType.java
New file
@@ -0,0 +1,40 @@
package com.zy.core.enums;
public enum ShuttleTaskModeType {
    INIT(0, "初始"),    // 初始
    ;
    public Integer id;
    public String desc;
    ShuttleTaskModeType(Integer id, String desc) {
        this.id = id;
        this.desc = desc;
    }
    public static ShuttleTaskModeType get(Short id) {
        if (null == id) {
            return null;
        }
        for (ShuttleTaskModeType type : ShuttleTaskModeType.values()) {
            if (type.id.equals(id.intValue())) {
                return type;
            }
        }
        return null;
    }
    public static ShuttleTaskModeType get(ShuttleTaskModeType type) {
        if (null == type) {
            return null;
        }
        for (ShuttleTaskModeType shuttleTaskModeType : ShuttleTaskModeType.values()) {
            if (shuttleTaskModeType == type) {
                return shuttleTaskModeType;
            }
        }
        return null;
    }
}
src/main/java/com/zy/core/enums/SlaveType.java
@@ -9,6 +9,7 @@
    Scale,
    Car,
    Ste,
    Shuttle,
    ;
    public static SlaveType findInstance(String s){
src/main/java/com/zy/core/model/ShuttleSlave.java
New file
@@ -0,0 +1,46 @@
package com.zy.core.model;
import com.zy.core.Slave;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.ArrayList;
import java.util.List;
@EqualsAndHashCode(callSuper = true)
@Data
public class ShuttleSlave extends Slave {
    private Integer rack;
    private Integer slot;
    private Boolean demo;
    // 穿梭车入库站点
    private List<Sta> shuttleInStn = new ArrayList<>();
    // 穿梭车出库站点
    private List<Sta> shuttleOutStn = new ArrayList<>();
    @Data
    public static class Sta {
        // 输送线plc编号
        private Integer devpPlcId;
        // 穿梭车站点编号
        private Integer staNo;
        // 排
        private Integer row;
        // 列
        private Integer bay;
        // 层
        private Integer lev;
    }
}
src/main/java/com/zy/core/model/command/ShuttleCommand.java
New file
@@ -0,0 +1,98 @@
package com.zy.core.model.command;
import lombok.Data;
@Data
public class ShuttleCommand {
    /**
     * 四向穿梭车号
     */
    private Integer shuttleNo = 0;
    /**
     * 任务号
     */
    private Integer taskNo = 0;
    /**
     * 作业类型
     */
    private Short taskMode = 0;
    /**
     * 任务确认 false:未确认 true:已确认
     */
    private Boolean complete = Boolean.FALSE;
    /**
     * 控制指令字
     */
    private Integer commandWord;
    /**
     * 启始二维编号
     */
    private String startCodeNum;
    /**
     * 中间二维编号
     */
    private String middleCodeNum;
    /**
     * 目标二维编号
     */
    private String distCodeNum;
    /**
     * 起点到目标点的距离长度
     */
    private Integer startToDistDistance;
    /**
     * 中间点到目标点的距离长度
     */
    private Integer middleToDistDistance;
    /**
     * 小车运行方向
     */
    private Integer runDirection;
    /**
     * 托盘顶升
     */
    private Integer palletLift;
    /**
     * 小车强制移动距离
     */
    private Integer forceMoveDistance;
    /**
     * 充电开关
     */
    private Integer chargeSwitch;
    /**
     * 小车IO控制
     */
    private byte IOControl;
    /**
     * 小车运行速度
     */
    private Integer runSpeed;
    /**
     * 小车雷达备用
     */
    private Integer radarTmp;
    /**
     * 指令结束位
     */
    private Integer commandEnd;
}
src/main/java/com/zy/core/model/protocol/ShuttleProtocol.java
New file
@@ -0,0 +1,294 @@
package com.zy.core.model.protocol;
import com.zy.core.enums.ShuttleStatusType;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
/**
 * 四向穿梭车
 */
@Slf4j
@Data
public class ShuttleProtocol {
    /**
     * 四向穿梭车号
     */
    private Short shuttleNo;
    /**
     * 任务号
     */
    public Short taskNo = 0;
    /**
     * 排
     */
    public Short row;
    /**
     * 列
     */
    public Short bay;
    /**
     * 层
     */
    public Short lev;
    /**
     * 控制指令字
     */
    private Integer commandWord;
    /**
     * 启始二维编号
     */
    private Integer startCodeNum;
    /**
     * 中间二维编号
     */
    private Integer middleCodeNum;
    /**
     * 目标二维编号
     */
    private Integer distCodeNum;
    /**
     * 起点到目标点的距离长度
     */
    private Integer startToDistDistance;
    /**
     * 中间点到目标点的距离长度
     */
    private Integer middleToDistDistance;
    /**
     * 小车运行方向
     */
    private Integer runDirection;
    /**
     * 托盘顶升
     */
    private Integer palletLift;
    /**
     * 小车强制移动距离
     */
    private Integer forceMoveDistance;
    /**
     * 充电开关
     */
    private Integer chargeSwitch;
    /**
     * 小车IO控制
     */
    private Integer IOControl;
    /**
     * 小车运行速度
     */
    private Integer runSpeed;
    /**
     * 小车雷达备用
     */
    private Integer radarTmp;
    /**
     * 指令结束位
     */
    private Integer commandEnd;
    /**
     * 小车忙状态位
     * true: 忙
     * false: 空闲
     */
    private Boolean busyStatus;
    /**
     * 小车忙状态位枚举
     */
    private ShuttleStatusType busyStatusType;
    /**
     * 当前二维码
     * 0为空
     */
    private String currentCode;
    /**
     * 电池电量百分比
     */
    private Double batteryPower;
    /**
     * 电池温度
     */
    private Double batteryTemp;
    /**
     * 错误编号
     */
    private Integer errorCode;
    /**
     * Plc输出状态IO
     */
    private byte plcOutputStatusIO;
    /**
     * 错误信息码
     */
    private Integer statusErrorCode;
    /**
     * PLC输入状态
     */
    private byte plcInputStatus;
    /**
     * 当前或者之前读到的二维码值
     */
    private String currentOrBeforeCode;
    /**
     * 读到的二维码X方向偏移量
     */
    private Integer codeOffsetX;
    /**
     * 读到的二维码Y方向偏移量
     */
    private Integer codeOffsetY;
    /**
     * 当前的电压值
     */
    private Double currentVoltage;
    /**
     * 当前的模拟量值
     */
    private Integer currentAnalogValue;
    /**
     * 当前的升降伺服速度
     */
    private Double currentLiftServoSpeed;
    /**
     * 当前的行走伺服速度
     */
    private Double currentMoveServoSpeed;
    /**
     * 当前的升降伺服负载率
     */
    private Double currentLiftServoLoad;
    /**
     * 当前的行走伺服负载率
     */
    private Double currentMoveServoLoad;
    /**
     * 作业标记
     */
    private String pakMk = "-";
    // 任务信息 ---------------------------------------------------------
    /**
     * 96.入库任务中
     */
    private boolean pakInTask;
    /**
     * 97. 出库任务中
     */
    private boolean pakOutTask;
    /**
     * 98. 移库任务中
     */
    private boolean pakMoveTask;
    /**
     * 99. 回原点任务中
     */
    private boolean goHpTask;
    /**
     * 100. 去反原点任务中
     */
    private boolean goOHpTask;
    /**
     * 101. 去原点避让位
     */
    private boolean goHpAvoid;
    /**
     * 102. 去反原点避让位
     */
    private boolean goOHpAvoid;
    /**
     * 104. 入库取空结束
     */
    private boolean pakInEmpty;
    /**
     * 105. 入库正常结束
     */
    private boolean pakInFinish;
    /**
     * 106. 出库取空结束
     */
    private boolean pakOutEmpty;
    /**
     * 107. 出库正常结束
     */
    private boolean pakOutFinish;
    /**
     * 108. 去原点避让完成
     */
    private boolean goHpAvoidFinish;
    /**
     * 109. 去反原点避让完成
     */
    private boolean goOHpAvoidFinish;
    /**
     * 110. 去原点避让完成
     */
    private boolean goHpAvoidErr;
    /**
     * 111. 去反原点避让完成
     */
    private boolean goOHpAvoidErr;
    public void setBusyStatus(Boolean status) {
        this.busyStatus = status;
        this.busyStatusType = ShuttleStatusType.get(status);
    }
    public void setBusyStatus(ShuttleStatusType type) {
        this.busyStatus = type.id.booleanValue();
        this.busyStatusType = type;
    }
}
src/main/java/com/zy/core/properties/SlaveProperties.java
@@ -1,10 +1,7 @@
package com.zy.core.properties;
import com.zy.core.Slave;
import com.zy.core.model.CrnSlave;
import com.zy.core.model.DevpSlave;
import com.zy.core.model.LedSlave;
import com.zy.core.model.SteSlave;
import com.zy.core.model.*;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@@ -42,4 +39,6 @@
    private List<Slave> car = new ArrayList<>();
    private List<ShuttleSlave> shuttle = new ArrayList<>();
}
src/main/java/com/zy/core/thread/ShuttleThread.java
New file
@@ -0,0 +1,275 @@
package com.zy.core.thread;
import HslCommunication.Core.Transfer.DataFormat;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.ModBus.ModbusTcpNet;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.alibaba.fastjson.JSON;
import com.core.common.DateUtils;
import com.core.common.RadixTools;
import com.core.exception.CoolException;
import com.zy.core.News;
import com.zy.core.ThreadHandler;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.ShuttleStatusType;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.ShuttleSlave;
import com.zy.core.model.SteSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.ShuttleCommand;
import com.zy.core.model.command.SteCommand;
import com.zy.core.model.protocol.ShuttleProtocol;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.Date;
/**
 * 四向穿梭车线程
 */
@Data
@Slf4j
public class ShuttleThread implements  Runnable, ThreadHandler {
    private ModbusTcpNet modbusTcpNet;
    private ShuttleSlave slave;
    private ShuttleProtocol shuttleProtocol;
    private SiemensS7Net siemensS7Net;
    public ShuttleThread(ShuttleSlave slave) {
        this.slave = slave;
    }
    @Override
    public void run() {
        this.connect();
        while (true) {
            try {
                int step = 1;
                Task task = MessageQueue.poll(SlaveType.Shuttle, slave.getId());
                if (task != null) {
                    step = task.getStep();
                }
                switch (step) {
                    // 读数据
                    case 1:
                        readStatus();
                        break;
                    // 写入数据
                    case 2:
                        write((ShuttleCommand) task.getData());
                        break;
                    default:
                        break;
                }
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public boolean connect() {
        boolean result = false;
        //-------------------------四向穿梭车连接方法------------------------//
        modbusTcpNet = new ModbusTcpNet(slave.getIp(), slave.getPort(), (byte) 0x01);
        // 当你需要指定格式的数据解析时,就需要设置下面的这个信息
        modbusTcpNet.setDataFormat(DataFormat.ABCD);
        OperateResult connect = modbusTcpNet.ConnectServer();
        if(connect.IsSuccess){
            result = true;
            OutputQueue.CRN.offer(MessageFormat.format( "【{0}】四向穿梭车plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            log.info("四向穿梭车plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
        } 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("四向穿梭车plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] ", slave.getId(), slave.getIp(), slave.getPort());
        }
        modbusTcpNet.ConnectClose();
        //-------------------------四向穿梭车连接方法------------------------//
        return result;
    }
    @Override
    public void close() {
    }
    private void readStatus() {
        try {
            OperateResultExOne<byte[]> result = modbusTcpNet.Read("0", (short) 17);
            if (result.IsSuccess) {
                if (null == shuttleProtocol) {
                    shuttleProtocol = new ShuttleProtocol();
                    shuttleProtocol.setShuttleNo(slave.getId().shortValue());
                }
                //----------设置四向穿梭车状态-----------
                //获取数据
                byte[] content = result.Content;
                //--------控制字--------
                //控制指令字
                shuttleProtocol.setCommandWord(modbusTcpNet.getByteTransform().TransUInt16(content, 0));
                //启始二维编号
                shuttleProtocol.setStartCodeNum(modbusTcpNet.getByteTransform().TransUInt16(content, 2));
                //中间二维编号
                shuttleProtocol.setMiddleCodeNum(modbusTcpNet.getByteTransform().TransUInt16(content, 4));
                //目标二维编号
                shuttleProtocol.setDistCodeNum(modbusTcpNet.getByteTransform().TransUInt16(content, 6));
                //起点到目标点的距离长度
                shuttleProtocol.setStartToDistDistance(modbusTcpNet.getByteTransform().TransInt32(content, 8));
                //中间点到目标点的距离长度
                shuttleProtocol.setMiddleToDistDistance(modbusTcpNet.getByteTransform().TransInt32(content, 12));
                //小车运行方向
                shuttleProtocol.setRunDirection(modbusTcpNet.getByteTransform().TransUInt16(content, 16));
                //托盘顶升
                shuttleProtocol.setPalletLift(modbusTcpNet.getByteTransform().TransUInt16(content,18));
                //小车强制移动距离
                shuttleProtocol.setForceMoveDistance(modbusTcpNet.getByteTransform().TransInt32(content, 20));
                //充电开关
                shuttleProtocol.setChargeSwitch(modbusTcpNet.getByteTransform().TransUInt16(content,24));
                //小车IO控制
                shuttleProtocol.setIOControl(modbusTcpNet.getByteTransform().TransUInt16(content,26));
                //小车运行速度
                shuttleProtocol.setRunSpeed(modbusTcpNet.getByteTransform().TransUInt16(content,28));
                //小车雷达备用
                shuttleProtocol.setRadarTmp(modbusTcpNet.getByteTransform().TransUInt16(content,30));
                //指令结束位
                shuttleProtocol.setCommandEnd(modbusTcpNet.getByteTransform().TransUInt16(content,32));
                //---------状态字---------
//                shuttleProtocol.setBusyStatus(modbusTcpNet.getByteTransform().TransUInt16(content,32));
                ///设置四向穿梭车状态-end
                OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
                //读取四向穿梭车设备信息,提供查询
                //.....
                // 根据实时信息更新数据库
                //.....
            }else {
                OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】{1}四向穿梭车plc状态信息失败", DateUtils.convert(new Date()), slave.getId()));
                throw new CoolException(MessageFormat.format( "四向穿梭车plc状态信息失败 ===>> [id:{0}] [ip:{1}] [port:{2}]", slave.getId(), slave.getIp(), slave.getPort()));
            }
        } catch (Exception e) {
            OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】四向穿梭车plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            initShuttle();
        }
    }
    private boolean write(ShuttleCommand command){
        if (null == command) {
            News.error("四向穿梭车写入命令为空");
            return false;
        }
        //判断小车是否在充电
        SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
        if (devpThread.charge1){
        }
        command.setShuttleNo(slave.getId());
        OperateResult result = null;
        // 开始任务
        //...
        try {
            // 日志记录
            if (!command.getComplete() && command.getTaskMode() != 0) {
                //日志记录保存到数据库中
                //.....
            }
        } catch (Exception ignore) {}
        if (result != null && result.IsSuccess) {
            // 维护数据库排列层
//            if (!steProtocol.getWaiting()) {
//                if (!Cools.isEmpty(command.getRow(), command.getBay(), command.getLev())) {
//                    this.modifyPos(command.getRow().intValue(), command.getBay().intValue(), command.getLev().intValue());
//                }
//            }
            News.info("四向穿梭车命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            return true;
        } else {
            OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】写入四向穿梭车plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            News.error("写入四向穿梭车plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            return false;
        }
    }
    /**
     * 初始化四向穿梭车
     */
    private void initShuttle() {
        if (null == shuttleProtocol) {
            shuttleProtocol = new ShuttleProtocol();
        }
        shuttleProtocol.setShuttleNo(slave.getId().shortValue());
        shuttleProtocol.setBusyStatus(ShuttleStatusType.BUSY);
        shuttleProtocol.setCurrentCode("0");
    }
    /******************************************************************************************/
    /**************************************** 测试专用 *****************************************/
    /*****************************************************************************************/
    public static void main(String[] args) throws InterruptedException {
        ShuttleSlave slave = new ShuttleSlave();
        slave.setId(1);
        slave.setIp("192.168.4.24");
        slave.setPort(502);
        ShuttleThread thread = new ShuttleThread(slave);
        thread.connect();
        thread.readStatus();
        System.out.println(JSON.toJSONString(thread.shuttleProtocol));
        // 任务作业
//        SteCommand command = new SteCommand();
//        command.setSteNo(1); // 堆垛机编号
//        Random random = new Random();
//        int taskNo = random.nextInt(9090);
//        command.setTaskNo(taskNo); // 工作号
//        command.setTaskMode(SteTaskModeType.MOVE_LEFT); // 任务模式
//        thread.write(command);
        // 任务完成
//        SteCommand command = new SteCommand();
//        command.setSteNo(1); // 堆垛机编号
//        command.setComplete(Boolean.TRUE); // 任务模式
//        thread.write(command);
        // 控制模式
//        SteCommand command = new SteCommand();
//        command.setControlMode((short) 1);
//        thread.write(command);
        // 复位信号
//        SteCommand command = new SteCommand();
//        command.setReset(Boolean.TRUE);
//        thread.write(command);
        // 删除指令
//        SteCommand command = new SteCommand();
//        command.setDelete(Boolean.TRUE);
//        thread.write(command);
        // 穿梭车运行禁止
//        SteCommand command = new SteCommand();
//        command.setRun((short)0);
//        thread.write(command);
    }
}
src/main/resources/mapper/BasShuttleMapper.xml
New file
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zy.asrs.mapper.BasShuttleMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.zy.asrs.entity.BasShuttle">
        <result column="shuttle_no" property="shuttleNo" />
        <result column="status" property="status" />
        <result column="shuttle_status" property="shuttleStatus" />
        <result column="wrk_no" property="wrkNo" />
        <result column="row" property="row" />
        <result column="bay" property="bay" />
        <result column="lev" property="lev" />
        <result column="his_row" property="hisRow" />
        <result column="his_bay" property="hisBay" />
        <result column="his_lev" property="hisLev" />
        <result column="idle_loc" property="idleLoc" />
        <result column="auto_charge" property="autoCharge" />
        <result column="charge_line" property="chargeLine" />
        <result column="create_by" property="createBy" />
        <result column="create_time" property="createTime" />
        <result column="update_by" property="updateBy" />
        <result column="update_time" property="updateTime" />
        <result column="memo" property="memo" />
        <result column="lift_no" property="liftNo" />
    </resultMap>
</mapper>
src/main/webapp/static/css/shuttle.css
New file
@@ -0,0 +1,334 @@
body {
    background-color: #6CA7A8;
}
.button-window {
    float: left;
    width: 100%;
    height: 100%;
    padding: 10px;
    background-color: #6CA7A8;
    border-radius: 5px;
    box-shadow: 0 0 3px rgba(0 0 0 .3);
}
/* -------------------- 第一模块 -------------------- */
.log-board {
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 0 3px rgba(0,0,0,.3);
    height: 25%;
}
/* 左 */
.command-log {
    float: left;
    height: 100%;
    width: 20%;
    text-align: center;
}
.command-log h2 {
    padding: 10px;
}
.shuttle-command-item {
    padding: 4px 0;
    margin-top: 5px;
}
.shuttle-command-item label {
    font-size: 20px;
    font-weight: bold;
    vertical-align: middle;
}
.demoBtn {
    vertical-align: middle;
    /*width: 30%;*/
    height: 30px;
    left: 0;
    top: 0;
    padding: 5px 15px;
    text-shadow: inherit;
    font-size: 15px;
    margin-left: 5px;
    margin-right: 5px;
    display: inline-block;
    background-color: #FF5722;
    border: none;
    color: #FFF;
    box-shadow: 1px 1px 5px #B6B6B6;
    border-radius: 3px;
    cursor: pointer;
}
.demoBtn:hover {
    opacity: 0.8
}
.demoBtn:focus {
    outline: 0;
}
/* 右 */
.shuttle-state {
    float: left;
    height: 100%;
    width: 80%;
    overflow: auto;
}
/* 穿梭车状态表 */
#shuttle-state-table {
    font-size: 12px;
    border-collapse: collapse;
    margin: 0 auto;
    text-align: center;
}
#shuttle-state-table td, #shuttle-state-table th {
    border: 1px solid #cad9ea;
    color: #666;
    height: 25px;
}
#shuttle-state-table thead th {
    background-color: #CCE8EB;
    width: 300px;
}
#shuttle-state-table tr:nth-child(odd) {
    background: #fff;
}
#shuttle-state-table tr:nth-child(even) {
    background: #F5FAFA;
}
/* -------------------- 第二模块 -------------------- */
.shuttle-msg {
    /*overflow: auto;*/
    margin-top: 10px;
    height: 23%;
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 0 3px rgba(0,0,0,.3);
}
/* 堆垛机状态信息表 */
#shuttle-msg-table {
    font-size: 12px;
    border-collapse: collapse;
    margin: 0 auto;
    text-align: center;
}
#shuttle-msg-table td, #shuttle-msg-table th {
    border: 1px solid #f1f1f1;
    color: #666;
    height: 30px;
}
#shuttle-msg-table thead th {
    background-color: #fff;
    width: 400px;
}
#shuttle-msg-table tr:nth-child(odd) {
    background: #fff;
}
#shuttle-msg-table tr:nth-child(even) {
    background: #fff;
}
/* -------------------- 第三模块 -------------------- */
.shuttle-operation {
    position: relative;
    margin-top: 10px;
    height: 25%;
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 0 3px rgba(0,0,0,.3);
}
/* 任务设备选择框 */
.task-select {
    width: 13%;
    height: 100%;
    overflow: hidden;
    display: inline-block;
    padding: 20px 0 10px 20px;
    /*clear: right;*/
}
.operator-item {
    display: inline-block;
    height: 100%;
    text-align: center;
    position: relative;
    vertical-align: middle;
    padding: 0 20px;
}
.operator-item .select-title {
    display: inline-block;
    position: absolute;
    top: -11px;
    left: 50%;
    transform: translate(-50%, 0);
    background-color: #fff;
    color: #2e95d3;
    font-size: 12px;
    border: 1px solid #8d8d8d;
    border-radius: 5px;
    padding: 5px;
    z-index: 999;
}
.operator-item .select-container {
    padding: 30px 0;
    height: 100%;
    border: 1px solid #8d8d8d;
    border-radius: 5px;
}
#shuttle-select .select-container label {
    display: block;
    padding: 5px 40px;
    vertical-align: middle; margin-top:-2px; margin-bottom:1px;
}
.select-container input {
    display: inline-block;
    font-size: 12px;
    vertical-align: middle; margin-top:-2px; margin-bottom:1px;
}
.select-container-item {
    display: inline-block;
    padding: 0 10px;
}
.select-container-item input {
    height: 20px;
    border: 1px solid #8D8D8D;
    border-radius: 3px;
    width: 80px;
    outline: none;
}
/* 任务作业选择框 */
.task-operator {
    width: 86%;
    height: 100%;
    overflow: hidden;
    padding: 5px 0 10px 20px;
    display: inline-block;
    margin-right: 10px;
}
.task-operator fieldset {
    padding: 15px 20px 5px 50px;
    /*border-width: 1px;*/
    /*border-style: solid;*/
    height: 100%;
    border: 1px solid #8d8d8d;
    border-radius: 5px;
}
.task-operator legend {
    background-color: #fff;
    color: #2e95d3;
    font-size: 12px;
    border: 1px solid #8d8d8d;
    border-radius: 5px;
    padding: 5px;
    z-index: 999;
}
button.item {
    margin-top: 5px;
    border: 1px solid #333;
    font-size: 13px;
    padding: 1px 1px 1px 1px;
    width: 100px;
    height: 40px;
    outline: none;
    cursor: pointer;
    color: #333;
    background-color: transparent;
    margin-right: 5px;
    border-radius: 5px;
}
button.item:hover {
    background-color: #333;
    color: #fff;
}
/* 手动操作遮罩 */
.shuttle-operation-shade {
    position: absolute;
    height: 100%;
    width: 100%;
    z-index: 1000;
    text-align: center;
    padding: 80px 0;
}
.shuttle-operation-shade-span {
    font-size: xx-large;
    font-weight: bold;
    color: red;
}
/* -------------------- 第四模块 -------------------- */
.shuttle-output-board {
    margin-top: 10px;
    height: 20%;
    background-color: #fff;
    border-radius: 5px;
    box-shadow: 0 0 3px rgba(0,0,0,.3);
}
#shuttle-output {
    border-left: none;
    border-right: none;
    border-top: 1px solid #9d9d9d;
    border-bottom: 1px solid #333;
    width: 100%;
    height: 100%;
    overflow: auto;
    resize:none;
    color: #666;
}
/* 详情弹出层 */
#shuttle-detl {
    padding: 30px 10px 0 25px;
    overflow: hidden;
}
#shuttle-detl form {
    overflow: hidden;
}
.form-item {
    margin-bottom: 10px;
}
.form-label {
    display: inline-block;
    width: 130px;
    text-align: right;
}
.form-input {
    display: inline-block;
    padding-left: 15px;
}
.form-input input {
    outline-style: none ;
    border: 1px solid #ccc;
    border-radius: 3px;
    padding: 5px 8px;
    width: 150px;
    height: 30px;
    font-size: 14px;
    font-weight: bolder;
}
.form-input input:focus{
    border-color: #66afe9;
    outline: 0;
    -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);
    box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)
}
.form-button-container {
    text-align: center;
}
.form-button {
    margin: 10px 10px;
    width: 50px;
    height: 30px;
    color:white;
    background-color:cornflowerblue;
    border-radius: 3px;
    border-width: 0;
    outline: none;
    font-size: 15px;
    text-align: center;
    cursor: pointer;
}
.form-button:hover {
    opacity: 0.7;
}
src/main/webapp/static/js/map.json
@@ -1072,8 +1072,8 @@
    "value": -1,
    "data": ""
  }, {
    "value": 4,
    "data": "200"
    "value": -1,
    "data": ""
  }, {
    "value": -1,
    "data": ""
@@ -1151,11 +1151,11 @@
    "value": -1,
    "data": ""
  }, {
    "value": 4,
    "data": "201"
    "value": -1,
    "data": ""
  }, {
    "value": 4,
    "data": "202"
    "value": -1,
    "data": ""
  }, {
    "value": -1,
    "data": ""
@@ -1233,11 +1233,11 @@
    "value": -1,
    "data": ""
  }, {
    "value": 4,
    "data": "203"
    "value": -1,
    "data": ""
  }, {
    "value": 4,
    "data": "204"
    "data": "100"
  }, {
    "value": -1,
    "data": ""
@@ -1316,10 +1316,10 @@
    "data": ""
  }, {
    "value": 4,
    "data": "205"
    "data": "104"
  }, {
    "value": 4,
    "data": "206"
    "data": "101"
  }, {
    "value": -1,
    "data": ""
@@ -1397,11 +1397,11 @@
    "value": -1,
    "data": ""
  }, {
    "value": -1,
    "data": ""
    "value": 4,
    "data": "103"
  }, {
    "value": 4,
    "data": "207"
    "data": "102"
  }, {
    "value": -1,
    "data": ""
@@ -1483,7 +1483,7 @@
    "data": ""
  }, {
    "value": 4,
    "data": "208"
    "data": ""
  }, {
    "value": 0,
    "data": ""
src/main/webapp/views/index.html
@@ -21,7 +21,8 @@
            <li><a id="console" onclick="nav(this.id)" class="nav-select" href="#">主控图</a></li>
            <li><a id="pipeline" onclick="nav(this.id)" class="nav-unselect" href="#">输送设备</a></li>
            <li><a id="crn" onclick="nav(this.id)" class="nav-unselect" href="#">堆垛机</a></li>
            <li><a id="ste" onclick="nav(this.id)" class="nav-unselect" href="#">穿梭车</a></li>
<!--            <li><a id="ste" onclick="nav(this.id)" class="nav-unselect" href="#">穿梭车</a></li>-->
            <li><a id="shuttle" onclick="nav(this.id)" class="nav-unselect" href="#">四向穿梭车</a></li>
        </ul>
    </div>
</div>
src/main/webapp/views/shuttle.html
New file
@@ -0,0 +1,786 @@
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>四向穿梭车监控管理</title>
    <link rel="stylesheet" type="text/css" href="../static/css/normalize.css">
    <link rel="stylesheet" type="text/css" href="../static/css/common.css">
    <link rel="stylesheet" type="text/css" href="../static/layui/css/layui.css">
    <link rel="stylesheet" href="../static/css/shuttle.css">
    <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script>
    <script type="text/javascript" src="../static/js/layer/layer.js"></script>
    <script type="text/javascript" src="../static/layui/layui.js"></script>
    <script type="text/javascript" src="../static/js/common.js"></script>
</head>
<body>
    <div style="padding: 10px;height: 100%;float: left;width: 6%">
        <div class="button-window"></div>
    </div>
    <div style="height: 100%;padding-left: 6%">
        <div style="padding: 10px;height: 100%">
            <!-- 日志监控板 -->
            <div class="log-board">
                <div class="command-log" id="commandLogId">
<!--                    <div data-shuttleNo="1" class="shuttle-command-item">-->
<!--                        <label>1#</label>-->
<!--                        <button class="demoBtn pos-btn">数据维护</button>-->
<!--                        <button id="mode-1" class="demoBtn mode-btn" >设备信息</button>-->
<!--                    </div>-->
                </div>
                <!-- 堆垛机状态位信息 -->
                <div class="shuttle-state">
                    <table id="shuttle-state-table">
                        <thead>
                            <tr>
                                <th>四向穿梭车</th>
                                <th>待定</th>
                                <th>状态</th>
                                <th>有物</th>
                                <th>在轨</th>
                                <th>电量</th>
                                <th>排</th>
                                <th>列</th>
                                <th>层</th>
                                <th>等待WCS确认</th>
                                <th>定位</th>
                                <th>充电状态</th>
                                <th>报警信息1</th>
                                <th>报警信息2</th>
                            </tr>
                        </thead>
                        <tbody>
                        </tbody>
                    </table>
                </div>
            </div>
            <!-- 穿梭车状态 -->
            <div class="shuttle-msg">
                <table id="shuttle-msg-table">
                    <thead>
                        <tr>
                            <th>四向穿梭车</th>
                            <th>工作号</th>
                            <th>状态</th>
                            <th>源站</th>
                            <th>目标站</th>
                            <th>源库位</th>
                            <th>目标库位</th>
                            <th>速度</th>
                            <th>作业标记</th>
                        </tr>
                    </thead>
                    <tbody>
                    </tbody>
                </table>
            </div>
            <!-- 手动操作 -->
            <div class="shuttle-operation">
                <!-- 遮罩层 -->
                <div class="shuttle-operation-shade">
                    <span class="shuttle-operation-shade-span">
                        WCS 系统运行中,请停止后操作
                    </span>
                </div>
                <!-- 设备任务选择 -->
                <div class="task-select">
                    <!-- 选择 -->
                    <div id="shuttle-select" class="operator-item">
                        <span class="select-title">四向穿梭车号</span>
                        <div class="select-container" id="shuttleRadioBoxId">
<!--                            <label><input type="radio" name="shuttleSelect" value="1" checked>&nbsp;1号穿梭车</label>-->
                        </div>
                    </div>
                </div>
                <!-- 设备任务操作 -->
                <div class="task-operator">
                    <div style="display: flex;">
                        <div class="task-operator" style="height: auto;width: auto;">
                            <div class="operator-item" style="height: auto">
                                <span class="select-title">源站/源库位</span>
                                <div class="select-container" style="height: auto">
                                    <div class="select-container-item">
                                        <span>站</span>
                                        <label><input id="sourceStaNo" type="number" name="points" min="0" /></label>
                                    </div>
                                    <div class="select-container-item">
                                        <span>排</span>
                                        <label><input id="sourceRow" type="number" name="points" min="1" style="background-color: #a9eeff" value="1" /></label>
                                    </div>
                                    <div class="select-container-item">
                                        <span>列</span>
                                        <label><input id="sourceBay" type="number" name="points" min="0" style="background-color: #a9eeff" value="0" /></label>
                                    </div>
                                    <div class="select-container-item">
                                        <span>层</span>
                                        <label><input id="sourceLev" type="number" name="points" min="1" style="background-color: #a9eeff" value="1" /></label>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="task-operator" style="height: auto;width: auto;">
                            <div class="operator-item" style="height: auto">
                                <span class="select-title">源站/源库位</span>
                                <div class="select-container" style="height: auto">
                                    <div class="select-container-item">
                                        <span>站</span>
                                        <label><input id="distStaNo" type="number" name="points" min="0" /></label>
                                    </div>
                                    <div class="select-container-item">
                                        <span>排</span>
                                        <label><input id="distRow" type="number" name="points" min="1" style="background-color: #a9eeff" value="1" /></label>
                                    </div>
                                    <div class="select-container-item">
                                        <span>列</span>
                                        <label><input id="distBay" type="number" name="points" min="0" style="background-color: #a9eeff" value="0" /></label>
                                    </div>
                                    <div class="select-container-item">
                                        <span>层</span>
                                        <label><input id="distLev" type="number" name="points" min="1" style="background-color: #a9eeff" value="1" /></label>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <fieldset style="height: auto;padding-bottom: 20px;">
                        <legend>手动操作</legend>
                        <div class="button-group">
                            <button class="item" onclick="shuttleOperator(4)">托盘顶升</button>
                            <button class="item" onclick="shuttleOperator(4)">托盘放下</button>
                            <button class="item" onclick="shuttleOperator(5)">左移</button>
                            <button class="item" onclick="shuttleOperator(6)">右移</button>
                            <button class="item" onclick="shuttleOperator(7)">前移</button>
                            <button class="item" onclick="shuttleOperator(8)">后移</button>
                            <button class="item" onclick="shuttleOperator(9)">强制移动</button>
                            <button class="item" onclick="shuttleOperator(16)">任务完成</button>
                        </div>
                    </fieldset>
                </div>
            </div>
            <!-- 穿梭车日志输出 -->
            <div class="shuttle-output-board">
                <textarea id="shuttle-output"></textarea>
            </div>
        </div>
    </div>
    <div id="shuttle-detl" style="display: none">
        <div>
            <div class="form-item">
                <label class="form-label">四向穿梭车号:</label>
                <div class="form-input">
                    <input id="shuttleNo" name="shuttleNo" class="layui-input" lay-verify="required|number" autocomplete="off" disabled="disabled">
                </div>
            </div>
            <div class="form-item">
                <label class="form-label">工作号:</label>
                <div class="form-input">
                    <input id="workNo" name="workNo" type="number" class="layui-input" lay-verify="number" autocomplete="off">
                </div>
            </div>
            <div class="form-item">
                <label class="form-label">排:</label>
                <div class="form-input">
                    <input id="row" name="row" type="number" class="layui-input" lay-verify="number" autocomplete="off">
                </div>
            </div>
            <div class="form-item">
                <label class="form-label">列:</label>
                <div class="form-input">
                    <input id="bay" name="bay" type="number" class="layui-input" autocomplete="off">
                </div>
            </div>
            <div class="form-item">
                <label class="form-label">层:</label>
                <div class="form-input">
                    <input id="lev" name="lev" type="number" class="layui-input" autocomplete="off">
                </div>
            </div>
            <div class="form-item">
                <label class="form-label">作业标记:</label>
                <div class="form-input">
                    <input id="pakMk" name="pakMk" type="text" class="layui-input" autocomplete="off">
                </div>
            </div>
            <div class="form-item form-button-container">
                <button class="form-button" id="save">保存</button>
                <button class="form-button" id="cancel" style="background-color: #D0D0D0">取消</button>
            </div>
        </div>
    </div>
    <div id="shuttle-detl2" style="display: none">
        <div style="width: 1400px">
            <div class="form-item" style="text-align: left">
                <spen style="margin:  20px 10px 10px 10px; padding: 10px 10px 10px 10px;border: black;border-width: 3px;border-style:dotted;">
                    异常:<spen style="color: #FD482C;">✔</spen>
                </spen>
                <spen style="margin:  20px 10px 10px 10px; padding: 10px 10px 10px 10px;border: black;border-width: 3px;border-style: double;">
                    正常:<spen style="color: #00FF00;">—</spen>
                </spen>
            </div>
            <div style="float:left;margin:  10px 10px 10px 10px; padding: 10px 10px 10px 10px;border: black;border-width: 3px;border-style:dotted;">
                <div class="form-item" style="text-align: center">
                    <label>四向穿梭车异常</label>
                </div>
                <div class="form-item">
                    <label class="form-label">四向穿梭车号:</label>
                    <div class="form-input">
                        <input id="shuttleNo1" name="shuttleNo" class="layui-input" lay-verify="required|number" autocomplete="off" disabled="disabled" readonly>
                    </div>
                </div>
            </div>
            <div style="float:left;margin:  10px 10px 10px 10px; padding: 10px 10px 10px 10px;border: black;border-width: 3px;border-style:dotted">
                <div class="form-item" style="text-align: center">
                    <label>四向穿梭车提示信息</label>
                </div>
            </div>
            <div style="float:left;margin:  10px 10px 10px 10px; padding: 10px 10px 10px 10px;border: black;border-width: 3px;border-style:dotted">
                <div class="form-item" style="text-align: center">
                    <label>任务信息</label>
                </div>
                <div class="form-item">
                    <label class="form-label">入库任务中:</label>
                    <div class="form-input">
                        <input id="pakInTask" name="pakInTask" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">出库任务中:</label>
                    <div class="form-input">
                        <input id="pakOutTask" name="pakOutTask" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">移库任务中:</label>
                    <div class="form-input">
                        <input id="pakMoveTask" name="pakMoveTask" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">回原点任务中:</label>
                    <div class="form-input">
                        <input id="goHpTask" name="goHpTask" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">去反原点任务中:</label>
                    <div class="form-input">
                        <input id="goOHpTask" name="goOHpTask" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">去原点避让位:</label>
                    <div class="form-input">
                        <input id="goHpAvoid" name="goHpAvoid" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">去反原点避让位:</label>
                    <div class="form-input">
                        <input id="goOHpAvoid" name="goOHpAvoid" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">入库取空结束:</label>
                    <div class="form-input">
                        <input id="pakInEmpty" name="pakInEmpty" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">入库正常结束:</label>
                    <div class="form-input">
                        <input id="pakInFinish" name="pakInFinish" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">出库取空结束:</label>
                    <div class="form-input">
                        <input id="pakOutEmpty" name="pakOutEmpty" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">出库正常结束:</label>
                    <div class="form-input">
                        <input id="pakOutFinish" name="pakOutFinish" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">去原点避让完成:</label>
                    <div class="form-input">
                        <input id="goHpAvoidFinish" name="goHpAvoidFinish" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">去反原点避让完成:</label>
                    <div class="form-input">
                        <input id="goOHpAvoidFinish" name="goOHpAvoidFinish" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">去原点避让完成:</label>
                    <div class="form-input">
                        <input id="goHpAvoidErr" name="goHpAvoidErr" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
                <div class="form-item">
                    <label class="form-label">去反原点避让完成:</label>
                    <div class="form-input">
                        <input id="goOHpAvoidErr" name="goOHpAvoidErr" class="layui-input" autocomplete="off" readonly>
                    </div>
                </div>
            </div>
            <div style="float:left;margin:  10px 10px 10px 10px; padding: 10px 10px 10px 10px;border: black;border-width: 3px;border-style:dotted">
                <div class="form-item" style="text-align: center">
                    <label>状态信息</label>
                </div>
<!--                <div class="form-item">-->
<!--                    <label class="form-label">联机模式:</label>-->
<!--                    <div class="form-input">-->
<!--                        <input id="autoMode" name="autoMode" class="layui-input" autocomplete="off" readonly>-->
<!--                    </div>-->
<!--                </div>-->
<!--                <div class="form-item">-->
<!--                    <label class="form-label">电压过低:</label>-->
<!--                    <div class="form-input">-->
<!--                        <input id="voltageLow" name="voltageLow" class="layui-input" autocomplete="off" readonly>-->
<!--                    </div>-->
<!--                </div>-->
            </div>
        </div>
    </div>
</body>
</html>
<script>
    // 空白行数
    var shuttleStateTableBlankRows = 0;
    var shuttleMsgTableBlankRows = 0;
    // 实际行数
    var shuttleStateTableFullRows = 0;
    var shuttleMsgTableFullRows = 0;
    // 初始化
    var shuttleOutputDom = document.getElementById("shuttle-output");
    $(document).ready(function() {
        initShuttleStateTable();
        getShuttleStateInfo();
        initShuttleMsgTable();
        getShuttleMsgInfo();
        operatorBlockShow();
        setShuttleRadio();
    });
    setInterval(function () {
        getShuttleStateInfo()
        getShuttleMsgInfo();
    },1000)
    setInterval(function () {
        getShuttleOutput();
        operatorBlockShow();
    },500);
    // 判断手动操作模块是否可用
    function operatorBlockShow() {
        if (parent.systemRunning) {
            $('.shuttle-operation').css("opacity", "0.5");
            $('.shuttle-operation-shade').show();
            $('.shuttle-operation-shade-span').show();
        }  else {
            $('.shuttle-operation').css("opacity", "1");
            $('.shuttle-operation-shade').hide();
            $('.shuttle-operation-shade-span').hide();
        }
    }
    var layerIdx;
    $(document).on('click ','.pos-btn', function () {
        let shuttleNo = Number($(this).parent().attr("data-shuttleNo"));
        layerIdx = layer.open({
            type: 1,
            title: false,
            shadeClose: true,
            offset: [$(this).offset().top + 30 + 'px', $(this).offset().left + 'px'],
            anim: 5,
            shade: [0],
            area: ['310px', '370px'],
            closeBtn: 0,
            content: $("#shuttle-detl"),
            success: function(layero, index){
                http.get(baseUrl+ "/shuttle/detl/"+shuttleNo, null, function (res) {
                    $('#shuttleNo').val(shuttleNo);
                    $('#workNo').val(res.data.workNo);
                    $('#row').val(res.data.row);
                    $('#bay').val(res.data.bay);
                    $('#lev').val(res.data.lev);
                    $('#crnNo').val(res.data.crnNo);
                    $('#pakMk').val(res.data.pakMk);
                })
            },
            end: function () {
                $('#shuttleNo').val("");
                $('#workNo').val("");
                $('#row').val("");
                $('#bay').val("");
                $('#lev').val("");
                $('#crnNo').val("");
                $('#pakMk').val("");
            }
        })
    })
    var layerIdx0;
    $(document).on('click ','.mode-btn', function () {
        let shuttleNo = Number($(this).parent().attr("data-shuttleNo"));
        layerIdx0 = layer.open({
            type: 1,
            title: false,
            shadeClose: true,
            offset: [$(this).offset().top + 30 + 'px', $(this).offset().left + 'px'],
            anim: 5,
            shade: [0],
            area: ['70%', '85%'],
            closeBtn: 0,
            content: $("#shuttle-detl2"),
            success: function(layero, index){
                console.log(shuttleNo)
                http.get(baseUrl+ "/shuttle/sensor/detl/"+shuttleNo, null, function (res) {
                    $('#shuttleNo1').val(res.data.shuttleNo);
                    // getColor(res.data.liftErr,'#liftErr');
                    // getColor(res.data.inFetchErr,'#inFetchErr');
                    // getColor(res.data.outFetchErr,'#outFetchErr');
                    // getColor(res.data.antiErr,'#antiErr');
                    // getColor(res.data.liftSwitchErr,'#liftSwitchErr');
                    // getColor(res.data.trackErr,'#trackErr');
                    // getColor(res.data.timeoutErr,'#timeoutErr');
                    // getColor(res.data.connectErr,'#connectErr');
                    // getColor(res.data.emergencyErr,'#emergencyErr');
                    // getColor(res.data.taskTypeErr,'#taskTypeErr');
                    // getColor(res.data.taskNoErr,'#taskNoErr');
                    // getColor(res.data.newTaskErr,'#newTaskErr');
                    // getColor(res.data.errTaskErr,'#errTaskErr');
                    // getColor(res.data.stopErr,'#stopErr');
                    // getColor(res.data.offlineTaskErr,'#offlineTaskErr');
                    // getColor(res.data.startTaskErr,'#startTaskErr');
                    // getColor(res.data.voltageTaskErr,'#voltageTaskErr');
                    // getColor(res.data.devpErr,'#devpErr');
                    // getColor(res.data.online,'#online');
                    // getColor(res.data.notOnTrack,'#notOnTrack');
                    // getColor(res.data.lowVoltage,'#lowVoltage');
                    // getColor(res.data.electricityLoss,'#electricityLoss');
                    // getColor(res.data.forcedTravel,'#forcedTravel');
                    // getColor(res.data.demoMode,'#demoMode');
                    // getColor(res.data.brushConnect,'#brushConnect');
                    // getColor(res.data.taskManualForbid,'#taskManualForbid');
                    // getColor(res.data.onlineManualForbid,'#onlineManualForbid');
                    // getColor(res.data.devpEmergency,'#devpEmergency');
                    // getColor(res.data.taskInterrupt,'#taskInterrupt');
                    // getColor(res.data.taskClear,'#taskClear');
                    // getColor(res.data.taskConfirmTimeout,'#taskConfirmTimeout');
                    // getColor(res.data.taskWithCharge,'#taskWithCharge');
                    getColor(res.data.pakInTask,'#pakInTask');
                    getColor(res.data.pakOutTask,'#pakOutTask');
                    getColor(res.data.pakMoveTask,'#pakMoveTask');
                    getColor(res.data.goHpTask,'#goHpTask');
                    getColor(res.data.goOHpTask,'#goOHpTask');
                    getColor(res.data.goHpAvoid,'#goHpAvoid');
                    getColor(res.data.goOHpAvoid,'#goOHpAvoid');
                    getColor(res.data.pakInEmpty,'#pakInEmpty');
                    getColor(res.data.pakInFinish,'#pakInFinish');
                    getColor(res.data.pakOutEmpty,'#pakOutEmpty');
                    getColor(res.data.pakOutFinish,'#pakOutFinish');
                    getColor(res.data.goHpAvoidFinish,'#goHpAvoidFinish');
                    getColor(res.data.goOHpAvoidFinish,'#goOHpAvoidFinish');
                    getColor(res.data.goHpAvoidErr,'#goHpAvoidErr');
                    getColor(res.data.goOHpAvoidErr,'#goOHpAvoidErr');
                    // getColor(res.data.autoMode,'#autoMode');
                    // getColor(res.data.voltageLow,'#voltageLow');
                })
            },
            end: function () {
                $('#shuttleNo').val("");
            }
        })
    })
    function getColor(res,e){
        $(e).val(res?"✔":"—");
        if (res){
            $(e).attr("style", "color: #FD482C;");
        }else {
            $(e).attr("style", "color: #00FF00;");
        }
    }
    // $(document).on('click ','.mode-btn', function () {
    //     let shuttleNo = Number($(this).parent().attr("data-shuttleNo"));
    //     layer.confirm("改变" + shuttleNo + ' 号穿梭车在线状态吗?', function(){
    //         var index = layer.load(1, {
    //             shade: [0.1,'#fff']
    //         });
    //         $.ajax({
    //             url: baseUrl+ "/shuttle/mode/switch",
    //             headers: {'token': localStorage.getItem('token')},
    //             data: {
    //                 shuttleNo: Number(shuttleNo),
    //                 password: 'root'
    //             },
    //             method: 'POST',
    //             success: function (res) {
    //                 layer.close(index);
    //                 if (res.code === 200){
    //                     layer.msg(res.msg, {icon: 1});
    //                 } else if (res.code === 403){
    //                     window.location.href = baseUrl+"/login";
    //                 }  else {
    //                     layer.msg(res.msg, {icon: 2});
    //                 }
    //             }
    //         });
    //     });
    // })
    $(document).on('click ','#save', function () {
        http.post(baseUrl+ "/shuttle/detl/update", {
            shuttleNo: $('#shuttleNo').val(),
            workNo: $('#workNo').val(),
            row:  $('#row').val(),
            bay: $('#bay').val(),
            lev:  $('#lev').val(),
            crnNo: $('#crnNo').val(),
            pakMk: $('#pakMk').val(),
        }, function (res) {
            layer.msg("修改成功", {icon: 1,});
            layer.close(layerIdx);
        })
    })
    $(document).on('click ','#cancel', function () {
        layer.close(layerIdx);
    })
    function setShuttleRadio() {
        $.ajax({
            url: baseUrl+ "/shuttle/table/shuttle/state",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    let table = res.data;
                    for (let i=1;i<=table.length;i++){
                        //渲染四向穿梭车选项html
                        let shuttleRadioBox = '<label><input type="radio" name="shuttleSelect" ';
                        if (i === 1) {
                            shuttleRadioBox += 'checked '
                        }
                        shuttleRadioBox += 'value="' + table[i - 1].shuttleNo + '">&nbsp;' + table[i - 1].shuttleNo + '号穿梭车</label>'
                        $("#shuttleRadioBoxId").append(shuttleRadioBox)
                        //渲染四向穿梭车数据维护和设备信息html
                        let shuttleCommandLogBox = '<div class="shuttle-command-item" data-shuttleNo="' + table[i - 1].shuttleNo + '">\n' +
                            '<label>' + table[i - 1].shuttleNo + '#</label>\n' +
                            '<button class="demoBtn pos-btn">数据维护</button>\n' +
                            '<button class="demoBtn mode-btn" id="mode-' + table[i - 1].shuttleNo + '">设备信息</button>\n' +
                            '</div>'
                        $("#commandLogId").append(shuttleCommandLogBox);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 四向穿梭车信息表获取 ---- 表一
    function getShuttleStateInfo() {
        let tableEl = $('#shuttle-state-table');
        $.ajax({
            url: baseUrl+ "/shuttle/table/shuttle/state",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    let table = res.data;
                    if (table.length > shuttleStateTableBlankRows && table.length !== shuttleStateTableFullRows) {
                        initShuttleStateTable(table.length-shuttleStateTableBlankRows);
                        shuttleStateTableFullRows = table.length;
                    }
                    for (let i=1;i<=table.length;i++){
                        // $("#mode-"+table[i-1].shuttleNo).html(table[i-1].statusVal===0?'联机':'脱机');
                        let tr = tableEl.find("tr").eq(i);
                        setVal(tr.children("td").eq(0), table[i-1].shuttleNo);
                        setVal(tr.children("td").eq(1), table[i-1].status);
                        setVal(tr.children("td").eq(2), table[i-1].status);
                        setVal(tr.children("td").eq(3), table[i-1].loading);
                        setVal(tr.children("td").eq(4), table[i-1].track);
                        setVal(tr.children("td").eq(5), table[i-1].batteryPower);
                        setVal(tr.children("td").eq(6), table[i-1].row);
                        setVal(tr.children("td").eq(7), table[i-1].bay);
                        setVal(tr.children("td").eq(8), table[i-1].lev);
                        setVal(tr.children("td").eq(9), table[i-1].waiting);
                        setVal(tr.children("td").eq(10), table[i-1].loca);
                        setVal(tr.children("td").eq(11), table[i-1].chargeStatus);
                        setVal(tr.children("td").eq(12), table[i-1].alarm1);
                        setVal(tr.children("td").eq(13), table[i-1].alarm2);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 四向穿梭车数据表获取 ---- 表二
    function getShuttleMsgInfo() {
        let tableEl = $('#shuttle-msg-table');
        $.ajax({
            url: baseUrl+ "/shuttle/table/shuttle/msg",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    var table = res.data;
                    if (table.length > shuttleMsgTableBlankRows && table.length !== shuttleMsgTableFullRows) {
                        initShuttleMsgTable(table.length-shuttleMsgTableBlankRows);
                        shuttleMsgTableFullRows = table.length;
                    }
                    for (var i=1;i<=table.length;i++){
                        var tr = tableEl.find("tr").eq(i);
                        setVal(tr.children("td").eq(0), table[i-1].shuttleNo);
                        setVal(tr.children("td").eq(1), table[i-1].workNo);
                        setVal(tr.children("td").eq(2), table[i-1].status);
                        setVal(tr.children("td").eq(3), table[i-1].sourceStaNo);
                        setVal(tr.children("td").eq(4), table[i-1].staNo);
                        setVal(tr.children("td").eq(5), table[i-1].sourceLocNo);
                        setVal(tr.children("td").eq(6), table[i-1].locNo);
                        setVal(tr.children("td").eq(7), table[i-1].speed);
                        setVal(tr.children("td").eq(8), table[i-1].pakMk);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 穿梭车日志输出 -----------------------------------------------------------------------
    function getShuttleOutput() {
        $.ajax({
            url: baseUrl + "/shuttle/output/shuttle",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200) {
                    shuttleOutput(res.data);
                } else if (res.code === 403) {
                    window.location.href = baseUrl + "/login";
                } else {
                    console.log(res.msg);
                }
            }
        })
    }
    // 任务指令下发
    function shuttleOperator(shuttleTaskMode) {
        http.post(baseUrl+"/shuttle/operator/shuttle", {
            shuttleNo: $('input[name="shuttleSelect"]:checked').val(),
            shuttleTaskMode: shuttleTaskMode
        }, function (res) {
            layer.msg(res.msg, {icon: 1});
        });
    }
    // ------------------------------------------------------------------------------------------------
    // 四向穿梭车信息表获取  ----- 表一
    function initShuttleStateTable(row) {
        let line;
        if (row === undefined){
            let one = $('#shuttle-state-table thead').height();
            let total = $('.shuttle-state').height();
            let count = total / one;
            count = parseInt(count) - 1;
            shuttleStateTableBlankRows = count;
            line = count;
        } else {
            line = row;
        }
        let html = "";
        for (let i = 0; i < line; i ++){
            html += " <tr>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "     </tr>\n";
        }
        $('#shuttle-state-table tbody').after(html);
    }
    // 穿梭车数据表获取  ----- 表二
    function initShuttleMsgTable(row) {
        let line;
        if (row === undefined){
            let one = $('#shuttle-msg-table thead').height();
            let total = $('.shuttle-msg').height();
            let count = total / one;
            count = parseInt(count) - 1;
            shuttleMsgTableBlankRows = count;
            line = count;
        } else {
            line = row;
        }
        let html = "";
        for (let i = 0; i < line; i ++){
            html += " <tr>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "     </tr>\n";
        }
        $('#shuttle-msg-table tbody').after(html);
    }
    // 日志输出框
    function shuttleOutput(content){
        shuttleOutputDom.value += content;
        shuttleOutputDom.scrollTop = shuttleOutputDom.scrollHeight;
    }
</script>