package com.zy.asrs.wcs.rcs.thread.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.common.utils.HttpHandler; 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.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.rcs.News; import com.zy.asrs.wcs.rcs.cache.OutputQueue; import com.zy.asrs.wcs.rcs.entity.DeviceDataLog; import com.zy.asrs.wcs.rcs.model.CommandResponse; 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 com.zy.asrs.wcs.core.utils.RedisUtil; import com.zy.asrs.wcs.rcs.entity.Device; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.*; @Slf4j @SuppressWarnings("all") public class SurayLiftThread implements LiftThread { private static String API_URL = "http://127.0.0.1:8082"; private Device device; private RedisUtil redisUtil; private LiftProtocol liftProtocol; public SurayLiftThread(Device device,RedisUtil redisUtil) { this.device = device; this.redisUtil = redisUtil; API_URL = "http://" + device.getIp() + ":" + device.getPort(); } @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 { //获取提升机数据 JSONObject data = requestDeviceStatus(); if (data != null) { if (null == liftProtocol) { liftProtocol = new LiftProtocol(); liftProtocol.setLiftNo(Integer.valueOf(device.getDeviceNo())); liftProtocol.setProtocolStatus(LiftProtocolStatusType.IDLE); liftProtocol.setDevice(device); InnerLiftExtend innerLiftExtend = new InnerLiftExtend(); innerLiftExtend.setLock(false);//默认未锁定 liftProtocol.setExtend(innerLiftExtend); } //----------读取提升机状态----------- //模式 liftProtocol.setModel(true); boolean runningState = data.getInteger("runningState") == 1; if (!data.getInteger("completeTaskNo").equals(data.getInteger("taskNo"))) { runningState = true;//工作号不一致,认为处于运行中 } //运行状态 liftProtocol.setRun(runningState); //就绪状态 liftProtocol.setReady(data.getInteger("readyState") == 1); //有托盘 liftProtocol.setHasTray(data.getString("haveCargo").equals("Y")); //有小车 liftProtocol.setHasCar(data.getInteger("haveCar") == 1); //故障码 liftProtocol.setErrorCode("0"); //层 liftProtocol.setLev(data.getInteger("curFloor")); //已完成的任务号 liftProtocol.setCompleteTaskNo(data.getString("completeTaskNo")); //************补充扩展字段************* InnerLiftExtend liftExtend = (InnerLiftExtend) liftProtocol.getExtend(); liftExtend.setLock(data.getInteger("lockStatus") == 1 ? true : false); liftProtocol.setExtend(liftExtend); // //前超限 // 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(status2[5]); // //有小车 // liftProtocol.setHasCar(status2[6]); // //设备故障 // liftProtocol.setDeviceError(status2[7]); // //任务号 // liftProtocol.setTaskNo(siemensS7Net.getByteTransform().TransInt16(result1.Content, 2)); // //目的地址 // liftProtocol.setDistAddress(siemensS7Net.getByteTransform().TransInt16(result1.Content, 4)); // //已完成任务号 // liftProtocol.setCompleteTaskNo(siemensS7Net.getByteTransform().TransInt16(result1.Content, 6)); // liftProtocol.setLev(lev); 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(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() .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())); } }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())); } Thread.sleep(200); } 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 boolean connect() { return false; } @Override public void close() { } @Override public LiftProtocol getStatus() { return this.liftProtocol.clone(); } @Override public Device getDevice() { return this.device; } @Override public synchronized CommandResponse move(LiftCommand command) { CommandResponse response = new CommandResponse(false); try { String loginToken = requestLoginToken(); if (loginToken == null) { return response; } HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + loginToken); String responseStr = new HttpHandler.Builder() .setUri(API_URL) .setPath("/RDS/lifterTask") .setHeaders(headers) .setJson(command.getBody()) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(responseStr); Integer code = jsonObject.getInteger("code"); response.setMessage(JSON.toJSONString(jsonObject)); if (code.equals(200)) { response.setResult(true); return response; } } catch (Exception e) { e.printStackTrace(); } return response; } @Override public synchronized CommandResponse palletInOut(LiftCommand command) { CommandResponse response = new CommandResponse(false); try { String loginToken = requestLoginToken(); if (loginToken == null) { return response; } HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + loginToken); String responseStr = new HttpHandler.Builder() .setUri(API_URL) .setPath("/RDS/lifterTask") .setHeaders(headers) .setJson(command.getBody()) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(responseStr); Integer code = jsonObject.getInteger("code"); response.setMessage(JSON.toJSONString(jsonObject)); if (code.equals(200)) { response.setResult(true); return response; } } catch (Exception e) { e.printStackTrace(); } return response; } @Override public synchronized CommandResponse lock(LiftCommand command) { CommandResponse response = new CommandResponse(false); try { String loginToken = requestLoginToken(); if (loginToken == null) { return response; } HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + loginToken); String responseStr = new HttpHandler.Builder() .setUri(API_URL) .setPath("/RDS/lifterOperation") .setHeaders(headers) .setJson(command.getBody()) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(responseStr); Integer code = jsonObject.getInteger("code"); response.setMessage(JSON.toJSONString(jsonObject)); if (code.equals(200)) { response.setResult(true); return response; } } catch (Exception e) { e.printStackTrace(); } return response; } @Override public synchronized CommandResponse unlock(LiftCommand command) { CommandResponse response = new CommandResponse(false); try { String loginToken = requestLoginToken(); if (loginToken == null) { return response; } HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + loginToken); String responseStr = new HttpHandler.Builder() .setUri(API_URL) .setPath("/RDS/lifterOperation") .setHeaders(headers) .setJson(command.getBody()) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(responseStr); Integer code = jsonObject.getInteger("code"); response.setMessage(JSON.toJSONString(jsonObject)); if (code.equals(200)) { response.setResult(true); return response; } } catch (Exception e) { e.printStackTrace(); } return response; } @Override public synchronized CommandResponse reset(LiftCommand command) { CommandResponse response = new CommandResponse(false); try { String loginToken = requestLoginToken(); if (loginToken == null) { return response; } HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + loginToken); String responseStr = new HttpHandler.Builder() .setUri(API_URL) .setPath("/RDS/lifterOperation") .setHeaders(headers) .setJson(command.getBody()) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(responseStr); Integer code = jsonObject.getInteger("code"); response.setMessage(JSON.toJSONString(jsonObject)); if (code.equals(200)) { response.setResult(true); return response; } } catch (Exception e) { e.printStackTrace(); } return response; } @Override public boolean isIdle() { return isIdle(null); } @Override public boolean isIdle(MotionCtgType flag) { if (flag == null) { InnerLiftExtend extend = (InnerLiftExtend) this.liftProtocol.getExtend();//获取扩展字段 // 判断提升机是否自动、就绪、空闲、未锁定 if (this.liftProtocol.getModel() && !this.liftProtocol.getRun() && this.liftProtocol.getPakMk() && this.liftProtocol.getReady() && this.liftProtocol.getErrorCode().equals("0") && (this.liftProtocol.getProtocolStatusType().equals(LiftProtocolStatusType.IDLE) || this.liftProtocol.getProtocolStatusType().equals(LiftProtocolStatusType.WAITING)) && !extend.getLock() ) { return true; } return false; } switch (Objects.requireNonNull(MotionCtgType.get(String.valueOf(flag)))){ case SHUTTLE_MOVE_FROM_LIFT://穿梭车出提升机 case SHUTTLE_MOVE_TO_LIFT://穿梭车进提升机 case LIFT_SHUTTLE_ARRIVAL://提升机解锁 return isIdleShuttleMoveToLift(); case LIFT_LOCK://提升机锁定 case LIFT_UNLOCK://提升机解锁 return isIdleLiftLock(); } return false; } //穿梭车进提升机时-提升机状态判断 private boolean isIdleShuttleMoveToLift() { InnerLiftExtend extend = (InnerLiftExtend) this.liftProtocol.getExtend();//获取扩展字段 // 判断提升机是否自动、就绪、空闲 if (this.liftProtocol.getModel() && !this.liftProtocol.getRun() && this.liftProtocol.getPakMk() && this.liftProtocol.getErrorCode().equals("0") && (this.liftProtocol.getProtocolStatusType().equals(LiftProtocolStatusType.IDLE) || this.liftProtocol.getProtocolStatusType().equals(LiftProtocolStatusType.WAITING)) ) { if (!extend.getLock()) { //提升机未锁定,需要判断是否就绪 if (!this.liftProtocol.getReady()) { return false; } } return true; } return false; } //提升机锁定-提升机状态判断 private boolean isIdleLiftLock() { // 判断提升机是否自动、就绪、空闲 if (this.liftProtocol.getModel() && !this.liftProtocol.getRun() && this.liftProtocol.getPakMk() && 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.getErrorCode().equals("0") ) { if (this.liftProtocol.getTaskNo() == 0) { //无任务情况下检测是否就绪 if (!this.liftProtocol.getReady()) { return false; } } return true; } return false; } @Override public boolean setProtocolStatus(LiftProtocolStatusType status) { this.liftProtocol.setProtocolStatus(status); return true; } @Override public boolean setSyncTaskNo(Integer taskNo) { this.liftProtocol.setTaskNo(taskNo); return true; } @Override public boolean isLock(ExecuteSupport support) { InnerLiftExtend extend = (InnerLiftExtend) this.liftProtocol.getExtend(); return extend.getLock(); } @Override public int generateDeviceTaskNo(int taskNo, MotionCtgType motionCtgType) { return taskNo; } //***************设备层通讯-不同厂商设备通讯方案不一致*************** //请求登录 private String requestLoginToken() { try { HashMap param = new HashMap<>(); param.put("username", "admin"); param.put("password", "admin123"); param.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); String response = new HttpHandler.Builder() .setUri(API_URL) .setPath("/RDS/loginToken") .setJson(JSON.toJSONString(param)) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(response); Integer code = jsonObject.getInteger("code"); if (code.equals(200)) { return jsonObject.getString("token"); } } catch (Exception e) { e.printStackTrace(); } return null; } //获取设备状态 private JSONObject requestDeviceStatus() { //模拟数据 // String data = "[{\"taskNo\":1244,\"curFloor\":2,\"readyState\":1,\"haveCar\":'N',\"completeTaskNo\":0,\"haveCargo\":\"Y\",\"runningstate\":0,\"floors\":[{\"floor\":1,\"location\":1,\"run\":1,\"error\":1,\"cargoState\":\"Y\"},{\"floor\":1,\"location\":2,\"run\":0,\"error\":0,\"cargoState\":\"N\"}]}]"; // return JSON.parseArray(data).getJSONObject(0); try { String loginToken = requestLoginToken(); if (loginToken == null) { return null; } HashMap headers = new HashMap<>(); headers.put("Authorization", "Bearer " + loginToken); HashMap param = new HashMap<>(); param.put("messageName", "deviceRgvStatus"); param.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); param.put("deviceNo", device.getDeviceNo()); String response = new HttpHandler.Builder() .setUri(API_URL) .setPath("/RDS/deviceLifterStatus") .setHeaders(headers) .setJson(JSON.toJSONString(param)) .build() .doPost(); JSONObject jsonObject = JSON.parseObject(response); Integer code = jsonObject.getInteger("code"); if (code.equals(200)) { return jsonObject.getJSONArray("data").getJSONObject(0); } } catch (Exception e) { e.printStackTrace(); } return null; } //空载移动 @Override public List getMoveCommand(Integer taskNo, Integer sourceLev, Integer targetLev, LiftCommandModeType mode) { int taskMode = 3;//空载移动 HashMap body = new HashMap<>(); body.put("messageName", "lifterTask"); body.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); body.put("deviceNo", Integer.parseInt(this.device.getDeviceNo())); body.put("taskId", taskNo); body.put("startLayer", 0); body.put("endLayer", targetLev); body.put("startLocation", 0); body.put("endLocation", 0); body.put("model", taskMode); LiftCommand command = new LiftCommand(); command.setLiftNo(Integer.valueOf(this.device.getDeviceNo())); command.setBody(JSON.toJSONString(body)); command.setMode(LiftCommandModeType.MOVE.id); command.setOriginLev(0); command.setTargetLev(targetLev); ArrayList list = new ArrayList<>(); list.add(command); list.addAll(getTaskClearCommand()); return list; } //载车移动 @Override public List getMoveWithShuttleCommand(Integer taskNo, Integer sourceLev, Integer targetLev, LiftCommandModeType mode) { HashMap body = new HashMap<>(); body.put("messageName", "lifterTask"); body.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); body.put("deviceNo", Integer.parseInt(this.device.getDeviceNo())); body.put("taskId", taskNo); body.put("startLayer", sourceLev); body.put("endLayer", targetLev); body.put("startLocation", 0); body.put("endLocation", 0); body.put("model", 2);//载车移动 LiftCommand command = new LiftCommand(); command.setLiftNo(Integer.valueOf(this.device.getDeviceNo())); command.setBody(JSON.toJSONString(body)); command.setMode(LiftCommandModeType.MOVE.id); command.setOriginLev(sourceLev); command.setTargetLev(targetLev); ArrayList list = new ArrayList<>(); list.add(command); list.addAll(getTaskClearCommand()); return list; } //托盘出入 @Override public List getPalletInOutCommand(Integer taskNo, Integer sourceLev, Integer targetLev, Integer originSta, Integer targetSta, LiftCommandModeType mode) { HashMap body = new HashMap<>(); body.put("messageName", "lifterTask"); body.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); body.put("deviceNo", Integer.parseInt(this.device.getDeviceNo())); body.put("taskId", taskNo); body.put("startLayer", sourceLev); body.put("endLayer", targetLev); body.put("startLocation", originSta); body.put("endLocation", targetSta); body.put("model", 1);//托盘出入 LiftCommand command = new LiftCommand(); command.setLiftNo(Integer.valueOf(this.device.getDeviceNo())); command.setBody(JSON.toJSONString(body)); command.setMode(LiftCommandModeType.PALLET_INOUT.id); command.setOriginLev(sourceLev); command.setTargetLev(targetLev); command.setOriginSta(originSta); command.setTargetSta(targetSta); ArrayList list = new ArrayList<>(); list.add(command); list.addAll(getTaskClearCommand()); return list; } //锁定/解锁提升机 @Override public List getLockCommand(Integer taskNo, Boolean lock) { HashMap body = new HashMap<>(); body.put("messageName", "lifterOperation"); body.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); body.put("deviceNo", Integer.parseInt(this.device.getDeviceNo())); body.put("taskId", taskNo); body.put("operation", lock ? 6 : 7); body.put("remark", taskNo); LiftCommand command = new LiftCommand(); command.setLiftNo(Integer.valueOf(this.device.getDeviceNo())); command.setBody(JSON.toJSONString(body)); command.setMode(lock ? LiftCommandModeType.LOCK.id : LiftCommandModeType.UNLOCK.id); ArrayList list = new ArrayList<>(); list.add(command); return list; } //小车已到位/已驶离信号 @Override public List getShuttleSignalCommand(Integer taskNo, Boolean signal) { HashMap body = new HashMap<>(); body.put("messageName", "lifterOperation"); body.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); body.put("deviceNo", Integer.parseInt(this.device.getDeviceNo())); body.put("taskId", taskNo); body.put("operation", signal ? 4 : 5); LiftCommand command = new LiftCommand(); command.setLiftNo(Integer.valueOf(this.device.getDeviceNo())); command.setBody(JSON.toJSONString(body)); command.setMode(signal ? LiftCommandModeType.LOCK.id : LiftCommandModeType.UNLOCK.id); ArrayList list = new ArrayList<>(); list.add(command); return list; } //获取提升机任务清除命令 private List getTaskClearCommand() { HashMap body = new HashMap<>(); body.put("messageName", "lifterOperation"); body.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); body.put("deviceNo", Integer.parseInt(this.device.getDeviceNo())); body.put("operation", 1); LiftCommand command = new LiftCommand(); command.setLiftNo(Integer.valueOf(this.device.getDeviceNo())); command.setBody(JSON.toJSONString(body)); command.setMode(LiftCommandModeType.RESET.id); ArrayList list = new ArrayList<>(); list.add(command); return list; } /** * 扩展字段 */ @Data private class InnerLiftExtend { /** * 提升机锁定 */ private Boolean lock = false; } }