thingsboard-client-demo/src/main/java/com/tuoheng/status/machine/config/DrcMachineConfig.java

145 lines
5.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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());
}
}