using Entity.DbModel.Station; using log4net; using Newtonsoft.Json; using Service.Execute.Enum; using Service.Execute.StaticTools; using Service.Execute.Step; using Service.Execute.SwapException; using Service.Execute.Tech; using Swapping.Business.Rfid; namespace Service.Execute; public class SwappingStateMachine : IDisposable { private static readonly ILog _log = LogManager.GetLogger(typeof(SwappingStateMachine)); private static SwappingStateMachine _swappingStateMachine = new SwappingStateMachine(); public static bool CancelFlag { get; set; } = false; public static bool StopFlag { get; set; } = false; public LedTool LedTool = null; private Thread _executeThread; private Dictionary Dictionary = new Dictionary(); private StateResult _result = new StateResult() { SwappingState = SwappingState.Begin }; public static InfoEnum.BusinessSwappingState BusinessSwappingState = InfoEnum.BusinessSwappingState.UnKnown; public static DateTime BusinessSwappingStateUpdateTime = DateTime.Now; public static ExceptionReason ExceptionReason = ExceptionReason.None; public RfidReadModel? RfidReadModel=null; public SwapOrder? SwapOrder=null; #region 小步状态 //雷达检测/车辆进入 public static bool RadarInFlag = false; //开始读rfid public static bool BeginRfidReadFlag = false; //读rfid public static bool RfidReadFlag = false; //云平台车辆认证 public static bool CloudVelCheckFlag = false; //Tbox连接 public static bool TBoxConnectionFlag = false; //选包 public static bool SelectPackFlag = false; //车辆到位 public static bool VehiclesInPlaceFlag = false; //通道定位 public static bool ChannelPositioningFlag = false; //下发选包 public static bool DistributeSelectPackFlag = false; //云平台下发启动换电 public static bool CloudPackFlag = false; //车辆解锁 public static bool VelUnlockFlag = false; //开始换电 public static bool StartSwappingFlag = false; //拆旧电池 public static bool UnOldBatteryFlag = false; //入库旧电池 public static bool StorageOldBatteryFlag = false; //搬运新电池 public static bool OutNewBatteryFlag = false; //安装新电池 public static bool InstallNewBatteryFlag = false; //安装完成 public static bool FinishNewBatteryFlag = false; //车辆上锁 public static bool VelLockFlag = false; //车辆离开 public static bool RadarOutFlag = false; #endregion private SwappingStateMachine() { _executeThread = new Thread(Work); _executeThread.Name = "Swapping main"; Dictionary[SwappingState.Begin] = new BeginState(); Dictionary[SwappingState.StationReady] = new StationReadyState(); Dictionary[SwappingState.CarPrepare] = new CarPrepareState(); Dictionary[SwappingState.SelectPack] = new SelectPackState(); Dictionary[SwappingState.CarCtrl] = new CarCtrlState(); Dictionary[SwappingState.DoSwapping] = new DoSwappingState(); Dictionary[SwappingState.SwapDone] = new SwapDoneState(); Dictionary[SwappingState.Exception] = new ExceptionState(); Dictionary[SwappingState.Canceled] = new CancelState(); LedTool = new LedTool(); } public static SwappingStateMachine GetInstance() { return _swappingStateMachine; } public static StateResult ReturnWithInvokeErr(InvokeStatus status,ExceptionReason exceptionReason) { if (status == InvokeStatus.Cancel) { return new StateResult() { SwappingState = SwappingState.Canceled }; } else if(status==InvokeStatus.TimeOut) { return null; } else { return StateResult.Exception(ExceptionReason.ReadRfidError, null); } } private void Work() { _log.Info("State machine begin work"); while (!StopFlag) { _log.Info($"handle = {_result.SwappingState} begin"); try { StateResult? result = Dictionary[_result.SwappingState].Handle(this); if (result != null) { _result = result; } } catch (Exception e) { _log.Error($"handle {_result.SwappingState} error", e); } _log.Info($"handle = {_result.SwappingState} end"); Thread.Sleep(500); } _log.Info("State machine canceled"); } public void Stop() { StopFlag = true; CancelFlag = true; Thread.Sleep(2000); } public bool IsCanceled() { return CancelFlag; } public bool Start() { Reset(); _executeThread.Start(); _log.Info($"start machine ok"); return true; } public void Reset() { } public void Dispose() { StopFlag = true; CancelFlag = true; Thread.Sleep(2000); } } public enum SwappingState { Begin, StationReady, CarPrepare, SelectPack, CarCtrl, DoSwapping, SwapDone, Exception, Canceled }