#
vincentlu
2026-04-13 bc729b420fc0db8db80fc4d2b8e67f56edada33e
#
4个文件已添加
3个文件已修改
206 ■■■■■ 已修改文件
version/doc/hua/华睿机器人设备对接协议说明V1.016.pdf 补丁 | 查看 | 原始文档 | blame | 历史
version/doc/hua/华睿科技VDA5050协议接入手册-V1.009.pdf 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/constant/RedisConstant.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-common/src/main/java/com/zy/acs/common/hk/action/HkInstantActionDown.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-hk/zy-acs-hk-latent/src/main/java/com/zy/acs/hk/latent/listen/MessageListener.java 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/HandlerController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/hik/HikInstantActionPublishService.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
version/doc/hua/»ªî£»úÆ÷ÈËÉ豸¶Ô½ÓЭÒé˵Ã÷V1.016.pdf
Binary files differ
version/doc/hua/»ªî£¿Æ¼¼VDA5050ЭÒé½ÓÈëÊÖ²á-V1.009.pdf
Binary files differ
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";
}
zy-acs-common/src/main/java/com/zy/acs/common/hk/action/HkInstantActionDown.java
New file
@@ -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;
}
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;
    }
}
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 {
zy-acs-manager/src/main/java/com/zy/acs/manager/core/service/hik/HikInstantActionPublishService.java
New file
@@ -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;
    }
}