自动化立体仓库 - WCS系统
luxiaotao1123
2020-09-08 28a7821e43bd5763739fe67384cfea6693b3500b
Merge branches 'gdwcs' and 'jswcs' of https://gitee.com/luxiaotao1123/zy-wcs into jswcs

 Conflicts:
 src/main/webapp/views/console.html
8个文件已添加
1 文件已重命名
32个文件已修改
2367 ■■■■ 已修改文件
pom.xml 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/Boot.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/ConsoleController.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/CrnController.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/SiteController.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/enums/CrnStatusType.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/CrnMsgTableVo.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/CrnStateTableVo.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/domain/vo/SiteTableVo.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/WrkMastMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/WrkDetlService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java 249 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/WrkDetlServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/Utils.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/model/MatDto.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/service/CommonService.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/utils/CollectionUtils.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/MainProcess.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/ServerBootstrap.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/cache/MessageQueue.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/enums/CrnStatusType.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/CrnSlave.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/LedSlave.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/command/LedCommand.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/CrnError1.java 63 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/CrnProtocol.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/CrnTemp1.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/protocol/StaProtocol.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/properties/SlaveProperties.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/CrnThread.java 267 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/DevpThread.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/LedThread.java 355 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 99 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/lib/slf4j-api-1.7.30.jar 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/lib/slf4j-simple-1.7.30.jar 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkMastMapper.xml 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/css/console.css 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/common.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/console.html 241 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/crn.html 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/pipeline.html 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -103,10 +103,89 @@
            <artifactId>okhttp</artifactId>
            <version>3.10.0</version>
        </dependency>
        <!-- led sdk -->
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>5m3</artifactId>
            <scope>system</scope>
            <version>0.5.0</version>
            <systemPath>${project.basedir}/src/main/resources/lib/bx05-0.5.0-SNAPSHOT.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>5m3message</artifactId>
            <scope>system</scope>
            <version>0.5.0</version>
            <systemPath>${project.basedir}/src/main/resources/lib/bx05.message-0.5.0-SNAPSHOT.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>5m3doc</artifactId>
            <scope>system</scope>
            <version>0.5.0</version>
            <systemPath>${project.basedir}/src/main/resources/lib/bx05-0.5.0-SNAPSHOT-javadoc.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>rxtx</artifactId>
            <scope>system</scope>
            <version>2.1.7</version>
            <systemPath>${project.basedir}/src/main/resources/lib/rxtx-2.1.7.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>simple-xml</artifactId>
            <scope>system</scope>
            <version>2.7.1</version>
            <systemPath>${project.basedir}/src/main/resources/lib/simple-xml-2.7.1.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>stax</artifactId>
            <scope>system</scope>
            <version>1.2.0</version>
            <systemPath>${project.basedir}/src/main/resources/lib/stax-1.2.0.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>stax-api</artifactId>
            <scope>system</scope>
            <version>1.0.1</version>
            <systemPath>${project.basedir}/src/main/resources/lib/stax-api-1.0.1.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>uia-comm</artifactId>
            <scope>system</scope>
            <version>0.5.1</version>
            <systemPath>${project.basedir}/src/main/resources/lib/uia-comm-0.5.1.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>uia-message</artifactId>
            <scope>system</scope>
            <version>0.6.0</version>
            <systemPath>${project.basedir}/src/main/resources/lib/uia-message-0.6.0.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>uia-utils</artifactId>
            <scope>system</scope>
            <version>0.2.0</version>
            <systemPath>${project.basedir}/src/main/resources/lib/uia-utils-0.2.0.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.wcs.led</groupId>
            <artifactId>xpp3</artifactId>
            <scope>system</scope>
            <version>1.1.3.3</version>
            <systemPath>${project.basedir}/src/main/resources/lib/xpp3-1.1.3.3.jar</systemPath>
        </dependency>
    </dependencies>
    <build>
        <finalName>jswcs</finalName>
        <finalName>gdwcs</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
src/main/java/com/zy/Boot.java
@@ -1,8 +1,6 @@
package com.zy;
import com.core.common.SpringUtils;
import com.zy.common.utils.RandomValidateCodeUtil;
import com.zy.core.ServerBootstrap;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@@ -15,10 +13,10 @@
    public static void main(String[] args) {
        RandomValidateCodeUtil.init();
        SpringApplication.run(Boot.class, args);
        new Thread(()-> {
            ServerBootstrap serverBootstrap = SpringUtils.getBean(ServerBootstrap.class);
            serverBootstrap.init();
        }).start();
//        new Thread(()-> {
//            ServerBootstrap serverBootstrap = SpringUtils.getBean(ServerBootstrap.class);
//            serverBootstrap.init();
//        }).start();
    }
src/main/java/com/zy/asrs/controller/ConsoleController.java
@@ -73,7 +73,7 @@
                return R.error("口令错误");
            }
        }
        Thread.sleep(2000L);
        Thread.sleep(200L);
        SystemProperties.WCS_RUNNING_STATUS.set(param.getOperatorType()==1?Boolean.TRUE:Boolean.FALSE);
        return R.ok().add(Cools.add("status", SystemProperties.WCS_RUNNING_STATUS.get()));
    }
@@ -112,12 +112,10 @@
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            if (crnThread == null) {
                log.error("{}号堆垛机连接失败", crn.getId());
                continue;
            }
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                log.error("{}号堆垛机连接失败", crn.getId());
                continue;
            }
            CrnLatestDataVo vo = new CrnLatestDataVo();
@@ -126,17 +124,23 @@
//            Short totalBay = locMastMapper.selectTotalBay();
            vo.setOffset((double) new Random().nextInt(560));     //  堆垛机偏移量
            vo.setBay(crnProtocol.getBay());    //  当前列
            vo.setBay((short) (crnProtocol.getBay() - crn.getOffset()));    //  当前列
            /**
             * 堆垛机状态判断
             */
            if (crnProtocol.getTaskNo()>0) {
                WrkMast wrkMast = wrkMastService.selectById(crnProtocol.getTaskNo());
                if (wrkMast != null) {
                    vo.setCrnStatus(CrnStatusType.process(wrkMast.getIoType()));
                }
            if (crnProtocol.getAlarm() > 0) {
                vo.setCrnStatus(CrnStatusType.MACHINE_ERROR);
            } else {
                vo.setCrnStatus(crnProtocol.modeType.equals(CrnModeType.AUTO)? CrnStatusType.MACHINE_AUTO: CrnStatusType.MACHINE_UN_AUTO);
                if (crnProtocol.getTaskNo()>0) {
                    WrkMast wrkMast = wrkMastService.selectById(crnProtocol.getTaskNo());
                    if (wrkMast != null) {
                        vo.setCrnStatus(CrnStatusType.process(wrkMast.getIoType()));
                    } else {
                        vo.setCrnStatus(crnProtocol.modeType.equals(CrnModeType.AUTO)? CrnStatusType.MACHINE_AUTO: CrnStatusType.MACHINE_UN_AUTO);
                    }
                } else {
                    vo.setCrnStatus(crnProtocol.modeType.equals(CrnModeType.AUTO)? CrnStatusType.MACHINE_AUTO: CrnStatusType.MACHINE_UN_AUTO);
                }
            }
            vos.add(vo);
@@ -150,6 +154,9 @@
        List<BarcodeDataVo> list = new ArrayList<>();
        for (Slave barcode : slaveProperties.getBarcode()) {
            BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, barcode.getId());
            if (null == barcodeThread) {
                continue;
            }
            BarcodeDataVo vo = new BarcodeDataVo();
            vo.setBarcodeId(barcode.getId());
            vo.setCodeValue(barcodeThread.getBarcode());
src/main/java/com/zy/asrs/controller/CrnController.java
@@ -1,6 +1,7 @@
package com.zy.asrs.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.annotations.ManagerAuth;
import com.core.common.R;
import com.core.exception.CoolException;
@@ -10,12 +11,15 @@
import com.zy.asrs.domain.vo.CrnMsgTableVo;
import com.zy.asrs.domain.vo.CrnStateTableVo;
import com.zy.asrs.entity.BasCrnError;
import com.zy.asrs.entity.BasCrnp;
import com.zy.asrs.entity.WrkMast;
import com.zy.asrs.mapper.BasCrnErrorMapper;
import com.zy.asrs.service.BasCrnpService;
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.CrnLiftPosType;
import com.zy.core.enums.CrnModeType;
import com.zy.core.enums.CrnTaskModeType;
import com.zy.core.enums.SlaveType;
@@ -49,6 +53,8 @@
    private WrkMastService wrkMastService;
    @Autowired
    private BasCrnErrorMapper basCrnErrorMapper;
    @Autowired
    private BasCrnpService basCrnpService;
    @ManagerAuth(memo = "进行中的命令")
@@ -82,21 +88,21 @@
    @ManagerAuth(memo = "堆垛机信息表")
    public R crnStateTable(){
        List<CrnStateTableVo> list = new ArrayList<>();
        for (CrnSlave crn : slaveProperties.getCrn()) {
        List<BasCrnp> crnps = basCrnpService.selectList(new EntityWrapper<BasCrnp>().orderBy("crn_no"));
        for (BasCrnp basCrnp : crnps) {
            // 表格行
            CrnStateTableVo vo = new CrnStateTableVo();
            vo.setCrnNo(basCrnp.getCrnNo());   //  堆垛机号
            list.add(vo);
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
            if (crnThread == null) {
                log.error("{}号堆垛机连接失败", crn.getId());
                continue;
            }
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) {
                log.error("{}号堆垛机连接失败", crn.getId());
                continue;
            }
            // 表格行
            CrnStateTableVo vo = new CrnStateTableVo();
            vo.setCrnNo(crn.getId());   //  堆垛机号
            vo.setWorkNo(crnProtocol.getTaskNo());  //  任务号
            if (crnProtocol.getTaskNo()>0) {
                WrkMast wrkMast = wrkMastService.selectById(crnProtocol.getTaskNo());
@@ -107,14 +113,16 @@
                vo.setStatusType(crnProtocol.modeType.equals(CrnModeType.AUTO)? CrnStatusType.MACHINE_AUTO.getDesc(): CrnStatusType.MACHINE_UN_AUTO.getDesc());   //  模式状态
            }
            vo.setStatus(crnProtocol.getStatusType().desc);     //  状态
            vo.setWarn(""); //  报警 todo
            vo.setLoading(crnProtocol.getLoaded()==1?"Y":"N");  //  有物
            vo.setLoading(crnProtocol.getLoaded()==1?"有物":"无物");  //  有物
            vo.setBay(crnProtocol.getBay());    //  列
            vo.setLev(crnProtocol.getLevel());  //  层
            vo.setForkOffset(crnProtocol.getForkPosType().desc);    //  货叉位置
            vo.setLiftPos(crnProtocol.getLiftPosType().desc);   //  载货台位置
            vo.setWorkNo(crnProtocol.getAlarm1());  //  异常码
            list.add(vo);
            vo.setXOrigin(crnProtocol.getBay()==1?"是":"否");     //  走行原点
            vo.setYOrigin(crnProtocol.getLevel()==1?"是":"否");     // 升降原点
            vo.setForkOffset(crnProtocol.getForkPosType().desc);    // 货叉位置
            vo.setXLocation(crnProtocol.getWalkPos() == 1?"是":"否");      // 走行定位
            vo.setYLocation(crnProtocol.getLiftPosType().equals(CrnLiftPosType.NONE)?"否":"是");      // 升降定位
            vo.setStop(crnProtocol.getCrnTemp1().stop?"是":"否");       //  急停
            vo.setWarnCode(String.valueOf(crnProtocol.getAlarm()));  //  异常码
        }
        return R.ok().add(list);
    }
@@ -123,9 +131,14 @@
    @ManagerAuth(memo = "堆垛机数据表")
    public R crnMsgTable(){
        List<CrnMsgTableVo> list = new ArrayList<>();
        for (CrnSlave crn : slaveProperties.getCrn()) {
        List<BasCrnp> crnps = basCrnpService.selectList(new EntityWrapper<BasCrnp>().orderBy("crn_no"));
        for (BasCrnp basCrnp : crnps) {
            // 表格行
            CrnMsgTableVo vo = new CrnMsgTableVo();
            vo.setCrnNo(basCrnp.getCrnNo());   //  堆垛机号
            list.add(vo);
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, basCrnp.getCrnNo());
            if (crnThread == null) {
                continue;
            }
@@ -133,13 +146,11 @@
            if (crnProtocol == null) {
                continue;
            }
            // 表格行
            CrnMsgTableVo vo = new CrnMsgTableVo();
            vo.setCrnNo(crn.getId());   //  堆垛机号
            vo.setWorkNo(crnProtocol.getTaskNo());  //  任务号
            BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm1());
            BasCrnError crnError = basCrnErrorMapper.selectById(crnProtocol.getAlarm());
            if (null != crnError) {
                vo.setError(crnError.getErrorCode() + crnError.getErrName());
                vo.setError(crnError.getErrName());
            }
            if (crnProtocol.getTaskNo()>0) {
                WrkMast wrkMast = wrkMastService.selectById(crnProtocol.getTaskNo());
@@ -153,8 +164,13 @@
            } else {
                vo.setStatus(crnProtocol.modeType.equals(CrnModeType.AUTO)? CrnStatusType.MACHINE_AUTO.getDesc(): CrnStatusType.MACHINE_UN_AUTO.getDesc());   //  模式状态
            }
            list.add(vo);
            vo.setXspeed(crnProtocol.getXSpeed());  //  走行速度(m/min)
            vo.setYspeed(crnProtocol.getYSpeed());  //  升降速度(m/min)
            vo.setZspeed(crnProtocol.getZSpeed());  //  叉牙速度(m/min)
            vo.setXdistance(crnProtocol.getXDistance());  //  走行距离(Km)
            vo.setYdistance(crnProtocol.getYDistance());  //  升降距离(Km)
            vo.setXduration(crnProtocol.getXDuration());    //  走行时长(H)
            vo.setYduration(crnProtocol.getYDuration());    //  升降时长(H)
        }
        return R.ok().add(list);
    }
@@ -392,15 +408,15 @@
                    throw new CoolException("堆垛机不在线");
                }
                // 空闲判断
                if (crnProtocol.getStatusType().equals(com.zy.core.enums.CrnStatusType.IDLE) && crnProtocol.getTaskNo() == 0) {
//                if (crnProtocol.getStatusType().equals(com.zy.core.enums.CrnStatusType.IDLE) && crnProtocol.getTaskNo() == 0) {
                    if (MessageQueue.offer(SlaveType.Crn, crn.getId(), new Task(2, command))) {
                        return true;
                    } else {
                        throw new CoolException("命令下发失败");
                    }
                } else {
                    throw new CoolException("堆垛机不在空闲状态");
                }
//                } else {
//                    throw new CoolException("堆垛机不在空闲状态");
//                }
            }
        }
        return false;
src/main/java/com/zy/asrs/controller/SiteController.java
@@ -1,9 +1,12 @@
package com.zy.asrs.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.annotations.ManagerAuth;
import com.core.common.R;
import com.zy.asrs.domain.vo.PlcErrorTableVo;
import com.zy.asrs.domain.vo.SiteTableVo;
import com.zy.asrs.entity.BasDevp;
import com.zy.asrs.service.BasDevpService;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.OutputQueue;
import com.zy.core.cache.SlaveConnection;
@@ -17,6 +20,7 @@
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -30,31 +34,35 @@
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private BasDevpService basDevpService;
    @PostMapping("/table/site")
    @ManagerAuth(memo = "站点信息表")
    public R siteTable(){
        List<SiteTableVo> list = new ArrayList<>();
        // 内存数据
        Map<Integer, StaProtocol> station = new HashMap<>();
        for (DevpSlave devp : slaveProperties.getDevp()) {
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
            Map<Integer, StaProtocol> station = devpThread.getStation();
            for (Map.Entry<Integer, StaProtocol> entry : station.entrySet()) {
                StaProtocol staProtocol = entry.getValue();
                SiteTableVo vo = new SiteTableVo();
                vo.setDevNo(entry.getKey());    // 站点编号
                vo.setWorkNo(staProtocol.getWorkNo());   //  工作号
                vo.setAutoing(staProtocol.isAutoing()?"Y":"N");     //  自动
                vo.setLoading(staProtocol.isLoading()?"Y":"N");     // 有物
                vo.setInEnable(staProtocol.isInEnable()?"Y":"N");   // 可入
                vo.setOutEnable(staProtocol.isOutEnable()?"Y":"N"); // 可出
                vo.setInreq1(staProtocol.isInreq1()?"Y":"N");       // 需求1
                vo.setEmptyMk(staProtocol.isEmptyMk()?"Y":"N");     // 空板信号
                vo.setStaNo(staProtocol.getStaNo());                // 目标站
                list.add(vo);
            }
            station.putAll(devpThread.getStation());
        }
        // 持久数据
        List<BasDevp> basDevps = basDevpService.selectList(new EntityWrapper<BasDevp>().orderBy("dev_no"));
        for (BasDevp devp : basDevps) {
            SiteTableVo vo = new SiteTableVo();
            vo.setDevNo(devp.getDevNo());    // 站点编号
            list.add(vo);
            StaProtocol staProtocol = station.get(devp.getDevNo());
            if (null == staProtocol) { continue; }
            vo.setWorkNo(staProtocol.getWorkNo());   //  工作号
            vo.setAutoing(staProtocol.isAutoing()?"Y":"N");     //  自动
            vo.setLoading(staProtocol.isLoading()?"Y":"N");     // 有物
            vo.setInEnable(staProtocol.isInEnable()?"Y":"N");   // 可入
            vo.setOutEnable(staProtocol.isOutEnable()?"Y":"N"); // 可出
            vo.setPakMk(staProtocol.isPakMk()?"Y":"N");       // 入库标记
            vo.setEmptyMk(staProtocol.isEmptyMk()?"Y":"N");     // 空板信号
            vo.setStaNo(staProtocol.getStaNo());                // 目标站
        }
        return R.ok().add(list);
    }
@@ -68,12 +76,15 @@
            Map<Integer, StaProtocol> station = devpThread.getStation();
            for(Map.Entry<Integer, StaProtocol> entry : station.entrySet()) {
                PlcErrorTableVo vo = new PlcErrorTableVo();
                vo.setNo(entry.getKey());   //  序号
                vo.setPlcDesc("");  //  todo:luxiaotao plc错误描述
                vo.setError("");    //  todo:luxiaotao 异常信息
                list.add(vo);
                StaProtocol staProtocol = entry.getValue();
//                if (staProtocol) {
//                    PlcErrorTableVo vo = new PlcErrorTableVo();
//                    vo.setNo(entry.getKey());   //  序号
//
//                    vo.setPlcDesc("");  //  todo:luxiaotao plc错误描述
//                    vo.setError("");    //  todo:luxiaotao 异常信息
//                    list.add(vo);
//                }
            }
        }
@@ -123,7 +134,7 @@
                    vo.setLoading(staProtocol.isLoading()?"Y":"N");     // 有物
                    vo.setInEnable(staProtocol.isInEnable()?"Y":"N");   // 可入
                    vo.setOutEnable(staProtocol.isOutEnable()?"Y":"N"); // 可出
                    vo.setInreq1(staProtocol.isInreq1()?"Y":"N");       // 需求1
                    vo.setPakMk(staProtocol.isPakMk()?"Y":"N");       // 需求1
                    vo.setEmptyMk(staProtocol.isEmptyMk()?"Y":"N");     // 空板信号
                    vo.setStaNo(staProtocol.getStaNo());                // 目标站
                    return R.ok().add(vo);
src/main/java/com/zy/asrs/domain/enums/CrnStatusType.java
@@ -38,9 +38,9 @@
    public static CrnStatusType process(Integer ioType){
        if (ioType>100) {
            return MACHINE_PAKIN;
        } else if (ioType < 100 && ioType!=3 && ioType!=6 && ioType!=11) {
            return MACHINE_PAKOUT;
        } else if (ioType < 100 && ioType!=3 && ioType!=6 && ioType!=11) {
            return MACHINE_PAKIN;
        } else if (ioType == 3) {
            return MACHINE_SITE_MOVE;
        } else if (ioType == 11) {
src/main/java/com/zy/asrs/domain/vo/CrnMsgTableVo.java
@@ -1,5 +1,6 @@
package com.zy.asrs.domain.vo;
import com.zy.asrs.utils.Utils;
import lombok.Data;
/**
@@ -12,22 +13,22 @@
    private Integer crnNo;
    // 工作号
    private Short workNo;
    private Short workNo = 0;
    // 状态
    private String status = "";
    private String status = "-";
    // 源站
    private String sourceStaNo = "";
    private String sourceStaNo = "-";
    // 目标站
    private String staNo = "";
    private String staNo = "-";
    // 源库位
    private String sourceLocNo = "";
    private String sourceLocNo = "-";
    // 目标库位
    private String locNo = "";
    private String locNo = "-";
    // 异常
    private String error = "";
@@ -38,4 +39,52 @@
    // 命令
    private String command = "";
    // 走行速度(m/min)
    private Float xspeed = 0.0F;
    // 升降速度(m/min)
    private Float yspeed = 0.0F;
    // 叉牙速度(m/min)
    private Float zspeed = 0.0F;
    // 走行距离(Km)
    private Float xdistance = 0.0F;
    // 升降距离(Km)
    private Float ydistance = 0.0F;
    // 走行时长(H)
    private Float xduration = 0.0F;
    // 升降时长(H)
    private Float yduration = 0.0F;
    public void setXspeed(Float xspeed) {
        this.xspeed = Utils.scale(xspeed);
    }
    public void setYspeed(Float yspeed) {
        this.yspeed = Utils.scale(yspeed);
    }
    public void setZspeed(Float zspeed) {
        this.zspeed = Utils.scale(zspeed);
    }
    public void setXdistance(Float xdistance) {
        this.xdistance = Utils.scale(xdistance);
    }
    public void setYdistance(Float ydistance) {
        this.ydistance = Utils.scale(ydistance);
    }
    public void setXduration(Float xduration) {
        this.xduration = Utils.scale(xduration);
    }
    public void setYduration(Float yduration) {
        this.yduration = Utils.scale(yduration);
    }
}
src/main/java/com/zy/asrs/domain/vo/CrnStateTableVo.java
@@ -12,13 +12,10 @@
    private Integer crnNo;
    // 模式
    private String statusType;
    // 报警
    private String warn;
    private String statusType = "-";
    // 有物
    private String loading;
    private String loading = "-";
    // 列
    private Short bay;
@@ -26,29 +23,43 @@
    // 层
    private Short lev;
    // 走行原点
    private String xOrigin = "-";
    // 升降原点
    private String yOrigin = "-";
    // 走行定位
    private String xLocation = "-";
    // 升降定位
    private String yLocation = "-";
    // 货叉位置
    private String forkOffset;
    private String forkOffset = "-";
    // 载货台位置
    private String liftPos;
    private String liftPos = "-";
    // 急停
    private String stop = "-";
    // 列坐标
    private String bayCoor;
    private String bayCoor = "-";
    // 层坐标
    private String levCoor;
    private String levCoor = "-";
    // 完成
    private String complete;
    private String complete = "-";
    // 任务号
    private Short workNo;
    private Short workNo = 0;
    // 状态
    private String status;
    private String status = "-";
    // 异常码
    private String warnCode;
    private String warnCode = "-";
}
src/main/java/com/zy/asrs/domain/vo/SiteTableVo.java
@@ -12,27 +12,27 @@
    private Integer devNo;
    // 工作号
    private Short workNo;
    private Short workNo = 0;
    // 自动
    private String autoing;
    private String autoing = "-";
    // 有物
    private String loading;
    private String loading = "-";
    // 可入
    private String inEnable;
    private String inEnable = "-";
    // 可出
    private String outEnable;
    private String outEnable = "-";
    // 需求1
    private String inreq1;
    private String pakMk = "-";
    // 空板信号
    private String emptyMk;
    private String emptyMk = "-";
    // 目标站
    private Short staNo;
    private Short staNo = 0;
}
src/main/java/com/zy/asrs/mapper/WrkMastMapper.java
@@ -18,31 +18,33 @@
    // wcs ---------------------------------------------
    // 入库第一步,扫码仪获取条码信息时查询
    @Select("select top 1 * from asr_wrk_mast where source_sta_no=#{sourceStaNo} and wrk_sts=2 and barcode=#{barcode} and (io_type=1 or io_type=10) order by io_pri desc,io_time,wrk_no ASC")
//    @Select("select top 1 * from asr_wrk_mast where source_sta_no=#{sourceStaNo} and wrk_sts=2 and barcode=#{barcode} and (io_type=1 or io_type=10) order by io_pri desc,io_time,wrk_no ASC")
    WrkMast selectPakInStep1(@Param("sourceStaNo")Integer sourceStaNo, @Param("barcode")String barcode);
    WrkMast selectPakInStep11(@Param("sourceStaNo")Integer sourceStaNo);
    // 入库第二步,当托盘物料在堆垛机入库站时时查询
    @Select("select top 1 * from dbo.asr_wrk_mast where wrk_sts=2 and crn_no=#{crnNo} and wrk_no=#{workNo} and (io_type=1 or io_type=10 or io_type=53 or io_type=54 or io_type=57) order by io_pri desc,io_time,wrk_no ASC")
//    @Select("select top 1 * from dbo.asr_wrk_mast where wrk_sts=2 and crn_no=#{crnNo} and wrk_no=#{workNo} and (io_type=1 or io_type=10 or io_type=53 or io_type=54 or io_type=57) order by io_pri desc,io_time,wrk_no ASC")
    WrkMast selectPakInStep2(@Param("crnNo")Integer crnNo, @Param("workNo")Integer workNo);
    // 入库第三步,当堆垛机把货放入库位时
    @Select("select top 1 from dbo.asr_wrk_mast where wrk_no=#{workNo}")
//    @Select("select top 1 from dbo.asr_wrk_mast where wrk_no=#{workNo}")
    WrkMast selectPakInStep3(@Param("workNo")Integer workNo);
    // 拣料再入库时,站点有物且需求时查询
    @Select("select top 1 * from asr_wrk_mast where wrk_no=#{workNo} and wrk_sts=14 and (io_type=103 or io_type=107 or io_type=104)")
//    @Select("select top 1 * from asr_wrk_mast where wrk_no=#{workNo} and wrk_sts=14 and (io_type=103 or io_type=107 or io_type=104)")
    WrkMast selectPickStep(@Param("workNo")Integer workNo);
    // 出库第一步,从库位到堆垛机出库站
    @Select("select top 1 * from dbo.asr_wrk_mast where crn_no=#{crnNo} and wrk_sts=11 and io_type>100 order by io_pri desc,io_time,wrk_no asc")
//    @Select("select top 1 * from dbo.asr_wrk_mast where crn_no=#{crnNo} and wrk_sts=11 and io_type>100 order by io_pri desc,io_time,wrk_no asc")
    WrkMast selectPakOutStep1(@Param("crnNo")Integer crnNO);
    // 出库第二步,从堆垛机出库站到目标出库站,堆垛机出库站有物时执行
    @Select("select top 1 * from dbo.asr_wrk_mast where source_sta_no=#{sourceStaNo} and wrk_sts=12 and io_type>100 order by io_pri desc,io_time desc,wrk_no ASC")
//    @Select("select top 1 * from dbo.asr_wrk_mast where source_sta_no=#{sourceStaNo} and wrk_sts=12 and io_type>100 order by io_pri desc,io_time desc,wrk_no ASC")
    WrkMast selectPakOutStep2(@Param("sourceStaNo")Integer sourceStaNo);
    // 库位移转工作档,在进行一次入出库作业后紧跟库位移转
    @Select("select top 1 * from dbo.asr_wrk_mast where wrk_sts=11 and (io_type=11 or io_type=110) and crn_no=#{crnNo} order by io_time,wrk_no")
//    @Select("select top 1 * from dbo.asr_wrk_mast where wrk_sts=11 and (io_type=11 or io_type=110) and crn_no=#{crnNo} order by io_time,wrk_no")
    WrkMast selectLocMove(@Param("crnNo")Integer crnNo);
    // work log -------------------------------------------------------
src/main/java/com/zy/asrs/service/WrkDetlService.java
@@ -8,7 +8,8 @@
public interface WrkDetlService extends IService<WrkDetl> {
    void createWorkDetail(Integer workNo, List<WaitPakin> waitPakins, String barcode);
    List<WrkDetl> findByWorkNo(Integer workNo);
}
src/main/java/com/zy/asrs/service/impl/MainServiceImpl.java
@@ -9,20 +9,26 @@
import com.zy.asrs.mapper.WaitPakinMapper;
import com.zy.asrs.mapper.WrkMastMapper;
import com.zy.asrs.service.*;
import com.zy.common.model.MatDto;
import com.zy.common.model.StartupDto;
import com.zy.common.service.CommonService;
import com.zy.common.utils.CollectionUtils;
import com.zy.core.cache.MessageQueue;
import com.zy.core.cache.SlaveConnection;
import com.zy.core.enums.*;
import com.zy.core.model.CrnSlave;
import com.zy.core.model.DevpSlave;
import com.zy.core.model.LedSlave;
import com.zy.core.model.Task;
import com.zy.core.model.command.CrnCommand;
import com.zy.core.model.command.LedCommand;
import com.zy.core.model.protocol.CrnProtocol;
import com.zy.core.model.protocol.StaProtocol;
import com.zy.core.properties.SlaveProperties;
import com.zy.core.thread.BarcodeThread;
import com.zy.core.thread.CrnThread;
import com.zy.core.thread.DevpThread;
import com.zy.core.thread.LedThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -30,8 +36,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -79,9 +84,12 @@
                // 获取入库站信息
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
                if (staProtocol == null) {
                    continue;
                }
                // 判断是否满足入库条件
                if (staProtocol.isAutoing() && staProtocol.isLoading()
                        && !staProtocol.isEmptyMk() && staProtocol.isInreq1() && staProtocol.getWorkNo()==0
                        && !staProtocol.isEmptyMk() && staProtocol.getWorkNo() == 0
                        && staProtocol.isPakMk() && !Cools.isEmpty(barcode)) {
                    // 判断重复工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep1(inSta.getStaNo(), barcode);
@@ -147,7 +155,6 @@
                    staProtocol.setWorkNo((short) workNo);
                    staProtocol.setStaNo(startupDto.getStaNo().shortValue());
                    staProtocol.setPakMk(false);
                    staProtocol.setInreq1(false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    if (!result) {
                        throw new CoolException("更新plc站点信息失败");
@@ -161,6 +168,55 @@
    }
    /**
     * 入库站,根据条码扫描生成入库工作档,工作状态 1 ==>> 2
     */
    @Async
    public void generateStoreWrkFile2() {
        // 根据输送线plc遍历
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历入库口
            for (DevpSlave.Sta inSta : devp.getInSta()) {
                // 获取入库站信息
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
                if (staProtocol == null) { continue; }
                // 判断是否满足入库条件
                if (staProtocol.isAutoing() && staProtocol.isLoading()
                        && !staProtocol.isEmptyMk() && staProtocol.getWorkNo() == 0
                        && staProtocol.isPakMk()) {
                    // 判断重复工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakInStep11(inSta.getStaNo());
                    if (wrkMast == null) {
                        continue;
                    }
                    // 更新工作主档
                    wrkMast.setWrkSts(2L); // 工作状态:2.设备上走
                    wrkMast.setModiTime(new Date());
                    Integer update = wrkMastMapper.updateById(wrkMast);
                    if (update == 0) {
                        throw new CoolException("更新工作档失败");
                    }
                    // 命令下发区 --------------------------------------------------------------------------
                    // 更新站点信息 且 下发plc命令
                    staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue());
                    staProtocol.setStaNo(wrkMast.getStaNo().shortValue());
                    staProtocol.setPakMk(false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    if (!result) {
                        throw new CoolException("更新plc站点信息失败");
                    }
                }
            }
        }
    }
    /**
     * 拣料、并板、盘点再入库
@@ -173,8 +229,8 @@
                // 获取拣料入库站信息
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(pickSta.getStaNo());
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInreq1()
                if (staProtocol == null) { continue; }
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable()
                    && staProtocol.getWorkNo() > 0 && staProtocol.isPakMk()){
                    WrkMast wrkMast = wrkMastMapper.selectPickStep(staProtocol.getWorkNo().intValue());
                    if (wrkMast == null) {
@@ -227,7 +283,6 @@
                    staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue());
                    staProtocol.setStaNo(wrkMast.getStaNo().shortValue());
                    staProtocol.setPakMk(false);
                    staProtocol.setInreq1(false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    if (!result) {
                        throw new CoolException("更新plc站点信息失败");
@@ -245,12 +300,13 @@
     */
    @Async
    public void crnStnToOutStn() {
        for (DevpSlave devp : slaveProperties.getDevp()) {
            // 遍历拣料入库口
            for (DevpSlave.Sta outSta : devp.getOutSta()) {
        for (CrnSlave crnSlave : slaveProperties.getCrn()) {
            // 遍历堆垛机出库站
            for (CrnSlave.CrnStn crnStn : crnSlave.getCrnOutStn()) {
                // 获取堆垛机出库站信息
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(outSta.getStaNo());
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
                StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
                if (staProtocol == null) { continue; }
                if (staProtocol.isAutoing() && staProtocol.isLoading() && (staProtocol.getWorkNo() == 0 || staProtocol.getStaNo() == null)) {
                    // 查询工作档
                    WrkMast wrkMast = wrkMastMapper.selectPakOutStep2(staProtocol.getSiteId());
@@ -268,32 +324,32 @@
                        // 移动中
                        continue;
                    }
                    // 更新工作档状态为14失败 todo:luxiaotao
                    //  判断堆垛机状态等待确认
                    if (crnProtocol.modeType == CrnModeType.AUTO && crnProtocol.getTaskNo().equals(wrkMast.getWrkNo().shortValue())
                            && crnProtocol.statusType == CrnStatusType.IDLE
                            && crnProtocol.statusType == CrnStatusType.WAITING
                            && crnProtocol.forkPosType == CrnForkPosType.HOME) {
                        // 命令下发区 --------------------------------------------------------------------------
                        // 1.复位堆垛机
                        crnThread.setResetFlag(true);
                        // 2.下发站点信息
                        staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue());
                        staProtocol.setStaNo(wrkMast.getStaNo().shortValue());
                        if (!MessageQueue.offer(SlaveType.Devp, crnStn.getDevpPlcId(), new Task(2, staProtocol))) {
                            throw new CoolException("更新plc站点信息失败");
                        }
                        // 更新工作档状态为14失败
                        wrkMast.setWrkSts(14L);
                        wrkMast.setCrnEndTime(new Date());
                        if (wrkMastMapper.updateById(wrkMast) == 0) {
                            throw new CoolException("更新工作档的工作状态为14失败,工作号"+wrkMast.getWrkNo());
                        }
                    }
                    // 命令下发区 --------------------------------------------------------------------------
                    // 1.复位堆垛机 更新堆垛机信息 且 下发plc命令 todo:luxiaotao
                    crnProtocol.setStatus(CrnStatusType.IDLE);
                    crnProtocol.setTaskNo((short)0);
                    if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(4, crnProtocol))) {
                        throw new CoolException("更新堆垛机信息失败");
                    }
                    // 2.下发站点信息
                    staProtocol.setWorkNo(wrkMast.getWrkNo().shortValue());
                    staProtocol.setStaNo(wrkMast.getStaNo().shortValue());
                    if (!MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol))) {
                        throw new CoolException("更新plc站点信息失败");
                    }
                }
            }
        }
@@ -308,6 +364,7 @@
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) { continue; }
            BasCrnp basCrnp = basCrnpService.selectById(crn.getId());
            if (basCrnp == null) {
                log.error("{}号堆垛机尚未在数据库进行维护!", crn.getId());
@@ -318,26 +375,26 @@
                // 如果最近一次是入库模式
                if (crnProtocol.getLastIo().equals("I")) {
                    if (basCrnp.getInEnable().equals("Y")) {
                        this.crnStnToLoc(crn); //  入库
                        this.crnStnToLoc(crn, crnProtocol); //  入库
                        crnProtocol.setLastIo("O");
                    } else if (basCrnp.getOutEnable().equals("Y")) {
                        this.locToCrnStn(crn); //  出库
                        this.locToCrnStn(crn, crnProtocol); //  出库
                        crnProtocol.setLastIo("I");
                    }
                }
                // 如果最近一次是出库模式
                else if (crnProtocol.getLastIo().equals("O")) {
                    if (basCrnp.getOutEnable().equals("Y")) {
                        this.locToCrnStn(crn); //  出库
                        this.locToCrnStn(crn, crnProtocol); //  出库
                        crnProtocol.setLastIo("I");
                    } else if (basCrnp.getInEnable().equals("Y")) {
                        this.crnStnToLoc(crn); //  入库
                        this.crnStnToLoc(crn, crnProtocol); //  入库
                        crnProtocol.setLastIo("O");
                    }
                }
            }
            // 库位移转
            this.locToLoc(crn);
            this.locToLoc(crn, crnProtocol);
        }
    }
@@ -345,19 +402,21 @@
     * 入库  ===>>  堆垛机站到库位
     */
    @Async
    public void crnStnToLoc(CrnSlave slave){
    public void crnStnToLoc(CrnSlave slave, CrnProtocol crnProtocol){
        for (CrnSlave.CrnStn crnStn : slave.getCrnInStn()) {
            boolean flag = false;
            // 获取堆垛机入库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
            StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
            if (staProtocol == null) { continue; }
            // 查询站点详细信息
            BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo());
            if (staDetl == null) {
                log.error("入库 ===>> 堆垛机站点在数据库不存在, 站点编号={}", crnStn.getStaNo());
                continue;
            }
            if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() > 0 && staDetl.getCanining().equals("Y")) {
            if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.getWorkNo() > 0
                    && staDetl.getCanining()!=null && staDetl.getCanining().equals("Y")) {
                flag = true;
            }
            if (!flag) {
@@ -377,6 +436,11 @@
            }
            if (!locMast.getLocSts().equals("S") && !locMast.getLocSts().equals("Q")) {
                log.error("入库操作库位状态不符合--状态, 库位号={},库位状态={}", wrkMast.getLocNo(), locMast.getLocSts());
                continue;
            }
            // 堆垛机控制过滤
            if (!crnProtocol.getStatusType().equals(CrnStatusType.IDLE) || crnProtocol.getTaskNo() != 0) {
                continue;
            }
@@ -411,7 +475,7 @@
     * 出库  ===>>  库位到堆垛机站
     */
    @Async
    public void locToCrnStn(CrnSlave slave){
    public void locToCrnStn(CrnSlave slave, CrnProtocol crnProtocol){
        for (CrnSlave.CrnStn crnStn : slave.getCrnOutStn()) {
            // 获取工作状态为11(生成出库ID)的出库工作档
            WrkMast wrkMast = wrkMastMapper.selectPakOutStep1(slave.getId());
@@ -432,6 +496,7 @@
            // 获取堆垛机出库站信息
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, crnStn.getDevpPlcId());
            StaProtocol staProtocol = devpThread.getStation().get(crnStn.getStaNo());
            if (staProtocol == null) { continue; }
            // 查询站点详细信息
            BasDevp staDetl = basDevpService.selectById(crnStn.getStaNo());
            if (staDetl == null) {
@@ -439,9 +504,14 @@
                continue;
            }
            // 判断堆垛机出库站状态
            if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting().equals("Y")
            if (staProtocol.isAutoing() && !staProtocol.isLoading() && staDetl.getCanouting() !=null && staDetl.getCanouting().equals("Y")
                    && staProtocol.getWorkNo() == 0) {
                // 命令下发区 --------------------------------------------------------------------------
                // 堆垛机控制过滤
                if (!crnProtocol.getStatusType().equals(CrnStatusType.IDLE) || crnProtocol.getTaskNo() != 0) {
                    continue;
                }
                // 1.堆垛机开始移动
                CrnCommand crnCommand = new CrnCommand();
@@ -475,7 +545,7 @@
     * 库位移转
     */
    @Async
    public void locToLoc(CrnSlave slave){
    public void locToLoc(CrnSlave slave, CrnProtocol crnProtocol){
        // 获取工作档信息
        WrkMast wrkMast = wrkMastMapper.selectLocMove(slave.getId());
        if (null == wrkMast) {
@@ -502,6 +572,12 @@
        if (!basCrnp.getInEnable().equals("Y") && !basCrnp.getOutEnable().equals("Y")) {
            return;
        }
        // 堆垛机控制过滤
        if (!crnProtocol.getStatusType().equals(CrnStatusType.IDLE) || crnProtocol.getTaskNo() != 0) {
            return;
        }
        // 命令下发区 --------------------------------------------------------------------------
        CrnCommand crnCommand = new CrnCommand();
        crnCommand.setCrnNo(slave.getId()); // 堆垛机编号
@@ -516,7 +592,17 @@
        crnCommand.setDestinationPosZ(sta.getLev1().shortValue());     // 目标库位层
        if (!MessageQueue.offer(SlaveType.Crn, wrkMast.getCrnNo(), new Task(2, crnCommand))) {
            log.error("堆垛机命令下发失败,堆垛机号={},任务数据={}", wrkMast.getCrnNo(), JSON.toJSON(crnCommand));
        } else {
            // 修改工作档状态 11.生成出库ID => 12.吊车出库中
            Date now = new Date();
            wrkMast.setWrkSts(12L);
            wrkMast.setCrnStrTime(now);
            wrkMast.setModiTime(now);
            if (wrkMastMapper.updateById(wrkMast) == 0) {
                log.error("【库位移转】 修改工作档状态 11.生成出库ID => 12.吊车出库中 失败!!,工作号={}", wrkMast.getWrkNo());
            }
        }
    }
    /**
@@ -528,6 +614,7 @@
            // 获取堆垛机信息
            CrnThread crnThread = (CrnThread) SlaveConnection.get(SlaveType.Crn, crn.getId());
            CrnProtocol crnProtocol = crnThread.getCrnProtocol();
            if (crnProtocol == null) { continue; }
            //  状态:等待确认 并且  任务完成位 = 1
            if (crnProtocol.statusType == CrnStatusType.WAITING && crnProtocol.getTaskNo() != 0) {
                // 获取入库待确认工作档
@@ -540,25 +627,25 @@
                if (wrkMast.getWrkSts() == 3 || (wrkMast.getWrkSts() == 12 && wrkMast.getIoType() == 11)){
                    wrkMast.setWrkSts(4L);
                // 出库 + 拣料/盘点/并板出库中:12.吊车出库中 ==> 14.出库完成
                } else if (wrkMast.getWrkSts() == 12) {
                    wrkMast.setWrkSts(14L);
                    // todo:luxiaotao
//                } else if (wrkMast.getWrkSts() == 12) {
//                    wrkMast.setWrkSts(14L);
                } else  {
                    continue;
                }
                Date now = new Date();
                wrkMast.setCrnEndTime(now);
                wrkMast.setModiTime(now);
                // 修改成功后复位堆垛机
                if (wrkMastMapper.updateById(wrkMast) > 0) {
                    // 命令下发区 -------------------------------------------------------------------------
                    // 堆垛机复位
                    if (!MessageQueue.offer(SlaveType.Crn, crn.getId(), new Task(3, new CrnCommand()))) {
                        log.error("堆垛机复位命令下发失败,工作号={}", wrkMast.getWrkNo());
                    }
                    crnThread.setResetFlag(true);
                }
                // 完成通知档
                if (wrkMastMapper.updateWaitPakInStep2(wrkMast.getBarcode()) == 0) {
                    log.error("入库通知档修改结束状态失败,workNo=[{}]", wrkMast.getWrkNo());
                }
//                if (wrkMastMapper.updateWaitPakInStep2(wrkMast.getBarcode()) == 0) {
//                    log.error("入库通知档修改结束状态失败,workNo=[{}]", wrkMast.getWrkNo());
//                }
            }
        }
@@ -585,13 +672,14 @@
                // 获取空板入库站信息
                DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                StaProtocol staProtocol = devpThread.getStation().get(emptyInSta.getStaNo());
                if (staProtocol == null) { continue; }
                // 站点条件判断
                if (staProtocol.isAutoing() && staProtocol.isLoading() && !staProtocol.isInreq1()
                if (staProtocol.isAutoing() && staProtocol.isLoading() && staProtocol.isInEnable()
                        && staProtocol.isEmptyMk() && staProtocol.getWorkNo() == 0 && staProtocol.isPakMk()) {
                    // 工作号
                    int workNo = commonService.getWorkNo(0);
                    // 检索库位
                    StartupDto startupDto = commonService.getLocNo(1, 1, emptyInSta.getStaNo(), null);
                    StartupDto startupDto = commonService.getLocNo(1, 10, emptyInSta.getStaNo(), null);
                    // 插入工作主档
                    WrkMast wrkMast = new WrkMast();
@@ -630,12 +718,12 @@
                    staProtocol.setWorkNo((short) workNo);
                    staProtocol.setStaNo(startupDto.getStaNo().shortValue());
                    staProtocol.setPakMk(false);
                    staProtocol.setInreq1(false);
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(2, staProtocol));
                    if (!result) {
                        throw new CoolException("更新plc站点信息失败");
                    }
                }
@@ -643,4 +731,63 @@
        }
    }
    /**
     * 出库  ===>> 工作档信息写入led显示器
     */
    @Async
    public void ledExecute() {
        for (LedSlave led : slaveProperties.getLed()) {
            // 获取输送线plc线程
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, led.getDevpPlcId());
            // 命令集合
            List<LedCommand> commands = new ArrayList<>();
            // 工作档集合
            List<WrkMast> wrkMasts = new ArrayList<>();
            for (Integer staNo : led.getStaArr()) {
                // 获取叉车站点
                StaProtocol staProtocol = devpThread.getStation().get(staNo);
                if (null == staProtocol || null == staProtocol.getWorkNo() || 0 == staProtocol.getWorkNo()) { continue; }
                // 获取工作档数据
                WrkMast wrkMast = wrkMastMapper.selectById(staProtocol.getWorkNo());
                if (wrkMast.getWrkSts() == 14L || wrkMast.getWrkSts() == 15L) {
                    wrkMasts.add(wrkMast);
                    // 添加命令
                    List<WrkDetl> wrkDetls = wrkDetlService.findByWorkNo(wrkMast.getWrkNo());
                    LedCommand ledCommand = new LedCommand();
                    ledCommand.setWorkNo(wrkMast.getWrkNo());
                    ledCommand.setSourceLocNo(wrkMast.getSourceLocNo());
                    ledCommand.setStaNo(wrkMast.getStaNo());
                    wrkDetls.forEach(wrkDetl -> ledCommand.getMatDtos().add(new MatDto(wrkDetl.getMatnr(), wrkDetl.getMatnr(), wrkDetl.getAnfme())));
                    commands.add(ledCommand);
                }
            }
            Set<Integer> workNos = wrkMasts.stream().map(WrkMast::getWrkNo).collect(Collectors.toSet());
            // 获取LED线程
            LedThread ledThread = (LedThread) SlaveConnection.get(SlaveType.Led, led.getId());
            // 相同工作号集合则过滤
            if (CollectionUtils.equals(ledThread.getWorkNos(), workNos)) {
                continue;
            }
            // 命令下发 -------------------------------------------------------------------------------
            if (!commands.isEmpty()) {
                if (!MessageQueue.offer(SlaveType.Led, led.getId(), new Task(1, commands))) {
                    continue;
                }
            }
            // 修改主档led标记
            for (WrkMast wrkMast : wrkMasts) {
                wrkMast.setOveMk("Y");
                wrkMast.setModiTime(new Date());
                if (wrkMastMapper.updateById(wrkMast) == 0) {
                    throw new CoolException("更新工作档失败");
                }
            }
            // 更新线程当前工作号集合
            ledThread.setWorkNos(workNos);
        }
    }
}
src/main/java/com/zy/asrs/service/impl/WrkDetlServiceImpl.java
@@ -1,5 +1,6 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.core.common.Cools;
import com.core.exception.CoolException;
@@ -49,4 +50,9 @@
        }
    }
    @Override
    public List<WrkDetl> findByWorkNo(Integer workNo) {
        return this.baseMapper.selectList(new EntityWrapper<WrkDetl>().eq("wrk_no", workNo));
    }
}
src/main/java/com/zy/asrs/utils/Utils.java
New file
@@ -0,0 +1,22 @@
package com.zy.asrs.utils;
import com.core.common.Arith;
import java.math.BigDecimal;
import java.text.DecimalFormat;
/**
 * Created by vincent on 2020/8/27
 */
public class Utils {
    private static final DecimalFormat fmt = new DecimalFormat("##0.00");
    public static float scale(Float f){
        if (f == null || f == 0f || Float.isNaN(f)) {
            return 0f;
        }
        return (float) Arith.multiplys(2, f, 1);
    }
}
src/main/java/com/zy/common/model/MatDto.java
@@ -11,7 +11,18 @@
    // 物料编号
    private String matNo;
    // 物料名称
    private String maknx;
    // 物料数量
    private Double count;
    public MatDto() {
    }
    public MatDto(String matNo, String maknx, Double count) {
        this.matNo = matNo;
        this.maknx = maknx;
        this.count = count;
    }
}
src/main/java/com/zy/common/service/CommonService.java
File was renamed from src/main/java/com/zy/asrs/service/impl/CommonService.java
@@ -1,4 +1,4 @@
package com.zy.asrs.service.impl;
package com.zy.common.service;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
@@ -89,12 +89,19 @@
     * @return locNo 检索到的库位号
     */
    public StartupDto getLocNo(Integer whsType, Integer staDescId, Integer sourceStaNo, List<String> matNos) {
        if (sourceStaNo == 3) {
            whsType = 1;
        } else if (sourceStaNo == 7) {
            whsType = 2;
        } else {
            throw new CoolException("无效入库站");
        }
        StartupDto startupDto = new StartupDto();
        RowLastno rowLastno = rowLastnoService.selectById(whsType);
        if (Cools.isEmpty(rowLastno)) {
            throw new CoolException("数据异常,请联系管理员");
        }
        if (rowLastno.getWhsType() == 1){
        if (whsType == 1 || whsType == 2){
            int curRow = rowLastno.getCurrentRow();
            int sRow = rowLastno.getsRow();
            int eRow = rowLastno.geteRow();
@@ -106,48 +113,54 @@
            LocMast locMast = null;
            // 同一天同规格货物靠近摆法规则
            if (!Cools.isEmpty(matNos)) {
                List<String> locNos = locDetlService.getSameDetlToday(matNos.get(0));
                for (String locNo : locNos) {
                    // 获取排
                    int row = Integer.parseInt(locNo.substring(0, 2));
                    // 判断是否为深库位
                    double remainder = Arith.remainder(row, rowCount / crn_qty);
                    int targetRow;
                    if (remainder == 1) {
                        // 得到当前库位的外围库位
                        targetRow =  row + 1;
                    } else if (remainder == 0) {
                        // 得到当前库位的内围库位
                        targetRow =  row - 1;
                    } else {
                        continue;
                    }
                    String targetLocNo = zerofill(String.valueOf(targetRow), 2)+locNo.substring(2);
                    // 检测目标库位是否为空库位
                    LocMast targetLocMast = locMastService.selectById(targetLocNo);
                    if (targetLocMast != null && targetLocMast.getLocSts().equals("O")) {
                        locMast = targetLocMast;
                        crnNo = locMast.getCrnNo();
                        break;
                    }
                }
            }
//            if (!Cools.isEmpty(matNos)) {
//                List<String> locNos = locDetlService.getSameDetlToday(matNos.get(0));
//                for (String locNo : locNos) {
//                    // 获取排
//                    int row = Integer.parseInt(locNo.substring(0, 2));
//                    // 判断是否为深库位
//                    double remainder = Arith.remainder(row, rowCount / crn_qty);
//                    int targetRow;
//                    if (remainder == 1) {
//                        // 得到当前库位的外围库位
//                        targetRow =  row + 1;
//                    } else if (remainder == 0) {
//                        // 得到当前库位的内围库位
//                        targetRow =  row - 1;
//                    } else {
//                        continue;
//                    }
//                    String targetLocNo = zerofill(String.valueOf(targetRow), 2)+locNo.substring(2);
//                    // 检测目标库位是否为空库位
//                    LocMast targetLocMast = locMastService.selectById(targetLocNo);
//                    if (targetLocMast != null && targetLocMast.getLocSts().equals("O")) {
//                        locMast = targetLocMast;
//                        crnNo = locMast.getCrnNo();
//                        break;
//                    }
//                }
//            }
            // 如果没有相近物料,则按规则轮询货架
            if (null == locMast) {
                // 获取目标站所在货架排号
                Shelves shelves = new Shelves(rowCount, crn_qty);
                curRow = shelves.start(curRow);
                if (curRow < 0) {
                    throw new CoolException("检索库位失败,请联系管理员");
                // 获取目标站所在货架排号 todo:luxiaotao
                if (curRow == sRow) {
                    curRow = eRow;
                } else {
                    curRow = sRow;
                }
                for (List<Integer> node : shelves.nodes){
                    if (node.contains(curRow)) {
                        crnNo = shelves.nodes.indexOf(node) + 1;
                        break;
                    }
                }
                crnNo = whsType;
//                Shelves shelves = new Shelves(rowCount, crn_qty);
//                curRow = shelves.start(curRow);
//                if (curRow < 0) {
//                    throw new CoolException("检索库位失败,请联系管理员");
//                }
//                for (List<Integer> node : shelves.nodes){
//                    if (node.contains(curRow)) {
//                        crnNo = shelves.nodes.indexOf(node) + 1;
//                        break;
//                    }
//                }
            }
            basCrnpService.checkSiteStatus(crnNo);
@@ -162,7 +175,7 @@
            }
            BasDevp staNo = basDevpService.selectById(staDesc.getCrnStn());
            int inQty = staNo.getInQty()==null?0:staNo.getInQty();
            if (staNo.getInEnable().equals("Y") && staNo.getAutoing().equals("Y") && inQty<2) {
            if (staNo.getAutoing().equals("Y") && inQty<2) {
                // 查找库位
                if (locMast == null) {
                    locMast = locMastService.queryFreeLocMast(curRow);
src/main/java/com/zy/common/utils/CollectionUtils.java
New file
@@ -0,0 +1,20 @@
package com.zy.common.utils;
import java.util.Set;
/**
 * Created by vincent on 2020/9/3
 */
public class CollectionUtils {
    public static boolean equals(Set<?> set1, Set<?> set2) {
        if(set1 == null || set2 ==null){
            return false;
        }
        if(set1.size()!=set2.size()){
            return false;
        }
        return set1.containsAll(set2);
    }
}
src/main/java/com/zy/core/MainProcess.java
@@ -37,10 +37,11 @@
                    // 间隔
                    Thread.sleep(1500);
                    log.info("WCS 工作中 .....................");
//                    log.info("WCS 工作中 .....................");
                    // 入库  ===>> 入库站到堆垛机站,根据条码扫描生成入库工作档
                    mainService.generateStoreWrkFile();
//                    mainService.generateStoreWrkFile();
                    mainService.generateStoreWrkFile2();
                    // 拣料、并板、盘点再入库
                    mainService.stnToCrnStnPick();
                    // 出库  ===>>  堆垛机出库站到出库站
@@ -53,6 +54,8 @@
                    mainService.recCrnErr();
                    // 入库  ===>> 空栈板初始化入库,叉车入库站放货
                    mainService.storeEmptyPlt();
                    // 出库  ===>> 工作档信息写入led显示器
                    mainService.ledExecute();
                } catch (Exception e) {
                    e.printStackTrace();
src/main/java/com/zy/core/ServerBootstrap.java
@@ -5,14 +5,17 @@
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.properties.SlaveProperties;
import com.zy.core.thread.BarcodeThread;
import com.zy.core.thread.CrnThread;
import com.zy.core.thread.DevpThread;
import com.zy.core.thread.LedThread;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
@@ -28,14 +31,17 @@
    private MainProcess mainProcess;
//    @PostConstruct
    @PostConstruct
    @Async
    public void init(){
        log.info("核心控制层开始初始化...............................................");
        // 初始化消息队列
        initMq();
        // 初始化下位机线程
        initThread();
        // 开始主流程进程
        mainProcess.start();
        log.info("核心控制层已启动...............................................");
    }
    private void initMq(){
@@ -63,6 +69,7 @@
    private void initThread(){
        // 初始化堆垛机线程
        log.info("初始化堆垛机线程...................................................");
        for (CrnSlave crn : slaveProperties.getCrn()) {
            CrnThread crnThread = new CrnThread(crn);
            new Thread(crnThread).start();
@@ -70,18 +77,27 @@
        }
        // 初始化输送线线程
        log.info("初始化输送线线程...................................................");
        for (DevpSlave devp : slaveProperties.getDevp()) {
            DevpThread devpThread = new DevpThread(devp);
            new Thread(devpThread).start();
            SlaveConnection.put(SlaveType.Devp, devp.getId(), devpThread);
        }
        // 初始化条码扫描仪线程
        for (Slave barcode : slaveProperties.getBarcode()) {
            BarcodeThread barcodeThread = new BarcodeThread(barcode);
            new Thread(barcodeThread).start();
            SlaveConnection.put(SlaveType.Barcode, barcode.getId(), barcodeThread);
//        // 初始化条码扫描仪线程
//        for (Slave barcode : slaveProperties.getBarcode()) {
//            BarcodeThread barcodeThread = new BarcodeThread(barcode);
//            new Thread(barcodeThread).start();
//            SlaveConnection.put(SlaveType.Barcode, barcode.getId(), barcodeThread);
//        }
        // 初始化LED线程
        log.info("初始化LED线程...................................................");
        for (LedSlave led : slaveProperties.getLed()) {
            LedThread ledThread = new LedThread(led);
            new Thread(ledThread).start();
            SlaveConnection.put(SlaveType.Led, led.getId(), ledThread);
        }
    }
src/main/java/com/zy/core/cache/MessageQueue.java
@@ -7,6 +7,7 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
 * 消息队列
@@ -21,7 +22,7 @@
    // 条码扫描仪mq交换机
    private static final Map<Integer, ConcurrentLinkedQueue<Task>> BARCODE_EXCHANGE = new ConcurrentHashMap<>();
    // Led灯 mq交换机
    private static final Map<Integer, ConcurrentLinkedQueue<Task>> LED_EXCHANGE = new ConcurrentHashMap<>();
    private static final Map<Integer, LinkedBlockingQueue<Task>> LED_EXCHANGE = new ConcurrentHashMap<>();
    // 磅称mq交换机
    private static final Map<Integer, ConcurrentLinkedQueue<Task>> SCALE_EXCHANGE = new ConcurrentHashMap<>();
@@ -40,7 +41,7 @@
                BARCODE_EXCHANGE.put(slave.getId(), new ConcurrentLinkedQueue<>());
                break;
            case Led:
                LED_EXCHANGE.put(slave.getId(), new ConcurrentLinkedQueue<>());
                LED_EXCHANGE.put(slave.getId(), new LinkedBlockingQueue<>(1));
                break;
            case Scale:
                SCALE_EXCHANGE.put(slave.getId(), new ConcurrentLinkedQueue<>());
src/main/java/com/zy/core/enums/CrnStatusType.java
@@ -11,7 +11,7 @@
    ORIGIN(6, "反原点"),
    LOC_MOVE(7, "库位移位"),
    WAITING(90, "任务完成等待WCS确认"),
//    SOS(99, "报警"),
    SOS(99, "报警"),
    ;
    public Integer id;
src/main/java/com/zy/core/model/CrnSlave.java
@@ -29,7 +29,7 @@
    @Data
    public static class CrnStn {
        // 堆垛机plc编号
        // 输送线plc编号
        private Integer devpPlcId;
        // 堆垛机站点编号
src/main/java/com/zy/core/model/LedSlave.java
New file
@@ -0,0 +1,24 @@
package com.zy.core.model;
import com.zy.core.Slave;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.ArrayList;
import java.util.List;
/**
 * LED配置
 * Created by vincent on 2020/8/6
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class LedSlave extends Slave {
    // 输送线plc编号
    private Integer devpPlcId;
    // 叉车站点数组
    private List<Integer> staArr = new ArrayList<>();
}
src/main/java/com/zy/core/model/command/LedCommand.java
New file
@@ -0,0 +1,28 @@
package com.zy.core.model.command;
import com.zy.common.model.MatDto;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
/**
 * led命令报文
 * Created by vincent on 2020/8/11
 */
@Data
public class LedCommand extends Object {
    private Integer workNo;
    private Integer staNo;
    private Integer sourceStaNo;
    private String locNo;
    private String sourceLocNo;
    private List<MatDto> matDtos = new ArrayList<>();
}
src/main/java/com/zy/core/model/protocol/CrnError1.java
@@ -8,53 +8,50 @@
@Data
public class CrnError1 {
    // 遥控器急停
    public boolean remoteStop;
    // 行走超速
    public boolean walkOverspeedErr;
    // 主控盘急停
    public boolean mainStop;
    // 行走速度超范围
    public boolean walkOverspeedRangeErr;
    // 操作盘急停
    public boolean controlStop;
    // 行走速度有偏差
    public boolean walkSpeedOffsetErr;
    // X行走变频器故障
    public boolean xCoverErr;
    // 行走位置有偏差
    public boolean walkLocationOffsetErr;
    // Y升降变频器故障
    public boolean yCoverErr;
    // 行走测距器异常
    public boolean walkDiastimeterErr;
    // Z货叉变频器故障
    public boolean zCoverErr;
    // 行走目标位置出界
    public boolean walkOutsideErr;
    // 激光故障
    public boolean laserErr;
    // 行走限位开关触发
    public boolean walkLimitSwitchErr;
    // 条码阅读器故障
    public boolean barcodeErr;
    // 行走制动序列异常
    public boolean walkBrakeErr;
    // X前极限
    public boolean xFrontLimitErr;
    // 行走测距器故障
    public boolean walkDiastimeterFau;
    // X后极限
    public boolean xBackLimitErr;
    // 升降超速
    public boolean liftOverSpeedErr;
    // Y上极限
    public boolean yUpLimitErr;
    // 升降速度超范围
    public boolean liftOverspeedRangeErr;
    // Y下极限
    public boolean yDownLimitErr;
    // 升降速度有偏差
    public boolean liftSpeedOffsetErr;
    // Z左极限
    public boolean zLeftLimitErr;
    // 升降位置有偏差
    public boolean liftLocationOffsetErr;
    // Z右极限
    public boolean zRightLimitErr;
    // 升降测距器异常
    public boolean liftDiastimeterErr;
    // 左超宽1
    public boolean leftOverWidthErr1;
    // 左超宽2
    public boolean leftOverWidthErr2;
    // 升降目标位置出界
    public boolean liftOutsideErr;
}
src/main/java/com/zy/core/model/protocol/CrnProtocol.java
@@ -108,6 +108,16 @@
     */
    private Short alarm1;
    private boolean[] temp1;
    private CrnTemp1 crnTemp1;
    private Short temp2;
    private Short temp3;
    private Short temp4;
    /**
     * 异常1
     */
@@ -228,83 +238,39 @@
    public void setError1(boolean[] error1){
        this.error1 = error1;
        this.crnError1 = new CrnError1();
        this.crnError1.remoteStop = error1[0];
        this.crnError1.mainStop = error1[1];
        this.crnError1.controlStop = error1[2];
        this.crnError1.xCoverErr = error1[3];
        this.crnError1.yCoverErr = error1[4];
        this.crnError1.zCoverErr = error1[5];
        this.crnError1.laserErr = error1[6];
        this.crnError1.barcodeErr = error1[7];
        this.crnError1.xFrontLimitErr = error1[8];
        this.crnError1.xBackLimitErr = error1[9];
        this.crnError1.yUpLimitErr = error1[10];
        this.crnError1.yDownLimitErr = error1[11];
        this.crnError1.zLeftLimitErr = error1[12];
        this.crnError1.zRightLimitErr = error1[13];
        this.crnError1.leftOverWidthErr1 = error1[14];
        this.crnError1.leftOverWidthErr2 = error1[15];
        this.crnError1.walkOverspeedErr = error1[1];
        this.crnError1.walkOverspeedRangeErr = error1[2];
        this.crnError1.walkSpeedOffsetErr = error1[3];
        this.crnError1.walkLocationOffsetErr = error1[4];
        this.crnError1.walkDiastimeterErr = error1[5];
        this.crnError1.walkOutsideErr = error1[6];
        this.crnError1.walkLimitSwitchErr = error1[7];
        this.crnError1.walkBrakeErr = error1[8];
        this.crnError1.walkDiastimeterFau = error1[9];
        this.crnError1.liftOverSpeedErr = error1[10];
        this.crnError1.liftOverspeedRangeErr = error1[11];
        this.crnError1.liftSpeedOffsetErr = error1[12];
        this.crnError1.liftLocationOffsetErr = error1[13];
        this.crnError1.liftDiastimeterErr = error1[14];
        this.crnError1.liftOutsideErr = error1[15];
    }
    public void setError2(boolean[] error2){
        this.error2 = error2;
        this.crnError2 = new CrnError2();
        this.crnError2.leftOverLenErr1 = error2[0];
        this.crnError2.leftOverLenErr2 = error2[1];
        this.crnError2.leftOverHighErr = error2[2];
        this.crnError2.rightOverWidthErr1 = error2[3];
        this.crnError2.rightOverWidthErr2 = error2[4];
        this.crnError2.rightOverLenErr1 = error2[5];
        this.crnError2.rightOverLenErr2 = error2[6];
        this.crnError2.rightOverHighErr = error2[7];
        this.crnError2.leftLooseRopeErr = error2[8];
        this.crnError2.rightLooseRopeErr = error2[9];
        this.crnError2.frontDoorErr = error2[10];
        this.crnError2.backDoorErr = error2[11];
        this.crnError2.startupErr = error2[12];
        this.crnError2.xFrontLocaUpErr = error2[13];
        this.crnError2.xFrontLocaDownErr = error2[14];
        this.crnError2.xBackLocaUpErr = error2[15];
    }
    public void setError3(boolean[] error3) {
        this.error3 = error3;
        this.crnError3 = new CrnError3();
        this.crnError3.xBackLocaDownErr = error3[0];
        this.crnError3.yUpLocaUpErr = error3[1];
        this.crnError3.yUpLocaDownErr = error3[2];
        this.crnError3.yDownLocaUpErr = error3[3];
        this.crnError3.yDownLocaDownErr = error3[4];
        this.crnError3.zLeftLocaUpErr = error3[5];
        this.crnError3.zLeftLocaDownErr = error3[6];
        this.crnError3.zRightLocaUpErr = error3[7];
        this.crnError3.zRightLocaDownErr = error3[8];
        this.crnError3.leftTakeNoneErr = error3[9];
        this.crnError3.rightTakeNoneErr = error3[10];
        this.crnError3.leftTakeThenLoadErr = error3[11];
        this.crnError3.rightTakeThenLoadErr = error3[12];
        this.crnError3.leftPutAndLoadErr = error3[13];
        this.crnError3.rightPutAndLoadErr = error3[14];
        this.crnError3.leftPutThenNoneErr = error3[15];
    }
    public void setError4(boolean[] error4) {
        this.error4 = error4;
        this.crnError4 = new CrnError4();
        this.crnError4.rightPutThenNoneErr = error4[0];
        this.crnError4.xLooseBrakeTimeout = error4[1];
        this.crnError4.yLooseBrakeTimeout = error4[2];
        this.crnError4.zLooseBrakeTimeout = error4[3];
    }
    public void setError5(boolean[] error5) {
        this.error5 = error5;
        this.crnError5 = new CrnError5();
    }
    public void setError6(boolean[] error6) {
        this.error6 = error6;
        this.crnError6 = new CrnError6();
    public void setTemp1(boolean[] temp1) {
        this.temp1 = temp1;
        this.crnTemp1 = new CrnTemp1();
        this.crnTemp1.liftLimitSwitchErr = temp1[0];
        this.crnTemp1.liftBrakeErr = temp1[1];
        this.crnTemp1.liftDiastimeterFau = temp1[2];
        this.crnTemp1.stop = temp1[3];
        this.crnTemp1.warn = temp1[4];
        this.crnTemp1.overHighErr = temp1[5];
        this.crnTemp1.leftOverWidthErr = temp1[6];
        this.crnTemp1.rightOverWidthErr = temp1[7];
        this.crnTemp1.leftOverLenErr = temp1[8];
        this.crnTemp1.rightOverLenErr = temp1[9];
        this.crnTemp1.pakinThenLoadedErr = temp1[10];
        this.crnTemp1.pakOutThenNoneErr = temp1[11];
    }
    /**
@@ -316,7 +282,9 @@
    public BasCrnp toSqlModel(BasCrnp basCrnp){
        basCrnp.setCrnErr(alarm1.longValue());
        if (alarm!=null) {
            basCrnp.setCrnErr(alarm.longValue());
        }
        basCrnp.setWrkNo(taskNo.intValue());
        return basCrnp;
    }
src/main/java/com/zy/core/model/protocol/CrnTemp1.java
New file
@@ -0,0 +1,47 @@
package com.zy.core.model.protocol;
import lombok.Data;
/**
 * Created by vincent on 2020/8/17
 */
@Data
public class CrnTemp1 {
    // 升降限位开关触发
    public boolean liftLimitSwitchErr;
    // 行走制动序列异常
    public boolean liftBrakeErr;
    // 行走测距器故障
    public boolean liftDiastimeterFau;
    // 急停
    public boolean stop;
    // 相序报警
    public boolean warn;
    // 超高
    public boolean overHighErr;
    // 左超宽
    public boolean leftOverWidthErr;
    // 右超宽
    public boolean rightOverWidthErr;
    // 左超长
    public boolean leftOverLenErr;
    // 右超长
    public boolean rightOverLenErr;
    // 有物入
    public boolean pakinThenLoadedErr;
    // 无物出
    public boolean pakOutThenNoneErr;
}
src/main/java/com/zy/core/model/protocol/StaProtocol.java
@@ -41,7 +41,7 @@
    private boolean inreq1;
    // 锁定标记
    private boolean pakMk;
    private boolean pakMk = true;
    public BasDevp toSqlModel(){
        BasDevp basDevp = new BasDevp();
src/main/java/com/zy/core/properties/SlaveProperties.java
@@ -3,6 +3,7 @@
import com.zy.core.Slave;
import com.zy.core.model.CrnSlave;
import com.zy.core.model.DevpSlave;
import com.zy.core.model.LedSlave;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@@ -24,7 +25,7 @@
    private List<Slave> barcode = new ArrayList<>();
    private List<Slave> led = new ArrayList<>();
    private List<LedSlave> led = new ArrayList<>();
    private List<Slave> scale = new ArrayList<>();
src/main/java/com/zy/core/thread/CrnThread.java
@@ -2,11 +2,11 @@
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import HslCommunication.Profinet.Melsec.MelsecMcNet;
import com.alibaba.fastjson.JSON;
import com.core.common.DateUtils;
import com.core.common.SpringUtils;
import com.core.exception.CoolException;
import com.zy.asrs.entity.BasCrnp;
import com.zy.asrs.service.BasCrnpService;
import com.zy.core.ThreadHandler;
@@ -33,9 +33,10 @@
@Slf4j
public class CrnThread implements Runnable, ThreadHandler {
    private SiemensS7Net siemensNet;
    private MelsecMcNet melsecMcNet;
    private CrnSlave slave;
    private CrnProtocol crnProtocol;
    private boolean resetFlag = false;
    public CrnThread(CrnSlave slave) {
        this.slave = slave;
@@ -48,7 +49,7 @@
        while (true) {
            try {
                int step = 1;
                Task task = MessageQueue.poll(SlaveType.Devp, slave.getId());
                Task task = MessageQueue.poll(SlaveType.Crn, slave.getId());
                if (task != null) {
                    step = task.getStep();
                }
@@ -93,19 +94,17 @@
    @Override
    public boolean connect() {
        boolean result = false;
        siemensNet = new SiemensS7Net(SiemensPLCS.S300, slave.getIp());
        siemensNet.setRack(slave.getRack().byteValue());
        siemensNet.setSlot(slave.getSlot().byteValue());
        OperateResult connect = siemensNet.ConnectServer();
        melsecMcNet = new MelsecMcNet(slave.getIp(), slave.getPort());
        OperateResult connect = melsecMcNet.ConnectServer();
        if(connect.IsSuccess){
            result = true;
            OutputQueue.CRN.offer(MessageFormat.format( "【{0}】堆垛机plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.info("堆垛机plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            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}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.error("堆垛机plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            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());
        }
        siemensNet.ConnectClose();
        melsecMcNet.ConnectClose();
        return result;
    }
@@ -113,60 +112,91 @@
     * 读取状态
     */
    private void readStatus(){
        OperateResultExOne<byte[]> result = siemensNet.Read("DB8.18", (short) 56);
        if (result.IsSuccess) {
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
            if (null == crnProtocol) {
                crnProtocol = new CrnProtocol();
            }
            crnProtocol.setMode(siemensNet.getByteTransform().TransInt16(result.Content, 0));
            crnProtocol.setTaskNo(siemensNet.getByteTransform().TransInt16(result.Content, 2));
            crnProtocol.setStatus(siemensNet.getByteTransform().TransInt16(result.Content, 4));
            crnProtocol.setBay(siemensNet.getByteTransform().TransInt16(result.Content, 6));
            crnProtocol.setLevel(siemensNet.getByteTransform().TransInt16(result.Content, 8));
            crnProtocol.setForkPos(siemensNet.getByteTransform().TransInt16(result.Content, 10));
            crnProtocol.setLiftPos(siemensNet.getByteTransform().TransInt16(result.Content, 12));
            crnProtocol.setWalkPos(siemensNet.getByteTransform().TransInt16(result.Content, 14));
//            crnProtocol.setTaskFinish(siemensNet.getByteTransform().TransInt16(result.Content, 16));
            crnProtocol.setLoaded(siemensNet.getByteTransform().TransInt16(result.Content, 18));
            crnProtocol.setAlarm1(siemensNet.getByteTransform().TransInt16(result.Content, 20));
            // 异常信息
            crnProtocol.setError1(siemensNet.getByteTransform().TransBool(result.Content, 22, 2));
            crnProtocol.setError2(siemensNet.getByteTransform().TransBool(result.Content, 24, 2));
            crnProtocol.setError3(siemensNet.getByteTransform().TransBool(result.Content, 26, 2));
            crnProtocol.setError4(siemensNet.getByteTransform().TransBool(result.Content, 28, 2));
            crnProtocol.setError5(siemensNet.getByteTransform().TransBool(result.Content, 30, 2));
            crnProtocol.setError6(siemensNet.getByteTransform().TransBool(result.Content, 32, 2));
            crnProtocol.setXSpeed(siemensNet.getByteTransform().TransSingle(result.Content, 34));
            crnProtocol.setYSpeed(siemensNet.getByteTransform().TransSingle(result.Content, 38));
            crnProtocol.setZSpeed(siemensNet.getByteTransform().TransSingle(result.Content, 42));
            crnProtocol.setXDistance(siemensNet.getByteTransform().TransSingle(result.Content, 46));
            crnProtocol.setYDistance(siemensNet.getByteTransform().TransSingle(result.Content, 50));
            crnProtocol.setXDuration(siemensNet.getByteTransform().TransSingle(result.Content, 54));
            crnProtocol.setYDuration(siemensNet.getByteTransform().TransSingle(result.Content, 58));
        try {
            /**
             *   当读到status == 90.任务完成等待WCS确认 时
             *   下发任务完成指令
             */
            if (crnProtocol.getStatusType().equals(CrnStatusType.WAITING)) {
                CrnCommand crnCommand = new CrnCommand();
                crnCommand.setAckFinish((short)1);
                write(crnCommand);
            }
            /* 方法1 */
            OperateResultExOne<byte[]> result = melsecMcNet.Read("D2231", (short) 62);
            if (result.IsSuccess) {
                if (null == crnProtocol) {
                    crnProtocol = new CrnProtocol();
                }
                crnProtocol.setMode(melsecMcNet.getByteTransform().TransInt16(result.Content, 0));
                crnProtocol.setTaskNo(melsecMcNet.getByteTransform().TransInt16(result.Content, 4));
                crnProtocol.setStatus(melsecMcNet.getByteTransform().TransInt16(result.Content, 6));
                crnProtocol.setBay(melsecMcNet.getByteTransform().TransInt16(result.Content, 8));
                crnProtocol.setLevel(melsecMcNet.getByteTransform().TransInt16(result.Content, 10));
                crnProtocol.setForkPos(melsecMcNet.getByteTransform().TransInt16(result.Content, 12));
                crnProtocol.setLiftPos(melsecMcNet.getByteTransform().TransInt16(result.Content, 14));
                crnProtocol.setWalkPos(melsecMcNet.getByteTransform().TransInt16(result.Content, 16));
//               crnProtocol.setTaskFinish(melsecMcNet.getByteTransform().TransInt16(result.Content, 18));
                crnProtocol.setLoaded(melsecMcNet.getByteTransform().TransInt16(result.Content, 20));
                crnProtocol.setAlarm(melsecMcNet.getByteTransform().TransInt16(result.Content, 22));
                crnProtocol.setError1(melsecMcNet.getByteTransform().TransBool(result.Content, 24, 2));
                crnProtocol.setTemp1(melsecMcNet.getByteTransform().TransBool(result.Content, 26, 2));
                crnProtocol.setTemp2(melsecMcNet.getByteTransform().TransInt16(result.Content, 28));
                crnProtocol.setTemp3(melsecMcNet.getByteTransform().TransInt16(result.Content, 30));
                crnProtocol.setTemp4(melsecMcNet.getByteTransform().TransInt16(result.Content, 32));
                crnProtocol.setXSpeed(melsecMcNet.getByteTransform().TransSingle(result.Content, 34));
                crnProtocol.setYSpeed(melsecMcNet.getByteTransform().TransSingle(result.Content, 38));
                crnProtocol.setZSpeed(melsecMcNet.getByteTransform().TransSingle(result.Content, 42));
                crnProtocol.setXDistance(melsecMcNet.getByteTransform().TransSingle(result.Content, 46));
                crnProtocol.setYDistance(melsecMcNet.getByteTransform().TransSingle(result.Content, 50));
                crnProtocol.setXDuration(melsecMcNet.getByteTransform().TransSingle(result.Content, 54));
                crnProtocol.setYDuration(melsecMcNet.getByteTransform().TransSingle(result.Content, 58));
            // 根据实时信息更新数据库
            BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class);
            BasCrnp basCrnp = new BasCrnp();
            basCrnp.setCrnNo(slave.getId());
            if (basCrnpService.updateById(crnProtocol.toSqlModel(basCrnp))){
                log.error("堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            }
                OutputQueue.CRN.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), slave.getId()));
        } else {
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】读取堆垛机plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.error("读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
                // 复位信号
                if (crnProtocol.getStatusType().equals(CrnStatusType.WAITING)) {
                    if (resetFlag) {
                        if (melsecMcNet.Write("D2218", (short) 1).IsSuccess) {
                            resetFlag = false;
                        }
                    }
                }
                // 根据实时信息更新数据库
                BasCrnpService basCrnpService = SpringUtils.getBean(BasCrnpService.class);
                BasCrnp basCrnp = new BasCrnp();
                basCrnp.setCrnNo(slave.getId());
                if (!basCrnpService.updateById(crnProtocol.toSqlModel(basCrnp))){
                    log.error("堆垛机plc数据库更新失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
                }
            } else {
                OutputQueue.CRN.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()));
            }
            /* 方法2 */
//            crnProtocol.setMode(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setTaskNo(melsecMcNet.ReadInt16("D2233").Content);
//            crnProtocol.setStatus(melsecMcNet.ReadInt16("D2234").Content);
//            crnProtocol.setBay(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setLevel(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setForkPos(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setLiftPos(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setWalkPos(melsecMcNet.ReadInt16("D2231").Content);
////            crnProtocol.setTaskFinish(siemensNet.getByteTransform().TransInt16(result.Content, 16));
//            crnProtocol.setLoaded(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setAlarm(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setError1(melsecMcNet.ReadBool("D2231", (short) 2).Content);
//            crnProtocol.setTemp1(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setTemp2(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setTemp3(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setTemp4(melsecMcNet.ReadInt16("D2231").Content);
//            crnProtocol.setXSpeed(melsecMcNet.ReadFloat("D2231").Content);
//            crnProtocol.setYSpeed(melsecMcNet.ReadFloat("D2231").Content);
//            crnProtocol.setZSpeed(melsecMcNet.ReadFloat("D2231").Content);
//            crnProtocol.setXDistance(melsecMcNet.ReadFloat("D2231").Content);
//            crnProtocol.setYDistance(melsecMcNet.ReadFloat("D2231").Content);
//            crnProtocol.setXDuration(melsecMcNet.ReadFloat("D2231").Content);
//            crnProtocol.setYDuration(melsecMcNet.ReadFloat("D2231").Content);
        } 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()));
            log.error("读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
        }
    }
    /**
@@ -178,38 +208,65 @@
            return;
        }
        command.setCrnNo(slave.getId());
        short[] array = new short[9];
        array[0] = command.getAckFinish();
        array[1] = command.getTaskNo();
        array[2] = command.getTaskMode();
        array[3] = command.getSourcePosX();
        array[4] = command.getSourcePosY();
        array[5] = command.getSourcePosZ();
        array[6] = command.getDestinationPosX();
        array[7] = command.getDestinationPosY();
        array[8] = command.getDestinationPosZ();
        OperateResult result = siemensNet.Write("DB8.0", array);
        if (result.IsSuccess) {
            System.out.println(MessageFormat.format("【{0}】[id:{1}] >>>>> {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(command)));
        /* 方法 1 */
        do {
            if (command.getDestinationPosZ() != null) {
                if (!melsecMcNet.Write("D2202", command.getDestinationPosZ()).IsSuccess) { break; }
            }
            if (command.getDestinationPosY() != null) {
                if (!melsecMcNet.Write("D2204", command.getDestinationPosY()).IsSuccess) { break; }
            }
            if (command.getDestinationPosX() != null) {
                if (!melsecMcNet.Write("D2208", command.getDestinationPosX()).IsSuccess) { break; }
            }
            if (command.getSourcePosZ() != null) {
                if (!melsecMcNet.Write("D2210", command.getSourcePosZ()).IsSuccess) { break; }
            }
            if (command.getSourcePosY() != null) {
                if (!melsecMcNet.Write("D2212", command.getSourcePosY()).IsSuccess) { break; }
            }
            if (command.getDestinationPosX() != null) {
                if (!melsecMcNet.Write("D2214", command.getSourcePosX()).IsSuccess) { break; }
            }
            if (command.getTaskMode() != null) {
                if (!melsecMcNet.Write("D2216", command.getTaskMode()).IsSuccess) { break; }
            }
            if (command.getTaskNo() != null) {
                if (!melsecMcNet.Write("D2217", command.getTaskNo()).IsSuccess) { break; }
            }
            if (command.getAckFinish() != null) {
                if (!melsecMcNet.Write("D2218", command.getAckFinish()).IsSuccess) { break; }
            }
            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)));
//            readStatus();
        } else {
            System.out.println(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            OutputQueue.CRN.offer(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.error("写入堆垛机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
        }
            return;
        } while (false);
        System.out.println(MessageFormat.format("【{0}】写入堆垛机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
        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());
        /* 方法 2 */
//        melsecMcNet.Write("D2218", command.getAckFinish());
//        melsecMcNet.Write("D2217", command.getTaskNo());
//        melsecMcNet.Write("D2216", command.getTaskMode());
//        melsecMcNet.Write("D2214", command.getSourcePosX());
//        melsecMcNet.Write("D2212", command.getSourcePosY());
//        melsecMcNet.Write("D2210", command.getSourcePosZ());
//        melsecMcNet.Write("D2208", command.getDestinationPosX());
//        melsecMcNet.Write("D2204", command.getDestinationPosY());
//        melsecMcNet.Write("D2202", command.getDestinationPosZ());
    }
    @Override
    public void close() {
        siemensNet.ConnectClose();
    }
    public CrnProtocol getCrnProtocol(){
        if (crnProtocol == null) {
            readStatus();
        }
        return this.crnProtocol;
        melsecMcNet.ConnectClose();
    }
@@ -219,14 +276,14 @@
    public static void main(String[] args) throws InterruptedException {
        CrnSlave slave = new CrnSlave();
        slave.setId(1);
        slave.setIp("192.168.6.9");
        slave.setIp("192.168.3.39");
        slave.setPort(5015);
        slave.setRack(0);
        slave.setSlot(0);
        CrnThread crnThread = new CrnThread(slave);
        crnThread.connect();
        crnThread.readStatus();
        System.out.println(JSON.toJSONString(crnThread.crnProtocol));
        Thread.sleep(3000L);
        // 1.入库 源和目标都发
//        CrnCommand command = new CrnCommand();
@@ -299,19 +356,19 @@
//        command.setDestinationPosZ((short) 0);     // 目标库位层
//        crnThread.write(command);
//        // 7.坐标移行   目标发   pass
//        CrnCommand command = new CrnCommand();
//        command.setCrnNo(1); // 堆垛机编号
//        command.setTaskNo((short) 0); // 工作号
//        command.setAckFinish((short) 0);  // 任务完成确认位
//        command.setTaskMode(CrnTaskModeType.OFFSET_MOVE); // 任务模式
//        command.setSourcePosX((short) 0);     // 源库位排
//        command.setSourcePosY((short) 0);     // 源库位列
//        command.setSourcePosZ((short) 0);     // 源库位层
//        command.setDestinationPosX((short) 2);     // 目标库位排
//        command.setDestinationPosY((short) 1);     // 目标库位列
//        command.setDestinationPosZ((short) 1);     // 目标库位层
//        crnThread.write(command);
        // 7.坐标移行   目标发   pass
        CrnCommand command = new CrnCommand();
        command.setCrnNo(1); // 堆垛机编号
        command.setTaskNo((short) 0); // 工作号
        command.setAckFinish((short) 0);  // 任务完成确认位
        command.setTaskMode(CrnTaskModeType.OFFSET_MOVE); // 任务模式
        command.setSourcePosX((short) 0);     // 源库位排
        command.setSourcePosY((short) 0);     // 源库位列
        command.setSourcePosZ((short) 0);     // 源库位层
        command.setDestinationPosX((short) 1);     // 目标库位排
        command.setDestinationPosY((short) 3);     // 目标库位列
        command.setDestinationPosZ((short) 3);     // 目标库位层
        crnThread.write(command);
        // 只有出现指定异常才进行复位
//        if (crnThread.crnProtocol.getCrnError2().leftTakeNoneErr
src/main/java/com/zy/core/thread/DevpThread.java
@@ -2,8 +2,7 @@
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import HslCommunication.Profinet.Melsec.MelsecMcNet;
import com.alibaba.fastjson.JSON;
import com.core.common.DateUtils;
import com.core.common.SpringUtils;
@@ -35,7 +34,7 @@
public class DevpThread implements Runnable, ThreadHandler {
    private DevpSlave slave;
    private SiemensS7Net siemensS7Net;
    private MelsecMcNet melsecMcNet;
    private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>();
    private short heartBeatVal = 1;
@@ -76,7 +75,7 @@
                }
                // 心跳
                heartbeat();
//                heartbeat();
                Thread.sleep(400);
            } catch (Exception e) {
                e.printStackTrace();
@@ -88,27 +87,25 @@
    @Override
    public boolean connect() {
        boolean result = false;
        siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, slave.getIp());
        siemensS7Net.setRack(slave.getRack().byteValue());
        siemensS7Net.setSlot(slave.getSlot().byteValue());
        OperateResult connect = siemensS7Net.ConnectServer();
        melsecMcNet = new MelsecMcNet(slave.getIp(), slave.getPort());
        OperateResult connect = melsecMcNet.ConnectServer();
        if(connect.IsSuccess){
            result = true;
            OutputQueue.DEVP.offer(MessageFormat.format( "【{0}】输送线plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            OutputQueue.DEVP.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.DEVP.offer(MessageFormat.format( "【{0}】输送线plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]  [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            OutputQueue.DEVP.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());
        }
        siemensS7Net.ConnectClose();
        melsecMcNet.ConnectClose();
        return result;
    }
    /**
     * 读取状态 ====> 整块plc
     */
    private void read(){
        OperateResultExOne<byte[]> result = siemensS7Net.Read("DB100.0", (short) 40);
    private void read() throws InterruptedException {
        OperateResultExOne<byte[]> result = melsecMcNet.Read("D101", (short) 30);
        if (result.IsSuccess) {
            for (int i = 1; i <= 8; i++) {
                StaProtocol staProtocol = station.get(i);
@@ -117,20 +114,24 @@
                    staProtocol.setSiteId(i);
                    station.put(i, staProtocol);
                }
                staProtocol.setWorkNo(siemensS7Net.getByteTransform().TransInt16(result.Content, (i-1)*2));     // 工作号
                staProtocol.setStaNo(siemensS7Net.getByteTransform().TransInt16(result.Content, (i-1)*2+20));   // 目标站
                staProtocol.setWorkNo(melsecMcNet.getByteTransform().TransInt16(result.Content, (i-1)*2));     // 工作号
                staProtocol.setStaNo(melsecMcNet.getByteTransform().TransInt16(result.Content, (i-1)*2+40));   // 目标站
            }
        }
        OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB100.40", (short) 8);
        Thread.sleep(100);
        OperateResultExOne<boolean[]> result1 = melsecMcNet.ReadBool("M800", (short) 64);
        if (result1.IsSuccess) {
            for (int i = 1; i <= 8; i++) {
                boolean[] status = siemensS7Net.getByteTransform().TransBool(result1.Content, i-1, 1);
                StaProtocol staProtocol = station.get(i);
                staProtocol.setAutoing(status[0]);  // 自动
                staProtocol.setLoading(status[1]);  // 有物
                staProtocol.setInEnable(status[2]); // 可入
                staProtocol.setOutEnable(status[3]);// 可出
                staProtocol.setEmptyMk(status[4]);  // 空板信号
                staProtocol.setAutoing(result1.Content[(i-1)*8]);  // 自动
                staProtocol.setLoading(result1.Content[(i-1)*8+1]);  // 有物
                staProtocol.setInEnable(result1.Content[(i-1)*8+2]); // 可入
                staProtocol.setOutEnable(result1.Content[(i-1)*8+3]);// 可出
                staProtocol.setEmptyMk(result1.Content[(i-1)*8+4]);  // 空板信号
                if (!staProtocol.isPakMk() && !staProtocol.isLoading()) {
                    staProtocol.setPakMk(true);
                }
            }
        }
        if (result.IsSuccess && result1.IsSuccess) {
@@ -148,25 +149,26 @@
                    throw new Exception("更新数据库数据失败");
                }
            } catch (Exception e) {
                OutputQueue.DEVP.offer(MessageFormat.format("【{0}】更新数据库数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
                log.error("更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
                OutputQueue.DEVP.offer(MessageFormat.format("【{0}】更新数据库数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort()));
                log.error("更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
            }
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】读取输送线plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            log.error("读取堆垛机plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            OutputQueue.DEVP.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());
        }
    }
    /**
     * 写入 ID+目标站 =====> 单站点写入
     */
    private void write(StaProtocol staProtocol){
    private void write(StaProtocol staProtocol) throws InterruptedException {
        if (null == staProtocol) {
            return;
        }
        OperateResult write = siemensS7Net.Write("DB100." + (staProtocol.getSiteId() - 1) * 2, staProtocol.getWorkNo());    // 工作号
        OperateResult write1 = siemensS7Net.Write("DB100." + ((staProtocol.getSiteId() - 1) * 2 + 20), staProtocol.getStaNo());    // 目标站
        OperateResult write = melsecMcNet.Write("D10" + staProtocol.getSiteId(), staProtocol.getWorkNo());    // 工作号
        Thread.sleep(100);
        OperateResult write1 = melsecMcNet.Write("D12" + staProtocol.getSiteId(), staProtocol.getStaNo());    // 目标站
//        boolean[] status = new boolean[8];
//        status[0] = staProtocol.isAutoing();
//        status[1] = staProtocol.isLoading();
@@ -175,10 +177,14 @@
//        status[4] = staProtocol.isEmptyMk();
//        OperateResult write2 = siemensS7Net.Write("DB100." + ((staProtocol.getSiteId() - 1) + 40), status);     //  状态
        if (!write.IsSuccess || !write1.IsSuccess) {
            if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) {
                staProtocol.setPakMk(true);
            }
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol)));
            log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol));
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(staProtocol)));
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), slave.getId(), JSON.toJSON(staProtocol)));
            log.info("输送线命令下发 [id:{}] >>>>> 命令下发: {}",  slave.getId(), JSON.toJSON(staProtocol));
        }
    }
@@ -189,7 +195,7 @@
        if (null == staProtocol) {
            return;
        }
        OperateResult write = siemensS7Net.Write("DB100." + (staProtocol.getSiteId() - 1) * 2, staProtocol.getWorkNo());    // 工作号
        OperateResult write = melsecMcNet.Write("D10" + staProtocol.getSiteId(), staProtocol.getWorkNo());    // 工作号
        if (!write.IsSuccess ) {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol)));
            log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol));
@@ -205,7 +211,7 @@
        if (null == staProtocol) {
            return;
        }
        OperateResult write = siemensS7Net.Write("DB100." + ((staProtocol.getSiteId() - 1) * 2 + 20), staProtocol.getStaNo());    // 目标站
        OperateResult write = melsecMcNet.Write("D12" + staProtocol.getSiteId(), staProtocol.getStaNo());    // 目标站
        if (!write.IsSuccess ) {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol)));
            log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol));
@@ -223,7 +229,7 @@
        } else {
            heartBeatVal = 1;
        }
        OperateResult write = siemensS7Net.Write("DB100.50", heartBeatVal);
        OperateResult write = melsecMcNet.Write("DB100.50", heartBeatVal);
        if (!write.IsSuccess) {
            log.error("输送线plc编号={} 心跳失败", slave.getId());
        }
@@ -231,26 +237,36 @@
    @Override
    public void close() {
        siemensS7Net.ConnectClose();
        melsecMcNet.ConnectClose();
    }
    public static void main(String[] args) {
    public static void main(String[] args) throws Exception {
        DevpSlave slave = new DevpSlave();
        slave.setIp("192.168.2.125");
        slave.setIp("192.168.3.65");
        slave.setPort(6000);
        DevpThread devpThread = new DevpThread(slave);
        devpThread.connect();
        devpThread.read();
        OperateResult d1021 = devpThread.melsecMcNet.Write("D102", (short) 234);
        if (d1021.IsSuccess) {
            System.out.println("success");
        }
        OperateResultExOne<Short> d102 = devpThread.melsecMcNet.ReadInt16("D102");
        System.out.println(d102.Content);
//        devpThread.read();
        System.out.println("第一次读");
        // 写
        StaProtocol staProtocol = devpThread.getStation().get(1);
        staProtocol.setWorkNo((short) 232);
        staProtocol.setStaNo((short) 6);
        staProtocol.setAutoing(true);
        staProtocol.setEmptyMk(true);
        staProtocol.setInEnable(true);
        devpThread.write(staProtocol);
        System.out.println("----------------------------------------");
//        StaProtocol staProtocol = devpThread.getStation().get(1);
//        staProtocol.setWorkNo((short) 232);
//        staProtocol.setStaNo((short) 6);
//        staProtocol.setAutoing(true);
//        staProtocol.setEmptyMk(true);
//        staProtocol.setInEnable(true);
//        devpThread.write(staProtocol);
//        System.out.println("----------------------------------------");
        Thread.sleep(400);
        // 读
        devpThread.read();
//        devpThread.read();
        System.out.println("第二次读");
        System.out.println(JSON.toJSONString(devpThread.station));
    }
src/main/java/com/zy/core/thread/LedThread.java
New file
@@ -0,0 +1,355 @@
package com.zy.core.thread;
import com.zy.common.model.MatDto;
import com.zy.core.Slave;
import com.zy.core.ThreadHandler;
import com.zy.core.cache.MessageQueue;
import com.zy.core.enums.SlaveType;
import com.zy.core.model.Task;
import com.zy.core.model.command.LedCommand;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import onbon.bx05.Bx5GEnv;
import onbon.bx05.Bx5GException;
import onbon.bx05.Bx5GScreen;
import onbon.bx05.Bx5GScreenClient;
import onbon.bx05.area.TextCaptionBxArea;
import onbon.bx05.area.page.TextBxPage;
import onbon.bx05.file.ProgramBxFile;
import onbon.bx05.message.led.ReturnControllerStatus;
import onbon.bx05.utils.DisplayStyleFactory;
import java.awt.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
 * Created by vincent on 2020/9/1
 */
@Data
@Slf4j
public class LedThread implements Runnable, ThreadHandler {
    private Slave slave;
    private Bx5GScreenClient screen;
    ProgramBxFile pf;
    TextCaptionBxArea area;
    DisplayStyleFactory.DisplayStyle[] styles = DisplayStyleFactory.getStyles().toArray(new DisplayStyleFactory.DisplayStyle[0]);
    private Set<Integer> workNos = new HashSet<>();
    public LedThread(Slave slave) {
        this.slave = slave;
        try {
            Bx5GEnv.initial(3000);
            screen = new Bx5GScreenClient("my");
            screen.turnOn();
            pf = new ProgramBxFile( 0, screen.getProfile());
            pf.setFrameShow(false);
            // 分别输入X,Y,width,height
            area = new TextCaptionBxArea( 0,0,192,128,screen.getProfile());
        } catch (Exception e) {
            e.printStackTrace();
            log.info("led连接构造器错误 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
        }
    }
    @Override
    @SuppressWarnings({"InfiniteLoopStatement", "unchecked"})
    public void run() {
        connect();
        while (true) {
            try {
                Task task = MessageQueue.poll(SlaveType.Led, slave.getId());
                if (task != null) {
                    switch (task.getStep()) {
                        // 写数据
                        case 1:
                            write((List<LedCommand>)task.getData());
                            break;
                        default:
                            break;
                    }
                }
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public boolean connect() {
        boolean connRes = false;
        try {
            connRes = screen.connect(slave.getIp(),slave.getPort());
        } catch (Exception ignore) {
        }
        if (connRes) {
            log.info("led连接成功 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
        } else {
            log.error("led连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
        }
        return connRes;
    }
    @Override
    public void close() {
        screen.disconnect();
    }
    private void write(List<LedCommand> list) throws Bx5GException {
        // 创建一个数据页
        TextBxPage page = new TextBxPage();
        for (LedCommand command : list) {
            page.newLine("出库任务("+command.getWorkNo()+")");
            page.newLine("源库位:"+command.getSourceLocNo());
            page.newLine("目标站:"+command.getStaNo());
            for (MatDto matDto : command.getMatDtos()) {
                page.newLine(matDto.getMaknx() + "【数量" + matDto.getCount() +"】");
            }
            page.newLine("\n");
        }
        // 设置字体
        page.setFont(new Font("宋体",Font.PLAIN,12));
        // 设置显示特技为快速打出
        page.setDisplayStyle(styles[6]);
        area.addPage(page);
        pf.addArea(area);
        // 更新节目
        screen.writeProgram(pf);
    }
    public static void main(String[] args) throws Exception {
        Bx5GEnv.initial(3000);
        Bx5GScreenClient screen = new Bx5GScreenClient("my");
        DisplayStyleFactory.DisplayStyle[] styles = DisplayStyleFactory.getStyles().toArray(new DisplayStyleFactory.DisplayStyle[0]);
        if (!screen.connect("192.168.10.61",5005)) {
            System.err.println("连接失败!!!!");
            return;
        }
        screen.turnOn();
        ProgramBxFile pf = new ProgramBxFile( 0, screen.getProfile());
        pf.setFrameShow(false);
        // 分别输入X,Y,width,heigth
        TextCaptionBxArea area = new TextCaptionBxArea( 0,0,192,128,screen.getProfile());
        // 创建一个数据页
        // 第一行数据
        TextBxPage page = new TextBxPage("全板入库");
        page.newLine("目标库位:0100204");
        // 第二行数据
        page.newLine("接收器 RX18 XH 6V 【数量:2】");
        page.newLine("中控 BM蓝牙 英文 6V 【数量:1】");
        page.newLine("线束 S2588-1-XX 无实物【数量:5】");
        page.newLine("接收器 RX18 XH 6V 【数量:2】");
        page.newLine("中控 BM蓝牙 英文 6V 【数量:1】");
        page.newLine("线束 S2588-1-XX 无实物【数量:5】");
        page.newLine("接收器 RX18 XH 6V 【数量:2】");
        page.newLine("中控 BM蓝牙 英文 6V 【数量:1】");
        page.newLine("线束 S2588-1-XX 无实物【数量:5】");
        // 设置字体
        page.setFont( new Font("宋体",Font.PLAIN,12));
        // 设置显示特技为快速打出
        page.setDisplayStyle(styles[6]);
        area.addPage(page);
        pf.addArea( area );
        // 更新节目
        screen.writeProgram(pf);
        // 继开与控制器之间的链接
        screen.disconnect();
    }
    public static void main1(String[] args) throws Exception {
        Bx5GEnv.initial(3000);
        // 创建screen对象,用于对控制器进行访问,客户端模式
        Bx5GScreenClient screen = new Bx5GScreenClient("my");
        // 创建screen对象,用于对控制器进行访问,串口模式
        //        Bx5GScreenRS screen = new Bx5GScreenRS("MyScreen");
        // 在对控制器交互之前,需要先与控制器建立连接
        boolean conn = screen.connect("192.168.10.61",5005);
        System.out.println(conn);
        // 与控制器交互完成后,需断开与控制器之间的连接
//        screen.disconnect();
        // 以下为一些简单控制命令的使用方法
        // 开关机命令
//        screen.turnOff();// 关机
        screen.turnOn();// 开机
//        screen.syncTime();// 校时
//        screen.ping();// ping命令
//        // 查询控制器状态
//        screen.checkControllerStatus();
//        // 查询控制器当前固件版本
//        screen.checkFirmware();
//        // 查询控制器内存
//        screen.checkMemVolumes();
//        // 锁定屏幕当前画面
//        screen.lock();
//        // 解除锁定屏幕当前画面
//        screen.unlock();
        Bx5GScreen.Result <ReturnControllerStatus> result1 =
                screen.checkControllerStatus();
        if (result1.isOK())
        {
            ReturnControllerStatus status = result1.reply;
            System.out.println(status.getBrightness());
            System.out.println(status.getRtcDay());
            System.out.println(status.getScreenOnOff());
            //
            // status 还有很对其他接口,可以根据实际需求再次调用以获取相应状态
        }
//
        // 以下是静态区部分 Demo
        // 创建节目文件
        ProgramBxFile pf = new ProgramBxFile( 0,screen.getProfile() );
// 是否显示节目边框
        pf.setFrameShow(true);
// 节目边框的移动速度
        pf.setFrameSpeed(20);
// 使用第几个内置边框
        pf.loadFrameImage(13);
        DisplayStyleFactory.DisplayStyle[] styles = DisplayStyleFactory.getStyles().toArray(new DisplayStyleFactory.DisplayStyle[0]);
// 创建一个文本区
        // 分别输入X,Y,width,heigth
        // 注意区域坐标和宽度高度,不要越界
        TextCaptionBxArea area = new TextCaptionBxArea( 0,0,160,64,screen.getProfile() );
        // 创建一个数据页
        // 第一行数据
        TextBxPage page = new TextBxPage("入库");
        // 第二行数据
        page.newLine( "物料:" );
        page.newLine("接收器 RX18 XH 6V (数量:2)");
        page.newLine("中控 BM蓝牙 英文 6V (数量:1)");
        page.newLine("线束 S2588-1-XX 无实物(数量:5)");
        page.newLine("目标库位:0100204");
        // 设置字体
        page.setFont( new Font("宋体",Font.PLAIN,12) );
        // 设置显示特技为快速打出
        page.setDisplayStyle( styles[2] );
        // 数据页可以是图片
//        ImageFileBxPage iPage = new ImageFileBxPage( "E;a/001.bmp" );
//
//        // 数据页可以是txt文件
//        TextFileBxPage tPage  = new TextFileBxPage("E:a/001.txt");
        // 将前面的page添加到area中 area中可以添加多个page 其中page可以是字符串,可以是txt文件,可以是图片,不可以是表格,如果需要Led屏上显示表格,请先将表格绘制成图片
        area.addPage( page );
//        area.addPage( iPage );
//        area.addPage( tPage );
        // 将area添加到节目中  节目中可以添加多个area
        pf.addArea( area );
        // 更新节目
        screen.writeProgram( pf );
        //
        // 以下是动态区部分 Demo
        // 动态区的特点
        // DynamicBxAreaRule(id, runMode, immediatePlay, timeout)
        // runMode 运行模式:
        //   0:循环显示。
        //   1:显示完成后静止显示最后一页数据。
        //   2:循环显示,超过设定时间后数据仍未更新时不再显示。
        //   3:循环显示,超过设定时间后数据仍未更新时显示 Logo 信息。
        //   4:循环显示,显示完最后一页后就不再显示。
        // immediatePlay 是否立即播放:
        //   0:与异步节目一起播放。
        //   1:异步节目停止播放,仅播放动态区域。
        //   2:当播放完节目编号最高的异步节目后播放该动态区域。
        //
        // 定义一个动态区
        // 可以通过ID来更新不同的动态区内容, 此处 ID 为 0
//        DynamicBxAreaRule dynRule = new DynamicBxAreaRule(0, (byte) 0, (byte) 1, 0);
        //dArea.addProgram("P000");
        //dArea.addProgram("P001");
//        int posX = 440;
//        int posY = 4;
//        TextCaptionBxArea dAreaContent = new TextCaptionBxArea(posX, posY, 64, 16, screen.getProfile());
//        TextBxPage page = new TextBxPage("动态第一次尝试");
//        page.setDisplayStyle(DisplayStyleFactory.getStyle(4));
//        dAreaContent.addPage(page);
//
//        // 发送动态区之前,如果需要删除之前的动态区,可以调用以下接口
//        // 通常如果动态区的位置或大小没有发生改变,不用删除
//        screen.deleteAllDynamic();
//
//        // 更新动态区
//        screen.writeDynamic(dynRule, dAreaContent);
//        Thread.sleep(15000);
//
//        //
//        // 下面模拟再次更新动态区
//        page = new TextBxPage("再次尝试");
//        TextBxPage page2 = new TextBxPage("成功");
//
//        dAreaContent.clearPages();
//        dAreaContent.addPage(page);
//        dAreaContent.addPage(page2);
//
//        // 更新动态区
//        screen.writeDynamic(dynRule, dAreaContent);
        //
        // 继开与控制器之间的链接
        screen.disconnect();
    }
}
src/main/resources/application.yml
@@ -1,15 +1,18 @@
server:
  port: 9090
  servlet:
    context-path: /@pom.build.finalName@
    context-path: /gdwcs
spring:
  application:
    name: @pom.build.finalName@
    name: gdwcs
  datasource:
    # sql-server
    driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
    url: jdbc:sqlserver://127.0.0.1:1433;databasename=jsasrs
    #url: jdbc:sqlserver://192.168.3.99:1433;databasename=gdasrs
    #username: sa
    #password: eisoft
    url: jdbc:sqlserver://localhost:1433;databasename=gdasrs
    username: sa
    password: sa@123
  mvc:
@@ -22,11 +25,11 @@
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  global-config:
    field-strategy: 0
#  global-config:
#    field-strategy: 0
logging:
  path: /stock/out/logs
  path: /stock/out/wcs/logs
super:
  pwd: xltys1995
@@ -35,64 +38,106 @@
  enable: false
# 下位机配置
#wcs-slave:
  # 堆垛机
wcs-slave:
  # 堆垛机1
  crn[0]:
    id: 1
    ip: 192.168.6.9
    port: 102
    ip: 192.168.10.39
    port: 5015
    rack: 0
    slot: 0
    # 偏移量,当堆垛机站点列号=1时,偏移量=0
    offset: 1
    # 偏移量,当堆垛机站点列号=1时,偏移量=2
    offset: 2
    # 堆垛机入库站点
    crnInStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 5
      staNo: 4
      row: 2
      bay: 1
      lev: 1
    # 堆垛机出库站点
    crnOutStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 6
      staNo: 2
      row: 1
      bay: 1
      lev: 1
    # 堆垛机2
  crn[1]:
    id: 2
    ip: 192.168.10.40
    port: 5016
    rack: 0
    slot: 0
    # 偏移量,当堆垛机站点列号=1时,偏移量=0
    offset: 2
    # 堆垛机入库站点
    crnInStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 8
      row: 4
      bay: 1
      lev: 1
    # 堆垛机出库站点
    crnOutStn[0]:
      devpPlcId: ${wcs-slave.devp[0].id}
      staNo: 6
      row: 3
      bay: 1
      lev: 1
  # 输送线
  devp[0]:
    id: 1
    ip: 192.168.2.125
    port: 102
    ip: 192.168.10.65
    port: 6000
    rack: 0
    slot: 1
    # 入库口
    # 入库口1
    inSta[0]:
      staNo: 2
      staNo: 3
      barcode: ${wcs-slave.barcode[0].id}
    # 空板入库口
    # 入库口2
    inSta[1]:
      staNo: 7
      barcode: ${wcs-slave.barcode[0].id}
    # 空板入库口1
    emptyInSta[0]:
      staNo: 2
    # 出库口
      staNo: 3
    # 空板入库口2
    emptyInSta[1]:
      staNo: 7
    # 出库口1
    outSta[0]:
      staNo: 6
      staNo: 1
    # 出库口2
    outSta[1]:
      staNo: 5
    # 拣料入库口
    pickSta[0]:
      staNo: 2
  # 条码扫描仪
  barcode[0]:
    id: 1
    ip: 192.168.2.150
    ip: 192.168.10.150
    port: 51236
  # LED
  # LED1
  led[0]:
    id: 1
    ip: 192.168.1.1
    port: 8888
    ip: 192.168.10.61
    port: 5005
    devpPlcId: ${wcs-slave.devp[0].id}
    staArr: 1,2
  # LED2
  led[1]:
    id: 2
    ip: 192.168.10.62
    port: 5005
    devpPlcId: ${wcs-slave.devp[0].id}
    staArr: 5,6
  # 磅称
  scale[0]:
    id: 1
    ip: 192.168.1.1
    ip: 192.168.10.152
    port: 8888
src/main/resources/lib/slf4j-api-1.7.30.jar
Binary files differ
src/main/resources/lib/slf4j-simple-1.7.30.jar
Binary files differ
src/main/resources/mapper/WrkMastMapper.xml
@@ -75,4 +75,36 @@
        order by io_time,wrk_no asc
    </select>
    <select id="selectPakInStep1" resultMap="BaseResultMap">
        select top 1 * from asr_wrk_mast where source_sta_no=#{sourceStaNo} and wrk_sts=2 and barcode=#{barcode} and (io_type=1 or io_type=10) order by io_pri desc,io_time,wrk_no ASC
    </select>
    <select id="selectPakInStep11" resultMap="BaseResultMap">
        select top 1 * from asr_wrk_mast where source_sta_no=#{sourceStaNo} and wrk_sts=1 and (io_type=1 or io_type=10) order by io_pri desc,io_time,wrk_no ASC
    </select>
    <select id="selectPakInStep2" resultMap="BaseResultMap">
        select top 1 * from dbo.asr_wrk_mast where wrk_sts=2 and crn_no=#{crnNo} and wrk_no=#{workNo} and (io_type=1 or io_type=10 or io_type=53 or io_type=54 or io_type=57) order by io_pri desc,io_time,wrk_no ASC
    </select>
    <select id="selectPakInStep3" resultMap="BaseResultMap">
        select top 1 * from dbo.asr_wrk_mast where wrk_no=#{workNo}
    </select>
    <select id="selectPickStep" resultMap="BaseResultMap">
        select top 1 * from asr_wrk_mast where wrk_no=#{workNo} and wrk_sts=14 and (io_type=103 or io_type=107 or io_type=104)
    </select>
    <select id="selectPakOutStep1" resultMap="BaseResultMap">
        select top 1 * from dbo.asr_wrk_mast where crn_no=#{crnNo} and wrk_sts=11 and io_type>100 order by io_pri desc,io_time,wrk_no asc
    </select>
    <select id="selectPakOutStep2" resultMap="BaseResultMap">
        select top 1 * from dbo.asr_wrk_mast where source_sta_no=#{sourceStaNo} and wrk_sts=12 and io_type>100 order by io_pri desc,io_time desc,wrk_no ASC
    </select>
    <select id="selectLocMove" resultMap="BaseResultMap">
        select top 1 * from dbo.asr_wrk_mast where wrk_sts=11 and io_type=11 and crn_no=#{crnNo} order by io_time,wrk_no
    </select>
</mapper>
src/main/webapp/static/css/console.css
@@ -118,7 +118,7 @@
}
/* 输送线第一列 */
.site-row-1 {
    left: 200px;
    left: 100px;
}
.site-row-1 .site {
    width: 100px;
@@ -162,40 +162,15 @@
    background-color: yellow;
}
/* ------------------ 台车 ------------------ */
/* 轨道 */
.car-track {
    position: absolute;
    background: url(../image/bg.jpg);
}
#car-track-1 {
    top: 122px;
    left: 100px;
    width: 100px;
    height: 200px;
}
/* 车 */
.car {
    position: absolute;
}
.site-8 {
    top: 122px;
    left: 100px;
    width: 100px;
    height: 40px;
    line-height: 40px
}
/* ------------------ 货架总成 ------------------ */
.main-part {
    position: absolute;
    top: 100px;
    left: 300px;
    left: 200px;
}
.main-part .lane {
    margin-bottom: 30px;
    /*margin-bottom: 30px;*/
}
/* 排号 */
.row-no {
@@ -291,37 +266,37 @@
/* 入库 */
.machine-put {
.machine-put-flag {
    background-color: #90d0f3;
}
/* 出库 */
.machine-take {
.machine-take-flag {
    background-color: yellow;
}
/* 库到库 */
.machine-stock-move {
.machine-stock-move-flag {
    background-color: #0c24fb;
    color: #fff;
}
/* 站到站 */
.machine-site-move {
.machine-site-move-flag {
    background-color: #faa328;
}
/* PToP */
.machine-p-move {
.machine-p-move-flag {
    background-color: #128014;
    color: #fff;
}
/* 异常 */
.machine-error {
.machine-error-flag {
    background-color: red;
}
/* 自动 */
.machine-auto {
.machine-auto-flag {
    background-color: rgb(42,253,47);
}
/* 非自动/收到 */
.machine-unauto {
.machine-unauto-flag {
    background-color: #aaaaaa;
}
@@ -332,7 +307,7 @@
    position: absolute;
    background-color:#333!important;
    color: #333 !important;
    width: 90%;
    width: 95%;
    margin-top: 10px;
}
@@ -343,9 +318,9 @@
/* 入库口 */
.cargo-put {
    transform: rotateY(180deg);
    top: 285px;
    left: 313px;
    /*transform: rotateY(180deg);*/
    top: 160px;
    left: 43px;
    position: absolute;
    width: 50px;
    height: 40px;
@@ -373,8 +348,8 @@
}
/* 扫码器1 */
#code-decoder-1 {
    top: 320px;
    left: 200px;
    top: 144px;
    left: 100px;
}
/* 扫码器数据1 */
#code-decoder-data-1 {
@@ -382,6 +357,17 @@
    margin-left: 35px;
}
/* 扫码器1 */
#code-decoder-2 {
    top: 204px;
    left: 100px;
}
/* 扫码器数据1 */
#code-decoder-data-2 {
    font-size: xx-small;
    margin-left: 35px;
}
/* 弹窗 */
form .form-item {
    display: inline-block;
src/main/webapp/static/js/common.js
@@ -1,4 +1,4 @@
var baseUrl = "/jswcs";
var baseUrl = "/gdwcs";
// 赋值
function setVal(el, val) {
src/main/webapp/views/console.html
@@ -51,14 +51,14 @@
            <div class="tips-item">
                <label>堆垛机状态颜色:&nbsp;</label>
                <div class="item-group">
                    <span class="machine-put">入库</span>
                    <span class="machine-take">出库</span>
                    <span class="machine-stock-move">库到库</span>
                    <span class="machine-site-move">站到站</span>
                    <span class="machine-p-move">PToP</span>
                    <span class="machine-error">异常</span>
                    <span class="machine-auto">自动</span>
                    <span class="machine-unauto">非自动/手动</span>
                    <span class="machine-put-flag">入库</span>
                    <span class="machine-take-flag">出库</span>
                    <span class="machine-stock-move-flag">库到库</span>
                    <span class="machine-site-move-flag">站到站</span>
                    <span class="machine-p-move-flag">PToP</span>
                    <span class="machine-error-flag">异常</span>
                    <span class="machine-auto-flag">自动</span>
                    <span class="machine-unauto-flag">非自动/手动</span>
                </div>
            </div>
            <div class="tips-item">
@@ -79,27 +79,26 @@
    <!----------- 工具栏 ---------->
    <!-- 入库口 -->
    <div class="cargo-put"></div>
    <!-- 扫码器 -->
    <div id="code-decoder-1" class="code-decoder">
        <span id="code-decoder-data-1" class="code-decoder-data">0</span>
    </div>
<!--    &lt;!&ndash; 扫码器 1&ndash;&gt;-->
<!--    <div id="code-decoder-1" class="code-decoder">-->
<!--        <span id="code-decoder-data-1" class="code-decoder-data">0</span>-->
<!--    </div>-->
<!--    &lt;!&ndash; 扫码器 2&ndash;&gt;-->
<!--    <div id="code-decoder-2" class="code-decoder">-->
<!--        <span id="code-decoder-data-2" class="code-decoder-data">0</span>-->
<!--    </div>-->
    <!----------- 左输送线 ---------->
    <!-- 台车轨道 -->
    <div id="car-track-1" class="car-track"></div>
    <!-- 台车实例 -->
    <div id="site-8" class="site car">8</div>
    <!-- 第一列(宽度 100px) -->
    <div class="site-row site-row-1">
        <div id="site-7" class="site" style="height: 40px;line-height: 40px">7</div>
        <div id="site-4" class="site" style="height: 40px;line-height: 40px">4</div>
        <div id="site-3" class="site" style="height: 40px;line-height: 40px;">3</div>
        <div id="site-2" class="site" style="height: 40px;line-height: 40px">2</div>
        <div id="site-1" class="site" style="height: 40px;line-height: 40px">1</div>
        <div id="site-1" class="site" style="height: 20px;line-height: 20px;">1</div>
        <div id="site-3" class="site" style="height: 20px;line-height: 20px; margin-top: 20px">3</div>
        <div id="site-5" class="site" style="height: 20px;line-height: 20px; margin-top: 0px">5</div>
        <div id="site-7" class="site" style="height: 20px;line-height: 20px; margin-top: 20px">7</div>
    </div>
    <!-- 货架 + 堆垛机 + 入库站点 + 出库站点 -->
@@ -109,8 +108,7 @@
            <span class="row-no">1#</span>
            <!-- 货架 -->
            <div class="stock-group">
                <div id="site-6" class="site" style="">6</div>
                <button class="item">1</button>
                <div id="site-2" class="site" style="">2</div>
                <button class="item">2</button>
                <button class="item">3</button>
                <button class="item">4</button>
@@ -144,6 +142,23 @@
                <button class="item">32</button>
                <button class="item">33</button>
                <button class="item">34</button>
                <button class="item">35</button>
                <button class="item">36</button>
                <button class="item">37</button>
                <button class="item">38</button>
                <button class="item">39</button>
                <button class="item">40</button>
                <button class="item">41</button>
                <button class="item">42</button>
                <button class="item">43</button>
                <button class="item">44</button>
                <button class="item">45</button>
                <button class="item">46</button>
                <button class="item">47</button>
                <button class="item">48</button>
                <button class="item">49</button>
                <button class="item">50</button>
                <button class="item">51</button>
                <div class="site site-none">&nbsp;&nbsp;&nbsp;&nbsp;</div>
            </div>
            <!-- 堆垛机 -->
@@ -153,8 +168,7 @@
            </div>
            <!-- 货架 -->
            <div class="stock-group">
                <div id="site-5" class="site" style="">5</div>
                <button class="item">1</button>
                <div id="site-4" class="site" style="">4</div>
                <button class="item">2</button>
                <button class="item">3</button>
                <button class="item">4</button>
@@ -188,9 +202,143 @@
                <button class="item">32</button>
                <button class="item">33</button>
                <button class="item">34</button>
                <button class="item">35</button>
                <button class="item">36</button>
                <button class="item">37</button>
                <button class="item">38</button>
                <button class="item">39</button>
                <button class="item">40</button>
                <button class="item">41</button>
                <button class="item">42</button>
                <button class="item">43</button>
                <button class="item">44</button>
                <button class="item">45</button>
                <button class="item">46</button>
                <button class="item">47</button>
                <button class="item">48</button>
                <button class="item">49</button>
                <button class="item">50</button>
                <button class="item">51</button>
                <div class="site site-none">&nbsp;&nbsp;&nbsp;&nbsp;</div>
            </div>
            <span class="row-no">2#</span>
        </div>
        <div class="lane">
            <!-- 货架 -->
            <div class="stock-group">
                <div id="site-6" class="site" style="">6</div>
                <button class="item">2</button>
                <button class="item">3</button>
                <button class="item">4</button>
                <button class="item">5</button>
                <button class="item">6</button>
                <button class="item">7</button>
                <button class="item">8</button>
                <button class="item">9</button>
                <button class="item">10</button>
                <button class="item">11</button>
                <button class="item">12</button>
                <button class="item">13</button>
                <button class="item">14</button>
                <button class="item">15</button>
                <button class="item">16</button>
                <button class="item">17</button>
                <button class="item">18</button>
                <button class="item">19</button>
                <button class="item">20</button>
                <button class="item">21</button>
                <button class="item">22</button>
                <button class="item">23</button>
                <button class="item">24</button>
                <button class="item">25</button>
                <button class="item">26</button>
                <button class="item">27</button>
                <button class="item">28</button>
                <button class="item">29</button>
                <button class="item">30</button>
                <button class="item">31</button>
                <button class="item">32</button>
                <button class="item">33</button>
                <button class="item">34</button>
                <button class="item">35</button>
                <button class="item">36</button>
                <button class="item">37</button>
                <button class="item">38</button>
                <button class="item">39</button>
                <button class="item">40</button>
                <button class="item">41</button>
                <button class="item">42</button>
                <button class="item">43</button>
                <button class="item">44</button>
                <button class="item">45</button>
                <button class="item">46</button>
                <button class="item">47</button>
                <button class="item">48</button>
                <button class="item">49</button>
                <button class="item">50</button>
                <button class="item">51</button>
                <div class="site site-none">&nbsp;&nbsp;&nbsp;&nbsp;</div>
            </div>
            <!-- 堆垛机 -->
            <div class="crn">
                <hr class="pathway">
                <div id="crn-2" class="machine"></div>
            </div>
            <!-- 货架 -->
            <div class="stock-group">
                <div id="site-8" class="site" style="">8</div>
                <button class="item">2</button>
                <button class="item">3</button>
                <button class="item">4</button>
                <button class="item">5</button>
                <button class="item">6</button>
                <button class="item">7</button>
                <button class="item">8</button>
                <button class="item">9</button>
                <button class="item">10</button>
                <button class="item">11</button>
                <button class="item">12</button>
                <button class="item">13</button>
                <button class="item">14</button>
                <button class="item">15</button>
                <button class="item">16</button>
                <button class="item">17</button>
                <button class="item">18</button>
                <button class="item">19</button>
                <button class="item">20</button>
                <button class="item">21</button>
                <button class="item">22</button>
                <button class="item">23</button>
                <button class="item">24</button>
                <button class="item">25</button>
                <button class="item">26</button>
                <button class="item">27</button>
                <button class="item">28</button>
                <button class="item">29</button>
                <button class="item">30</button>
                <button class="item">31</button>
                <button class="item">32</button>
                <button class="item">33</button>
                <button class="item">34</button>
                <button class="item">35</button>
                <button class="item">36</button>
                <button class="item">37</button>
                <button class="item">38</button>
                <button class="item">39</button>
                <button class="item">40</button>
                <button class="item">41</button>
                <button class="item">42</button>
                <button class="item">43</button>
                <button class="item">44</button>
                <button class="item">45</button>
                <button class="item">46</button>
                <button class="item">47</button>
                <button class="item">48</button>
                <button class="item">49</button>
                <button class="item">50</button>
                <button class="item">51</button>
                <div class="site site-none">&nbsp;&nbsp;&nbsp;&nbsp;</div>
            </div>
            <span class="row-no">4#</span>
        </div>
    </div>
</main>
@@ -459,7 +607,7 @@
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    alert(res.msg);
                    console.log(res.msg);
                }
            }
        });
@@ -486,7 +634,7 @@
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    alert(res.msg);
                    console.log(res.msg);
                }
            }
        });
@@ -511,9 +659,9 @@
                        }
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                    parent.location.href = baseUrl+"/login";
                }  else {
                    alert(res.msg);
                    console.log(res.msg);
                }
            }
        });
@@ -532,12 +680,13 @@
                        var crnEl = $("#crn-"+crns[i].crnId);
                        crnEl.attr("class", "machine " + crns[i].crnStatus);
                        // crnAnimate(crns[i].crnId, crns[i].offset);
                        crnEl.animate({left: (crns[i].bay * ($('.item').eq(0).width()+4)) +'px'}, 1000);
                        var unit = $('.item').eq(0).width()+4;
                        crnEl.animate({left: (crns[i].bay * unit + 20) +'px'}, 1000);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    alert(res.msg);
                    console.log(res.msg);
                }
            }
        });
@@ -558,7 +707,7 @@
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    alert(res.msg);
                    console.log(res.msg);
                }
            }
        });
@@ -678,17 +827,17 @@
    }
    // 台车点击事件
    $(document).on("click", ".car", function () {
        var value = prompt('目标站:', "1");
        if (value == null) {
            alert('不能为空!');
        } else if (value === '') {
            alert('不能为空!');
        } else {
            carAnimate(8, Number(value));
        }
    })
    // // 台车点击事件
    // $(document).on("click", ".item", function () {
    //     var value = prompt('目标站:', "1");
    //     if (value == null) {
    //         alert('不能为空!');
    //     } else if (value === '') {
    //         alert('不能为空!');
    //     } else {
    //         carAnimate(8, Number(value));
    //     }
    // })
</script>
</html>
src/main/webapp/views/crn.html
@@ -27,11 +27,11 @@
            <span>&nbsp;</span>
            <input id="crn1" disabled="disabled">
        </div>
<!--        <div class="crn-command-item">-->
<!--            <label>2#</label>-->
<!--            <span>&nbsp;</span>-->
<!--            <input id="crn2" disabled="disabled">-->
<!--        </div>-->
        <div class="crn-command-item">
            <label>2#</label>
            <span>&nbsp;</span>
            <input id="crn2" disabled="disabled">
        </div>
    </div>
    <!-- 堆垛机状态位信息 -->
    <div class="crn-state">
@@ -39,15 +39,17 @@
            <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>
                </tr>
            </thead>
@@ -69,6 +71,13 @@
                <th>源库位</th>
                <th>目标库位</th>
                <th>异常</th>
                <th>走行速度(m/min)</th>
                <th>升降速度(m/min)</th>
                <th>叉牙速度(m/min)</th>
                <th>走行距离(Km)</th>
                <th>升降距离(Km)</th>
                <th>走行时长(H)</th>
                <th>升降时长(H)</th>
            </tr>
        </thead>
        <tbody>
@@ -92,7 +101,7 @@
            <span class="select-title">堆垛机号</span>
            <div class="select-container">
                <label><input type="radio" name="crnSelect" value="1" checked>&nbsp;1号堆垛机</label>
<!--                <label><input type="radio" name="crnSelect" value="2">&nbsp;2号堆垛机</label>-->
                <label><input type="radio" name="crnSelect" value="2">&nbsp;2号堆垛机</label>
            </div>
        </div>
        <!-- 源站/源库位 选择 -->
@@ -247,16 +256,18 @@
                    for (var i=1;i<=table.length;i++){
                        var tr = tableEl.find("tr").eq(i);
                        setVal(tr.children("td").eq(0), table[i-1].crnNo);
                        setVal(tr.children("td").eq(1), table[i-1].workNo);
                        setVal(tr.children("td").eq(2), table[i-1].statusType);
                        setVal(tr.children("td").eq(3), table[i-1].status);
                        setVal(tr.children("td").eq(4), table[i-1].warn);
                        setVal(tr.children("td").eq(5), table[i-1].loading);
                        setVal(tr.children("td").eq(6), table[i-1].bay);
                        setVal(tr.children("td").eq(7), table[i-1].lev);
                        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].bay);
                        setVal(tr.children("td").eq(5), table[i-1].lev);
                        setVal(tr.children("td").eq(6), table[i-1].xorigin);
                        setVal(tr.children("td").eq(7), table[i-1].yorigin);
                        setVal(tr.children("td").eq(8), table[i-1].forkOffset);
                        setVal(tr.children("td").eq(9), table[i-1].liftPos);
                        setVal(tr.children("td").eq(10), table[i-1].warnCode);
                        setVal(tr.children("td").eq(9), table[i-1].xlocation);
                        setVal(tr.children("td").eq(10), table[i-1].ylocation);
                        setVal(tr.children("td").eq(11), table[i-1].stop);
                        setVal(tr.children("td").eq(12), table[i-1].warnCode);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
@@ -290,7 +301,14 @@
                        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(6), table[i-1].error);
                        setVal(tr.children("td").eq(7), table[i-1].error);
                        setVal(tr.children("td").eq(8), table[i-1].xspeed);
                        setVal(tr.children("td").eq(9), table[i-1].yspeed);
                        setVal(tr.children("td").eq(10), table[i-1].zspeed);
                        setVal(tr.children("td").eq(11), table[i-1].xdistance);
                        setVal(tr.children("td").eq(12), table[i-1].ydistance);
                        setVal(tr.children("td").eq(13), table[i-1].xduration);
                        setVal(tr.children("td").eq(14), table[i-1].yduration);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
@@ -457,6 +475,8 @@
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "       <td></td>\n" +
                "     </tr>\n";
        }
        $('#crn-state-table tbody').after(html);
@@ -486,6 +506,13 @@
                "       <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";
        }
        $('#crn-msg-table tbody').after(html);
src/main/webapp/views/pipeline.html
@@ -62,7 +62,7 @@
                    <th>有物</th>
                    <th>可入</th>
                    <th>可出</th>
                    <th>需求1</th>
                    <th>入库标记</th>
                    <th>空板信号</th>
                    <th>目标站</th>
                </tr>
@@ -147,7 +147,7 @@
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    alert(res.msg);
                    console.log(res.msg);
                }
            }
        });
@@ -175,14 +175,14 @@
                        setVal(tr.children("td").eq(3), table[i-1].loading);
                        setVal(tr.children("td").eq(4), table[i-1].inEnable);
                        setVal(tr.children("td").eq(5), table[i-1].outEnable);
                        setVal(tr.children("td").eq(6), table[i-1].inreq1);
                        setVal(tr.children("td").eq(6), table[i-1].pakMk);
                        setVal(tr.children("td").eq(7), table[i-1].emptyMk);
                        setVal(tr.children("td").eq(8), table[i-1].staNo);
                    }
                } else if (res.code === 403){
                    window.location.href = baseUrl+"/login";
                }  else {
                    alert(res.msg);
                    console.log(res.msg);
                }
            }
        });