1
zhang
1 天以前 b78572fb09a2c63398e8d87bd19d5d3f92f5aa58
1
11个文件已删除
8个文件已添加
1 文件已重命名
19个文件已修改
2096 ■■■■ 已修改文件
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/CtuController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/SiteController.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/WmsController.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/DevpThread.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/ServerBootstrap.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/Slave.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/ThreadHandler.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/cache/MessageQueue.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/cache/OutputQueue.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/cache/SlaveConnection.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/DeviceField.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/PlcAlarmDefinition.java 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/PlcConstant.java 1 ●●●● 补丁 | 查看 | 原始文档 | 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/constant/StationStatusField.java 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/SlaveType.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/TaskType.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/listen/DevpPlcDataSubscriber.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/listen/DevpTaskDataSubscriber.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/model/StaProtocol.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/model/Task.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/AppleLocOperationHandler.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/ClearSingleOperationHandler.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/FakeUserOperationHandler.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/OutOperationHandler.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/SendTaskOperationHandler.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/DevpSlave.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/OutputQueue.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/Slave.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/SlaveProperties.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/service/DevpS7Service.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/service/Snap7Service.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/service/StationService.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/BarcodeThread.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/S7DevpThread.java 364 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/SiemensDevpThread.java 403 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/service/impl/DevpServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/utils/Utils.java 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/resources/application.yml 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/CtuController.java
@@ -3,11 +3,9 @@
import com.zy.acs.conveyor.common.web.BaseController;
import com.zy.acs.conveyor.controller.requestParam.StationRequestParam;
import com.zy.acs.conveyor.controller.responseParam.StationResponseParam;
import com.zy.acs.conveyor.core.DevpThread;
import com.zy.acs.conveyor.core.cache.SlaveConnection;
import com.zy.acs.conveyor.core.enums.SlaveType;
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
import com.zy.acs.conveyor.core.model.StaProtocol;
import com.zy.acs.conveyor.core.properties.SlaveProperties;
import com.zy.acs.conveyor.core.service.StationService;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.R;
import lombok.extern.slf4j.Slf4j;
@@ -32,6 +30,11 @@
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private StationService stationService;
    /**
     * 站点查询
     */
@@ -40,9 +43,8 @@
    public R query(@RequestBody StationRequestParam param) {
        log.info("站点查询:{}", param);
        List<String> staNos = param.getStaNos();
        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, param.getDevpId());
        Map<Integer, StaProtocol> station = stationService.getStationMap(param.getDevpId());
        List<StationResponseParam> list = new ArrayList<>();
        Map<Integer, StaProtocol> station = devpThread.getStation();
        if (Cools.isEmpty(staNos)) {
            for (Map.Entry<Integer, StaProtocol> entry : station.entrySet()) {
                staNos.add(entry.getKey() + "");
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/SiteController.java
@@ -1,17 +1,14 @@
package com.zy.acs.conveyor.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.conveyor.controller.vo.SiteTableVo;
import com.zy.acs.conveyor.core.DevpThread;
import com.zy.acs.conveyor.core.cache.MessageQueue;
import com.zy.acs.conveyor.core.cache.OutputQueue;
import com.zy.acs.conveyor.core.cache.SlaveConnection;
import com.zy.acs.conveyor.core.enums.SlaveType;
import com.zy.acs.conveyor.core.enums.TaskType;
import com.zy.acs.conveyor.core.model.Task;
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
import com.zy.acs.conveyor.core.constant.RedisConveyorConstant;
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 com.zy.acs.conveyor.core.service.StationService;
import com.zy.acs.conveyor.entity.Devp;
import com.zy.acs.conveyor.service.DevpService;
import com.zy.acs.framework.annotations.ManagerAuth;
@@ -34,8 +31,16 @@
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private DevpService devpService;
    @Autowired
    private StationService stationService;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    @PostMapping("/table/site")
@@ -45,8 +50,8 @@
        // 内存数据
        Map<Integer, StaProtocol> station = new HashMap<>();
        for (DevpSlave devp : slaveProperties.getDevp()) {
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
            station.putAll(devpThread.getStation());
            Map<Integer, StaProtocol> stationMap = stationService.getStationMap(devp.getId());
            station.putAll(stationMap);
        }
        // 持久数据
        List<Devp> devps = devpService.selectList(new EntityWrapper<Devp>().orderBy("dev_no"));
@@ -64,7 +69,6 @@
            vo.setLoading(staProtocol.isLoading() ? "Y" : "N");     // 有物
            vo.setInEnable(staProtocol.isInEnable() ? "Y" : "N");   // 可入
            vo.setOutEnable(staProtocol.isOutEnable() ? "Y" : "N"); // 可出
            vo.setPakMk(staProtocol.isPakMk() ? "Y" : "N");       // 入库标记
            vo.setEmptyMk(staProtocol.isEmptyMk() ? "Y" : "N");     // 空板信号
            vo.setStaNo(staProtocol.getStaNo());                // 目标站
//            vo.setLocType1(staProtocol.isHigh() != staProtocol.isLow() && staProtocol.isLow() ? "低" : "高");     //高低库位
@@ -96,8 +100,7 @@
    public R siteDetl(@PathVariable("siteId") Integer siteId) {
        SiteTableVo vo = new SiteTableVo();
        for (DevpSlave devp : slaveProperties.getDevp()) {
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
            Map<Integer, StaProtocol> station = devpThread.getStation();
            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();
@@ -107,7 +110,6 @@
                    vo.setLoading(staProtocol.isLoading() ? "Y" : "N");     // 有物
                    vo.setInEnable(staProtocol.isInEnable() ? "Y" : "N");   // 可入
                    vo.setOutEnable(staProtocol.isOutEnable() ? "Y" : "N"); // 可出
                    vo.setPakMk(staProtocol.isPakMk() ? "Y" : "N");       // 需求1
                    vo.setEmptyMk(staProtocol.isEmptyMk() ? "Y" : "N");     // 空板信号
                    vo.setStaNo(staProtocol.getStaNo());                // 目标站
                    vo.setLocType1(staProtocol.isHigh() != staProtocol.isLow() && staProtocol.isLow() ? "低" : "高");     //高低库位
@@ -125,8 +127,7 @@
                            @RequestParam Integer staNo,
                            @RequestParam String pakMk) {
        for (DevpSlave devp : slaveProperties.getDevp()) {
            DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
            Map<Integer, StaProtocol> station = devpThread.getStation();
            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();
@@ -141,15 +142,9 @@
                    if (staNo != null) {
                        staProtocol.setStaNo(staNo);
                    }
                    if (pakMk != null) {
                        staProtocol.setPakMk(pakMk.equals("Y"));
                    }
                    boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(TaskType.WRITE, staProtocol));
                    if (result) {
                    redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                        return R.ok();
                    } else {
                        return R.error("下发命令失败");
                    }
                }
            }
        }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/controller/WmsController.java
@@ -2,12 +2,9 @@
import com.zy.acs.conveyor.common.web.BaseController;
import com.zy.acs.conveyor.controller.requestParam.StaParam;
import com.zy.acs.conveyor.controller.responseParam.StationResponseParam;
import com.zy.acs.conveyor.controller.vo.PlcErrorTableVo;
import com.zy.acs.conveyor.core.DevpThread;
import com.zy.acs.conveyor.core.cache.SlaveConnection;
import com.zy.acs.conveyor.core.enums.SlaveType;
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
import com.zy.acs.conveyor.core.model.StaProtocol;
import com.zy.acs.conveyor.core.service.StationService;
import com.zy.acs.conveyor.entity.Job;
import com.zy.acs.conveyor.service.JobService;
import com.zy.acs.framework.common.R;
@@ -33,6 +30,9 @@
    @Autowired
    private JobService jobService;
    @Autowired
    private StationService stationService;
    /**
     * 站点查询
     */
@@ -41,9 +41,7 @@
    public R query(@RequestBody StaParam param) {
        log.info("根据站点查询staNo:{}", param);
        String staNo = param.getStaNo();
        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, param.getDevpId());
        List<StationResponseParam> list = new ArrayList<>();
        Map<Integer, StaProtocol> station = devpThread.getStation();
        Map<Integer, StaProtocol> station = stationService.getStationMap(param.getDevpId());
        StaProtocol staProtocol = station.get(Integer.parseInt(staNo));
        Integer workNo = staProtocol.getWorkNo();
        if (workNo != null) {
@@ -64,8 +62,7 @@
    public R getError(@RequestBody StaParam param) {
        log.info("根据站点查询staNo:{}", param);
        String staNo = param.getStaNo();
        DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Devp, param.getDevpId());
        Map<Integer, StaProtocol> station = devpThread.getStation();
        Map<Integer, StaProtocol> station = stationService.getStationMap(param.getDevpId());
        StaProtocol staProtocol = station.get(Integer.parseInt(staNo));
        return R.ok(staPlcErr(staProtocol));
    }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/DevpThread.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/ServerBootstrap.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/Slave.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/ThreadHandler.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/cache/MessageQueue.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/cache/OutputQueue.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/cache/SlaveConnection.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/DeviceField.java
@@ -37,12 +37,9 @@
    /**
     * 根据 DB 块编号和站点偏移生成具体地址
     *
     * @param dbBlock           DB块编号
     * @param stationBaseOffset 站点基址偏移(站点号*站点长度)
     * @return PLC4X 地址字符串,如 "DB100.DBD0"
     */
    public String buildAddress(int dbBlock, int stationBaseOffset) {
        int finalOffset = stationBaseOffset + offset;
        return String.format(addressPattern, dbBlock, finalOffset);
    public String buildAddress() {
        return addressPattern + PlcConstant.ADDRESS_CONCATENATION + offset;
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/PlcAlarmDefinition.java
@@ -4,23 +4,47 @@
 * PLC 报警定义(对应 §2.3)
 */
public enum PlcAlarmDefinition {
    EMERGENCY_STOP("DB25", 1, "急停"),
    LOWER_BREAKER_TRIP("DB25", 2, "低位断路器断开"),
    LOWER_INVERTER_FAULT("DB25", 3, "低位变频器故障"),
    CONVEYOR_TIMEOUT("DB25", 4, "输送运行超时"),
    LIFT_TIMEOUT("DB25", 5, "顶升运行超时"),
    TASK_REQUEST_TIMEOUT("DB25", 6, "申请任务超时"),
    PALLET_PROTRUSION("DB25", 7, "托盘突出报警"),
    TASK_DUPLICATE("DB25", 8, "任务重复报警"),
    PRECONDITION_ERROR("DB25", 9, "入站过程中前置条件异常");
    ALL("DB25", 0, 4, "所有报警"),
    EMERGENCY_STOP("DB25", 1, 4, "急停"),
    LOWER_BREAKER_TRIP("DB25", 2, 4, "低位断路器断开"),
    LOWER_INVERTER_FAULT("DB25", 3, 4, "低位变频器故障"),
    CONVEYOR_TIMEOUT("DB25", 4, 4, "输送运行超时"),
    LIFT_TIMEOUT("DB25", 5, 4, "顶升运行超时"),
    TASK_REQUEST_TIMEOUT("DB25", 6, 4, "申请任务超时"),
    PALLET_PROTRUSION("DB25", 7, 4, "托盘突出报警"),
    TASK_DUPLICATE("DB25", 8, 4, "任务重复报警"),
    PRECONDITION_ERROR("DB25", 9, 4, "入站过程中前置条件异常");
    private final String addressPattern;
    private final int index;          // 报警序号(1-based)
    private final int byteLength;
    private final String description;
    PlcAlarmDefinition(String addressPattern, int index, String description) {
    PlcAlarmDefinition(String addressPattern, int index, int byteLength, String description) {
        this.addressPattern = addressPattern;
        this.index = index;
        this.byteLength = byteLength;
        this.description = description;
    }
    public String buildAddress() {
        return addressPattern + PlcConstant.ADDRESS_CONCATENATION + index;
    }
    public String getAddressPattern() {
        return addressPattern;
    }
    public int getIndex() {
        return index;
    }
    public int getByteLength() {
        return byteLength;
    }
    public String getDescription() {
        return description;
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/PlcConstant.java
@@ -7,5 +7,4 @@
    public static final String ADDRESS_CONCATENATION = ".";
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/RedisConveyorConstant.java
New file
@@ -0,0 +1,6 @@
package com.zy.acs.conveyor.core.constant;
public class RedisConveyorConstant {
    public static final String CONVEYOR_TASK_FLAG = "CONVEYOR_TASK_FLAG";
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/constant/StationStatusField.java
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/SlaveType.java
@@ -2,13 +2,10 @@
public enum SlaveType {
    Crn,
    Devp,
    Barcode,
    Led,
    Scale,
    Car,
    Rgv;
    ;
    public static SlaveType findInstance(String s) {
        for (SlaveType type : SlaveType.values()) {
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/enums/TaskType.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/listen/DevpPlcDataSubscriber.java
New file
@@ -0,0 +1,56 @@
package com.zy.acs.conveyor.core.listen;
import com.zy.acs.conveyor.core.properties.DevpSlave;
import com.zy.acs.conveyor.core.properties.SlaveProperties;
import com.zy.acs.conveyor.core.service.DevpS7Service;
import com.zy.acs.conveyor.core.service.StationService;
import com.zy.acs.conveyor.core.thread.SiemensDevpThread;
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;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 读取plc数据
 */
@Slf4j
@Component
public class DevpPlcDataSubscriber {
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private DevpS7Service devpS7Service;
    @Autowired
    private StationService stationService;
    private static final Map<String, Thread> conContain = new ConcurrentHashMap<>();
    @EventListener(ApplicationReadyEvent.class)
    private void start() {
        for (DevpSlave devp : slaveProperties.getDevp()) {
            Thread thread = new Thread(new SiemensDevpThread(devp, devpS7Service.get(devp.getId()), stationService.getStationMap(devp.getId())));
            conContain.put(devp.getId().toString(), thread);
            thread.start();
        }
    }
    @PreDestroy
    public void shutDown() {
        for (Map.Entry<String, Thread> entry : conContain.entrySet()) {
            if (entry.getValue() != null) entry.getValue().interrupt();
        }
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/listen/DevpTaskDataSubscriber.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 DevpTaskDataSubscriber {
    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_TASK_FLAG);
                    if (null != protocol) {
                        snap7Service.write(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/StaProtocol.java
File was renamed from zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/model/protocol/StaProtocol.java
@@ -1,4 +1,4 @@
package com.zy.acs.conveyor.core.model.protocol;
package com.zy.acs.conveyor.core.model;
import com.zy.acs.conveyor.entity.Devp;
import lombok.Data;
@@ -9,6 +9,8 @@
 */
@Data
public class StaProtocol implements Cloneable {
    private Integer plcId;
    // 站点编号
    private Integer siteId;
@@ -46,8 +48,11 @@
    // 低
    private boolean low;
    // 锁定标记
    private boolean pakMk = true;
    //条码
    private String barcode;
    //重量
    private Double weight;
    // 外形检测 ------------------------------------------------------------------------
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/model/Task.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/AppleLocOperationHandler.java
@@ -1,27 +1,22 @@
package com.zy.acs.conveyor.core.operation.handler;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.conveyor.controller.vo.ApplyInDto;
import com.zy.acs.conveyor.controller.vo.ApplyInRepsonseDto;
import com.zy.acs.conveyor.core.cache.MessageQueue;
import com.zy.acs.conveyor.core.cache.SlaveConnection;
import com.zy.acs.conveyor.core.constant.RedisConveyorConstant;
import com.zy.acs.conveyor.core.enums.ConveyorStateType;
import com.zy.acs.conveyor.core.enums.SlaveType;
import com.zy.acs.conveyor.core.enums.TaskType;
import com.zy.acs.conveyor.core.model.Task;
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
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.thread.BarcodeThread;
import com.zy.acs.conveyor.core.thread.SiemensDevpThread;
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;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.exception.CoolException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -29,6 +24,7 @@
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.Date;
import java.util.Map;
/**
 * 入库
@@ -51,6 +47,13 @@
    private JobService jobService;
    @Autowired
    private StationService stationService;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    @Override
    public ConveyorStateType getType() {
        return ConveyorStateType.APPLYLOC;
@@ -65,9 +68,8 @@
                // 遍历入库口
                for (DevpSlave.Sta inSta : devp.getInSta()) {
                    // 根据输送线plc遍历
                    SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                    StaProtocol staProtocol = devpThread.getStation().get(inSta.getStaNo());
                    BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, devp.getId());
                    Map<Integer, StaProtocol> stationMap = stationService.getStationMap(devp.getId());
                    StaProtocol staProtocol = stationMap.get(inSta.getStaNo());
                    if (staProtocol == null) {
                        continue;
                    } else {
@@ -78,8 +80,8 @@
                        continue;
                    }
                    if (staProtocol.getWorkNo() > 0 && staProtocol.isAutoing()) {
                        String barcode = barcodeThread.getBarcode();
                        if (barcodeThread == null || Cools.isEmpty(barcode)) {
                        String barcode = staProtocol.getBarcode();
                        if (Cools.isEmpty(barcode)) {
                            log.error("站点:{},未扫到码值:{}", staProtocol.getSiteId(), barcode);
                            return;
                        }
@@ -93,13 +95,9 @@
                                    Integer workNo = getWorkNo();
                                    staProtocol.setWorkNo(workNo);
                                    staProtocol.setStaNo(inSta.getTargetSta());
                                    if (MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(TaskType.WRITE, staProtocol))) {
                                        if (!jobService.insert(initJob(locOfWms, barcode, workNo, inSta.getTargetSta() + ""))) {
                                            throw new CoolException("更新输送线任务失败," + " - " + staProtocol.getWorkNo());
                                        }
                                        log.info("入库前进:{},{}", staProtocol.getWorkNo(), inSta.getTargetSta());
                                    } else {
                                        log.info("下发失败:{},{}", staProtocol.getWorkNo(), inSta.getTargetSta());
                                    redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                                    if (jobService.insert(initJob(locOfWms, barcode, workNo, inSta.getTargetSta() + ""))) {
                                        log.info("申请入库成功,条码:{},站点:{}", barcode, inSta.getStaNo());
                                    }
                                } else {
                                    log.info("WMS未返回库位信息,条码:{},站点:{}", barcode, inSta.getStaNo());
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/ClearSingleOperationHandler.java
@@ -1,23 +1,22 @@
package com.zy.acs.conveyor.core.operation.handler;
import com.zy.acs.conveyor.core.cache.MessageQueue;
import com.zy.acs.conveyor.core.cache.SlaveConnection;
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.enums.SlaveType;
import com.zy.acs.conveyor.core.enums.TaskType;
import com.zy.acs.conveyor.core.model.Task;
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
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.thread.SiemensDevpThread;
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;
/**
@@ -35,6 +34,12 @@
    private JobService jobService;
    @Autowired
    private StationService stationService;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    @Override
    public ConveyorStateType getType() {
        return ConveyorStateType.CLEARSIGNAL;
@@ -48,8 +53,8 @@
                // 遍历等待ctu取货站
                for (DevpSlave.Sta takeSta : devp.getTakeSta()) {
                    // 根据输送线plc遍历
                    SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                    StaProtocol staProtocol = devpThread.getStation().get(takeSta.getStaNo());
                    Map<Integer, StaProtocol> stationMap = stationService.getStationMap(devp.getId());
                    StaProtocol staProtocol = stationMap.get(takeSta.getStaNo());
                    if (staProtocol == null) {
                        continue;
                    } else {
@@ -65,12 +70,12 @@
                            //String s = ctuMainService.checkStationStatus(takeSta.getStaNo());
                            staProtocol.setWorkNo(0);
                            staProtocol.setStaNo(0);
                            boolean result = MessageQueue.offer(SlaveType.Devp, 1, new Task(TaskType.WRITE, staProtocol));
                            if (result) {
                            redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                                log.info("" + config.getMark() + "站点清空失败:{},{}", takeSta.getStaNo(), staProtocol.getWorkNo());
                                job.setJobSts(ConveyorStateType.CLEARSIGNAL.getStatus());
                                jobService.updateById(job);
                            }
                        }
                    }
                }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/FakeUserOperationHandler.java
@@ -1,22 +1,21 @@
package com.zy.acs.conveyor.core.operation.handler;
import com.zy.acs.conveyor.core.cache.MessageQueue;
import com.zy.acs.conveyor.core.cache.SlaveConnection;
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.enums.SlaveType;
import com.zy.acs.conveyor.core.enums.TaskType;
import com.zy.acs.conveyor.core.model.Task;
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
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.SlaveProperties;
import com.zy.acs.conveyor.core.thread.SiemensDevpThread;
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;
/**
 * 模拟用户按按钮
@@ -33,6 +32,12 @@
    private JobService jobService;
    @Autowired
    private StationService stationService;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    @Override
    public ConveyorStateType getType() {
        return ConveyorStateType.FAKEUSER;
@@ -43,8 +48,8 @@
        try {
            // 根据输送线plc遍历
            SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1);
            StaProtocol staProtocol = devpThread.getStation().get(1004);
            Map<Integer, StaProtocol> stationMap = stationService.getStationMap(1);
            StaProtocol staProtocol = stationMap.get(1004);
            if (staProtocol == null) {
                return;
            } else {
@@ -54,7 +59,7 @@
            if (!staProtocol.isLoading()) {
                return;
            }
            StaProtocol staProtocol5 = devpThread.getStation().get(1005);
            StaProtocol staProtocol5 = stationMap.get(1005);
            if (staProtocol5.isLoading()) {
                log.info("1005有物,等无物之后才入库");
                return;
@@ -64,13 +69,13 @@
                if (jobByWorkNo != null && jobByWorkNo.getJobSts() == ConveyorStateType.OUTBOUND.getStatus()) {
                    staProtocol.setWorkNo(9992);
                    staProtocol.setStaNo(1005);
                    boolean result = MessageQueue.offer(SlaveType.Devp, 1, new Task(TaskType.WRITE, staProtocol));
                    if (result) {
                    redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                        jobByWorkNo.setJobSts(3);
                        jobByWorkNo.setMemo("模拟按按钮");
                        jobService.updateById(jobByWorkNo);
                        log.info("入库输送线下发:{},{}", staProtocol.getWorkNo(), 1006);
                    }
                }
            }
        } catch (Exception e) {
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/OutOperationHandler.java
@@ -1,17 +1,14 @@
package com.zy.acs.conveyor.core.operation.handler;
import com.zy.acs.conveyor.core.cache.MessageQueue;
import com.zy.acs.conveyor.core.cache.SlaveConnection;
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.enums.SlaveType;
import com.zy.acs.conveyor.core.enums.TaskType;
import com.zy.acs.conveyor.core.model.Task;
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
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.thread.SiemensDevpThread;
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.CtuMainService;
@@ -23,6 +20,8 @@
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.Map;
@Slf4j
@Component
@@ -41,6 +40,11 @@
    @Autowired
    private JobService jobService;
    @Autowired
    private StationService stationService;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    @Override
    public ConveyorStateType getType() {
@@ -56,8 +60,8 @@
                // 遍历出库口
                for (DevpSlave.Sta releaseSta : devp.getReleaseSta()) {
                    // 获取入库站信息
                    SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                    StaProtocol staProtocol = devpThread.getStation().get(releaseSta.getStaNo());
                    Map<Integer, StaProtocol> stationMap = stationService.getStationMap(devp.getId());
                    StaProtocol staProtocol = stationMap.get(releaseSta.getStaNo());
                    if (staProtocol == null) {
                        continue;
                    } else {
@@ -91,12 +95,8 @@
                                if (!jobService.insert(job)) {
                                    throw new CoolException("插入输送线任务失败," + jobBySeqNum + " - " + workNo);
                                }
                                boolean result = MessageQueue.offer(SlaveType.Devp, devp.getId(), new Task(TaskType.WRITE, staProtocol));
                                if (result) {
                                redis.push(RedisConveyorConstant.CONVEYOR_TASK_FLAG, staProtocol);
                                    log.info("输送线下发:{},{}", staProtocol.getWorkNo(), releaseSta.getTargetSta());
                                } else {
                                    log.error("发布命令至输送线队列失败!!! [plc编号:{}]", devp.getId());
                                }
                            }
                        } else {
                            log.info("站点信息不符合入库条件!!!" + " 调用RCS检验未通过,站点:{}", staProtocol.getSiteId());
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/operation/handler/SendTaskOperationHandler.java
@@ -1,17 +1,16 @@
package com.zy.acs.conveyor.core.operation.handler;
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.cache.SlaveConnection;
import com.zy.acs.conveyor.core.enums.ConveyorStateType;
import com.zy.acs.conveyor.core.enums.SlaveType;
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
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.thread.SiemensDevpThread;
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;
@@ -23,6 +22,7 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * 发送任务给RCS
@@ -42,6 +42,14 @@
    @Autowired
    private CtuMainService ctuMainService;
    @Autowired
    private StationService stationService;
    private final RedisSupport redis = RedisSupport.defaultRedisSupport;
    @Override
    public ConveyorStateType getType() {
        return ConveyorStateType.SENDTASK;
@@ -55,8 +63,8 @@
                // 遍历入库口
                for (DevpSlave.Sta inSta : devp.getInSta()) {
                    // 根据输送线plc遍历
                    SiemensDevpThread devpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, devp.getId());
                    StaProtocol staProtocol = devpThread.getStation().get(inSta.getTargetSta());
                    Map<Integer, StaProtocol> stationMap = stationService.getStationMap(devp.getId());
                    StaProtocol staProtocol = stationMap.get(inSta.getTargetSta());
                    if (staProtocol == null) {
                        continue;
                    } else {
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/DevpSlave.java
@@ -1,6 +1,5 @@
package com.zy.acs.conveyor.core.properties;
import com.zy.acs.conveyor.core.Slave;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -19,12 +18,19 @@
    private Integer slot;
    private List<Sta> releaseSta = new ArrayList<>();
    private List<Sta> takeSta = new ArrayList<>();
    private List<Sta> inSta = new ArrayList<>();
    private List<Integer> barcodeArr = new ArrayList<>();
    private List<Integer> staNos = new ArrayList<>();
    private List<Integer> staNosError = new ArrayList<>();
    @Data
    public static class Sta {
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/OutputQueue.java
New file
@@ -0,0 +1,15 @@
package com.zy.acs.conveyor.core.properties;
import java.util.concurrent.ArrayBlockingQueue;
/**
 * Created by vincent on 2020/8/17
 */
public class OutputQueue {
    // 输送线输出日志
    public static ArrayBlockingQueue<String> DEVP = new ArrayBlockingQueue<>(32);
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/Slave.java
New file
@@ -0,0 +1,18 @@
package com.zy.acs.conveyor.core.properties;
import lombok.Data;
/**
 * Created by vincent on 2020/8/4
 */
@Data
public class Slave {
    private Integer id;
    private String ip;
    private Integer port;
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/properties/SlaveProperties.java
@@ -1,6 +1,5 @@
package com.zy.acs.conveyor.core.properties;
import com.zy.acs.conveyor.core.Slave;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@@ -20,15 +19,8 @@
@ConfigurationProperties(prefix = "cv-slave")
public class SlaveProperties {
    private boolean doubleDeep;
    private List<Integer> doubleLocs = new ArrayList<>();
    private int groupCount;
    private List<DevpSlave> devp = new ArrayList<>();
    private List<Slave> barcode = new ArrayList<>();
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/service/DevpS7Service.java
New file
@@ -0,0 +1,78 @@
package com.zy.acs.conveyor.core.service;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.zy.acs.common.utils.News;
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 com.zy.acs.framework.common.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.text.MessageFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Service
public class DevpS7Service {
    @Autowired
    private SlaveProperties slaveProperties;
    private final Map<Integer, SiemensS7Net> DEVP_CACHE = new ConcurrentHashMap<>();
    @PostConstruct
    public void init() {
        News.info("初始化输送线线程...................................................");
        List<DevpSlave> devpSlaves = slaveProperties.getDevp();
        for (DevpSlave devp : devpSlaves) {
            add(devp, connect(devp));
        }
    }
    public void add(DevpSlave devp, SiemensS7Net siemensS7Net) {
        DEVP_CACHE.put(devp.getId(), siemensS7Net);
    }
    public void remove(Integer id) {
        DEVP_CACHE.remove(id);
    }
    public SiemensS7Net get(Integer id) {
        SiemensS7Net siemensS7Net = DEVP_CACHE.get(id);
        if (siemensS7Net != null) {
            return siemensS7Net;
        }
        slaveProperties.getDevp().stream().filter(devp -> devp.getId().equals(id)).findFirst().ifPresent(devp -> {
            add(devp, connect(devp));
        });
        return DEVP_CACHE.get(id);
    }
    private SiemensS7Net connect(DevpSlave devp) {
        SiemensS7Net siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, devp.getIp());
        siemensS7Net.setRack(devp.getRack().byteValue());
        siemensS7Net.setSlot(devp.getSlot().byteValue());
        OperateResult connect = siemensS7Net.ConnectServer();
        if (connect.IsSuccess) {
            News.info("SiemensDevp" + " - 1" + " - 输送线plc连接成功 ===>> [id:{}] [ip:{}] [port:{}]", devp.getId(), devp.getIp(), devp.getPort());
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】输送线plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]",
                    DateUtils.convert(new Date()), devp.getId(), devp.getIp(), devp.getPort(), devp.getRack(), devp.getSlot()));
            News.error("SiemensDevp" + " - 2" + " - 输送线plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", devp.getId(), devp.getIp(), devp.getPort());
        }
        return siemensS7Net;
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/service/Snap7Service.java
New file
@@ -0,0 +1,111 @@
package com.zy.acs.conveyor.core.service;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
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.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.stereotype.Service;
import java.text.MessageFormat;
import java.util.List;
@Slf4j
@Service
public class Snap7Service {
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private DevpS7Service devpS7Service;
    private static final int WRITE_RETRY_MAX = 5;
    private static final int WRITE_RETRY_INTERVAL_MS = 200;
    public void read(StaProtocol staProtocol, SiemensS7Net siemensS7Net) {
    }
    public void write(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;
        }
        int baseOffset = 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
                + (baseOffset + TaskField.DEST_STATION.getOffset());
        // 任务下发重试机制
        int writeCount = 0;
        boolean success = false;
        while (writeCount < WRITE_RETRY_MAX) {
            OperateResult writeResult = siemensS7Net.Write(workNoAddr, staProtocol.getWorkNo().shortValue());
            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);
        }
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/service/StationService.java
New file
@@ -0,0 +1,83 @@
package com.zy.acs.conveyor.core.service;
import com.zy.acs.common.utils.News;
import com.zy.acs.conveyor.core.model.StaProtocol;
import com.zy.acs.conveyor.core.properties.DevpSlave;
import com.zy.acs.conveyor.core.properties.SlaveProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Service
public class StationService {
    @Autowired
    private SlaveProperties slaveProperties;
    private Map<Integer, Map<Integer, StaProtocol>> STATION_CACHE = new ConcurrentHashMap<>();
    @PostConstruct
    public void init() {
        News.info("初始化站点缓存...................................................");
        List<DevpSlave> devpSlaves = slaveProperties.getDevp();
        for (DevpSlave devp : devpSlaves) {
            List<Integer> staNos = devp.getStaNos();
            for (Integer staNo : staNos) {
                STATION_CACHE.computeIfAbsent(devp.getId(), k -> new ConcurrentHashMap<>());
                Map<Integer, StaProtocol> stationMap = STATION_CACHE.get(devp.getId());
                StaProtocol staProtocol = new StaProtocol();
                staProtocol.setPlcId(devp.getId());
                staProtocol.setSiteId(staNo);
                staProtocol.setWorkNo(0);
                stationMap.put(staNo, staProtocol);
            }
        }
    }
    public void remove(Integer plcId) {
        STATION_CACHE.remove(plcId);
    }
    public void remove(Integer plcId, Integer staNo) {
        Map<Integer, StaProtocol> stationMap = STATION_CACHE.get(plcId);
        if (stationMap != null) {
            stationMap.remove(staNo);
        }
    }
    public StaProtocol get(Integer plcId, Integer staNo) {
        Map<Integer, StaProtocol> stationMap = STATION_CACHE.get(plcId);
        if (stationMap != null) {
            return stationMap.get(staNo);
        }
        return null;
    }
    public Map<Integer, StaProtocol> getStationMap(Integer plcId) {
        return STATION_CACHE.get(plcId);
    }
    public Map<Integer, Map<Integer, StaProtocol>> getAllStations(Integer devpId) {
        return STATION_CACHE;
    }
    public void updateStaProtocol(StaProtocol staProtocol) {
        Map<Integer, StaProtocol> stationMap = STATION_CACHE.get(staProtocol.getPlcId());
        if (stationMap != null) {
            stationMap.put(staProtocol.getSiteId(), staProtocol);
        }
    }
}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/BarcodeThread.java
File was deleted
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/S7DevpThread.java
@@ -1,185 +1,179 @@
package com.zy.acs.conveyor.core.thread;
import com.alibaba.fastjson.JSON;
import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
import com.zy.acs.common.utils.ByteUtils;
import com.zy.acs.common.utils.News;
import com.zy.acs.conveyor.core.DevpThread;
import com.zy.acs.conveyor.core.cache.MessageQueue;
import com.zy.acs.conveyor.core.cache.OutputQueue;
import com.zy.acs.conveyor.core.cache.SlaveConnection;
import com.zy.acs.conveyor.core.constant.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.SlaveType;
import com.zy.acs.conveyor.core.enums.TaskType;
import com.zy.acs.conveyor.core.model.Task;
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
import com.zy.acs.conveyor.core.properties.DevpSlave;
import com.zy.acs.conveyor.entity.Devp;
import com.zy.acs.conveyor.service.DevpService;
import com.zy.acs.conveyor.utils.SpringContextUtil;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.DateUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 输送线线程
 * Created by vincent on 2020/8/4
 */
@Data
@Slf4j
public class S7DevpThread implements Runnable, DevpThread {
    private DevpSlave slave;
    private S7PLC s7PLC;
    private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>();
    @Override
    @SuppressWarnings("InfiniteLoopStatement")
    public void run() {
        connect();
        while (true) {
            try {
                TaskType step = TaskType.READ;
                Task task = MessageQueue.poll(SlaveType.Devp, slave.getId());
                if (task != null) {
                    step = task.getStep();
                }
                switch (step) {
                    // 读数据
                    case READ:
                        read();
                        break;
                    // 写数据 ID+目标站
                    case WRITE:
                        write((StaProtocol) task.getData());
                        break;
                    default:
                        break;
                }
                Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    @Override
    public boolean connect() {
        s7PLC = new S7PLC(EPlcType.S1200, slave.getIp());
        s7PLC.connect();
        return true;
    }
    /**
     * 读取状态 ====> 整块plc
     */
    private void read() throws InterruptedException {
        List<Integer> staNos = slave.getStaNos();
        int staNoSize = staNos.size();
        byte[] stationStatus = s7PLC.readByte(StationStatusField.TASK_NUMBER.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + StationStatusField.TASK_NUMBER.getOffset(), StationStatusField.TASK_NUMBER.getOffset() + staNoSize * StationStatusField.ALL.getByteLength());
        for (int i = 0; i < staNoSize; i++) {
            // 站点编号
            Integer siteId = staNos.get(i);
            StaProtocol staProtocol = station.get(siteId);
            if (null == staProtocol) {
                staProtocol = new StaProtocol();
                staProtocol.setSiteId(siteId);
                station.put(siteId, staProtocol);
            }
            staProtocol.setWorkNo((int) ByteUtils.getLong(stationStatus, StationStatusField.TASK_NUMBER.getOffset() + i * StationStatusField.ALL.getByteLength()));
            staProtocol.setStaNo((int) ByteUtils.getShort(stationStatus, StationStatusField.FINAL_TARGET.getOffset() + i * StationStatusField.ALL.getByteLength()));
            boolean[] status = ByteUtils.getBooleans(stationStatus, StationStatusField.STATUS_WORD.getOffset() + i * StationStatusField.ALL.getByteLength(), StationStatusField.STATUS_WORD.getByteLength());
            staProtocol.setAutoing(status[0]);  // 自动
            staProtocol.setLoading(status[1]);  // 有物
            staProtocol.setInEnable(status[2]); // 可入
            staProtocol.setOutEnable(status[3]);// 可出
            staProtocol.setEmptyMk(status[4]);  // 空板信号
            staProtocol.setFullPlt(status[5]);  // 满托盘
            staProtocol.setHigh(status[6]);     // 高库位
            staProtocol.setLow(status[7]);      // 低库位
            if (!staProtocol.isPakMk() && !staProtocol.isLoading()) {
                staProtocol.setPakMk(true);
            }
        }
        List<Integer> barcodeNumber = slave.getBarcodeNumber();
        byte[] deviceField = s7PLC.readByte(DeviceField.BARCODE.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + DeviceField.BARCODE.getOffset(), DeviceField.BARCODE.getOffset() + DeviceField.BARCODE.getByteLength() * barcodeNumber.size());
        for (int i = 0; i < barcodeNumber.size(); i++) {
            String barcode = ByteUtils.getString(deviceField, i * DeviceField.BARCODE.getByteLength(), DeviceField.BARCODE.getByteLength());
            BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, barcodeNumber.get(i));
            if (Cools.isEmpty(barcode)) {
                barcodeThread.clearBarcode();
            } else {
                if (!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) {
                    barcodeThread.setBarcode(barcode);
                    log.info("料箱码:{}", barcode);
                }
            }
        }
        OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功", DateUtils.convert(new Date()), slave.getId()));
        // 根据实时信息更新数据库
        try {
            List<Devp> devps = new ArrayList<>();
            for (Integer siteId : staNos) {
                StaProtocol staProtocol = station.get(siteId);
                devps.add(staProtocol.toSqlModel());
            }
            DevpService devpService = SpringContextUtil.getBean(DevpService.class);
            if (null != devpService) {
                devpService.updateBatchByDevpNo(devps);
            } else {
                throw new Exception("更新数据库数据失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】更新数据库数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            News.error("SiemensDevp" + " - 3" + " - 更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
        }
    }
    /**
     * 写入 ID+目标站 =====> 单站点写入
     */
    private void write(StaProtocol staProtocol) throws InterruptedException {
        if (null == staProtocol) {
            return;
        }
        List<Integer> staNos = slave.getStaNos();
        int index = staNos.indexOf(staProtocol.getSiteId());
        s7PLC.writeInt32(TaskField.TASK_NUMBER.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + (TaskField.DEST_STATION.getOffset() + index * TaskField.ALL.getByteLength()), staProtocol.getWorkNo());    // 工作号
        Thread.sleep(100);
        s7PLC.writeInt16(TaskField.DEST_STATION.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + (index * TaskField.ALL.getByteLength() + TaskField.DEST_STATION.getOffset() + TaskField.DEST_STATION.getAddressPattern()), staProtocol.getStaNo().shortValue());    // 目标站
        OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol)));
        News.error("SiemensDevp" + " - 4" + " - 写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol));
    }
    @Override
    public void close() {
        s7PLC.close();
    }
}
//package com.zy.acs.conveyor.core.thread;
//
//import com.alibaba.fastjson.JSON;
//import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
//import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
//import com.zy.acs.common.utils.ByteUtils;
//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.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.SlaveType;
//import com.zy.acs.conveyor.core.model.StaProtocol;
//import com.zy.acs.conveyor.core.properties.DevpSlave;
//import com.zy.acs.conveyor.entity.Devp;
//import com.zy.acs.conveyor.service.DevpService;
//import com.zy.acs.conveyor.utils.SpringContextUtil;
//import com.zy.acs.framework.common.Cools;
//import com.zy.acs.framework.common.DateUtils;
//import lombok.Data;
//import lombok.extern.slf4j.Slf4j;
//
//import java.text.MessageFormat;
//import java.util.ArrayList;
//import java.util.Date;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.ConcurrentHashMap;
//
/// **
// * 输送线线程
// * Created by vincent on 2020/8/4
// */
//@Data
//@Slf4j
//public class S7DevpThread implements Runnable, DevpThread {
//
//    private DevpSlave slave;
//
//    private S7PLC s7PLC;
//
//    private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>();
//
//
//    @Override
//    @SuppressWarnings("InfiniteLoopStatement")
//    public void run() {
//        connect();
//        while (true) {
//            try {
//                TaskType step = TaskType.READ;
//                Task task = MessageQueue.poll(SlaveType.Devp, slave.getId());
//                if (task != null) {
//                    step = task.getStep();
//                }
//                switch (step) {
//                    // 读数据
//                    case READ:
//                        read();
//                        break;
//                    // 写数据 ID+目标站
//                    case WRITE:
//                        write((StaProtocol) task.getData());
//                        break;
//                    default:
//                        break;
//                }
//                Thread.sleep(100);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//
//        }
//    }
//
//
//    @Override
//    public boolean connect() {
//        s7PLC = new S7PLC(EPlcType.S1200, slave.getIp());
//        s7PLC.connect();
//        return true;
//    }
//
//    /**
//     * 读取状态 ====> 整块plc
//     */
//    private void read() throws InterruptedException {
//        List<Integer> staNos = slave.getStaNos();
//        int staNoSize = staNos.size();
//        byte[] stationStatus = s7PLC.readByte(StationStatusField.TASK_NUMBER.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + StationStatusField.TASK_NUMBER.getOffset(), StationStatusField.TASK_NUMBER.getOffset() + staNoSize * StationStatusField.ALL.getByteLength());
//        for (int i = 0; i < staNoSize; i++) {
//            // 站点编号
//            Integer siteId = staNos.get(i);
//            StaProtocol staProtocol = station.get(siteId);
//            if (null == staProtocol) {
//                staProtocol = new StaProtocol();
//                staProtocol.setSiteId(siteId);
//                station.put(siteId, staProtocol);
//            }
//            staProtocol.setWorkNo((int) ByteUtils.getLong(stationStatus, StationStatusField.TASK_NUMBER.getOffset() + i * StationStatusField.ALL.getByteLength()));
//            staProtocol.setStaNo((int) ByteUtils.getShort(stationStatus, StationStatusField.FINAL_TARGET.getOffset() + i * StationStatusField.ALL.getByteLength()));
//            boolean[] status = ByteUtils.getBooleans(stationStatus, StationStatusField.STATUS_WORD.getOffset() + i * StationStatusField.ALL.getByteLength(), StationStatusField.STATUS_WORD.getByteLength());
//            staProtocol.setAutoing(status[0]);  // 自动
//            staProtocol.setLoading(status[1]);  // 有物
//            staProtocol.setInEnable(status[2]); // 可入
//            staProtocol.setOutEnable(status[3]);// 可出
//            staProtocol.setEmptyMk(status[4]);  // 空板信号
//            staProtocol.setFullPlt(status[5]);  // 满托盘
//            staProtocol.setHigh(status[6]);     // 高库位
//            staProtocol.setLow(status[7]);      // 低库位
//            if (!staProtocol.isPakMk() && !staProtocol.isLoading()) {
//                staProtocol.setPakMk(true);
//            }
//        }
//        List<Integer> barcodeNumber = slave.getBarcodeArr();
//        byte[] deviceField = s7PLC.readByte(DeviceField.BARCODE.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + DeviceField.BARCODE.getOffset(), DeviceField.BARCODE.getOffset() + DeviceField.BARCODE.getByteLength() * barcodeNumber.size());
//        for (int i = 0; i < barcodeNumber.size(); i++) {
//            String barcode = ByteUtils.getString(deviceField, i * DeviceField.BARCODE.getByteLength(), DeviceField.BARCODE.getByteLength());
//            BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, barcodeNumber.get(i));
//            if (Cools.isEmpty(barcode)) {
//                barcodeThread.clearBarcode();
//            } else {
//                if (!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) {
//                    barcodeThread.setBarcode(barcode);
//                    log.info("料箱码:{}", barcode);
//                }
//            }
//        }
//
//
//        // 根据实时信息更新数据库
//        try {
//            List<Devp> devps = new ArrayList<>();
//            for (Integer siteId : staNos) {
//                StaProtocol staProtocol = station.get(siteId);
//                devps.add(staProtocol.toSqlModel());
//            }
//            DevpService devpService = SpringContextUtil.getBean(DevpService.class);
//            if (null != devpService) {
//                devpService.updateBatchByDevpNo(devps);
//            } else {
//                throw new Exception("更新数据库数据失败");
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            News.error("SiemensDevp" + " - 3" + " - 更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
//        }
//
//
//    }
//
//    /**
//     * 写入 ID+目标站 =====> 单站点写入
//     */
//    private void write(StaProtocol staProtocol) throws InterruptedException {
//        if (null == staProtocol) {
//            return;
//        }
//        List<Integer> staNos = slave.getStaNos();
//        int index = staNos.indexOf(staProtocol.getSiteId());
//
//        s7PLC.writeInt32(TaskField.TASK_NUMBER.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + (TaskField.DEST_STATION.getOffset() + index * TaskField.ALL.getByteLength()), staProtocol.getWorkNo());    // 工作号
//        Thread.sleep(100);
//        s7PLC.writeInt16(TaskField.DEST_STATION.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + (index * TaskField.ALL.getByteLength() + TaskField.DEST_STATION.getOffset() + TaskField.DEST_STATION.getAddressPattern()), staProtocol.getStaNo().shortValue());    // 目标站
//
//        OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol)));
//        News.error("SiemensDevp" + " - 4" + " - 写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol));
//    }
//
//
//    @Override
//    public void close() {
//        s7PLC.close();
//    }
//
//
//}
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/core/thread/SiemensDevpThread.java
@@ -1,36 +1,23 @@
package com.zy.acs.conveyor.core.thread;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.Profinet.Siemens.SiemensPLCS;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.alibaba.fastjson.JSON;
import com.zy.acs.common.utils.News;
import com.zy.acs.conveyor.core.DevpThread;
import com.zy.acs.conveyor.core.cache.MessageQueue;
import com.zy.acs.conveyor.core.cache.OutputQueue;
import com.zy.acs.conveyor.core.cache.SlaveConnection;
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.conveyor.core.enums.SlaveType;
import com.zy.acs.conveyor.core.enums.TaskType;
import com.zy.acs.conveyor.core.model.Task;
import com.zy.acs.conveyor.core.model.protocol.StaProtocol;
import com.zy.acs.conveyor.core.model.StaProtocol;
import com.zy.acs.conveyor.core.properties.DevpSlave;
import com.zy.acs.conveyor.entity.Devp;
import com.zy.acs.conveyor.service.DevpService;
import com.zy.acs.conveyor.utils.SpringContextUtil;
import com.zy.acs.framework.common.Cools;
import com.zy.acs.framework.common.DateUtils;
import com.zy.acs.framework.exception.CoolException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 输送线线程
@@ -38,187 +25,212 @@
 */
@Data
@Slf4j
public class SiemensDevpThread implements Runnable, DevpThread {
public class SiemensDevpThread implements Runnable {
    private DevpSlave slave;
    private SiemensS7Net siemensS7Net;
    private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>();
    private Map<Integer, StaProtocol> station;
    private volatile boolean connected = false;
    private static final int WRITE_RETRY_MAX = 5;
    private static final int WRITE_RETRY_INTERVAL_MS = 200;
    private static final int READ_INTERVAL_MS = 100;
    private static final int DB_UPDATE_INTERVAL_MS = 2000; // 数据库更新间隔
    private long lastDbUpdateTime = 0;
    public SiemensDevpThread(DevpSlave slave) {
    public SiemensDevpThread(DevpSlave slave, SiemensS7Net siemensS7Net, Map<Integer, StaProtocol> station) {
        this.slave = slave;
        this.siemensS7Net = siemensS7Net;
        this.station = station;
    }
    @Override
    @SuppressWarnings("InfiniteLoopStatement")
    public void run() {
        connect();
        while (true) {
        while (!Thread.currentThread().isInterrupted()) {
            try {
                TaskType step = TaskType.READ;
                Task task = MessageQueue.poll(SlaveType.Devp, slave.getId());
                if (task != null) {
                    step = task.getStep();
                }
                switch (step) {
                    // 读数据
                    case READ:
                        read();
                Thread.sleep(READ_INTERVAL_MS);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                log.warn("SiemensDevp线程被中断 [id:{}]", slave.getId());
                        break;
                    // 写数据 ID+目标站
                    case WRITE:
                        write((StaProtocol) task.getData());
                        break;
                    default:
                        break;
                }
                Thread.sleep(100);
            } catch (Exception e) {
                e.printStackTrace();
            }
                log.error("SiemensDevp线程运行异常 [id:{}]", slave.getId(), e);
        }
    }
    /**
     * 初始化站点状态
     */
    private void initSite() {
        List<Integer> staNos = slave.getStaNos();
        // 站点编号
        for (Integer siteId : staNos) {
            StaProtocol staProtocol = station.get(siteId);
            if (null == staProtocol) {
                staProtocol = new StaProtocol();
                staProtocol.setSiteId(siteId);
                station.put(siteId, staProtocol);
            }
            staProtocol.setWorkNo(0);    // ID
            staProtocol.setAutoing(false);      // 自动
            staProtocol.setLoading(false);      // 有物
            staProtocol.setInEnable(false);     // 可入
            staProtocol.setOutEnable(false);    // 可出
            staProtocol.setEmptyMk(false);      // 空板信号
            staProtocol.setStaNo(0);     // 目标站
            if (!staProtocol.isPakMk() && !staProtocol.isLoading()) {
                staProtocol.setPakMk(true);
            }
        }
    }
    @Override
    public boolean connect() {
        boolean result = false;
        siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, slave.getIp());
        siemensS7Net.setRack(slave.getRack().byteValue());
        siemensS7Net.setSlot(slave.getSlot().byteValue());
        OperateResult connect = siemensS7Net.ConnectServer();
        if (connect.IsSuccess) {
            result = true;
            //OutputQueue.DEVP.offer(MessageFormat.format("【{0}】输送线plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            News.info("SiemensDevp" + " - 1" + " - 输送线plc连接成功 ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】输送线plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]  [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
            News.error("SiemensDevp" + " - 2" + " - 输送线plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", slave.getId(), slave.getIp(), slave.getPort());
        }
        siemensS7Net.ConnectClose();
        initSite();
        return result;
        log.info("SiemensDevp读线程已退出 [id:{}]", slave.getId());
    }
    /**
     * 读取状态 ====> 整块plc
     */
    private void read() throws InterruptedException {
        if (!connected || siemensS7Net == null) {
            log.warn("PLC未连接,跳过读取 [id:{}]", slave.getId());
            return;
        }
        List<Integer> staNos = slave.getStaNos();
        int staNoSize = staNos.size();
        OperateResultExOne<byte[]> result = siemensS7Net.Read(StationStatusField.ALL.buildAddress(), (short) (staNoSize * StationStatusField.ALL.getByteLength()));
        if (result.IsSuccess) {
        // 读取站点状态
        OperateResultExOne<byte[]> result = siemensS7Net.Read(
                StationStatusField.ALL.buildAddress(),
                (short) (staNoSize * StationStatusField.ALL.getByteLength()));
        if (!result.IsSuccess) {
            log.error("读取站点状态失败 [id:{}] [error:{}]", slave.getId(), result.Message);
            connected = false;
            return;
        }
        byte[] content = result.Content;
            for (int i = 0; i < staNoSize; i++) {
                Integer siteId = staNos.get(i); // 站点编号
                StaProtocol staProtocol = station.get(siteId);
                if (null == staProtocol) {
                    staProtocol = new StaProtocol();
                    staProtocol.setSiteId(siteId);
                    station.put(siteId, staProtocol);
                }
                    staProtocol.setWorkNo((int) siemensS7Net.getByteTransform().TransUInt32(result.Content, i * StationStatusField.ALL.getByteLength()));
                    staProtocol.setStaNo((int) siemensS7Net.getByteTransform().TransInt16(result.Content, i * StationStatusField.ALL.getByteLength() + 4));
                boolean[]   status = siemensS7Net.getByteTransform().TransBool(result.Content, i * StationStatusField.ALL.getByteLength()+6, 2);
                staProtocol.setAutoing(status[0]);  // 自动
                staProtocol.setLoading(status[1]);  // 有物
                staProtocol.setInEnable(status[2]); // 可入
                staProtocol.setOutEnable(status[3]);// 可出
                staProtocol.setEmptyMk(status[4]);  // 空板信号
                staProtocol.setFullPlt(status[5]);  // 满托盘
                staProtocol.setHigh(status[6]);     // 高库位
                staProtocol.setLow(status[7]);      // 低库位
                if (!staProtocol.isPakMk() && !staProtocol.isLoading()) {
                    staProtocol.setPakMk(true);
                }
            }
            StaProtocol staProtocol = station.get(staNos.get(staNoSize));
            parseStationStatus(content, i, staProtocol);
        }
        // 读取条码
        readBarcodes();
        //条码扫描器
        List<Integer> barcodeList = slave.getBarcodeNumber();
        OperateResultExOne<byte[]> result5 = siemensS7Net.Read("DB101.102", (short) (barcodeList.size() * 8));
        if (result5.IsSuccess) {
            for (int i = 0; i < barcodeList.size(); i++) {
                Integer barcodeId = barcodeList.get(i);
                String barcode = siemensS7Net.getByteTransform().TransString(result5.Content, i * 8, 8, "UTF-8");
                BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, barcodeId);
                if (Cools.isEmpty(barcode)) {
                    barcodeThread.clearBarcode();
                } else {
                    if (!Cools.isEmpty(barcodeThread) && !barcodeThread.getBarcode().equals(barcode)) {
                        barcodeThread.setBarcode(barcode);
        // 读取外形检测错误
        readDimensionErrors();
        // 读取PLC故障
        readPlcAlarms(staNos, staNoSize);
        // 定期更新数据库(降低频率)
        updateDatabaseIfNeeded();
    }
    /**
     * 解析单个站点状态
     */
    private void parseStationStatus(byte[] content, int index, StaProtocol staProtocol) {
        int offset = index * StationStatusField.ALL.getByteLength();
        staProtocol.setWorkNo(siemensS7Net.getByteTransform().TransInt32(content, offset));
        staProtocol.setStaNo((int) siemensS7Net.getByteTransform().TransInt16(
                content, offset + StationStatusField.FINAL_TARGET.getOffset()));
        boolean[] status = siemensS7Net.getByteTransform().TransBool(
                content, offset + StationStatusField.STATUS_WORD.getOffset(),
                StationStatusField.STATUS_WORD.getByteLength());
        staProtocol.setAutoing(status[0]);
        staProtocol.setLoading(status[1]);
        staProtocol.setInEnable(status[2]);
        staProtocol.setOutEnable(status[3]);
        staProtocol.setEmptyMk(status[4]);
        staProtocol.setFullPlt(status[5]);
        staProtocol.setHigh(status[6]);
        staProtocol.setLow(status[7]);
    }
    /**
     * 读取条码信息
     */
    private void readBarcodes() {
        List<Integer> barcodeArr = slave.getBarcodeArr();
        if (barcodeArr == null || barcodeArr.isEmpty()) {
            return;
        }
        OperateResultExOne<byte[]> result = siemensS7Net.Read(
                DeviceField.BARCODE.buildAddress(),
                (short) (barcodeArr.size() * DeviceField.BARCODE.getByteLength()));
        if (!result.IsSuccess) {
            log.warn("读取条码失败 [id:{}]", slave.getId());
            return;
        }
        byte[] content = result.Content;
        for (int i = 0; i < barcodeArr.size(); i++) {
            String barcode = siemensS7Net.getByteTransform().TransString(
                    content, i * DeviceField.BARCODE.getByteLength(),
                    DeviceField.BARCODE.getByteLength(), "UTF-8");
            if (!Cools.isEmpty(barcode)) {
                StaProtocol staProtocol = station.get(barcodeArr.get(i));
                staProtocol.setBarcode(barcode);
                        log.info("料箱码:{}", barcode);
                    }
                }
            }
    /**
     * 读取外形检测错误
     */
    private void readDimensionErrors() {
        List<Integer> staNosError = slave.getStaNosError();
        if (staNosError == null || staNosError.isEmpty()) {
            return;
        }
        OperateResultExOne<byte[]> result = siemensS7Net.Read(
                DeviceField.DIMENSION_WORD.buildAddress(),
                (short) (staNosError.size() * DeviceField.DIMENSION_WORD.getByteLength()));
        OperateResultExOne<byte[]> resultError = siemensS7Net.Read("DB103.0", (short) (staNoSize * 2));
        if (resultError.IsSuccess) {
            ArrayList<Integer> staNoError = new ArrayList<Integer>() {{
                add(102);
                add(201);
                add(211);
            }};
            for (int i = 0; i < staNoError.size(); i++) {
                Integer siteId = staNoError.get(i); // 站点编号
        if (!result.IsSuccess) {
            log.warn("读取外形检测错误失败 [id:{}]", slave.getId());
            return;
        }
        byte[] content = result.Content;
        for (int i = 0; i < staNosError.size(); i++) {
            Integer siteId = staNosError.get(i);
                StaProtocol staProtocol = station.get(siteId);
                if (null == staProtocol) {
                    staProtocol = new StaProtocol();
                    staProtocol.setSiteId(siteId);
                    station.put(siteId, staProtocol);
                }
                boolean[] status = siemensS7Net.getByteTransform().TransBool(resultError.Content, i * 2, 1);
                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]);// 扫码失败
            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]);
            }
        }
        //plc故障
        OperateResultExOne<byte[]> resultErr2 = siemensS7Net.Read("DB25.0", (short) (staNoSize * 4));
        if (resultErr2.IsSuccess) {
    /**
     * 读取PLC故障信息
     */
    private void readPlcAlarms(List<Integer> staNos, int staNoSize) {
        OperateResultExOne<byte[]> result = siemensS7Net.Read(
                PlcAlarmDefinition.ALL.buildAddress(),
                (short) (staNoSize * PlcAlarmDefinition.ALL.getByteLength()));
        if (!result.IsSuccess) {
            log.warn("读取PLC故障信息失败 [id:{}]", slave.getId());
            return;
        }
        byte[] content = result.Content;
            for (int i = 0; i < staNoSize; i++) {
                Integer siteId = staNos.get(i); // 站点编号
                boolean[] status = siemensS7Net.getByteTransform().TransBool(resultErr2.Content, i * 4, 2);
            Integer siteId = staNos.get(i);
                StaProtocol staProtocol = station.get(siteId);
                if (staProtocol != null) {
            if (staProtocol == null) {
                continue;
            }
            boolean[] status = siemensS7Net.getByteTransform().TransBool(
                    content, i * PlcAlarmDefinition.ALL.getByteLength(), 1);
                    staProtocol.setBreakerErr(status[0]);
                    staProtocol.setInfraredErr(status[1]);
                    staProtocol.setOutTimeErr(status[2]);
@@ -229,77 +241,42 @@
                    staProtocol.setUpcontactErr(status[7]);
                }
            }
        }
        if (result.IsSuccess) {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功", DateUtils.convert(new Date()), slave.getId()));
            // 根据实时信息更新数据库
            try {
                List<Devp> devps = new ArrayList<>();
                for (Integer siteId : staNos) {
                    StaProtocol staProtocol = station.get(siteId);
                    devps.add(staProtocol.toSqlModel());
                }
                DevpService devpService = SpringContextUtil.getBean(DevpService.class);
                if (null != devpService) {
                    devpService.updateBatchByDevpNo(devps);
                } else {
                    throw new Exception("更新数据库数据失败");
                }
            } catch (Exception e) {
                initSite();
                e.printStackTrace();
                OutputQueue.DEVP.offer(MessageFormat.format("【{0}】更新数据库数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
                News.error("SiemensDevp" + " - 3" + " - 更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot());
            }
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】读取输送线plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), slave.getId(), slave.getIp(), slave.getPort(), slave.getRack(), slave.getSlot()));
        }
    }
    /**
     * 写入 ID+目标站 =====> 单站点写入
     * 按需更新数据库(降低更新频率)
     */
    private void write(StaProtocol staProtocol) throws InterruptedException {
        if (null == staProtocol) {
    private void updateDatabaseIfNeeded() {
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastDbUpdateTime < DB_UPDATE_INTERVAL_MS) {
            return;
        }
        try {
        List<Integer> staNos = slave.getStaNos();
        int index = staNos.indexOf(staProtocol.getSiteId());
            List<Devp> devps = new ArrayList<>(staNos.size());
            for (Integer siteId : staNos) {
                StaProtocol staProtocol = station.get(siteId);
                if (staProtocol != null) {
                    devps.add(staProtocol.toSqlModel());
                }
            }
        OperateResult write = null;
        OperateResult write1 = null;
        //任务下发次数
        int writeCount = 0;
        do {
            write = siemensS7Net.Write("DB100." + index * 4, staProtocol.getWorkNo().shortValue());    // 工作号
            Thread.sleep(200);
            write1 = siemensS7Net.Write("DB100." + (index * 4 + 2), staProtocol.getStaNo().shortValue());    // 目标站
            if (write.IsSuccess && write1.IsSuccess) {
                log.info("写入输送线命令成功。输送线plc编号={},站点数据={},写入次数={}", slave.getId(), JSON.toJSON(staProtocol), writeCount);
                break;
            if (devps.isEmpty()) {
                return;
            }
            DevpService devpService = SpringContextUtil.getBean(DevpService.class);
            if (devpService != null) {
                devpService.updateBatchByDevpNo(devps);
                lastDbUpdateTime = currentTime;
                log.debug("批量更新数据库成功 [id:{}] [count:{}]", slave.getId(), devps.size());
            } else {
                writeCount++;
                log.error("写入输送线命令失败。输送线plc编号={},站点数据={},写入次数={}", slave.getId(), JSON.toJSON(staProtocol), writeCount);
                log.error("DevpService未找到,无法更新数据库 [id:{}]", slave.getId());
            }
        } while (writeCount < 5);
        if (!write.IsSuccess) {
            staProtocol = station.get(staProtocol.getSiteId());
            if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() == 0) {
                staProtocol.setPakMk(true);
        } catch (Exception e) {
            log.error("更新数据库数据失败 [id:{}]", slave.getId(), e);
            News.error("SiemensDevp - 3 - 更新数据库数据失败 ===>> [id:{}]", slave.getId());
            }
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", slave.getId(), JSON.toJSON(staProtocol)));
            News.error("SiemensDevp" + " - 4" + " - 写入输送线站点数据失败。输送线plc编号={},站点数据={}", slave.getId(), JSON.toJSON(staProtocol));
        }
    }
    @Override
    public void close() {
        siemensS7Net.ConnectClose();
    }
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/service/impl/DevpServiceImpl.java
@@ -12,6 +12,7 @@
@Service("basDevpService")
public class DevpServiceImpl extends ServiceImpl<DevpMapper, Devp> implements DevpService {
    @Override
    public void updateBatchByDevpNo(List<Devp> devps) {
        for (Devp devp : devps) {
zy-asc-conveyor/src/main/java/com/zy/acs/conveyor/utils/Utils.java
File was deleted
zy-asc-conveyor/src/main/resources/application.yml
@@ -16,6 +16,15 @@
  mvc:
    static-path-pattern: /**
redis:
  host: localhost
  password: xltys1995
  port: 6379
  max: 30
  min: 10
  timeout: 5000
  index: 6
logging:
  file:
    path: /stock/out/cv/logs
@@ -79,8 +88,6 @@
    port: 102
    rack: 0
    slot: 0
    barcodeNumber:
      - 1
    staNos:
      - 1001
      - 1002
@@ -88,6 +95,16 @@
      - 1004
      - 1005
      - 1006
      - 1007
      - 1008
      - 1009
      - 1010
      - 1011
      - 1012
      - 1013
    staNosError:
      - 1006
    barcodeArr:
      - 1007
    # ctu放货站点
    releaseSta[0]:
@@ -106,9 +123,6 @@
      # 本站点
      staNo: 1007
  # 条码扫描仪1
  barcode[0]:
    id: 1
    ip: 10.10.10.194
    port: 51236