|
|
using Autofac;
|
|
|
using Entity.Attr;
|
|
|
using Entity.Constant;
|
|
|
using HybirdFrameworkCore.Autofac;
|
|
|
using log4net;
|
|
|
using Repository.Station;
|
|
|
using Service.Execute.Api;
|
|
|
using Service.Execute.Model;
|
|
|
using Service.Execute.Model.Tbox;
|
|
|
using Service.Execute.StaticTools;
|
|
|
using Service.Execute.SwapException;
|
|
|
using Service.Execute.Utils;
|
|
|
using Service.Init;
|
|
|
using Service.Plc.Client;
|
|
|
using Service.Station;
|
|
|
|
|
|
namespace Service.Execute.Step;
|
|
|
|
|
|
public class DoSwappingState : IState
|
|
|
{
|
|
|
private readonly ILog _log = LogManager.GetLogger(typeof(DoSwappingState));
|
|
|
private readonly CommonMgr _CommonMgr = AppInfo.Container.Resolve<CommonMgr>();
|
|
|
|
|
|
public StateResult Handle(SwappingStateMachine machine)
|
|
|
{
|
|
|
//上报云平台换电开始
|
|
|
machine.BusinessSwappingForCloudState = InfoEnum.BusinessSwappingForCloudState.BeginSwap;
|
|
|
machine.BusinessSwappingStateUpdateTime = DateTime.Now;
|
|
|
_log.Info($"BusinessSwappingForCloudState={machine.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);
|
|
|
}
|
|
|
|
|
|
InvokeStatus holdOn = HoldOn(machine);
|
|
|
if (holdOn != InvokeStatus.Done)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(holdOn, 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);
|
|
|
}
|
|
|
|
|
|
|
|
|
//航车回归安全位置
|
|
|
InvokeStatus toInvokeStatus = ToSafePosition(machine);
|
|
|
if (toInvokeStatus != InvokeStatus.Done)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(toInvokeStatus, ExceptionReason.None);
|
|
|
}
|
|
|
//查询换电任务是否结束
|
|
|
|
|
|
|
|
|
return new StateResult()
|
|
|
{
|
|
|
SwappingState = SwappingState.SwapDone
|
|
|
};
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 下发plc启动换电
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public InvokeStatus StartSwapping(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("UnLockCar", 1000, 5, machine.IsCanceled,
|
|
|
() => machine.StartSwappingFlag, () =>
|
|
|
{
|
|
|
Task<bool> result = TBoxApi.UnLockCarManyTimes(machine.RfidReadModel.VelVin);
|
|
|
bool unLock = result.Result;
|
|
|
if (unLock)
|
|
|
{
|
|
|
//查询当前是否有任务执行
|
|
|
|
|
|
var readTaskNo = PlcMgr.PlcClient?.ReadTaskNo();
|
|
|
if (readTaskNo == 0 || readTaskNo == 1)
|
|
|
{
|
|
|
PlcMgr.PlcClient?.ExChangeTaskNo(1);
|
|
|
//查询车辆锁止状态
|
|
|
var startSwapping = PlcApi.StartSwapping(machine.SwapOrderBatteryInfo.InBinInfo.No,
|
|
|
machine.SwapOrderBatteryInfo.UpBinInfo.No);
|
|
|
|
|
|
//查詢當前任務狀態是否被更改
|
|
|
var readPlcTaskStatus = PlcApi.ReadTaskStatus(1);
|
|
|
if (startSwapping && readPlcTaskStatus)
|
|
|
{
|
|
|
machine.SwapOrder.SwapBeginTime = DateTime.Now;
|
|
|
_CommonMgr.UpdateSwapOrder(machine);
|
|
|
machine.SwapStatus = 0;
|
|
|
machine.StartSwappingFlag = true;
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.StartSwappingFlag,
|
|
|
machine);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
_log.Info("当前有任务在执行");
|
|
|
}
|
|
|
}
|
|
|
}, () => { SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrStartSwap); }, false, () => { }, 10,
|
|
|
InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// plc读任务状态 上使能
|
|
|
/// </summary>
|
|
|
/// <param name="machine"></param>
|
|
|
/// <returns></returns>
|
|
|
public InvokeStatus HoldOn(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("plc HoldOn", 1000, 5, machine.IsCanceled,
|
|
|
() => machine.PlcHoldFlag, () =>
|
|
|
{
|
|
|
//查询车辆锁止状态
|
|
|
var taskPrepare = PlcApi.ReadTaskStatus(1);
|
|
|
if (taskPrepare)
|
|
|
{
|
|
|
bool holdOn = PlcApi.HoldOn();
|
|
|
if (holdOn)
|
|
|
{
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.StartSwapInfo);
|
|
|
machine.PlcHoldFlag = true;
|
|
|
}
|
|
|
}
|
|
|
}, () => { });
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 读取plc任务状态电池拆卸中
|
|
|
/// 读取plc任务状态电池入库搬运中
|
|
|
/// 读取plc任务状态电池出库搬运中
|
|
|
/// 读取plc任务状态电池安装中
|
|
|
/// 读取plc任务状态电池安装完成
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public InvokeStatus UnPack(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("plc UnPack", 500, 5, machine.IsCanceled,
|
|
|
() => machine.UnOldBatteryFlag, () =>
|
|
|
{
|
|
|
// machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoUnPack.GetLed());
|
|
|
|
|
|
|
|
|
int status = PlcApi.ReadPlcTaskStatus();
|
|
|
//处理程序太快,plc还没有初始值的状态
|
|
|
if (status == 1002 || status != 1003)
|
|
|
{
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
machine.UnOldBatteryFlag = true;
|
|
|
}
|
|
|
|
|
|
if (machine.UnOldBatteryFlag)
|
|
|
{
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.UnOldBatteryFlag,
|
|
|
machine);
|
|
|
}
|
|
|
}, () => { SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoUnPack); }, false, () => { }, 10,
|
|
|
InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
public InvokeStatus OldBatteryCarryIn(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("plc OldBatteryCarryIn", 500, 5, machine.IsCanceled,
|
|
|
() => machine.StorageOldBatteryFlag, () =>
|
|
|
{
|
|
|
// machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoOldBatteryCarryIn.GetLed());
|
|
|
var readPlcTaskStatus = PlcApi.ReadPlcTaskStatus();
|
|
|
|
|
|
if (readPlcTaskStatus == 1003 || readPlcTaskStatus != 1004)
|
|
|
{
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
machine.StorageOldBatteryFlag = true;
|
|
|
}
|
|
|
|
|
|
machine.StorageOldBatteryFlag = readPlcTaskStatus == 1004;
|
|
|
|
|
|
if (machine.StorageOldBatteryFlag)
|
|
|
{
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.StorageOldBatteryFlag,
|
|
|
machine);
|
|
|
}
|
|
|
}, () => { SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoOldBatteryCarryIn); }, false, () => { }, 10,
|
|
|
InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
public InvokeStatus NewBatteryCarryOut(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("plc NewBatteryCarryOut", 500, 5, machine.IsCanceled,
|
|
|
() => machine.OutNewBatteryFlag, () =>
|
|
|
{
|
|
|
// machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoNewBatteryCarryOut.GetLed());
|
|
|
|
|
|
if (PlcApi.ReadPlcTaskStatus() == 1004)
|
|
|
{
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
machine.OutNewBatteryFlag = true;
|
|
|
}
|
|
|
|
|
|
if (machine.OutNewBatteryFlag)
|
|
|
{
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.OutNewBatteryFlag,
|
|
|
machine);
|
|
|
}
|
|
|
}, () => { SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoNewBatteryCarryOut); }, false, () => { }, 10,
|
|
|
InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
|
|
|
public InvokeStatus Pack(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("plc Pack ing", 500, 5, machine.IsCanceled,
|
|
|
() => machine.InstallNewBatteryFlag, () =>
|
|
|
{
|
|
|
// machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoPack.GetLed());
|
|
|
if (PlcApi.ReadPlcTaskStatus() == 1005)
|
|
|
{
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
machine.InstallNewBatteryFlag = true;
|
|
|
}
|
|
|
|
|
|
if (machine.InstallNewBatteryFlag)
|
|
|
{
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.InstallNewBatteryFlag,
|
|
|
machine);
|
|
|
}
|
|
|
}, () => { SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoPack); }, false, () => { },
|
|
|
10, InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
public InvokeStatus PackFinish(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("plc Pack Finish", 500, 5, machine.IsCanceled,
|
|
|
() => machine.FinishNewBatteryFlag, () =>
|
|
|
{
|
|
|
// machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoPackFinish.GetLed());
|
|
|
var readPlcTaskStatus = PlcApi.ReadPlcTaskStatus();
|
|
|
if (readPlcTaskStatus == 1006 || readPlcTaskStatus == 1007)
|
|
|
{
|
|
|
machine.FinishNewBatteryFlag = true;
|
|
|
machine.BusinessSwappingForCloudState =
|
|
|
InfoEnum.BusinessSwappingForCloudState.SwapFinish;
|
|
|
// CloudApi.SendStateLog(machine.SwapOrder, machine.BusinessSwappingForCloudState);
|
|
|
machine.BusinessSwappingStateUpdateTime = DateTime.Now;
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoPackFinish);
|
|
|
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.FinishNewBatteryFlag,
|
|
|
machine);
|
|
|
}
|
|
|
}, () => { }, false, () => { },
|
|
|
10, InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 行车回归安全位置
|
|
|
/// </summary>
|
|
|
/// <param name="machine"></param>
|
|
|
/// <returns></returns>
|
|
|
public InvokeStatus ToSafePosition(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("plc ToSavePosition", 500, 5, machine.IsCanceled,
|
|
|
() => machine.ToSafePositionFlag, () =>
|
|
|
{
|
|
|
// machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoPackFinish.GetLed());
|
|
|
|
|
|
if (PlcApi.ReadPlcTaskStatus() == 1007)
|
|
|
{
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoToSafePosition);
|
|
|
machine.ToSafePositionFlag = true;
|
|
|
machine.BusinessSwappingStateUpdateTime = DateTime.Now;
|
|
|
|
|
|
machine.SwapStatus = 1;
|
|
|
}
|
|
|
}, () => { });
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查看通道状态
|
|
|
/// :0:无效值
|
|
|
/// 1000;拍照OK
|
|
|
///1010;拍照NG
|
|
|
///1020;拍照超限,请移车
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public StateResult CheckChannelStatus(SwappingStateMachine machine)
|
|
|
{
|
|
|
int count = 0;
|
|
|
while (!machine.ChannelStatusOkFlag)
|
|
|
{
|
|
|
if (machine.CancelFlag)
|
|
|
{
|
|
|
_log.Info($" CheckChannelStatus canceled");
|
|
|
return StateResult.Cancel;
|
|
|
}
|
|
|
|
|
|
_log.Info("begin plc CheckChannelStatus");
|
|
|
Thread.Sleep(2000);
|
|
|
var channelStatus = PlcApi.ChannelStatus();
|
|
|
if (count % 10 == 0)
|
|
|
{
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.CarTakePhotoInfo);
|
|
|
}
|
|
|
|
|
|
count++;
|
|
|
|
|
|
if (channelStatus == 1000)
|
|
|
{
|
|
|
machine.ChannelStatusOkFlag = true;
|
|
|
return null;
|
|
|
}
|
|
|
else if (channelStatus == 1020)
|
|
|
{
|
|
|
//需要移车 先解锁 提示移动车辆,等待3分钟
|
|
|
var lockCar = TBoxApi.LockCarManyTimes(machine.RfidReadModel.VelVin);
|
|
|
if (lockCar.Result)
|
|
|
{
|
|
|
// machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrChannelStatus.GetLed());
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrChannelStatus);
|
|
|
//等待2分钟
|
|
|
Thread.Sleep(3 * 60 * 1000);
|
|
|
machine.VehiclesInPlace2Flag = false;
|
|
|
machine.StartSwappingFlag = false;
|
|
|
machine.PlcHoldFlag = false;
|
|
|
machine.ChannelStatusOkFlag = false;
|
|
|
//回归到本阶段的读锁止状态
|
|
|
return new StateResult()
|
|
|
{
|
|
|
SwappingState = SwappingState.DoSwapping
|
|
|
};
|
|
|
}
|
|
|
}
|
|
|
else if (channelStatus == 1010)
|
|
|
{
|
|
|
//故障 不能继续换电,提示驶离,上报云平台,修改换电订单
|
|
|
machine.SwapStatus = (int)InfoEnum.SwapOrderResult.Fail;
|
|
|
machine.SwapFailReason = "拍照故障 plc故障码1010";
|
|
|
//跳转到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,
|
|
|
() => machine.VehiclesInPlace2Flag, () =>
|
|
|
{
|
|
|
var result = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin);
|
|
|
TboxCarInfoModel tboxCarInfoModel = result.Result;
|
|
|
|
|
|
int succCount = 0;
|
|
|
List<bool> succL = new List<bool>()
|
|
|
{
|
|
|
StaticStationInfo.TboxStateFlameout, StaticStationInfo.TboxStateBreak, StaticStationInfo.TboxStateN
|
|
|
};
|
|
|
var successCount = succL.Where(i => i).Count();
|
|
|
|
|
|
var status = tboxCarInfoModel?.CarStatus;
|
|
|
|
|
|
if (StaticStationInfo.TboxStateFlameout)
|
|
|
{
|
|
|
if (status?.Keys == 0)
|
|
|
{
|
|
|
succCount++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (StaticStationInfo.TboxStateBreak)
|
|
|
{
|
|
|
if (status?.Break == 1)
|
|
|
{
|
|
|
succCount++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (StaticStationInfo.TboxStateN)
|
|
|
{
|
|
|
if (status?.Gear == 0)
|
|
|
{
|
|
|
succCount++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (succCount == successCount)
|
|
|
{
|
|
|
machine.VehiclesInPlace2Flag = true;
|
|
|
}
|
|
|
}, () =>
|
|
|
{
|
|
|
machine.ExceptionReason = ExceptionReason.CarInPositionError;
|
|
|
// machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorCarInPositionTimeout.GetLed());
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorCarInPositionTimeout);
|
|
|
}, false, () => { }
|
|
|
, 20, InvokeStatus.None);
|
|
|
}
|
|
|
}
|