From bc729b420fc0db8db80fc4d2b8e67f56edada33e Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期一, 13 四月 2026 10:23:35 +0800
Subject: [PATCH] #
---
version/doc/hua/华睿科技VDA5050协议接入手册-V1.009.pdf | 0
zy-acs-common/src/main/java/com/zy/acs/common/constant/RedisConstant.java | 2
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/hik/HikInstantActionPublishService.java | 83 ++++++++++++++++++++
zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java | 14 +++
version/doc/hua/华睿机器人设备对接协议说明V1.016.pdf | 0
zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/listen/MessageListener.java | 89 +++++++++++++++++----
zy-acs-common/src/main/java/com/zy/acs/common/hk/action/HkInstantActionDown.java | 18 ++++
7 files changed, 188 insertions(+), 18 deletions(-)
diff --git "a/version/doc/hua/\345\215\216\347\235\277\346\234\272\345\231\250\344\272\272\350\256\276\345\244\207\345\257\271\346\216\245\345\215\217\350\256\256\350\257\264\346\230\216V1.016.pdf" "b/version/doc/hua/\345\215\216\347\235\277\346\234\272\345\231\250\344\272\272\350\256\276\345\244\207\345\257\271\346\216\245\345\215\217\350\256\256\350\257\264\346\230\216V1.016.pdf"
new file mode 100644
index 0000000..9507269
--- /dev/null
+++ "b/version/doc/hua/\345\215\216\347\235\277\346\234\272\345\231\250\344\272\272\350\256\276\345\244\207\345\257\271\346\216\245\345\215\217\350\256\256\350\257\264\346\230\216V1.016.pdf"
Binary files differ
diff --git "a/version/doc/hua/\345\215\216\347\235\277\347\247\221\346\212\200VDA5050\345\215\217\350\256\256\346\216\245\345\205\245\346\211\213\345\206\214-V1.009.pdf" "b/version/doc/hua/\345\215\216\347\235\277\347\247\221\346\212\200VDA5050\345\215\217\350\256\256\346\216\245\345\205\245\346\211\213\345\206\214-V1.009.pdf"
new file mode 100644
index 0000000..02560b1
--- /dev/null
+++ "b/version/doc/hua/\345\215\216\347\235\277\347\247\221\346\212\200VDA5050\345\215\217\350\256\256\346\216\245\345\205\245\346\211\213\345\206\214-V1.009.pdf"
Binary files differ
diff --git a/zy-acs-common/src/main/java/com/zy/acs/common/constant/RedisConstant.java b/zy-acs-common/src/main/java/com/zy/acs/common/constant/RedisConstant.java
index d2db9d0..d8c8010 100644
--- a/zy-acs-common/src/main/java/com/zy/acs/common/constant/RedisConstant.java
+++ b/zy-acs-common/src/main/java/com/zy/acs/common/constant/RedisConstant.java
@@ -61,6 +61,8 @@
public static final String HK_AGV_PATH_DOWN_FLAG = "HK_AGV_PATH_DOWN_FLAG";
+ public static final String HK_AGV_INSTANT_ACTION_DOWN_FLAG = "HK_AGV_INSTANT_ACTION_DOWN_FLAG";
+
public static final String HK_AGV_DATA_FLAG = "HK_AGV_DATA_FLAG";
}
diff --git a/zy-acs-common/src/main/java/com/zy/acs/common/hk/action/HkInstantActionDown.java b/zy-acs-common/src/main/java/com/zy/acs/common/hk/action/HkInstantActionDown.java
new file mode 100644
index 0000000..a345731
--- /dev/null
+++ b/zy-acs-common/src/main/java/com/zy/acs/common/hk/action/HkInstantActionDown.java
@@ -0,0 +1,18 @@
+package com.zy.acs.common.hk.action;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 娴峰悍鍗虫椂鍔ㄤ綔涓嬪彂闃熷垪娑堟伅銆�
+ */
+@Data
+public class HkInstantActionDown implements Serializable {
+
+ private static final long serialVersionUID = 7609495759663594622L;
+
+ private String agvNo;
+
+ private HkInstantActionMessage instantActionMessage;
+}
diff --git a/zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/listen/MessageListener.java b/zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/listen/MessageListener.java
index afa7433..e1e0473 100644
--- a/zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/listen/MessageListener.java
+++ b/zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/listen/MessageListener.java
@@ -2,10 +2,13 @@
import com.alibaba.fastjson.JSON;
import com.zy.acs.common.constant.RedisConstant;
+import com.zy.acs.common.hk.action.HkInstantActionDown;
+import com.zy.acs.common.hk.action.HkInstantActionMessage;
import com.zy.acs.common.hk.order.HkOrderDown;
import com.zy.acs.common.hk.order.HkOrderMessage;
import com.zy.acs.common.utils.RedisSupport;
import com.zy.acs.framework.common.Cools;
+import com.zy.acs.hk.latent.mqtt.publisher.HkInstantActionPublisher;
import com.zy.acs.hk.latent.mqtt.publisher.HkOrderPublisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,6 +32,8 @@
@Autowired
private HkOrderPublisher hkOrderPublisher;
+ @Autowired
+ private HkInstantActionPublisher hkInstantActionPublisher;
@PostConstruct
private void start(){
@@ -36,24 +41,12 @@
while (!Thread.currentThread().isInterrupted()) {
HkOrderDown orderDown = redis.pop(RedisConstant.HK_AGV_PATH_DOWN_FLAG);
if (orderDown != null) {
- try {
- log.info("鐩戝惉鍣� >>> {}", JSON.toJSONString(orderDown));
- HkOrderMessage orderMessage = normalize(orderDown);
- if (orderMessage == null) {
- log.error("drop invalid hk order message, payload={}", JSON.toJSONString(orderDown));
- } else {
- hkOrderPublisher.publish(orderMessage);
- }
- } catch (IllegalArgumentException e) {
- log.error("drop illegal hk order message, payload={}", JSON.toJSONString(orderDown), e);
- } catch (Exception e) {
- log.error("publish hk order failed, requeue to head payload={}", JSON.toJSONString(orderDown), e);
- try {
- redis.pushHeadStrict(RedisConstant.HK_AGV_PATH_DOWN_FLAG, orderDown);
- } catch (Exception pushEx) {
- log.error("requeue hk order failed, payload={}", JSON.toJSONString(orderDown), pushEx);
- }
- }
+ handleOrderDown(orderDown);
+ }
+
+ HkInstantActionDown instantActionDown = redis.pop(RedisConstant.HK_AGV_INSTANT_ACTION_DOWN_FLAG);
+ if (instantActionDown != null) {
+ handleInstantActionDown(instantActionDown);
}
// 闂撮殧
try {
@@ -67,6 +60,48 @@
@PreDestroy
public void shutDown(){
if (thread != null) thread.interrupt();
+ }
+
+ private void handleOrderDown(HkOrderDown orderDown) {
+ try {
+ log.info("鐩戝惉鍣� >>> {}", JSON.toJSONString(orderDown));
+ HkOrderMessage orderMessage = normalize(orderDown);
+ if (orderMessage == null) {
+ log.error("drop invalid hk order message, payload={}", JSON.toJSONString(orderDown));
+ } else {
+ hkOrderPublisher.publish(orderMessage);
+ }
+ } catch (IllegalArgumentException e) {
+ log.error("drop illegal hk order message, payload={}", JSON.toJSONString(orderDown), e);
+ } catch (Exception e) {
+ log.error("publish hk order failed, requeue to head payload={}", JSON.toJSONString(orderDown), e);
+ try {
+ redis.pushHeadStrict(RedisConstant.HK_AGV_PATH_DOWN_FLAG, orderDown);
+ } catch (Exception pushEx) {
+ log.error("requeue hk order failed, payload={}", JSON.toJSONString(orderDown), pushEx);
+ }
+ }
+ }
+
+ private void handleInstantActionDown(HkInstantActionDown instantActionDown) {
+ try {
+ log.info("鐩戝惉鍣� >>> {}", JSON.toJSONString(instantActionDown));
+ HkInstantActionMessage instantActionMessage = normalize(instantActionDown);
+ if (instantActionMessage == null) {
+ log.error("drop invalid hk instant action message, payload={}", JSON.toJSONString(instantActionDown));
+ } else {
+ hkInstantActionPublisher.publish(instantActionMessage);
+ }
+ } catch (IllegalArgumentException e) {
+ log.error("drop illegal hk instant action message, payload={}", JSON.toJSONString(instantActionDown), e);
+ } catch (Exception e) {
+ log.error("publish hk instant action failed, requeue to head payload={}", JSON.toJSONString(instantActionDown), e);
+ try {
+ redis.pushHeadStrict(RedisConstant.HK_AGV_INSTANT_ACTION_DOWN_FLAG, instantActionDown);
+ } catch (Exception pushEx) {
+ log.error("requeue hk instant action failed, payload={}", JSON.toJSONString(instantActionDown), pushEx);
+ }
+ }
}
private HkOrderMessage normalize(HkOrderDown orderDown) {
@@ -93,4 +128,22 @@
return orderMessage;
}
+ private HkInstantActionMessage normalize(HkInstantActionDown instantActionDown) {
+ if (instantActionDown == null || instantActionDown.getInstantActionMessage() == null) {
+ return null;
+ }
+
+ HkInstantActionMessage instantActionMessage = instantActionDown.getInstantActionMessage();
+ if (Cools.isEmpty(instantActionMessage.getSerialNumber()) && !Cools.isEmpty(instantActionDown.getAgvNo())) {
+ instantActionMessage.setSerialNumber(instantActionDown.getAgvNo());
+ }
+ if (Cools.isEmpty(instantActionMessage.getSerialNumber())) {
+ return null;
+ }
+ if (instantActionMessage.getInstantActions() == null || instantActionMessage.getInstantActions().isEmpty()) {
+ return null;
+ }
+ return instantActionMessage;
+ }
+
}
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java
index 2e52cda..77fec31 100644
--- a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java
@@ -13,6 +13,7 @@
import com.zy.acs.manager.common.domain.param.HandlerPublishParam;
import com.zy.acs.manager.common.exception.BusinessException;
import com.zy.acs.manager.core.service.*;
+import com.zy.acs.manager.core.service.hik.HikInstantActionPublishService;
import com.zy.acs.manager.core.service.astart.MapDataDispatcher;
import com.zy.acs.manager.core.service.astart.domain.DynamicNode;
import com.zy.acs.manager.manager.entity.*;
@@ -81,6 +82,8 @@
private AgvAreaDispatcher agvAreaDispatcher;
@Autowired
private ConfigService configService;
+ @Autowired
+ private HikInstantActionPublishService hikInstantActionPublishService;
@PreAuthorize("hasAuthority('manager:agv:update')")
@OperationLog("Locate All Agv")
@@ -467,6 +470,7 @@
}
if (null != agv) {
+ publishRestoreCancelIfNeeded(agv);
mapDataDispatcher.modifyDynamicMatrix(null, null, agv.getUuid(), true);
avoidWaveCalculator.calcDynamicNodeByVehicle(agv, null);
@@ -477,6 +481,7 @@
} else {
List<Agv> agvList = agvService.list(new LambdaQueryWrapper<Agv>());
for (Agv one : agvList) {
+ publishRestoreCancelIfNeeded(one);
mapDataDispatcher.modifyDynamicMatrix(null, null, one.getUuid(), true);
avoidWaveCalculator.calcDynamicNodeByVehicle(one, null);
}
@@ -490,6 +495,15 @@
return R.ok();
}
+ private void publishRestoreCancelIfNeeded(Agv agv) {
+ if (agv == null) {
+ return;
+ }
+ if (hikInstantActionPublishService.support(agv.getId())) {
+ hikInstantActionPublishService.publishCancelOrder(agv.getUuid());
+ }
+ }
+
@RequestMapping(value = "/unlock", method = {RequestMethod.GET, RequestMethod.POST})
public R unlockPath(@RequestHeader String appKey,
@RequestBody HandlerPublishParam param) throws ExecutionException, InterruptedException {
diff --git a/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/hik/HikInstantActionPublishService.java b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/hik/HikInstantActionPublishService.java
new file mode 100644
index 0000000..09da197
--- /dev/null
+++ b/zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/hik/HikInstantActionPublishService.java
@@ -0,0 +1,83 @@
+package com.zy.acs.manager.core.service.hik;
+
+import com.zy.acs.common.constant.RedisConstant;
+import com.zy.acs.common.hk.action.HkAction;
+import com.zy.acs.common.hk.action.HkActionParameter;
+import com.zy.acs.common.hk.action.HkInstantActionDown;
+import com.zy.acs.common.hk.action.HkInstantActionMessage;
+import com.zy.acs.common.hk.action.type.HkActionType;
+import com.zy.acs.common.utils.Utils;
+import com.zy.acs.framework.common.SnowflakeIdWorker;
+import com.zy.acs.framework.exception.CoolException;
+import com.zy.acs.manager.common.config.HikOrderProperties;
+import com.zy.acs.manager.manager.entity.AgvModel;
+import com.zy.acs.manager.manager.service.AgvModelService;
+import com.zy.acs.common.utils.RedisSupport;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+@Slf4j
+@Service
+public class HikInstantActionPublishService {
+
+ private final RedisSupport redis = RedisSupport.defaultRedisSupport;
+
+ @Autowired
+ private HikOrderProperties hikOrderProperties;
+ @Autowired
+ private SnowflakeIdWorker snowflakeIdWorker;
+ @Autowired
+ private AgvModelService agvModelService;
+
+ public boolean support(Long agvId) {
+ AgvModel agvModel = agvModelService.getByAgvId(agvId);
+ if (agvModel == null || !StringUtils.hasText(agvModel.getProtocol())) {
+ return false;
+ }
+ return agvModel.getProtocol().toLowerCase(Locale.ROOT).contains("hik");
+ }
+
+ public void publishCancelOrder(String agvNo) {
+ if (!StringUtils.hasText(agvNo)) {
+ throw new CoolException("agvNo can not be blank");
+ }
+
+ HkInstantActionMessage message = new HkInstantActionMessage();
+ message.setHeaderId(snowflakeIdWorker.nextId());
+ message.setTimestamp(Instant.now().toString());
+ message.setVersion(hikOrderProperties.getMajorVersion());
+ message.setManufacturer(hikOrderProperties.getManufacturer());
+ message.setSerialNumber(agvNo);
+ message.setInstantActions(Utils.singletonList(buildCancelOrderAction()));
+
+ HkInstantActionDown down = new HkInstantActionDown();
+ down.setAgvNo(agvNo);
+ down.setInstantActionMessage(message);
+ redis.pushStrict(RedisConstant.HK_AGV_INSTANT_ACTION_DOWN_FLAG, down);
+
+ log.info("push hik cancelOrder instant action to redis, agvNo={}, redisKey={}",
+ agvNo, RedisConstant.HK_AGV_INSTANT_ACTION_DOWN_FLAG);
+ }
+
+ private HkAction buildCancelOrderAction() {
+ HkAction action = new HkAction();
+ action.setActionId("cancelOrder-" + snowflakeIdWorker.nextId());
+ action.setActionType(HkActionType.CANCEL_ORDER);
+ action.setActionDescription("restoreAgv cancel current order");
+
+ List<HkActionParameter> parameters = new ArrayList<>();
+ HkActionParameter parameter = new HkActionParameter();
+ parameter.setKey("instantStop");
+ parameter.setValue(Boolean.FALSE); // true: 绔嬪嵆鍋滆溅锛� false锛氬湪灏辫繎鐐逛綅涓婂仠杞�
+ parameters.add(parameter);
+ action.setActionParameters(parameters);
+ return action;
+ }
+}
--
Gitblit v1.9.1