#
Junjie
1 天以前 f653130e5df936041f7a5ae005e10c91415b64b1
#
2个文件已添加
673 ■■■■■ 已修改文件
src/main/java/com/zy/core/model/LiftStation.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/thread/impl/ZyForkLiftThread.java 650 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/core/model/LiftStation.java
New file
@@ -0,0 +1,23 @@
package com.zy.core.model;
import lombok.Data;
@Data
public class LiftStation {
    // 提升机号
    private Integer liftNo;
    // 提升机站点号
    private Integer staNo;
    // 排
    private Integer row;
    // 列
    private Integer bay;
    // 层
    private Integer lev;
}
src/main/java/com/zy/core/thread/impl/ZyForkLiftThread.java
New file
@@ -0,0 +1,650 @@
package com.zy.core.thread.impl;
import HslCommunication.Core.Types.OperateResult;
import HslCommunication.Core.Types.OperateResultExOne;
import HslCommunication.Profinet.Siemens.SiemensS7Net;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.DateUtils;
import com.core.common.SpringUtils;
import com.zy.asrs.entity.BasLift;
import com.zy.asrs.entity.DeviceConfig;
import com.zy.asrs.entity.DeviceDataLog;
import com.zy.asrs.service.BasLiftService;
import com.zy.asrs.service.DeviceDataLogService;
import com.zy.asrs.utils.Utils;
import com.zy.common.ExecuteSupport;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
import com.zy.core.action.ForkLiftAction;
import com.zy.core.cache.OutputQueue;
import com.zy.core.enums.*;
import com.zy.core.model.*;
import com.zy.core.model.command.ForkLiftCommand;
import com.zy.core.model.protocol.ForkLiftProtocol;
import com.zy.core.model.protocol.ForkLiftStaProtocol;
import com.zy.core.thread.ForkLiftThread;
import com.zy.core.utils.DeviceMsgUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.*;
@Slf4j
@SuppressWarnings("all")
public class ZyForkLiftThread implements ForkLiftThread {
    private DeviceConfig device;
    private ForkLiftProtocol forkLiftProtocol;
    private RedisUtil redisUtil;
    private List<ForkLiftStaProtocol> forkLiftStaProtocols = new ArrayList<>();
    private List<DeviceMsgModel> readResultList = new ArrayList<>();
    private List<DeviceMsgModel> resultList = new ArrayList<>();
    public ZyForkLiftThread(DeviceConfig device, List<LiftStation> stationList, RedisUtil redisUtil) {
        this.device = device;
        this.redisUtil = redisUtil;
        //初始化站点
        for (LiftStation station : stationList) {
            ForkLiftStaProtocol forkLiftStaProtocol = new ForkLiftStaProtocol();
            forkLiftStaProtocol.setStaNo(station.getStaNo());//站点号
            forkLiftStaProtocol.setLev(station.getLev());//站点楼层
            String locNo = Utils.getLocNo(station.getRow(), station.getBay(), station.getLev());
            forkLiftStaProtocol.setLocNo(locNo);//站点库位号
            forkLiftStaProtocol.setLiftNo(station.getLiftNo());//提升机号
            forkLiftStaProtocols.add(forkLiftStaProtocol);
        }
    }
    @Override
    public boolean connect() {
        return true;
    }
    @Override
    public void close() {
    }
    @Override
    public void run() {
        News.info("{}号货叉提升机线程启动", device.getDeviceNo());
        this.connect();
        //设备读取
        Thread readThread = new Thread(() -> {
            while (true) {
                try {
                    listenMessageFromRedis();
                    read();
                    Thread.sleep(100);
                } catch (Exception e) {
                    log.error("ForkliftThread Fail", e);
                }
            }
        });
        readThread.start();
        while (true) {
            try {
                execute();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    private void execute() {
        ForkLiftAction forkLiftAction = null;
        try {
            forkLiftAction = SpringUtils.getBean(ForkLiftAction.class);
        }catch (Exception e){}
        if (forkLiftAction == null) {
            return;
        }
        Object object = redisUtil.get(RedisKeyType.FORK_LIFT_FLAG.key + device.getDeviceNo());
        if (object == null) {
            return;
        }
        Integer taskNo = Integer.valueOf(String.valueOf(object));
        if (taskNo != 0) {
            //存在任务需要执行
            boolean result = forkLiftAction.executeWork(device.getDeviceNo(), taskNo);
        }
    }
    private void read() {
        try {
            readStatus();
            //提升机处于运行状态,将标记置为true
            if (forkLiftProtocol.getProtocolStatusType().equals(ForkLiftProtocolStatusType.PICK_UP)
                    || forkLiftProtocol.getProtocolStatusType().equals(ForkLiftProtocolStatusType.PUT_DOWN)
                    || forkLiftProtocol.getProtocolStatusType().equals(ForkLiftProtocolStatusType.WAITING)) {
                forkLiftProtocol.setPakMk(true);
            }
        } catch (Exception e) {
            OutputQueue.FORKLIFT.offer(MessageFormat.format("【{0}】读取提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getDeviceNo(), device.getIp(), device.getPort()));
        }
    }
    private void readStatus() {
        try {
            //获取提升机数据
            DeviceMsgUtils deviceMsgUtils = null;
            try {
                deviceMsgUtils = SpringUtils.getBean(DeviceMsgUtils.class);
            }catch (Exception e){
            }
            if(deviceMsgUtils == null){
                return;
            }
            ForkLiftCommand readStatusCommand = getReadStatusCommand();
            //指令超过2条,不再下发任务状态请求
            TreeSet<String> deviceCommandMsgListKey = deviceMsgUtils.getDeviceCommandMsgListKey(SlaveType.ForkLift, device.getDeviceNo());
            if (deviceCommandMsgListKey.size() < 2) {
                requestCommand(readStatusCommand);//请求状态
            }
            if (this.readResultList.isEmpty()) {
                return;
            }
            DeviceMsgModel deviceMsgModel = this.readResultList.get(0);
            this.readResultList.remove(0);
            JSONObject deviceMsg = JSON.parseObject(JSON.toJSONString(deviceMsgModel.getDeviceMsg()));
            if (!deviceMsg.getString("result").equals("success")) {
                return;
            }
            JSONObject data = deviceMsg.getJSONObject("deviceStatus");
            if (null == forkLiftProtocol) {
                forkLiftProtocol = new ForkLiftProtocol();
                forkLiftProtocol.setLiftNo(device.getDeviceNo());
                forkLiftProtocol.setProtocolStatus(ForkLiftProtocolStatusType.NONE);
                InnerForkLiftExtend innerForkLiftExtend = new InnerForkLiftExtend();
            }
            //----------读取提升机状态-----------
            //模式
            forkLiftProtocol.setModel(data.getInteger("model"));
            //PLC任务号
            forkLiftProtocol.setWrkNo(data.getInteger("wrkNo"));
            //任务状态
            forkLiftProtocol.setProtocolStatus(data.getInteger("protocolStatus"));
            //任务模式
            forkLiftProtocol.setTaskMode(data.getInteger("taskMode"));
            //取货数据
            forkLiftProtocol.setPick(data.getInteger("pick"));
            //放货数据
            forkLiftProtocol.setPut(data.getInteger("put"));
            //出入库模式
            forkLiftProtocol.setIOMode(data.getInteger("iOMode"));
            //故障码
            forkLiftProtocol.setErrorCode(data.getInteger("errorCode"));
            //当前层
            forkLiftProtocol.setLev(data.getInteger("lev"));
            //************补充扩展字段*************
            InnerForkLiftExtend forkLiftExtend = (InnerForkLiftExtend) forkLiftProtocol.getExtend();
            forkLiftProtocol.setExtend(forkLiftExtend);
            JSONArray trayList = data.getJSONArray("trayList");
            for (int i = 0; i < trayList.size(); i++) {
                int hasTray = (int) trayList.get(i);
                ForkLiftStaProtocol forkLiftStaProtocol = forkLiftStaProtocols.get(i);
                forkLiftStaProtocol.setHasTray(hasTray == 1);
            }
            JSONArray carList = data.getJSONArray("carList");
            for (int i = 0; i < carList.size(); i++) {
                int hasCar = (int) carList.get(i);
                ForkLiftStaProtocol forkLiftStaProtocol = forkLiftStaProtocols.get(i);
                forkLiftStaProtocol.setHasCar(hasCar == 1);
            }
            if (System.currentTimeMillis() - forkLiftProtocol.getDeviceDataLog() > 1000 * 5) {
                //采集时间超过5s,保存一次数据记录
                //保存数据记录
                DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class);
                DeviceDataLog deviceDataLog = new DeviceDataLog();
                deviceDataLog.setOriginData(JSON.toJSONString(data));
                deviceDataLog.setWcsData(JSON.toJSONString(forkLiftProtocol));
                deviceDataLog.setType("forkLift");
                deviceDataLog.setDeviceNo(forkLiftProtocol.getLiftNo());
                deviceDataLog.setCreateTime(new Date());
                deviceDataLogService.insert(deviceDataLog);
                //更新采集时间
                forkLiftProtocol.setDeviceDataLog(System.currentTimeMillis());
            }
            //将提升机状态保存至数据库
            BasLiftService basLiftService = SpringUtils.getBean(BasLiftService.class);
            BasLift basLift = basLiftService.selectOne(new EntityWrapper<BasLift>()
                    .eq("lift_no", device.getDeviceNo()));
            if (basLift == null) {
                basLift = new BasLift();
                //提升机号
                basLift.setLiftNo(forkLiftProtocol.getLiftNo());
                basLift.setStatus(1);
                basLiftService.insert(basLift);
            }
            //任务号
            basLift.setWrkNo(forkLiftProtocol.getTaskNo());
            //修改时间
            basLift.setUpdateTime(new Date());
            //设备状态
            basLift.setDeviceStatus(JSON.toJSONString(forkLiftProtocol));
            if (basLiftService.updateById(basLift)) {
                OutputQueue.FORKLIFT.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), forkLiftProtocol.getLiftNo()));
            }
        } catch (Exception e) {
            e.printStackTrace();
            OutputQueue.FORKLIFT.offer(MessageFormat.format("【{0}】读取货叉提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getDeviceNo(), device.getIp(), device.getPort()));
        }
    }
    @Override
    public ForkLiftProtocol getStatus(boolean clone) {
        if (this.forkLiftProtocol == null) {
            return null;
        }
        return clone ? this.forkLiftProtocol.clone() : this.forkLiftProtocol;
    }
    @Override
    public List<ForkLiftStaProtocol> getForkLiftStaProtocols() {
        return this.forkLiftStaProtocols;
    }
    @Override
    public ForkLiftProtocol getStatus() {
        return getStatus(true);
    }
    @Override
    public CommandResponse pickAndPut(ForkLiftCommand command) {
        CommandResponse response = new CommandResponse(false);
        try {
            //发出请求
            String resultKey = requestCommand(command);
            //查询请求结果
            JSONObject result = queryCommandStatus(resultKey);
            if (result == null) {
                return response;//请求失败
            }
            if(!result.getString("result").equals("success")) {
                return response;//请求失败
            }
            this.forkLiftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
            response.setMessage(JSON.toJSONString(result));
            response.setResult(true);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            response.setMessage(e.getMessage());
            return response;
        }
    }
    @Override
    public CommandResponse shuttleSwitch(ForkLiftCommand command) {
        CommandResponse response = new CommandResponse(false);
        try {
            //发出请求
            String resultKey = requestCommand(command);
            //查询请求结果
            JSONObject result = queryCommandStatus(resultKey);
            if (result == null) {
                return response;//请求失败
            }
            if(!result.getString("result").equals("success")) {
                return response;//请求失败
            }
            this.forkLiftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
            response.setMessage(JSON.toJSONString(result));
            response.setResult(true);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            response.setMessage(e.getMessage());
            return response;
        }
    }
    @Override
    public CommandResponse move(ForkLiftCommand command) {
        CommandResponse response = new CommandResponse(false);
        try {
            //发出请求
            String resultKey = requestCommand(command);
            //查询请求结果
            JSONObject result = queryCommandStatus(resultKey);
            if (result == null) {
                return response;//请求失败
            }
            if(!result.getString("result").equals("success")) {
                return response;//请求失败
            }
            this.forkLiftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
            response.setMessage(JSON.toJSONString(result));
            response.setResult(true);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            response.setMessage(e.getMessage());
            return response;
        }
    }
    @Override
    public CommandResponse switchIOMode(ForkLiftCommand command) {
        CommandResponse response = new CommandResponse(false);
        try {
            //发出请求
            String resultKey = requestCommand(command);
            //查询请求结果
            JSONObject result = queryCommandStatus(resultKey);
            if (result == null) {
                return response;//请求失败
            }
            if(!result.getString("result").equals("success")) {
                return response;//请求失败
            }
            this.forkLiftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
            response.setMessage(JSON.toJSONString(result));
            response.setResult(true);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            response.setMessage(e.getMessage());
            return response;
        }
    }
    @Override
    public CommandResponse reset() {
        CommandResponse response = new CommandResponse(false);
        try {
            ForkLiftCommand resetCommand = getResetCommand(9999);
            //发出请求
            String resultKey = requestCommand(resetCommand);
            //查询请求结果
            JSONObject result = queryCommandStatus(resultKey);
            if (result == null) {
                return response;//请求失败
            }
            if(!result.getString("result").equals("success")) {
                return response;//请求失败
            }
            this.forkLiftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间
            response.setMessage(JSON.toJSONString(result));
            response.setResult(true);
            return response;
        } catch (Exception e) {
            e.printStackTrace();
            response.setMessage(e.getMessage());
            return response;
        }
    }
    @Override
    public boolean isIdle() {
        if (this.forkLiftProtocol.getTaskNo() == null
                || this.forkLiftProtocol.getProtocolStatus() == null
                || this.forkLiftProtocol.getModel() == null
                || this.forkLiftProtocol.getErrorCode() == null
        ) {
            return false;
        }
        boolean res = this.forkLiftProtocol.getProtocolStatus() == ForkLiftProtocolStatusType.IDLE.id
                && this.forkLiftProtocol.getWrkNo() == 0
                && this.forkLiftProtocol.getTaskNo() == 0
                && this.forkLiftProtocol.getModel() == 2
                && this.forkLiftProtocol.getErrorCode() == 0
                ;
        return res;
    }
    @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.forkLiftProtocol.getTaskNo() == null
                || this.forkLiftProtocol.getProtocolStatus() == null
                || this.forkLiftProtocol.getModel() == null
                || this.forkLiftProtocol.getErrorCode() == null
        ) {
            return false;
        }
        boolean res = this.forkLiftProtocol.getProtocolStatus() == ForkLiftProtocolStatusType.IDLE.id
                && this.forkLiftProtocol.getWrkNo() == 0
                && this.forkLiftProtocol.getModel() == 2
                && this.forkLiftProtocol.getErrorCode() == 0
                ;
        return res;
    }
    @Override
    public boolean setProtocolStatus(ForkLiftProtocolStatusType status) {
        return false;
    }
    @Override
    public boolean setSyncTaskNo(Integer taskNo) {
        this.forkLiftProtocol.setSyncTaskNo(taskNo);
        return true;
    }
    @Override
    public int generateDeviceTaskNo(int taskNo, ForkLiftTaskModeType type) {
        return taskNo;
    }
    @Override
    public ForkLiftCommand getPickAndPutCommand(Integer taskNo, Integer pick, Integer put) {
        Integer realPick = pick % 1000;
        Integer realPut = put % 1000;
        ForkLiftCommand command = new ForkLiftCommand();
        command.setLiftNo(device.getDeviceNo());
        command.setTaskNo(taskNo);
        command.setMode(ForkLiftTaskModeType.PICK_PUT.id);
        command.setPick(realPick);
        command.setPut(realPut);
        command.setConfirm(1);
        return command;
    }
    @Override
    public ForkLiftCommand getShuttleSwitchCommand(Integer taskNo, Integer pick, Integer put) {
        Integer realPick = pick % 1000;
        Integer realPut = put % 1000;
        ForkLiftCommand command = new ForkLiftCommand();
        command.setLiftNo(device.getDeviceNo());
        command.setTaskNo(taskNo);
        command.setMode(ForkLiftTaskModeType.SHUTTLE_SWITCH.id);
        command.setPick(realPick);
        command.setPut(realPut);
        command.setConfirm(1);
        return command;
    }
    @Override
    public ForkLiftCommand getMoveCommand(Integer taskNo, Integer pick, Integer put) {
        Integer realPick = pick % 1000;
        Integer realPut = put % 1000;
        ForkLiftCommand command = new ForkLiftCommand();
        command.setLiftNo(device.getDeviceNo());
        command.setTaskNo(taskNo);
        command.setMode(ForkLiftTaskModeType.MOVE.id);
        command.setPick(realPick);
        command.setPut(realPut);
        command.setConfirm(1);
        return command;
    }
    @Override
    public ForkLiftCommand getSwitchIOCommand(Integer taskNo, ForkLiftIoModeType mode) {
        ForkLiftCommand command = new ForkLiftCommand();
        command.setLiftNo(device.getDeviceNo());
        if (mode.equals(ForkLiftIoModeType.IN)) {
            command.setMode(ForkLiftTaskModeType.SWITCH_IN.id);
        } else {
            command.setMode(ForkLiftTaskModeType.SWITCH_OUt.id);
        }
        return command;
    }
    @Override
    public ForkLiftCommand getResetCommand(Integer taskNo) {
        ForkLiftCommand command = new ForkLiftCommand();
        command.setLiftNo(device.getDeviceNo());
        command.setMode(ForkLiftTaskModeType.RESET.id);
        return command;
    }
    //获取读状态信息命令
    private ForkLiftCommand getReadStatusCommand() {
        ForkLiftCommand command = new ForkLiftCommand();
        command.setLiftNo(device.getDeviceNo());
        command.setMode(ForkLiftTaskModeType.READ_STATUS.id);
        return command;
    }
    //发出请求
    private String requestCommand(ForkLiftCommand command) throws IOException {
        try {
            DeviceMsgUtils deviceMsgUtils = SpringUtils.getBean(DeviceMsgUtils.class);
            if (deviceMsgUtils == null) {
                return null;
            }
            //压缩数据包
            JSONObject data = JSON.parseObject(JSON.toJSONString(command));
            DeviceCommandMsgModel commandMsgModel = new DeviceCommandMsgModel();
            commandMsgModel.setDeviceId(device.getDeviceNo());
            commandMsgModel.setDeviceType(String.valueOf(SlaveType.ForkLift));
            commandMsgModel.setCommand(data);
            String key = deviceMsgUtils.sendDeviceCommand(SlaveType.ForkLift, device.getDeviceNo(), commandMsgModel);
            return key;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    private JSONObject queryCommandStatus(String resultKey) {
        // 获取服务器响应
        // 尝试50次
        JSONObject result = null;
        for (int i = 0; i < 50; i++) {
            result = getRequestBody(resultKey);
            if (result == null) {
                try {
                    Thread.sleep(500);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }else {
                break;
            }
        }
        return result;
    }
    public JSONObject getRequestBody(String resultKey) {
        try {
            // 获取服务器响应
            JSONObject result = null;
            int idx = -1;
            for (int i = 0; i < resultList.size(); i++) {
                DeviceMsgModel deviceMsgModel = resultList.get(i);
                if(deviceMsgModel.getResultKey().equals(resultKey)){
                    idx = i;
                    result = JSON.parseObject(JSON.toJSONString(deviceMsgModel.getDeviceMsg()));
                    break;
                }
            }
            if (result == null) {
                return null;//无响应结果
            }
            resultList.remove(idx);
            return result;
        } catch (Exception e) {
            return null;
        }
    }
    private void listenMessageFromRedis() {
        try {
            DeviceMsgUtils deviceMsgUtils = null;
            try {
                deviceMsgUtils = SpringUtils.getBean(DeviceMsgUtils.class);
            }catch (Exception e){
            }
            if (deviceMsgUtils == null) {
                return;
            }
            DeviceMsgModel deviceMsg = deviceMsgUtils.getDeviceMsg(SlaveType.ForkLift, device.getDeviceNo());
            if(deviceMsg == null){
                return;
            }
            if (deviceMsg.getDeviceMsgType().equals("status")) {
                readResultList.add(deviceMsg);
            }else {
                resultList.add(deviceMsg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 扩展字段
     */
    @Data
    private class InnerForkLiftExtend {
    }
}