自动化立体仓库 - WCS系统
#
luxiaotao1123
2022-08-25 9ee93c74e0de265b8a55454c621147b036fb0930
#
3个文件已添加
1个文件已删除
7个文件已修改
495 ■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/CarController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/SteController.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/SteMsgTableVo.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/SteStateTableVo.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/ServerBootstrap.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/OutputQueue.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/SteStatusType.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/SteProtocol.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/SteThread.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/ste.html 114 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/CarController.java
File was deleted
src/main/java/com/zy/asrs/controller/SteController.java
New file
@@ -0,0 +1,146 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.annotations.ManagerAuth;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.domain.enums.CrnStatusType;
import com.zy.asrs.domain.vo.SteMsgTableVo;
import com.zy.asrs.domain.vo.SteStateTableVo;
import com.zy.asrs.entity.BasSte;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.service.BasSteService;
import com.zy.asrs.service.WrkMastService;
import com.zy.core.cache.OutputQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.protocol.SteProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.SteThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
 * 穿梭车接口
 * Created by vincent on 2022/3/14
 */
@Slf4j
@RestController
@RequestMapping("/ste")
public class SteController {
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private BasSteService basSteService;
    @Autowired
    private WrkMastService wrkMastService;
    @PostMapping("/table/ste/state")
    @ManagerAuth(memo = "穿梭车信息表")
    public R steStateTable(){
        List<SteStateTableVo> list = new ArrayList<>();
        List<BasSte> stes = basSteService.selectList(new EntityWrapper<BasSte>().orderBy("ste_no"));
        for (BasSte basSte : stes) {
            // 表格行
            SteStateTableVo vo = new SteStateTableVo();
            vo.setSteNo(basSte.getSteNo());   //  穿梭车号
            list.add(vo);
            // 获取穿梭车信息
            SteThread steThread = (SteThread) SlaveConnection.get(SlaveType.Ste, basSte.getSteNo());
            if (steThread == null) {
                continue;
            }
            SteProtocol steProtocol = steThread.getSteProtocol();
            if (steProtocol == null) {
                continue;
            }
            vo.setTaskNo(steProtocol.getTaskNo());  //  任务号
            vo.setStatusType(steProtocol.mode == 0 ? "离线" : "在线");   //  模式状态
            if (!Cools.isEmpty(steProtocol.getStatus())) {
                vo.setStatus(steProtocol.getStatusType().desc);     //  状态
            }
            if (!Cools.isEmpty(steProtocol.getLoad())) {
                vo.setLoading(steProtocol.getLoad()==1?"✔":"×");  //  有物
            }
            if (!Cools.isEmpty(steProtocol.getWaiting())) {
                vo.setWaiting(steProtocol.getWaiting()?"✔":"×");
            }
            vo.setRow(steProtocol.getRow());
            vo.setBay(steProtocol.getBay());
            vo.setLev(steProtocol.getLev());
            vo.setCharge(steProtocol.getCharge() + "%");
            if (!Cools.isEmpty(steProtocol.getLoca())) {
                vo.setLoca(steProtocol.getLocaType().desc);
            }
            vo.setSpeed(steProtocol.getSpeed());
            vo.setCloser(steProtocol.getCloser());
            if (!Cools.isEmpty(steProtocol.getPos())) {
                vo.setPos(steProtocol.getPos()==0?"低位":"高位");
            }
            if (!Cools.isEmpty(steProtocol.getTrack())) {
                vo.setTrack(steProtocol.getTrack()==0?"✔":"×");
            }
        }
        return R.ok().add(list);
    }
    @PostMapping("/table/ste/msg")
    @ManagerAuth(memo = "穿梭车数据表")
    public R steMsgTable(){
        List<SteMsgTableVo> list = new ArrayList<>();
        List<BasSte> stes = basSteService.selectList(new EntityWrapper<BasSte>().orderBy("ste_no"));
        for (BasSte basSte : stes) {
            // 表格行
            SteMsgTableVo vo = new SteMsgTableVo();
            vo.setSteNo(basSte.getSteNo());   //  穿梭车号
            list.add(vo);
            // 获取穿梭车信息
            SteThread steThread = (SteThread) SlaveConnection.get(SlaveType.Ste, basSte.getSteNo());
            if (steThread == null) {
                continue;
            }
            SteProtocol steProtocol = steThread.getSteProtocol();
            if (steProtocol == null) {
                continue;
            }
            vo.setWorkNo(steProtocol.getTaskNo());  //  任务号
            if (steProtocol.getTaskNo() > 0) {
                WrkMast wrkMast = wrkMastService.selectById(steProtocol.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());    //  目标库位
                }
            } else {
                vo.setStatus(steProtocol.mode == 1? CrnStatusType.MACHINE_AUTO.getDesc(): CrnStatusType.MACHINE_UN_AUTO.getDesc());   //  模式状态
            }
            vo.setSpeed(steProtocol.getSpeed());  // 速度
            vo.setCloser(steProtocol.getCloser());  // 近点距离
        }
        return R.ok().add(list);
    }
    @PostMapping("/output/ste")
    @ManagerAuth
    public R steOutput(){
        StringBuilder str = new StringBuilder();
        String s;
        int i = 0;
        while((s = OutputQueue.STE.poll()) != null && i <=10) {
            str.append("\n").append(s);
            i++;
        }
        return R.ok().add(str.toString());
    }
}
src/main/java/com/zy/asrs/domain/vo/SteMsgTableVo.java
New file
@@ -0,0 +1,48 @@
package com.zy.asrs.domain.vo;
import lombok.Data;
/**
 * Created by vincent on 2020-06-02
 */
@Data
public class SteMsgTableVo {
    // 穿梭车号
    private Integer steNo;
    // 工作号
    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;
    // 近点距离
    public Double closer = 0.0D;
}
src/main/java/com/zy/asrs/domain/vo/SteStateTableVo.java
New file
@@ -0,0 +1,84 @@
package com.zy.asrs.domain.vo;
import lombok.Data;
/**
 * Created by vincent on 2020-06-02
 */
@Data
public class SteStateTableVo {
    // 穿梭车号
    private Integer steNo;
    // 模式
    private String statusType = "-";
    // 状态
    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 charge = "-";
    /**
     * 电池馈电
     */
    public String feed = "-";
    /**
     * 当前位置     1,近点,2远点,3A点,4B点
     */
    public String loca = "-";
    /**
     * 近点距离
     */
    public Double closer;
    /**
     * 当前速度
     */
    public Double speed;
    /**
     * 高低位 0,低位,1高位
     */
    public String pos = "-";
    /**
     * 在轨道上 0不在,1在
     */
    public String track = "-";
}
src/main/java/com/zy/core/ServerBootstrap.java
@@ -87,7 +87,7 @@
        log.info("初始化穿梭车线程...................................................");
        for (SteSlave crn : slaveProperties.getSte()) {
            SteThread steThread = new SteThread(crn);
            new Thread((Runnable) steThread).start();
            new Thread(steThread).start();
            SlaveConnection.put(SlaveType.Ste, crn.getId(), steThread);
        }
        // 初始化输送线线程
src/main/java/com/zy/core/cache/OutputQueue.java
@@ -15,4 +15,7 @@
    public static ArrayBlockingQueue<String> DEVP = new ArrayBlockingQueue<>(32);
    // 条码器输出日志
    public static ArrayBlockingQueue<JSONObject> BARCODE = new ArrayBlockingQueue<>(32);
    // 穿梭车输出日志
    public static ArrayBlockingQueue<String> STE = new ArrayBlockingQueue<>(32);
}
src/main/java/com/zy/core/enums/SteStatusType.java
@@ -5,7 +5,7 @@
    IDLE(0, "空闲"),
    MOVING(1, "作业中"),
    SOS(2, "报警"),
    OFF_LINE(-1, "离线"),
    OFF_LINE(-1, "未知"),
    ;
    public Integer id;
src/main/java/com/zy/core/model/protocol/SteProtocol.java
@@ -34,6 +34,11 @@
    public SteStatusType statusType;
    /**
     * 任务号
     */
    public Integer taskNo = 0;
    /**
     * 正在执行任务
     */
    public Boolean execute;
@@ -58,7 +63,7 @@
    /**
     * 电池电量
     */
    public Float charge;
    public Float charge = 0.0F;
    /**
     * 满电
@@ -75,7 +80,6 @@
     */
    public Short feed;
    /**
     * 当前位置     1,近点,2远点,3A点,4B点
     */
@@ -91,7 +95,7 @@
    /**
     * 当前速度
     */
    public Double speed;
    public Double speed = 0.0D;
    /**
     * 高低位 0,低位,1高位
@@ -107,11 +111,6 @@
     * 在轨道上 0不在,1在
     */
    public Short track;
    /**
     * 任务号
     */
    public Integer taskNo = 0;
    /**
     * 任务类型
src/main/java/com/zy/core/thread/SteThread.java
@@ -108,10 +108,10 @@
        OperateResult connect = siemensS7Net.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()));
            OutputQueue.STE.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()));
            OutputQueue.STE.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());
            initSte();
        }
@@ -169,7 +169,7 @@
                steProtocol.setCrnStopFork(siemensS7Net.getByteTransform().TransInt16(result.Content, 40));
                steProtocol.setCrnAllowRun(siemensS7Net.getByteTransform().TransInt16(result.Content, 42));
                OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
                OutputQueue.STE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
                // 复位信号
                if (steProtocol.getWaiting()) {
@@ -194,12 +194,12 @@
                }
            } else {
                OutputQueue.CRN.offer(MessageFormat.format("【{0}】{1}穿梭车plc状态信息失败",DateUtils.convert(new Date()), slave.getId()));
                OutputQueue.STE.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) {
            e.printStackTrace();
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取穿梭车plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            OutputQueue.STE.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());
            initSte();
        }
@@ -296,10 +296,10 @@
            }
            log.info("穿梭车命令下发[id:{}] >>>>> {}", slave.getId(), JSON.toJSON(command));
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            OutputQueue.STE.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
            return true;
        } else {
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入穿梭车plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
            OutputQueue.STE.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());
            return false;
        }
src/main/resources/application.yml
@@ -75,22 +75,20 @@
    port: 502
    rack: 0
    slot: 0
    # 偏移量,当堆垛机站点列号=1时,偏移量=2
    demo: false
    # 穿梭车入库站点
    steInStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 100
      row: 2
      bay: 1
      lev: 1
    # 穿梭车出库站点
    steOutStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 101
      row: 3
      bay: 1
      lev: 1
  # 穿梭车2
  ste[1]:
    id: 2
    ip: 10.10.10.11
    port: 502
    rack: 0
    slot: 0
  # 穿梭车3
  ste[2]:
    id: 3
    ip: 10.10.10.12
    port: 502
    rack: 0
    slot: 0
  # 输送线
  devp[0]:
    id: 1
src/main/webapp/views/ste.html
@@ -96,9 +96,8 @@
                                <th>排</th>
                                <th>列</th>
                                <th>层</th>
                                <th>货叉定位</th>
                                <th>载货台定位</th>
                                <th>走行在定位</th>
                                <th>等待WCS确认</th>
                                <th>定位</th>
                                <th>报警信息1</th>
                                <th>报警信息2</th>
                            </tr>
@@ -114,20 +113,14 @@
                    <thead>
                        <tr>
                            <th>穿梭车</th>
                            <th>任务号</th>
                            <th>任务类型</th>
                            <th>当前位置</th>
                            <th>工作号</th>
                            <th>状态</th>
                            <th>源站</th>
                            <th>目标站</th>
                            <th>源库位</th>
                            <th>目标库位</th>
                            <th>速度</th>
                            <th>近点距离</th>
                            <th>当前速度</th>
                            <th>高低位</th>
                            <th>过账指令任务号</th>
                            <th>过账指令状态</th>
                            <th>盘点数量</th>
                            <th>穿梭板就绪</th>
                            <th>充电桩号</th>
                            <th>堆垛机运行</th>
                            <th>堆垛机伸叉</th>
                            <th>堆垛机搬移</th>
                        </tr>
                    </thead>
                    <tbody>
@@ -218,7 +211,12 @@
    setInterval(function () {
        getSteStateInfo()
        getSteMsgInfo();
    },1000)
    setInterval(function () {
        getSteOutput();
        operatorBlockShow();
    },500);
    // 判断手动操作模块是否可用
    function operatorBlockShow() {
@@ -240,12 +238,94 @@
    // 穿梭车信息表获取 ---- 表一
    function getSteStateInfo() {
        let tableEl = $('ste-state-table');
        let tableEl = $('#ste-state-table');
        $.ajax({
            url: baseUrl+ "/ste/table/ste/state",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    let table = res.data;
                    if (table.length > steStateTableBlankRows && table.length !== steStateTableFullRows) {
                        initSteStateTable(table.length-steStateTableBlankRows);
                        steStateTableFullRows = table.length;
                    }
                    for (let i=1;i<=table.length;i++){
                        let tr = tableEl.find("tr").eq(i);
                        setVal(tr.children("td").eq(0), table[i-1].steNo);
                        setVal(tr.children("td").eq(1), table[i-1].statusType);
                        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].charge);
                        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].alarm1);
                        setVal(tr.children("td").eq(12), table[i-1].alarm2);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 穿梭车数据表获取 ---- 表二
    function getSteMsgInfo() {
        let tableEl = $('#ste-msg-table');
        $.ajax({
            url: baseUrl+ "/ste/table/ste/msg",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200){
                    var table = res.data;
                    if (table.length > steMsgTableBlankRows && table.length !== steMsgTableFullRows) {
                        initSteMsgTable(table.length-steMsgTableBlankRows);
                        steMsgTableFullRows = 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].steNo);
                        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].closer);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    console.log(res.msg);
                }
            }
        });
    }
    // 穿梭车日志输出 -----------------------------------------------------------------------
    function getSteOutput() {
        $.ajax({
            url: baseUrl + "/ste/output/ste",
            headers: {'token': localStorage.getItem('token')},
            method: 'POST',
            success: function (res) {
                if (res.code === 200) {
                    steOutput(res.data);
                } else if (res.code === 403) {
                    window.location.href = baseUrl + "/login";
                } else {
                    console.log(res.msg);
                }
            }
        })
    }
    // ------------------------------------------------------------------------------------------------