From 073239cedaab68465e109b1957144f5fca17958d Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Thu, 18 Dec 2025 12:22:18 +0800
Subject: [PATCH] 增加航线状态机

---
 ard-work/pom.xml                                                                                |    5 
 ard-work/src/main/java/com/ard/work/component/netty/command/notice/WayLineFinishedReplyCmd.java |    4 
 ard-work/src/main/java/com/ard/work/component/netty/handler/MessageProtocolDecoder.java         |    4 
 ard-admin/src/main/java/com/ard/web/controller/route/RouteController.java                       |   65 +++++++++
 ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java                             |   42 +++++
 ard-work/src/main/java/com/ard/work/config/RouteStateMachineConfig.java                         |  108 +++++++++++++++
 ard-work/src/main/java/com/ard/work/domain/enums/RouteEvent.java                                |   10 +
 ard-work/src/main/java/com/ard/work/config/RouteStateMachineListener.java                       |   35 +++++
 ard-work/src/main/java/com/ard/work/config/RouteStateMachineService.java                        |  115 ++++++++++++++++
 ard-work/src/main/java/com/ard/work/domain/enums/RouteState.java                                |    9 +
 10 files changed, 387 insertions(+), 10 deletions(-)

diff --git a/ard-admin/src/main/java/com/ard/web/controller/route/RouteController.java b/ard-admin/src/main/java/com/ard/web/controller/route/RouteController.java
new file mode 100644
index 0000000..82d7a8a
--- /dev/null
+++ b/ard-admin/src/main/java/com/ard/web/controller/route/RouteController.java
@@ -0,0 +1,65 @@
+package com.ard.web.controller.route;
+
+import com.ard.common.core.domain.AjaxResult;
+import com.ard.work.config.RouteStateMachineService;
+import com.ard.work.domain.enums.RouteEvent;
+import com.ard.work.domain.enums.RouteState;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@Api(tags = "航线状态机")
+@RestController
+@RequestMapping("/api/route")
+@RequiredArgsConstructor
+public class RouteController {
+
+    @Autowired
+    private RouteStateMachineService stateMachineService;
+
+    /**
+     * 发送航线事件
+     */
+    @ApiOperation("航线状态测试")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "boxSn", value = "设备编号", required = true, dataType = "String", paramType = "path"),
+            @ApiImplicitParam(name = "event", value = "事件", required = true, dataType = "RouteEvent", paramType = "query")
+    })
+    @PostMapping("/{boxSn}/event")
+    public AjaxResult sendRouteEvent(
+            @PathVariable String boxSn,
+            @RequestParam RouteEvent event) {
+        boolean success = stateMachineService.sendEvent(boxSn, event);
+        if (success) {
+            RouteState currentState = stateMachineService.getCurrentState(boxSn);
+            return AjaxResult.success("事件执行成功,设备" + boxSn + "当前状态:" + currentState);
+        } else {
+            return AjaxResult.error("事件执行失败(状态流转不允许),设备" + boxSn + "当前状态:" +
+                    stateMachineService.getCurrentState(boxSn));
+        }
+
+    }
+
+    /**
+     * 获取设备当前航线状态
+     */
+    @ApiOperation("获取设备当前航线状态")
+    @GetMapping("/{boxSn}/state")
+    public RouteState getRouteState(@PathVariable String boxSn) {
+        return stateMachineService.getCurrentState(boxSn);
+    }
+
+    /**
+     * 重置设备航线状态
+     */
+    @ApiOperation("重置设备航线状态")
+    @PostMapping("/{boxSn}/reset")
+    public String resetRouteState(@PathVariable String boxSn) {
+        stateMachineService.resetStateMachine(boxSn);
+        return "设备" + boxSn + "航线状态已重置为:" + RouteState.IDLE;
+    }
+}
\ No newline at end of file
diff --git a/ard-work/pom.xml b/ard-work/pom.xml
index ef3f0a4..974b23f 100644
--- a/ard-work/pom.xml
+++ b/ard-work/pom.xml
@@ -113,6 +113,11 @@
             <groupId>com.ard</groupId>
             <artifactId>ard-oss</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.statemachine</groupId>
+            <artifactId>spring-statemachine-starter</artifactId>
+            <version>2.3.0</version>
+        </dependency>
     </dependencies>
     <repositories>
         <repository>
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/command/notice/FlyWayEndReplyCmd.java b/ard-work/src/main/java/com/ard/work/component/netty/command/notice/WayLineFinishedReplyCmd.java
similarity index 87%
rename from ard-work/src/main/java/com/ard/work/component/netty/command/notice/FlyWayEndReplyCmd.java
rename to ard-work/src/main/java/com/ard/work/component/netty/command/notice/WayLineFinishedReplyCmd.java
index 1231cfe..2f0ddc7 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/command/notice/FlyWayEndReplyCmd.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/command/notice/WayLineFinishedReplyCmd.java
@@ -13,13 +13,13 @@
  **/
 @Data
 @EqualsAndHashCode(callSuper = false)
-public class FlyWayEndReplyCmd extends BaseCmd {
+public class WayLineFinishedReplyCmd extends BaseCmd {
     private final byte encryptFlag = 0x00;  // 加密标志
     private final byte actionCode = 0x2E;   // 动作编号
     private final byte result;              // 执行结果
     private final int errorCode;            // 错误码
 
-    public FlyWayEndReplyCmd(String boxSn, byte result, int errorCode) {
+    public WayLineFinishedReplyCmd(String boxSn, byte result, int errorCode) {
         setDataHeader((short) 0x6A77);      // 设置帧头
         setCmdCode((byte) 0x3D);            // 设置指令编号
         setDataLength((short) 23);          // 数据长度
diff --git a/ard-work/src/main/java/com/ard/work/component/netty/handler/MessageProtocolDecoder.java b/ard-work/src/main/java/com/ard/work/component/netty/handler/MessageProtocolDecoder.java
index 337ed0c..e60cf12 100644
--- a/ard-work/src/main/java/com/ard/work/component/netty/handler/MessageProtocolDecoder.java
+++ b/ard-work/src/main/java/com/ard/work/component/netty/handler/MessageProtocolDecoder.java
@@ -12,7 +12,7 @@
 import com.ard.work.domain.dto.telemetry.TelemetryData;
 import com.ard.work.component.netty.command.BaseCmd;
 import com.ard.work.component.netty.command.notice.BoxPowerStatusReplyCmd;
-import com.ard.work.component.netty.command.notice.FlyWayEndReplyCmd;
+import com.ard.work.component.netty.command.notice.WayLineFinishedReplyCmd;
 import com.ard.work.component.netty.command.notice.UavReadyReplyCmd;
 import com.ard.work.component.netty.command.real.SignalInfoCmd;
 import com.ard.work.component.netty.command.real.UavStateCmd;
@@ -185,7 +185,7 @@
             case 0x25:
                 return new RecordStopReplyCmd(boxSn, result, errorCode);
             case 0x2E:
-                return new FlyWayEndReplyCmd(boxSn, result, errorCode);
+                return new WayLineFinishedReplyCmd(boxSn, result, errorCode);
             // Special cases
             case 0x3D:
             case 0x40:
diff --git a/ard-work/src/main/java/com/ard/work/config/RouteStateMachineConfig.java b/ard-work/src/main/java/com/ard/work/config/RouteStateMachineConfig.java
new file mode 100644
index 0000000..f4d88f6
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/config/RouteStateMachineConfig.java
@@ -0,0 +1,108 @@
+package com.ard.work.config;
+
+import com.ard.work.domain.enums.RouteEvent;
+import com.ard.work.domain.enums.RouteState;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.statemachine.config.EnableStateMachineFactory;
+import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
+import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
+import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
+import org.springframework.statemachine.guard.Guard;
+import org.springframework.statemachine.service.DefaultStateMachineService;
+import org.springframework.statemachine.service.StateMachineService;
+
+import java.util.EnumSet;
+
+@Configuration
+@EnableStateMachineFactory
+public class RouteStateMachineConfig extends StateMachineConfigurerAdapter<RouteState, RouteEvent> {
+
+    /**
+     * 配置状态机的状态集
+     */
+    @Override
+    public void configure(StateMachineStateConfigurer<RouteState, RouteEvent> states) throws Exception {
+        states
+                .withStates()
+                .initial(RouteState.IDLE)  // 初始状态
+                .states(EnumSet.allOf(RouteState.class)); // 注册所有状态
+    }
+
+    /**
+     * 配置状态流转规则
+     */
+    @Override
+    public void configure(StateMachineTransitionConfigurer<RouteState, RouteEvent> transitions)
+            throws Exception {
+
+        transitions
+                // IDLE → UPLOADED
+                .withExternal()
+                .source(RouteState.IDLE)
+                .target(RouteState.UPLOADED)
+                .event(RouteEvent.UPLOAD_SUCCESS)
+                .and()
+
+                // UPLOADED → RUNNING
+                .withExternal()
+                .source(RouteState.UPLOADED)
+                .target(RouteState.RUNNING)
+                .event(RouteEvent.START_SUCCESS)
+                .and()
+
+                // RUNNING → PAUSED
+                .withExternal()
+                .source(RouteState.RUNNING)
+                .target(RouteState.PAUSED)
+                .event(RouteEvent.PAUSE_SUCCESS)
+                .and()
+
+                // PAUSED → RUNNING
+                .withExternal()
+                .source(RouteState.PAUSED)
+                .target(RouteState.RUNNING)
+                .event(RouteEvent.RESUME_SUCCESS)
+                .and()
+
+                // RUNNING / PAUSED → STOPPED
+                .withExternal()
+                .source(RouteState.RUNNING)
+                .target(RouteState.STOPPED)
+                .event(RouteEvent.STOP_SUCCESS)
+                .and()
+                .withExternal()
+                .source(RouteState.PAUSED)
+                .target(RouteState.STOPPED)
+                .event(RouteEvent.STOP_SUCCESS)
+                .and()
+
+                // ⭐ STOPPED → IDLE(为下一条航线做准备)
+                .withExternal()
+                .source(RouteState.STOPPED)
+                .target(RouteState.IDLE)
+                .event(RouteEvent.RESET_ROUTE);
+    }
+
+
+    /**
+     * 可选:守卫器 - 校验boxSn合法性(示例)
+     */
+    @Bean
+    public Guard<RouteState, RouteEvent> validBoxSnGuard() {
+        return context -> {
+            // 从扩展变量中获取boxSn并校验
+            String boxSn = (String) context.getMessageHeader("boxSn");
+            return boxSn != null && !boxSn.isEmpty();
+        };
+    }
+
+    /**
+     * 状态机服务(用于管理多实例)
+     */
+    @Bean
+    public StateMachineService<RouteState, RouteEvent> stateMachineService(
+            org.springframework.statemachine.config.StateMachineFactory<RouteState, RouteEvent> factory) {
+        return new DefaultStateMachineService<>(factory);
+    }
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/work/config/RouteStateMachineListener.java b/ard-work/src/main/java/com/ard/work/config/RouteStateMachineListener.java
new file mode 100644
index 0000000..1f44591
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/config/RouteStateMachineListener.java
@@ -0,0 +1,35 @@
+package com.ard.work.config;
+
+import com.ard.work.domain.enums.RouteEvent;
+import com.ard.work.domain.enums.RouteState;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.statemachine.StateContext;
+import org.springframework.statemachine.listener.StateMachineListenerAdapter;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+public class RouteStateMachineListener
+        extends StateMachineListenerAdapter<RouteState, RouteEvent> {
+
+    @Override
+    public void stateContext(StateContext<RouteState, RouteEvent> context) {
+
+        if (context.getStage() != StateContext.Stage.STATE_ENTRY) {
+            return; // 避免多次触发
+        }
+
+        RouteState target = context.getTarget() != null
+                ? context.getTarget().getId()
+                : null;
+
+        String boxSn = (String) context.getMessageHeaders().get("boxSn");
+
+        if (boxSn == null || target == null) {
+            return;
+        }
+
+        log.info("boxSn={} 状态变更为 {}", boxSn, target);
+    }
+
+}
diff --git a/ard-work/src/main/java/com/ard/work/config/RouteStateMachineService.java b/ard-work/src/main/java/com/ard/work/config/RouteStateMachineService.java
new file mode 100644
index 0000000..a1e1f07
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/config/RouteStateMachineService.java
@@ -0,0 +1,115 @@
+package com.ard.work.config;
+
+import com.ard.work.domain.enums.RouteEvent;
+import com.ard.work.domain.enums.RouteState;
+import lombok.RequiredArgsConstructor;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.support.MessageBuilder;
+import org.springframework.statemachine.StateMachine;
+import org.springframework.statemachine.service.StateMachineService;
+import org.springframework.statemachine.support.DefaultExtendedState;
+import org.springframework.statemachine.support.DefaultStateMachineContext;
+import org.springframework.stereotype.Service;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+@Service
+@RequiredArgsConstructor
+public class RouteStateMachineService {
+
+    private final StateMachineService<RouteState, RouteEvent> stateMachineService;
+    private final RouteStateMachineListener listener;
+    private final ConcurrentHashMap<String, Boolean> listenerRegisteredMap = new ConcurrentHashMap<>();
+
+    private StateMachine<RouteState, RouteEvent> getStateMachine(String boxSn) {
+        StateMachine<RouteState, RouteEvent> stateMachine =
+                stateMachineService.acquireStateMachine(boxSn);
+
+        // 使用原子操作确保 listener 只添加一次
+        listenerRegisteredMap.computeIfAbsent(boxSn, k -> {
+            stateMachine.addStateListener(listener);
+            return true;
+        });
+        stateMachine.start();
+        return stateMachine;
+    }
+
+    /**
+     * 发送事件到指定boxSn的状态机
+     */
+    public boolean sendEvent(String boxSn, RouteEvent event) {
+        try {
+            // 获取/创建指定boxSn的状态机实例
+            StateMachine<RouteState, RouteEvent> stateMachine = getStateMachine(boxSn);
+
+            // 构建事件消息(携带boxSn作为头信息)
+            Message<RouteEvent> message = MessageBuilder
+                    .withPayload(event)
+                    .setHeader("boxSn", boxSn)
+                    .build();
+
+            // 发送事件并返回执行结果
+            return stateMachine.sendEvent(message);
+        } catch (Exception e) {
+            // 异常处理:日志记录、状态机重置等
+            throw new RuntimeException("发送航线状态事件失败,boxSn=" + boxSn + ", event=" + event, e);
+        }
+    }
+
+    /**
+     * 获取指定boxSn的当前状态
+     */
+    public RouteState getCurrentState(String boxSn) {
+        try {
+            StateMachine<RouteState, RouteEvent> stateMachine =
+                    stateMachineService.acquireStateMachine(boxSn);
+            return stateMachine.getState().getId();
+        } catch (Exception e) {
+            // 未找到状态机实例时返回初始状态
+            return RouteState.IDLE;
+        }
+    }
+
+    /**
+     * 释放指定boxSn的状态机实例(可选,节省资源)
+     */
+    public void releaseStateMachine(String boxSn) {
+        stateMachineService.releaseStateMachine(boxSn);
+    }
+
+    /**
+     * 重置指定boxSn的状态机(恢复到初始状态)
+     */
+    public void resetStateMachine(String boxSn) {
+        try {
+            StateMachine<RouteState, RouteEvent> stateMachine =
+                    stateMachineService.acquireStateMachine(boxSn);
+
+            // 1️⃣ 停止状态机
+            stateMachine.stop();
+
+            // 2️⃣ 构造 ExtendedState(可选,但强烈推荐)
+            DefaultExtendedState extendedState = new DefaultExtendedState();
+            extendedState.getVariables().put("boxSn", boxSn);
+
+            // 3️⃣ 重置状态机到 IDLE
+            stateMachine.getStateMachineAccessor()
+                    .doWithAllRegions(accessor -> {
+                        accessor.resetStateMachine(
+                                new DefaultStateMachineContext<>(
+                                        RouteState.IDLE, // 初始状态
+                                        null,            // event
+                                        null,            // event headers
+                                        extendedState    // 扩展状态
+                                )
+                        );
+                    });
+
+            // 4️⃣ 重新启动
+            stateMachine.start();
+
+        } catch (Exception e) {
+            throw new RuntimeException("重置航线状态机失败,boxSn=" + boxSn, e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/work/domain/enums/RouteEvent.java b/ard-work/src/main/java/com/ard/work/domain/enums/RouteEvent.java
new file mode 100644
index 0000000..22c685b
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/domain/enums/RouteEvent.java
@@ -0,0 +1,10 @@
+package com.ard.work.domain.enums;
+
+public enum RouteEvent {
+    UPLOAD_SUCCESS,
+    START_SUCCESS,
+    PAUSE_SUCCESS,
+    RESUME_SUCCESS,
+    STOP_SUCCESS,
+    RESET_ROUTE
+}
diff --git a/ard-work/src/main/java/com/ard/work/domain/enums/RouteState.java b/ard-work/src/main/java/com/ard/work/domain/enums/RouteState.java
new file mode 100644
index 0000000..807dac1
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/domain/enums/RouteState.java
@@ -0,0 +1,9 @@
+package com.ard.work.domain.enums;
+
+public enum RouteState {
+    IDLE,           // 空闲(未上传)
+    UPLOADED,       // 航线上传完成
+    RUNNING,        // 执行中
+    PAUSED,         // 已暂停
+    STOPPED         // 已停止
+}
diff --git a/ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java b/ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java
index 84dfaab..949e296 100644
--- a/ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java
+++ b/ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java
@@ -14,7 +14,7 @@
 import com.ard.work.component.netty.command.control.SpeedControlCmd;
 import com.ard.work.component.netty.command.manual.*;
 import com.ard.work.component.netty.command.notice.BoxPowerStatusReplyCmd;
-import com.ard.work.component.netty.command.notice.FlyWayEndReplyCmd;
+import com.ard.work.component.netty.command.notice.WayLineFinishedReplyCmd;
 import com.ard.work.component.netty.command.notice.UavReadyReplyCmd;
 import com.ard.work.component.netty.command.real.SignalInfoCmd;
 import com.ard.work.component.netty.command.real.UavStateCmd;
@@ -26,10 +26,10 @@
 import com.ard.work.component.netty.handler.ErrorCodeEnum;
 import com.ard.work.component.netty.protobuf.TelemetryDataPB;
 import com.ard.work.component.websocket.utils.WebSocketUtil;
+import com.ard.work.config.RouteStateMachineService;
 import com.ard.work.domain.cache.UavSignalInfoCache;
 import com.ard.work.domain.cache.UavStateCache;
 import com.ard.work.domain.cache.UavTelemetryDataCache;
-import com.ard.work.domain.cache.UavWaylineCache;
 import com.ard.work.domain.dto.BoxHistoryDTO;
 import com.ard.work.domain.dto.BoxPhotosDTO;
 import com.ard.work.domain.dto.BoxSettingsDTO;
@@ -49,6 +49,7 @@
 import com.ard.work.domain.dto.wayline.*;
 import com.ard.work.domain.entity.ArdDroneInfo;
 import com.ard.work.domain.entity.ArdServerInfo;
+import com.ard.work.domain.enums.RouteEvent;
 import com.ard.work.domain.message.ServerReplyMessage;
 import com.ard.work.domain.message.UavControlType;
 import com.ard.work.domain.receiver.*;
@@ -56,6 +57,7 @@
 import com.ard.work.service.IArdServerInfoService;
 import com.ard.work.service.ITyService;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -78,6 +80,8 @@
     private IArdDroneInfoService ardDroneService;
     @Resource
     private TyClient tyClient;
+    @Autowired
+    private RouteStateMachineService stateMachineService;
 
     /**
      * 获取边缘服务器token信息
@@ -975,10 +979,6 @@
                     CameraModeReplyCmd cameraModeReplyCommand = (CameraModeReplyCmd) tyCommand;
                     logPrint("无人机设置相机模式", cameraModeReplyCommand.getResult(), cameraModeReplyCommand.getErrorCode());
                 }
-                if (tyCommand instanceof FlyWayEndReplyCmd) {
-                    FlyWayEndReplyCmd flyWayEndReplyCmd = (FlyWayEndReplyCmd) tyCommand;
-                    logPrint("无人机飞行结束", flyWayEndReplyCmd.getResult(), flyWayEndReplyCmd.getErrorCode());
-                }
                 //格式化存储卡
                 if (tyCommand instanceof FormatSdCardReplyCmd) {
                     FormatSdCardReplyCmd formatSdCardReplyCmd = (FormatSdCardReplyCmd) tyCommand;
@@ -1044,23 +1044,53 @@
                 }
                 //开始航线回复
                 if (tyCommand instanceof WayLineBeginReplyCmd) {
+
                     WayLineBeginReplyCmd wayLineBeginReplyCmd = (WayLineBeginReplyCmd) tyCommand;
                     logPrint("开始航线", wayLineBeginReplyCmd.getResult(), wayLineBeginReplyCmd.getErrorCode());
+                    if (wayLineBeginReplyCmd.getResult() == 0) {
+                        byte[] boxSnBytes = tyCommand.getBoxSn();
+                        String boxSn = new String(boxSnBytes);
+                        stateMachineService.sendEvent(boxSn, RouteEvent.START_SUCCESS);
+                    }
                 }
                 //暂停航线回复
                 if (tyCommand instanceof WayLinePauseReplyCmd) {
                     WayLinePauseReplyCmd wayLinePauseReplyCmd = (WayLinePauseReplyCmd) tyCommand;
                     logPrint("暂停航线", wayLinePauseReplyCmd.getResult(), wayLinePauseReplyCmd.getErrorCode());
+                    if (wayLinePauseReplyCmd.getResult() == 0) {
+                        byte[] boxSnBytes = tyCommand.getBoxSn();
+                        String boxSn = new String(boxSnBytes);
+                        stateMachineService.sendEvent(boxSn, RouteEvent.PAUSE_SUCCESS);
+                    }
                 }
                 //恢复航线回复
                 if (tyCommand instanceof WayLineResumeReplyCmd) {
                     WayLineResumeReplyCmd wayLineResumeReplyCmd = (WayLineResumeReplyCmd) tyCommand;
                     logPrint("恢复航线", wayLineResumeReplyCmd.getResult(), wayLineResumeReplyCmd.getErrorCode());
+                    if (wayLineResumeReplyCmd.getResult() == 0) {
+                        byte[] boxSnBytes = tyCommand.getBoxSn();
+                        String boxSn = new String(boxSnBytes);
+                        stateMachineService.sendEvent(boxSn, RouteEvent.RESUME_SUCCESS);
+                    }
                 }
                 //结束航线回复
                 if (tyCommand instanceof WayLineEndReplyCmd) {
                     WayLineEndReplyCmd wayLineEndReplyCmd = (WayLineEndReplyCmd) tyCommand;
                     logPrint("结束航线", wayLineEndReplyCmd.getResult(), wayLineEndReplyCmd.getErrorCode());
+                    if (wayLineEndReplyCmd.getResult() == 0) {
+                        byte[] boxSnBytes = tyCommand.getBoxSn();
+                        String boxSn = new String(boxSnBytes);
+                        stateMachineService.sendEvent(boxSn, RouteEvent.STOP_SUCCESS);
+                    }
+                }
+                if (tyCommand instanceof WayLineFinishedReplyCmd) {
+                    WayLineFinishedReplyCmd wayLineFinishedReplyCmd = (WayLineFinishedReplyCmd) tyCommand;
+                    logPrint("航线执行完成", wayLineFinishedReplyCmd.getResult(), wayLineFinishedReplyCmd.getErrorCode());
+                    if (wayLineFinishedReplyCmd.getResult() == 0) {
+                        byte[] boxSnBytes = tyCommand.getBoxSn();
+                        String boxSn = new String(boxSnBytes);
+                        stateMachineService.sendEvent(boxSn, RouteEvent.RESET_ROUTE);
+                    }
                 }
                 //设置返航高度回复
                 if (tyCommand instanceof ReturnHeightSettingReplyCmd) {

--
Gitblit v1.9.3