|  |  | 
 |  |  | import com.alibaba.fastjson.JSON; | 
 |  |  | import com.alibaba.fastjson.JSONObject; | 
 |  |  | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 
 |  |  | import com.fasterxml.jackson.core.JsonProcessingException; | 
 |  |  | import com.fasterxml.jackson.databind.ObjectMapper; | 
 |  |  | 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.domain.param.ShuttleMoveLocParam; | 
 |  |  | import com.zy.asrs.wcs.core.entity.BasLift; | 
 |  |  | import com.zy.asrs.wcs.core.entity.BasShuttle; | 
 |  |  | import com.zy.asrs.wcs.core.entity.Loc; | 
 |  |  | import com.zy.asrs.wcs.core.model.NavigateNode; | 
 |  |  | import com.zy.asrs.wcs.core.model.command.ShuttleCommand; | 
 |  |  | import com.zy.asrs.wcs.core.model.enums.ShuttleCommandModeType; | 
 |  |  | import com.zy.asrs.wcs.core.model.enums.ShuttleRunDirection; | 
 |  |  | import com.zy.asrs.wcs.core.model.command.ShuttleRedisCommand; | 
 |  |  | import com.zy.asrs.wcs.core.model.enums.*; | 
 |  |  | import com.zy.asrs.wcs.core.service.BasLiftService; | 
 |  |  | import com.zy.asrs.wcs.core.service.BasShuttleService; | 
 |  |  | import com.zy.asrs.wcs.core.service.LocService; | 
 |  |  | import com.zy.asrs.wcs.core.utils.LiftDispatcher; | 
 |  |  | import com.zy.asrs.wcs.core.utils.NavigateUtils; | 
 |  |  | import com.zy.asrs.wcs.core.utils.Utils; | 
 |  |  | import com.zy.asrs.wcs.rcs.News; | 
 |  |  | import com.zy.asrs.wcs.rcs.cache.OutputQueue; | 
 |  |  | import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant; | 
 |  |  | import com.zy.asrs.wcs.rcs.entity.DeviceDataLog; | 
 |  |  | import com.zy.asrs.wcs.rcs.model.CommandResponse; | 
 |  |  | import com.zy.asrs.wcs.rcs.model.enums.ShuttleProtocolStatusType; | 
 |  |  | import com.zy.asrs.wcs.rcs.model.enums.SlaveType; | 
 |  |  | import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol; | 
 |  |  | 
 |  |  | import com.zy.asrs.wcs.rcs.thread.ShuttleThread; | 
 |  |  | import com.zy.asrs.wcs.core.utils.RedisUtil; | 
 |  |  | import com.zy.asrs.wcs.rcs.entity.Device; | 
 |  |  | import com.zy.asrs.wcs.system.entity.Dict; | 
 |  |  | import com.zy.asrs.wcs.system.service.DictService; | 
 |  |  | import lombok.Data; | 
 |  |  | import lombok.extern.slf4j.Slf4j; | 
 |  |  |  | 
 |  |  | import java.text.MessageFormat; | 
 |  |  | import java.text.SimpleDateFormat; | 
 |  |  | import java.util.*; | 
 |  |  | import java.util.concurrent.TimeUnit; | 
 |  |  |  | 
 |  |  | @Slf4j | 
 |  |  | @SuppressWarnings("all") | 
 |  |  | public class SurayShuttleThread implements ShuttleThread { | 
 |  |  |  | 
 |  |  |     private static final String API_URL = "http://127.0.0.1:8082"; | 
 |  |  |     private static String API_URL = "http://127.0.0.1:8082"; | 
 |  |  |  | 
 |  |  |     private Device device; | 
 |  |  |     private RedisUtil redisUtil; | 
 |  |  | 
 |  |  |     public SurayShuttleThread(Device device,RedisUtil redisUtil) { | 
 |  |  |         this.device = device; | 
 |  |  |         this.redisUtil = redisUtil; | 
 |  |  |         API_URL = "http://" + device.getIp() + ":" + device.getPort(); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  | 
 |  |  |                 //----------读取四向穿梭车状态----------- | 
 |  |  |                 //小车设备状态 | 
 |  |  |                 Integer deviceStatus = data.getInteger("deviceStatus"); | 
 |  |  |                 if (deviceStatus == 255) { | 
 |  |  |                     //离线 | 
 |  |  |                     shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.OFFLINE); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 if(deviceStatus != 4 || deviceStatus != 6 || deviceStatus != 7 || deviceStatus != 8 || deviceStatus != 255 || deviceStatus != -1) { | 
 |  |  |                     shuttleProtocol.setMode(1);//自动状态 | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 shuttleProtocol.setDeviceStatus(deviceStatus); | 
 |  |  |                 //当前二维码 | 
 |  |  |                 shuttleProtocol.setCurrentCode(data.getString("groundCode") == null ? "0" : data.getString("groundCode")); | 
 |  |  |                 //电池电量 | 
 |  |  |                 shuttleProtocol.setBatteryPower(data.getString("battery") == null ? "0%" : data.getString("battery")); | 
 |  |  |  | 
 |  |  |                 shuttleProtocol.setBatteryPower(data.getString("battery") == null ? "0" : data.getString("battery")); | 
 |  |  |                 //故障 | 
 |  |  |                 shuttleProtocol.setErrorCode(deviceStatus == 6 ? "1" : "0"); | 
 |  |  |  | 
 |  |  |                 //是否顶升 | 
 |  |  |                 shuttleProtocol.setHasLift(data.getInteger("palletStatus") == 1 ? true : false); | 
 |  |  | 
 |  |  |                 extend.setStatusDescription(data.getString("statusDescription"));//状态描述 | 
 |  |  |                 shuttleProtocol.setExtend(extend);//扩展字段 | 
 |  |  |  | 
 |  |  |                 //最近一次在线时间 | 
 |  |  |                 shuttleProtocol.setLastOnlineTime(System.currentTimeMillis()); | 
 |  |  |                 ///读取四向穿梭车状态-end | 
 |  |  |  | 
 |  |  |                 //小车处于忙碌状态,将标记置为true | 
 |  |  |                 if (!shuttleProtocol.getIdle()) { | 
 |  |  |                 if (deviceStatus == 1 || deviceStatus == 2 || deviceStatus == 5) { | 
 |  |  |                     shuttleProtocol.setPakMk(true); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  | //                if (shuttleProtocol.getProtocolStatusType() == null && shuttleProtocol.getDeviceStatus().intValue() == ShuttleDeviceStatusType.IDLE.id) { | 
 |  |  | //                    //小车空闲状态、小车任务状态为未知,认定曾离线过,需要复位成空闲 | 
 |  |  | //                    shuttleProtocol.setProtocolStatusType(ShuttleProtocolStatusType.IDLE); | 
 |  |  | //                } | 
 |  |  |                 if (shuttleProtocol.getProtocolStatusType() == null && shuttleProtocol.getDeviceStatus().intValue() == 3) { | 
 |  |  |                     //小车空闲状态、小车任务状态为未知,认定曾离线过,需要复位成空闲 | 
 |  |  |                     shuttleProtocol.setProtocolStatusType(ShuttleProtocolStatusType.IDLE); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 if (System.currentTimeMillis() - shuttleProtocol.getDeviceDataLog() > 1000 * 5) { | 
 |  |  |                     //采集时间超过5s,保存一次数据记录 | 
 |  |  | 
 |  |  |  | 
 |  |  |                     //更新采集时间 | 
 |  |  |                     shuttleProtocol.setDeviceDataLog(System.currentTimeMillis()); | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 //将四向穿梭车状态保存至数据库 | 
 |  |  |                 BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class); | 
 |  |  |                 BasShuttle basShuttle = shuttleService.getOne(new LambdaQueryWrapper<BasShuttle>() | 
 |  |  |                         .eq(BasShuttle::getShuttleNo, device.getDeviceNo()) | 
 |  |  |                         .eq(BasShuttle::getHostId, device.getHostId())); | 
 |  |  |                 if (basShuttle == null) { | 
 |  |  |                     basShuttle = new BasShuttle(); | 
 |  |  |                     //四向穿梭车号 | 
 |  |  |                     basShuttle.setShuttleNo(Integer.valueOf(device.getDeviceNo())); | 
 |  |  |                     basShuttle.setStatus(1); | 
 |  |  |                     basShuttle.setDeleted(0); | 
 |  |  |                     basShuttle.setHostId(device.getHostId()); | 
 |  |  |                     basShuttle.setDeviceId(device.getId().intValue()); | 
 |  |  |                     shuttleService.save(basShuttle); | 
 |  |  |                 } | 
 |  |  |                 //任务号 | 
 |  |  |                 basShuttle.setTaskNo(shuttleProtocol.getTaskNo().intValue()); | 
 |  |  |                 //修改时间 | 
 |  |  |                 basShuttle.setUpdateTime(new Date()); | 
 |  |  |                 //设备状态 | 
 |  |  |                 basShuttle.setProtocol(JSON.toJSONString(shuttleProtocol)); | 
 |  |  |                 if (shuttleService.updateById(basShuttle)) { | 
 |  |  |                     OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】[id:{1}] <<<<< 实时数据更新成功",DateUtils.convert(new Date()), device.getDeviceNo())); | 
 |  |  |                 } | 
 |  |  |             } else { | 
 |  |  |                 OutputQueue.SHUTTLE.offer(MessageFormat.format("【{0}】{1}读取四向穿梭车状态信息失败", DateUtils.convert(new Date()), device.getDeviceNo())); | 
 |  |  | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public ShuttleProtocol getStatus() { | 
 |  |  |         return this.shuttleProtocol; | 
 |  |  |         return getStatus(true); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public ShuttleProtocol getStatus(boolean clone) { | 
 |  |  |         if (this.shuttleProtocol == null) { | 
 |  |  |             return null; | 
 |  |  |         } | 
 |  |  |         return clone ? this.shuttleProtocol.clone() : this.shuttleProtocol; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public synchronized boolean movePath(List<NavigateNode> nodes, Integer taskNo) { | 
 |  |  |     public synchronized CommandResponse movePath(List<NavigateNode> nodes, Integer taskNo) { | 
 |  |  |         CommandResponse response = new CommandResponse(false); | 
 |  |  |         try { | 
 |  |  |             NavigateUtils navigateUtils = SpringUtils.getBean(NavigateUtils.class); | 
 |  |  |             //默认地图母轨方向x | 
 |  |  |             String mapDirection = "x"; | 
 |  |  |             DictService dictService = SpringUtils.getBean(DictService.class); | 
 |  |  |             Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>() | 
 |  |  |                     .eq(Dict::getFlag, "direction_map") | 
 |  |  |                     .eq(Dict::getStatus, 1)); | 
 |  |  |             if (dict != null) { | 
 |  |  |                 mapDirection = dict.getValue(); | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             String loginToken = requestLoginToken(); | 
 |  |  |             if (loginToken == null) { | 
 |  |  |                 return false; | 
 |  |  |                 return response; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             HashMap<String, Object> headers = new HashMap<>(); | 
 |  |  | 
 |  |  |  | 
 |  |  |             ArrayList<HashMap<String, Object>> modes = new ArrayList<>(); | 
 |  |  |             //获取分段路径 | 
 |  |  |             ArrayList<ArrayList<NavigateNode>> data = NavigateUtils.getSectionPath(nodes); | 
 |  |  |             for (ArrayList<NavigateNode> sectionNodes : data) { | 
 |  |  |             ArrayList<ArrayList<NavigateNode>> data = navigateUtils.getSectionPath(nodes); | 
 |  |  |             for (int idx = 0; idx < data.size(); idx++) { | 
 |  |  |                 ArrayList<NavigateNode> sectionNodes = data.get(idx); | 
 |  |  |                 boolean isRemoveFooterNode = false;//是否剔除尾节点 | 
 |  |  |                 if (idx != data.size() - 1) { | 
 |  |  |                     isRemoveFooterNode = true;//剔除尾节点 | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 boolean flag = true; | 
 |  |  |                 int oper; | 
 |  |  |                 //开始路径 | 
 |  |  |                 NavigateNode startPath = nodes.get(0); | 
 |  |  |                 if (ShuttleRunDirection.get(startPath.getDirection()) == ShuttleRunDirection.LEFT | 
 |  |  |                 NavigateNode startPath = sectionNodes.get(0); | 
 |  |  |                 //结束路径 | 
 |  |  |                 NavigateNode targetPath = sectionNodes.get(sectionNodes.size() - 1); | 
 |  |  |                 if (mapDirection.equals("y") && ShuttleRunDirection.get(startPath.getDirection()) == ShuttleRunDirection.LEFT | 
 |  |  |                         || ShuttleRunDirection.get(startPath.getDirection()) == ShuttleRunDirection.RIGHT) { | 
 |  |  |                     //母轨方向 | 
 |  |  |                     oper = 5; | 
 |  |  |                 }else { | 
 |  |  |                 } else { | 
 |  |  |                     //子轨方向 | 
 |  |  |                     oper = 6; | 
 |  |  |                 } | 
 |  |  |  | 
 |  |  |                 for (NavigateNode node : sectionNodes) { | 
 |  |  |                 for (int i = 0; i < sectionNodes.size(); i++) { | 
 |  |  |                     if (isRemoveFooterNode && i == sectionNodes.size() - 1) { | 
 |  |  |                         continue; | 
 |  |  |                     } | 
 |  |  |                     NavigateNode node = sectionNodes.get(i); | 
 |  |  |                     HashMap<String, Object> map = new HashMap<>(); | 
 |  |  |                     map.put("nodexX", node.getX()); | 
 |  |  |                     map.put("nodexY", node.getY()); | 
 |  |  |                     map.put("nodexZ", node.getZ()); | 
 |  |  |                     map.put("nodeX", node.getX()); | 
 |  |  |                     map.put("nodeY", node.getY()); | 
 |  |  |                     map.put("nodeZ", node.getZ()); | 
 |  |  |                     if (flag) { | 
 |  |  |                         map.put("oper", oper); | 
 |  |  |                         flag = false; | 
 |  |  | 
 |  |  |             param.put("taskId", taskNo); | 
 |  |  |             param.put("nodeNum", nodes.size()); | 
 |  |  |             param.put("modes", modes); | 
 |  |  |             String response = new HttpHandler.Builder() | 
 |  |  |             String responseStr = new HttpHandler.Builder() | 
 |  |  |                     .setUri(API_URL) | 
 |  |  |                     .setPath("/RDS/runRoute") | 
 |  |  |                     .setHeaders(headers) | 
 |  |  |                     .setJson(JSON.toJSONString(param)) | 
 |  |  |                     .setTimeout(60, TimeUnit.SECONDS) | 
 |  |  |                     .build() | 
 |  |  |                     .doPost(); | 
 |  |  |             JSONObject jsonObject = JSON.parseObject(response); | 
 |  |  |             JSONObject jsonObject = JSON.parseObject(responseStr); | 
 |  |  |             Integer code = jsonObject.getInteger("code"); | 
 |  |  |             System.out.println("路径下发" + taskNo); | 
 |  |  |             System.out.println(JSON.toJSONString(jsonObject)); | 
 |  |  |             System.out.println(JSON.toJSONString(param)); | 
 |  |  |             if (code.equals(200)) { | 
 |  |  |                 return true; | 
 |  |  |                 System.out.println("路径下发" + taskNo); | 
 |  |  |                 response.setResult(true); | 
 |  |  |                 response.setMessage(responseStr); | 
 |  |  |                 return response; | 
 |  |  |             } | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             e.printStackTrace(); | 
 |  |  |         } | 
 |  |  |         return false; | 
 |  |  |         return response; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public synchronized boolean move(ShuttleCommand command) { | 
 |  |  |     public synchronized CommandResponse move(ShuttleCommand command) { | 
 |  |  |         CommandResponse response = new CommandResponse(false); | 
 |  |  |         try { | 
 |  |  |             String loginToken = requestLoginToken(); | 
 |  |  |             if (loginToken == null) { | 
 |  |  |                 return false; | 
 |  |  |                 return response; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             HashMap<String, Object> headers = new HashMap<>(); | 
 |  |  |             headers.put("Authorization", "Bearer " + loginToken); | 
 |  |  |  | 
 |  |  |             String response = new HttpHandler.Builder() | 
 |  |  |             String responseStr = new HttpHandler.Builder() | 
 |  |  |                     .setUri(API_URL) | 
 |  |  |                     .setPath("/RDS/runOrder") | 
 |  |  |                     .setHeaders(headers) | 
 |  |  |                     .setJson(command.getBody()) | 
 |  |  |                     .setTimeout(60, TimeUnit.SECONDS) | 
 |  |  |                     .build() | 
 |  |  |                     .doPost(); | 
 |  |  |             JSONObject jsonObject = JSON.parseObject(response); | 
 |  |  |             JSONObject jsonObject = JSON.parseObject(responseStr); | 
 |  |  |             Integer code = jsonObject.getInteger("code"); | 
 |  |  |             System.out.println(JSON.toJSONString(command.getBody())); | 
 |  |  |             if (code.equals(200)) { | 
 |  |  |                 return true; | 
 |  |  |                 this.shuttleProtocol.setSendTime(System.currentTimeMillis());//指令下发时间 | 
 |  |  |                 response.setResult(true); | 
 |  |  |                 response.setMessage(responseStr); | 
 |  |  |                 return response; | 
 |  |  |             } | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             e.printStackTrace(); | 
 |  |  |         } | 
 |  |  |         return false; | 
 |  |  |         return response; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public synchronized boolean lift(ShuttleCommand command) { | 
 |  |  |     public synchronized CommandResponse lift(ShuttleCommand command) { | 
 |  |  |         CommandResponse response = new CommandResponse(false); | 
 |  |  |         try { | 
 |  |  |             String loginToken = requestLoginToken(); | 
 |  |  |             if (loginToken == null) { | 
 |  |  |                 return false; | 
 |  |  |                 return response; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             HashMap<String, Object> headers = new HashMap<>(); | 
 |  |  |             headers.put("Authorization", "Bearer " + loginToken); | 
 |  |  |  | 
 |  |  |             String response = new HttpHandler.Builder() | 
 |  |  |             String responseStr = new HttpHandler.Builder() | 
 |  |  |                     .setUri(API_URL) | 
 |  |  |                     .setPath("/RDS/actionOrder") | 
 |  |  |                     .setHeaders(headers) | 
 |  |  |                     .setJson(command.getBody()) | 
 |  |  |                     .setTimeout(60, TimeUnit.SECONDS) | 
 |  |  |                     .build() | 
 |  |  |                     .doPost(); | 
 |  |  |             JSONObject jsonObject = JSON.parseObject(response); | 
 |  |  |             JSONObject jsonObject = JSON.parseObject(responseStr); | 
 |  |  |             Integer code = jsonObject.getInteger("code"); | 
 |  |  |             if (code.equals(200)) { | 
 |  |  |                 return true; | 
 |  |  |                 this.shuttleProtocol.setSendTime(System.currentTimeMillis());//指令下发时间 | 
 |  |  |                 response.setResult(true); | 
 |  |  |                 response.setMessage(responseStr); | 
 |  |  |                 return response; | 
 |  |  |             } | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             e.printStackTrace(); | 
 |  |  |         } | 
 |  |  |         return false; | 
 |  |  |         return response; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public synchronized boolean charge(ShuttleCommand command) { | 
 |  |  |     public synchronized CommandResponse charge(ShuttleCommand command) { | 
 |  |  |         CommandResponse response = new CommandResponse(false); | 
 |  |  |         try { | 
 |  |  |             String loginToken = requestLoginToken(); | 
 |  |  |             if (loginToken == null) { | 
 |  |  |                 return false; | 
 |  |  |                 return response; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             HashMap<String, Object> headers = new HashMap<>(); | 
 |  |  |             headers.put("Authorization", "Bearer " + loginToken); | 
 |  |  |  | 
 |  |  |             String response = new HttpHandler.Builder() | 
 |  |  |             String responseStr = new HttpHandler.Builder() | 
 |  |  |                     .setUri(API_URL) | 
 |  |  |                     .setPath("/RDS/actionOrder") | 
 |  |  |                     .setHeaders(headers) | 
 |  |  |                     .setJson(command.getBody()) | 
 |  |  |                     .setTimeout(60, TimeUnit.SECONDS) | 
 |  |  |                     .build() | 
 |  |  |                     .doPost(); | 
 |  |  |             JSONObject jsonObject = JSON.parseObject(response); | 
 |  |  |             JSONObject jsonObject = JSON.parseObject(responseStr); | 
 |  |  |             Integer code = jsonObject.getInteger("code"); | 
 |  |  |             if (code.equals(200)) { | 
 |  |  |                 return true; | 
 |  |  |                 this.shuttleProtocol.setSendTime(System.currentTimeMillis());//指令下发时间 | 
 |  |  |                 response.setResult(true); | 
 |  |  |                 response.setMessage(responseStr); | 
 |  |  |                 return response; | 
 |  |  |             } | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             e.printStackTrace(); | 
 |  |  |         } | 
 |  |  |         return false; | 
 |  |  |         return response; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public synchronized boolean reset(ShuttleCommand command) { | 
 |  |  |         return false; | 
 |  |  |     public synchronized CommandResponse reset(ShuttleCommand command) { | 
 |  |  |         setSyncTaskNo(0); | 
 |  |  |         setProtocolStatus(ShuttleProtocolStatusType.IDLE); | 
 |  |  |         enableMoveLoc(null, false); | 
 |  |  |         return new CommandResponse(true, JSON.toJSONString(command)); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public CommandResponse updateLocation(ShuttleCommand command) { | 
 |  |  |         CommandResponse response = new CommandResponse(false); | 
 |  |  |         try { | 
 |  |  |             String loginToken = requestLoginToken(); | 
 |  |  |             if (loginToken == null) { | 
 |  |  |                 return response; | 
 |  |  |             } | 
 |  |  |  | 
 |  |  |             HashMap<String, Object> headers = new HashMap<>(); | 
 |  |  |             headers.put("Authorization", "Bearer " + loginToken); | 
 |  |  |  | 
 |  |  |             String responseStr = new HttpHandler.Builder() | 
 |  |  |                     .setUri(API_URL) | 
 |  |  |                     .setPath("/RDS/changeLocation") | 
 |  |  |                     .setHeaders(headers) | 
 |  |  |                     .setJson(command.getBody()) | 
 |  |  |                     .setTimeout(60, TimeUnit.SECONDS) | 
 |  |  |                     .build() | 
 |  |  |                     .doPost(); | 
 |  |  |             JSONObject jsonObject = JSON.parseObject(responseStr); | 
 |  |  |             Integer code = jsonObject.getInteger("code"); | 
 |  |  |             if (code.equals(200)) { | 
 |  |  |                 this.shuttleProtocol.setSendTime(System.currentTimeMillis());//指令下发时间 | 
 |  |  |                 response.setResult(true); | 
 |  |  |                 response.setMessage(responseStr); | 
 |  |  |                 return response; | 
 |  |  |             } | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             e.printStackTrace(); | 
 |  |  |         } | 
 |  |  |         return response; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean isIdle() { | 
 |  |  |         if (this.shuttleProtocol.getIdle() == null | 
 |  |  |         return this.isIdle(null); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean isIdle(ExecuteSupport support) { | 
 |  |  |         if (null != support) { | 
 |  |  |             Boolean judgement = support.judgement(); | 
 |  |  |             if (judgement != null && !judgement) { | 
 |  |  |                 return true; | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         if (this.shuttleProtocol.getDeviceStatus() == null | 
 |  |  |                 || this.shuttleProtocol.getPakMk() == null | 
 |  |  |                 || this.shuttleProtocol.getErrorCode() == null | 
 |  |  |                 || this.shuttleProtocol.getProtocolStatus() == null | 
 |  |  | 
 |  |  |             return false; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         boolean res = this.shuttleProtocol.getIdle() | 
 |  |  |         boolean res = (this.shuttleProtocol.getDeviceStatus() == 3 || this.shuttleProtocol.getDeviceStatus() == 11) | 
 |  |  |                 && this.shuttleProtocol.getPakMk() | 
 |  |  |                 && this.shuttleProtocol.getErrorCode().equals("0") | 
 |  |  |                 && this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.IDLE.id | 
 |  |  |                 && (this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.IDLE.id | 
 |  |  |                 || this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.WAITING.id | 
 |  |  |                 || this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.CHARGING_WAITING.id); | 
 |  |  |         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.shuttleProtocol.getDeviceStatus() == null | 
 |  |  |                 || this.shuttleProtocol.getPakMk() == null | 
 |  |  |                 || this.shuttleProtocol.getErrorCode() == null | 
 |  |  |         ) { | 
 |  |  |             return false; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         boolean res = (this.shuttleProtocol.getDeviceStatus() == 3 || this.shuttleProtocol.getDeviceStatus() == 11) | 
 |  |  |                 && this.shuttleProtocol.getPakMk() | 
 |  |  |                 && this.shuttleProtocol.getErrorCode().equals("0") | 
 |  |  |                 ; | 
 |  |  |         return res; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public ShuttleCommand getMoveCommand(Integer taskNo, String startCodeNum, String distCodeNum, Integer allDistance, Integer runDirection, Integer runSpeed) { | 
 |  |  |     public boolean isRequireCharge() { | 
 |  |  |         if (this.shuttleProtocol.getDeviceStatus() == null | 
 |  |  |                 || this.shuttleProtocol.getPakMk() == null | 
 |  |  |                 || this.shuttleProtocol.getErrorCode() == null | 
 |  |  |                 || this.shuttleProtocol.getProtocolStatus() == null | 
 |  |  |         ) { | 
 |  |  |             return false; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         boolean res = (this.shuttleProtocol.getDeviceStatus() == 3) | 
 |  |  |                 && this.shuttleProtocol.getPakMk() | 
 |  |  |                 && this.shuttleProtocol.getErrorCode().equals("0") | 
 |  |  |                 && this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.IDLE.id | 
 |  |  |                 ; | 
 |  |  |         if (!res) { | 
 |  |  |             return res; | 
 |  |  |         } else { | 
 |  |  |             // 电量小于阈值需要进行充电 | 
 |  |  |             try { | 
 |  |  |                 BasShuttleService shuttleService = SpringUtils.getBean(BasShuttleService.class); | 
 |  |  |                 if (shuttleService == null) { | 
 |  |  |                     return false; | 
 |  |  |                 } | 
 |  |  |                 BasShuttle basShuttle = shuttleService.getOne(new LambdaQueryWrapper<BasShuttle>().eq(BasShuttle::getDeviceId, this.device.getId())); | 
 |  |  |                 if (basShuttle == null) { | 
 |  |  |                     return false; | 
 |  |  |                 } | 
 |  |  |                 Integer chargeLine = basShuttle.getChargeLine(); | 
 |  |  |                 if (chargeLine == null) { | 
 |  |  |                     return false; | 
 |  |  |                 } | 
 |  |  |                 return Integer.valueOf(this.shuttleProtocol.getBatteryPower()) < chargeLine; | 
 |  |  |             } catch (Exception e) { | 
 |  |  |                 return false; | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean isCharging() { | 
 |  |  |         if (this.shuttleProtocol.getDeviceStatus() == null) { | 
 |  |  |             return false; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         if (this.shuttleProtocol.getDeviceStatus() == 5 || this.shuttleProtocol.getDeviceStatus() == 13) { | 
 |  |  |             //充电中和电池均衡 =》 充电 | 
 |  |  |             return true; | 
 |  |  |         } | 
 |  |  |         return false; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean isChargingCompleted() { | 
 |  |  |         Integer maxPower = 100; | 
 |  |  |         DictService dictService = SpringUtils.getBean(DictService.class); | 
 |  |  |         if (dictService != null) { | 
 |  |  |             Dict chargeMaxValue = dictService.getOne(new LambdaQueryWrapper<Dict>() | 
 |  |  |                     .eq(Dict::getFlag, "chargeMaxValue") | 
 |  |  |                     .eq(Dict::getStatus, 1)); | 
 |  |  |             if (chargeMaxValue != null) { | 
 |  |  |                 maxPower = Integer.parseInt(chargeMaxValue.getValue()); | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         if (this.shuttleProtocol.getBatteryPower() == null) { | 
 |  |  |             return false; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         if (Integer.valueOf(this.shuttleProtocol.getBatteryPower()) >= maxPower) { | 
 |  |  |             return true; | 
 |  |  |         } | 
 |  |  |         return false; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public List<NavigateNode> getMoveAdvancePath() { | 
 |  |  |         ObjectMapper objectMapper = SpringUtils.getBean(ObjectMapper.class); | 
 |  |  |         ArrayList<NavigateNode> path = new ArrayList<>(); | 
 |  |  |         if (shuttleProtocol.getTaskNo() != 0) { | 
 |  |  |             //存在任务,获取指令 | 
 |  |  |             Object object = redisUtil.get(DeviceRedisConstant.SHUTTLE_WORK_FLAG + shuttleProtocol.getTaskNo()); | 
 |  |  |             if (object != null) { | 
 |  |  |                 ShuttleRedisCommand redisCommand = null; | 
 |  |  |                 try { | 
 |  |  |                     redisCommand = objectMapper.readValue(String.valueOf(object), ShuttleRedisCommand.class); | 
 |  |  |                 } catch (JsonProcessingException e) { | 
 |  |  |                     return path; | 
 |  |  |                 } | 
 |  |  |                 List<NavigateNode> nodes = redisCommand.getAssignCommand().getNodes();//穿梭车预计路径 | 
 |  |  |                 if (nodes == null) { | 
 |  |  |                     return path; | 
 |  |  |                 } | 
 |  |  |                 if (!nodes.isEmpty()) { | 
 |  |  |                     path.addAll(nodes); | 
 |  |  |                 } | 
 |  |  |             } | 
 |  |  |         } | 
 |  |  |         return path; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public int generateDeviceTaskNo(int taskNo, MotionCtgType motionCtgType) { | 
 |  |  |         int deviceTaskNo = taskNo; | 
 |  |  |         try { | 
 |  |  |             deviceTaskNo = Utils.getTaskNo("SURAY_SHUTTLE"); | 
 |  |  |         } catch (Exception e) { | 
 |  |  |             return taskNo; | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         switch (Objects.requireNonNull(MotionCtgType.get(String.valueOf(motionCtgType)))){ | 
 |  |  |             case SHUTTLE_MOVE://穿梭车移动 | 
 |  |  |             case SHUTTLE_MOVE_LIFT_PALLET://穿梭车顶升并移动 | 
 |  |  |             case SHUTTLE_MOVE_DOWN_PALLET://穿梭车移动并托盘下降 | 
 |  |  |             case SHUTTLE_MOVE_FROM_LIFT://出提升机 | 
 |  |  |             case SHUTTLE_MOVE_TO_LIFT://进提升机 | 
 |  |  |                 return deviceTaskNo; | 
 |  |  |             default: | 
 |  |  |                 return taskNo; | 
 |  |  |         } | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public synchronized boolean setProtocolStatus(ShuttleProtocolStatusType status) { | 
 |  |  |         this.shuttleProtocol.setProtocolStatus(status); | 
 |  |  |         return true; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public synchronized boolean setSyncTaskNo(Integer taskNo) { | 
 |  |  |         this.shuttleProtocol.setSyncTaskNo(taskNo); | 
 |  |  |         return true; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public synchronized boolean setPakMk(boolean pakMk) { | 
 |  |  |         this.shuttleProtocol.setPakMk(pakMk); | 
 |  |  |         return true; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean enableMoveLoc(ShuttleMoveLocParam param, boolean enable) { | 
 |  |  |         if (enable) { | 
 |  |  |             shuttleProtocol.setMoveLoc(true);//开启跑库 | 
 |  |  |             shuttleProtocol.setMoveType(param.getMoveType()); | 
 |  |  |             shuttleProtocol.setXStart(param.getStartX()); | 
 |  |  |             shuttleProtocol.setXTarget(param.getTargetX()); | 
 |  |  |             shuttleProtocol.setXCurrent(param.getStartX()); | 
 |  |  |             shuttleProtocol.setYStart(param.getStartY()); | 
 |  |  |             shuttleProtocol.setYTarget(param.getTargetY()); | 
 |  |  |             shuttleProtocol.setYCurrent(param.getStartY()); | 
 |  |  |         }else { | 
 |  |  |             shuttleProtocol.setMoveLoc(false); | 
 |  |  |             shuttleProtocol.setMoveType(0); | 
 |  |  |             shuttleProtocol.setXStart(0); | 
 |  |  |             shuttleProtocol.setXTarget(0); | 
 |  |  |             shuttleProtocol.setXCurrent(0); | 
 |  |  |             shuttleProtocol.setYStart(0); | 
 |  |  |             shuttleProtocol.setYTarget(0); | 
 |  |  |             shuttleProtocol.setYCurrent(0); | 
 |  |  |         } | 
 |  |  |         return true; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public boolean requestWaiting() { | 
 |  |  |         if (this.shuttleProtocol.getProtocolStatusType().equals(ShuttleProtocolStatusType.IDLE)) { | 
 |  |  |             this.shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.WAITING); | 
 |  |  |             return true; | 
 |  |  |         } | 
 |  |  |         return false; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public ShuttleCommand getMoveCommand(Integer taskNo, String startCodeNum, String distCodeNum, Integer allDistance, Integer runDirection, Integer runSpeed, List<NavigateNode> nodes) { | 
 |  |  |         HashMap<String, Object> body = new HashMap<>(); | 
 |  |  |         body.put("messageName", "runOrder"); | 
 |  |  |         body.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); | 
 |  |  | 
 |  |  |         body.put("nodeY", loc.getBay()); | 
 |  |  |         body.put("nodeZ", loc.getLev()); | 
 |  |  |  | 
 |  |  |         //检测目标点是否为提升机 | 
 |  |  |         BasLiftService basLiftService = SpringUtils.getBean(BasLiftService.class); | 
 |  |  |         BasLift basLift = basLiftService.getOne(new LambdaQueryWrapper<BasLift>().eq(BasLift::getRow, loc.getRow()) | 
 |  |  |                 .eq(BasLift::getBay, loc.getBay()) | 
 |  |  |                 .eq(BasLift::getHostId, this.device.getHostId())); | 
 |  |  |         if (basLift != null) { | 
 |  |  |             LiftDispatcher liftDispatcher = SpringUtils.getBean(LiftDispatcher.class); | 
 |  |  |             Integer realLev = liftDispatcher.getLiftLevOffset(basLift.getDeviceId().intValue(), loc.getLev()); | 
 |  |  |             body.put("nodeZ", realLev); | 
 |  |  |         } | 
 |  |  |  | 
 |  |  |         ShuttleCommand command = new ShuttleCommand(); | 
 |  |  |         command.setShuttleNo(Integer.parseInt(this.device.getDeviceNo())); | 
 |  |  |         command.setBody(JSON.toJSONString(body)); | 
 |  |  |         command.setMode(ShuttleCommandModeType.MOVE.id); | 
 |  |  |         command.setTargetLocNo(loc.getLocNo()); | 
 |  |  |         command.setTaskNo(taskNo); | 
 |  |  |         return command; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  | 
 |  |  |         command.setShuttleNo(Integer.parseInt(this.device.getDeviceNo())); | 
 |  |  |         command.setBody(JSON.toJSONString(body)); | 
 |  |  |         command.setMode(lift ? ShuttleCommandModeType.PALLET_LIFT.id : ShuttleCommandModeType.PALLET_DOWN.id); | 
 |  |  |         command.setTaskNo(taskNo); | 
 |  |  |         return command; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  | 
 |  |  |         command.setShuttleNo(Integer.parseInt(this.device.getDeviceNo())); | 
 |  |  |         command.setBody(JSON.toJSONString(body)); | 
 |  |  |         command.setMode(charge ? ShuttleCommandModeType.CHARGE_OPEN.id : ShuttleCommandModeType.CHARGE_CLOSE.id); | 
 |  |  |         command.setTaskNo(taskNo); | 
 |  |  |         return command; | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     @Override | 
 |  |  |     public ShuttleCommand getUpdateLocationCommand(Integer taskNo, String locNo) { | 
 |  |  |         HashMap<String, Object> body = new HashMap<>(); | 
 |  |  |         body.put("messageName", "runOrder"); | 
 |  |  |         body.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); | 
 |  |  |         body.put("deviceNo", Integer.parseInt(this.device.getDeviceNo())); | 
 |  |  |  | 
 |  |  |         String coord = "(" + Utils.getRow(locNo) + "," + Utils.getBay(locNo) + "," + Utils.getLev(locNo) + ")"; | 
 |  |  |         body.put("coord", coord); | 
 |  |  |  | 
 |  |  |         ShuttleCommand command = new ShuttleCommand(); | 
 |  |  |         command.setShuttleNo(Integer.parseInt(this.device.getDeviceNo())); | 
 |  |  |         command.setBody(JSON.toJSONString(body)); | 
 |  |  |         command.setMode(ShuttleCommandModeType.UPDATE_LOCATION.id); | 
 |  |  |         command.setTaskNo(taskNo); | 
 |  |  |         return command; | 
 |  |  |     } | 
 |  |  |  |