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 forkLiftStaProtocols = new ArrayList<>(); private List readResultList = new ArrayList<>(); private List resultList = new ArrayList<>(); public ZyForkLiftThread(DeviceConfig device, List 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 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() .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 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 { } }