Jelajahi Sumber

海康agv任务参数调整及主动查询任务状态并更新任务

yejian 2 tahun lalu
induk
melakukan
2c89748653

+ 5 - 0
imcs-admin-boot/imcs-business-biz/src/main/java/com/github/zuihou/business/externalApi/service/AgvHikOrderInfoService.java

@@ -52,4 +52,9 @@ public interface AgvHikOrderInfoService extends SuperCacheService<AgvHikOrderInf
 
 
     R query3dResouceDataInfo(Map<String, String> data);
+
+    /**
+     * 查询海康任务接口,如果有任务取消的主动标记任务不成功
+     */
+    R execSynHikAgvTaskInfo();
 }

+ 138 - 31
imcs-admin-boot/imcs-business-biz/src/main/java/com/github/zuihou/business/externalApi/service/impl/AgvHikOrderInfoServiceImpl.java

@@ -3,6 +3,7 @@ package com.github.zuihou.business.externalApi.service.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.date.DatePattern;
 import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -22,7 +23,9 @@ import com.github.zuihou.common.constant.ParameterKey;
 import com.github.zuihou.common.util.UniqueKeyGenerator;
 import com.github.zuihou.context.BaseContextHandler;
 import com.github.zuihou.database.mybatis.auth.DataScope;
+import com.github.zuihou.database.mybatis.conditions.Wraps;
 import com.github.zuihou.database.mybatis.conditions.query.LbqWrapper;
+import com.github.zuihou.tenant.entity.Productionresource;
 import com.github.zuihou.utils.BeanPlusUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
@@ -40,6 +43,7 @@ import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * <p>
@@ -91,6 +95,8 @@ public class AgvHikOrderInfoServiceImpl extends SuperCacheServiceImpl<AgvHikOrde
         }
     };
 
+    private static Boolean agvTaskQuartzFlag = true;
+
     @Override
     public IPage<AgvHikOrderInfo> pageList(IPage<AgvHikOrderInfo> page, String orderName, String orderNo, String partName, String partNo, String createTime, LbqWrapper<AgvHikOrderInfo> wrapper){
         return baseMapper.pageList(page,orderName,orderNo,partName, partNo,createTime, wrapper, new DataScope());
@@ -125,7 +131,7 @@ public class AgvHikOrderInfoServiceImpl extends SuperCacheServiceImpl<AgvHikOrde
         if(null==redisTemplate.opsForValue().get(ParameterKey.ADDTASK)){
             addAgvTaskUrl = parameterService.getValue(ParameterKey.ADDTASK, null);
             if(StringUtils.isEmpty(addAgvTaskUrl)){
-                ret = R.fail("agv任务创建地址未配置");
+                return R.fail("agv任务创建地址未配置");
             }else{
                 redisTemplate.opsForValue().set(ParameterKey.ADDTASK,addAgvTaskUrl);
             }
@@ -166,9 +172,13 @@ public class AgvHikOrderInfoServiceImpl extends SuperCacheServiceImpl<AgvHikOrde
         positionCodePath.add(0,begin);
         positionCodePath.add(1,end);
         jsonObject.put("reqCode",reqCode);
-        jsonObject.put("taskTyp","F01");
+        jsonObject.put("taskTyp","YJTASK");
         jsonObject.put("positionCodePath",positionCodePath.toJSONString());
+        jsonObject.put("priority","1");
+        jsonObject.put("podDir","0");
+        jsonObject.put("podTyp","01");
         jsonObject.put("taskCode",taskCode);
+
         HttpEntity<String> addAgvTaskRequest = new HttpEntity<String>(jsonObject.toJSONString(), headers);
 
         String agvCallbackUrl = (null == msgUtil.redis_get(ParameterKey.PARAMETERS)? "": ((Map<String,String>)msgUtil.redis_get(ParameterKey.PARAMETERS)).get(ParameterKey.AGVCALLBACKURL).toString());
@@ -233,35 +243,35 @@ public class AgvHikOrderInfoServiceImpl extends SuperCacheServiceImpl<AgvHikOrde
         HttpHeaders headers = new HttpHeaders();
         headers.setContentType(MediaType.APPLICATION_JSON);
         // TODO 后续联调真实对接
-//        HttpEntity<String> agvStatusRequest = new HttpEntity<String>(jsonObject.toJSONString(), headers);
-//        ResponseEntity<String> agvStatusEntity = restTemplate.postForEntity(agvStatusUrl, agvStatusRequest, String.class);
-//
-//        String retData = agvStatusEntity.getBody();
-        String retData = "{\n" +
-                "    \"code\": \"0\",\n" +
-                "    \"data\": [\n" +
-                "        {\n" +
-                "            \"robotCode\": \"10001\",\n" +
-                "            \"status\": \"1\"\n" +
-                "        },\n" +
-                "        {\n" +
-                "            \"robotCode\": \"10002\",\n" +
-                "            \"status\": \"2\"\n" +
-                "        },\n" +
-                "        {\n" +
-                "            \"robotCode\": \"10003\",\n" +
-                "            \"status\": \"4\"\n" +
-                "        },\n" +
-                "        {\n" +
-                "            \"robotCode\": \"10004\",\n" +
-                "            \"status\": \"5\"\n" +
-                "        },\n" +
-                "        {\n" +
-                "            \"robotCode\": \"10005\",\n" +
-                "            \"status\": \"7\"\n" +
-                "        }\n" +
-                "    ]\n" +
-                "}";
+        HttpEntity<String> agvStatusRequest = new HttpEntity<String>(jsonObject.toJSONString(), headers);
+        ResponseEntity<String> agvStatusEntity = restTemplate.postForEntity(agvStatusUrl, agvStatusRequest, String.class);
+
+        String retData = agvStatusEntity.getBody();
+//        String retData = "{\n" +
+//                "    \"code\": \"0\",\n" +
+//                "    \"data\": [\n" +
+//                "        {\n" +
+//                "            \"robotCode\": \"10001\",\n" +
+//                "            \"status\": \"1\"\n" +
+//                "        },\n" +
+//                "        {\n" +
+//                "            \"robotCode\": \"10002\",\n" +
+//                "            \"status\": \"2\"\n" +
+//                "        },\n" +
+//                "        {\n" +
+//                "            \"robotCode\": \"10003\",\n" +
+//                "            \"status\": \"4\"\n" +
+//                "        },\n" +
+//                "        {\n" +
+//                "            \"robotCode\": \"10004\",\n" +
+//                "            \"status\": \"5\"\n" +
+//                "        },\n" +
+//                "        {\n" +
+//                "            \"robotCode\": \"10005\",\n" +
+//                "            \"status\": \"7\"\n" +
+//                "        }\n" +
+//                "    ]\n" +
+//                "}";
         log.info("agvStatus = {}",retData);
 
         JSONObject retObj = JSONObject.parseObject(retData);
@@ -318,4 +328,101 @@ public class AgvHikOrderInfoServiceImpl extends SuperCacheServiceImpl<AgvHikOrde
         }
         return R.success(retData);
     }
+
+    @Override
+    public R execSynHikAgvTaskInfo() {
+        try{
+            if(agvTaskQuartzFlag){
+                agvTaskQuartzFlag = false;
+                // 先查询agv任务中未完成的任务
+                List<AgvHikOrderDetailInfo> agvHikOrderDetailInfos = agvHikOrderDetailInfoService.list(Wraps.<AgvHikOrderDetailInfo>lbQ().isNull(AgvHikOrderDetailInfo::getMethod).or().eq(AgvHikOrderDetailInfo::getMethod,"start").or().eq(AgvHikOrderDetailInfo::getMethod,"outbin"));
+                List<String> taskCodes = agvHikOrderDetailInfos.stream().map(p -> p.getTaskCode()).collect(Collectors.toList());
+                // 根据任务编号查询agv任务状态,如果是取消的更新agv任务失败并告警人工介入
+                // 组装请求参数报文
+                String agvTaskStatusUrl = "";
+                if(null==redisTemplate.opsForValue().get(ParameterKey.GET_AGV_TASK_STATUS)){
+                    agvTaskStatusUrl = parameterService.getValue(ParameterKey.GET_AGV_TASK_STATUS, null);
+                    if(StringUtils.isEmpty(agvTaskStatusUrl)){
+                        return R.fail("agv任务状态查询地址未配置");
+                    }else{
+                        redisTemplate.opsForValue().set(ParameterKey.GET_AGV_TASK_STATUS,agvTaskStatusUrl);
+                    }
+                }else{
+                    agvTaskStatusUrl = (String)redisTemplate.opsForValue().get(ParameterKey.GET_AGV_TASK_STATUS);
+                }
+                String reqCode = UniqueKeyGenerator.getUniqueKeyStartWithTimestamp(32);
+                String reqTime = DateUtil.format(Calendar.getInstance().getTime(), DatePattern.NORM_DATETIME_MS_PATTERN);
+                JSONObject jsonObject = new JSONObject();
+                jsonObject.put("reqCode",reqCode);
+                jsonObject.put("reqTime",reqTime);
+                jsonObject.put("taskCodes", JSONArray.parseArray(JSON.toJSONString(taskCodes)));
+
+                HttpHeaders headers = new HttpHeaders();
+                headers.setContentType(MediaType.APPLICATION_JSON);
+                HttpEntity<String> agvStatusRequest = new HttpEntity<String>(jsonObject.toJSONString(), headers);
+                ResponseEntity<String> agvStatusEntity = restTemplate.postForEntity(agvTaskStatusUrl, agvStatusRequest, String.class);
+
+                String retData = agvStatusEntity.getBody();
+
+                log.info("agvTaskStatus = {}",retData);
+
+                JSONObject retObj = JSONObject.parseObject(retData);
+                if("0".equals(retObj.getString("code"))){
+                    JSONArray retAgvTaskStatusArray = retObj.getJSONArray("data");
+                    for(int i = 0; i < retAgvTaskStatusArray.size(); i++){
+                        JSONObject retAgvTaskStatus = retAgvTaskStatusArray.getJSONObject(i);
+                        String taskCode = retAgvTaskStatus.getString("taskCode");
+                        String taskStatus = retAgvTaskStatus.getString("taskStatus");
+                        // 取消任务
+                        if("5".equals(taskStatus) || "10".equals(taskStatus)){
+                            // 模拟agv任务回调失败
+                            JSONObject jsonAgvTaskCallBack = new JSONObject();
+                            jsonAgvTaskCallBack.put("taskCode",taskCode);
+                            jsonAgvTaskCallBack.put("method","cancel");
+                            jsonAgvTaskCallBack.put("code",taskStatus);
+                            jsonAgvTaskCallBack.put("msg",translateTaskStatus(taskStatus));
+                            // 组装参数发送至agv回调接口
+                            HttpHeaders agvTaskCallBackHeaders = new HttpHeaders();
+                            agvTaskCallBackHeaders.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
+
+                            HttpEntity<String> formEntity = new HttpEntity<String>(jsonAgvTaskCallBack.toJSONString(),agvTaskCallBackHeaders);
+                            log.info("agv模拟回调参数:{}", jsonObject.toJSONString());
+                            String agvCallbackUrl = (null == msgUtil.redis_get(ParameterKey.PARAMETERS)? "": ((Map<String,String>)msgUtil.redis_get(ParameterKey.PARAMETERS)).get(ParameterKey.AGVCALLBACKURL).toString());
+                            String returnData = restTemplate.postForObject(agvCallbackUrl,formEntity, String.class);
+                            log.info("agv模拟回调同步返回:{}", returnData);
+                        }
+                    }
+                    return R.success();
+                }else{
+                    return  R.fail("agv查询任务状态失败");
+                }
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }finally {
+            agvTaskQuartzFlag =  true;
+        }
+        return R.success();
+    }
+
+    /**
+     * agv taskStatus 转义 任务状态: 1-已创建,2-正在执行, 5-取消完成,9-已结束, 10-被打断
+     * @param taskStatus
+     * @return
+     */
+    private String translateTaskStatus(String taskStatus) {
+        String taskStatusName = "";
+        switch (taskStatus){
+            case "5":
+                taskStatusName = "取消完成";
+                break;
+            case "10":
+                taskStatusName = "被打断";
+                break;
+            default:
+                taskStatusName = "";
+                break;
+        }
+        return taskStatusName;
+    }
 }

+ 8 - 3
imcs-admin-boot/imcs-business-controller/src/main/java/com/github/zuihou/business/controller/externalApi/HikAgvControl.java

@@ -44,6 +44,7 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -54,6 +55,7 @@ import org.springframework.web.client.RestTemplate;
 import javax.annotation.Resource;
 import java.util.Calendar;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -237,7 +239,6 @@ public class HikAgvControl extends SuperController<AgvHikOrderInfoService, Long,
                 return HikR.success().setReqCode(agvHikOrderDetailInfo.getReqCode());
             }
         }else{
-            // TODO 记录AGV任务异常信息并告警
             Object autoNodeTaskInfo = redisTemplate.opsForValue().get(taskCode);
 
             String taskId = autoNodeTaskInfo.toString().split("-")[0];
@@ -246,7 +247,6 @@ public class HikAgvControl extends SuperController<AgvHikOrderInfoService, Long,
             autoNodeTaskInfoObj.put("taskId",taskId);
             autoNodeTaskInfoObj.put("taskNodeId",taskNodeId);
             redisTemplate.delete(taskCode);
-            // TODO 后续改成0失败
             autoNodeTaskInfoObj.put("code","0");
 //            autoNodeTaskInfoObj.put("msg",msg);
             autoNodeTaskInfoObj.put("msg","AGV任务执行失败");
@@ -261,7 +261,6 @@ public class HikAgvControl extends SuperController<AgvHikOrderInfoService, Long,
             if(flag){
                 return HikR.success().setReqCode(agvHikOrderDetailInfo.getReqCode());
             }else{
-                // TODO 记录告警日志方便电子看板或者其他地方展示系统通讯异常
                 return HikR.success().setReqCode(agvHikOrderDetailInfo.getReqCode());
             }
         }
@@ -312,4 +311,10 @@ public class HikAgvControl extends SuperController<AgvHikOrderInfoService, Long,
     public R query3dResouceDataInfo(@RequestBody Map<String, String> data) {
         return baseService.query3dResouceDataInfo(data);
     }
+
+    @Scheduled(cron="0 0/2 * * * ?")
+    public void selectHikAgvTaskInfo(){
+        BaseContextHandler.setTenant("0000");
+        baseService.execSynHikAgvTaskInfo();
+    }
 }

+ 3 - 0
imcs-admin-boot/imcs-common/src/main/java/com/github/zuihou/common/constant/ParameterKey.java

@@ -55,6 +55,9 @@ public interface ParameterKey {
     // agv状态
     String GET_AGV_STATUS = "get_agv_status";
 
+    // agv状态
+    String GET_AGV_TASK_STATUS = "get_agv_task_status";
+
     // 结点任务完成回调地址
     String STATION_GA_SWITCH_FLAG = "stationGaSwitchFlag";
     // AGV下达任务请求地址