#
Junjie
2024-07-10 2b4747decaee49c1b9bdd568b306118eaf4a41e6
#
1个文件已修改
2个文件已添加
760 ■■■■■ 已修改文件
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/protocol/LiftProtocol.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/JxgtDevpThread.java 352 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/JxgtLiftThread.java 403 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/model/protocol/LiftProtocol.java
@@ -98,6 +98,11 @@
    private Boolean hasCar;
    /**
     * 故障
     */
    private Boolean error;
    /**
     * 故障码
     */
    private String errorCode;
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/JxgtDevpThread.java
New file
@@ -0,0 +1,352 @@
package com.zy.asrs.wcs.rcs.thread.impl;
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.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.asrs.framework.common.Cools;
import com.zy.asrs.framework.common.DateUtils;
import com.zy.asrs.framework.common.SpringUtils;
import com.zy.asrs.wcs.core.entity.BasConveyor;
import com.zy.asrs.wcs.core.entity.BasConveyorSta;
import com.zy.asrs.wcs.core.entity.DeviceBarcode;
import com.zy.asrs.wcs.core.service.BasConveyorService;
import com.zy.asrs.wcs.core.service.BasConveyorStaService;
import com.zy.asrs.wcs.core.service.DeviceBarcodeService;
import com.zy.asrs.wcs.core.utils.RedisUtil;
import com.zy.asrs.wcs.rcs.News;
import com.zy.asrs.wcs.rcs.cache.OutputQueue;
import com.zy.asrs.wcs.rcs.cache.SlaveConnection;
import com.zy.asrs.wcs.rcs.entity.Device;
import com.zy.asrs.wcs.rcs.model.dto.WorkModeTypeDto;
import com.zy.asrs.wcs.rcs.model.enums.SlaveType;
import com.zy.asrs.wcs.rcs.model.enums.WorkModeType;
import com.zy.asrs.wcs.rcs.model.protocol.StaProtocol;
import com.zy.asrs.wcs.rcs.thread.BarcodeThread;
import com.zy.asrs.wcs.rcs.thread.DevpThread;
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;
@Slf4j
public class JxgtDevpThread implements DevpThread, Runnable {
    private Device device;
    private RedisUtil redisUtil;
    private SiemensS7Net siemensS7Net;
    private Map<Integer, StaProtocol> station = new ConcurrentHashMap<>();
    public static ArrayList<BasConveyorSta> stationList = new ArrayList<>();
    /**
     * 条码数量
     */
    private int barcodeSize = 2;
    /**
     * 入出库模式
     * 0:未知
     * 1:入库启动中
     * 2.入库模式
     * 3.出库启动中 (不能生成入库工作档)
     * 4.出库模式
     */
    private Map<Integer, WorkModeTypeDto> workModeTypes = new ConcurrentHashMap<>();
    public JxgtDevpThread(Device device, RedisUtil redisUtil) {
        this.device = device;
        this.redisUtil = redisUtil;
        workModeTypes.put(101, new WorkModeTypeDto(101, WorkModeType.NONE, "DB1001.120"));
    }
    private ArrayList<BasConveyorSta> getStaNo() {
        try {
            if (stationList.isEmpty()) {
                BasConveyorService basConveyorService = SpringUtils.getBean(BasConveyorService.class);
                BasConveyorStaService basConveyorStaService = SpringUtils.getBean(BasConveyorStaService.class);
                BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper<BasConveyor>()
                        .eq(BasConveyor::getDeviceId, device.getId())
                        .eq(BasConveyor::getHostId, device.getHostId()));
                if(basConveyor != null) {
                    List<BasConveyorSta> stations = basConveyorStaService.list(new LambdaQueryWrapper<BasConveyorSta>()
                            .eq(BasConveyorSta::getConveyorId, basConveyor.getId())
                            .eq(BasConveyorSta::getHostId, device.getHostId()));
                    stationList.addAll(stations);
                }
            }
            return stationList;
        } catch (Exception e) {
            return stationList;
        }
    }
    @Override
    @SuppressWarnings("InfiniteLoopStatement")
    public void run() {
        News.info("{}号输送线线程启动", device.getDeviceNo());
        this.connect();
        while (true) {
            try {
                read();
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    private void read() throws InterruptedException {
        updateWorkMode();
        ArrayList<BasConveyorSta> staNos = getStaNo();
        int staNoSize = staNos.size();
        OperateResultExOne<byte[]> result = siemensS7Net.Read("DB100.16", (short) (staNoSize * 18));
        if (result.IsSuccess) {
            for (int i = 0; i < staNoSize; i++) {
                BasConveyorSta siteStation = staNos.get(i);
                int siteId = siteStation.getSiteNo();// 站点编号
                StaProtocol staProtocol = station.get(siteId);
                if (null == staProtocol) {
                    staProtocol = new StaProtocol();
                    staProtocol.setSiteId(siteId);
                    station.put(siteId, staProtocol);
                }
                staProtocol.setAutoing(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 18) == 2);  // 自动
                staProtocol.setLoading(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 18 + 2) == 1);  // 有物
                staProtocol.setInEnable(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 18 + 4) == 1); // 可入
                staProtocol.setOutEnable(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 18 + 6) == 2);// 可出
                //高低信号
                short locType1 = siemensS7Net.getByteTransform().TransInt16(result.Content, i * 18 + 8);
                staProtocol.setLow(locType1 == 1);
//                staProtocol.setWorkMode((int) siemensS7Net.getByteTransform().TransInt16(result.Content, i * 40 + 8));// 工作模式
                staProtocol.setWorkNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 10));     // 工作号
                staProtocol.setStaNo(siemensS7Net.getByteTransform().TransInt16(result.Content, i * 18 + 14));   // 目标站
                if (!staProtocol.isPakMk() && !staProtocol.isLoading()) {
                    staProtocol.setPakMk(true);
                }
            }
        }
        OperateResultExOne<byte[]> resultBarcode = siemensS7Net.Read("DB100.160", (short) 8);
        //条码数据
        String barcode = siemensS7Net.getByteTransform().TransString(resultBarcode.Content,0,8, "UTF-8");// 条码
        BasConveyorStaService basConveyorStaService = SpringUtils.getBean(BasConveyorStaService.class);
        DeviceBarcodeService deviceBarcodeService = SpringUtils.getBean(DeviceBarcodeService.class);
        BasConveyorSta basConveyorSta = basConveyorStaService.getOne(new LambdaQueryWrapper<BasConveyorSta>().eq(BasConveyorSta::getSiteNo, 31002));
        if (basConveyorSta != null) {
            DeviceBarcode deviceBarcode = deviceBarcodeService.getById(basConveyorSta.getBarcodeId());
            if (deviceBarcode != null) {
                BarcodeThread barcodeThread = (BarcodeThread) SlaveConnection.get(SlaveType.Barcode, Integer.parseInt(deviceBarcode.getDeviceId()));
                if (barcodeThread != null) {
                    barcodeThread.setBarcode(barcode);
                }
            }
        }
        if (!Cools.isEmpty(result) && result.IsSuccess) {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), device.getId()));
            // 根据实时信息更新数据库
            try {
                List<BasConveyorSta> stations = new ArrayList<>();
                for (BasConveyorSta sta : getStaNo()) {
                    StaProtocol staProtocol = station.get(sta.getSiteNo());
                    BasConveyorSta sqlModel = staProtocol.toSqlModel(sta);
                    stations.add(sqlModel);
                }
                if (!stations.isEmpty()) {
                    if (null != basConveyorStaService && !basConveyorStaService.updateBatchById(stations)) {
                        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()), device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot()));
                News.error("更新数据库数据失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot());
            }
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】读取输送线plc状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}] [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot()));
//            log.error("读取输送线plc状态信息失败 ===>> [id:{}] [ip:{}] [port:{}] [rack:{}] [slot:{}]", device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot());
        }
    }
    @Override
    public boolean connect() {
        boolean result = false;
        siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, device.getIp());
        siemensS7Net.setRack(device.getRack().byteValue());
        siemensS7Net.setSlot(device.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()), device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot()));
            News.info("输送线plc连接成功 ===>> [id:{}] [ip:{}] [port:{}]", device.getId(), device.getIp(), device.getPort());
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format( "【{0}】输送线plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]  [rack:{4}] [slot:{5}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort(), device.getRack(), device.getSlot()));
            News.error("输送线plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}]", device.getId(), device.getIp(), device.getPort());
        }
        // siemensS7Net.ConnectClose();
        return result;
    }
    @Override
    public void close() {
    }
    @Override
    public boolean writeWorkNo(int siteId, short workNo) {
        int index = findStaNosIndex(siteId);
        OperateResult write = siemensS7Net.Write("DB101." + (index * 8 + 20), workNo);    // 工作号
        if (!write.IsSuccess) {
            StaProtocol staProtocol = station.get(siteId);
            if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) {
                staProtocol.setPakMk(true);
            }
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", device.getId(), JSON.toJSON(staProtocol)));
            log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", device.getId(), JSON.toJSON(staProtocol));
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), device.getId(), JSON.toJSON(workNo)));
            log.info("输送线命令下发 [id:{}] >>>>> 命令下发: {}",  device.getId(), JSON.toJSON(workNo));
            return true;
        }
        return false;
    }
    @Override
    public boolean writeStaNo(int siteId,short staNo) {
        int index = findStaNosIndex(siteId);
        OperateResult write = siemensS7Net.Write("DB1001." + (index * 8 + 20 + 4), staNo);    // 目标站
        if (!write.IsSuccess) {
            StaProtocol staProtocol = station.get(siteId);
            if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) {
                staProtocol.setPakMk(true);
            }
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", device.getId(), JSON.toJSON(staProtocol)));
            log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", device.getId(), JSON.toJSON(staProtocol));
        } else {
            OutputQueue.DEVP.offer(MessageFormat.format("【{0}】 输送线命令下发 [id:{1}] >>>>> {2}", DateUtils.convert(new Date()), device.getId(), JSON.toJSON(staNo)));
            log.info("输送线命令下发 [id:{}] >>>>> 命令下发: {}",  device.getId(), JSON.toJSON(staNo));
            return true;
        }
        return false;
    }
    @Override
    public boolean writeWorkSta(int siteId, short workNo, short staNo) {
        int index = findStaNosIndex(siteId);
        String workNoAddress = "DB1001." + (index * 8 + 20);
        String staNoAddress = "DB1001." + (index * 8 + 20 + 4);
        OperateResult write1 = null;    // 工作号
        OperateResult write2 = null;     // 目标站
        //任务下发次数
        int writeCount = 0;
        do {
            write1 = siemensS7Net.Write(workNoAddress, workNo);    // 工作号
            write2 = siemensS7Net.Write(staNoAddress, staNo);    // 目标站
            if ((write1.IsSuccess && write2.IsSuccess)) {
                OperateResultExOne<byte[]> readResult = siemensS7Net.Read("DB1000." + (index * 40 + 100 + 2), (short) 4);
                if (readResult.IsSuccess) {
                    short workNo2 = siemensS7Net.getByteTransform().TransInt16(readResult.Content, 0);
                    short staNo2 = siemensS7Net.getByteTransform().TransInt16(readResult.Content, 2);
                    if (workNo == workNo2 && staNo == staNo2) {
                        //任务命令写入成功
                        log.info("写入输送线命令后返回成功,并且回读成功。输送线plc编号={},{},{},写入次数={}", siteId, JSON.toJSON(workNo), JSON.toJSON(staNo), writeCount);
                        return true;
                    } else {//返回结果是成功了,但是真实值不相同
                        writeCount++;
                        log.error("写入输送线命令后返回成功,但是读取任务值不一致。输送线plc编号={},{},{},写入次数={}", siteId, JSON.toJSON(workNo), JSON.toJSON(staNo), writeCount);
                    }
                } else {
                    writeCount++;
                    log.error("写入输送线命令后读取失败。输送线plc编号={},站点数据={},{},写入次数={}", siteId, JSON.toJSON(workNo), JSON.toJSON(staNo), writeCount);
                }
            }else {
                writeCount++;
            }
        }while (writeCount < 5) ;
        StaProtocol staProtocol = station.get(siteId);
        if (staProtocol.getWorkNo() == 0 && staProtocol.getStaNo() ==0) {
            staProtocol.setPakMk(true);
        }
        OutputQueue.DEVP.offer(MessageFormat.format("【{0}】写入输送线站点数据失败。输送线plc编号={1},站点数据={2}", device.getId(), JSON.toJSON(staProtocol)));
        log.error("写入输送线站点数据失败。输送线plc编号={},站点数据={}", device.getId(), JSON.toJSON(staProtocol));
        return false;
    }
    @Override
    public Map<Integer, StaProtocol> getStation() {
        return this.station;
    }
    private int findStaNosIndex(int siteId) {
        ArrayList<BasConveyorSta> staNos = getStaNo();
        int index = -1;
        for (int i = 0; i < staNos.size(); i++) {
            BasConveyorSta sta = staNos.get(i);
            if (sta.getSiteNo() == siteId) {
                index = i;
                break;
            }
        }
        return index;
    }
    /**
     * 设置入库标记
     */
    @Override
    public void setPakMk(Integer siteId, boolean pakMk) {
        StaProtocol staProtocol = station.get(siteId);
        if (null != staProtocol) {
            staProtocol.setPakMk(pakMk);
        }
    }
    private void updateWorkMode() {
        for (Map.Entry<Integer, WorkModeTypeDto> entry : workModeTypes.entrySet()) {
            WorkModeTypeDto workModeTypeDto = entry.getValue();
            WorkModeType workModeType = workModeTypeDto.getWorkModeType();
            if (workModeType != WorkModeType.NONE) {
                if (!siemensS7Net.Write(workModeTypeDto.getAddress(), workModeType.id).IsSuccess) {
                    OutputQueue.DEVP.offer(MessageFormat.format("写入输送线{}入出库模式失败。输送线编号={}", workModeTypeDto.getSiteId(), device.getId()));
                    log.error("写入输送线{}入出库模式失败。输送线编号={}", workModeTypeDto.getSiteId(), device.getId());
                }
            }
        }
    }
    @Override
    public boolean switchWorkMode(int siteId, int workMode) {
        WorkModeTypeDto workModeTypeDto = workModeTypes.get(siteId);
        if(workModeTypeDto == null) {
            return false;
        }
        workModeTypeDto.setWorkModeType(WorkModeType.get((short) workMode));
        workModeTypes.put(siteId, workModeTypeDto);
        return true;
    }
}
zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/rcs/thread/impl/JxgtLiftThread.java
New file
@@ -0,0 +1,403 @@
package com.zy.asrs.wcs.rcs.thread.impl;
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.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zy.asrs.framework.common.DateUtils;
import com.zy.asrs.framework.common.SpringUtils;
import com.zy.asrs.framework.exception.CoolException;
import com.zy.asrs.wcs.common.ExecuteSupport;
import com.zy.asrs.wcs.core.domain.dto.BasLiftStaDto;
import com.zy.asrs.wcs.core.entity.BasLift;
import com.zy.asrs.wcs.core.model.command.LiftCommand;
import com.zy.asrs.wcs.core.model.enums.LiftCommandModeType;
import com.zy.asrs.wcs.core.model.enums.MotionCtgType;
import com.zy.asrs.wcs.core.service.BasLiftService;
import com.zy.asrs.wcs.core.utils.RedisUtil;
import com.zy.asrs.wcs.rcs.News;
import com.zy.asrs.wcs.rcs.cache.OutputQueue;
import com.zy.asrs.wcs.rcs.entity.Device;
import com.zy.asrs.wcs.rcs.entity.DeviceDataLog;
import com.zy.asrs.wcs.rcs.model.enums.LiftProtocolStatusType;
import com.zy.asrs.wcs.rcs.model.protocol.LiftProtocol;
import com.zy.asrs.wcs.rcs.service.DeviceDataLogService;
import com.zy.asrs.wcs.rcs.thread.LiftThread;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;
@Slf4j
@SuppressWarnings("all")
public class JxgtLiftThread implements LiftThread {
    private Device device;
    private RedisUtil redisUtil;
    private LiftProtocol liftProtocol;
    private SiemensS7Net siemensS7Net;
    private List<BasLiftStaDto> staList = new ArrayList<>();
    public JxgtLiftThread(Device device, RedisUtil redisUtil) {
        this.device = device;
        this.redisUtil = redisUtil;
    }
    @Override
    public void run() {
        News.info("{}号提升机线程启动", device.getDeviceNo());
        this.connect();
        while (true) {
            try {
                read();
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    private void read() {
        try {
            readStatus();
            //提升机处于运行状态,将标记置为true
            if (liftProtocol.getRun()) {
                liftProtocol.setPakMk(true);
            }
        } catch (Exception e) {
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】读取提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort()));
        }
    }
    private void readStatus() {
        try {
            //获取提升机数据
            OperateResultExOne<byte[]> result1 = siemensS7Net.Read("DB100.0", (short) 20);
            if (result1.IsSuccess) {
                if (null == liftProtocol) {
                    liftProtocol = new LiftProtocol();
                    liftProtocol.setLiftNo(Integer.valueOf(device.getDeviceNo()));
                    liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE);
                    liftProtocol.setDevice(device);
                    InnerLiftExtend innerLiftExtend = new InnerLiftExtend();
                    liftProtocol.setExtend(innerLiftExtend);
                }
                //----------读取提升机状态-----------
                //模式
                liftProtocol.setModel(siemensS7Net.getByteTransform().TransInt16(result1.Content, 0) == 1);
                //忙闲
                liftProtocol.setRun(siemensS7Net.getByteTransform().TransInt16(result1.Content, 2) == 0);
//                //前超限
//                liftProtocol.setFrontOverrun(status1[4]);
//                //后超限
//                liftProtocol.setBackOverrun(status1[5]);
//                //左超限
//                liftProtocol.setLeftOverrun(status1[6]);
//                //右超限
//                liftProtocol.setRightOverrun(status1[7]);
//                //超高
//                liftProtocol.setOverHeight(status2[0]);
//                //超重
//                liftProtocol.setOverWeight(status2[1]);
                //有托盘
                liftProtocol.setHasTray(siemensS7Net.getByteTransform().TransInt16(result1.Content, 4) == 1);
                //有小车
                liftProtocol.setHasCar(siemensS7Net.getByteTransform().TransInt16(result1.Content, 6) == 1);
                //当前楼层
                liftProtocol.setLev((int) siemensS7Net.getByteTransform().TransInt16(result1.Content, 8));
                //工作号
                liftProtocol.setTaskNo(siemensS7Net.getByteTransform().TransInt32(result1.Content, 12));
                //设备故障
                liftProtocol.setError(siemensS7Net.getByteTransform().TransInt16(result1.Content, 16) == 1);
                //故障码
                liftProtocol.setErrorCode(String.valueOf(siemensS7Net.getByteTransform().TransInt16(result1.Content, 18)));
                //************补充扩展字段*************
                InnerLiftExtend liftExtend = (InnerLiftExtend) liftProtocol.getExtend();
                //锁定
                liftExtend.setLock(siemensS7Net.getByteTransform().TransInt16(result1.Content, 10) == 1);
                liftProtocol.setExtend(liftExtend);
            }else {
                OutputQueue.LIFT.offer(MessageFormat.format("【{0}】{1}读取提升机状态信息失败", DateUtils.convert(new Date()), device.getId()));
                throw new CoolException(MessageFormat.format( "读取提升机状态信息失败 ===>> [id:{0}] [ip:{1}] [port:{2}]", device.getId(), device.getIp(), device.getPort()));
            }
            if (System.currentTimeMillis() - liftProtocol.getDeviceDataLog() > 1000 * 5) {
                //采集时间超过5s,保存一次数据记录
                //保存数据记录
                DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class);
                DeviceDataLog deviceDataLog = new DeviceDataLog();
                deviceDataLog.setOriginData(Base64.getEncoder().encodeToString(result1.Content));
                deviceDataLog.setWcsData(JSON.toJSONString(liftProtocol));
                deviceDataLog.setType("lift");
                deviceDataLog.setDeviceNo(String.valueOf(liftProtocol.getLiftNo()));
                deviceDataLog.setCreateTime(new Date());
                deviceDataLog.setHostId(device.getHostId());
                deviceDataLogService.save(deviceDataLog);
                //更新采集时间
                liftProtocol.setDeviceDataLog(System.currentTimeMillis());
            }
            //将提升机状态保存至数据库
            BasLiftService basLiftService = SpringUtils.getBean(BasLiftService.class);
            BasLift basLift = basLiftService.getOne(new LambdaQueryWrapper<BasLift>()
                    .eq(BasLift::getLiftNo, device.getDeviceNo())
                    .eq(BasLift::getHostId, device.getHostId()));
            if (basLift == null) {
                basLift = new BasLift();
                //提升机号
                basLift.setLiftNo(Integer.valueOf(device.getDeviceNo()));
                basLift.setStatus(1);
                basLift.setDeleted(0);
                basLift.setHostId(device.getHostId());
                basLift.setDeviceId(device.getId());
                basLiftService.save(basLift);
            }
            //任务号
            basLift.setTaskNo(liftProtocol.getTaskNo().intValue());
            //修改时间
            basLift.setUpdateTime(new Date());
            //设备状态
            basLift.setProtocol(JSON.toJSONString(liftProtocol));
            if (basLiftService.updateById(basLift)) {
                OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), device.getDeviceNo()));
            }
        } catch (Exception e) {
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】读取提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort()));
        }
    }
    @Override
    public LiftProtocol getStatus() {
        return this.liftProtocol.clone();
    }
    @Override
    public Device getDevice() {
        return this.device;
    }
    @Override
    public boolean move(LiftCommand command) {
        return write(command);
    }
    @Override
    public boolean palletInOut(LiftCommand command) {
        return write(command);
    }
    private boolean write(LiftCommand command) {
        if (null == command) {
            News.error("提升机写入命令为空");
            return false;
        }
        List<Short> shorts = JSON.parseArray(command.getBody(), Short.class);
        short[] array = new short[shorts.size()];//获取命令报文
        for (int i = 0; i < shorts.size(); i++) {
            array[i] = shorts.get(i);
        }
        OperateResult result = siemensS7Net.Write("DB83.0", array);
        if (result != null && result.IsSuccess) {
            liftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
            News.info("提升机命令下发[id:{}] >>>>> {}", device.getId(), JSON.toJSON(command));
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] >>>>> 命令下发: {2}", DateUtils.convert(new Date()), device.getId(), JSON.toJSON(command)));
            return true;
        } else {
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】写入提升机plc数据失败 ===>> [id:{1}] [ip:{2}] [port:{3}],次数:{}", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort()));
            News.error("写入提升机plc数据失败 ===>> [id:{}] [ip:{}] [port:{}]", device.getId(), device.getIp(), device.getPort());
            return false;
        }
    }
    @Override
    public boolean lock(LiftCommand command) {
        return true;
    }
    @Override
    public boolean unlock(LiftCommand command) {
        return true;
    }
    @Override
    public boolean reset(LiftCommand command) {
        return false;
    }
    @Override
    public boolean isIdle() {
        return isIdle(null);
    }
    @Override
    public boolean isIdle(MotionCtgType flag) {
        // 判断提升机是否自动、就绪、空闲
        if (this.liftProtocol.getModel()
                && !this.liftProtocol.getRun()
                && this.liftProtocol.getReady()
                && this.liftProtocol.getPakMk()
                && !this.liftProtocol.getError()
                && this.liftProtocol.getErrorCode().equals("0")
                && (this.liftProtocol.getProtocolStatusType().equals(LiftProtocolStatusType.IDLE)
                || this.liftProtocol.getProtocolStatusType().equals(LiftProtocolStatusType.WAITING))
        ) {
            return true;
        }
        return false;
    }
    @Override
    public boolean isDeviceIdle() {
        return isDeviceIdle(null);
    }
    @Override
    public boolean isDeviceIdle(ExecuteSupport support) {
        if (null != support) {
            Boolean judgement = support.judgement();
            if (judgement != null && !judgement) {
                return true;
            }
        }
        // 判断提升机是否自动、就绪、空闲
        if (this.liftProtocol.getModel()
                && !this.liftProtocol.getRun()
                && this.liftProtocol.getReady()
                && !this.liftProtocol.getError()
                && this.liftProtocol.getErrorCode().equals("0")
        ) {
            return true;
        }
        return false;
    }
    @Override
    public synchronized boolean setProtocolStatus(LiftProtocolStatusType status) {
        this.liftProtocol.setProtocolStatus(status);
        return true;
    }
    @Override
    public synchronized boolean setSyncTaskNo(Integer taskNo) {
        this.liftProtocol.setTaskNo(taskNo);
        return true;
    }
    @Override
    public boolean isLock(ExecuteSupport support) {
        if (support != null) {
            return support.judgement();
        }
        return true;
    }
    @Override
    public List<LiftCommand> getMoveCommand(Integer taskNo, Integer sourceLev, Integer targetLev, LiftCommandModeType mode) {
        /**
         * 任务类型
         * 1=移托盘;升降机将源站台托盘移到目标站台
         * 2=移小车,升降机移到目标层,等待
         */
        short taskMode = 2;
        if (mode.equals(LiftCommandModeType.PALLET_INOUT)) {
            taskMode = 1;
        }
        // 开始任务
        short[] array = new short[4];
        //任务类型
        array[0] = taskMode;
        //源站台编号
        array[1] = sourceLev.shortValue();
        //目标站台编号
        array[2] = targetLev.shortValue();
        //任务号
        array[3] = taskNo.shortValue();
        LiftCommand command = new LiftCommand();
        command.setLiftNo(Integer.valueOf(this.device.getDeviceNo()));
        command.setBody(JSON.toJSONString(array));
        command.setMode(LiftCommandModeType.MOVE.id);
        command.setOriginLev(sourceLev);
        command.setTargetLev(targetLev);
        ArrayList<LiftCommand> list = new ArrayList<>();
        list.add(command);
        return list;
    }
    @Override
    public List<LiftCommand> getMoveWithShuttleCommand(Integer taskNo, Integer sourceLev, Integer targetLev, LiftCommandModeType mode) {
        return getMoveCommand(taskNo, sourceLev, targetLev, mode);
    }
    @Override
    public List<LiftCommand> getPalletInOutCommand(Integer taskNo, Integer sourceLev, Integer targetLev, Integer originSta, Integer targetSta, LiftCommandModeType mode) {
        return getMoveCommand(taskNo, sourceLev, targetLev, mode);
    }
    @Override
    public List<LiftCommand> getLockCommand(Integer taskNo, Boolean lock) {
        return null;
    }
    @Override
    public List<LiftCommand> getShuttleSignalCommand(Integer taskNo, Boolean signal) {
        return null;
    }
    @Override
    public boolean connect() {
        boolean result = false;
        //-------------------------提升机连接方法------------------------//
        siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, device.getIp());
        OperateResult connect = siemensS7Net.ConnectServer();
        if(connect.IsSuccess){
            result = true;
            OutputQueue.LIFT.offer(MessageFormat.format( "【{0}】提升机plc连接成功 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort()));
            log.info("提升机plc连接成功 ===>> [id:{}] [ip:{}] [port:{}] ", device.getId(), device.getIp(), device.getPort());
        } else {
            OutputQueue.LIFT.offer(MessageFormat.format("【{0}】提升机plc连接失败!!! ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getId(), device.getIp(), device.getPort()));
            log.error("提升机plc连接失败!!! ===>> [id:{}] [ip:{}] [port:{}] ", device.getId(), device.getIp(), device.getPort());
        }
        siemensS7Net.ConnectClose();
        //-------------------------提升机连接方法------------------------//
        return result;
    }
    @Override
    public void close() {
        siemensS7Net.ConnectClose();
    }
    /**
     * 扩展字段
     */
    @Data
    private class InnerLiftExtend {
        /**
         * 提升机锁定
         */
        private Boolean lock = false;
    }
}