完成主流程v1开发

master
lxw 6 months ago
parent e68bae1fb6
commit b27b313163

@ -25,7 +25,7 @@ namespace Service.Cloud.Msg.Cloud.Req
/// </summary>
public string cn { get; set; }
/// <summary>
/// 是否开始换电
/// 是否开始换电 1:可以开始换电 2:终止换电
/// </summary>
public byte cs { get; set; }
public string GetCmd()

@ -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 ;
}
/// <summary>
/// 云平台下发换电指令
/// </summary>
/// <returns></returns>
public static CarCanStart CarCanStart()
{
return CloudClientMgr.CloudClient.CarCanStart;
}
/// <summary>
/// 清除下发的换电指令
/// </summary>
/// <returns></returns>
public static CarCanStart ClearCarCanStartInfo()
{
return CloudClientMgr.CloudClient.CarCanStart=null;
}
}

@ -45,4 +45,57 @@ public class PlcApi
{
return true;
}
/// <summary>
/// 写出口灯
/// 红灯1020
/// 绿灯1000
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static bool WriteExistLamp(int data)
{
return true;
}
/// <summary>
/// 下发选包
/// </summary>
/// <param name="inBinNo">入仓位,仓位号</param>
/// <param name="outBinNo">出仓位,仓位号</param>
/// <returns></returns>
public static bool DistributeSelectPack(string inBinNo, string outBinNo)
{
return true;
}
/// <summary>
/// 下发启动换电
/// </summary>
/// <returns></returns>
public static bool StartSwapping()
{
return true;
}
/// <summary>
/// 查看拍照状态
/// </summary>
/// <returns></returns>
public static byte ChannelStatus()
{
return 0;
}
/// <summary>
/// 读plc任务状态
/// </summary>
/// <returns></returns>
public static byte ReadPlcTaskStatus()
{
return 0;
}
}

@ -62,4 +62,52 @@ public class TBoxApi
return false;
}
}
/// <summary>
/// 车辆解锁
/// </summary>
/// <returns></returns>
public static async Task<bool> 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;
}
}
/// <summary>
/// 车辆上锁
/// </summary>
/// <returns></returns>
public static async Task<bool> 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;
}
}
}

@ -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
}
}

@ -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
};
}

@ -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
};
}
/// <summary>
/// 车辆解锁
/// </summary>
/// <returns></returns>
public InvokeStatus UnLockCar(SwappingStateMachine machine)
{
return Invoker.Invoke("UnLockCar", 500, 100, machine.IsCanceled,
() => SwappingStateMachine.VelUnlockFlag, () =>
{
Task<bool> result = TBoxApi.UnLockCar();
bool unLock = result.Result;
if (unLock)
{
//查询车辆锁止状态
Task<TboxCarInfoModel> 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);
}
/// <summary>
/// 下发选包
/// </summary>
/// <returns></returns>
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()); });
}
}

@ -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);
}
/// <summary>
/// 云平台车辆认证
/// </summary>
@ -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<BinInfo>(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<SwapAmtOrder, SwapAmtOrder>().ReverseMap());
IMapper mapperAmt = configAmt.CreateMapper();
SwapAmtOrder swapAmtOrder = mapperAmt.Map<SwapAmtOrder>(orderBatteryInfo.swapAmtOrder);
swapAmtOrder.Status = 6;
swapAmtOrder.Status = (int)InfoEnum.AmtOrderStatus.Swapping;
AmtOrderRepository.Update(swapAmtOrder);
}

@ -1,52 +0,0 @@
using Entity.Constant;
namespace Service.Execute.Step;
/// <summary>
/// 云平台下发换电
/// </summary>
public class CloudSendOutSwapState: IState
{
public StateResult Handle(SwappingStateMachine machine)
{
return new StateResult()
{
SwappingState = SwappingState.StationReady
};
}
/// <summary>
/// 等待云平台下发换电
/// </summary>
/// <returns></returns>
/*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);
}*/
}

@ -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
};
}
/// <summary>
/// 下发plc启动换电
/// </summary>
/// <returns></returns>
public InvokeStatus StartSwapping(SwappingStateMachine machine)
{
return Invoker.Invoke("UnLockCar", 1000, 5, machine.IsCanceled,
() => SwappingStateMachine.StartSwappingFlag, () =>
{
Task<bool> 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;
}
}
}, () => { });
}
/// <summary>
/// 读取plc任务状态电池拆卸中
/// 读取plc任务状态电池入库搬运中
/// 读取plc任务状态电池出库搬运中
/// 读取plc任务状态电池安装中
/// 读取plc任务状态电池安装完成
/// </summary>
/// <returns></returns>
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;
}
}, () => { });
}
/// <summary>
/// 查看通道状态
/// :0无效值
/// 1000;拍照OK
///1010;拍照NG
///1020;拍照超限,请移车
/// </summary>
/// <returns></returns>
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;
}
/// <summary>
/// 车辆到位
/// </summary>
/// <returns></returns>
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);
}
}

@ -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
};
}

@ -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;
/// <summary>
/// 云平台下发换电
/// </summary>
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
};
}
/// <summary>
/// 等待云平台下发换电
/// </summary>
/// <returns></returns>
public InvokeStatus SwapCanStart(SwappingStateMachine machine)
{
return Invoker.Invoke("check swapCanStart", 1000, 50, machine.IsCanceled,
() => SwappingStateMachine.CloudCarCanStartFlag, () =>
{
//远程模式
if (StationConstant.StationModel.Remote ==
BaseEnumExtensions.GetEnumByCode<StationConstant.StationModel>(
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);
}
}

@ -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));
/// <summary>
/// 修改换电订单
/// 查看是否有预约单 更新预约单的状态
/// </summary>
/// <param name="machine"></param>
/// <returns></returns>
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
};
}
/// <summary>
/// 车辆上锁
/// </summary>
/// <returns></returns>
public InvokeStatus LockCar(SwappingStateMachine machine)
{
return Invoker.Invoke("LockCar", 500, 100, machine.IsCanceled,
() => SwappingStateMachine.VelLockFlag, () =>
{
Task<bool> result = TBoxApi.LockCar();
bool unLock = result.Result;
if (unLock)
{
//查询车辆锁止状态
Task<TboxCarInfoModel> 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;
}
}
});
}
}

@ -17,6 +17,8 @@ namespace Service.Execute.SwapException;
CloudSendSwapError,
SelectPackError,
HvPwrOffError,
UnLockCarError,
LockCarError,
LvPwrOffError,
SelfCheckError,
TimeOutError

@ -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,

Loading…
Cancel
Save