1
zhang
19 小时以前 6e7005a9c8f0e9c21f2d3a4d77a779381e859ac3
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 * PlcConstant.STATION_STATUS_LENGTH);
        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 * PlcConstant.STATION_STATUS_LENGTH));
            staProtocol.setStaNo((int) ByteUtils.getShort(stationStatus, StationStatusField.FINAL_TARGET.getOffset() + i * PlcConstant.STATION_STATUS_LENGTH));
            boolean[] status = ByteUtils.getBooleans(stationStatus, StationStatusField.STATUS_WORD.getOffset() + i * PlcConstant.STATION_STATUS_LENGTH, 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);
            }
        }
        byte[] deviceField = s7PLC.readByte(DeviceField.BARCODE.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + DeviceField.BARCODE.getOffset(), DeviceField.BARCODE.getOffset() + DeviceField.BARCODE.getByteLength() * slave.getBarcodeSize());
        for (int i = 0; i < slave.getBarcodeSize(); i++) {
            String barcode = ByteUtils.getString(deviceField, i * DeviceField.BARCODE.getByteLength(), DeviceField.BARCODE.getByteLength());
            BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, 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 * PlcConstant.TASK_LENGTH), staProtocol.getWorkNo());    // 工作号
        Thread.sleep(100);
        s7PLC.writeInt16(TaskField.DEST_STATION.getAddressPattern() + PlcConstant.ADDRESS_CONCATENATION + (index * PlcConstant.TASK_LENGTH + 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();
//    }
//
//
//}