package com.wcs.back.service.impl; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.wcs.back.domain.*; import com.wcs.back.service.IWcsService; import com.wcs.back.util.http.HttpUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * wcs回调Service * * @author zf * @date 2023/11/27 */ @Service public class WcsServiceImpl implements IWcsService { private static final Logger log = LoggerFactory.getLogger(WcsServiceImpl.class); @Value("${wms.httpUrl}") public String httpUrl; @Value("${wms.roboticArmUrl}") public String roboticArmUrl; @Value("${wms.ctuUrl}") public String ctuUrl; @Value("${wms.drumLineTaskHttpUrl}") public String drumLineTaskHttpUrl; /** * 普通搬运任务下发 * * @param json * @return */ @Override public WcsResult SetUp_Task(String json, HttpServletRequest request) throws JsonProcessingException { // 获取客户端IP地址 String clientIpAddress = getClientIpAddress(request); String url = "http://"+clientIpAddress+httpUrl; // 创建一个 ScheduledExecutorService 实例 ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2); ObjectMapper objectMapper = new ObjectMapper(); List agvSetUpTaskList = objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, AgvSetUpTask.class)); // 创建两个倒计时任务 // 1.30秒后回调取料成功 AgvSetUpTask agvSetUpTask = agvSetUpTaskList.get(0); // 2.60秒后回调已送达 AgvSetUpTask agvSetUpTask2 = agvSetUpTaskList.get(1); // 定义第一个任务,30秒后执行 Runnable task1 = () -> { // 回调1的具体逻辑 TaskCallBack taskCallBack = new TaskCallBack(); taskCallBack.setTaskNo(agvSetUpTask.getTaskNo()); taskCallBack.setTaskIndex(agvSetUpTask.getTaskIndex()); taskCallBack.setArmSite(agvSetUpTask.getArmSite()); taskCallBack.setActionType(agvSetUpTask.getActionType()); taskCallBack.setAgv(1); taskCallBack.setTaskState(2); taskCallBack.setExeAgv(1); sendHttpPost(taskCallBack, url); }; // 定义第二个任务,60秒后执行 Runnable task2 = () -> { // 任务2的具体逻辑 TaskCallBack taskCallBack2 = new TaskCallBack(); taskCallBack2.setTaskNo(agvSetUpTask2.getTaskNo()); taskCallBack2.setTaskIndex(agvSetUpTask2.getTaskIndex()); taskCallBack2.setArmSite(agvSetUpTask2.getArmSite()); taskCallBack2.setActionType(agvSetUpTask2.getActionType()); taskCallBack2.setAgv(1); taskCallBack2.setTaskState(3); taskCallBack2.setExeAgv(1); sendHttpPost(taskCallBack2, url); }; // 安排任务1,30秒后执行 scheduler.schedule(task1, 30, TimeUnit.SECONDS); // 安排任务2,60秒后执行 scheduler.schedule(task2, 60, TimeUnit.SECONDS); WcsResult wcsResult = new WcsResult(); wcsResult.setResultCode(1); wcsResult.setMessage("成功"); return wcsResult; } /** * 机械臂拆托任务下发 * * @param json * @param request * @return */ @Override public WcsResult Dismantling_Task(String json, HttpServletRequest request) throws JsonProcessingException { // 获取客户端IP地址 String clientIpAddress = getClientIpAddress(request); String url = "http://"+clientIpAddress+roboticArmUrl; // 滚筒url,已送达是滚筒返回 String gtUrl = "http://"+clientIpAddress+drumLineTaskHttpUrl; ObjectMapper objectMapper = new ObjectMapper(); RoboticArmTaskVo roboticArmTaskVo = objectMapper.readValue(json, RoboticArmTaskVo.class); List armSiteList = roboticArmTaskVo.getArmSiteList(); int size = armSiteList.size(); // 创建一个 ScheduledExecutorService 实例 ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2+(2*size)); // 创建倒计时任务 // 1.30秒后回调取料成功 // 2.60秒后,每隔10秒回调拆箱成功,如果全部拆箱完成,则过10秒回调拆托完成 // 3.等2的任务全部做完后,等待10秒,每隔10秒回调已送达(目的区域是20-分拣区) // 取料成功 Runnable task1 = () -> { // 回调1的具体逻辑 RoboticArmTaskBackVo roboticArmTaskBackVo = new RoboticArmTaskBackVo(); roboticArmTaskBackVo.setTaskNo(roboticArmTaskVo.getTaskNo()); roboticArmTaskBackVo.setTaskState("10"); roboticArmTaskBackVo.setRemark("取料成功!"); sendHttpPost(roboticArmTaskBackVo, url); }; // 30秒之后执行,取料成功 scheduler.schedule(task1, 30, TimeUnit.SECONDS); // 拆箱成功 Integer time = 60; for (RoboticArmTaskVo.DismantlingInfo dismantlingInfo : armSiteList){ Runnable taskSite = () -> { // 回调1的具体逻辑 RoboticArmTaskBackVo roboticArmTaskBackVo = new RoboticArmTaskBackVo(); roboticArmTaskBackVo.setTaskNo(roboticArmTaskVo.getTaskNo()); roboticArmTaskBackVo.setDisassemblyTaskNo(dismantlingInfo.getDisassemblyTaskNo()); // 料箱号只能模拟从wms调用空料箱 String materialBinId = HttpUtils.HttpPostWithJson("http://"+clientIpAddress+":50902/wcs/getEmptyPallet", ""); dismantlingInfo.setMaterialBinId(materialBinId); roboticArmTaskBackVo.setMaterialBinId(materialBinId); roboticArmTaskBackVo.setTaskState("20"); roboticArmTaskBackVo.setRemark("拆箱成功!"); sendHttpPost(roboticArmTaskBackVo, url); }; // 循环执行拆箱回调 scheduler.schedule(taskSite, time, TimeUnit.SECONDS); time += 10; } // 拆托成功,在全部拆箱完成之后执行 Runnable ctTask = () -> { // 回调1的具体逻辑 RoboticArmTaskBackVo roboticArmTaskBackVo = new RoboticArmTaskBackVo(); roboticArmTaskBackVo.setTaskNo(roboticArmTaskVo.getTaskNo()); roboticArmTaskBackVo.setTaskState("30"); roboticArmTaskBackVo.setRemark("拆托成功!"); sendHttpPost(roboticArmTaskBackVo, url); }; scheduler.schedule(ctTask, time, TimeUnit.SECONDS); // 送至分拣需要回调已送达 time += 10; for (RoboticArmTaskVo.DismantlingInfo dismantlingInfo : armSiteList){ if (dismantlingInfo.getDestinationArea().equals("20")){ Runnable taskSite = () -> { RoboticArmTaskBackVo roboticArmTaskBackVo = new RoboticArmTaskBackVo(); roboticArmTaskBackVo.setTaskNo(roboticArmTaskVo.getTaskNo()); roboticArmTaskBackVo.setDisassemblyTaskNo(dismantlingInfo.getDisassemblyTaskNo()); roboticArmTaskBackVo.setMaterialBinId(dismantlingInfo.getMaterialBinId()); roboticArmTaskBackVo.setTaskState("40"); roboticArmTaskBackVo.setRemark("已送达!"); sendHttpPost(roboticArmTaskBackVo, gtUrl); }; // 循环执行拆箱回调 scheduler.schedule(taskSite, time, TimeUnit.SECONDS); time += 10; } } WcsResult wcsResult = new WcsResult(); wcsResult.setResultCode(1); wcsResult.setMessage("成功"); return wcsResult; } /** * CTU任务下发 * * @param json * @param request * @return */ @Override public WcsResult SetUp_CTUTask(String json, HttpServletRequest request) throws JsonProcessingException { // 获取客户端IP地址 String clientIpAddress = getClientIpAddress(request); String url = "http://"+clientIpAddress+ctuUrl; ObjectMapper objectMapper = new ObjectMapper(); CTUTaskVo ctuTaskVo = objectMapper.readValue(json, CTUTaskVo.class); List siteList = ctuTaskVo.getSiteList(); int size = siteList.size(); // 创建一个 ScheduledExecutorService 实例 ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2*size); // 创建倒计时任务 // 循环取料成功 Integer time = 10; for (CTUTaskVo.Site site : siteList){ Runnable taskSite = () -> { CTUTaskBackVo ctuTaskBackVo = new CTUTaskBackVo(); ctuTaskBackVo.setTaskNo(ctuTaskVo.getTaskNo()); ctuTaskBackVo.setMaterialBinId(site.getMaterialBinId()); ctuTaskBackVo.setBizNo(site.getBizNo()); ctuTaskBackVo.setTaskState("10"); ctuTaskBackVo.setRemark("取料成功!"); sendHttpPost(ctuTaskBackVo, url); }; // 循环执行取料成功回调 scheduler.schedule(taskSite, time, TimeUnit.SECONDS); time += 10; } // 循环已送达 time += 20; for (CTUTaskVo.Site site : siteList){ Runnable taskSite = () -> { CTUTaskBackVo ctuTaskBackVo = new CTUTaskBackVo(); ctuTaskBackVo.setTaskNo(ctuTaskVo.getTaskNo()); ctuTaskBackVo.setMaterialBinId(site.getMaterialBinId()); ctuTaskBackVo.setBizNo(site.getBizNo()); ctuTaskBackVo.setTaskState("40"); ctuTaskBackVo.setRemark("已送达!"); sendHttpPost(ctuTaskBackVo, url); }; // 循环执行送达回调 scheduler.schedule(taskSite, time, TimeUnit.SECONDS); time += 10; } WcsResult wcsResult = new WcsResult(); wcsResult.setResultCode(1); wcsResult.setMessage("成功"); return wcsResult; } /** * 滚筒线任务下发 * * @param json * @param request * @return */ @Override public WcsResult DrumLine_Task(String json, HttpServletRequest request) throws JsonProcessingException { // 获取客户端IP地址 String clientIpAddress = getClientIpAddress(request); String url = "http://"+clientIpAddress+drumLineTaskHttpUrl; ObjectMapper objectMapper = new ObjectMapper(); DrumLineTaskVo drumLineTaskVo = objectMapper.readValue(json, DrumLineTaskVo.class); // 创建一个 ScheduledExecutorService 实例 ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); // 创建倒计时任务 Runnable task = () -> { DrumLineTaskBackVo drumLineTaskBackVo = new DrumLineTaskBackVo(); drumLineTaskBackVo.setTaskNo(drumLineTaskVo.getTaskNo()); drumLineTaskBackVo.setTaskState("40"); drumLineTaskBackVo.setMaterialBinId(drumLineTaskVo.getBusinessNo()); drumLineTaskBackVo.setRemark("已送达!"); sendHttpPost(drumLineTaskBackVo, url); }; // 30秒后执行已送达回调 scheduler.schedule(task, 30, TimeUnit.SECONDS); WcsResult wcsResult = new WcsResult(); wcsResult.setResultCode(1); wcsResult.setMessage("成功"); return wcsResult; } /** * 指令下发 * * @param json * @param request * @return */ @Override public WcsResult Directives(String json, HttpServletRequest request) throws JsonProcessingException { // 获取客户端IP地址 String clientIpAddress = getClientIpAddress(request); // 创建一个 ScheduledExecutorService 实例 ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); ObjectMapper objectMapper = new ObjectMapper(); DirectivesVo directivesVo = objectMapper.readValue(json, DirectivesVo.class); WcsResult wcsResult = new WcsResult(); wcsResult.setResultCode(1); wcsResult.setMessage("成功"); return wcsResult; } /** * 获取重量 * * @param rollerID * @return */ @Override public WcsResult2 GetWeight(String rollerID) { WcsResult2 wcsResult2 = new WcsResult2(); wcsResult2.setCode(1); wcsResult2.setState(true); wcsResult2.setMessage(""); wcsResult2.setDataInfo(100); return wcsResult2; } /** * 获取滚筒线信息 * * @return */ @Override public WcsResult2 GetRollerInfo() { WcsResult2 wcsResult2 = new WcsResult2(); wcsResult2.setCode(1); wcsResult2.setState(true); wcsResult2.setMessage(""); List rollerInfoVos = new ArrayList<>(); RollerInfoVo rollerInfoVo = new RollerInfoVo(); rollerInfoVo.setRollerID("1"); rollerInfoVo.setConnectState(true); rollerInfoVo.setMode(1); rollerInfoVo.setInOutStatus(2); rollerInfoVo.setNumber(0); rollerInfoVo.setEStopStatus(1); rollerInfoVo.setFaultStatus(1); rollerInfoVos.add(rollerInfoVo); wcsResult2.setDataInfo(rollerInfoVos); return wcsResult2; } // 发送 HTTP POST 请求 private WcsResult sendHttpPost(T taskCallBack, String url) { String jsonString = JSON.toJSONString(taskCallBack); String sendPost = HttpUtils.HttpPostWithJson(url, jsonString); WcsResult agvResult = JSONObject.parseObject(sendPost, WcsResult.class); // 处理回调结果,根据具体逻辑设置 log.info("请求json:"+jsonString); log.info("响应json:"+agvResult.toString()); return agvResult; } // 获取请求端ip地址 private String getClientIpAddress(HttpServletRequest request) { String xForwardedForHeader = request.getHeader("X-Forwarded-For"); if (xForwardedForHeader == null) { return request.getRemoteAddr(); } // 如果使用了代理服务器,X-Forwarded-For头部可以包含多个IP地址,从左到右是从原始客户端到最近的代理服务器 // 这里简单地取第一个IP地址作为客户端IP地址 return xForwardedForHeader.split(",")[0].trim(); } }