diff --git a/Service/Cloud/Msg/Cloud/Req/CarCanStart.cs b/Service/Cloud/Msg/Cloud/Req/CarCanStart.cs
index a5fe31b..0683ce9 100644
--- a/Service/Cloud/Msg/Cloud/Req/CarCanStart.cs
+++ b/Service/Cloud/Msg/Cloud/Req/CarCanStart.cs
@@ -25,7 +25,7 @@ namespace Service.Cloud.Msg.Cloud.Req
///
public string cn { get; set; }
///
- /// 是否开始换电
+ /// 是否开始换电 1:可以开始换电 2:终止换电
///
public byte cs { get; set; }
public string GetCmd()
diff --git a/Service/Execute/Api/CloudApi.cs b/Service/Execute/Api/CloudApi.cs
index 8b5f749..a16a55e 100644
--- a/Service/Execute/Api/CloudApi.cs
+++ b/Service/Execute/Api/CloudApi.cs
@@ -1,5 +1,7 @@
using Entity.DbModel.Station;
using log4net;
+using Service.Cloud.Client;
+using Service.Cloud.Msg.Cloud.Req;
using Service.Execute.Enum;
using Service.Execute.Model;
@@ -35,4 +37,22 @@ public class CloudApi
{
return ;
}
+
+ ///
+ /// 云平台下发换电指令
+ ///
+ ///
+ public static CarCanStart CarCanStart()
+ {
+ return CloudClientMgr.CloudClient.CarCanStart;
+ }
+
+ ///
+ /// 清除下发的换电指令
+ ///
+ ///
+ public static CarCanStart ClearCarCanStartInfo()
+ {
+ return CloudClientMgr.CloudClient.CarCanStart=null;
+ }
}
\ No newline at end of file
diff --git a/Service/Execute/Api/PlcApi.cs b/Service/Execute/Api/PlcApi.cs
index 9350067..b3bff41 100644
--- a/Service/Execute/Api/PlcApi.cs
+++ b/Service/Execute/Api/PlcApi.cs
@@ -45,4 +45,57 @@ public class PlcApi
{
return true;
}
+
+ ///
+ /// 写出口灯
+ /// 红灯:1020
+ /// 绿灯:1000
+ ///
+ ///
+ ///
+ public static bool WriteExistLamp(int data)
+ {
+ return true;
+ }
+
+ ///
+ /// 下发选包
+ ///
+ /// 入仓位,仓位号
+ /// 出仓位,仓位号
+ ///
+ public static bool DistributeSelectPack(string inBinNo, string outBinNo)
+ {
+ return true;
+ }
+
+
+ ///
+ /// 下发启动换电
+ ///
+ ///
+ public static bool StartSwapping()
+ {
+ return true;
+ }
+
+ ///
+ /// 查看拍照状态
+ ///
+ ///
+ public static byte ChannelStatus()
+ {
+ return 0;
+ }
+
+
+ ///
+ /// 读plc任务状态
+ ///
+ ///
+ public static byte ReadPlcTaskStatus()
+ {
+ return 0;
+ }
+
}
\ No newline at end of file
diff --git a/Service/Execute/Api/TboxApi.cs b/Service/Execute/Api/TboxApi.cs
index ad18ddb..6d3896d 100644
--- a/Service/Execute/Api/TboxApi.cs
+++ b/Service/Execute/Api/TboxApi.cs
@@ -62,4 +62,52 @@ public class TBoxApi
return false;
}
}
+
+ ///
+ /// 车辆解锁
+ ///
+ ///
+ public static async Task UnLockCar()
+ {
+ Log.Info("UnLockCar");
+ string url = BASE_URL + "/CarControl/unLock";
+ try
+ {
+ string s = await _httpClient.GetStringAsync(url);
+
+
+ Log.Info($"UnLockCar resp = {s}");
+ return bool.Parse(s);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ return false;
+ }
+ }
+
+ ///
+ /// 车辆上锁
+ ///
+ ///
+ public static async Task LockCar()
+ {
+ Log.Info("LockCar");
+ string url = BASE_URL + "/CarControl/lock";
+ try
+ {
+ string s = await _httpClient.GetStringAsync(url);
+
+
+ Log.Info($"LockCar resp = {s}");
+ return bool.Parse(s);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ return false;
+ }
+ }
+
+
}
\ No newline at end of file
diff --git a/Service/Execute/Enum/InfoEnum.cs b/Service/Execute/Enum/InfoEnum.cs
index 851daa6..40ef22a 100644
--- a/Service/Execute/Enum/InfoEnum.cs
+++ b/Service/Execute/Enum/InfoEnum.cs
@@ -8,32 +8,32 @@ public class InfoEnum
public enum SwapInfo : ushort
{
[Info("Rfid读写失败", "Rfid读写失败")] ErrorReadRfid = 1,
- [Info("车辆进站", "车辆进站")] InfoCarIn = 2,
[Info("Tbox连接失败", "Tbox连接失败,请联系站务人员")] ErrorTBoxConn = 4,
[Info("云端校验失败", "云端校验失败,请联系站务人员")] ErrorCloudCheck = 5,
[Info("车辆已到位", "车辆已到位")] InfoCarInPosition = 6,
[Info("车辆到位超时", "车辆到位超时")] ErrorCarInPositionTimeout = 7,
[Info("云平台下发换电失败", "云平台下发换电超时")] CloudSendSwapError = 8,
+ [Info("云平台下发取消换电", "云平台下发取消换电")] CloudSendSwapCancel = 9,
-
- [Info("自由度调整,挂N挡,拉手刹", "自由度调整,挂N挡,拉手刹")]
- InfoCarPrepare = 9,
- [Info("自由度调整超时", "自由度调整超时")] ErrorCarPrepareTimeout = 10,
- [Info("请选择更换电池数量", "请选择更换电池数量")] InfoSelectPack = 11,
+
+ [Info("解锁车辆失败", "解锁车辆失败")] ErrUnLockCar = 10,
+ [Info("下发选包结果失败", "下发选包结果失败")] ErrDistributeSelectPack = 11,
[Info("选包失败,请驶离", "选包失败,请驶离")] ErrorSelectPack = 12,
- [Info("下高压失败,请联系站务人员", "下高压失败,请联系站务人员")]
- ErrorHvPwrOff = 13,
+
- [Info("下低压失败,请联系站务人员", "下低压失败,请联系站务人员")]
- ErrorLvPwrOff = 14,
+ [Info("通道拍照定位失败,请重新调整车辆位置", "通道拍照定位失败,请重新调整车辆位置")]
+ ErrChannelStatus = 14,
[Info("电池拆卸中,请稍后", "电池拆卸中,请稍后")] InfoUnPack = 15,
+
[Info("电池安装中,请稍后", "电池安装中,请稍后")] InfoPack = 16,
[Info("电池包已安装完成", "电池包已安装完成")] InfoPackFinish = 17,
- [Info("车辆自检中,请稍后", "车辆自检中,请稍后")] InfoSelfCheck = 18,
- [Info("自检失败,请联系站务人员", "自检失败,请联系站务人员")] ErrorSelfCheck = 19,
[Info("换电已完成,请驶离", "换电已完成,请驶离")] InfoCarLeave = 20,
+ [Info("换电失败,请驶离", "换电失败,请驶离")] ErrInfoCarLeave = 21,
+ [Info("旧电池搬运中,请稍后", "旧电池搬运中,请稍后")] InfoOldBatteryCarryIn = 22,
+ [Info("旧电池搬运中,请稍后", "旧电池搬运中,请稍后")] InfoNewBatteryCarryOut = 23,
+ [Info("上锁车辆失败", "上锁车辆失败")] ErrLockCar = 24,
}
public enum SelectBinStatusInfo : byte
@@ -50,7 +50,7 @@ public class InfoEnum
[Remark("无可用捆绑")] NoGroupError
}
- //1:预约成功;2:预约取消;3:预约失败;4:换电完成;5:换电失败
+
public enum AmtOrderStatus : byte
{
[Remark("预约成功")] Success = 1,
@@ -59,8 +59,9 @@ public class InfoEnum
[Remark("换电完成")] SwapFinish = 4,
[Remark("换电失败")] SwapFail = 5,
[Remark("换电中")] Swapping = 6,
- [Remark("预约失败")] Expire = 7,
+ [Remark("预约过期")] Expire = 7,
}
+ //云平台上报步序
public enum BusinessSwappingForCloudState : byte
{
@@ -87,7 +88,7 @@ public class InfoEnum
public enum SwapOrderResult : byte
{
- Success = 0,
- Fail = 1
+ Success = 1,
+ Fail = 2
}
}
\ No newline at end of file
diff --git a/Service/Execute/Step/CancelState.cs b/Service/Execute/Step/CancelState.cs
index f91e9da..d11f102 100644
--- a/Service/Execute/Step/CancelState.cs
+++ b/Service/Execute/Step/CancelState.cs
@@ -1,13 +1,35 @@
-namespace Service.Execute.Step;
+using log4net;
+using Repository.Station;
+using Service.Execute.Enum;
-public class CancelState: IState
+namespace Service.Execute.Step;
+
+public class CancelState : IState
{
+ private SwapOrderRepository SwapOrderRepository { get; set; }
+
+ private SwapAmtOrderRepository SwapAmtOrderRepository { get; set; }
+ private static readonly ILog _log = LogManager.GetLogger(typeof(CancelState));
+
public StateResult Handle(SwappingStateMachine machine)
{
-
+ _log.Info($"'goto cancel");
+ SwappingStateMachine.CancelFlag = false;
+ if (machine.SwapOrderBatteryInfo.swapAmtOrder != null)
+ {
+ machine.SwapOrderBatteryInfo.swapAmtOrder.Status = (byte)InfoEnum.AmtOrderStatus.SwapFail;
+ SwapAmtOrderRepository.Update(machine.SwapOrderBatteryInfo.swapAmtOrder);
+ }
+
+ if (machine.SwapOrder != null)
+ {
+ machine.SwapOrder.SwapResult = (byte)InfoEnum.SwapOrderResult.Fail;
+ SwapOrderRepository.Update(machine.SwapOrder);
+ }
+
+ machine.Reset();
return new StateResult()
{
-
SwappingState = SwappingState.StationReady
};
}
diff --git a/Service/Execute/Step/CarCtrlState.cs b/Service/Execute/Step/CarCtrlState.cs
index 4850a4f..6d2f6e5 100644
--- a/Service/Execute/Step/CarCtrlState.cs
+++ b/Service/Execute/Step/CarCtrlState.cs
@@ -1,14 +1,81 @@
-namespace Service.Execute.Step;
+using log4net;
+using Service.Execute.Api;
+using Service.Execute.Enum;
+using Service.Execute.Model;
+using Service.Execute.StaticTools;
+using Service.Execute.SwapException;
+using Swapping.Business.Tech;
-public class CarCtrlState: IState
+namespace Service.Execute.Step;
+
+public class CarCtrlState : IState
{
+ private readonly ILog _log = LogManager.GetLogger(typeof(CarCtrlState));
+
public StateResult Handle(SwappingStateMachine machine)
{
-
+ //解锁车辆
+ InvokeStatus unLockCar = UnLockCar(machine);
+ if (unLockCar != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(unLockCar, ExceptionReason.None);
+ }
+
+ //下发选包
+ InvokeStatus distributeSelectPack = DistributeSelectPack(machine);
+
+ if (distributeSelectPack != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(distributeSelectPack, ExceptionReason.None);
+ }
+
return new StateResult()
{
-
- SwappingState = SwappingState.StationReady
+ SwappingState = SwappingState.DoSwapping
};
}
+
+ ///
+ /// 车辆解锁
+ ///
+ ///
+ public InvokeStatus UnLockCar(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("UnLockCar", 500, 100, machine.IsCanceled,
+ () => SwappingStateMachine.VelUnlockFlag, () =>
+ {
+ Task result = TBoxApi.UnLockCar();
+ bool unLock = result.Result;
+ if (unLock)
+ {
+ //查询车辆锁止状态
+ Task carInfo = TBoxApi.GetCarInfo();
+ if (carInfo.Result.HeartBeatMsg.LockStatus == 1)
+ {
+ SwappingStateMachine.VelUnlockFlag = true;
+ }
+ }
+ }, () =>
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrUnLockCar.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrUnLockCar);
+ }, false, () => { SwappingStateMachine.ExceptionReason = ExceptionReason.UnLockCarError; }
+ , 10, InvokeStatus.None);
+ }
+
+
+ ///
+ /// 下发选包
+ ///
+ ///
+ public InvokeStatus DistributeSelectPack(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("DistributeSelectPack", 500, 10, machine.IsCanceled,
+ () => SwappingStateMachine.DistributeSelectPackFlag, () =>
+ {
+ var swapOrderBatteryInfo = machine.SwapOrderBatteryInfo;
+ SwappingStateMachine.DistributeSelectPackFlag =
+ PlcApi.DistributeSelectPack(swapOrderBatteryInfo.InBinInfo.No, swapOrderBatteryInfo.UpBinInfo.No);
+ }, () => { machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrDistributeSelectPack.GetLed()); });
+ }
}
\ No newline at end of file
diff --git a/Service/Execute/Step/CarPrepareState.cs b/Service/Execute/Step/CarPrepareState.cs
index 0fb106a..c1623d7 100644
--- a/Service/Execute/Step/CarPrepareState.cs
+++ b/Service/Execute/Step/CarPrepareState.cs
@@ -84,7 +84,7 @@ public class CarPrepareState : IState
return new StateResult()
{
- SwappingState = SwappingState.SelectPack
+ SwappingState = SwappingState.SwapCanStart
};
}
@@ -110,6 +110,13 @@ public class CarPrepareState : IState
machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoCarInPosition.GetLed());
SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.InfoCarInPosition);
SwappingStateMachine.VehiclesInPlaceFlag = true;
+ //告知云平台换电准备完成
+ SwappingStateMachine.BusinessSwappingForCloudState =
+ InfoEnum.BusinessSwappingForCloudState.SwapReady;
+ SwappingStateMachine.ExceptionReason = ExceptionReason.None;
+ CloudApi.SendStateLog(machine.SwapOrder, SwappingStateMachine.BusinessSwappingForCloudState);
+ //清除下发的指令,等待新的指令
+ CloudApi.ClearCarCanStartInfo();
}
}
}, () =>
@@ -121,6 +128,7 @@ public class CarPrepareState : IState
, 20, InvokeStatus.None);
}
+
///
/// 云平台车辆认证
///
@@ -141,15 +149,10 @@ public class CarPrepareState : IState
}
else
{
- //置为换电准备中 ,上报换电准备中
- SwappingStateMachine.BusinessSwappingForCloudState =
- InfoEnum.BusinessSwappingForCloudState.SwapReady;
SwappingStateMachine.ExceptionReason = ExceptionReason.None;
_log.Info("cloud check vehicle done");
SwappingStateMachine.CloudVelCheckFlag = true;
machine.LedTool.WriteProgramContent("换电准备中:云平台车辆验证完成");
- CloudApi.SendStateLog(machine.SwapOrder, SwappingStateMachine.BusinessSwappingForCloudState);
- SwappingStateMachine.CloudVelCheckFlag = true;
}
}
else
@@ -183,6 +186,9 @@ public class CarPrepareState : IState
}, () => { SwappingStateMachine.ExceptionReason = ExceptionReason.ConnTBoxError; }, false, () =>
{
SwappingStateMachine.ExceptionReason = ExceptionReason.ConnTBoxError;
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorTBoxConn.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrorTBoxConn);
+
}
, 10, InvokeStatus.None);
}
@@ -254,7 +260,8 @@ public class CarPrepareState : IState
public InvokeStatus SelectPack(SwappingStateMachine machine)
{
SwapAmtOrder? swapAmtOrder =
- AmtOrderRepository.QueryByClause(i => i.Status == 1 && i.VehicleNo.Equals(machine.TBoxCarInfoModel.CarNo));
+ AmtOrderRepository.QueryByClause(i =>
+ i.Status == (int)InfoEnum.AmtOrderStatus.Success && i.VehicleNo.Equals(machine.TBoxCarInfoModel.CarNo));
return Invoker.Invoke("selectPack", 500, 20, machine.IsCanceled,
@@ -316,7 +323,7 @@ public class CarPrepareState : IState
IMapper mapperBinInfo = configBinInfo.CreateMapper();
BinInfo dbBinInfo = mapperBinInfo.Map(orderBatteryInfo.UpBinInfo);
- dbBinInfo.AmtLock = "1";
+ dbBinInfo.AmtLock = InfoEnum.AmtBatLockStatus.Lock.ToString();
BinInfoRepository.Update(dbBinInfo);
if (!orderBatteryInfo.isAmt)
{
@@ -327,7 +334,7 @@ public class CarPrepareState : IState
new MapperConfiguration(cfg => cfg.CreateMap().ReverseMap());
IMapper mapperAmt = configAmt.CreateMapper();
SwapAmtOrder swapAmtOrder = mapperAmt.Map(orderBatteryInfo.swapAmtOrder);
- swapAmtOrder.Status = 6;
+ swapAmtOrder.Status = (int)InfoEnum.AmtOrderStatus.Swapping;
AmtOrderRepository.Update(swapAmtOrder);
}
diff --git a/Service/Execute/Step/CloudSendOutSwapState.cs b/Service/Execute/Step/CloudSendOutSwapState.cs
deleted file mode 100644
index b09e25f..0000000
--- a/Service/Execute/Step/CloudSendOutSwapState.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using Entity.Constant;
-
-namespace Service.Execute.Step;
-
-///
-/// 云平台下发换电
-///
-public class CloudSendOutSwapState: IState
-{
- public StateResult Handle(SwappingStateMachine machine)
- {
-
- return new StateResult()
- {
-
- SwappingState = SwappingState.StationReady
- };
- }
-
-
- ///
- /// 等待云平台下发换电
- ///
- ///
- /*public InvokeStatus CloudSendOutSwap(SwappingStateMachine machine)
- {
- return Invoker.Invoke("check CarInPosition", 500, 50, machine.IsCanceled,
- () => SwappingStateMachine.VehiclesInPlaceFlag, () =>
- {
- var result = TBoxApi.GetCarInfo();
- TboxCarInfoModel tboxCarInfoModel = result.Result;
-
- if (tboxCarInfoModel.HeartBeatMsg.KeyStatus == 0)
- {
- SwappingStateMachine.VehiclesInPlaceFlag = true;
- //写入口等 :红灯
- if (PlcApi.WriteEntranceLamp(1020))
- {
- machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoCarInPosition.GetLed());
- SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.InfoCarInPosition);
- SwappingStateMachine.VehiclesInPlaceFlag = true;
- }
- }
- }, () =>
- {
- SwappingStateMachine.ExceptionReason = ExceptionReason.CarInPositionError;
- machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorCarInPositionTimeout.GetLed());
- SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrorCarInPositionTimeout);
- }, false, () => { }
- , 20, InvokeStatus.None);
- }*/
-}
\ No newline at end of file
diff --git a/Service/Execute/Step/DoSwappingState.cs b/Service/Execute/Step/DoSwappingState.cs
index a9759b1..58eb0f5 100644
--- a/Service/Execute/Step/DoSwappingState.cs
+++ b/Service/Execute/Step/DoSwappingState.cs
@@ -1,14 +1,274 @@
-namespace Service.Execute.Step;
+using log4net;
+using Repository.Station;
+using Service.Execute.Api;
+using Service.Execute.Enum;
+using Service.Execute.Model;
+using Service.Execute.StaticTools;
+using Service.Execute.SwapException;
+using Swapping.Business.Tech;
-public class DoSwappingState: IState
+namespace Service.Execute.Step;
+
+public class DoSwappingState : IState
{
+ private readonly ILog _log = LogManager.GetLogger(typeof(DoSwappingState));
+ private SwapOrderRepository SwapOrderRepository { get; set; }
+
public StateResult Handle(SwappingStateMachine machine)
{
-
+ //上报云平台换电开始
+ SwappingStateMachine.BusinessSwappingForCloudState = InfoEnum.BusinessSwappingForCloudState.BeginSwap;
+ SwappingStateMachine.BusinessSwappingStateUpdateTime = DateTime.Now;
+ _log.Info($"BusinessSwappingForCloudState={SwappingStateMachine.BusinessSwappingForCloudState}");
+ CloudApi.SendStateLog(machine.SwapOrder, InfoEnum.BusinessSwappingForCloudState.BeginSwap);
+
+ //再次读锁止状态,防止plc需要挪车
+ InvokeStatus carInPosition2 = CarInPosition2(machine);
+ if (carInPosition2 != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(carInPosition2, ExceptionReason.None);
+ }
+
+ //下发启动换电
+ InvokeStatus startSwapping = StartSwapping(machine);
+ if (startSwapping != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(startSwapping, ExceptionReason.None);
+ }
+
+ //查看通道状态
+ StateResult checkChannelStatus = CheckChannelStatus(machine);
+ if (checkChannelStatus != null)
+ {
+ return checkChannelStatus;
+ }
+
+ //旧电池拆卸
+ InvokeStatus unPack = UnPack(machine);
+ if (unPack != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(unPack, ExceptionReason.None);
+ }
+
+ //旧电池搬运
+ InvokeStatus oldBatteryCarryIn = OldBatteryCarryIn(machine);
+ if (oldBatteryCarryIn != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(oldBatteryCarryIn, ExceptionReason.None);
+ }
+
+ //新电池搬运
+ InvokeStatus newBatteryCarryOut = NewBatteryCarryOut(machine);
+ if (newBatteryCarryOut != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(newBatteryCarryOut, ExceptionReason.None);
+ }
+
+ //安装
+ InvokeStatus pack = Pack(machine);
+ if (pack != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(pack, ExceptionReason.None);
+ }
+
+ //安装完成
+ InvokeStatus packFinish = PackFinish(machine);
+ if (packFinish != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(packFinish, ExceptionReason.None);
+ }
+
+
return new StateResult()
{
-
- SwappingState = SwappingState.StationReady
+ SwappingState = SwappingState.SwapDone
};
}
+
+ ///
+ /// 下发plc启动换电
+ ///
+ ///
+ public InvokeStatus StartSwapping(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("UnLockCar", 1000, 5, machine.IsCanceled,
+ () => SwappingStateMachine.StartSwappingFlag, () =>
+ {
+ Task result = TBoxApi.UnLockCar();
+ bool unLock = result.Result;
+ if (unLock)
+ {
+ //查询车辆锁止状态
+ var startSwapping = PlcApi.StartSwapping();
+ if (startSwapping)
+ {
+ machine.SwapOrder.SwapBeginTime = DateTime.Now;
+ SwapOrderRepository.Update(machine.SwapOrder);
+ machine.SwapStatus = 0;
+ SwappingStateMachine.StartSwappingFlag = true;
+ }
+ }
+ }, () => { });
+ }
+
+
+ ///
+ /// 读取plc任务状态电池拆卸中
+ /// 读取plc任务状态电池入库搬运中
+ /// 读取plc任务状态电池出库搬运中
+ /// 读取plc任务状态电池安装中
+ /// 读取plc任务状态电池安装完成
+ ///
+ ///
+ public InvokeStatus UnPack(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("plc UnPack", 500, 5, machine.IsCanceled,
+ () => SwappingStateMachine.UnOldBatteryFlag, () =>
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoUnPack.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.InfoUnPack);
+
+ SwappingStateMachine.UnOldBatteryFlag = PlcApi.ReadPlcTaskStatus() == 1002;
+ }, () => { });
+ }
+
+ public InvokeStatus OldBatteryCarryIn(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("plc OldBatteryCarryIn", 500, 5, machine.IsCanceled,
+ () => SwappingStateMachine.StorageOldBatteryFlag, () =>
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoOldBatteryCarryIn.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.InfoOldBatteryCarryIn);
+
+ SwappingStateMachine.StorageOldBatteryFlag = PlcApi.ReadPlcTaskStatus() == 1003;
+ }, () => { });
+ }
+
+ public InvokeStatus NewBatteryCarryOut(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("plc NewBatteryCarryOut", 500, 5, machine.IsCanceled,
+ () => SwappingStateMachine.OutNewBatteryFlag, () =>
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoNewBatteryCarryOut.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.InfoNewBatteryCarryOut);
+
+ SwappingStateMachine.OutNewBatteryFlag = PlcApi.ReadPlcTaskStatus() == 1004;
+ }, () => { });
+ }
+
+
+ public InvokeStatus Pack(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("plc Pack ing", 500, 5, machine.IsCanceled,
+ () => SwappingStateMachine.InstallNewBatteryFlag, () =>
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoPack.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.InfoPack);
+
+ SwappingStateMachine.InstallNewBatteryFlag = PlcApi.ReadPlcTaskStatus() == 1005;
+ }, () => { });
+ }
+
+ public InvokeStatus PackFinish(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("plc Pack Finish", 500, 5, machine.IsCanceled,
+ () => SwappingStateMachine.FinishNewBatteryFlag, () =>
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoPackFinish.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.InfoPackFinish);
+ if (PlcApi.ReadPlcTaskStatus() == 1006)
+ {
+ SwappingStateMachine.FinishNewBatteryFlag = true;
+ SwappingStateMachine.BusinessSwappingForCloudState =
+ InfoEnum.BusinessSwappingForCloudState.SwapFinish;
+ CloudApi.SendStateLog(machine.SwapOrder,SwappingStateMachine.BusinessSwappingForCloudState);
+ SwappingStateMachine.BusinessSwappingStateUpdateTime = DateTime.Now;
+ //上报云平台换电完成
+ machine.SwapStatus = 1;
+ }
+ }, () => { });
+ }
+
+
+ ///
+ /// 查看通道状态
+ /// :0:无效值
+ /// 1000;拍照OK
+ ///1010;拍照NG
+ ///1020;拍照超限,请移车
+ ///
+ ///
+ public StateResult CheckChannelStatus(SwappingStateMachine machine)
+ {
+ while (!SwappingStateMachine.ChannelStatusOkFlag)
+ {
+ _log.Info("begin plc CheckChannelStatus");
+ Thread.Sleep(1000);
+ var channelStatus = PlcApi.ChannelStatus();
+ if (channelStatus == 1000)
+ {
+ SwappingStateMachine.ChannelStatusOkFlag = true;
+ return null;
+ }
+ else if (channelStatus == 1020)
+ {
+ //需要移车 先解锁 提示移动车辆,等待3分钟
+ var lockCar = TBoxApi.LockCar();
+ if (lockCar.Result)
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrChannelStatus.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrChannelStatus);
+ //等待3分钟
+ Thread.Sleep(3000);
+ SwappingStateMachine.VehiclesInPlace2Flag = false;
+ SwappingStateMachine.StartSwappingFlag = false;
+
+ //回归到本阶段的读锁止状态
+ return new StateResult()
+ {
+ SwappingState = SwappingState.DoSwapping
+ };
+ }
+ }
+ else if (channelStatus == 1010)
+ {
+ //故障 不能继续换电,提示驶离,上报云平台,修改换电订单
+ machine.SwapStatus = (int)InfoEnum.SwapOrderResult.Fail;
+
+ //跳转到SwappDone
+ return new StateResult()
+ {
+ SwappingState = SwappingState.SwapDone
+ };
+ }
+ }
+
+ return null;
+ }
+
+
+ ///
+ /// 车辆到位
+ ///
+ ///
+ public InvokeStatus CarInPosition2(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("check CarInPosition2", 500, 50, machine.IsCanceled,
+ () => SwappingStateMachine.VehiclesInPlace2Flag, () =>
+ {
+ var result = TBoxApi.GetCarInfo();
+ TboxCarInfoModel tboxCarInfoModel = result.Result;
+
+ if (tboxCarInfoModel.HeartBeatMsg.KeyStatus == 0)
+ {
+ SwappingStateMachine.VehiclesInPlace2Flag = true;
+ }
+ }, () =>
+ {
+ SwappingStateMachine.ExceptionReason = ExceptionReason.CarInPositionError;
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorCarInPositionTimeout.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrorCarInPositionTimeout);
+ }, false, () => { }
+ , 20, InvokeStatus.None);
+ }
}
\ No newline at end of file
diff --git a/Service/Execute/Step/ExceptionState.cs b/Service/Execute/Step/ExceptionState.cs
index 650f7fd..0676c49 100644
--- a/Service/Execute/Step/ExceptionState.cs
+++ b/Service/Execute/Step/ExceptionState.cs
@@ -1,13 +1,17 @@
-namespace Service.Execute.Step;
+using log4net;
-public class ExceptionState: IState
+namespace Service.Execute.Step;
+
+public class ExceptionState : IState
{
+ private static readonly ILog _log = LogManager.GetLogger(typeof(ExceptionState));
+
public StateResult Handle(SwappingStateMachine machine)
{
-
+ _log.Info($"'goto cancel");
+
return new StateResult()
{
-
SwappingState = SwappingState.StationReady
};
}
diff --git a/Service/Execute/Step/SwapCanStartState.cs b/Service/Execute/Step/SwapCanStartState.cs
new file mode 100644
index 0000000..cc2e544
--- /dev/null
+++ b/Service/Execute/Step/SwapCanStartState.cs
@@ -0,0 +1,98 @@
+using Entity.Constant;
+using log4net;
+using Repository.Station;
+using Service.Cloud.Client;
+using Service.Cloud.Msg.Cloud.Req;
+using Service.Execute.Api;
+using Service.Execute.Enum;
+using Service.Execute.StaticTools;
+using Service.Execute.SwapException;
+using Service.Init;
+using Swapping.Business.Tech;
+
+namespace Service.Execute.Step;
+
+///
+/// 云平台下发换电
+///
+public class SwapCanStartState : IState
+{
+ private readonly ILog _log = LogManager.GetLogger(typeof(SwapCanStartState));
+
+ private SwapOrderRepository SwapOrderRepository { get; set; }
+
+ public StateResult Handle(SwappingStateMachine machine)
+ {
+ InvokeStatus swapCanStart = SwapCanStart(machine);
+
+ if (InvokeStatus.Done != swapCanStart)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(swapCanStart, ExceptionReason.None);
+ }
+
+ return new StateResult()
+ {
+ SwappingState = SwappingState.CarCtrl
+ };
+ }
+
+
+ ///
+ /// 等待云平台下发换电
+ ///
+ ///
+ public InvokeStatus SwapCanStart(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("check swapCanStart", 1000, 50, machine.IsCanceled,
+ () => SwappingStateMachine.CloudCarCanStartFlag, () =>
+ {
+ //远程模式
+ if (StationConstant.StationModel.Remote ==
+ BaseEnumExtensions.GetEnumByCode(
+ int.Parse(StaticStationInfo.StationModel)))
+ {
+ CarCanStart carCanStart = CloudApi.CarCanStart();
+ if (carCanStart != null)
+ {
+ //车牌号
+ if (carCanStart.cn.Equals(machine.TBoxCarInfoModel.CarNo))
+ {
+ //可以开始换电
+ if (carCanStart.cs == 1)
+ {
+ _log.Info("SwapCanStart ok");
+ //更新换电订单
+ machine.SwapOrder.CloudSn = carCanStart.on;
+ SwapOrderRepository.Update(machine.SwapOrder.CloudSn);
+ SwappingStateMachine.CloudCarCanStartFlag = true;
+ }
+ else
+ {
+ _log.Info("SwapCanStart cancel");
+ //语音提示云平台取消换电
+ SwappingStateMachine.CloudCarCanStartFlag = false;
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.CloudSendSwapCancel.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.CloudSendSwapError);
+ SwappingStateMachine.BusinessSwappingForCloudState =
+ InfoEnum.BusinessSwappingForCloudState.SwapReady;
+ CloudApi.SendStateLog(machine.SwapOrder,
+ SwappingStateMachine.BusinessSwappingForCloudState);
+ }
+ }
+ }
+ }
+ else
+ {
+ SwappingStateMachine.CloudCarCanStartFlag = true;
+ //直接下发换电
+ _log.Info("SwapCanStart ok");
+ }
+ }, () =>
+ {
+ SwappingStateMachine.ExceptionReason = ExceptionReason.CloudSendSwapError;
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.CloudSendSwapError.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.CloudSendSwapError);
+ }, false, () => { }
+ , 10, InvokeStatus.None);
+ }
+}
\ No newline at end of file
diff --git a/Service/Execute/Step/SwapDoneState.cs b/Service/Execute/Step/SwapDoneState.cs
index 2a47703..d1061e6 100644
--- a/Service/Execute/Step/SwapDoneState.cs
+++ b/Service/Execute/Step/SwapDoneState.cs
@@ -1,14 +1,141 @@
-namespace Service.Execute.Step;
+using log4net;
+using Repository.Station;
+using Service.Execute.Api;
+using Service.Execute.Enum;
+using Service.Execute.Model;
+using Service.Execute.StaticTools;
+using Service.Execute.SwapException;
+using Swapping.Business.Tech;
-public class SwapDoneState: IState
+namespace Service.Execute.Step;
+
+public class SwapDoneState : IState
{
+ private SwapOrderRepository SwapOrderRepository { get; set; }
+
+ private SwapAmtOrderRepository SwapAmtOrderRepository { get; set; }
+
+ private readonly ILog _log = LogManager.GetLogger(typeof(SwapDoneState));
+
+ ///
+ /// 修改换电订单
+ /// 查看是否有预约单 更新预约单的状态
+ ///
+ ///
+ ///
public StateResult Handle(SwappingStateMachine machine)
{
-
+ //更新换电订单
+ machine.SwapOrder.SwapResult = machine.SwapStatus;
+ machine.SwapOrder.SwapEndTime = DateTime.Now;
+ machine.SwapOrder.FailReason = machine.SwapFailReason;
+ SwapOrderRepository.Update(machine.SwapOrder);
+
+
+ if (machine.SwapStatus == (int)InfoEnum.SwapOrderResult.Success)
+ {
+ //上传云平台换电状态
+ SwappingStateMachine.BusinessSwappingForCloudState = InfoEnum.BusinessSwappingForCloudState.SwapDoneWithVel;
+ CloudApi.SendStateLog(machine.SwapOrder, SwappingStateMachine.BusinessSwappingForCloudState);
+ }
+
+ //云平台没有匹配的失败状态
+ //车辆上锁 ,提示请驶离
+ InvokeStatus lockCar = LockCar(machine);
+
+ if (lockCar != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(lockCar, ExceptionReason.None);
+ }
+
+ //出口雷达监测
+ InvokeStatus existRadar = ExistRadar(machine);
+ if (existRadar != InvokeStatus.Done)
+ {
+ return SwappingStateMachine.ReturnWithInvokeErr(existRadar, ExceptionReason.None);
+ }
+
return new StateResult()
{
-
SwappingState = SwappingState.StationReady
};
}
+
+ ///
+ /// 车辆上锁
+ ///
+ ///
+ public InvokeStatus LockCar(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("LockCar", 500, 100, machine.IsCanceled,
+ () => SwappingStateMachine.VelLockFlag, () =>
+ {
+ Task result = TBoxApi.LockCar();
+ bool unLock = result.Result;
+ if (unLock)
+ {
+ //查询车辆锁止状态
+ Task carInfo = TBoxApi.GetCarInfo();
+ if (carInfo.Result.HeartBeatMsg.LockStatus == 2)
+ {
+ //设置出口的是绿灯
+ if (PlcApi.WriteExistLamp(1000))
+ {
+ machine.LedTool?.WriteProgramContent(
+ machine.SwapStatus == (int)InfoEnum.SwapOrderResult.Success
+ ? InfoEnum.SwapInfo.InfoCarLeave.GetLed()
+ : InfoEnum.SwapInfo.ErrInfoCarLeave.GetLed());
+ SoundTool.PlayOneSound(machine.SwapStatus == (int)InfoEnum.SwapOrderResult.Success
+ ? (int)InfoEnum.SwapInfo.InfoCarLeave
+ : (int)InfoEnum.SwapInfo.ErrInfoCarLeave);
+ SwappingStateMachine.VelLockFlag = true;
+ }
+ }
+ }
+ }, () =>
+ {
+ machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrLockCar.GetLed());
+ SoundTool.PlayOneSound((int)InfoEnum.SwapInfo.ErrLockCar);
+ }, false, () => { SwappingStateMachine.ExceptionReason = ExceptionReason.LockCarError; }
+ , 10, InvokeStatus.None);
+ }
+
+
+ public InvokeStatus ExistRadar(SwappingStateMachine machine)
+ {
+ return Invoker.Invoke("wait exist radar", 1000, 5, machine.IsCanceled,
+ () => SwappingStateMachine.RadarOutFlag, () =>
+ {
+ if (!PlcApi.EntranceRadar())
+ {
+ _log.Info("exist radar false");
+ }
+ else
+ {
+ SwappingStateMachine.ExceptionReason = ExceptionReason.None;
+ _log.Info("exist radar true");
+
+
+ if (PlcApi.WriteExistLamp(1020))
+ {
+ //出口写红灯
+ //更新车辆离场时间,上报云平台
+ SwappingStateMachine.BusinessSwappingForCloudState =
+ InfoEnum.BusinessSwappingForCloudState.SwapDoneWithoutVel;
+ machine.SwapOrder.VehicleLeaveTime = DateTime.Now;
+ SwapOrderRepository.Update(machine.SwapOrder);
+ if (machine.SwapOrderBatteryInfo.swapAmtOrder != null)
+ {
+ machine.SwapOrderBatteryInfo.swapAmtOrder.Status =
+ machine.SwapStatus == (int)InfoEnum.SwapOrderResult.Success
+ ? (int)InfoEnum.AmtOrderStatus.SwapFinish
+ : (int)InfoEnum.AmtOrderStatus.SwapFail;
+ SwapAmtOrderRepository.Update(machine.SwapOrderBatteryInfo.swapAmtOrder);
+ }
+
+ SwappingStateMachine.RadarOutFlag = true;
+ }
+ }
+ });
+ }
}
\ No newline at end of file
diff --git a/Service/Execute/SwapException/ExceptionReason.cs b/Service/Execute/SwapException/ExceptionReason.cs
index 7dea255..2da6f1d 100644
--- a/Service/Execute/SwapException/ExceptionReason.cs
+++ b/Service/Execute/SwapException/ExceptionReason.cs
@@ -17,6 +17,8 @@ namespace Service.Execute.SwapException;
CloudSendSwapError,
SelectPackError,
HvPwrOffError,
+ UnLockCarError,
+ LockCarError,
LvPwrOffError,
SelfCheckError,
TimeOutError
diff --git a/Service/Execute/SwappingStateMachine.cs b/Service/Execute/SwappingStateMachine.cs
index 3028612..dd58b15 100644
--- a/Service/Execute/SwappingStateMachine.cs
+++ b/Service/Execute/SwappingStateMachine.cs
@@ -14,6 +14,8 @@ 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;
@@ -28,7 +30,9 @@ public class SwappingStateMachine : IDisposable
public static DateTime BusinessSwappingStateUpdateTime = DateTime.Now;
public static ExceptionReason ExceptionReason = ExceptionReason.None;
-
+ //换电实时状态 0:开始 1:成功 2:失败
+ public int? SwapStatus = null;
+ public string SwapFailReason = "";
public RfidReadModel? RfidReadModel=null;
public TboxCarInfoModel? TBoxCarInfoModel = null;
@@ -65,21 +69,23 @@ public class SwappingStateMachine : IDisposable
//车辆到位
public static bool VehiclesInPlaceFlag = false;
- //通道定位
- public static bool ChannelPositioningFlag = false;
//下发选包
public static bool DistributeSelectPackFlag = false;
//云平台下发启动换电
- public static bool CloudPackFlag = false;
+ public static bool CloudCarCanStartFlag = false;
//车辆解锁
public static bool VelUnlockFlag = false;
//开始换电
public static bool StartSwappingFlag = false;
-
+ //拍照状态
+ public static bool ChannelStatusOkFlag = false;
+
+ //二次检测车辆到位
+ public static bool VehiclesInPlace2Flag = false;
//拆旧电池
public static bool UnOldBatteryFlag = false;
@@ -113,7 +119,7 @@ public class SwappingStateMachine : IDisposable
Dictionary[SwappingState.Begin] = new BeginState();
Dictionary[SwappingState.StationReady] = new StationReadyState();
Dictionary[SwappingState.CarPrepare] = new CarPrepareState();
- Dictionary[SwappingState.SelectPack] = new CloudSendOutSwapState();
+ Dictionary[SwappingState.SwapCanStart] = new SwapCanStartState();
Dictionary[SwappingState.CarCtrl] = new CarCtrlState();
Dictionary[SwappingState.DoSwapping] = new DoSwappingState();
Dictionary[SwappingState.SwapDone] = new SwapDoneState();
@@ -141,7 +147,7 @@ public class SwappingStateMachine : IDisposable
}
else
{
- return StateResult.Exception(ExceptionReason.ReadRfidError, null);
+ return StateResult.Exception(exceptionReason, null);
}
}
@@ -209,7 +215,7 @@ public enum SwappingState
Begin,
StationReady,
CarPrepare,
- SelectPack,
+ SwapCanStart,
CarCtrl,
DoSwapping,
SwapDone,