添加DRC控制
This commit is contained in:
parent
a53c531b47
commit
a377485b23
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.tuoheng.status.machine.action.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base action for DRC enter handling; platform implementations extend this.
|
||||||
|
*/
|
||||||
|
public abstract class EnterAction implements PlatformAction<DrcState, DrcEvent> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.tuoheng.status.machine.action.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base action for DRC entered handling; platform implementations extend this.
|
||||||
|
*/
|
||||||
|
public abstract class EnteredAction implements PlatformAction<DrcState, DrcEvent> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.tuoheng.status.machine.action.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base action for DRC exit handling; platform implementations extend this.
|
||||||
|
*/
|
||||||
|
public abstract class ExitAction implements PlatformAction<DrcState, DrcEvent> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.tuoheng.status.machine.action.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base action for DRC exited handling; platform implementations extend this.
|
||||||
|
*/
|
||||||
|
public abstract class ExitedAction implements PlatformAction<DrcState, DrcEvent> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,144 @@
|
||||||
|
package com.tuoheng.status.machine.config;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.platform.factory.PlatformStrategyFactory;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.DrcPlatformStrategy;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.statemachine.StateMachine;
|
||||||
|
import org.springframework.statemachine.config.StateMachineBuilder;
|
||||||
|
import org.springframework.statemachine.config.StateMachineFactory;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DRC(飞行控制模式)状态机配置(多平台支持版本)
|
||||||
|
* 通过PlatformStrategyFactory动态获取平台特定的Guard、Action和Listener
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class DrcMachineConfig {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PlatformStrategyFactory platformStrategyFactory;
|
||||||
|
|
||||||
|
@Bean(name = "drcStateMachineFactory")
|
||||||
|
public StateMachineFactory<DrcState, DrcEvent> drcStateMachineFactory() throws Exception {
|
||||||
|
return new StateMachineFactory<DrcState, DrcEvent>() {
|
||||||
|
@Override
|
||||||
|
public StateMachine<DrcState, DrcEvent> getStateMachine() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StateMachine<DrcState, DrcEvent> getStateMachine(String machineId) {
|
||||||
|
try {
|
||||||
|
// 根据机巢SN获取平台策略
|
||||||
|
DrcPlatformStrategy strategy = platformStrategyFactory.getDrcStrategy(machineId);
|
||||||
|
|
||||||
|
StateMachineBuilder.Builder<DrcState, DrcEvent> builder = StateMachineBuilder.builder();
|
||||||
|
configureDrcStateMachine(builder, strategy);
|
||||||
|
configureDrcStates(builder);
|
||||||
|
configureDrcTransitions(builder, strategy);
|
||||||
|
|
||||||
|
StateMachine<DrcState, DrcEvent> stateMachine = builder.build();
|
||||||
|
stateMachine.getExtendedState().getVariables().put("machineId", machineId);
|
||||||
|
return stateMachine;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to create DRC state machine for: " + machineId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StateMachine<DrcState, DrcEvent> getStateMachine(UUID uuid) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureDrcStateMachine(
|
||||||
|
StateMachineBuilder.Builder<DrcState, DrcEvent> builder,
|
||||||
|
DrcPlatformStrategy strategy) throws Exception {
|
||||||
|
builder.configureConfiguration()
|
||||||
|
.withConfiguration()
|
||||||
|
.autoStartup(true)
|
||||||
|
.listener(strategy.getListener());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureDrcStates(StateMachineBuilder.Builder<DrcState, DrcEvent> builder) throws Exception {
|
||||||
|
builder.configureStates()
|
||||||
|
.withStates()
|
||||||
|
.initial(DrcState.UNKNOWN)
|
||||||
|
.states(EnumSet.allOf(DrcState.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureDrcTransitions(
|
||||||
|
StateMachineBuilder.Builder<DrcState, DrcEvent> builder,
|
||||||
|
DrcPlatformStrategy strategy) throws Exception {
|
||||||
|
builder.configureTransitions()
|
||||||
|
// ========== 从 UNKNOWN 到所有状态的转换(服务器重启后状态同步) ==========
|
||||||
|
// UNKNOWN -> EXITED
|
||||||
|
.withExternal()
|
||||||
|
.source(DrcState.UNKNOWN)
|
||||||
|
.target(DrcState.EXITED)
|
||||||
|
.event(DrcEvent.EXITED)
|
||||||
|
.and()
|
||||||
|
|
||||||
|
// UNKNOWN -> ENTERING
|
||||||
|
.withExternal()
|
||||||
|
.source(DrcState.UNKNOWN)
|
||||||
|
.target(DrcState.ENTERING)
|
||||||
|
.event(DrcEvent.ENTER)
|
||||||
|
.and()
|
||||||
|
|
||||||
|
// UNKNOWN -> ENTERED
|
||||||
|
.withExternal()
|
||||||
|
.source(DrcState.UNKNOWN)
|
||||||
|
.target(DrcState.ENTERED)
|
||||||
|
.event(DrcEvent.ENTERED)
|
||||||
|
.and()
|
||||||
|
|
||||||
|
// UNKNOWN -> EXITING
|
||||||
|
.withExternal()
|
||||||
|
.source(DrcState.UNKNOWN)
|
||||||
|
.target(DrcState.EXITING)
|
||||||
|
.event(DrcEvent.EXIT)
|
||||||
|
.and()
|
||||||
|
|
||||||
|
// ========== 正常状态转换(带 Guard 和 Action) ==========
|
||||||
|
// EXITED -> ENTERING
|
||||||
|
.withExternal()
|
||||||
|
.source(DrcState.EXITED)
|
||||||
|
.target(DrcState.ENTERING)
|
||||||
|
.event(DrcEvent.ENTER)
|
||||||
|
.action(strategy.getEnterAction())
|
||||||
|
.guard(strategy.getCanEnterGuard())
|
||||||
|
.and()
|
||||||
|
|
||||||
|
// ENTERING -> ENTERED
|
||||||
|
.withExternal()
|
||||||
|
.source(DrcState.ENTERING)
|
||||||
|
.target(DrcState.ENTERED)
|
||||||
|
.event(DrcEvent.ENTERED)
|
||||||
|
.action(strategy.getEnteredAction())
|
||||||
|
.and()
|
||||||
|
|
||||||
|
// ENTERED -> EXITING
|
||||||
|
.withExternal()
|
||||||
|
.source(DrcState.ENTERED)
|
||||||
|
.target(DrcState.EXITING)
|
||||||
|
.event(DrcEvent.EXIT)
|
||||||
|
.action(strategy.getExitAction())
|
||||||
|
.guard(strategy.getCanExitGuard())
|
||||||
|
.and()
|
||||||
|
|
||||||
|
// EXITING -> EXITED
|
||||||
|
.withExternal()
|
||||||
|
.source(DrcState.EXITING)
|
||||||
|
.target(DrcState.EXITED)
|
||||||
|
.event(DrcEvent.EXITED)
|
||||||
|
.action(strategy.getExitedAction());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.tuoheng.status.machine.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DRC(飞行控制模式)事件枚举
|
||||||
|
* 定义DRC状态机中的所有事件
|
||||||
|
*/
|
||||||
|
public enum DrcEvent {
|
||||||
|
/**
|
||||||
|
* 进入DRC模式指令
|
||||||
|
* 触发源: 用户指令
|
||||||
|
*/
|
||||||
|
ENTER,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进入DRC模式完成
|
||||||
|
* 触发源: Events事件
|
||||||
|
*/
|
||||||
|
ENTERED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出DRC模式指令
|
||||||
|
* 触发源: 用户指令/自动
|
||||||
|
*/
|
||||||
|
EXIT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出DRC模式完成
|
||||||
|
* 触发源: Events事件
|
||||||
|
*/
|
||||||
|
EXITED
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.tuoheng.status.machine.guard.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base guard for checking if can enter DRC mode; platform implementations extend this.
|
||||||
|
*/
|
||||||
|
public abstract class CanEnterGuard implements PlatformGuard<DrcState, DrcEvent> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.tuoheng.status.machine.guard.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base guard for checking if can exit DRC mode; platform implementations extend this.
|
||||||
|
*/
|
||||||
|
public abstract class CanExitGuard implements PlatformGuard<DrcState, DrcEvent> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
package com.tuoheng.status.machine.listener;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.PlatformListener;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认DRC状态监听器
|
||||||
|
* 提供基础的状态变化监听功能,各平台可以继承并定制
|
||||||
|
*/
|
||||||
|
public abstract class DefaultDrcListener implements PlatformListener<DrcState, DrcEvent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateChanged(State<DrcState, DrcEvent> from, State<DrcState, DrcEvent> to) {
|
||||||
|
if (from != null && to != null) {
|
||||||
|
System.out.println(String.format("[%s] 状态变化: %s -> %s",
|
||||||
|
getName(), from.getId(), to.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateEntered(State<DrcState, DrcEvent> state) {
|
||||||
|
System.out.println(String.format("[%s] 进入状态: %s", getName(), state.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateExited(State<DrcState, DrcEvent> state) {
|
||||||
|
System.out.println(String.format("[%s] 退出状态: %s", getName(), state.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eventNotAccepted(Message<DrcEvent> event) {
|
||||||
|
System.out.println(String.format("[%s] 事件未被接受: %s", getName(), event.getPayload()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transition(Transition<DrcState, DrcEvent> transition) {
|
||||||
|
// 默认不处理
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transitionStarted(Transition<DrcState, DrcEvent> 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<DrcState, DrcEvent> 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<DrcState, DrcEvent> stateMachine) {
|
||||||
|
String machineId = (String) stateMachine.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[%s] 状态机启动: %s", getName(), machineId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateMachineStopped(StateMachine<DrcState, DrcEvent> stateMachine) {
|
||||||
|
String machineId = (String) stateMachine.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[%s] 状态机停止: %s", getName(), machineId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateMachineError(StateMachine<DrcState, DrcEvent> 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<DrcState, DrcEvent> stateContext) {
|
||||||
|
// 默认不处理
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@ import com.tuoheng.status.machine.repository.AirportPlatformRepository;
|
||||||
import com.tuoheng.status.machine.platform.strategy.AirportPlatformStrategy;
|
import com.tuoheng.status.machine.platform.strategy.AirportPlatformStrategy;
|
||||||
import com.tuoheng.status.machine.platform.strategy.CoverPlatformStrategy;
|
import com.tuoheng.status.machine.platform.strategy.CoverPlatformStrategy;
|
||||||
import com.tuoheng.status.machine.platform.strategy.DronePlatformStrategy;
|
import com.tuoheng.status.machine.platform.strategy.DronePlatformStrategy;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.DrcPlatformStrategy;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|
@ -44,6 +45,13 @@ public class PlatformStrategyFactory {
|
||||||
*/
|
*/
|
||||||
private final Map<PlatformType, DronePlatformStrategy> droneStrategyMap = new ConcurrentHashMap<>();
|
private final Map<PlatformType, DronePlatformStrategy> droneStrategyMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储所有DRC平台策略实现
|
||||||
|
* Key: PlatformType
|
||||||
|
* Value: DrcPlatformStrategy实现
|
||||||
|
*/
|
||||||
|
private final Map<PlatformType, DrcPlatformStrategy> drcStrategyMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储各平台对应的系统管理器实现
|
* 存储各平台对应的系统管理器实现
|
||||||
* Key: PlatformType
|
* Key: PlatformType
|
||||||
|
|
@ -53,13 +61,14 @@ public class PlatformStrategyFactory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 注册所有平台策略
|
* 注册所有平台策略
|
||||||
* Spring会自动注入所有实现了AirportPlatformStrategy、CoverPlatformStrategy和DronePlatformStrategy的Bean
|
* Spring会自动注入所有实现了AirportPlatformStrategy、CoverPlatformStrategy、DronePlatformStrategy和DrcPlatformStrategy的Bean
|
||||||
*/
|
*/
|
||||||
@Autowired
|
@Autowired
|
||||||
public void registerStrategies(
|
public void registerStrategies(
|
||||||
List<AirportPlatformStrategy> airportStrategies,
|
List<AirportPlatformStrategy> airportStrategies,
|
||||||
List<CoverPlatformStrategy> coverStrategies,
|
List<CoverPlatformStrategy> coverStrategies,
|
||||||
List<DronePlatformStrategy> droneStrategies,
|
List<DronePlatformStrategy> droneStrategies,
|
||||||
|
List<DrcPlatformStrategy> drcStrategies,
|
||||||
List<AirportSystemManager> systemManagers) {
|
List<AirportSystemManager> systemManagers) {
|
||||||
|
|
||||||
// 注册机巢策略
|
// 注册机巢策略
|
||||||
|
|
@ -83,6 +92,13 @@ public class PlatformStrategyFactory {
|
||||||
strategy.getPlatformType().getName(), strategy.getClass().getSimpleName()));
|
strategy.getPlatformType().getName(), strategy.getClass().getSimpleName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 注册DRC策略
|
||||||
|
for (DrcPlatformStrategy strategy : drcStrategies) {
|
||||||
|
drcStrategyMap.put(strategy.getPlatformType(), strategy);
|
||||||
|
System.out.println(String.format("注册DRC平台策略: %s -> %s",
|
||||||
|
strategy.getPlatformType().getName(), strategy.getClass().getSimpleName()));
|
||||||
|
}
|
||||||
|
|
||||||
// 注册系统管理器
|
// 注册系统管理器
|
||||||
for (AirportSystemManager manager : systemManagers) {
|
for (AirportSystemManager manager : systemManagers) {
|
||||||
managerMap.put(manager.getPlatformType(), manager);
|
managerMap.put(manager.getPlatformType(), manager);
|
||||||
|
|
@ -223,6 +239,42 @@ public class PlatformStrategyFactory {
|
||||||
return droneStrategyMap.get(platformType);
|
return droneStrategyMap.get(platformType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据机巢SN获取DRC平台策略
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return DRC平台策略
|
||||||
|
* @throws IllegalArgumentException 如果机巢未注册或平台策略不存在
|
||||||
|
*/
|
||||||
|
public DrcPlatformStrategy getDrcStrategy(String airportSn) {
|
||||||
|
// 从数据库查询平台类型
|
||||||
|
PlatformType platformType = airportPlatformRepository.getPlatformType(airportSn);
|
||||||
|
|
||||||
|
if (platformType == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("机巢未注册或平台类型未配置: %s", airportSn));
|
||||||
|
}
|
||||||
|
|
||||||
|
DrcPlatformStrategy strategy = drcStrategyMap.get(platformType);
|
||||||
|
|
||||||
|
if (strategy == null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("未找到DRC平台策略: %s (机巢: %s)", platformType.getName(), airportSn));
|
||||||
|
}
|
||||||
|
|
||||||
|
return strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据平台类型获取DRC平台策略
|
||||||
|
*
|
||||||
|
* @param platformType 平台类型
|
||||||
|
* @return DRC平台策略
|
||||||
|
*/
|
||||||
|
public DrcPlatformStrategy getDrcStrategyByType(PlatformType platformType) {
|
||||||
|
return drcStrategyMap.get(platformType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取机巢的平台类型
|
* 获取机巢的平台类型
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
package com.tuoheng.status.machine.platform.impl.dji;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.platform.PlatformType;
|
||||||
|
import com.tuoheng.status.machine.platform.impl.dji.action.drc.*;
|
||||||
|
import com.tuoheng.status.machine.platform.impl.dji.guard.drc.*;
|
||||||
|
import com.tuoheng.status.machine.platform.impl.dji.listener.DjiDrcListener;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.DrcPlatformStrategy;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.PlatformAction;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.PlatformGuard;
|
||||||
|
import com.tuoheng.status.machine.platform.strategy.PlatformListener;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DJI平台DRC策略实现
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DjiDrcPlatformStrategy implements DrcPlatformStrategy {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCanEnterGuard canEnterGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiCanExitGuard canExitGuard;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiEnterAction enterAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiEnteredAction enteredAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiExitAction exitAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiExitedAction exitedAction;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DjiDrcListener djiDrcListener;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformType getPlatformType() {
|
||||||
|
return PlatformType.DJI;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<DrcState, DrcEvent> getCanEnterGuard() {
|
||||||
|
return canEnterGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformGuard<DrcState, DrcEvent> getCanExitGuard() {
|
||||||
|
return canExitGuard;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<DrcState, DrcEvent> getEnterAction() {
|
||||||
|
return enterAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<DrcState, DrcEvent> getEnteredAction() {
|
||||||
|
return enteredAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<DrcState, DrcEvent> getExitAction() {
|
||||||
|
return exitAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformAction<DrcState, DrcEvent> getExitedAction() {
|
||||||
|
return exitedAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlatformListener<DrcState, DrcEvent> getListener() {
|
||||||
|
return djiDrcListener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.machine.platform.impl.dji.action.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.action.drc.EnterAction;
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiEnterAction extends EnterAction {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiEnterAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<DrcState, DrcEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 进入DRC模式: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.machine.platform.impl.dji.action.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.action.drc.EnteredAction;
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiEnteredAction extends EnteredAction {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiEnteredAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<DrcState, DrcEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 已进入DRC模式: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.machine.platform.impl.dji.action.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.action.drc.ExitAction;
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiExitAction extends ExitAction {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiExitAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<DrcState, DrcEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 退出DRC模式: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package com.tuoheng.status.machine.platform.impl.dji.action.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.action.drc.ExitedAction;
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DjiExitedAction extends ExitedAction {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiExitedAction";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(StateContext<DrcState, DrcEvent> context) {
|
||||||
|
String machineId = (String) context.getExtendedState().getVariables().get("machineId");
|
||||||
|
System.out.println(String.format("[DJI] 已退出DRC模式: %s", machineId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.tuoheng.status.machine.platform.impl.dji.guard.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.guard.drc.CanEnterGuard;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DJI平台:检查是否可以进入DRC模式
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DjiCanEnterGuard extends CanEnterGuard {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCanEnterGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<DrcState, DrcEvent> context) {
|
||||||
|
// DJI平台特定的进入DRC模式检查逻辑
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.tuoheng.status.machine.platform.impl.dji.guard.drc;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.guard.drc.CanExitGuard;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
import org.springframework.statemachine.StateContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DJI平台:检查是否可以退出DRC模式
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DjiCanExitGuard extends CanExitGuard {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DjiCanExitGuard";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean evaluate(StateContext<DrcState, DrcEvent> context) {
|
||||||
|
// DJI平台特定的退出DRC模式检查逻辑
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.tuoheng.status.machine.platform.impl.dji.listener;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.listener.DefaultDrcListener;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DJI平台DRC状态监听器
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DjiDrcListener extends DefaultDrcListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "DJI-DRC";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.tuoheng.status.machine.platform.strategy;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.platform.PlatformType;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DRC(飞行控制模式)平台策略接口
|
||||||
|
* 定义各平台需要实现的Guard、Action和Listener
|
||||||
|
*/
|
||||||
|
public interface DrcPlatformStrategy {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台类型
|
||||||
|
*/
|
||||||
|
PlatformType getPlatformType();
|
||||||
|
|
||||||
|
// ==================== Guards ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可以进入DRC模式
|
||||||
|
*/
|
||||||
|
PlatformGuard<DrcState, DrcEvent> getCanEnterGuard();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可以退出DRC模式
|
||||||
|
*/
|
||||||
|
PlatformGuard<DrcState, DrcEvent> getCanExitGuard();
|
||||||
|
|
||||||
|
// ==================== Actions ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进入DRC模式动作
|
||||||
|
*/
|
||||||
|
PlatformAction<DrcState, DrcEvent> getEnterAction();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进入DRC模式完成动作
|
||||||
|
*/
|
||||||
|
PlatformAction<DrcState, DrcEvent> getEnteredAction();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出DRC模式动作
|
||||||
|
*/
|
||||||
|
PlatformAction<DrcState, DrcEvent> getExitAction();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出DRC模式完成动作
|
||||||
|
*/
|
||||||
|
PlatformAction<DrcState, DrcEvent> getExitedAction();
|
||||||
|
|
||||||
|
// ==================== Listener ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取平台Listener
|
||||||
|
* 每个平台有一个Listener实例,所有该平台的DRC共享
|
||||||
|
*/
|
||||||
|
PlatformListener<DrcState, DrcEvent> getListener();
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package com.tuoheng.status.machine.redis;
|
||||||
import com.tuoheng.status.machine.status.AirportState;
|
import com.tuoheng.status.machine.status.AirportState;
|
||||||
import com.tuoheng.status.machine.status.CoverState;
|
import com.tuoheng.status.machine.status.CoverState;
|
||||||
import com.tuoheng.status.machine.status.DroneState;
|
import com.tuoheng.status.machine.status.DroneState;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -11,7 +12,7 @@ import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用 Redis 记录和恢复机巢/舱门/无人机状态的存储组件。
|
* 使用 Redis 记录和恢复机巢/舱门/无人机/DRC状态的存储组件。
|
||||||
*
|
*
|
||||||
* 当前实现采用内存 Map 占位,便于无 Redis 环境下直接运行。
|
* 当前实现采用内存 Map 占位,便于无 Redis 环境下直接运行。
|
||||||
* 如果接入真正的 Redis,只需将存取逻辑替换为 RedisTemplate 等实现。
|
* 如果接入真正的 Redis,只需将存取逻辑替换为 RedisTemplate 等实现。
|
||||||
|
|
@ -22,6 +23,7 @@ public class RedisStateStore {
|
||||||
private final Map<String, AirportState> airportStateMap = new ConcurrentHashMap<>();
|
private final Map<String, AirportState> airportStateMap = new ConcurrentHashMap<>();
|
||||||
private final Map<String, CoverState> coverStateMap = new ConcurrentHashMap<>();
|
private final Map<String, CoverState> coverStateMap = new ConcurrentHashMap<>();
|
||||||
private final Map<String, DroneState> droneStateMap = new ConcurrentHashMap<>();
|
private final Map<String, DroneState> droneStateMap = new ConcurrentHashMap<>();
|
||||||
|
private final Map<String, DrcState> drcStateMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public void saveAirportState(String airportSn, AirportState state) {
|
public void saveAirportState(String airportSn, AirportState state) {
|
||||||
if (airportSn != null && state != null) {
|
if (airportSn != null && state != null) {
|
||||||
|
|
@ -41,6 +43,12 @@ public class RedisStateStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void saveDrcState(String airportSn, DrcState state) {
|
||||||
|
if (airportSn != null && state != null) {
|
||||||
|
drcStateMap.put(airportSn, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Optional<AirportState> loadAirportState(String airportSn) {
|
public Optional<AirportState> loadAirportState(String airportSn) {
|
||||||
return Optional.ofNullable(airportStateMap.get(airportSn));
|
return Optional.ofNullable(airportStateMap.get(airportSn));
|
||||||
}
|
}
|
||||||
|
|
@ -53,6 +61,10 @@ public class RedisStateStore {
|
||||||
return Optional.ofNullable(droneStateMap.get(droneSn));
|
return Optional.ofNullable(droneStateMap.get(droneSn));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<DrcState> loadDrcState(String airportSn) {
|
||||||
|
return Optional.ofNullable(drcStateMap.get(airportSn));
|
||||||
|
}
|
||||||
|
|
||||||
public Set<String> allAirportIds() {
|
public Set<String> allAirportIds() {
|
||||||
// 合并两张表的 key,防止有只存机场或只存舱门的情况
|
// 合并两张表的 key,防止有只存机场或只存舱门的情况
|
||||||
Set<String> ids = ConcurrentHashMap.newKeySet();
|
Set<String> ids = ConcurrentHashMap.newKeySet();
|
||||||
|
|
@ -64,5 +76,9 @@ public class RedisStateStore {
|
||||||
public Set<String> allDroneIds() {
|
public Set<String> allDroneIds() {
|
||||||
return droneStateMap.keySet();
|
return droneStateMap.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<String> allDrcIds() {
|
||||||
|
return drcStateMap.keySet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,191 @@
|
||||||
|
package com.tuoheng.status.machine.service;
|
||||||
|
|
||||||
|
import com.tuoheng.status.machine.events.DrcEvent;
|
||||||
|
import com.tuoheng.status.machine.redis.RedisStateStore;
|
||||||
|
import com.tuoheng.status.machine.status.DrcState;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.statemachine.StateMachine;
|
||||||
|
import org.springframework.statemachine.config.StateMachineFactory;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DRC状态机管理器
|
||||||
|
* 负责管理多个机巢的DRC状态机实例
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class DrcMachineService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
StateMachineFactory<DrcState, DrcEvent> drcStateMachineFactory;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisStateStore redisStateStore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储所有机巢的DRC状态机实例
|
||||||
|
* Key: 机巢ID (airportSn)
|
||||||
|
* Value: 状态机实例
|
||||||
|
*/
|
||||||
|
private final Map<String, StateMachine<DrcState, DrcEvent>> stateMachineMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取或创建状态机
|
||||||
|
* 如果状态机不存在,则创建新的状态机实例
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return 状态机实例
|
||||||
|
*/
|
||||||
|
public StateMachine<DrcState, DrcEvent> getOrCreateStateMachine(String airportSn) {
|
||||||
|
return stateMachineMap.computeIfAbsent(airportSn, id -> {
|
||||||
|
StateMachine<DrcState, DrcEvent> stateMachine = drcStateMachineFactory.getStateMachine(id);
|
||||||
|
// 服务器重启后,状态机初始化为 UNKNOWN 状态
|
||||||
|
// 不从 Redis 恢复旧状态,等待第一次心跳同步真实状态
|
||||||
|
// 这样可以避免服务器重启期间丢失心跳导致的状态不一致问题
|
||||||
|
stateMachine.start();
|
||||||
|
System.out.println(String.format("创建并启动DRC状态机: %s, 初始状态: UNKNOWN (等待心跳同步)", id));
|
||||||
|
return stateMachine;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取状态机(不创建)
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return 状态机实例,如果不存在返回null
|
||||||
|
*/
|
||||||
|
public StateMachine<DrcState, DrcEvent> getStateMachine(String airportSn) {
|
||||||
|
return stateMachineMap.get(airportSn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取状态机的当前状态
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return 当前状态,如果状态机不存在返回null
|
||||||
|
*/
|
||||||
|
public DrcState getCurrentState(String airportSn) {
|
||||||
|
StateMachine<DrcState, DrcEvent> stateMachine = stateMachineMap.get(airportSn);
|
||||||
|
if (stateMachine == null) {
|
||||||
|
System.out.println("DRC状态机不存在: " + airportSn);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return stateMachine.getState().getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取状态机的所有当前状态(包括子状态)
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return 当前状态集合的字符串表示
|
||||||
|
*/
|
||||||
|
public String getCurrentStates(String airportSn) {
|
||||||
|
StateMachine<DrcState, DrcEvent> stateMachine = stateMachineMap.get(airportSn);
|
||||||
|
if (stateMachine == null) {
|
||||||
|
return "状态机不存在";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder states = new StringBuilder();
|
||||||
|
stateMachine.getState().getIds().forEach(state -> {
|
||||||
|
if (states.length() > 0) {
|
||||||
|
states.append(" -> ");
|
||||||
|
}
|
||||||
|
states.append(state);
|
||||||
|
});
|
||||||
|
|
||||||
|
return states.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送事件到状态机
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @param event 事件
|
||||||
|
* @return 是否发送成功
|
||||||
|
*/
|
||||||
|
public boolean sendEvent(String airportSn, DrcEvent event) {
|
||||||
|
StateMachine<DrcState, DrcEvent> stateMachine = getOrCreateStateMachine(airportSn);
|
||||||
|
boolean result = stateMachine.sendEvent(event);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
// 持久化最新状态
|
||||||
|
redisStateStore.saveDrcState(airportSn, stateMachine.getState().getId());
|
||||||
|
System.out.println(String.format("DRC事件发送成功 - 机巢: %s, 事件: %s, 当前状态: %s",
|
||||||
|
airportSn, event, getCurrentStates(airportSn)));
|
||||||
|
} else {
|
||||||
|
System.out.println(String.format("DRC事件发送失败 - 机巢: %s, 事件: %s, 当前状态: %s",
|
||||||
|
airportSn, event, getCurrentStates(airportSn)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除状态机
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
*/
|
||||||
|
public void removeStateMachine(String airportSn) {
|
||||||
|
StateMachine<DrcState, DrcEvent> stateMachine = stateMachineMap.remove(airportSn);
|
||||||
|
if (stateMachine != null) {
|
||||||
|
stateMachine.stop();
|
||||||
|
System.out.println("停止并移除DRC状态机: " + airportSn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查状态机是否存在
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @return 是否存在
|
||||||
|
*/
|
||||||
|
public boolean hasStateMachine(String airportSn) {
|
||||||
|
return stateMachineMap.containsKey(airportSn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有状态机的数量
|
||||||
|
*
|
||||||
|
* @return 状态机数量
|
||||||
|
*/
|
||||||
|
public int getStateMachineCount() {
|
||||||
|
return stateMachineMap.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有机巢ID
|
||||||
|
*
|
||||||
|
* @return 机巢ID集合
|
||||||
|
*/
|
||||||
|
public java.util.Set<String> getAllAirportIds() {
|
||||||
|
return stateMachineMap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查状态机是否处于指定状态
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
* @param state 要检查的状态
|
||||||
|
* @return 是否处于指定状态
|
||||||
|
*/
|
||||||
|
public boolean isInState(String airportSn, DrcState state) {
|
||||||
|
StateMachine<DrcState, DrcEvent> stateMachine = stateMachineMap.get(airportSn);
|
||||||
|
if (stateMachine == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return stateMachine.getState().getIds().contains(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重启状态机
|
||||||
|
*
|
||||||
|
* @param airportSn 机巢序列号
|
||||||
|
*/
|
||||||
|
public void restartStateMachine(String airportSn) {
|
||||||
|
removeStateMachine(airportSn);
|
||||||
|
getOrCreateStateMachine(airportSn);
|
||||||
|
System.out.println("重启DRC状态机: " + airportSn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,5 +5,28 @@ package com.tuoheng.status.machine.status;
|
||||||
* 未知状态 退出状态 进入中 进入状态 退出中
|
* 未知状态 退出状态 进入中 进入状态 退出中
|
||||||
*/
|
*/
|
||||||
public enum DrcState {
|
public enum DrcState {
|
||||||
|
/**
|
||||||
|
* 未知状态(服务器重启后的初始状态,等待第一次心跳同步)
|
||||||
|
*/
|
||||||
|
UNKNOWN,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出状态(DRC模式已退出)
|
||||||
|
*/
|
||||||
|
EXITED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进入中(正在进入DRC模式)
|
||||||
|
*/
|
||||||
|
ENTERING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进入状态(已进入DRC模式)
|
||||||
|
*/
|
||||||
|
ENTERED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退出中(正在退出DRC模式)
|
||||||
|
*/
|
||||||
|
EXITING
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue