1
zhang
4 天以前 cfd97f512b0b73bb1d86c52d6b204e6cd82dbf26
1
1个文件已删除
3个文件已添加
4 文件已重命名
29个文件已修改
1 文件已复制
1348 ■■■■ 已修改文件
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/controller/SiteController.java 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/WmsController.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/requestParam/StaParam.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/requestParam/StationRequestParam.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/vo/ApplyInDto.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/vo/SiteTableVo.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/RedisConveyorConstant.java 6 ●●●●● 补丁 | 查看 | 原始文档 | 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/enums/DeviceField.java 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/PlcAlarmDefinition.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/SafeSignalField.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/StationStatusField.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/TaskField.java 14 ●●●● 补丁 | 查看 | 原始文档 | 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 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/model/StaProtocol.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/ConveyorBackgroundService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/AppleLocOperationHandler.java 114 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/ClearSingleOperationHandler.java 46 ●●●● 补丁 | 查看 | 原始文档 | 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 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/SendTaskOperationHandler.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/StartUpOperationHandler.java 133 ●●●●● 补丁 | 查看 | 原始文档 | 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 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/service/Snap7Service.java 112 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/S7DevpThread.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/SiemensDevpThread.java 197 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/entity/Job.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/enums/WorkNoTypeType.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/mapper/JobMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/scheduler/JobLogScheduler.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/service/CtuMainService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/service/impl/CtuMainServiceImpl.java 46 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/service/impl/JobServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/service/impl/WmsMainServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/resources/application.yml 52 ●●●● 补丁 | 查看 | 原始文档 | 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/controller/SiteController.java
@@ -4,6 +4,7 @@
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.conveyor.controller.vo.SiteTableVo;
import com.zy.acs.conveyor.core.constant.RedisConveyorConstant;
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;
@@ -16,10 +17,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
 * 输送设备接口
@@ -69,10 +67,12 @@
            vo.setLoading(staProtocol.isLoading() ? "Y" : "N");     // 有物
            vo.setInEnable(staProtocol.isInEnable() ? "Y" : "N");   // 可入
            vo.setOutEnable(staProtocol.isOutEnable() ? "Y" : "N"); // 可出
            vo.setEmptyMk(staProtocol.isEmptyMk() ? "Y" : "N");     // 空板信号
            vo.setEmptyMk(staProtocol.isEmptyMk() != staProtocol.isFullPlt() ? (staProtocol.isEmptyMk() ? "空" : "满") : "-");     // 空板信号
            vo.setStaNo(staProtocol.getStaNo());                // 目标站
//            vo.setLocType1(staProtocol.isHigh() != staProtocol.isLow() && staProtocol.isLow() ? "低" : "高");     //高低库位
            vo.setLocType1(devp.getDevNo() == 102 ? "高" : "低");
            vo.setWeight(staProtocol.getWeight() == null ? 0D : staProtocol.getWeight());
            vo.setLocType1(staProtocol.isHigh() != staProtocol.isLow() ? (staProtocol.isLow() ? "低" : "高") : "-");     //高低库位
            vo.setAllow((staProtocol.getAllowPut() ? "可放" : "不可放") + "/" + (staProtocol.getAllowTake() ? "可取" : "不可取"));
            vo.setBarcode(staProtocol.getBarcode());
        }
        return R.ok().add(list);
@@ -110,9 +110,12 @@
                    vo.setLoading(staProtocol.isLoading() ? "Y" : "N");     // 有物
                    vo.setInEnable(staProtocol.isInEnable() ? "Y" : "N");   // 可入
                    vo.setOutEnable(staProtocol.isOutEnable() ? "Y" : "N"); // 可出
                    vo.setEmptyMk(staProtocol.isEmptyMk() ? "Y" : "N");     // 空板信号
                    vo.setEmptyMk(staProtocol.isEmptyMk() != staProtocol.isFullPlt() ? (staProtocol.isEmptyMk() ? "空" : "满") : "-");     // 空板信号
                    vo.setStaNo(staProtocol.getStaNo());                // 目标站
                    vo.setLocType1(staProtocol.isHigh() != staProtocol.isLow() && staProtocol.isLow() ? "低" : "高");     //高低库位
                    vo.setWeight(staProtocol.getWeight() == null ? 0D : staProtocol.getWeight());
                    vo.setLocType1(staProtocol.isHigh() != staProtocol.isLow() ? (staProtocol.isLow() ? "低" : "高") : "-");     //高低库位
                    vo.setAllow((staProtocol.getAllowPut() ? "可放" : "不可放") + "/" + (staProtocol.getAllowTake() ? "可取" : "不可取"));
                    vo.setBarcode(staProtocol.getBarcode());
                    return R.ok().add(vo);
                }
            }
@@ -124,8 +127,7 @@
    @ManagerAuth(memo = "修改站点数据")
    public R siteDetlUpdate(@RequestParam Integer siteId,
                            @RequestParam Integer workNo,
                            @RequestParam Integer staNo,
                            @RequestParam String pakMk) {
                            @RequestParam Integer staNo) {
        for (DevpSlave devp : slaveProperties.getDevp()) {
            Map<Integer, StaProtocol> station = stationService.getStationMap(devp.getId());
            for (Map.Entry<Integer, StaProtocol> entry : station.entrySet()) {
@@ -142,6 +144,7 @@
                    if (staNo != null) {
                        staProtocol.setStaNo(staNo);
                    }
                    staProtocol.setStartUpFlag(true);
                    redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                    return R.ok();
@@ -151,5 +154,47 @@
        return R.error("plc已掉线");
    }
    @PostMapping("/detl/safe")
    @ManagerAuth(memo = "补充安全信号")
    public R safe(@RequestParam Integer siteId) {
        for (DevpSlave devp : slaveProperties.getDevp()) {
            Map<Integer, StaProtocol> station = stationService.getStationMap(devp.getId());
            for (Map.Entry<Integer, StaProtocol> entry : station.entrySet()) {
                if (siteId.equals(entry.getKey())) {
                    StaProtocol staProtocol = entry.getValue();
                    if (staProtocol == null) {
                        continue;
                    } else {
                        staProtocol = staProtocol.clone();
                    }
                    boolean flag = true;
                    List<DevpSlave.Sta> putSta = devp.getPutSta();
                    List<DevpSlave.Sta> takeSta = devp.getTakeSta();
                    Optional<DevpSlave.Sta> first = takeSta.stream().filter(sta -> sta.getStaNo().equals(siteId)).findFirst();
                    int i = -1;
                    if (first.isPresent()) {
                        i = takeSta.indexOf(first.get());
                        if (i != -1) {
                            flag = false;
                        }
                    }
                    if (i == -1) {
                        first = putSta.stream().filter(sta -> sta.getStaNo().equals(siteId)).findFirst();
                        if (first.isPresent()) {
                            i = putSta.indexOf(first.get());
                            flag = true;
                        }
                    }
                    if (i == -1) {
                        return R.error("此站点无需安全信号");
                    }
                    staProtocol.setSafeSignal(new SafeSignal(i, true, flag));
                    redis.push(RedisConveyorConstant.CONVEYOR_SAFE_FLAG, staProtocol);
                    return R.ok();
                }
            }
        }
        return R.error("plc已掉线");
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/WmsController.java
@@ -39,10 +39,11 @@
    @ResponseBody
    @PostMapping("/station/getTaskNo")
    public R query(@RequestBody StaParam param) {
        log.info("根据站点查询staNo:{}", param);
        String staNo = param.getStaNo();
        Map<Integer, StaProtocol> station = stationService.getStationMap(param.getDevpId());
        StaProtocol staProtocol = station.get(Integer.parseInt(staNo));
        StaProtocol staProtocol = station.get(param.getStationId());
        if (staProtocol == null) {
            return R.error("站点不存在");
        }
        Integer workNo = staProtocol.getWorkNo();
        if (workNo != null) {
            Job jobByJobNo = jobService.getJobByJobNo(workNo);
@@ -60,19 +61,28 @@
    @ResponseBody
    @PostMapping("/station/getError")
    public R getError(@RequestBody StaParam param) {
        log.info("根据站点查询staNo:{}", param);
        String staNo = param.getStaNo();
        Map<Integer, StaProtocol> station = stationService.getStationMap(param.getDevpId());
        StaProtocol staProtocol = station.get(Integer.parseInt(staNo));
        return R.ok(staPlcErr(staProtocol));
        List<PlcErrorTableVo> list = new ArrayList<>();
        if (param.getStationId() != null) {
            Map<Integer, StaProtocol> station = stationService.getStationMap(param.getDevpId());
            StaProtocol staProtocol = station.get(param.getStationId());
            return R.ok(staPlcErr(list, staProtocol));
        }
        if (param.getStationIds() != null && !param.getStationIds().isEmpty()) {
            Map<Integer, StaProtocol> station = stationService.getStationMap(param.getDevpId());
            for (Integer stationId : param.getStationIds()) {
                StaProtocol staProtocol = station.get(stationId);
                list = staPlcErr(list, staProtocol);
                return R.ok(list);
            }
        }
        return R.ok();
    }
    private List<PlcErrorTableVo> staPlcErr(StaProtocol staProtocol) {
    private List<PlcErrorTableVo> staPlcErr(List<PlcErrorTableVo> list, StaProtocol staProtocol) {
        if (staProtocol == null) {
            return null;
        }
        List<PlcErrorTableVo> list = new ArrayList<>();
        if (staProtocol.getBreakerErr()) {
            PlcErrorTableVo vo = new PlcErrorTableVo();
            vo.setStaNo(staProtocol.getSiteId());
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/requestParam/StaParam.java
@@ -3,13 +3,19 @@
import lombok.Data;
import java.io.Serializable;
import java.util.List;
@Data
public class StaParam implements Serializable {
    /**
     * 站点列表
     */
    private String staNo;
    private Integer stationId;
    /**
     * 站点列表
     */
    private List<Integer> stationIds;
    /**
     * 输送线编号
     */
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/requestParam/StationRequestParam.java
@@ -16,6 +16,11 @@
     * 站点列表
     */
    private String staNo;
    /**
     * 站点列表
     */
    private String seqNum;
    /**
     * 输送线编号
     */
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/vo/ApplyInDto.java
@@ -8,11 +8,16 @@
@Data
public class ApplyInDto {
    //站点号
    private String staNo;
    //条码
    private String barcode;
    //是否满版
    private Boolean full;
    //重量
    private Double weight;
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/vo/SiteTableVo.java
@@ -37,4 +37,12 @@
    //高低库位
    private String locType1 = "-";
    private Double weight = 0D;
    //可取
    private String allow = "-";
    private String barcode = "-";
}
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 interface 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/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/enums/DeviceField.java
File was renamed from zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/DeviceField.java
@@ -1,25 +1,33 @@
package com.zy.acs.conveyor.core.constant;
package com.zy.acs.conveyor.core.enums;
import com.zy.acs.conveyor.core.constant.PlcConstant;
/**
 * 设备字段枚举(对应 §2.2)
 */
public enum DeviceField {
    // 扫码器:每站点16字节,String[14]
    BARCODE("DB101", 0, 16),
    BARCODE("DB103", 254, 18, new int[]{0, 2}, 21),
    // 出入库模式
    IO_MODE("DB103", 170, 4, new int[]{0, 2}, 21),
    // 称重:每站点4字节,Float
    WEIGHT("DB102", 0, 4),
    WEIGHT("DB103", 632, 6, new int[]{0, 2}, 21),
    // 尺寸异常:每站点2字节,Bit数组
    DIMENSION_WORD("DB103", 0, 2);
    DIMENSION_WORD("DB103", 2, 8, new int[]{0, 2, 4, 6}, 21);
    private final String addressPattern;
    private final int offset;
    private final int byteLength;
    private final int[] seg;
    private final int arrLength;
    DeviceField(String addressPattern, int offset, int byteLength) {
    DeviceField(String addressPattern, int offset, int byteLength, int[] seg, int arrLength) {
        this.addressPattern = addressPattern;
        this.offset = offset;
        this.byteLength = byteLength;
        this.seg = seg;
        this.arrLength = arrLength;
    }
    public String getAddressPattern() {
@@ -34,6 +42,14 @@
        return byteLength;
    }
    public int getArrLength() {
        return arrLength;
    }
    public int[] getSeg() {
        return seg;
    }
    /**
     * 根据 DB 块编号和站点偏移生成具体地址
     *
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/PlcAlarmDefinition.java
File was renamed from zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/PlcAlarmDefinition.java
@@ -1,4 +1,6 @@
package com.zy.acs.conveyor.core.constant;
package com.zy.acs.conveyor.core.enums;
import com.zy.acs.conveyor.core.constant.PlcConstant;
/**
 * PLC 报警定义(对应 §2.3)
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/SafeSignalField.java
copy from zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/DeviceField.java copy to zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/SafeSignalField.java
File was copied from zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/DeviceField.java
@@ -1,25 +1,24 @@
package com.zy.acs.conveyor.core.constant;
package com.zy.acs.conveyor.core.enums;
import com.zy.acs.conveyor.core.constant.PlcConstant;
/**
 * 设备字段枚举(对应 §2.2)
 */
public enum DeviceField {
    // 扫码器:每站点16字节,String[14]
    BARCODE("DB101", 0, 16),
    // 称重:每站点4字节,Float
    WEIGHT("DB102", 0, 4),
    // 尺寸异常:每站点2字节,Bit数组
    DIMENSION_WORD("DB103", 0, 2);
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;
    DeviceField(String addressPattern, int offset, int byteLength) {
    SafeSignalField(String addressPattern, int offset, int byteLength, int arrLength) {
        this.addressPattern = addressPattern;
        this.offset = offset;
        this.byteLength = byteLength;
        this.arrLength = arrLength;
    }
    public String getAddressPattern() {
@@ -34,6 +33,10 @@
        return byteLength;
    }
    public int getArrLength() {
        return arrLength;
    }
    /**
     * 根据 DB 块编号和站点偏移生成具体地址
     *
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/StationStatusField.java
File was renamed from zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/StationStatusField.java
@@ -1,11 +1,13 @@
package com.zy.acs.conveyor.core.constant;
package com.zy.acs.conveyor.core.enums;
import com.zy.acs.conveyor.core.constant.PlcConstant;
/**
 * 站点状态字段枚举(对应 §2.1)
 */
public enum StationStatusField {
    ALL("DB100", 0, 12),
    ALL("DB100", 10, 10),
    TASK_NUMBER("DB100", 0, 4),          // 任务号,偏移0,4字节
    FINAL_TARGET("DB100", 4, 2),          // 最终目标站,偏移4,2字节
    STATUS_WORD("DB100", 6, 2),           // 状态字,偏移6,2字节
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/TaskField.java
File was renamed from zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/TaskField.java
@@ -1,16 +1,16 @@
package com.zy.acs.conveyor.core.constant;
package com.zy.acs.conveyor.core.enums;
/**
 * 任务下发字段枚举(对应 §2.4)
 */
public enum TaskField {
    ALL("DB13", 0, 12),
    TASK_NUMBER("DB13", 0, 4),
    START_STATION("DB13", 4, 2),
    DEST_STATION("DB13", 6, 2),
    DIRECTION("DB13", 8, 2),
    ROUTE_NUMBER("DB13", 10, 2);
    ALL("DB13", 48, 48),
    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/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,22 @@
package com.zy.acs.conveyor.core.model;
import lombok.Data;
import java.io.Serializable;
@Data
public class SafeSignal implements Serializable {
    //是数组所在位置,就是第几个出库口或者第几个入库口
    private Integer index;
    //是写0还是1
    private Boolean value;
    //代表写在交互1还是交互2
    private Boolean flag;
    public SafeSignal(Integer index, Boolean value, Boolean flag) {
        this.index = index;
        this.value = value;
        this.flag = flag;
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/model/StaProtocol.java
@@ -3,12 +3,16 @@
import com.zy.acs.conveyor.entity.Devp;
import lombok.Data;
import java.io.Serializable;
/**
 * 输送线plc单个站点详细信息
 * Created by vincent on 2020/8/6
 */
@Data
public class StaProtocol implements Cloneable {
public class StaProtocol implements Cloneable, Serializable {
    private boolean startUpFlag = true;
    private Integer plcId;
@@ -30,10 +34,10 @@
    // 有物
    private boolean loading;
    // 可入
    // 需求入
    private boolean inEnable;
    // 可出
    // 需求出
    private boolean outEnable;
    // 空板信号
@@ -47,6 +51,18 @@
    // 低
    private boolean low;
    // 中
    private boolean mid;
    // 启动入库
    private boolean startup;
    // 中途任务申请
    private boolean segApply;
    // 入库异常
    private boolean applyErr;
    //条码
    private String barcode;
@@ -78,6 +94,9 @@
    // 扫码失败
    private boolean barcodeErr = false;
    // 有货报警,空托入库时检测托盘上有无货物
    private boolean loadErr = false;
    //故障-----------------------------------------------------------------------
    private Boolean breakerErr = false; //断路器故障
@@ -95,6 +114,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/ConveyorBackgroundService.java
@@ -36,7 +36,7 @@
    private long lastDbUpdateTime = 0;
    private static final int LOG_INTERVAL_MS = 30000;
    private static final int LOG_INTERVAL_MS = 300000;
    @PostConstruct
    public void init() {
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;
@@ -13,7 +14,6 @@
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.enums.WorkNoTypeType;
import com.zy.acs.conveyor.service.JobService;
import com.zy.acs.conveyor.service.WmsMainService;
import com.zy.acs.conveyor.service.WrkLastnoService;
@@ -77,34 +77,90 @@
                        staProtocol = staProtocol.clone();
                    }
                    // 判断是否满足条件
                    if (!staProtocol.isLoading()) {
                    if (staProtocol.getWorkNo() == 0) {
                        continue;
                    }
                    if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing()) {
                        String barcode = staProtocol.getBarcode();
                        if (Cools.isEmpty(barcode)) {
                            News.error("站点:{},未扫到码值:{}", staProtocol.getSiteId(), barcode);
                            return;
                    if (!staProtocol.isAutoing()) {
                        //News.error("{}:站点:{},非自动", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (!staProtocol.isLoading()) {
                        News.error("{}:站点:{},无物", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    if (staProtocol.isErr()){
                        if (staProtocol.isFrontErr()) {
                            News.error("{}:站点:{},前超限", config.getMark(), staProtocol.getSiteId());
                            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());
                                }
                            }
                        if (staProtocol.isBackErr()) {
                            News.error("{}:站点:{},后超限", config.getMark(), staProtocol.getSiteId());
                            continue;
                        }
                        if ( staProtocol.isHighErr()) {
                            News.error("{}:站点:{},高超限", config.getMark(), staProtocol.getSiteId());
                            continue;
                        }
                        if ( staProtocol.isLeftErr()) {
                            News.error("{}:站点:{},左超限", config.getMark(), staProtocol.getSiteId());
                            continue;
                        }
                        if ( staProtocol.isRightErr()) {
                            News.error("{}:站点:{},右超限", config.getMark(), staProtocol.getSiteId());
                            continue;
                        }
                        if (staProtocol.isWeightErr()) {
                            News.error("{}:站点:{},超重或", config.getMark(), staProtocol.getSiteId());
                            continue;
                        }
                        if ( staProtocol.isBarcodeErr()) {
                            News.error("{}:站点:{},扫码失败", config.getMark(), staProtocol.getSiteId());
                            continue;
                        }
                    }
                    if (staProtocol.isLoadErr()) {
                        News.error("{}:站点:{},入库时检测托盘上有无货物", config.getMark(), staProtocol.getSiteId());
                        continue;
                    }
                    String barcode = staProtocol.getBarcode();
                    if (Cools.isEmpty(barcode)) {
                        News.error("站点:{},未扫到码值:{}", staProtocol.getSiteId(), barcode);
                        continue;
                    }
                    Job job = jobService.getJobByJobNo(staProtocol.getWorkNo());
                    //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;
                        }
                        News.error("{}:站点:{},任务状态不对,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(job));
                        continue;
                    }
                    ApplyInRepsonseDto locOfWms = wmsMainService.getLocOfWms(applyIn(job, barcode, inSta.getStaNo() + "", staProtocol));
                    if (locOfWms != null) {
                        staProtocol.setWorkNo(staProtocol.getWorkNo());
                        staProtocol.setStaNo(inSta.getTargetSta());
                        redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                        job.setLoc(locOfWms.getLocNo());
                        job.setStaNo(String.valueOf(inSta.getTargetSta()));
                        job.setTaskNo(locOfWms.getTaskNo());
                        job.setBatchNo(locOfWms.getBatchNo());
                        job.setBarcode(barcode);
                        job.setWmsTime(new Date());
                        job.setJobSts(ConveyorStateType.INBOUND.getStatus());
                        //if (jobService.insert(initJob(locOfWms, barcode, workNo, inSta.getTargetSta() + ""))) {
                        if (jobService.updateById(job)) {
                            News.info("申请入库成功,条码:{},站点:{}", barcode, inSta.getStaNo());
                        }
                    } else {
                        News.error("WMS未返回库位信息,条码:{},站点:{}", barcode, inSta.getStaNo());
                    }
                }
            }
@@ -128,15 +184,13 @@
        return job;
    }
    private Integer getWorkNo() {
        return wrkLastnoService.nextWorkNo(WorkNoTypeType.WORK_NO_TYPE.type);
    }
    private ApplyInDto applyIn(String barcode, String staNo, StaProtocol staProtocol) {
    private ApplyInDto applyIn(Job job, String barcode, String staNo, StaProtocol staProtocol) {
        ApplyInDto applyInDto = new ApplyInDto();
        applyInDto.setStaNo(staNo);
        applyInDto.setBarcode(barcode);
        applyInDto.setFull(staProtocol.isFullPlt());
        applyInDto.setFull(Boolean.valueOf(job.getFull()));
        applyInDto.setWeight(staProtocol.getWeight());
        return applyInDto;
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/ClearSingleOperationHandler.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;
@@ -11,12 +13,14 @@
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.CtuMainService;
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.Date;
import java.util.Map;
@@ -37,6 +41,10 @@
    @Autowired
    private StationService stationService;
    @Autowired
    private CtuMainService ctuMainService;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
@@ -63,20 +71,38 @@
                    }
                    // 判断是否满足条件
                    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 && !staProtocol.isLoading()) {
                        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;
                        }
                        if (ctuMainService.checkComplete(job.getTaskNo())) {
                            staProtocol.setSafeSignal(new SafeSignal(devp.getTakeSta().indexOf(takeSta), true, false));
                            redis.push(RedisConveyorConstant.CONVEYOR_SAFE_FLAG, staProtocol);
                            job.setUpdateTime(new Date());
                            job.setJobSts(ConveyorStateType.CLEARSIGNAL.getStatus());
                            jobService.updateById(job);
                            //log.info("" + config.getMark() + "站点清空:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo());
                            News.info("" + config.getMark() + "站点清空:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo());
                            if (!jobService.updateById(job)) {
                                log.info("" + config.getMark() + "站点清空失败:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo());
                            } else {
                                News.info("" + config.getMark() + "站点清空:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo());
                            }
                        } else {
                            log.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;
@@ -22,11 +24,12 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.Date;
import java.util.Map;
@Slf4j
@Component
public class OutOperationHandler implements OperationHandler  {
public class OutOperationHandler implements OperationHandler {
    @Autowired
    private SlaveProperties slaveProperties;
@@ -59,50 +62,50 @@
            // 根据输送线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());
                            Job job = jobService.getJobByTaskNo(seqNum);
                            if (job != null) {
                                News.error("{}:站点:{},存在任务,{}", config.getMark(), staProtocol.getSiteId(), JSON.toJSON(job));
                                continue;
                            }
                            staProtocol.setSafeSignal(new SafeSignal(devp.getPutSta().indexOf(putSta), true, true));
                            redis.push(RedisConveyorConstant.CONVEYOR_SAFE_FLAG, staProtocol);
                            int workNo = wrkLastnoService.nextWorkNo(WorkNoTypeType.WORK_NO_OUT_TYPE.type);
                            staProtocol.setWorkNo(workNo);
                            staProtocol.setStaNo(putSta.getTargetSta());
                            job = new Job();
                            job.setTaskNo(seqNum);
                            job.setJobNo(workNo);
                            job.setCreateTime(new Date());
                            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());
                        }
                    }
                }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/SendTaskOperationHandler.java
@@ -1,10 +1,12 @@
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;
import com.zy.acs.conveyor.controller.vo.TaskDto;
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;
@@ -62,43 +64,54 @@
            // 根据输送线plc遍历
            for (DevpSlave devp : slaveProperties.getDevp()) {
                // 遍历入库口
                for (DevpSlave.Sta inSta : devp.getInSta()) {
                for (DevpSlave.Sta sta : devp.getTakeSta()) {
                    // 根据输送线plc遍历
                    Map<Integer, StaProtocol> stationMap = stationService.getStationMap(devp.getId());
                    StaProtocol staProtocol = stationMap.get(inSta.getTargetSta());
                    StaProtocol staProtocol = stationMap.get(sta.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() || staProtocol.getWorkNo() == 0) {
                        //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.getWorkNo() > 0 && !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.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);
//                        staProtocol.setWorkNo(staProtocol.getWorkNo());
//                        staProtocol.setStaNo(sta.getStaNo());
//                        redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                        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,133 @@
package com.zy.acs.conveyor.core.operation.handler;
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.enums.WorkNoTypeType;
import com.zy.acs.conveyor.service.JobService;
import com.zy.acs.conveyor.service.WrkLastnoService;
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.Date;
import java.util.Map;
/**
 * 模拟用户按按钮
 */
@Slf4j
@Component
public class StartUpOperationHandler implements OperationHandler {
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private JobService jobService;
    @Autowired
    private StationService stationService;
    @Autowired
    private WrkLastnoService wrkLastnoService;
    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;
//                    }
                    if (staProtocol.getWorkNo() == 0 && staProtocol.isStartUpFlag()) {
                        Job job = initJob(getWorkNo(), staProtocol.isFullPlt());
                        staProtocol.setWorkNo(job.getJobNo());
                        staProtocol.setStaNo(inSta.getStaNo());
                        staProtocol.setStartUpFlag(false);
                        redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                        if (!jobService.insert(job)) {
                            News.info("{},启动入库:工作号:{},目标站点:{},满:{},空:{}", config.getMark(), staProtocol.getWorkNo(), staProtocol.getStaNo(),staProtocol.isFullPlt(),staProtocol.isEmptyMk());
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }
    private Job initJob(Integer workNo, Boolean fullPlt) {
        Job job = new Job();
        job.setJobNo(workNo);
        job.setJobSts(ConveyorStateType.STARTUP.getStatus());
        job.setStartTime(new Date());
        job.setCreateTime(new Date());
        job.setFull(fullPlt.toString());
        return job;
    }
    private Integer getWorkNo() {
        return wrkLastnoService.nextWorkNo(WorkNoTypeType.WORK_NO_IN_TYPE.type);
    }
}
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
@@ -18,24 +18,27 @@
    private Integer slot;
    private Boolean weight;
    private List<Sta> releaseSta = new ArrayList<>();
    private Boolean barcode;
    private Boolean staNosError;
    private List<Sta> putSta = new ArrayList<>();
    private List<Sta> takeSta = new ArrayList<>();
    private List<Sta> inSta = new ArrayList<>();
    private List<Integer> barcodeArr = new ArrayList<>();
    private List<Integer> weightArr = new ArrayList<>();
    private List<Integer> staNos = new ArrayList<>();
    private List<Integer> staNosError = new ArrayList<>();
    @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,13 +5,16 @@
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.TaskField;
import com.zy.acs.conveyor.core.enums.SafeSignalField;
import com.zy.acs.conveyor.core.enums.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;
import com.zy.acs.conveyor.core.properties.SlaveProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.text.MessageFormat;
@@ -28,8 +31,8 @@
    @Autowired
    private DevpS7Service devpS7Service;
    private static final int WRITE_RETRY_MAX = 5;
    @Value("${plc-write.retry}")
    private int WRITE_RETRY;
    private static final int WRITE_RETRY_INTERVAL_MS = 200;
@@ -37,32 +40,110 @@
    }
    public void write(StaProtocol staProtocol) throws InterruptedException {
    public void writeSafe(StaProtocol staProtocol) throws InterruptedException {
        if (staProtocol == null) {
            log.warn("写入数据为空,跳过 [id:{}]", JSON.toJSONString(staProtocol));
            News.warn("写入数据为空,跳过 [id:{}]", JSON.toJSONString(staProtocol));
            return;
        }
        SiemensS7Net siemensS7Net = devpS7Service.get(staProtocol.getPlcId());
        if (siemensS7Net == null) {
            log.error("PLC未连接,无法写入 [id:{}]", JSON.toJSONString(staProtocol));
            News.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));
            News.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());
            News.error("站点编号不存在于配置中 [id:{}] [siteId:{}]", staProtocol.getPlcId(), staProtocol.getSiteId());
            return;
        }
        SafeSignal safeSignal = staProtocol.getSafeSignal();
        int baseOffset = 0;
        boolean[] array = new boolean[6];
        array[0] = true;
        array[1] = false;
        array[2] = false;
        array[5] = false;
        if (safeSignal.getFlag()) {
            array[3] = false;
            array[4] = safeSignal.getValue();
            baseOffset = SafeSignalField.SAFE_SIGNAL_TO_CONVEYOR.getOffset() + safeSignal.getIndex() * SafeSignalField.SAFE_SIGNAL_TO_CONVEYOR.getByteLength();
        } else {
            array[3] = safeSignal.getValue();
            array[4] = false;
            baseOffset = SafeSignalField.SAFE_SIGNAL_TO_CONVEYOR.getOffset() + 2 + safeSignal.getIndex() * SafeSignalField.SAFE_SIGNAL_TO_CONVEYOR.getByteLength();
        }
        String flagAddr = SafeSignalField.SAFE_SIGNAL_TO_CONVEYOR.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION
                + baseOffset;
        // 任务下发重试机制
        int writeCount = 0;
        boolean success = false;
        while (writeCount <= WRITE_RETRY) {
            OperateResult writeResult = siemensS7Net.Write(flagAddr, array);
            if (writeResult.IsSuccess) {
                News.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++;
            News.error("写入安全信号输送线命令失败 [id:{}] [siteId:{}] [retry:{}] [workErr:{}] ",
                    staProtocol.getPlcId(), staProtocol.getSiteId(), writeCount,
                    writeResult.Message);
            if (writeCount <= WRITE_RETRY) {
                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));
        }
    }
    public void write(StaProtocol staProtocol) throws InterruptedException {
        if (staProtocol == null) {
            News.warn("写入数据为空,跳过 [id:{}]", JSON.toJSONString(staProtocol));
            return;
        }
        int baseOffset = index * TaskField.ALL.getByteLength();
        SiemensS7Net siemensS7Net = devpS7Service.get(staProtocol.getPlcId());
        if (siemensS7Net == null) {
            News.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) {
            News.error("PLC未配置,无法写入 [id:{}]", JSON.toJSONString(staProtocol));
            return;
        }
        int index = devpSlave.getStaNos().indexOf(staProtocol.getSiteId());
        if (index < 0) {
            News.error("站点编号不存在于配置中 [id:{}] [siteId:{}]", staProtocol.getPlcId(), staProtocol.getSiteId());
            return;
        }
        int baseOffset = TaskField.ALL.getOffset() + index * TaskField.ALL.getByteLength();
        String workNoAddr = TaskField.TASK_NUMBER.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION
                + (baseOffset + TaskField.TASK_NUMBER.getOffset());
        String destStaAddr = TaskField.DEST_STATION.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION
@@ -72,14 +153,14 @@
        int writeCount = 0;
        boolean success = false;
        while (writeCount < WRITE_RETRY_MAX) {
            OperateResult writeResult = siemensS7Net.Write(workNoAddr, staProtocol.getWorkNo().shortValue());
        while (writeCount <= WRITE_RETRY) {
            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:{}]",
                News.info("写入输送线命令成功 [id:{}] [siteId:{}] [workNo:{}] [destSta:{}] [retry:{}]",
                        staProtocol.getPlcId(), staProtocol.getSiteId(), staProtocol.getWorkNo(),
                        staProtocol.getStaNo(), writeCount);
                OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线命令成功。输送线plc编号={1},站点数据={2}",
@@ -89,11 +170,11 @@
            }
            writeCount++;
            log.error("写入输送线命令失败 [id:{}] [siteId:{}] [retry:{}] [workErr:{}] [destErr:{}]",
            News.error("写入输送线命令失败 [id:{}] [siteId:{}] [retry:{}] [workErr:{}] [destErr:{}]",
                    staProtocol.getPlcId(), staProtocol.getSiteId(), writeCount,
                    writeResult.Message, writeResult1.Message);
            if (writeCount < WRITE_RETRY_MAX) {
            if (writeCount <= WRITE_RETRY) {
                Thread.sleep(WRITE_RETRY_INTERVAL_MS);
            }
        }
@@ -104,7 +185,6 @@
            OutputQueue.DEVP.offer(errorMsg);
            News.error("SiemensDevp - 4 - 写入输送线站点数据失败。输送线plc编号={},站点数据={}",
                    staProtocol.getPlcId(), JSON.toJSON(staProtocol));
            log.error(errorMsg);
        }
    }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/S7DevpThread.java
@@ -7,10 +7,10 @@
//import com.zy.acs.common.utils.News;
//import com.zy.acs.conveyor.core.DevpThread;
//import com.zy.acs.conveyor.core.cache.SlaveConnection;
//import com.zy.acs.conveyor.core.constant.DeviceField;
//import com.zy.acs.conveyor.core.enums.DeviceField;
//import com.zy.acs.conveyor.core.constant.PlcConstant;
//import com.zy.acs.conveyor.core.constant.StationStatusField;
//import com.zy.acs.conveyor.core.constant.TaskField;
//import com.zy.acs.conveyor.core.enums.StationStatusField;
//import com.zy.acs.conveyor.core.enums.TaskField;
//import com.zy.acs.conveyor.core.enums.SlaveType;
//import com.zy.acs.conveyor.core.model.StaProtocol;
//import com.zy.acs.conveyor.core.properties.DevpSlave;
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/SiemensDevpThread.java
@@ -3,9 +3,13 @@
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
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.StationStatusField;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.conveyor.core.constant.*;
import com.zy.acs.conveyor.core.enums.DeviceField;
import com.zy.acs.conveyor.core.enums.PlcAlarmDefinition;
import com.zy.acs.conveyor.core.enums.SafeSignalField;
import com.zy.acs.conveyor.core.enums.StationStatusField;
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.service.DevpS7Service;
@@ -36,6 +40,9 @@
    private SiemensS7Net siemensS7Net;
    private Map<Integer, StaProtocol> station;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    private static final int WRITE_RETRY_MAX = 5;
@@ -109,7 +116,7 @@
        byte[] content = result.Content;
        for (int i = 0; i < staNoSize; i++) {
            StaProtocol staProtocol = station.get(staNos.get(staNoSize));
            StaProtocol staProtocol = station.get(staNos.get(i));
            parseStationStatus(content, i, staProtocol);
        }
@@ -125,6 +132,10 @@
        // 读取PLC故障
        readPlcAlarms(staNos, staNoSize);
        // 读取安全交互信号
        readSaleSingle(slave.getPutSta(), slave.getTakeSta());
        // 定期更新数据库(降低频率)
        updateDatabaseIfNeeded();
    }
@@ -134,13 +145,17 @@
     */
    private void parseStationStatus(byte[] content, int index, StaProtocol staProtocol) {
        int offset = index * StationStatusField.ALL.getByteLength();
        staProtocol.setWorkNo(siemensS7Net.getByteTransform().TransInt32(content, offset));
        staProtocol.setWorkNo(siemensS7Net.getByteTransform().TransInt32(content, offset + StationStatusField.TASK_NUMBER.getOffset()));
        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,22 +165,36 @@
        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]);
        if (!status2[1] && !status[1]) {
            staProtocol.setStartUpFlag(true);
        }
        for (int i = 0; i < 8; i++) {
            if (status0[i + 8] != status2[i]) {
                log.info("状态码不一致 [id:{}] [i:{}] [status0:{}] [status2:{}]", slave.getId(), i, status0[i], status2[i]);
            }
        }
    }
    /**
     * 读取条码信息
     */
    private void readBarcodes() {
        List<Integer> barcodeArr = slave.getBarcodeArr();
        if (barcodeArr == null || barcodeArr.isEmpty()) {
        if (slave.getBarcode() == null || !slave.getBarcode()) {
            return;
        }
        OperateResultExOne<byte[]> result = siemensS7Net.Read(
                DeviceField.BARCODE.buildAddress(),
                (short) (barcodeArr.size() * DeviceField.BARCODE.getByteLength()));
                (short) (DeviceField.BARCODE.getByteLength() * DeviceField.BARCODE.getArrLength()));
        if (!result.IsSuccess) {
            log.warn("读取条码失败 [id:{}]", slave.getId());
@@ -173,48 +202,57 @@
        }
        byte[] content = result.Content;
        for (int i = 0; i < barcodeArr.size(); i++) {
        for (int i = 0; i < DeviceField.BARCODE.getArrLength(); i++) {
            int[] seg = DeviceField.BARCODE.getSeg();
            int staNo = siemensS7Net.getByteTransform().TransInt16(
                    content, seg[0] + i * DeviceField.BARCODE.getByteLength());
            String barcode = siemensS7Net.getByteTransform().TransString(
                    content, i * DeviceField.BARCODE.getByteLength(),
                    DeviceField.BARCODE.getByteLength(), "UTF-8");
                    content, seg[1] + i * DeviceField.BARCODE.getByteLength(),
                    DeviceField.BARCODE.getByteLength() - seg[1], "UTF-8").trim();
            if (!Cools.isEmpty(barcode)) {
                StaProtocol staProtocol = station.get(barcodeArr.get(i));
            if (!Cools.isEmpty(barcode) && !barcode.contains("Default") && !barcode.contains("Error") && staNo != 0) {
                StaProtocol staProtocol = station.get(staNo);
                if (staProtocol == null) {
                    log.warn("站点不存在 [id:{}] [staNo:{}]", slave.getId(), barcodeArr.get(i));
                    log.warn("扫码站点不存在 [id:{}] [staNo:{}]", slave.getId(), staNo);
                    continue;
                }
                staProtocol.setBarcode(barcode);
                News.info("料箱码:{}", barcode);
                //News.info("料箱码:{}", barcode);
            }
        }
    }
    /**
     * 读取条码信息
     * 读取重量信息
     */
    private void readWeight() {
        List<Integer> weightArr = slave.getWeightArr();
        if (weightArr == null || weightArr.isEmpty()) {
        if (slave.getWeight() == null || !slave.getWeight()) {
            return;
        }
        OperateResultExOne<byte[]> result = siemensS7Net.Read(
                DeviceField.WEIGHT.buildAddress(),
                (short) (weightArr.size() * DeviceField.WEIGHT.getByteLength()));
                (short) (DeviceField.WEIGHT.getArrLength() * DeviceField.WEIGHT.getByteLength()));
        if (!result.IsSuccess) {
            log.warn("读取重量失败 [id:{}]", slave.getId());
            return;
        }
        for (int i = 0; i < weightArr.size(); i++) {
            StaProtocol staProtocol = station.get(weightArr.get(i));
            if (staProtocol == null) {
                log.warn("站点不存在 [id:{}] [staNo:{}]", slave.getId(), weightArr.get(i));
                continue;
        byte[] content = result.Content;
        for (int i = 0; i < DeviceField.WEIGHT.getArrLength(); i++) {
            int[] seg = DeviceField.WEIGHT.getSeg();
            int staNo = siemensS7Net.getByteTransform().TransInt16(
                    content, seg[0] + i * DeviceField.WEIGHT.getByteLength());
            Double weight = (double) siemensS7Net.getByteTransform().TransSingle(
                    content, seg[1] + i * DeviceField.WEIGHT.getByteLength());
            if (!Cools.isEmpty(weight) && staNo != 0) {
                StaProtocol staProtocol = station.get(staNo);
                if (staProtocol == null) {
                    log.warn(" [id:{}] [staNo:{}]", slave.getId(), staNo);
                    continue;
                }
                staProtocol.setWeight(BigDecimal.valueOf(weight).setScale(4, RoundingMode.HALF_UP).doubleValue());
            }
            double weight = siemensS7Net.getByteTransform().TransSingle(result.Content, i * DeviceField.WEIGHT.getByteLength());
            staProtocol.setWeight(BigDecimal.valueOf(weight).setScale(4, RoundingMode.HALF_UP).doubleValue());
        }
    }
@@ -222,14 +260,13 @@
     * 读取外形检测错误
     */
    private void readDimensionErrors() {
        List<Integer> staNosError = slave.getStaNosError();
        if (staNosError == null || staNosError.isEmpty()) {
        if (slave.getStaNosError() == null || !slave.getStaNosError()) {
            return;
        }
        OperateResultExOne<byte[]> result = siemensS7Net.Read(
                DeviceField.DIMENSION_WORD.buildAddress(),
                (short) (staNosError.size() * DeviceField.DIMENSION_WORD.getByteLength()));
                (short) (DeviceField.DIMENSION_WORD.getArrLength() * DeviceField.DIMENSION_WORD.getByteLength()));
        if (!result.IsSuccess) {
            log.warn("读取外形检测错误失败 [id:{}]", slave.getId());
@@ -237,25 +274,35 @@
        }
        byte[] content = result.Content;
        for (int i = 0; i < staNosError.size(); i++) {
            Integer siteId = staNosError.get(i);
            StaProtocol staProtocol = station.get(siteId);
            if (staProtocol == null){
                log.warn("站点不存在 [id:{}] [staNo:{}]", slave.getId(), staNosError.get(i));
                continue;
        for (int i = 0; i < DeviceField.DIMENSION_WORD.getArrLength(); i++) {
            int[] seg = DeviceField.DIMENSION_WORD.getSeg();
            int staNo = siemensS7Net.getByteTransform().TransInt16(
                    content, seg[0]);
            if (staNo != 0) {
                StaProtocol staProtocol = station.get(staNo);
                if (staProtocol == null) {
                    log.warn("异常站点不存在 [id:{}] [staNo:{}]", slave.getId(), staNo);
                    continue;
                }
                boolean[] status = siemensS7Net.getByteTransform().TransBool(
                        content, seg[1] + i * DeviceField.DIMENSION_WORD.getByteLength(),
                        1);
//未使用,预留
//                boolean[] status1 = siemensS7Net.getByteTransform().TransBool(
//                        content, seg[1]+i * DeviceField.DIMENSION_WORD.getByteLength()+1,
//                        1);
                staProtocol.setLeftErr(status[0]);
                staProtocol.setRightErr(status[1]);
                staProtocol.setFrontErr(status[2]);
                staProtocol.setBackErr(status[3]);
                staProtocol.setHighErr(status[4]);
                staProtocol.setLoadErr(status[5]);
                staProtocol.setWeightErr(status[6]);
                staProtocol.setBarcodeErr(status[7]);
            }
            boolean[] status = siemensS7Net.getByteTransform().TransBool(
                    content, i * DeviceField.DIMENSION_WORD.getByteLength(),
                    DeviceField.DIMENSION_WORD.getByteLength());
            staProtocol.setFrontErr(status[0]);
            staProtocol.setBackErr(status[1]);
            staProtocol.setHighErr(status[2]);
            staProtocol.setLeftErr(status[3]);
            staProtocol.setRightErr(status[4]);
            staProtocol.setWeightErr(status[5]);
            staProtocol.setBarcodeErr(status[6]);
        }
    }
@@ -296,6 +343,64 @@
    }
    /**
     * 读取安全交互信号
     */
    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]);
            //
            if (status[3]) {
                staProtocolPut.setSafeSignal(new SafeSignal(i, false, true));
                redis.push(RedisConveyorConstant.CONVEYOR_SAFE_FLAG, staProtocolPut);
                News.info("安全交互信号复位 [id:{}] [staNo:{}]", slave.getId(), staProtocolPut.getSiteId());
            }
            if (status2[4]) {
                staProtocolTake.setSafeSignal(new SafeSignal(i, false, false));
                redis.push(RedisConveyorConstant.CONVEYOR_SAFE_FLAG, staProtocolTake);
                News.info("安全交互信号复位 [id:{}] [staNo:{}]", slave.getId(), staProtocolPut.getSiteId());
            }
        }
    }
    /**
     * 按需更新数据库(降低更新频率)
     */
    private void updateDatabaseIfNeeded() {
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/entity/Job.java
@@ -57,8 +57,11 @@
     */
    @TableField("job_no")
    private Integer jobNo;
    /**
     * 是否满版
     */
    @TableField("full")
    private String full;
    /**
     * 工作状态
     */
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/enums/WorkNoTypeType.java
@@ -2,7 +2,9 @@
public enum WorkNoTypeType {
    WORK_NO_TYPE(1);
    WORK_NO_IN_TYPE(1),
    WORK_NO_OUT_TYPE(2);
    public int type;
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/mapper/JobMapper.java
@@ -28,6 +28,8 @@
    List<Job> listJobByJobStsAndDay(@Param("jobSts") Integer jobSts, @Param("day") Integer day);
    List<Job> listJobByDay(@Param("day") Integer day);
    List<Job> listJobToLog(@Param("jobSts") Integer jobSts, @Param("day") Integer day);
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;
@@ -30,30 +29,25 @@
    private CtuServiceProperties properties;
    //@Scheduled(cron = "0 0 2 * * ?")
    @Scheduled(cron = "*/5 * * * * ?")
    //@Scheduled(cron = "*/5 * * * * ?")
    @Scheduled(cron = "0 0 1 * * ?")
    public void autoToLog() {
        List<Job> jobs = jobMapper.listJobByJobStsAndDay(ConveyorStateType.CLEARSIGNAL.getStatus(), 1);
        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;
            }
        jobs = jobMapper.listJobToLog(ConveyorStateType.OUTBOUND.getStatus(), 1);
        for (Job job : jobs) {
            jobService.saveJobLog(job);
        }
        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);
            }
    }
    @Scheduled(cron = "0 0 2 * * ?")
    public void delToLog() {
        List<Job> jobByDay = jobMapper.listJobByDay(15);
        for (Job job : jobByDay) {
            jobService.saveJobLog(job);
        }
    }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/service/CtuMainService.java
@@ -25,4 +25,12 @@
     */
    boolean sendTask(OpenBusSubmitParam openBusSubmitParam);
    /**
     * 检查任务
     *
     * @param seqNum
     * @return
     */
    Boolean checkComplete(String seqNum);
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/service/impl/CtuMainServiceImpl.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zy.acs.common.utils.News;
import com.zy.acs.conveyor.common.utils.HttpHandler;
import com.zy.acs.conveyor.controller.requestParam.StationRequestParam;
import com.zy.acs.conveyor.controller.vo.OpenBusSubmitParam;
@@ -36,6 +37,9 @@
    @Value("${ctu.station}")
    private String station;
    @Value("${ctu.checkTakeComplete}")
    private String checkTakeComplete;
    @Value("${ctu.sendTask}")
    private String sendTask;
@@ -45,7 +49,7 @@
    private Integer codeValue = 200;
    private Integer timeout = 1200;
    private Integer timeout = 10;
    @Transactional
@@ -108,16 +112,48 @@
                log.info("未返回站点状态:{}", staNo);
            } else {
                log.error("调用下发任务接口报错,响应码:{},响应内容:{}", jsonObject.getInteger(code), response);
                throw new CoolException("调用下发任务接口报错,响应码:" + jsonObject.getInteger(code));
                //throw new CoolException("调用下发任务接口报错,响应码:" + jsonObject.getInteger(code));
            }
        } catch (CoolException e) {
            log.error("调用站点状态接口异常", e);
            throw e;
            //throw e;
        } catch (Exception e) {
            log.error("检查站点状态失败,站点编号:{}", staNo, e);
            //log.error("检查站点状态失败,站点编号:{}", staNo, e);
        }
        return null;
    }
    /**
     * 检查站点状态
     *
     * @param seqNum 任务号
     * @return 站点是否可通行
     */
    public Boolean checkComplete(String seqNum) {
        StationRequestParam stationRequestParam = new StationRequestParam();
        stationRequestParam.setSeqNum(seqNum);
        String response = "";
        try {
            response = new HttpHandler.Builder()
                    .setUri(ctuUrl)
                    .setPath(checkTakeComplete)
                    .setTimeout(timeout, TimeUnit.SECONDS)
                    .setJson(JSON.toJSONString(stationRequestParam))
                    .build()
                    .doPost();
            News.info("RCS返回数据:{}", response);
            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject.getInteger(code).equals(codeValue)) {
                if (jsonObject.getBoolean(dataCode)) {
                    return true;
                }
            } else {
                log.error("调用下发任务接口报错,参数:{},响应内容:{}", seqNum, response);
                //throw new CoolException("调用下发任务接口报错,响应码:" + jsonObject.getInteger(code));
            }
        } catch (Exception e) {
            log.error("检查站点状态失败,任务编号:{},{}", seqNum, e.getMessage());
        }
        return false;
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/service/impl/JobServiceImpl.java
@@ -6,11 +6,14 @@
import com.zy.acs.conveyor.mapper.JobLogMapper;
import com.zy.acs.conveyor.mapper.JobMapper;
import com.zy.acs.conveyor.service.JobService;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
@Service
@@ -55,6 +58,9 @@
    public void saveJobLog(Job job) {
        JobLog jobLog = new JobLog();
        BeanUtils.copyProperties(job, jobLog);
        if (Cools.isEmpty(jobLog.getMemo())) {
            jobLog.setMemo(DateUtils.convert(new Date()));
        }
        jobLogMapper.insert(jobLog);
        baseMapper.deleteById(job.getId());
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/service/impl/WmsMainServiceImpl.java
@@ -58,7 +58,7 @@
                    .setJson(JSON.toJSONString(applyInDto))
                    .build()
                    .doPost();
            log.info("WMS返回数据:{}", response);
            log.info("请求数据:{},WMS返回数据:{}", applyInDto,response);
            JSONObject jsonObject = JSON.parseObject(response);
            if (jsonObject.get(code) != null && jsonObject.getInteger(code).equals(codeValue)) {
                return JSONObject.parseObject(jsonObject.getString(dataCode), ApplyInRepsonseDto.class);
zy-asc-conveyor/src/main/resources/application.yml
@@ -1,5 +1,5 @@
server:
  port: 9090
  port: 8877
  servlet:
    context-path: /cv
@@ -30,38 +30,35 @@
    path: /stock/out/cv/logs
wms:
  url: 10.10.10.220:8081
  url: 127.0.0.1:8082
  apply: /rsf-open-api/rcs/api/open/location/allocate
ctu:
  url: 10.10.10.200:8088
  url: 127.0.0.1:8088
  station: /api/open/station/convey
  checkTakeComplete: /api/open/station/checkTakeComplete
  sendTask: /api/open/bus/submit
  service:
    initial-delay: 0
    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
@@ -78,13 +75,16 @@
swagger:
  enable: false
#写入plc次数,可防止无法写入
plc-write:
  retry: 1
# 下位机配置
cv-slave:
  # 输送线1
  devp[0]:
    id: 1
    ip: 10.10.10.191
    ip: 10.10.10.100
    port: 102
    rack: 0
    slot: 0
@@ -102,24 +102,27 @@
      - 1011
      - 1012
      - 1013
    staNosError:
      - 1010
    barcodeArr:
      - 1010
    weightArr:
      - 1010
    # 站点异常模块是否开启
    staNosError: true
    # 扫码模块是否开启
    barcode: true
    # 称重模块是否开启
    weight: true
    # 取站点交互信号
    # ctu放货站点
    releaseSta[0]:
    putSta[0]:
      # 本站点
      staNo: 1001
      # 目标站点
      targetSta: 1007
    # ctu入库站点
    inSta[0]:
      # 源站点
      sourceStaNo: 1007
      # 本站点
      staNo: 1010
      # 目标站点
      targetSta: 1012
      targetSta: 1013
    # ctu取货站点
    takeSta[0]:
      # 本站点
@@ -127,3 +130,4 @@