|  |  |  | 
|---|
|  |  |  | 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.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.command.ShuttleRedisCommand; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.model.enums.*; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.service.BasShuttleService; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.service.LocService; | 
|---|
|  |  |  | 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.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.service.DeviceDataLogService; | 
|---|
|  |  |  | 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.Date; | 
|---|
|  |  |  | import java.util.HashMap; | 
|---|
|  |  |  | import java.util.*; | 
|---|
|  |  |  | import java.util.concurrent.TimeUnit; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Slf4j | 
|---|
|  |  |  | @SuppressWarnings("all") | 
|---|
|  |  |  | 
|---|
|  |  |  | shuttleProtocol.setShuttleNo(Integer.valueOf(device.getDeviceNo())); | 
|---|
|  |  |  | shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE); | 
|---|
|  |  |  | shuttleProtocol.setDevice(device); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | InnerSuhttleExtend extend = new InnerSuhttleExtend(); | 
|---|
|  |  |  | shuttleProtocol.setExtend(extend); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //----------读取四向穿梭车状态----------- | 
|---|
|  |  |  | //小车设备状态 | 
|---|
|  |  |  | 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.setErrorCode(deviceStatus == 6 ? "1" : "0"); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //是否顶升 | 
|---|
|  |  |  | shuttleProtocol.setHasLift(data.getInteger("palletStatus") == 1 ? true : false); | 
|---|
|  |  |  | //是否有托盘 | 
|---|
|  |  |  | shuttleProtocol.setHasPallet(data.getInteger("hasPallet") != 2 ? true : false); | 
|---|
|  |  |  | shuttleProtocol.setHasPallet(data.getInteger("hasPallet") == null ? true : data.getInteger("hasPallet") != 2 ? true : false); | 
|---|
|  |  |  | //行驶方向 | 
|---|
|  |  |  | shuttleProtocol.setRunDirection(data.getString("direction") == null ? "none" : data.getString("direction")); | 
|---|
|  |  |  | //是否为充电状态 | 
|---|
|  |  |  | shuttleProtocol.setHasCharge((deviceStatus == 5 || deviceStatus == 13) ? true : false); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //*********读取扩展字段********** | 
|---|
|  |  |  | InnerSuhttleExtend extend = (InnerSuhttleExtend) shuttleProtocol.getExtend(); | 
|---|
|  |  |  | extend.setMapVersion(data.getString("version"));//地图版本 | 
|---|
|  |  |  | extend.setStatusDescription(data.getString("statusDescription"));//状态描述 | 
|---|
|  |  |  | shuttleProtocol.setExtend(extend);//扩展字段 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //最近一次在线时间 | 
|---|
|  |  |  | shuttleProtocol.setLastOnlineTime(System.currentTimeMillis()); | 
|---|
|  |  |  | ///读取四向穿梭车状态-end | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //                //小车处于忙碌状态,将标记置为true | 
|---|
|  |  |  | //                if (shuttleProtocol.getDeviceStatusType() == ShuttleDeviceStatusType.BUSY) { | 
|---|
|  |  |  | //                    shuttleProtocol.setPakMk(true); | 
|---|
|  |  |  | //                } | 
|---|
|  |  |  | // | 
|---|
|  |  |  | //                if (shuttleProtocol.getProtocolStatusType() == null && shuttleProtocol.getDeviceStatus().intValue() == ShuttleDeviceStatusType.IDLE.id) { | 
|---|
|  |  |  | //                    //小车空闲状态、小车任务状态为未知,认定曾离线过,需要复位成空闲 | 
|---|
|  |  |  | //                    shuttleProtocol.setProtocolStatusType(ShuttleProtocolStatusType.IDLE); | 
|---|
|  |  |  | //                } | 
|---|
|  |  |  | //小车处于忙碌状态,将标记置为true | 
|---|
|  |  |  | if (deviceStatus == 1 || deviceStatus == 2 || deviceStatus == 5) { | 
|---|
|  |  |  | shuttleProtocol.setPakMk(true); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //                if (System.currentTimeMillis() - shuttleProtocol.getDeviceDataLog() > 1000 * 5) { | 
|---|
|  |  |  | //                    //采集时间超过5s,保存一次数据记录 | 
|---|
|  |  |  | //                    //保存数据记录 | 
|---|
|  |  |  | //                    DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class); | 
|---|
|  |  |  | //                    DeviceDataLog deviceDataLog = new DeviceDataLog(); | 
|---|
|  |  |  | //                    deviceDataLog.setOriginData(Base64.getEncoder().encodeToString(result.Content)); | 
|---|
|  |  |  | //                    deviceDataLog.setWcsData(JSON.toJSONString(shuttleProtocol)); | 
|---|
|  |  |  | //                    deviceDataLog.setType("shuttle"); | 
|---|
|  |  |  | //                    deviceDataLog.setDeviceNo(shuttleProtocol.getShuttleNo().intValue()); | 
|---|
|  |  |  | //                    deviceDataLog.setCreateTime(new Date()); | 
|---|
|  |  |  | //                    deviceDataLogService.insert(deviceDataLog); | 
|---|
|  |  |  | // | 
|---|
|  |  |  | //                    //更新采集时间 | 
|---|
|  |  |  | //                    shuttleProtocol.setDeviceDataLog(System.currentTimeMillis()); | 
|---|
|  |  |  | //                } | 
|---|
|  |  |  | if (shuttleProtocol.getProtocolStatusType() == null && shuttleProtocol.getDeviceStatus().intValue() == 3) { | 
|---|
|  |  |  | //小车空闲状态、小车任务状态为未知,认定曾离线过,需要复位成空闲 | 
|---|
|  |  |  | shuttleProtocol.setProtocolStatusType(ShuttleProtocolStatusType.IDLE); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (System.currentTimeMillis() - shuttleProtocol.getDeviceDataLog() > 1000 * 5) { | 
|---|
|  |  |  | //采集时间超过5s,保存一次数据记录 | 
|---|
|  |  |  | //保存数据记录 | 
|---|
|  |  |  | DeviceDataLogService deviceDataLogService = SpringUtils.getBean(DeviceDataLogService.class); | 
|---|
|  |  |  | DeviceDataLog deviceDataLog = new DeviceDataLog(); | 
|---|
|  |  |  | deviceDataLog.setOriginData(JSON.toJSONString(data)); | 
|---|
|  |  |  | deviceDataLog.setWcsData(JSON.toJSONString(shuttleProtocol)); | 
|---|
|  |  |  | deviceDataLog.setType(String.valueOf(SlaveType.Shuttle)); | 
|---|
|  |  |  | deviceDataLog.setDeviceNo(String.valueOf(shuttleProtocol.getShuttleNo())); | 
|---|
|  |  |  | deviceDataLog.setCreateTime(new Date()); | 
|---|
|  |  |  | deviceDataLog.setHostId(device.getHostId()); | 
|---|
|  |  |  | deviceDataLogService.save(deviceDataLog); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //更新采集时间 | 
|---|
|  |  |  | 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()); | 
|---|
|  |  |  | 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())); | 
|---|
|  |  |  | throw new CoolException(MessageFormat.format("读取四向穿梭车状态信息失败 ===>> [id:{0}] [ip:{1}] [port:{2}]", device.getDeviceNo(), device.getIp(), device.getPort())); | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public ShuttleProtocol getStatus() { | 
|---|
|  |  |  | return this.shuttleProtocol; | 
|---|
|  |  |  | if (this.shuttleProtocol == null) { | 
|---|
|  |  |  | return null; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return this.shuttleProtocol.clone(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public synchronized boolean movePath() { | 
|---|
|  |  |  | public synchronized boolean movePath(List<NavigateNode> nodes, Integer taskNo) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | String loginToken = requestLoginToken(); | 
|---|
|  |  |  | if (loginToken == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | HashMap<String, Object> headers = new HashMap<>(); | 
|---|
|  |  |  | headers.put("Authorization", "Bearer " + loginToken); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ArrayList<HashMap<String, Object>> modes = new ArrayList<>(); | 
|---|
|  |  |  | //获取分段路径 | 
|---|
|  |  |  | 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 = sectionNodes.get(0); | 
|---|
|  |  |  | //结束路径 | 
|---|
|  |  |  | NavigateNode targetPath = sectionNodes.get(sectionNodes.size() - 1); | 
|---|
|  |  |  | if (ShuttleRunDirection.get(startPath.getDirection()) == ShuttleRunDirection.LEFT | 
|---|
|  |  |  | || ShuttleRunDirection.get(startPath.getDirection()) == ShuttleRunDirection.RIGHT) { | 
|---|
|  |  |  | //母轨方向 | 
|---|
|  |  |  | oper = 5; | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | //子轨方向 | 
|---|
|  |  |  | oper = 6; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 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("nodeX", node.getX()); | 
|---|
|  |  |  | map.put("nodeY", node.getY()); | 
|---|
|  |  |  | map.put("nodeZ", node.getZ()); | 
|---|
|  |  |  | if (flag) { | 
|---|
|  |  |  | map.put("oper", oper); | 
|---|
|  |  |  | flag = false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | modes.add(map); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | HashMap<String, Object> param = new HashMap<>(); | 
|---|
|  |  |  | param.put("messageName", "runRoute"); | 
|---|
|  |  |  | param.put("msgTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())); | 
|---|
|  |  |  | param.put("deviceNo", device.getDeviceNo()); | 
|---|
|  |  |  | param.put("taskId", taskNo); | 
|---|
|  |  |  | param.put("nodeNum", nodes.size()); | 
|---|
|  |  |  | param.put("modes", modes); | 
|---|
|  |  |  | String response = 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); | 
|---|
|  |  |  | Integer code = jsonObject.getInteger("code"); | 
|---|
|  |  |  | if (code.equals(200)) { | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public synchronized boolean move() { | 
|---|
|  |  |  | public synchronized boolean move(ShuttleCommand command) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | String loginToken = requestLoginToken(); | 
|---|
|  |  |  | if (loginToken == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | HashMap<String, Object> headers = new HashMap<>(); | 
|---|
|  |  |  | headers.put("Authorization", "Bearer " + loginToken); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String response = 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); | 
|---|
|  |  |  | Integer code = jsonObject.getInteger("code"); | 
|---|
|  |  |  | if (code.equals(200)) { | 
|---|
|  |  |  | this.shuttleProtocol.setSendTime(System.currentTimeMillis());//指令下发时间 | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public synchronized boolean lift() { | 
|---|
|  |  |  | public synchronized boolean lift(ShuttleCommand command) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | String loginToken = requestLoginToken(); | 
|---|
|  |  |  | if (loginToken == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | HashMap<String, Object> headers = new HashMap<>(); | 
|---|
|  |  |  | headers.put("Authorization", "Bearer " + loginToken); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String response = 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); | 
|---|
|  |  |  | Integer code = jsonObject.getInteger("code"); | 
|---|
|  |  |  | if (code.equals(200)) { | 
|---|
|  |  |  | this.shuttleProtocol.setSendTime(System.currentTimeMillis());//指令下发时间 | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public synchronized boolean charge(ShuttleCommand command) { | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | String loginToken = requestLoginToken(); | 
|---|
|  |  |  | if (loginToken == null) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | HashMap<String, Object> headers = new HashMap<>(); | 
|---|
|  |  |  | headers.put("Authorization", "Bearer " + loginToken); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | String response = 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); | 
|---|
|  |  |  | Integer code = jsonObject.getInteger("code"); | 
|---|
|  |  |  | if (code.equals(200)) { | 
|---|
|  |  |  | this.shuttleProtocol.setSendTime(System.currentTimeMillis());//指令下发时间 | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | e.printStackTrace(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public synchronized boolean reset(ShuttleCommand command) { | 
|---|
|  |  |  | this.shuttleProtocol.setTaskNo(0); | 
|---|
|  |  |  | this.shuttleProtocol.setProtocolStatus(ShuttleProtocolStatusType.IDLE); | 
|---|
|  |  |  | return true; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public boolean isIdle() { | 
|---|
|  |  |  | return this.isIdle(null); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public boolean isIdle(ExecuteSupport support) { | 
|---|
|  |  |  | if (null != support) { | 
|---|
|  |  |  | if (!support.judgement()) { | 
|---|
|  |  |  | return false; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|
|  |  |  | 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.getDeviceStatus() == 11) | 
|---|
|  |  |  | && this.shuttleProtocol.getPakMk() | 
|---|
|  |  |  | && this.shuttleProtocol.getErrorCode().equals("0") | 
|---|
|  |  |  | && (this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.IDLE.id || this.shuttleProtocol.getProtocolStatus() == ShuttleProtocolStatusType.WAITING.id) | 
|---|
|  |  |  | ; | 
|---|
|  |  |  | return res; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public boolean isDeviceIdle() { | 
|---|
|  |  |  | 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 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.getById(this.device.getDeviceNo()); | 
|---|
|  |  |  | 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 | 
|---|
|  |  |  | 
|---|
|  |  |  | return command; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public ShuttleCommand getLiftCommand(Integer taskNo, Boolean lift) { | 
|---|
|  |  |  | HashMap<String, Object> body = new HashMap<>(); | 
|---|
|  |  |  | body.put("messageName", "actionOrder"); | 
|---|
|  |  |  | 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("action", lift ? 1 : 2); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ShuttleCommand command = new ShuttleCommand(); | 
|---|
|  |  |  | command.setShuttleNo(Integer.parseInt(this.device.getDeviceNo())); | 
|---|
|  |  |  | command.setBody(JSON.toJSONString(body)); | 
|---|
|  |  |  | command.setMode(lift ? ShuttleCommandModeType.PALLET_LIFT.id : ShuttleCommandModeType.PALLET_DOWN.id); | 
|---|
|  |  |  | return command; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Override | 
|---|
|  |  |  | public ShuttleCommand getChargeCommand(Integer taskNo, Boolean charge) { | 
|---|
|  |  |  | 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())); | 
|---|
|  |  |  | body.put("taskId", taskNo); | 
|---|
|  |  |  | body.put("action", charge ? 3 : 4); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ShuttleCommand command = new ShuttleCommand(); | 
|---|
|  |  |  | command.setShuttleNo(Integer.parseInt(this.device.getDeviceNo())); | 
|---|
|  |  |  | command.setBody(JSON.toJSONString(body)); | 
|---|
|  |  |  | command.setMode(charge ? ShuttleCommandModeType.CHARGE_OPEN.id : ShuttleCommandModeType.CHARGE_CLOSE.id); | 
|---|
|  |  |  | return command; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //***************设备层通讯-不同厂商设备通讯方案不一致*************** | 
|---|
|  |  |  |  | 
|---|
|  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return null; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Data | 
|---|
|  |  |  | private class InnerSuhttleExtend { | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 地图版本 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private String mapVersion; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 状态描述 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private String statusDescription; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } | 
|---|