1
zhang
1 天以前 038634540d95d4a5787b80a1fbab131df4d99823
1
1个文件已删除
4个文件已添加
15个文件已修改
786 ■■■■ 已修改文件
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/CtuController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/RedisConveyorConstant.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/SafeSignalField.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/TaskField.java 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/ConveyorStateType.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/listen/DevpSafeDataSubscriber.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/model/SafeSignal.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/model/StaProtocol.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/AppleLocOperationHandler.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/ClearSingleOperationHandler.java 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/FakeUserOperationHandler.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/OutOperationHandler.java 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/SendTaskOperationHandler.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/StartUpOperationHandler.java 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/CtuOperationConfig.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/DevpSlave.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/service/Snap7Service.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/SiemensDevpThread.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/scheduler/JobLogScheduler.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/resources/application.yml 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/CtuController.java
@@ -56,8 +56,8 @@
            stationResponseParam = new StationResponseParam();
            stationResponseParam.setStaNo(staNo);
            stationResponseParam.setOccupied(staProtocol.isLoading());
            stationResponseParam.setInEnable((staProtocol.isInEnable() && staProtocol.getWorkNo() == 0 ? true : false));
            stationResponseParam.setOutEnable((staProtocol.isOutEnable() ? true : false));
            stationResponseParam.setInEnable((staProtocol.getAllowPut()));
            stationResponseParam.setOutEnable((staProtocol.getAllowTake()));
            stationResponseParam.setOnline(staProtocol.isAutoing());
            list.add(stationResponseParam);
        }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/RedisConveyorConstant.java
@@ -1,6 +1,8 @@
package com.zy.acs.conveyor.core.constant;
public class RedisConveyorConstant {
    //输送线任务标识
    public static final String CONVEYOR_TASK_FLAG = "CONVEYOR_TASK_FLAG";
    //输送线安全交互标识
    public static final String CONVEYOR_SAFE_FLAG = "CONVEYOR_SAFE_FLAG";
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/SafeSignalField.java
New file
@@ -0,0 +1,46 @@
package com.zy.acs.conveyor.core.constant;
public enum SafeSignalField {
    SAFE_SIGNAL_TO_CONVEYOR("DB7", 4, 4, 8),
    SAFE_SIGNAL_FROM_CONVEYOR("DB7", 40, 4, 8),
    ;
    private final String addressPattern;
    private final int offset;
    private final int byteLength;
    private final int arrLength;
    SafeSignalField(String addressPattern, int offset, int byteLength, int arrLength) {
        this.addressPattern = addressPattern;
        this.offset = offset;
        this.byteLength = byteLength;
        this.arrLength = arrLength;
    }
    public String getAddressPattern() {
        return addressPattern;
    }
    public int getOffset() {
        return offset;
    }
    public int getByteLength() {
        return byteLength;
    }
    public int getArrLength() {
        return arrLength;
    }
    /**
     * 根据 DB 块编号和站点偏移生成具体地址
     *
     * @return PLC4X 地址字符串,如 "DB100.DBD0"
     */
    public String buildAddress() {
        return addressPattern + PlcConstant.ADDRESS_CONCATENATION + offset;
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/TaskField.java
@@ -6,11 +6,11 @@
 */
public enum TaskField {
    ALL("DB13", 48, 48),
    TASK_NUMBER("DB13", 0, 4),
    START_STATION("DB13", 4, 2),
    DEST_STATION("DB13", 6, 2),
    DIRECTION("DB13", 8, 2),
    ROUTE_NUMBER("DB13", 10, 2);
    TASK_NUMBER("DB13", 12, 4),
    START_STATION("DB13", 16, 2),
    DEST_STATION("DB13", 18, 2),
    DIRECTION("DB13", 20, 2),
    ROUTE_NUMBER("DB13", 22, 2);
    private final String addressPattern;
    private final int offset;
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/ConveyorStateType.java
@@ -3,8 +3,8 @@
public enum ConveyorStateType {
    //出库设备上走
    OUTBOUND(2),
    //模拟用户
    FAKEUSER(3),
    //启动入库
    STARTUP(3),
    //入库申请
    APPLYLOC(4),
    //入库设备上走
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/listen/DevpSafeDataSubscriber.java
New file
@@ -0,0 +1,56 @@
package com.zy.acs.conveyor.core.listen;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.conveyor.core.constant.RedisConveyorConstant;
import com.zy.acs.conveyor.core.model.StaProtocol;
import com.zy.acs.conveyor.core.service.Snap7Service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
/**
 * 读取redis写入plc
 */
@Slf4j
@Component
public class DevpSafeDataSubscriber {
    private Thread thread;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    @Autowired
    private Snap7Service snap7Service;
    @EventListener(ApplicationReadyEvent.class)
    private void start() {
        thread = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    // 间隔
                    Thread.sleep(20);
                    StaProtocol protocol = redis.pop(RedisConveyorConstant.CONVEYOR_SAFE_FLAG);
                    if (null != protocol) {
                        snap7Service.writeSafe(protocol);
                    }
                } catch (Exception ignore) {
                }
            }
        });
        thread.start();
    }
    @PreDestroy
    public void shutDown() {
        if (thread != null) thread.interrupt();
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/model/SafeSignal.java
New file
@@ -0,0 +1,18 @@
package com.zy.acs.conveyor.core.model;
import lombok.Data;
import java.io.Serializable;
@Data
public class SafeSignal implements Serializable {
    private Integer index;
    private Boolean flag;
    public SafeSignal(Integer index, Boolean flag) {
        this.index = index;
        this.flag = flag;
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/model/StaProtocol.java
@@ -32,10 +32,10 @@
    // 有物
    private boolean loading;
    // 可入
    // 需求入
    private boolean inEnable;
    // 可出
    // 需求出
    private boolean outEnable;
    // 空板信号
@@ -49,6 +49,18 @@
    // 低
    private boolean low;
    // 中
    private boolean mid;
    // 启动入库
    private boolean startup;
    // 中途任务申请
    private boolean segApply;
    // 入库异常
    private boolean applyErr;
    //条码
    private String barcode;
@@ -100,6 +112,43 @@
    private Boolean upcontactErr = false; //顶升电机接触器故障
    // 安全交互 ------------------------------------------------------------------------
    // ctu或agv写给输送线的
    // ctu申请放
    private Boolean applyPut = false;
    // ctu申请取
    private Boolean applyTake = false;
    // ctu取完成
    private Boolean putComplete = false;
    // ctu放完成
    private Boolean takeComplete = false;
    // 禁止运行
    private Boolean stop = false;
    // 输送线写给ctu或agv
    // 心跳
    private Boolean heartbeat = false;
    // 允许取
    private Boolean allowTake = false;
    // 允许放
    private Boolean allowPut = false;
    // 接货完成
    private Boolean inComplete = false;
    // 出货完成
    private Boolean outComplete = false;
    private SafeSignal safeSignal;
    public Boolean isErr() {
        if (frontErr || backErr || highErr || leftErr || rightErr || weightErr || barcodeErr) {
            return true;
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/AppleLocOperationHandler.java
@@ -1,5 +1,6 @@
package com.zy.acs.conveyor.core.operation.handler;
import com.alibaba.fastjson.JSON;
import com.zy.acs.common.utils.News;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.conveyor.controller.vo.ApplyInDto;
@@ -77,34 +78,46 @@
                        staProtocol = staProtocol.clone();
                    }
                    // 判断是否满足条件
                    if (!staProtocol.isLoading()) {
                    if (staProtocol.isInEnable()) {
                        continue;
                    }
                    if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing()) {
                        String barcode = staProtocol.getBarcode();
                        if (Cools.isEmpty(barcode)) {
                            News.error("站点:{},未扫到码值:{}", staProtocol.getSiteId(), barcode);
                            return;
                    if (!staProtocol.isLoading()) {
                        News.error("{}:站点:{},无物", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (!staProtocol.isAutoing()) {
                        News.error("{}:站点:{},非自动", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    String barcode = staProtocol.getBarcode();
                    if (Cools.isEmpty(barcode)) {
                        News.error("站点:{},未扫到码值:{}", staProtocol.getSiteId(), barcode);
                        continue;
                    }
                    Job job = jobService.getJobByBarcode(barcode);
                    if (job == null) {
                        News.error("{}:站点:{},找不到任务", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (job.getJobSts() != ConveyorStateType.STARTUP.getStatus()) {
                        if (job.getJobSts() == ConveyorStateType.INBOUND.getStatus()){
                            continue;
                        }
                        // 9991是空板,9992是满板
                        if (staProtocol.getWorkNo() >= 9991 && staProtocol.getWorkNo() <= 9992) {
                            Job job = jobService.getJobByBarcode(barcode);
                            // 申请入库
                            if (job == null || (job != null && job.getJobSts() == ConveyorStateType.CLEARSIGNAL.getStatus())) {
                                ApplyInRepsonseDto locOfWms = wmsMainService.getLocOfWms(applyIn(barcode, inSta.getStaNo() + "", staProtocol));
                                if (locOfWms != null) {
                                    Integer workNo = getWorkNo();
                                    staProtocol.setWorkNo(workNo);
                                    staProtocol.setStaNo(inSta.getTargetSta());
                                    redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                                    if (jobService.insert(initJob(locOfWms, barcode, workNo, inSta.getTargetSta() + ""))) {
                                        News.info("申请入库成功,条码:{},站点:{}", barcode, inSta.getStaNo());
                                    }
                                } else {
                                    News.error("WMS未返回库位信息,条码:{},站点:{}", barcode, inSta.getStaNo());
                                }
                            }
                        News.error("{}:站点:{},任务状态不对,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(job));
                        continue;
                    }
                    ApplyInRepsonseDto locOfWms = wmsMainService.getLocOfWms(applyIn(barcode, inSta.getStaNo() + "", staProtocol));
                    if (locOfWms != null) {
                        Integer workNo = getWorkNo();
                        staProtocol.setWorkNo(workNo);
                        staProtocol.setStaNo(inSta.getTargetSta());
                        redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                        if (jobService.insert(initJob(locOfWms, barcode, workNo, inSta.getTargetSta() + ""))) {
                            News.info("申请入库成功,条码:{},站点:{}", barcode, inSta.getStaNo());
                        }
                    } else {
                        News.error("WMS未返回库位信息,条码:{},站点:{}", barcode, inSta.getStaNo());
                    }
                }
            }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/ClearSingleOperationHandler.java
@@ -1,5 +1,6 @@
package com.zy.acs.conveyor.core.operation.handler;
import com.alibaba.fastjson.JSON;
import com.zy.acs.common.utils.News;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.conveyor.core.constant.RedisConveyorConstant;
@@ -63,19 +64,35 @@
                    }
                    // 判断是否满足条件
                    if (staProtocol.isLoading()) {
                        //News.error("{}:站点:{},有物", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing()) {
                    if (!staProtocol.isAutoing()) {
                        News.error("{}:站点:{},非自动", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (staProtocol.getWorkNo() > 0) {
                        Job job = jobService.getJobByJobNo(staProtocol.getWorkNo());
                        if (job != null && job.getJobSts() == ConveyorStateType.SENDTASK.getStatus()) {
                            //String s = ctuMainService.checkStationStatus(takeSta.getStaNo());
                            staProtocol.setWorkNo(0);
                            staProtocol.setStaNo(0);
                            redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                        if (job == null) {
                            News.error("{}:站点:{},找不到任务", config.getMark(), staProtocol.getSiteId());
                            continue;
                        }
                        if (job.getJobSts() != ConveyorStateType.SENDTASK.getStatus()) {
                            if (job.getJobSts() == ConveyorStateType.CLEARSIGNAL.getStatus()){
                                continue;
                            }
                            News.error("{}:站点:{},任务状态不对,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(job));
                            continue;
                        }
                        //String s = ctuMainService.checkStationStatus(takeSta.getStaNo());
                        staProtocol.setWorkNo(0);
                        staProtocol.setStaNo(0);
                        redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                            job.setJobSts(ConveyorStateType.CLEARSIGNAL.getStatus());
                            jobService.updateById(job);
                            //log.info("" + config.getMark() + "站点清空:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo());
                        job.setJobSts(ConveyorStateType.CLEARSIGNAL.getStatus());
                        if (!jobService.updateById(job)){
                            log.info("" + config.getMark() + "站点清空失败:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo());
                        }else {
                            News.info("" + config.getMark() + "站点清空:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo());
                        }
                    }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/FakeUserOperationHandler.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/OutOperationHandler.java
@@ -1,9 +1,11 @@
package com.zy.acs.conveyor.core.operation.handler;
import com.alibaba.fastjson.JSON;
import com.zy.acs.common.utils.News;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.conveyor.core.constant.RedisConveyorConstant;
import com.zy.acs.conveyor.core.enums.ConveyorStateType;
import com.zy.acs.conveyor.core.model.SafeSignal;
import com.zy.acs.conveyor.core.model.StaProtocol;
import com.zy.acs.conveyor.core.operation.OperationHandler;
import com.zy.acs.conveyor.core.properties.CtuOperationConfig;
@@ -59,51 +61,49 @@
            // 根据输送线plc遍历
            for (DevpSlave devp : slaveProperties.getDevp()) {
                // 遍历出库口
                for (DevpSlave.Sta releaseSta : devp.getReleaseSta()) {
                for (DevpSlave.Sta putSta : devp.getPutSta()) {
                    // 获取入库站信息
                    Map<Integer, StaProtocol> stationMap = stationService.getStationMap(devp.getId());
                    StaProtocol staProtocol = stationMap.get(releaseSta.getStaNo());
                    StaProtocol staProtocol = stationMap.get(putSta.getStaNo());
                    if (staProtocol == null) {
                        continue;
                    } else {
                        staProtocol = staProtocol.clone();
                    }
                    // 判断是否满足条件
                    if (!staProtocol.isLoading()) {
                        if (staProtocol.getWorkNo() > 0) {
                            News.error("输送线上有任务号无货,需要人工处理:{}", staProtocol.getSiteId());
                            //log.error("输送线上有任务号无货,需要人工处理:{}", staProtocol.getSiteId());
                        }
                    if (!staProtocol.isAutoing()) {
                        News.error("{},输送线未自动,需要开启:{}", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (staProtocol.isAutoing() && staProtocol.getWorkNo() == 0) {
                        if (staProtocol.isInEnable()) {
                            News.error("没有可入信号:{}", staProtocol.getSiteId());
                            //log.error("没有可入信号:{}", staProtocol.getSiteId());
                            continue;
                        }
                        String seqNum = ctuMainService.checkStationStatus(releaseSta.getStaNo());
                    if (staProtocol.getWorkNo() == 0 && staProtocol.isLoading()) {
                        String seqNum = ctuMainService.checkStationStatus(putSta.getStaNo());
                        if (seqNum != null) {
                            if (jobService.getJobByTaskNo(seqNum) == null) {
                                int workNo = wrkLastnoService.nextWorkNo(WorkNoTypeType.WORK_NO_TYPE.type);
                                // 下发移动 且 下发plc命令
                                staProtocol.setWorkNo(workNo);
                                staProtocol.setStaNo(releaseSta.getTargetSta());
                                Job job = new Job();
                                job.setTaskNo(seqNum);
                                job.setJobNo(workNo);
                                job.setJobSts(ConveyorStateType.OUTBOUND.getStatus());
                                if (!jobService.insert(job)) {
                                    throw new CoolException("插入输送线任务失败," + seqNum + " - " + workNo);
                                }
                                redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                                log.info("输送线下发:{},{}", staProtocol.getWorkNo(), releaseSta.getTargetSta());
                            staProtocol.setSafeSignal(new SafeSignal( devp.getPutSta().indexOf(putSta) ,true));
                            redis.push(RedisConveyorConstant.CONVEYOR_SAFE_FLAG,staProtocol );
                            Job job = jobService.getJobByTaskNo(seqNum);
                            if (job != null) {
                                News.error("{}:站点:{},存在任务,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(job));
                                continue;
                            }
                            int workNo = wrkLastnoService.nextWorkNo(WorkNoTypeType.WORK_NO_TYPE.type);
                            staProtocol.setWorkNo(workNo);
                            staProtocol.setStaNo(putSta.getTargetSta());
                            job = new Job();
                            job.setTaskNo(seqNum);
                            job.setJobNo(workNo);
                            job.setJobSts(ConveyorStateType.OUTBOUND.getStatus());
                            if (!jobService.insert(job)) {
                                throw new CoolException("插入输送线任务失败," + seqNum + " - " + workNo);
                            }
                            redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                            News.info("{},输送线下发:{},{}", config.getMark(), staProtocol.getWorkNo(), putSta.getTargetSta());
                        } else {
                            News.error("站点信息不符合入库条件!!!" + " 调用RCS检验未通过,站点:{}", staProtocol.getSiteId());
                            //log.info("站点信息不符合入库条件!!!" + " 调用RCS检验未通过,站点:{}", staProtocol.getSiteId());
                            News.error("{},站点信息不符合入库条件!!!" + " 调用RCS检验未通过,站点:{}", config.getMark(), staProtocol.getSiteId());
                        }
                    } else {
                        News.error("{},站点:{},异常状态,请补充", config.getMark(), staProtocol.getSiteId());
                    }
                }
            }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/SendTaskOperationHandler.java
@@ -1,6 +1,7 @@
package com.zy.acs.conveyor.core.operation.handler;
import com.alibaba.fastjson.JSON;
import com.zy.acs.common.utils.News;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.conveyor.controller.vo.OpenBusSubmitParam;
@@ -72,33 +73,44 @@
                        staProtocol = staProtocol.clone();
                    }
                    // 判断是否满足条件
                    if (!staProtocol.isLoading()) {
                        if (staProtocol.getWorkNo() > 0) {
                            News.error("输送线上有货无任务号,需要人工处理:{}", staProtocol.getSiteId());
                            //log.error("输送线上有任务号无货,需要人工处理:{}", staProtocol.getSiteId());
                        }
                    if (staProtocol.getWorkNo() == 0 && staProtocol.isLoading()) {
                        News.error("{},输送线上有货无任务号,需要人工处理站点:{}", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (staProtocol.getWorkNo() == 0) {
                        News.error("输送线上有货无任务号,需要人工处理:{}", staProtocol.getSiteId());
                        //log.error("输送线上有货无任务号,需要人工处理:{}", staProtocol.getSiteId());
                    if (staProtocol.getWorkNo() > 0 && !staProtocol.isLoading()) {
                        News.error("{},输送线上无货有任务号,需要人工处理站点:{}", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (staProtocol.isAutoing()) {
                        Job job = jobService.getJobByJobNoAndJobSts(staProtocol.getWorkNo(), ConveyorStateType.INBOUND.getStatus());
                        if (job != null) {
                            if (ctuMainService.sendTask(process(job))) {
                                job.setJobSts(ConveyorStateType.SENDTASK.getStatus());
                                job.setRcsTime(new Date());
                                jobService.updateById(job);
                                log.info("任务发送给RCS成功,WMS任务号:{},输送线工作号:{}", job.getTaskNo(), job.getJobNo());
                            } else {
                                log.info("任务发送给RCS失败,WMS任务号:{},输送线工作号:{}", job.getTaskNo(), job.getJobNo());
                            }
                    if (!staProtocol.isAutoing()) {
                        News.error("{}:站点:{},非自动", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (staProtocol.isInEnable()) {
                        News.error("{},站点:{},没有可入信号", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    Job jobByJobNo = jobService.getJobByJobNo(staProtocol.getWorkNo());
                    if (jobByJobNo == null) {
                        News.error("{}:站点:{},找不到任务", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (jobByJobNo.getJobSts() != ConveyorStateType.INBOUND.getStatus()) {
                        if (jobByJobNo.getJobSts() == ConveyorStateType.SENDTASK.getStatus()){
                            continue;
                        }
                        News.error("{}:站点:{},任务状态不对,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(jobByJobNo));
                        continue;
                    }
                    if (ctuMainService.sendTask(process(jobByJobNo))) {
                        jobByJobNo.setJobSts(ConveyorStateType.SENDTASK.getStatus());
                        jobByJobNo.setRcsTime(new Date());
                        jobService.updateById(jobByJobNo);
                        News.error("{},任务发送给RCS成功,WMS任务号:{},输送线工作号:{}", config.getMark(), jobByJobNo.getTaskNo(), jobByJobNo.getJobNo());
                    } else {
                        log.error("输送线未自动,需要开启:{}", staProtocol.getSiteId());
                        News.error("{},任务发送给RCS失败,WMS任务号:{},输送线工作号:{}", config.getMark(), jobByJobNo.getTaskNo(), jobByJobNo.getJobNo());
                    }
                }
            }
        } catch (Exception e) {
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/StartUpOperationHandler.java
New file
@@ -0,0 +1,107 @@
package com.zy.acs.conveyor.core.operation.handler;
import com.alibaba.fastjson.JSON;
import com.zy.acs.common.utils.News;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.conveyor.core.constant.RedisConveyorConstant;
import com.zy.acs.conveyor.core.enums.ConveyorStateType;
import com.zy.acs.conveyor.core.model.StaProtocol;
import com.zy.acs.conveyor.core.operation.OperationHandler;
import com.zy.acs.conveyor.core.properties.CtuOperationConfig;
import com.zy.acs.conveyor.core.properties.DevpSlave;
import com.zy.acs.conveyor.core.properties.SlaveProperties;
import com.zy.acs.conveyor.core.service.StationService;
import com.zy.acs.conveyor.entity.Job;
import com.zy.acs.conveyor.service.JobService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.Map;
/**
 * 模拟用户按按钮
 */
@Slf4j
@Component
public class StartUpOperationHandler implements OperationHandler {
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private JobService jobService;
    @Autowired
    private StationService stationService;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    @Override
    public ConveyorStateType getType() {
        return ConveyorStateType.STARTUP;
    }
    @Override
    public synchronized void execute(CtuOperationConfig config) {
        try {
            // 根据输送线plc遍历
            for (DevpSlave devp : slaveProperties.getDevp()) {
                // 遍历入库口
                for (DevpSlave.Sta inSta : devp.getInSta()) {
                    // 根据输送线plc遍历
                    Map<Integer, StaProtocol> stationMap = stationService.getStationMap(devp.getId());
                    StaProtocol staProtocol = stationMap.get(inSta.getSourceStaNo());
                    if (staProtocol == null) {
                        continue;
                    } else {
                        staProtocol = staProtocol.clone();
                    }
                    // 判断是否满足条件
                    if (!staProtocol.isStartup() || !staProtocol.isAutoing() || !staProtocol.isLoading()) {
                        if (!staProtocol.isStartup()) {
                            News.error("{}:站点:{},未启动入库", config.getMark(), staProtocol.getSiteId());
                            continue;
                        }
                        if (!staProtocol.isAutoing()) {
                            News.error("{}:站点:{},非自动", config.getMark(), staProtocol.getSiteId());
                            continue;
                        }
                        if (!staProtocol.isLoading()) {
                            News.error("{}:站点:{},无物", config.getMark(), staProtocol.getSiteId());
                            continue;
                        }
                    }
                    Job jobByJobNo = jobService.getJobByJobNo(staProtocol.getWorkNo());
                    if (jobByJobNo == null) {
                        News.error("{}:站点:{},找不到任务", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (jobByJobNo.getJobSts() != ConveyorStateType.OUTBOUND.getStatus()) {
                        if (jobByJobNo.getJobSts() == ConveyorStateType.STARTUP.getStatus()){
                            continue;
                        }
                        News.error("{}:站点:{},任务状态不对,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(jobByJobNo));
                        continue;
                    }
                    staProtocol.setStaNo(inSta.getStaNo());
                    redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                    jobByJobNo.setJobSts(ConveyorStateType.STARTUP.getStatus());
                    if (!jobService.updateById(jobByJobNo)) {
                        News.info("{},启动入库:{},{}", config.getMark(), staProtocol.getWorkNo(), staProtocol.getStaNo());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/CtuOperationConfig.java
@@ -9,7 +9,7 @@
@Data
public class CtuOperationConfig {
    private ConveyorStateType type;
    private int mark;
    private String mark;
    private int maxRetries = 3;
    private long retryDelay = 500;
    private Map<String, Object> params = new HashMap<>();
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/DevpSlave.java
@@ -24,7 +24,7 @@
    private Boolean staNosError;
    private List<Sta> releaseSta = new ArrayList<>();
    private List<Sta> putSta = new ArrayList<>();
    private List<Sta> takeSta = new ArrayList<>();
@@ -36,6 +36,8 @@
    @Data
    public static class Sta {
        private Integer sourceStaNo;
        private Integer staNo;
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/service/Snap7Service.java
@@ -5,7 +5,9 @@
import com.alibaba.fastjson.JSON;
import com.zy.acs.common.utils.News;
import com.zy.acs.conveyor.core.constant.PlcConstant;
import com.zy.acs.conveyor.core.constant.SafeSignalField;
import com.zy.acs.conveyor.core.constant.TaskField;
import com.zy.acs.conveyor.core.model.SafeSignal;
import com.zy.acs.conveyor.core.model.StaProtocol;
import com.zy.acs.conveyor.core.properties.DevpSlave;
import com.zy.acs.conveyor.core.properties.OutputQueue;
@@ -36,7 +38,77 @@
    public void read(StaProtocol staProtocol, SiemensS7Net siemensS7Net) {
    }
    public void writeSafe(StaProtocol staProtocol) throws InterruptedException {
        if (staProtocol == null) {
            log.warn("写入数据为空,跳过 [id:{}]", JSON.toJSONString(staProtocol));
            return;
        }
        SiemensS7Net siemensS7Net = devpS7Service.get(staProtocol.getPlcId());
        if (siemensS7Net == null) {
            log.error("PLC未连接,无法写入 [id:{}]", JSON.toJSONString(staProtocol));
            return;
        }
        List<DevpSlave> devp = slaveProperties.getDevp();
        DevpSlave devpSlave = devp.stream().filter(slave -> slave.getId().equals(staProtocol.getPlcId())).findFirst().orElse(null);
        if (devpSlave == null) {
            log.error("PLC未配置,无法写入 [id:{}]", JSON.toJSONString(staProtocol));
            return;
        }
        int index = devpSlave.getStaNos().indexOf(staProtocol.getSiteId());
        if (index < 0) {
            log.error("站点编号不存在于配置中 [id:{}] [siteId:{}]", staProtocol.getPlcId(), staProtocol.getSiteId());
            return;
        }
        SafeSignal safeSignal = staProtocol.getSafeSignal();
        int baseOffset = SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.getOffset() + safeSignal.getIndex() * SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.getByteLength();
        String workNoAddr = TaskField.TASK_NUMBER.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION
                + (baseOffset + TaskField.TASK_NUMBER.getOffset());
        String destStaAddr = TaskField.DEST_STATION.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION
                + (baseOffset + TaskField.DEST_STATION.getOffset());
        // 任务下发重试机制
        int writeCount = 0;
        boolean success = false;
        while (writeCount < WRITE_RETRY_MAX) {
            OperateResult writeResult = siemensS7Net.Write(workNoAddr, staProtocol.getWorkNo());
            Thread.sleep(WRITE_RETRY_INTERVAL_MS);
            OperateResult writeResult1 = siemensS7Net.Write(destStaAddr, staProtocol.getStaNo().shortValue());
            if (writeResult.IsSuccess && writeResult1.IsSuccess) {
                log.info("写入输送线命令成功 [id:{}] [siteId:{}] [workNo:{}] [destSta:{}] [retry:{}]",
                        staProtocol.getPlcId(), staProtocol.getSiteId(), staProtocol.getWorkNo(),
                        staProtocol.getStaNo(), writeCount);
                OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线命令成功。输送线plc编号={1},站点数据={2}",
                        staProtocol.getPlcId(), JSON.toJSON(staProtocol)));
                success = true;
                break;
            }
            writeCount++;
            log.error("写入输送线命令失败 [id:{}] [siteId:{}] [retry:{}] [workErr:{}] [destErr:{}]",
                    staProtocol.getPlcId(), staProtocol.getSiteId(), writeCount,
                    writeResult.Message, writeResult1.Message);
            if (writeCount < WRITE_RETRY_MAX) {
                Thread.sleep(WRITE_RETRY_INTERVAL_MS);
            }
        }
        if (!success) {
            String errorMsg = MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}",
                    staProtocol.getPlcId(), JSON.toJSON(staProtocol));
            OutputQueue.DEVP.offer(errorMsg);
            News.error("SiemensDevp - 4 - 写入输送线站点数据失败。输送线plc编号={},站点数据={}",
                    staProtocol.getPlcId(), JSON.toJSON(staProtocol));
            log.error(errorMsg);
        }
    }
    public void write(StaProtocol staProtocol) throws InterruptedException {
        if (staProtocol == null) {
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/SiemensDevpThread.java
@@ -5,6 +5,7 @@
import com.zy.acs.common.utils.News;
import com.zy.acs.conveyor.core.constant.DeviceField;
import com.zy.acs.conveyor.core.constant.PlcAlarmDefinition;
import com.zy.acs.conveyor.core.constant.SafeSignalField;
import com.zy.acs.conveyor.core.constant.StationStatusField;
import com.zy.acs.conveyor.core.model.StaProtocol;
import com.zy.acs.conveyor.core.properties.DevpSlave;
@@ -125,6 +126,10 @@
        // 读取PLC故障
        readPlcAlarms(staNos, staNoSize);
        // 读取安全交互信号
        readSaleSingle(slave.getPutSta(), slave.getTakeSta());
        // 定期更新数据库(降低频率)
        updateDatabaseIfNeeded();
    }
@@ -138,9 +143,13 @@
        staProtocol.setStaNo((int) siemensS7Net.getByteTransform().TransInt16(
                content, offset + StationStatusField.FINAL_TARGET.getOffset()));
        boolean[] status = siemensS7Net.getByteTransform().TransBool(
        boolean[] status0 = siemensS7Net.getByteTransform().TransBool(
                content, offset + StationStatusField.STATUS_WORD.getOffset(),
                StationStatusField.STATUS_WORD.getByteLength());
        boolean[] status = siemensS7Net.getByteTransform().TransBool(
                content, offset + StationStatusField.STATUS_WORD.getOffset(),
                1);
        staProtocol.setAutoing(status[0]);
        staProtocol.setLoading(status[1]);
@@ -150,7 +159,13 @@
        staProtocol.setFullPlt(status[5]);
        staProtocol.setHigh(status[6]);
        staProtocol.setLow(status[7]);
        boolean[] status2 = siemensS7Net.getByteTransform().TransBool(
                content, offset + StationStatusField.STATUS_WORD.getOffset() + 1,
                1);
        staProtocol.setMid(status2[0]);
        staProtocol.setStartup(status2[1]);
        staProtocol.setSegApply(status2[2]);
        staProtocol.setApplyErr(status2[3]);
    }
@@ -313,6 +328,51 @@
    }
    /**
     * 读取安全交互信号
     */
    private void readSaleSingle(List<DevpSlave.Sta> putSta, List<DevpSlave.Sta> takeSta) {
        int staNoSize = putSta.size();
        OperateResultExOne<byte[]> result = siemensS7Net.Read(
                SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.buildAddress(),
                (short) (staNoSize * SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.getByteLength()));
        if (!result.IsSuccess) {
            log.warn("读取PLC安全交互信息异常 [id:{}]", slave.getId());
            return;
        }
        byte[] content = result.Content;
        for (int i = 0; i < staNoSize; i++) {
            Integer put = putSta.get(i).getStaNo();
            Integer take = takeSta.get(i).getStaNo();
            StaProtocol staProtocolPut = station.get(put);
            StaProtocol staProtocolTake = station.get(take);
            if (staProtocolPut == null || staProtocolTake == null) {
                log.warn("站点不存在 [id:{}] [staNo:{},{}]", slave.getId(), put, take);
                continue;
            }
            boolean[] status = siemensS7Net.getByteTransform().TransBool(
                    content, i * SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.getByteLength(), 1);
            boolean[] status2 = siemensS7Net.getByteTransform().TransBool(
                    content, i * SafeSignalField.SAFE_SIGNAL_FROM_CONVEYOR.getByteLength() + 2, 1);
            staProtocolPut.setHeartbeat(status[0]);
            staProtocolPut.setAllowTake(status[1]);
            staProtocolPut.setAllowPut(status[2]);
            staProtocolPut.setInComplete(status[3]);
            staProtocolPut.setOutComplete(status[4]);
            staProtocolTake.setHeartbeat(status2[0]);
            staProtocolTake.setAllowTake(status2[1]);
            staProtocolTake.setAllowPut(status2[2]);
            staProtocolTake.setInComplete(status2[3]);
            staProtocolTake.setOutComplete(status2[4]);
        }
    }
    /**
     * 按需更新数据库(降低更新频率)
     */
    private void updateDatabaseIfNeeded() {
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/scheduler/JobLogScheduler.java
@@ -1,7 +1,6 @@
package com.zy.acs.conveyor.scheduler;
import com.zy.acs.conveyor.core.enums.ConveyorStateType;
import com.zy.acs.conveyor.core.properties.CtuOperationConfig;
import com.zy.acs.conveyor.core.properties.CtuServiceProperties;
import com.zy.acs.conveyor.entity.Job;
import com.zy.acs.conveyor.mapper.JobMapper;
@@ -37,25 +36,6 @@
        for (Job job : jobs) {
            jobService.saveJobLog(job);
        }
        Boolean flag = true;
        List<CtuOperationConfig> operations = properties.getOperations();
        for (CtuOperationConfig config : operations) {
            if (config.getType().equals(ConveyorStateType.FAKEUSER)) {
                flag = false;
            }
        }
        if (flag) {
            jobs = jobMapper.listJobToLog(ConveyorStateType.OUTBOUND.getStatus(), 1);
            for (Job job : jobs) {
                jobService.saveJobLog(job);
            }
        } else {
            jobs = jobMapper.listJobToLog(ConveyorStateType.FAKEUSER.getStatus(), 1);
            for (Job job : jobs) {
                jobService.saveJobLog(job);
            }
        }
    }
}
zy-asc-conveyor/src/main/resources/application.yml
@@ -41,27 +41,23 @@
    interval: 1000
    operations:
      - type: OUTBOUND
        mark: 10
        mark: 出库流程
        max-retries: 3
        retry-delay: 800
      #      - type: FAKEUSER
      #        mark: 20
      #        max-retries: 2
      #        retry-delay: 800
      - type: STARTUP
        mark: 启动入库流程
        max-retries: 2
        retry-delay: 800
      - type: APPLYLOC
        mark: 30
        mark: 申请入库流程
        max-retries: 2
        retry-delay: 2000
      #      - type: INBOUND
      #        mark: 40
      #        max-retries: 3
      #        retry-delay: 500
      - type: CLEARSIGNAL
        mark: 50
        mark: 清理信号流程
        max-retries: 2
        retry-delay: 800
      - type: SENDTASK
        mark: 60
        mark: 发送任务RCS流程
        max-retries: 2
        retry-delay: 800
@@ -102,17 +98,23 @@
      - 1011
      - 1012
      - 1013
    # 站点异常模块是否开启
    staNosError: true
    # 扫码模块是否开启
    barcode: true
    # 称重模块是否开启
    weight: true
    # 取站点交互信号
    # ctu放货站点
    releaseSta[0]:
    putSta[0]:
      # 本站点
      staNo: 1001
      # 目标站点
      targetSta: 1007
    # ctu入库站点
    inSta[0]:
      # 源站点
      sourceStaNo: 1007
      # 本站点
      staNo: 1010
      # 目标站点