package com.zy.asrs.service.impl; import com.alibaba.excel.util.StringUtils; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.core.common.Cools; import com.core.common.R; import com.zy.asrs.entity.*; import com.zy.asrs.enums.RcsRetMethodEnum; import com.zy.asrs.service.RcsService; import com.zy.asrs.service.TaskService; import com.zy.core.cache.MessageQueue; import com.zy.core.cache.SlaveConnection; import com.zy.core.enums.SlaveType; import com.zy.core.model.Task; import com.zy.core.model.protocol.StaProtocol; import com.zy.core.thread.SiemensDevpThread; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @Slf4j @Service public class RcsServiceImpl implements RcsService { // 海康RCS地址 @Value("${hik.url}") private String HIK_URL; @Autowired private TaskService taskService; /** * 2.2.1任务执行回馈 * 厂家:海量、华晓 * * @param rcsReporterTask * @return */ @Override public RcsReturn reporterTask(RcsReporterTask rcsReporterTask) { RcsReturn rcsReturn = new RcsReturn(); String robotTaskCode = rcsReporterTask.getRobotTaskCode(); String singleRobotCode = rcsReporterTask.getSingleRobotCode(); String[] split = robotTaskCode.split("-"); robotTaskCode = split[0]; JSONObject values = rcsReporterTask.getExtra().getJSONObject("values"); // start : 任务开始;outbin : 走出储位;end : 任务完成 String method = values.getString("method"); String carrierType = values.getString("carrierType"); String slotCategory = values.getString("slotCategory"); String slotCode = values.getString("slotCode"); EntityWrapper wrapper = new EntityWrapper<>(); wrapper.eq("task_no", robotTaskCode); AgvTask task = taskService.selectOne(wrapper); if(!Cools.isEmpty(task)){ try { // q3,q8=1 if ("1".equals(carrierType)) { //AGV switch (Objects.requireNonNull(RcsRetMethodEnum.getEnum(method))) { //放货申请 case APPLY_PUT: { Integer sourceStaNo = Integer.valueOf(task.getStaNo()); SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); StaProtocol staProtocol = siemensDevpThread.getStation().get(sourceStaNo).clone(); //wcs反馈rcs继续执行 if (staProtocol != null && !staProtocol.isLoading() && !staProtocol.isEmptyOutType()) { RcsTaskContinue rcsTaskContinue = new RcsTaskContinue(); rcsTaskContinue.setRobotTaskCode(task.getTaskNo()); rcsTaskContinue.setTriggerType("TASK"); rcsTaskContinue.setTriggerCode(task.getTaskNo()); String url =HIK_URL + "api/robot/controller/task/extend/continue"; String response = sendPost(url, JSONObject.toJSONString(rcsTaskContinue)); if (!StringUtils.isEmpty(response) && response.contains("code")){ RcsReturn rcsReturn1 = JSONObject.parseObject(response, RcsReturn.class); if("200".equals(rcsReturn1.getCode())) { //出发PLC站点的扫码器扫码 boolean result = MessageQueue.offer(SlaveType.Devp, 1, new com.zy.core.model.Task(3, staProtocol)); log.info("AGV放货完成,给站点写9991工作号,下发任务:{},站点:{},agv任务号:{}",result,task.getStaNo(),task.getTaskNo()); if (result) { // 返回RCS rcsReturn.setCode("SUCCESS"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); }else { // 返回RCS rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } } } } } break; //放货完成 --》agv已经离开 case TASK_END: { Integer sourceStaNo = Integer.valueOf(task.getStaNo()); SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); StaProtocol staProtocol = siemensDevpThread.getStation().get(sourceStaNo).clone(); //放货完成 --》agv已经离开 --》给PLC站点写9991工作号 if (staProtocol != null && staProtocol.isLoading() && staProtocol.isEmptyOutType() && staProtocol.getWorkNo() ==0) { staProtocol.setWorkNo((short) 9991); staProtocol.setStaNo(Short.valueOf(task.getStaNo())); boolean result = MessageQueue.offer(SlaveType.Devp, 1, new com.zy.core.model.Task(2, staProtocol)); log.info("AGV放货完成,给站点写9991工作号,下发任务:{},站点:{},agv任务号:{}",result,task.getStaNo(),task.getTaskNo()); if(result){ // 更新任务状态等内部逻辑 task.setWrkSts(304L); // 301 任务下发、302 任务执行、303 任务中断、304 任务结束 task.setModiTime(new Date()); taskService.updateById(task); // 返回RCS rcsReturn.setCode("SUCCESS"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); }else { // 返回RCS rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } } } break; //rcs请求wms取货申请 case APPLY_PICK: { Integer sourceStaNo = Integer.valueOf(task.getSourceStaNo()); SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); StaProtocol staProtocol = siemensDevpThread.getStation().get(sourceStaNo).clone(); //判断站点是否有料架和托盘 if (staProtocol != null && staProtocol.isLoading() && staProtocol.isEmptyOutType() && staProtocol.getWorkNo() >0 && staProtocol.getWorkNo() <9990) { RcsTaskContinue rcsTaskContinue = new RcsTaskContinue(); rcsTaskContinue.setRobotTaskCode(task.getTaskNo()); rcsTaskContinue.setTriggerType("TASK"); rcsTaskContinue.setTriggerCode(task.getTaskNo()); String url =HIK_URL + "api/robot/controller/task/extend/continue"; String response = sendPost(url, JSONObject.toJSONString(rcsTaskContinue)); if (!StringUtils.isEmpty(response) && response.contains("code")){ RcsReturn rcsReturn1 = JSONObject.parseObject(response, RcsReturn.class); if("200".equals(rcsReturn1.getCode())) { // 返回RCS rcsReturn.setCode("SUCCESS"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); }else { // 返回RCS rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } } } } break; //rcs取货完成,已退出输送线 case PICK_COMPLETE: { Integer sourceStaNo = Integer.valueOf(task.getSourceStaNo()); SiemensDevpThread siemensDevpThread = (SiemensDevpThread) SlaveConnection.get(SlaveType.Devp, 1); StaProtocol staProtocol = siemensDevpThread.getStation().get(sourceStaNo).clone(); //放货完成 --》agv已经离开 --》给PLC站点写9991工作号 if (staProtocol != null && !staProtocol.isLoading() && !staProtocol.isEmptyOutType() && staProtocol.getWorkNo() >0 && staProtocol.getWorkNo() <9990) { staProtocol.setWorkNo((short) 0); staProtocol.setStaNo((short) 0); boolean result = MessageQueue.offer(SlaveType.Devp, 1, new com.zy.core.model.Task(2, staProtocol)); log.info("AGV取货完成,给站点写0工作号,下发任务:{},站点:{},agv任务号:{}",result,task.getStaNo(),task.getTaskNo()); if(result){ // 返回RCS rcsReturn.setCode("SUCCESS"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); }else { // 返回RCS rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage(""); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } } } break; default: { } break; } } } catch (Exception e) { log.error("RCS反馈任务进度处理异常 - {}", rcsReporterTask, e); rcsReturn.setCode("Err_Internal"); rcsReturn.setMessage("内部处理异常"); JSONObject data = new JSONObject(); data.put("robotTaskCode", robotTaskCode); rcsReturn.setData(data); } } return rcsReturn; } /** * 向指定 URL 发送POST方法的请求 * * @param url 发送请求的 URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; StringBuilder result = new StringBuilder(); try { log.info("sendPost - {} - {}", url, param); URL realUrl = new URL(url); URLConnection conn = realUrl.openConnection(); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("Content-Length", ""); conn.setRequestProperty("Host", ""); conn.setRequestProperty("Accept", "*/*"); conn.setRequestProperty("Accept-Encoding", "gzip, deflate, br"); conn.setRequestProperty("Connection", "keep-alive"); conn.setRequestProperty("X-lr-request-id", String.valueOf(new Date().getTime())); conn.setRequestProperty("X-lr-version", "4.3"); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); conn.setDoOutput(true); conn.setDoInput(true); out = new PrintWriter(conn.getOutputStream()); out.print(param); out.flush(); in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)); String line; while ((line = in.readLine()) != null) { result.append(line); } log.info("recv - {}", result); } catch (ConnectException e) { log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e); } catch (SocketTimeoutException e) { log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e); } catch (IOException e) { log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e); } catch (Exception e) { log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e); } finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { log.error("调用in.close Exception, url=" + url + ",param=" + param, ex); } } return result.toString(); } }