package com.zy.core.thread.impl; 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.model.LiftPointModel; import com.zy.common.utils.RedisUtil; import com.zy.core.News; import com.zy.core.action.LiftAction; import com.zy.core.cache.OutputQueue; import com.zy.core.enums.*; import com.zy.core.model.CommandResponse; import com.zy.core.model.DeviceCommandMsgModel; import com.zy.core.model.DeviceMsgModel; import com.zy.core.model.LiftStation; import com.zy.core.model.command.LiftCommand; import com.zy.core.model.protocol.LiftProtocol; import com.zy.core.model.protocol.LiftStaProtocol; import com.zy.core.thread.LiftThread; 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.ArrayList; import java.util.Date; import java.util.List; import java.util.TreeSet; @Slf4j @SuppressWarnings("all") public class NyLiftThread implements LiftThread { private DeviceConfig device; private LiftProtocol liftProtocol; private RedisUtil redisUtil; LiftPointModel liftPointModel; private List liftStaProtocols = new ArrayList<>(); private List readResultList = new ArrayList<>(); private List resultList = new ArrayList<>(); public NyLiftThread(DeviceConfig device, LiftPointModel liftPointModel, List stationList, RedisUtil redisUtil) { this.device = device; this.redisUtil = redisUtil; this.liftPointModel = liftPointModel; //初始化站点 for (LiftStation station : stationList) { LiftStaProtocol liftStaProtocol = new LiftStaProtocol(); liftStaProtocol.setStaNo(station.getStaNo());//站点号 liftStaProtocol.setLev(station.getLev());//站点楼层 String locNo = Utils.getLocNo(station.getRow(), station.getBay(), station.getLev()); liftStaProtocol.setLocNo(locNo);//站点库位号 liftStaProtocol.setLiftNo(station.getLiftNo());//提升机号 liftStaProtocols.add(liftStaProtocol); } } @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(); readStatus(); Thread.sleep(100); } catch (Exception e) { log.error("LiftThread Fail", e); } } }); readThread.start(); while (true) { try { execute(); } catch (Exception e) { e.printStackTrace(); } } } private void execute() { LiftAction liftAction = null; try { liftAction = SpringUtils.getBean(LiftAction.class); }catch (Exception e){} if (liftAction == null) { return; } Object object = redisUtil.get(RedisKeyType.LIFT_FLAG.key + device.getDeviceNo()); if (object == null) { return; } Integer taskNo = Integer.valueOf(String.valueOf(object)); if (taskNo != 0) { //存在任务需要执行 boolean result = liftAction.executeWork(device.getDeviceNo(), taskNo); } } private void readStatus() { try { //获取提升机数据 DeviceMsgUtils deviceMsgUtils = null; try { deviceMsgUtils = SpringUtils.getBean(DeviceMsgUtils.class); }catch (Exception e){ } if(deviceMsgUtils == null){ return; } LiftCommand readStatusCommand = getReadStatusCommand(); //指令超过2条,不再下发任务状态请求 TreeSet deviceCommandMsgListKey = deviceMsgUtils.getDeviceCommandMsgListKey(SlaveType.Lift, 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 == liftProtocol) { liftProtocol = new LiftProtocol(); liftProtocol.setLiftNo(device.getDeviceNo()); liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE); InnerLiftExtend innerLiftExtend = new InnerLiftExtend(); liftProtocol.setExtend(innerLiftExtend); } //----------读取提升机状态----------- //模式 liftProtocol.setModel(data.getInteger("model")); //PLC任务号 liftProtocol.setPlcTaskNo(data.getInteger("plcTaskNo")); //设备状态 liftProtocol.setDeviceStatus(data.getInteger("deviceStatus")); //任务模式 liftProtocol.setTaskMode(data.getInteger("taskMode")); //取货数据 liftProtocol.setPick(data.getInteger("pick")); //放货数据 liftProtocol.setPut(data.getInteger("put")); //有托盘 liftProtocol.setHasTray(data.getInteger("hasTray") == 1); //有小车 liftProtocol.setHasCar(data.getInteger("hasCar") == 1); //出入库模式 liftProtocol.setIOMode(data.getInteger("iOMode")); //故障码 liftProtocol.setErrorCode(data.getInteger("errorCode")); //当前层 liftProtocol.setLev(data.getInteger("lev")); //************补充扩展字段************* InnerLiftExtend liftExtend = (InnerLiftExtend) liftProtocol.getExtend(); liftProtocol.setExtend(liftExtend); liftExtend.setFrontOverrun(data.getBoolean("frontOverrun")); liftExtend.setBackOverrun(data.getBoolean("backOverrun")); liftExtend.setLeftOverrun(data.getBoolean("leftOverrun")); liftExtend.setRightOverrun(data.getBoolean("rightOverrun")); liftExtend.setOverHeight(data.getBoolean("overHeight")); liftExtend.setOverWeight(data.getBoolean("overWeight")); JSONArray trayList = data.getJSONArray("trayList"); for (int i = 0; i < trayList.size(); i++) { int hasTray = (int) trayList.get(i); LiftStaProtocol liftStaProtocol = liftStaProtocols.get(i); liftStaProtocol.setHasTray(hasTray == 1); } JSONArray carList = data.getJSONArray("carList"); for (int i = 0; i < carList.size(); i++) { int hasCar = (int) carList.get(i); LiftStaProtocol liftStaProtocol = liftStaProtocols.get(i); liftStaProtocol.setHasCar(hasCar == 1); } if (System.currentTimeMillis() - liftProtocol.getDeviceDataLog() > 1000 * 5) { //采集时间超过5s,保存一次数据记录 //保存数据记录 DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class); DeviceDataLog deviceDataLog = new DeviceDataLog(); deviceDataLog.setOriginData(JSON.toJSONString(data)); deviceDataLog.setWcsData(JSON.toJSONString(liftProtocol)); deviceDataLog.setType("lift"); deviceDataLog.setDeviceNo(liftProtocol.getLiftNo()); deviceDataLog.setCreateTime(new Date()); deviceDataLogService.insert(deviceDataLog); //更新采集时间 liftProtocol.setDeviceDataLog(System.currentTimeMillis()); } //将提升机状态保存至数据库 BasLiftService basLiftService = SpringUtils.getBean(BasLiftService.class); BasLift basLift = basLiftService.selectOne(new EntityWrapper() .eq("lift_no", device.getDeviceNo())); if (basLift == null) { basLift = new BasLift(); //提升机号 basLift.setLiftNo(liftProtocol.getLiftNo()); basLift.setStatus(1); basLiftService.insert(basLift); } //任务号 basLift.setWrkNo(liftProtocol.getTaskNo()); //修改时间 basLift.setUpdateTime(new Date()); //设备状态 basLift.setDeviceStatus(JSON.toJSONString(liftProtocol)); if (basLiftService.updateById(basLift)) { OutputQueue.LIFT.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), liftProtocol.getLiftNo())); } } catch (Exception e) { e.printStackTrace(); OutputQueue.LIFT.offer(MessageFormat.format("【{0}】读取提升机状态信息失败 ===>> [id:{1}] [ip:{2}] [port:{3}]", DateUtils.convert(new Date()), device.getDeviceNo(), device.getIp(), device.getPort())); } } @Override public LiftProtocol getStatus(boolean clone) { if (this.liftProtocol == null) { return null; } return clone ? this.liftProtocol.clone() : this.liftProtocol; } @Override public List getLiftStaProtocols() { return this.liftStaProtocols; } @Override public LiftProtocol getStatus() { return getStatus(true); } @Override public CommandResponse pickAndPut(LiftCommand 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.liftProtocol.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(LiftCommand 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.liftProtocol.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(LiftCommand 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.liftProtocol.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(LiftCommand 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.liftProtocol.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 { LiftCommand 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.liftProtocol.setSendTime(System.currentTimeMillis());//指令下发时间 this.setSyncTaskNo(0); this.setProtocolStatus(LiftProtocolStatusType.IDLE); 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.liftProtocol.getTaskNo() == null || this.liftProtocol.getPlcTaskNo() == null || this.liftProtocol.getProtocolStatus() == null || this.liftProtocol.getModel() == null || this.liftProtocol.getErrorCode() == null || this.liftProtocol.getExtend() == null ) { return false; } InnerLiftExtend extend = (InnerLiftExtend) this.liftProtocol.getExtend(); boolean res = this.liftProtocol.getProtocolStatus() == LiftProtocolStatusType.IDLE.id // && this.liftProtocol.getPlcTaskNo() == 0 && this.liftProtocol.getTaskNo() == 0 && this.liftProtocol.getModel() == 2 && this.liftProtocol.getErrorCode() == 0 && !extend.getFrontOverrun() && !extend.getBackOverrun() && !extend.getLeftOverrun() && !extend.getRightOverrun() && !extend.getOverHeight() && !extend.getOverWeight() ; 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.liftProtocol.getProtocolStatus() == null || this.liftProtocol.getModel() == null || this.liftProtocol.getErrorCode() == null || this.liftProtocol.getExtend() == null ) { return false; } InnerLiftExtend extend = (InnerLiftExtend) this.liftProtocol.getExtend(); boolean res = this.liftProtocol.getProtocolStatus() == LiftProtocolStatusType.IDLE.id && this.liftProtocol.getModel() == 2 && this.liftProtocol.getErrorCode() == 0 && !extend.getFrontOverrun() && !extend.getBackOverrun() && !extend.getLeftOverrun() && !extend.getRightOverrun() && !extend.getOverHeight() && !extend.getOverWeight() ; return res; } @Override public boolean setProtocolStatus(LiftProtocolStatusType status) { this.liftProtocol.setProtocolStatus(status); return true; } @Override public boolean setSyncTaskNo(Integer taskNo) { this.liftProtocol.setSyncTaskNo(taskNo); return true; } @Override public int generateDeviceTaskNo(int taskNo, LiftTaskModeType type) { return taskNo; } @Override public String getCurrentLocNo() { if (liftProtocol.getLev() == null) { return null; } return Utils.getLocNo(liftPointModel.getRow(), liftPointModel.getBay(), liftProtocol.getLev()); } @Override public LiftCommand getPickAndPutCommand(Integer taskNo, Integer pick, Integer put) { LiftCommand command = new LiftCommand(); command.setLiftNo(device.getDeviceNo()); command.setTaskNo(taskNo); command.setMode(LiftTaskModeType.PICK_PUT.id); command.setPick(pick); command.setPut(put); return command; } @Override public LiftCommand getShuttleSwitchCommand(Integer taskNo, Integer pick, Integer put) { LiftCommand command = new LiftCommand(); command.setLiftNo(device.getDeviceNo()); command.setTaskNo(taskNo); command.setMode(LiftTaskModeType.SHUTTLE_SWITCH.id); command.setPick(pick); command.setPut(put); return command; } @Override public LiftCommand getMoveCommand(Integer taskNo, Integer pick, Integer put) { LiftCommand command = new LiftCommand(); command.setLiftNo(device.getDeviceNo()); command.setTaskNo(taskNo); command.setMode(LiftTaskModeType.MOVE.id); command.setPick(pick); command.setPut(put); return command; } @Override public LiftCommand getSwitchIOCommand(Integer taskNo, LiftIoModeType mode) { LiftCommand command = new LiftCommand(); command.setLiftNo(device.getDeviceNo()); if (mode.equals(LiftIoModeType.IN)) { command.setMode(LiftIoModeType.IN.id); } else { command.setMode(LiftIoModeType.OUT.id); } return command; } @Override public LiftCommand getResetCommand(Integer taskNo) { LiftCommand command = new LiftCommand(); command.setLiftNo(device.getDeviceNo()); command.setMode(LiftTaskModeType.RESET.id); return command; } //获取读状态信息命令 private LiftCommand getReadStatusCommand() { LiftCommand command = new LiftCommand(); command.setLiftNo(device.getDeviceNo()); command.setMode(LiftTaskModeType.READ_STATUS.id); return command; } //发出请求 private String requestCommand(LiftCommand 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.Lift)); commandMsgModel.setCommand(data); String key = deviceMsgUtils.sendDeviceCommand(SlaveType.Lift, 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.Lift, 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 InnerLiftExtend { /** * 前超限 */ private Boolean frontOverrun; /** * 后超限 */ private Boolean backOverrun; /** * 左超限 */ private Boolean leftOverrun; /** * 右超限 */ private Boolean rightOverrun; /** * 超高 */ private Boolean overHeight; /** * 超重 */ private Boolean overWeight; } }