多平台支持
This commit is contained in:
parent
6501986e3d
commit
fa6ad4f8f9
|
|
@ -0,0 +1,279 @@
|
||||||
|
# 多平台机巢状态机架构说明
|
||||||
|
|
||||||
|
## 架构概述
|
||||||
|
|
||||||
|
本系统采用**策略模式 + 工厂模式**实现多平台支持,允许DJI、AUTEL、YUNEEC等不同无人机平台共存并独立运行。
|
||||||
|
|
||||||
|
## 核心设计
|
||||||
|
|
||||||
|
### 1. 平台类型枚举 (PlatformType)
|
||||||
|
```
|
||||||
|
- DJI (大疆)
|
||||||
|
- AUTEL (道通)
|
||||||
|
- YUNEEC (昊翔)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 平台策略接口
|
||||||
|
|
||||||
|
#### AirportPlatformStrategy
|
||||||
|
定义机巢平台需要实现的所有Guard、Action和Listener:
|
||||||
|
- Guards: CanOnlineGuard, CanOfflineGuard, IsDebugModeGuard等
|
||||||
|
- Actions: OnlineAction, OfflineAction, OpenDebugModeAction等
|
||||||
|
- Listener: 状态变化监听器
|
||||||
|
|
||||||
|
#### CoverPlatformStrategy
|
||||||
|
定义舱门平台需要实现的所有Guard、Action和Listener:
|
||||||
|
- Guards: CanOpenGuard, CanCloseGuard, IsOpenedGuard等
|
||||||
|
- Actions: OpenAction, CloseAction, OpenedAction等
|
||||||
|
- Listener: 状态变化监听器
|
||||||
|
|
||||||
|
### 3. 平台策略工厂 (PlatformStrategyFactory)
|
||||||
|
|
||||||
|
**核心功能:**
|
||||||
|
- 根据机巢SN从数据库查询平台类型
|
||||||
|
- 返回对应平台的策略实现
|
||||||
|
- 自动注册所有平台策略实现
|
||||||
|
|
||||||
|
**关键方法:**
|
||||||
|
```java
|
||||||
|
AirportPlatformStrategy getAirportStrategy(String airportSn)
|
||||||
|
CoverPlatformStrategy getCoverStrategy(String airportSn)
|
||||||
|
PlatformType getPlatformType(String airportSn)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 数据库映射 (AirportPlatformRepository)
|
||||||
|
|
||||||
|
**存储结构:**
|
||||||
|
```
|
||||||
|
机巢SN -> 平台类型
|
||||||
|
airport-001 -> DJI
|
||||||
|
airport-002 -> AUTEL
|
||||||
|
airport-003 -> DJI
|
||||||
|
airport-004 -> YUNEEC
|
||||||
|
```
|
||||||
|
|
||||||
|
**说明:** 当前使用内存Map模拟数据库,实际使用时替换为真实数据库查询。
|
||||||
|
|
||||||
|
### 5. 默认Listener实现
|
||||||
|
|
||||||
|
#### DefaultAirportListener
|
||||||
|
提供机巢状态变化的基础监听功能:
|
||||||
|
- 状态进入/退出日志
|
||||||
|
- 状态转换日志
|
||||||
|
- 事件未接受日志
|
||||||
|
- 状态机启动/停止日志
|
||||||
|
|
||||||
|
#### DefaultCoverListener
|
||||||
|
提供舱门状态变化的基础监听功能(同上)
|
||||||
|
|
||||||
|
**特点:** 各平台可以继承默认Listener并定制自己的逻辑。
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
com.tuoheng.status.airport
|
||||||
|
├── platform
|
||||||
|
│ ├── PlatformType.java # 平台类型枚举
|
||||||
|
│ ├── strategy # 策略接口
|
||||||
|
│ │ ├── PlatformAction.java
|
||||||
|
│ │ ├── PlatformGuard.java
|
||||||
|
│ │ ├── PlatformListener.java
|
||||||
|
│ │ ├── AirportPlatformStrategy.java
|
||||||
|
│ │ └── CoverPlatformStrategy.java
|
||||||
|
│ ├── factory
|
||||||
|
│ │ └── PlatformStrategyFactory.java # 平台策略工厂
|
||||||
|
│ ├── repository
|
||||||
|
│ │ └── AirportPlatformRepository.java # 数据库映射
|
||||||
|
│ └── impl # 平台实现
|
||||||
|
│ └── dji # DJI平台实现
|
||||||
|
│ ├── DjiAirportPlatformStrategy.java
|
||||||
|
│ ├── DjiCoverPlatformStrategy.java
|
||||||
|
│ ├── action
|
||||||
|
│ │ ├── airport # 机巢Action
|
||||||
|
│ │ │ ├── DjiOnlineAction.java
|
||||||
|
│ │ │ ├── DjiOfflineAction.java
|
||||||
|
│ │ │ ├── DjiOpenDebugModeAction.java
|
||||||
|
│ │ │ ├── DjiCloseDebugModeAction.java
|
||||||
|
│ │ │ ├── DjiRebootAction.java
|
||||||
|
│ │ │ └── DjiRebootCompletedAction.java
|
||||||
|
│ │ └── cover # 舱门Action
|
||||||
|
│ │ ├── DjiOpenCoverAction.java
|
||||||
|
│ │ ├── DjiCoverOpenedAction.java
|
||||||
|
│ │ ├── DjiCloseCoverAction.java
|
||||||
|
│ │ ├── DjiCoverClosedAction.java
|
||||||
|
│ │ ├── DjiCoverErrorAction.java
|
||||||
|
│ │ └── DjiCoverResetAction.java
|
||||||
|
│ └── guard
|
||||||
|
│ ├── airport # 机巢Guard
|
||||||
|
│ │ ├── DjiCanOnlineGuard.java
|
||||||
|
│ │ ├── DjiCanOfflineGuard.java
|
||||||
|
│ │ ├── DjiIsDebugModeGuard.java
|
||||||
|
│ │ ├── DjiIsNotDebugModeGuard.java
|
||||||
|
│ │ ├── DjiCanCloseDebugModeGuard.java
|
||||||
|
│ │ └── DjiIsRebootCompletedGuard.java
|
||||||
|
│ └── cover # 舱门Guard
|
||||||
|
│ ├── DjiCanOpenCoverGuard.java
|
||||||
|
│ ├── DjiCanCloseCoverGuard.java
|
||||||
|
│ ├── DjiIsCoverOpenedGuard.java
|
||||||
|
│ └── DjiIsCoverClosedGuard.java
|
||||||
|
├── listener
|
||||||
|
│ ├── DefaultAirportListener.java # 默认机巢监听器
|
||||||
|
│ └── DefaultCoverListener.java # 默认舱门监听器
|
||||||
|
├── config
|
||||||
|
│ ├── AirportMachineConfig.java # 机巢状态机配置(多平台)
|
||||||
|
│ └── CoverMachineConfig.java # 舱门状态机配置(多平台)
|
||||||
|
├── service
|
||||||
|
│ ├── AirportMachineService.java # 机巢状态机服务
|
||||||
|
│ └── CoverMachineService.java # 舱门状态机服务
|
||||||
|
├── manager
|
||||||
|
│ └── AirportSystemManager.java # 系统管理器(协调器)
|
||||||
|
└── demo
|
||||||
|
├── AirportSystemDemo.java # 单平台演示
|
||||||
|
└── MultiPlatformDemo.java # 多平台演示
|
||||||
|
```
|
||||||
|
|
||||||
|
## 工作流程
|
||||||
|
|
||||||
|
### 1. 状态机创建流程
|
||||||
|
|
||||||
|
```
|
||||||
|
用户调用 -> AirportSystemManager.airportOnline(airportSn)
|
||||||
|
↓
|
||||||
|
AirportMachineService.sendEvent(airportSn, AIRPORT_ONLINE)
|
||||||
|
↓
|
||||||
|
AirportMachineService.getOrCreateStateMachine(airportSn)
|
||||||
|
↓
|
||||||
|
AirportMachineConfig.stateMachineFactory.getStateMachine(airportSn)
|
||||||
|
↓
|
||||||
|
PlatformStrategyFactory.getAirportStrategy(airportSn)
|
||||||
|
↓
|
||||||
|
AirportPlatformRepository.getPlatformType(airportSn) # 查询数据库
|
||||||
|
↓
|
||||||
|
返回对应平台的Strategy (如: DjiAirportPlatformStrategy)
|
||||||
|
↓
|
||||||
|
使用Strategy中的Guard、Action、Listener构建状态机
|
||||||
|
↓
|
||||||
|
状态机创建完成并启动
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 事件处理流程
|
||||||
|
|
||||||
|
```
|
||||||
|
事件触发 -> StateMachine.sendEvent(event)
|
||||||
|
↓
|
||||||
|
检查Guard条件 (如: DjiCanOnlineGuard.evaluate())
|
||||||
|
↓
|
||||||
|
Guard通过 -> 执行Action (如: DjiOnlineAction.execute())
|
||||||
|
↓
|
||||||
|
状态转换
|
||||||
|
↓
|
||||||
|
触发Listener回调 (如: DefaultAirportListener.stateChanged())
|
||||||
|
```
|
||||||
|
|
||||||
|
## 如何添加新平台
|
||||||
|
|
||||||
|
### 步骤1: 在PlatformType中添加新平台
|
||||||
|
```java
|
||||||
|
public enum PlatformType {
|
||||||
|
DJI("DJI", "大疆"),
|
||||||
|
AUTEL("AUTEL", "道通"),
|
||||||
|
YUNEEC("YUNEEC", "昊翔"),
|
||||||
|
NEW_PLATFORM("NEW", "新平台"); // 添加这行
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 步骤2: 创建平台实现目录
|
||||||
|
```
|
||||||
|
platform/impl/newplatform/
|
||||||
|
├── NewPlatformAirportStrategy.java
|
||||||
|
├── NewPlatformCoverStrategy.java
|
||||||
|
├── action/
|
||||||
|
│ ├── airport/
|
||||||
|
│ └── cover/
|
||||||
|
└── guard/
|
||||||
|
├── airport/
|
||||||
|
└── cover/
|
||||||
|
```
|
||||||
|
|
||||||
|
### 步骤3: 实现AirportPlatformStrategy接口
|
||||||
|
```java
|
||||||
|
@Component
|
||||||
|
public class NewPlatformAirportStrategy implements AirportPlatformStrategy {
|
||||||
|
@Override
|
||||||
|
public PlatformType getPlatformType() {
|
||||||
|
return PlatformType.NEW_PLATFORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实现所有Guard、Action、Listener的getter方法
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 步骤4: 实现CoverPlatformStrategy接口
|
||||||
|
```java
|
||||||
|
@Component
|
||||||
|
public class NewPlatformCoverStrategy implements CoverPlatformStrategy {
|
||||||
|
@Override
|
||||||
|
public PlatformType getPlatformType() {
|
||||||
|
return PlatformType.NEW_PLATFORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实现所有Guard、Action、Listener的getter方法
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 步骤5: 实现所有Guard和Action
|
||||||
|
参考DJI平台的实现,创建对应的Guard和Action类。
|
||||||
|
|
||||||
|
### 步骤6: 在数据库中配置映射关系
|
||||||
|
```java
|
||||||
|
repository.savePlatformMapping("airport-005", PlatformType.NEW_PLATFORM);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 步骤7: 测试
|
||||||
|
```java
|
||||||
|
systemManager.airportOnline("airport-005");
|
||||||
|
```
|
||||||
|
|
||||||
|
## 运行演示
|
||||||
|
|
||||||
|
### 单平台演示
|
||||||
|
```bash
|
||||||
|
运行: AirportSystemDemo.main()
|
||||||
|
演示内容: DJI平台的完整开舱、关舱、重启流程
|
||||||
|
```
|
||||||
|
|
||||||
|
### 多平台演示
|
||||||
|
```bash
|
||||||
|
运行: MultiPlatformDemo.main()
|
||||||
|
演示内容:
|
||||||
|
- DJI、AUTEL、YUNEEC三个平台同时运行
|
||||||
|
- 各平台独立的状态管理
|
||||||
|
- 动态注册新平台
|
||||||
|
- 多平台状态汇总
|
||||||
|
```
|
||||||
|
|
||||||
|
## 架构优势
|
||||||
|
|
||||||
|
1. **平台隔离**: 各平台的业务逻辑完全独立,互不影响
|
||||||
|
2. **易于扩展**: 添加新平台只需实现Strategy接口,无需修改现有代码
|
||||||
|
3. **数据库驱动**: 平台映射关系存储在数据库,支持动态配置
|
||||||
|
4. **多平台并发**: 支持多个平台同时运行,状态机独立管理
|
||||||
|
5. **默认实现**: 提供默认Listener,减少重复代码
|
||||||
|
6. **类型安全**: 使用枚举和接口保证类型安全
|
||||||
|
7. **Spring集成**: 利用Spring的依赖注入自动注册所有平台策略
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **数据库配置**: 当前使用内存Map模拟,生产环境需替换为真实数据库
|
||||||
|
2. **平台注册**: 所有平台Strategy实现必须标注@Component注解
|
||||||
|
3. **机巢SN**: 必须在数据库中配置机巢SN到平台类型的映射
|
||||||
|
4. **Listener定制**: 如需定制Listener,继承DefaultListener并覆盖相应方法
|
||||||
|
5. **线程安全**: Service层使用ConcurrentHashMap保证线程安全
|
||||||
|
|
||||||
|
## 未来扩展
|
||||||
|
|
||||||
|
1. **平台能力差异**: 可在Strategy中添加能力查询接口
|
||||||
|
2. **动态配置**: 支持运行时动态修改平台映射关系
|
||||||
|
3. **平台版本**: 支持同一平台的不同版本(如DJI v1, DJI v2)
|
||||||
|
4. **监控告警**: 集成监控系统,实时监控各平台状态
|
||||||
|
5. **性能优化**: 状态机缓存、懒加载等优化策略
|
||||||
|
|
@ -1,19 +1,8 @@
|
||||||
package com.tuoheng.status.airport.config;
|
package com.tuoheng.status.airport.config;
|
||||||
|
|
||||||
import com.tuoheng.status.airport.action.airport.OfflineAction;
|
|
||||||
import com.tuoheng.status.airport.action.airport.OnlineAction;
|
|
||||||
import com.tuoheng.status.airport.action.debug.CloseDebugModeAction;
|
|
||||||
import com.tuoheng.status.airport.action.debug.OpenDebugModeAction;
|
|
||||||
import com.tuoheng.status.airport.action.reboot.RebootAction;
|
|
||||||
import com.tuoheng.status.airport.action.reboot.RebootCompletedAction;
|
|
||||||
import com.tuoheng.status.airport.events.AirportEvent;
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
import com.tuoheng.status.airport.guard.airport.CanOfflineGuard;
|
import com.tuoheng.status.airport.platform.factory.PlatformStrategyFactory;
|
||||||
import com.tuoheng.status.airport.guard.airport.CanOnlineGuard;
|
import com.tuoheng.status.airport.platform.strategy.AirportPlatformStrategy;
|
||||||
import com.tuoheng.status.airport.guard.debug.CanCloseDebugModeGuard;
|
|
||||||
import com.tuoheng.status.airport.guard.debug.IsDebugModeGuard;
|
|
||||||
import com.tuoheng.status.airport.guard.debug.IsNotDebugModeGuard;
|
|
||||||
import com.tuoheng.status.airport.guard.reboot.IsRebootCompletedGuard;
|
|
||||||
import com.tuoheng.status.airport.listener.AirPortStatusListener;
|
|
||||||
import com.tuoheng.status.airport.status.AirportState;
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
@ -26,51 +15,14 @@ import java.util.EnumSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 机巢状态机配置(简化版 - 舱门状态已分离)
|
* 机巢状态机配置(多平台支持版本)
|
||||||
|
* 通过PlatformStrategyFactory动态获取平台特定的Guard、Action和Listener
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class AirportMachineConfig {
|
public class AirportMachineConfig {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
AirPortStatusListener airPortStatusListener;
|
private PlatformStrategyFactory platformStrategyFactory;
|
||||||
|
|
||||||
// ==================== Actions ====================
|
|
||||||
@Autowired
|
|
||||||
OnlineAction onlineAction;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
OfflineAction offlineAction;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
OpenDebugModeAction openDebugModeAction;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
CloseDebugModeAction closeDebugModeAction;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
RebootAction rebootAction;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
RebootCompletedAction rebootCompletedAction;
|
|
||||||
|
|
||||||
// ==================== Guards ====================
|
|
||||||
@Autowired
|
|
||||||
CanOnlineGuard canOnlineGuard;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
CanOfflineGuard canOfflineGuard;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
IsDebugModeGuard isDebugModeGuard;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
IsNotDebugModeGuard isNotDebugModeGuard;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
CanCloseDebugModeGuard canCloseDebugModeGuard;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
IsRebootCompletedGuard isRebootCompletedGuard;
|
|
||||||
|
|
||||||
@Bean(name = "airportStateMachineFactory")
|
@Bean(name = "airportStateMachineFactory")
|
||||||
public StateMachineFactory<AirportState, AirportEvent> stateMachineFactory() throws Exception {
|
public StateMachineFactory<AirportState, AirportEvent> stateMachineFactory() throws Exception {
|
||||||
|
|
@ -83,16 +35,19 @@ public class AirportMachineConfig {
|
||||||
@Override
|
@Override
|
||||||
public StateMachine<AirportState, AirportEvent> getStateMachine(String machineId) {
|
public StateMachine<AirportState, AirportEvent> getStateMachine(String machineId) {
|
||||||
try {
|
try {
|
||||||
|
// 根据机巢SN获取平台策略
|
||||||
|
AirportPlatformStrategy strategy = platformStrategyFactory.getAirportStrategy(machineId);
|
||||||
|
|
||||||
StateMachineBuilder.Builder<AirportState, AirportEvent> builder = StateMachineBuilder.builder();
|
StateMachineBuilder.Builder<AirportState, AirportEvent> builder = StateMachineBuilder.builder();
|
||||||
configureStateMachine(builder);
|
configureStateMachine(builder, strategy);
|
||||||
configureStates(builder);
|
configureStates(builder);
|
||||||
configureTransitions(builder);
|
configureTransitions(builder, strategy);
|
||||||
|
|
||||||
StateMachine<AirportState, AirportEvent> stateMachine = builder.build();
|
StateMachine<AirportState, AirportEvent> stateMachine = builder.build();
|
||||||
stateMachine.getExtendedState().getVariables().put("machineId", machineId);
|
stateMachine.getExtendedState().getVariables().put("machineId", machineId);
|
||||||
return stateMachine;
|
return stateMachine;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Failed to create state machine", e);
|
throw new RuntimeException("Failed to create state machine for: " + machineId, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,11 +58,13 @@ public class AirportMachineConfig {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureStateMachine(StateMachineBuilder.Builder<AirportState, AirportEvent> builder) throws Exception {
|
private void configureStateMachine(
|
||||||
|
StateMachineBuilder.Builder<AirportState, AirportEvent> builder,
|
||||||
|
AirportPlatformStrategy strategy) throws Exception {
|
||||||
builder.configureConfiguration()
|
builder.configureConfiguration()
|
||||||
.withConfiguration()
|
.withConfiguration()
|
||||||
.autoStartup(true)
|
.autoStartup(true)
|
||||||
.listener(airPortStatusListener);
|
.listener(strategy.getListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureStates(StateMachineBuilder.Builder<AirportState, AirportEvent> builder) throws Exception {
|
private void configureStates(StateMachineBuilder.Builder<AirportState, AirportEvent> builder) throws Exception {
|
||||||
|
|
@ -129,15 +86,17 @@ public class AirportMachineConfig {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureTransitions(StateMachineBuilder.Builder<AirportState, AirportEvent> builder) throws Exception {
|
private void configureTransitions(
|
||||||
|
StateMachineBuilder.Builder<AirportState, AirportEvent> builder,
|
||||||
|
AirportPlatformStrategy strategy) throws Exception {
|
||||||
builder.configureTransitions()
|
builder.configureTransitions()
|
||||||
// OFFLINE -> ONLINE(STANDBY)
|
// OFFLINE -> ONLINE(STANDBY)
|
||||||
.withExternal()
|
.withExternal()
|
||||||
.source(AirportState.OFFLINE)
|
.source(AirportState.OFFLINE)
|
||||||
.target(AirportState.ONLINE)
|
.target(AirportState.ONLINE)
|
||||||
.event(AirportEvent.AIRPORT_ONLINE)
|
.event(AirportEvent.AIRPORT_ONLINE)
|
||||||
.action(onlineAction)
|
.action(strategy.getOnlineAction())
|
||||||
.guard(canOnlineGuard)
|
.guard(strategy.getCanOnlineGuard())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// ONLINE -> OFFLINE
|
// ONLINE -> OFFLINE
|
||||||
|
|
@ -145,8 +104,8 @@ public class AirportMachineConfig {
|
||||||
.source(AirportState.ONLINE)
|
.source(AirportState.ONLINE)
|
||||||
.target(AirportState.OFFLINE)
|
.target(AirportState.OFFLINE)
|
||||||
.event(AirportEvent.AIRPORT_OFFLINE)
|
.event(AirportEvent.AIRPORT_OFFLINE)
|
||||||
.action(offlineAction)
|
.action(strategy.getOfflineAction())
|
||||||
.guard(canOfflineGuard)
|
.guard(strategy.getCanOfflineGuard())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// STANDBY -> DEBUG_MODE
|
// STANDBY -> DEBUG_MODE
|
||||||
|
|
@ -154,8 +113,8 @@ public class AirportMachineConfig {
|
||||||
.source(AirportState.STANDBY)
|
.source(AirportState.STANDBY)
|
||||||
.target(AirportState.DEBUG_MODE)
|
.target(AirportState.DEBUG_MODE)
|
||||||
.event(AirportEvent.DEBUG_MODE_OPEN)
|
.event(AirportEvent.DEBUG_MODE_OPEN)
|
||||||
.action(openDebugModeAction)
|
.action(strategy.getOpenDebugModeAction())
|
||||||
.guard(isNotDebugModeGuard)
|
.guard(strategy.getIsNotDebugModeGuard())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// DEBUG_MODE -> STANDBY
|
// DEBUG_MODE -> STANDBY
|
||||||
|
|
@ -163,8 +122,8 @@ public class AirportMachineConfig {
|
||||||
.source(AirportState.DEBUG_MODE)
|
.source(AirportState.DEBUG_MODE)
|
||||||
.target(AirportState.STANDBY)
|
.target(AirportState.STANDBY)
|
||||||
.event(AirportEvent.DEBUG_MODE_CLOSE)
|
.event(AirportEvent.DEBUG_MODE_CLOSE)
|
||||||
.action(closeDebugModeAction)
|
.action(strategy.getCloseDebugModeAction())
|
||||||
.guard(canCloseDebugModeGuard)
|
.guard(strategy.getCanCloseDebugModeGuard())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// DEBUG_MODE -> REBOOTING
|
// DEBUG_MODE -> REBOOTING
|
||||||
|
|
@ -172,8 +131,8 @@ public class AirportMachineConfig {
|
||||||
.source(AirportState.DEBUG_MODE)
|
.source(AirportState.DEBUG_MODE)
|
||||||
.target(AirportState.REBOOTING)
|
.target(AirportState.REBOOTING)
|
||||||
.event(AirportEvent.AIRPORT_REBOOT)
|
.event(AirportEvent.AIRPORT_REBOOT)
|
||||||
.action(rebootAction)
|
.action(strategy.getRebootAction())
|
||||||
.guard(isDebugModeGuard)
|
.guard(strategy.getIsDebugModeGuard())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// REBOOTING -> ONLINE(STANDBY)
|
// REBOOTING -> ONLINE(STANDBY)
|
||||||
|
|
@ -181,7 +140,7 @@ public class AirportMachineConfig {
|
||||||
.source(AirportState.REBOOTING)
|
.source(AirportState.REBOOTING)
|
||||||
.target(AirportState.ONLINE)
|
.target(AirportState.ONLINE)
|
||||||
.event(AirportEvent.REBOOT_COMPLETED)
|
.event(AirportEvent.REBOOT_COMPLETED)
|
||||||
.action(rebootCompletedAction)
|
.action(strategy.getRebootCompletedAction())
|
||||||
.guard(isRebootCompletedGuard);
|
.guard(strategy.getIsRebootCompletedGuard());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
package com.tuoheng.status.airport.config;
|
package com.tuoheng.status.airport.config;
|
||||||
|
|
||||||
import com.tuoheng.status.airport.events.CoverEvent;
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.factory.PlatformStrategyFactory;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.CoverPlatformStrategy;
|
||||||
import com.tuoheng.status.airport.status.CoverState;
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.statemachine.StateMachine;
|
import org.springframework.statemachine.StateMachine;
|
||||||
|
|
@ -12,11 +15,15 @@ import java.util.EnumSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 舱门状态机配置
|
* 舱门状态机配置(多平台支持版本)
|
||||||
|
* 通过PlatformStrategyFactory动态获取平台特定的Guard、Action和Listener
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class CoverMachineConfig {
|
public class CoverMachineConfig {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PlatformStrategyFactory platformStrategyFactory;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public StateMachineFactory<CoverState, CoverEvent> coverStateMachineFactory() throws Exception {
|
public StateMachineFactory<CoverState, CoverEvent> coverStateMachineFactory() throws Exception {
|
||||||
return new StateMachineFactory<CoverState, CoverEvent>() {
|
return new StateMachineFactory<CoverState, CoverEvent>() {
|
||||||
|
|
@ -28,16 +35,19 @@ public class CoverMachineConfig {
|
||||||
@Override
|
@Override
|
||||||
public StateMachine<CoverState, CoverEvent> getStateMachine(String machineId) {
|
public StateMachine<CoverState, CoverEvent> getStateMachine(String machineId) {
|
||||||
try {
|
try {
|
||||||
|
// 根据机巢SN获取平台策略
|
||||||
|
CoverPlatformStrategy strategy = platformStrategyFactory.getCoverStrategy(machineId);
|
||||||
|
|
||||||
StateMachineBuilder.Builder<CoverState, CoverEvent> builder = StateMachineBuilder.builder();
|
StateMachineBuilder.Builder<CoverState, CoverEvent> builder = StateMachineBuilder.builder();
|
||||||
configureCoverStateMachine(builder);
|
configureCoverStateMachine(builder, strategy);
|
||||||
configureCoverStates(builder);
|
configureCoverStates(builder);
|
||||||
configureCoverTransitions(builder);
|
configureCoverTransitions(builder, strategy);
|
||||||
|
|
||||||
StateMachine<CoverState, CoverEvent> stateMachine = builder.build();
|
StateMachine<CoverState, CoverEvent> stateMachine = builder.build();
|
||||||
stateMachine.getExtendedState().getVariables().put("machineId", machineId);
|
stateMachine.getExtendedState().getVariables().put("machineId", machineId);
|
||||||
return stateMachine;
|
return stateMachine;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Failed to create cover state machine", e);
|
throw new RuntimeException("Failed to create cover state machine for: " + machineId, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,10 +58,13 @@ public class CoverMachineConfig {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureCoverStateMachine(StateMachineBuilder.Builder<CoverState, CoverEvent> builder) throws Exception {
|
private void configureCoverStateMachine(
|
||||||
|
StateMachineBuilder.Builder<CoverState, CoverEvent> builder,
|
||||||
|
CoverPlatformStrategy strategy) throws Exception {
|
||||||
builder.configureConfiguration()
|
builder.configureConfiguration()
|
||||||
.withConfiguration()
|
.withConfiguration()
|
||||||
.autoStartup(true);
|
.autoStartup(true)
|
||||||
|
.listener(strategy.getListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureCoverStates(StateMachineBuilder.Builder<CoverState, CoverEvent> builder) throws Exception {
|
private void configureCoverStates(StateMachineBuilder.Builder<CoverState, CoverEvent> builder) throws Exception {
|
||||||
|
|
@ -61,13 +74,17 @@ public class CoverMachineConfig {
|
||||||
.states(EnumSet.allOf(CoverState.class));
|
.states(EnumSet.allOf(CoverState.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureCoverTransitions(StateMachineBuilder.Builder<CoverState, CoverEvent> builder) throws Exception {
|
private void configureCoverTransitions(
|
||||||
|
StateMachineBuilder.Builder<CoverState, CoverEvent> builder,
|
||||||
|
CoverPlatformStrategy strategy) throws Exception {
|
||||||
builder.configureTransitions()
|
builder.configureTransitions()
|
||||||
// CLOSED -> OPENING
|
// CLOSED -> OPENING
|
||||||
.withExternal()
|
.withExternal()
|
||||||
.source(CoverState.CLOSED)
|
.source(CoverState.CLOSED)
|
||||||
.target(CoverState.OPENING)
|
.target(CoverState.OPENING)
|
||||||
.event(CoverEvent.OPEN)
|
.event(CoverEvent.OPEN)
|
||||||
|
.action(strategy.getOpenAction())
|
||||||
|
.guard(strategy.getCanOpenGuard())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// OPENING -> OPENED
|
// OPENING -> OPENED
|
||||||
|
|
@ -75,6 +92,8 @@ public class CoverMachineConfig {
|
||||||
.source(CoverState.OPENING)
|
.source(CoverState.OPENING)
|
||||||
.target(CoverState.OPENED)
|
.target(CoverState.OPENED)
|
||||||
.event(CoverEvent.OPENED)
|
.event(CoverEvent.OPENED)
|
||||||
|
.action(strategy.getOpenedAction())
|
||||||
|
.guard(strategy.getIsOpenedGuard())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// OPENED -> CLOSING
|
// OPENED -> CLOSING
|
||||||
|
|
@ -82,6 +101,8 @@ public class CoverMachineConfig {
|
||||||
.source(CoverState.OPENED)
|
.source(CoverState.OPENED)
|
||||||
.target(CoverState.CLOSING)
|
.target(CoverState.CLOSING)
|
||||||
.event(CoverEvent.CLOSE)
|
.event(CoverEvent.CLOSE)
|
||||||
|
.action(strategy.getCloseAction())
|
||||||
|
.guard(strategy.getCanCloseGuard())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// CLOSING -> CLOSED
|
// CLOSING -> CLOSED
|
||||||
|
|
@ -89,6 +110,8 @@ public class CoverMachineConfig {
|
||||||
.source(CoverState.CLOSING)
|
.source(CoverState.CLOSING)
|
||||||
.target(CoverState.CLOSED)
|
.target(CoverState.CLOSED)
|
||||||
.event(CoverEvent.CLOSED)
|
.event(CoverEvent.CLOSED)
|
||||||
|
.action(strategy.getClosedAction())
|
||||||
|
.guard(strategy.getIsClosedGuard())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// ERROR handling
|
// ERROR handling
|
||||||
|
|
@ -96,18 +119,21 @@ public class CoverMachineConfig {
|
||||||
.source(CoverState.OPENING)
|
.source(CoverState.OPENING)
|
||||||
.target(CoverState.ERROR)
|
.target(CoverState.ERROR)
|
||||||
.event(CoverEvent.ERROR)
|
.event(CoverEvent.ERROR)
|
||||||
|
.action(strategy.getErrorAction())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
.withExternal()
|
.withExternal()
|
||||||
.source(CoverState.CLOSING)
|
.source(CoverState.CLOSING)
|
||||||
.target(CoverState.ERROR)
|
.target(CoverState.ERROR)
|
||||||
.event(CoverEvent.ERROR)
|
.event(CoverEvent.ERROR)
|
||||||
|
.action(strategy.getErrorAction())
|
||||||
.and()
|
.and()
|
||||||
|
|
||||||
// RESET from ERROR
|
// RESET from ERROR
|
||||||
.withExternal()
|
.withExternal()
|
||||||
.source(CoverState.ERROR)
|
.source(CoverState.ERROR)
|
||||||
.target(CoverState.CLOSED)
|
.target(CoverState.CLOSED)
|
||||||
.event(CoverEvent.RESET);
|
.event(CoverEvent.RESET)
|
||||||
|
.action(strategy.getResetAction());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,169 @@
|
||||||
|
package com.tuoheng.status.airport.demo;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.manager.AirportSystemManager;
|
||||||
|
import com.tuoheng.status.airport.platform.PlatformType;
|
||||||
|
import com.tuoheng.status.airport.platform.factory.PlatformStrategyFactory;
|
||||||
|
import com.tuoheng.status.airport.platform.repository.AirportPlatformRepository;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多平台演示程序
|
||||||
|
* 演示DJI、AUTEL、YUNEEC等多个平台同时运行的场景
|
||||||
|
*/
|
||||||
|
public class MultiPlatformDemo {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
|
||||||
|
// 创建 Spring 上下文
|
||||||
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||||
|
|
||||||
|
// 扫描所有组件
|
||||||
|
context.scan("com.tuoheng.status.airport");
|
||||||
|
context.refresh();
|
||||||
|
|
||||||
|
// 获取必要的Bean
|
||||||
|
AirportSystemManager systemManager = context.getBean(AirportSystemManager.class);
|
||||||
|
PlatformStrategyFactory strategyFactory = context.getBean(PlatformStrategyFactory.class);
|
||||||
|
AirportPlatformRepository repository = context.getBean(AirportPlatformRepository.class);
|
||||||
|
|
||||||
|
System.out.println("\n========== 多平台机巢系统演示开始 ==========\n");
|
||||||
|
|
||||||
|
// ==================== 场景1: 多平台机巢上线 ====================
|
||||||
|
System.out.println("【场景1】多平台机巢上线");
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
|
||||||
|
String djiAirport = "airport-001"; // DJI平台
|
||||||
|
String autelAirport = "airport-002"; // AUTEL平台
|
||||||
|
String djiAirport2 = "airport-003"; // DJI平台
|
||||||
|
|
||||||
|
System.out.println("1. DJI机巢上线: " + djiAirport);
|
||||||
|
System.out.println(" 平台类型: " + strategyFactory.getPlatformType(djiAirport).getName());
|
||||||
|
systemManager.airportOnline(djiAirport);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(djiAirport));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
System.out.println("2. AUTEL机巢上线: " + autelAirport);
|
||||||
|
System.out.println(" 平台类型: " + strategyFactory.getPlatformType(autelAirport).getName());
|
||||||
|
systemManager.airportOnline(autelAirport);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(autelAirport));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
System.out.println("3. 另一个DJI机巢上线: " + djiAirport2);
|
||||||
|
System.out.println(" 平台类型: " + strategyFactory.getPlatformType(djiAirport2).getName());
|
||||||
|
systemManager.airportOnline(djiAirport2);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(djiAirport2));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
// ==================== 场景2: DJI平台开舱流程 ====================
|
||||||
|
System.out.println("【场景2】DJI平台开舱流程");
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
|
||||||
|
System.out.println("4. DJI机巢开启调试模式: " + djiAirport);
|
||||||
|
systemManager.openDebugMode(djiAirport);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(djiAirport));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
System.out.println("5. DJI机巢开舱: " + djiAirport);
|
||||||
|
systemManager.openCover(djiAirport);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(djiAirport));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
System.out.println("6. DJI机巢舱门打开完成: " + djiAirport);
|
||||||
|
systemManager.coverOpened(djiAirport);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(djiAirport));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
// ==================== 场景3: AUTEL平台开舱流程(同时进行) ====================
|
||||||
|
System.out.println("【场景3】AUTEL平台开舱流程(与DJI平台并行)");
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
|
||||||
|
System.out.println("7. AUTEL机巢开启调试模式: " + autelAirport);
|
||||||
|
systemManager.openDebugMode(autelAirport);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(autelAirport));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
System.out.println("8. AUTEL机巢开舱: " + autelAirport);
|
||||||
|
systemManager.openCover(autelAirport);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(autelAirport));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
// ==================== 场景4: 查看所有机巢状态 ====================
|
||||||
|
System.out.println("【场景4】查看所有机巢当前状态");
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
System.out.println("DJI机巢-001: " + systemManager.getFullStatus(djiAirport));
|
||||||
|
System.out.println("AUTEL机巢-002: " + systemManager.getFullStatus(autelAirport));
|
||||||
|
System.out.println("DJI机巢-003: " + systemManager.getFullStatus(djiAirport2));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
// ==================== 场景5: DJI机巢关舱 ====================
|
||||||
|
System.out.println("【场景5】DJI机巢关舱流程");
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
|
||||||
|
System.out.println("9. DJI机巢关舱: " + djiAirport);
|
||||||
|
systemManager.closeCover(djiAirport);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(djiAirport));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
System.out.println("10. DJI机巢舱门关闭完成: " + djiAirport);
|
||||||
|
systemManager.coverClosed(djiAirport);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(djiAirport));
|
||||||
|
System.out.println();
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
// ==================== 场景6: 动态注册新平台机巢 ====================
|
||||||
|
System.out.println("【场景6】动态注册新平台机巢");
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
|
||||||
|
String yuneecAirport = "airport-004";
|
||||||
|
System.out.println("11. 注册YUNEEC平台机巢: " + yuneecAirport);
|
||||||
|
System.out.println(" 平台类型: " + strategyFactory.getPlatformType(yuneecAirport).getName());
|
||||||
|
systemManager.airportOnline(yuneecAirport);
|
||||||
|
System.out.println(" " + systemManager.getFullStatus(yuneecAirport));
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
// ==================== 场景7: 最终状态汇总 ====================
|
||||||
|
System.out.println("【场景7】所有机巢最终状态汇总");
|
||||||
|
System.out.println("----------------------------------------");
|
||||||
|
System.out.println(String.format("%-20s %-15s %s", "机巢SN", "平台类型", "状态"));
|
||||||
|
System.out.println("------------------------------------------------------------");
|
||||||
|
System.out.println(String.format("%-20s %-15s %s",
|
||||||
|
djiAirport,
|
||||||
|
strategyFactory.getPlatformType(djiAirport).getName(),
|
||||||
|
systemManager.getFullStatus(djiAirport)));
|
||||||
|
System.out.println(String.format("%-20s %-15s %s",
|
||||||
|
autelAirport,
|
||||||
|
strategyFactory.getPlatformType(autelAirport).getName(),
|
||||||
|
systemManager.getFullStatus(autelAirport)));
|
||||||
|
System.out.println(String.format("%-20s %-15s %s",
|
||||||
|
djiAirport2,
|
||||||
|
strategyFactory.getPlatformType(djiAirport2).getName(),
|
||||||
|
systemManager.getFullStatus(djiAirport2)));
|
||||||
|
System.out.println(String.format("%-20s %-15s %s",
|
||||||
|
yuneecAirport,
|
||||||
|
strategyFactory.getPlatformType(yuneecAirport).getName(),
|
||||||
|
systemManager.getFullStatus(yuneecAirport)));
|
||||||
|
System.out.println();
|
||||||
|
|
||||||
|
System.out.println("\n========== 多平台机巢系统演示结束 ==========\n");
|
||||||
|
|
||||||
|
System.out.println("✅ 多平台架构优势:");
|
||||||
|
System.out.println(" 1. 支持多个无人机平台(DJI、AUTEL、YUNEEC等)");
|
||||||
|
System.out.println(" 2. 各平台独立实现Guard、Action和Listener");
|
||||||
|
System.out.println(" 3. 通过数据库配置平台映射关系");
|
||||||
|
System.out.println(" 4. 多个平台可以同时运行,互不干扰");
|
||||||
|
System.out.println(" 5. 易于扩展新平台,只需实现对应的Strategy接口");
|
||||||
|
System.out.println(" 6. 默认Listener提供基础功能,各平台可定制");
|
||||||
|
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
package com.tuoheng.status.airport.listener;
|
|
||||||
|
|
||||||
import com.tuoheng.status.airport.events.AirportEvent;
|
|
||||||
import com.tuoheng.status.airport.status.AirportState;
|
|
||||||
import com.tuoheng.status.statemachine.events.Event;
|
|
||||||
import com.tuoheng.status.statemachine.status.Status;
|
|
||||||
import org.springframework.messaging.Message;
|
|
||||||
import org.springframework.statemachine.StateContext;
|
|
||||||
import org.springframework.statemachine.StateMachine;
|
|
||||||
import org.springframework.statemachine.listener.StateMachineListener;
|
|
||||||
import org.springframework.statemachine.state.State;
|
|
||||||
import org.springframework.statemachine.transition.Transition;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class AirPortStatusListener implements StateMachineListener<AirportState, AirportEvent> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateChanged(State<AirportState, AirportEvent> state, State<AirportState, AirportEvent> state1) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateEntered(State<AirportState, AirportEvent> state) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateExited(State<AirportState, AirportEvent> state) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eventNotAccepted(Message<AirportEvent> message) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transition(Transition<AirportState, AirportEvent> transition) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transitionStarted(Transition<AirportState, AirportEvent> transition) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void transitionEnded(Transition<AirportState, AirportEvent> transition) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateMachineStarted(StateMachine<AirportState, AirportEvent> stateMachine) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateMachineStopped(StateMachine<AirportState, AirportEvent> stateMachine) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateMachineError(StateMachine<AirportState, AirportEvent> stateMachine, Exception e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void extendedStateChanged(Object o, Object o1) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void stateContext(StateContext<AirportState, AirportEvent> stateContext) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.tuoheng.status.airport.listener;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformListener;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.messaging.Message;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.statemachine.StateMachine;
|
||||||
|
import org.springframework.statemachine.state.State;
|
||||||
|
import org.springframework.statemachine.transition.Transition;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认机巢状态监听器
|
||||||
|
* 提供基础的状态变化监听功能,各平台可以继承并定制
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DefaultAirportListener implements PlatformListener<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DefaultAirportListener";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateChanged(State<AirportState, AirportEvent> from, State<AirportState, AirportEvent> to) {
|
||||||
|
if (from != null && to != null) {
|
||||||
|
System.out.println(String.format("[%s] 状态变化: %s -> %s",
|
||||||
|
getName(), from.getId(), to.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateEntered(State<AirportState, AirportEvent> state) {
|
||||||
|
System.out.println(String.format("[%s] 进入状态: %s", getName(), state.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateExited(State<AirportState, AirportEvent> state) {
|
||||||
|
System.out.println(String.format("[%s] 退出状态: %s", getName(), state.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventNotAccepted(Message<AirportEvent> event) {
|
||||||
|
System.out.println(String.format("[%s] 事件未被接受: %s", getName(), event.getPayload()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transition(Transition<AirportState, AirportEvent> transition) {
|
||||||
|
// 默认不处理
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transitionStarted(Transition<AirportState, AirportEvent> transition) {
|
||||||
|
if (transition.getSource() != null && transition.getTarget() != null) {
|
||||||
|
System.out.println(String.format("[%s] 转换开始: %s -> %s",
|
||||||
|
getName(), transition.getSource().getId(), transition.getTarget().getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transitionEnded(Transition<AirportState, AirportEvent> transition) {
|
||||||
|
if (transition.getSource() != null && transition.getTarget() != null) {
|
||||||
|
System.out.println(String.format("[%s] 转换结束: %s -> %s",
|
||||||
|
getName(), transition.getSource().getId(), transition.getTarget().getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateMachineStarted(StateMachine<AirportState, AirportEvent> stateMachine) {
|
||||||
|
String machineId = (String) stateMachine.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[%s] 状态机启动: %s", getName(), machineId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateMachineStopped(StateMachine<AirportState, AirportEvent> stateMachine) {
|
||||||
|
String machineId = (String) stateMachine.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[%s] 状态机停止: %s", getName(), machineId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateMachineError(StateMachine<AirportState, AirportEvent> stateMachine, Exception exception) {
|
||||||
|
String machineId = (String) stateMachine.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.err.println(String.format("[%s] 状态机错误: %s, 异常: %s",
|
||||||
|
getName(), machineId, exception.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void extendedStateChanged(Object key, Object value) {
|
||||||
|
System.out.println(String.format("[%s] 扩展状态变化: %s = %s", getName(), key, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateContext(StateContext<AirportState, AirportEvent> stateContext) {
|
||||||
|
// 默认不处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.tuoheng.status.airport.listener;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformListener;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.messaging.Message;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.statemachine.StateMachine;
|
||||||
|
import org.springframework.statemachine.state.State;
|
||||||
|
import org.springframework.statemachine.transition.Transition;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认舱门状态监听器
|
||||||
|
* 提供基础的状态变化监听功能,各平台可以继承并定制
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DefaultCoverListener implements PlatformListener<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DefaultCoverListener";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateChanged(State<CoverState, CoverEvent> from, State<CoverState, CoverEvent> to) {
|
||||||
|
if (from != null && to != null) {
|
||||||
|
System.out.println(String.format("[%s] 状态变化: %s -> %s",
|
||||||
|
getName(), from.getId(), to.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateEntered(State<CoverState, CoverEvent> state) {
|
||||||
|
System.out.println(String.format("[%s] 进入状态: %s", getName(), state.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateExited(State<CoverState, CoverEvent> state) {
|
||||||
|
System.out.println(String.format("[%s] 退出状态: %s", getName(), state.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventNotAccepted(Message<CoverEvent> event) {
|
||||||
|
System.out.println(String.format("[%s] 事件未被接受: %s", getName(), event.getPayload()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transition(Transition<CoverState, CoverEvent> transition) {
|
||||||
|
// 默认不处理
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transitionStarted(Transition<CoverState, CoverEvent> transition) {
|
||||||
|
if (transition.getSource() != null && transition.getTarget() != null) {
|
||||||
|
System.out.println(String.format("[%s] 转换开始: %s -> %s",
|
||||||
|
getName(), transition.getSource().getId(), transition.getTarget().getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transitionEnded(Transition<CoverState, CoverEvent> transition) {
|
||||||
|
if (transition.getSource() != null && transition.getTarget() != null) {
|
||||||
|
System.out.println(String.format("[%s] 转换结束: %s -> %s",
|
||||||
|
getName(), transition.getSource().getId(), transition.getTarget().getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateMachineStarted(StateMachine<CoverState, CoverEvent> stateMachine) {
|
||||||
|
String machineId = (String) stateMachine.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[%s] 状态机启动: %s", getName(), machineId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateMachineStopped(StateMachine<CoverState, CoverEvent> stateMachine) {
|
||||||
|
String machineId = (String) stateMachine.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[%s] 状态机停止: %s", getName(), machineId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateMachineError(StateMachine<CoverState, CoverEvent> stateMachine, Exception exception) {
|
||||||
|
String machineId = (String) stateMachine.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.err.println(String.format("[%s] 状态机错误: %s, 异常: %s",
|
||||||
|
getName(), machineId, exception.getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void extendedStateChanged(Object key, Object value) {
|
||||||
|
System.out.println(String.format("[%s] 扩展状态变化: %s = %s", getName(), key, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateContext(StateContext<CoverState, CoverEvent> stateContext) {
|
||||||
|
// 默认不处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,41 +17,41 @@ import org.springframework.stereotype.Component;
|
||||||
public class AirportSystemManager {
|
public class AirportSystemManager {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private AirportMachineService airportManager;
|
private AirportMachineService airportService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CoverMachineService coverManager;
|
private CoverMachineService coverService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 机巢上线
|
* 机巢上线
|
||||||
*/
|
*/
|
||||||
public boolean airportOnline(String airportSn) {
|
public boolean airportOnline(String airportSn) {
|
||||||
return airportManager.sendEvent(airportSn, AirportEvent.AIRPORT_ONLINE);
|
return airportService.sendEvent(airportSn, AirportEvent.AIRPORT_ONLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 机巢离线
|
* 机巢离线
|
||||||
*/
|
*/
|
||||||
public boolean airportOffline(String airportSn) {
|
public boolean airportOffline(String airportSn) {
|
||||||
return airportManager.sendEvent(airportSn, AirportEvent.AIRPORT_OFFLINE);
|
return airportService.sendEvent(airportSn, AirportEvent.AIRPORT_OFFLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开启调试模式
|
* 开启调试模式
|
||||||
*/
|
*/
|
||||||
public boolean openDebugMode(String airportSn) {
|
public boolean openDebugMode(String airportSn) {
|
||||||
if (!airportManager.isInState(airportSn, AirportState.ONLINE)) {
|
if (!airportService.isInState(airportSn, AirportState.ONLINE)) {
|
||||||
System.out.println("机巢未在线,无法开启调试模式");
|
System.out.println("机巢未在线,无法开启调试模式");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return airportManager.sendEvent(airportSn, AirportEvent.DEBUG_MODE_OPEN);
|
return airportService.sendEvent(airportSn, AirportEvent.DEBUG_MODE_OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭调试模式
|
* 关闭调试模式
|
||||||
*/
|
*/
|
||||||
public boolean closeDebugMode(String airportSn) {
|
public boolean closeDebugMode(String airportSn) {
|
||||||
return airportManager.sendEvent(airportSn, AirportEvent.DEBUG_MODE_CLOSE);
|
return airportService.sendEvent(airportSn, AirportEvent.DEBUG_MODE_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,26 +59,26 @@ public class AirportSystemManager {
|
||||||
*/
|
*/
|
||||||
public boolean openCover(String airportSn) {
|
public boolean openCover(String airportSn) {
|
||||||
// 检查机巢是否在调试模式
|
// 检查机巢是否在调试模式
|
||||||
if (!airportManager.isInState(airportSn, AirportState.DEBUG_MODE)) {
|
if (!airportService.isInState(airportSn, AirportState.DEBUG_MODE)) {
|
||||||
System.out.println("必须在调试模式下才能开舱");
|
System.out.println("必须在调试模式下才能开舱");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查舱门是否已经打开
|
// 检查舱门是否已经打开
|
||||||
if (coverManager.isInState(airportSn, CoverState.OPENED)) {
|
if (coverService.isInState(airportSn, CoverState.OPENED)) {
|
||||||
System.out.println("舱门已经打开");
|
System.out.println("舱门已经打开");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送开舱指令到舱门状态机
|
// 发送开舱指令到舱门状态机
|
||||||
return coverManager.sendEvent(airportSn, CoverEvent.OPEN);
|
return coverService.sendEvent(airportSn, CoverEvent.OPEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 舱门打开完成
|
* 舱门打开完成
|
||||||
*/
|
*/
|
||||||
public boolean coverOpened(String airportSn) {
|
public boolean coverOpened(String airportSn) {
|
||||||
return coverManager.sendEvent(airportSn, CoverEvent.OPENED);
|
return coverService.sendEvent(airportSn, CoverEvent.OPENED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -86,58 +86,58 @@ public class AirportSystemManager {
|
||||||
*/
|
*/
|
||||||
public boolean closeCover(String airportSn) {
|
public boolean closeCover(String airportSn) {
|
||||||
// 检查机巢是否在调试模式
|
// 检查机巢是否在调试模式
|
||||||
if (!airportManager.isInState(airportSn, AirportState.DEBUG_MODE)) {
|
if (!airportService.isInState(airportSn, AirportState.DEBUG_MODE)) {
|
||||||
System.out.println("必须在调试模式下才能关舱");
|
System.out.println("必须在调试模式下才能关舱");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查舱门是否已经关闭
|
// 检查舱门是否已经关闭
|
||||||
if (coverManager.isInState(airportSn, CoverState.CLOSED)) {
|
if (coverService.isInState(airportSn, CoverState.CLOSED)) {
|
||||||
System.out.println("舱门已经关闭");
|
System.out.println("舱门已经关闭");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发送关舱指令到舱门状态机
|
// 发送关舱指令到舱门状态机
|
||||||
return coverManager.sendEvent(airportSn, CoverEvent.CLOSE);
|
return coverService.sendEvent(airportSn, CoverEvent.CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 舱门关闭完成
|
* 舱门关闭完成
|
||||||
*/
|
*/
|
||||||
public boolean coverClosed(String airportSn) {
|
public boolean coverClosed(String airportSn) {
|
||||||
return coverManager.sendEvent(airportSn, CoverEvent.CLOSED);
|
return coverService.sendEvent(airportSn, CoverEvent.CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 机巢重启
|
* 机巢重启
|
||||||
*/
|
*/
|
||||||
public boolean rebootAirport(String airportSn) {
|
public boolean rebootAirport(String airportSn) {
|
||||||
if (!airportManager.isInState(airportSn, AirportState.DEBUG_MODE)) {
|
if (!airportService.isInState(airportSn, AirportState.DEBUG_MODE)) {
|
||||||
System.out.println("必须在调试模式下才能重启");
|
System.out.println("必须在调试模式下才能重启");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return airportManager.sendEvent(airportSn, AirportEvent.AIRPORT_REBOOT);
|
return airportService.sendEvent(airportSn, AirportEvent.AIRPORT_REBOOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重启完成
|
* 重启完成
|
||||||
*/
|
*/
|
||||||
public boolean rebootCompleted(String airportSn) {
|
public boolean rebootCompleted(String airportSn) {
|
||||||
return airportManager.sendEvent(airportSn, AirportEvent.REBOOT_COMPLETED);
|
return airportService.sendEvent(airportSn, AirportEvent.REBOOT_COMPLETED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取机巢状态
|
* 获取机巢状态
|
||||||
*/
|
*/
|
||||||
public AirportState getAirportState(String airportSn) {
|
public AirportState getAirportState(String airportSn) {
|
||||||
return airportManager.getCurrentState(airportSn);
|
return airportService.getCurrentState(airportSn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取舱门状态
|
* 获取舱门状态
|
||||||
*/
|
*/
|
||||||
public CoverState getCoverState(String airportSn) {
|
public CoverState getCoverState(String airportSn) {
|
||||||
return coverManager.getCurrentState(airportSn);
|
return coverService.getCurrentState(airportSn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.tuoheng.status.airport.platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无人机平台类型枚举
|
||||||
|
*/
|
||||||
|
public enum PlatformType {
|
||||||
|
/**
|
||||||
|
* 大疆平台
|
||||||
|
*/
|
||||||
|
DJI("DJI", "大疆"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 道通平台
|
||||||
|
*/
|
||||||
|
AUTEL("AUTEL", "道通"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 昊翔平台
|
||||||
|
*/
|
||||||
|
YUNEEC("YUNEEC", "昊翔");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
PlatformType(String code, String name) {
|
||||||
|
this.code = code;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据code获取平台类型
|
||||||
|
*/
|
||||||
|
public static PlatformType fromCode(String code) {
|
||||||
|
for (PlatformType type : values()) {
|
||||||
|
if (type.code.equalsIgnoreCase(code)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown platform code: " + code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
package com.tuoheng.status.airport.platform.factory;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.platform.PlatformType;
|
||||||
|
import com.tuoheng.status.airport.platform.repository.AirportPlatformRepository;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.AirportPlatformStrategy;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.CoverPlatformStrategy;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台策略工厂
|
||||||
|
* 根据机巢SN从数据库查询平台类型,返回对应的平台策略
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class PlatformStrategyFactory {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AirportPlatformRepository airportPlatformRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储所有机巢平台策略实现
|
||||||
|
* Key: PlatformType
|
||||||
|
* Value: AirportPlatformStrategy实现
|
||||||
|
*/
|
||||||
|
private final Map<PlatformType, AirportPlatformStrategy> airportStrategyMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储所有舱门平台策略实现
|
||||||
|
* Key: PlatformType
|
||||||
|
* Value: CoverPlatformStrategy实现
|
||||||
|
*/
|
||||||
|
private final Map<PlatformType, CoverPlatformStrategy> coverStrategyMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册所有平台策略
|
||||||
|
* Spring会自动注入所有实现了AirportPlatformStrategy和CoverPlatformStrategy的Bean
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
public void registerStrategies(
|
||||||
|
List<AirportPlatformStrategy> airportStrategies,
|
||||||
|
List<CoverPlatformStrategy> coverStrategies) {
|
||||||
|
|
||||||
|
// 注册机巢策略
|
||||||
|
for (AirportPlatformStrategy strategy : airportStrategies) {
|
||||||
|
airportStrategyMap.put(strategy.getPlatformType(), strategy);
|
||||||
|
System.out.println(String.format("注册机巢平台策略: %s -> %s",
|
||||||
|
strategy.getPlatformType().getName(), strategy.getClass().getSimpleName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册舱门策略
|
||||||
|
for (CoverPlatformStrategy strategy : coverStrategies) {
|
||||||
|
coverStrategyMap.put(strategy.getPlatformType(), strategy);
|
||||||
|
System.out.println(String.format("注册舱门平台策略: %s -> %s",
|
||||||
|
strategy.getPlatformType().getName(), strategy.getClass().getSimpleName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据机巢SN获取机巢平台策略
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return 机巢平台策略
|
||||||
|
* @throws IllegalArgumentException 如果机巢未注册或平台策略不存在
|
||||||
|
*/
|
||||||
|
public AirportPlatformStrategy getAirportStrategy(String airportSn) {
|
||||||
|
// 从数据库查询平台类型
|
||||||
|
PlatformType platformType = airportPlatformRepository.getPlatformType(airportSn);
|
||||||
|
|
||||||
|
if (platformType == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("机巢未注册或平台类型未配置: %s", airportSn));
|
||||||
|
}
|
||||||
|
|
||||||
|
AirportPlatformStrategy strategy = airportStrategyMap.get(platformType);
|
||||||
|
|
||||||
|
if (strategy == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("未找到平台策略: %s (机巢: %s)", platformType.getName(), airportSn));
|
||||||
|
}
|
||||||
|
|
||||||
|
return strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据机巢SN获取舱门平台策略
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return 舱门平台策略
|
||||||
|
* @throws IllegalArgumentException 如果机巢未注册或平台策略不存在
|
||||||
|
*/
|
||||||
|
public CoverPlatformStrategy getCoverStrategy(String airportSn) {
|
||||||
|
// 从数据库查询平台类型
|
||||||
|
PlatformType platformType = airportPlatformRepository.getPlatformType(airportSn);
|
||||||
|
|
||||||
|
if (platformType == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("机巢未注册或平台类型未配置: %s", airportSn));
|
||||||
|
}
|
||||||
|
|
||||||
|
CoverPlatformStrategy strategy = coverStrategyMap.get(platformType);
|
||||||
|
|
||||||
|
if (strategy == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("未找到平台策略: %s (机巢: %s)", platformType.getName(), airportSn));
|
||||||
|
}
|
||||||
|
|
||||||
|
return strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据平台类型获取机巢平台策略
|
||||||
|
*
|
||||||
|
* @param platformType 平台类型
|
||||||
|
* @return 机巢平台策略
|
||||||
|
*/
|
||||||
|
public AirportPlatformStrategy getAirportStrategyByType(PlatformType platformType) {
|
||||||
|
return airportStrategyMap.get(platformType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据平台类型获取舱门平台策略
|
||||||
|
*
|
||||||
|
* @param platformType 平台类型
|
||||||
|
* @return 舱门平台策略
|
||||||
|
*/
|
||||||
|
public CoverPlatformStrategy getCoverStrategyByType(PlatformType platformType) {
|
||||||
|
return coverStrategyMap.get(platformType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取机巢的平台类型
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return 平台类型
|
||||||
|
*/
|
||||||
|
public PlatformType getPlatformType(String airportSn) {
|
||||||
|
return airportPlatformRepository.getPlatformType(airportSn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.listener.DefaultAirportListener;
|
||||||
|
import com.tuoheng.status.airport.platform.PlatformType;
|
||||||
|
import com.tuoheng.status.airport.platform.impl.dji.action.airport.*;
|
||||||
|
import com.tuoheng.status.airport.platform.impl.dji.guard.airport.*;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.AirportPlatformStrategy;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformListener;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DJI平台机巢策略实现
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DjiAirportPlatformStrategy implements AirportPlatformStrategy {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCanOnlineGuard canOnlineGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCanOfflineGuard canOfflineGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiIsDebugModeGuard isDebugModeGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiIsNotDebugModeGuard isNotDebugModeGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCanCloseDebugModeGuard canCloseDebugModeGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiIsRebootCompletedGuard isRebootCompletedGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiOnlineAction onlineAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiOfflineAction offlineAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiOpenDebugModeAction openDebugModeAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCloseDebugModeAction closeDebugModeAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiRebootAction rebootAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiRebootCompletedAction rebootCompletedAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DJI平台的Listener实例(单例,所有DJI机巢共享)
|
||||||
|
*/
|
||||||
|
private final PlatformListener<AirportState, AirportEvent> djiListener = new DefaultAirportListener() {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiAirportListener";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformType getPlatformType() {
|
||||||
|
return PlatformType.DJI;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<AirportState, AirportEvent> getCanOnlineGuard() {
|
||||||
|
return canOnlineGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<AirportState, AirportEvent> getCanOfflineGuard() {
|
||||||
|
return canOfflineGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<AirportState, AirportEvent> getIsDebugModeGuard() {
|
||||||
|
return isDebugModeGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<AirportState, AirportEvent> getIsNotDebugModeGuard() {
|
||||||
|
return isNotDebugModeGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<AirportState, AirportEvent> getCanCloseDebugModeGuard() {
|
||||||
|
return canCloseDebugModeGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<AirportState, AirportEvent> getIsRebootCompletedGuard() {
|
||||||
|
return isRebootCompletedGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<AirportState, AirportEvent> getOnlineAction() {
|
||||||
|
return onlineAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<AirportState, AirportEvent> getOfflineAction() {
|
||||||
|
return offlineAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<AirportState, AirportEvent> getOpenDebugModeAction() {
|
||||||
|
return openDebugModeAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<AirportState, AirportEvent> getCloseDebugModeAction() {
|
||||||
|
return closeDebugModeAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<AirportState, AirportEvent> getRebootAction() {
|
||||||
|
return rebootAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<AirportState, AirportEvent> getRebootCompletedAction() {
|
||||||
|
return rebootCompletedAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformListener<AirportState, AirportEvent> getListener() {
|
||||||
|
// 返回DJI平台的Listener单例
|
||||||
|
// 所有DJI机巢共享这个Listener实例
|
||||||
|
return djiListener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,123 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.listener.DefaultCoverListener;
|
||||||
|
import com.tuoheng.status.airport.platform.PlatformType;
|
||||||
|
import com.tuoheng.status.airport.platform.impl.dji.action.cover.*;
|
||||||
|
import com.tuoheng.status.airport.platform.impl.dji.guard.cover.*;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.CoverPlatformStrategy;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformListener;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DJI平台舱门策略实现
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DjiCoverPlatformStrategy implements CoverPlatformStrategy {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCanOpenCoverGuard canOpenGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCanCloseCoverGuard canCloseGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiIsCoverOpenedGuard isOpenedGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiIsCoverClosedGuard isClosedGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiOpenCoverAction openAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCoverOpenedAction openedAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCloseCoverAction closeAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCoverClosedAction closedAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCoverErrorAction errorAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCoverResetAction resetAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DJI平台的舱门Listener实例(单例,所有DJI机巢共享)
|
||||||
|
*/
|
||||||
|
private final PlatformListener<CoverState, CoverEvent> djiCoverListener = new com.tuoheng.status.airport.listener.DefaultCoverListener() {
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCoverListener";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformType getPlatformType() {
|
||||||
|
return PlatformType.DJI;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<CoverState, CoverEvent> getCanOpenGuard() {
|
||||||
|
return canOpenGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<CoverState, CoverEvent> getCanCloseGuard() {
|
||||||
|
return canCloseGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<CoverState, CoverEvent> getIsOpenedGuard() {
|
||||||
|
return isOpenedGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<CoverState, CoverEvent> getIsClosedGuard() {
|
||||||
|
return isClosedGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<CoverState, CoverEvent> getOpenAction() {
|
||||||
|
return openAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<CoverState, CoverEvent> getOpenedAction() {
|
||||||
|
return openedAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<CoverState, CoverEvent> getCloseAction() {
|
||||||
|
return closeAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<CoverState, CoverEvent> getClosedAction() {
|
||||||
|
return closedAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<CoverState, CoverEvent> getErrorAction() {
|
||||||
|
return errorAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<CoverState, CoverEvent> getResetAction() {
|
||||||
|
return resetAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformListener<CoverState, CoverEvent> getListener() {
|
||||||
|
// 返回DJI平台的舱门Listener单例
|
||||||
|
// 所有DJI机巢共享这个Listener实例
|
||||||
|
return djiCoverListener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiCloseDebugModeAction implements PlatformAction<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCloseDebugModeAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 关闭调试模式: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiOfflineAction implements PlatformAction<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiOfflineAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 机巢离线: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiOnlineAction implements PlatformAction<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiOnlineAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 机巢上线: %s", machineId));
|
||||||
|
// DJI平台特定的上线逻辑
|
||||||
|
// 例如:初始化DJI SDK连接、注册设备等
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiOpenDebugModeAction implements PlatformAction<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiOpenDebugModeAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 开启调试模式: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiRebootAction implements PlatformAction<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiRebootAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 机巢重启: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiRebootCompletedAction implements PlatformAction<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiRebootCompletedAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 重启完成: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.cover;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiCloseCoverAction implements PlatformAction<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCloseCoverAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<CoverState, CoverEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 开始关舱: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.cover;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiCoverClosedAction implements PlatformAction<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCoverClosedAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<CoverState, CoverEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 舱门已关闭: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.cover;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiCoverErrorAction implements PlatformAction<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCoverErrorAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<CoverState, CoverEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 舱门错误: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.cover;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiCoverOpenedAction implements PlatformAction<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCoverOpenedAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<CoverState, CoverEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 舱门已打开: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.cover;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiCoverResetAction implements PlatformAction<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCoverResetAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<CoverState, CoverEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 舱门重置: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.action.cover;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiOpenCoverAction implements PlatformAction<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiOpenCoverAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<CoverState, CoverEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 开始开舱: %s", machineId));
|
||||||
|
// DJI平台特定的开舱逻辑
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.guard.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiCanCloseDebugModeGuard implements PlatformGuard<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCanCloseDebugModeGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
System.out.println("[DJI] 检查是否可以关闭调试模式");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.guard.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiCanOfflineGuard implements PlatformGuard<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCanOfflineGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
System.out.println("[DJI] 检查机巢是否可以离线");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.guard.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DJI平台 - 机巢上线Guard
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DjiCanOnlineGuard implements PlatformGuard<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCanOnlineGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
// DJI平台特定的上线检查逻辑
|
||||||
|
System.out.println("[DJI] 检查机巢是否可以上线");
|
||||||
|
// 这里可以添加DJI平台特定的检查逻辑,例如:
|
||||||
|
// - 检查DJI设备连接状态
|
||||||
|
// - 检查DJI固件版本
|
||||||
|
// - 检查DJI授权状态
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.guard.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiIsDebugModeGuard implements PlatformGuard<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiIsDebugModeGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
System.out.println("[DJI] 检查是否处于调试模式");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.guard.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiIsNotDebugModeGuard implements PlatformGuard<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiIsNotDebugModeGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
System.out.println("[DJI] 检查是否不在调试模式");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.guard.airport;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiIsRebootCompletedGuard implements PlatformGuard<AirportState, AirportEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiIsRebootCompletedGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<AirportState, AirportEvent> context) {
|
||||||
|
System.out.println("[DJI] 检查重启是否完成");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.guard.cover;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiCanCloseCoverGuard implements PlatformGuard<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCanCloseCoverGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<CoverState, CoverEvent> context) {
|
||||||
|
System.out.println("[DJI] 检查舱门是否可以关闭");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.guard.cover;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiCanOpenCoverGuard implements PlatformGuard<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCanOpenCoverGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<CoverState, CoverEvent> context) {
|
||||||
|
System.out.println("[DJI] 检查舱门是否可以打开");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.guard.cover;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiIsCoverClosedGuard implements PlatformGuard<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiIsCoverClosedGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<CoverState, CoverEvent> context) {
|
||||||
|
System.out.println("[DJI] 检查舱门是否已关闭");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.impl.dji.guard.cover;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiIsCoverOpenedGuard implements PlatformGuard<CoverState, CoverEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiIsCoverOpenedGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<CoverState, CoverEvent> context) {
|
||||||
|
System.out.println("[DJI] 检查舱门是否已打开");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.tuoheng.status.airport.platform.repository;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.platform.PlatformType;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 机巢平台映射仓储
|
||||||
|
* 模拟数据库查询,存储机巢SN到平台类型的映射关系
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public class AirportPlatformRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模拟数据库存储
|
||||||
|
* Key: 机巢SN
|
||||||
|
* Value: 平台类型
|
||||||
|
*/
|
||||||
|
private final Map<String, PlatformType> airportPlatformMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化一些测试数据
|
||||||
|
*/
|
||||||
|
public AirportPlatformRepository() {
|
||||||
|
// 模拟数据库中的数据
|
||||||
|
airportPlatformMap.put("airport-001", PlatformType.DJI);
|
||||||
|
airportPlatformMap.put("airport-002", PlatformType.DJI);
|
||||||
|
airportPlatformMap.put("airport-003", PlatformType.DJI);
|
||||||
|
airportPlatformMap.put("airport-004", PlatformType.DJI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据机巢SN查询平台类型
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return 平台类型,如果不存在返回null
|
||||||
|
*/
|
||||||
|
public PlatformType getPlatformType(String airportSn) {
|
||||||
|
return airportPlatformMap.get(airportSn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存机巢平台映射关系
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @param platformType 平台类型
|
||||||
|
*/
|
||||||
|
public void savePlatformMapping(String airportSn, PlatformType platformType) {
|
||||||
|
airportPlatformMap.put(airportSn, platformType);
|
||||||
|
System.out.println(String.format("保存平台映射: %s -> %s", airportSn, platformType.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除机巢平台映射关系
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
*/
|
||||||
|
public void deletePlatformMapping(String airportSn) {
|
||||||
|
airportPlatformMap.remove(airportSn);
|
||||||
|
System.out.println(String.format("删除平台映射: %s", airportSn));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查机巢是否已注册
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return 是否已注册
|
||||||
|
*/
|
||||||
|
public boolean exists(String airportSn) {
|
||||||
|
return airportPlatformMap.containsKey(airportSn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.tuoheng.status.airport.platform.strategy;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.AirportEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.PlatformType;
|
||||||
|
import com.tuoheng.status.airport.status.AirportState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 机巢平台策略接口
|
||||||
|
* 定义各平台需要实现的Guard、Action和Listener
|
||||||
|
*/
|
||||||
|
public interface AirportPlatformStrategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台类型
|
||||||
|
*/
|
||||||
|
PlatformType getPlatformType();
|
||||||
|
|
||||||
|
// ==================== Guards ====================
|
||||||
|
|
||||||
|
PlatformGuard<AirportState, AirportEvent> getCanOnlineGuard();
|
||||||
|
|
||||||
|
PlatformGuard<AirportState, AirportEvent> getCanOfflineGuard();
|
||||||
|
|
||||||
|
PlatformGuard<AirportState, AirportEvent> getIsDebugModeGuard();
|
||||||
|
|
||||||
|
PlatformGuard<AirportState, AirportEvent> getIsNotDebugModeGuard();
|
||||||
|
|
||||||
|
PlatformGuard<AirportState, AirportEvent> getCanCloseDebugModeGuard();
|
||||||
|
|
||||||
|
PlatformGuard<AirportState, AirportEvent> getIsRebootCompletedGuard();
|
||||||
|
|
||||||
|
// ==================== Actions ====================
|
||||||
|
|
||||||
|
PlatformAction<AirportState, AirportEvent> getOnlineAction();
|
||||||
|
|
||||||
|
PlatformAction<AirportState, AirportEvent> getOfflineAction();
|
||||||
|
|
||||||
|
PlatformAction<AirportState, AirportEvent> getOpenDebugModeAction();
|
||||||
|
|
||||||
|
PlatformAction<AirportState, AirportEvent> getCloseDebugModeAction();
|
||||||
|
|
||||||
|
PlatformAction<AirportState, AirportEvent> getRebootAction();
|
||||||
|
|
||||||
|
PlatformAction<AirportState, AirportEvent> getRebootCompletedAction();
|
||||||
|
|
||||||
|
// ==================== Listener ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台Listener
|
||||||
|
* 每个平台有一个Listener实例,所有该平台的机巢共享
|
||||||
|
*/
|
||||||
|
PlatformListener<AirportState, AirportEvent> getListener();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.tuoheng.status.airport.platform.strategy;
|
||||||
|
|
||||||
|
import com.tuoheng.status.airport.events.CoverEvent;
|
||||||
|
import com.tuoheng.status.airport.platform.PlatformType;
|
||||||
|
import com.tuoheng.status.airport.status.CoverState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 舱门平台策略接口
|
||||||
|
* 定义各平台需要实现的Guard、Action和Listener
|
||||||
|
*/
|
||||||
|
public interface CoverPlatformStrategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台类型
|
||||||
|
*/
|
||||||
|
PlatformType getPlatformType();
|
||||||
|
|
||||||
|
// ==================== Guards ====================
|
||||||
|
|
||||||
|
PlatformGuard<CoverState, CoverEvent> getCanOpenGuard();
|
||||||
|
|
||||||
|
PlatformGuard<CoverState, CoverEvent> getCanCloseGuard();
|
||||||
|
|
||||||
|
PlatformGuard<CoverState, CoverEvent> getIsOpenedGuard();
|
||||||
|
|
||||||
|
PlatformGuard<CoverState, CoverEvent> getIsClosedGuard();
|
||||||
|
|
||||||
|
// ==================== Actions ====================
|
||||||
|
|
||||||
|
PlatformAction<CoverState, CoverEvent> getOpenAction();
|
||||||
|
|
||||||
|
PlatformAction<CoverState, CoverEvent> getOpenedAction();
|
||||||
|
|
||||||
|
PlatformAction<CoverState, CoverEvent> getCloseAction();
|
||||||
|
|
||||||
|
PlatformAction<CoverState, CoverEvent> getClosedAction();
|
||||||
|
|
||||||
|
PlatformAction<CoverState, CoverEvent> getErrorAction();
|
||||||
|
|
||||||
|
PlatformAction<CoverState, CoverEvent> getResetAction();
|
||||||
|
|
||||||
|
// ==================== Listener ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台Listener
|
||||||
|
* 每个平台有一个Listener实例,所有该平台的机巢共享
|
||||||
|
*/
|
||||||
|
PlatformListener<CoverState, CoverEvent> getListener();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.strategy;
|
||||||
|
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.statemachine.action.Action;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台Action接口
|
||||||
|
* 各平台实现自己的Action逻辑
|
||||||
|
*/
|
||||||
|
public interface PlatformAction<S, E> extends Action<S, E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Action名称
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行Action
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
void execute(StateContext<S, E> context);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.airport.platform.strategy;
|
||||||
|
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.statemachine.guard.Guard;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台Guard接口
|
||||||
|
* 各平台实现自己的Guard逻辑
|
||||||
|
*/
|
||||||
|
public interface PlatformGuard<S, E> extends Guard<S, E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Guard名称
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评估Guard条件
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
boolean evaluate(StateContext<S, E> context);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.tuoheng.status.airport.platform.strategy;
|
||||||
|
|
||||||
|
import org.springframework.statemachine.listener.StateMachineListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台Listener接口
|
||||||
|
* 各平台可以定制自己的Listener逻辑
|
||||||
|
*/
|
||||||
|
public interface PlatformListener<S, E> extends StateMachineListener<S, E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取Listener名称
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue