|
|
using Autofac;
|
|
|
using Entity.Attr;
|
|
|
using Entity.Constant;
|
|
|
using HybirdFrameworkCore.Autofac;
|
|
|
using log4net;
|
|
|
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.MyTask;
|
|
|
using Service.Station;
|
|
|
|
|
|
namespace Service.Execute.Step;
|
|
|
|
|
|
public class CarCtrlState : IState
|
|
|
{
|
|
|
private readonly ILog _log = LogManager.GetLogger(typeof(CarCtrlState));
|
|
|
private readonly CommonMgr _CommonMgr = AppInfo.Container.Resolve<CommonMgr>();
|
|
|
|
|
|
public StateResult Handle(SwappingStateMachine machine)
|
|
|
{
|
|
|
//拍照定位
|
|
|
//查看通道状态
|
|
|
StateResult checkChannelStatus = CheckChannelStatus(machine);
|
|
|
if (checkChannelStatus != null)
|
|
|
{
|
|
|
return checkChannelStatus;
|
|
|
}
|
|
|
|
|
|
//vcu反馈换电就绪
|
|
|
InvokeStatus startSwapToTBox = StartSwapToTBox(machine);
|
|
|
if (startSwapToTBox != InvokeStatus.Done)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(startSwapToTBox, ExceptionReason.None);
|
|
|
}
|
|
|
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoTboxHandUp);
|
|
|
|
|
|
////语言播报上高压,举货箱//这时已经发开始换电了
|
|
|
//InvokeStatus liftingBox = LiftingBox(machine);
|
|
|
//if (liftingBox != InvokeStatus.Done)
|
|
|
//{
|
|
|
// return SwappingStateMachine.ReturnWithInvokeErr(liftingBox, ExceptionReason.None);
|
|
|
//}
|
|
|
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoTboxEnergyDown);
|
|
|
|
|
|
//解锁车辆
|
|
|
InvokeStatus unLockCar = UnLockCar(machine);
|
|
|
if (unLockCar != InvokeStatus.Done)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(unLockCar, ExceptionReason.None);
|
|
|
}
|
|
|
|
|
|
//是否为拍按钮启动
|
|
|
InvokeStatus startButton = StartButton(machine);
|
|
|
if (startButton != InvokeStatus.Done)
|
|
|
{
|
|
|
return SwappingStateMachine.ReturnWithInvokeErr(startButton, ExceptionReason.None);
|
|
|
}
|
|
|
|
|
|
|
|
|
//Thread.Sleep(2000);
|
|
|
|
|
|
|
|
|
return new StateResult()
|
|
|
{
|
|
|
SwappingState = SwappingState.DoSwapping
|
|
|
};
|
|
|
}
|
|
|
|
|
|
///// <summary>
|
|
|
///// 举货箱
|
|
|
///// </summary>
|
|
|
///// <returns></returns>
|
|
|
//public InvokeStatus LiftingBox(SwappingStateMachine machine)
|
|
|
//{
|
|
|
// bool isRemote = false;
|
|
|
// return Invoker.Invoke("LiftingBox", 1000, 5, machine.IsCanceled, () => isRemote,
|
|
|
// () =>
|
|
|
// {
|
|
|
// Task<bool> result = TBoxApi.SetHeart(machine.RfidReadModel.VelVin, (byte)2 /*开始换电*/);//设置心跳状态
|
|
|
// if (result.Result)
|
|
|
// {
|
|
|
// var BoxDown = TBoxApi.BoxDown(machine.RfidReadModel.VelVin);
|
|
|
// BoxDown.Wait();
|
|
|
// if (BoxDown.Result)
|
|
|
// {
|
|
|
// isRemote = true;
|
|
|
// }
|
|
|
// }
|
|
|
// }, () =>
|
|
|
// {
|
|
|
// SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoTboxHandUp);
|
|
|
// }, false, () => { machine.ExceptionReason = ExceptionReason.LiftingBoxError; }
|
|
|
// , 10, InvokeStatus.None);
|
|
|
//}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 车辆解锁
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public InvokeStatus UnLockCar(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("UnLockCar", 1000, 3, machine.IsCanceled,
|
|
|
() => machine.VelUnlockFlag, () =>
|
|
|
{
|
|
|
Task<bool> result = TBoxApi.UnLockCarManyTimes(machine.RfidReadModel.VelVin);
|
|
|
result.Wait();
|
|
|
bool unLock = result.Result;
|
|
|
//if (unLock)
|
|
|
{
|
|
|
//查询车辆锁止状态
|
|
|
Task<TboxCarInfoModel> carInfo = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin);
|
|
|
var resultHeartBeatMsg = carInfo.Result.HeartBeatMsg;
|
|
|
|
|
|
//if (resultHeartBeatMsg?.HighVoltage != 2)
|
|
|
//{
|
|
|
// //SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoTboxEnergyDown);
|
|
|
//}
|
|
|
|
|
|
if (resultHeartBeatMsg?.LockStatus == 1 || machine.ManualConfirmCarUnlockFlag)
|
|
|
{
|
|
|
machine.ManualConfirmCarUnlockFlag = false;
|
|
|
machine.BoxCarInfoModel = carInfo.Result;
|
|
|
machine.VelUnlockFlag = true;
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.VelUnlockFlag,
|
|
|
machine);
|
|
|
{//开始下发电池包锁状态
|
|
|
PlcRealTimeTask.LockStatusTask = true;
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}, () =>
|
|
|
{
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrUnLockCar);
|
|
|
}, false, () => { machine.ExceptionReason = ExceptionReason.UnLockCarError; }
|
|
|
, 10, InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
///换电就绪
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public InvokeStatus StartSwapToTBox(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("StartSwapToTBox", 500, 10, machine.IsCanceled,
|
|
|
() => machine.TboxHandUpFlag, () =>
|
|
|
{
|
|
|
var carInfo = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin);
|
|
|
var tboxCarInfoModel = carInfo.Result;
|
|
|
//设置回复心跳状态为换电
|
|
|
Task<bool> result = TBoxApi.SetHeart(machine.RfidReadModel.VelVin, (byte)2 /*换电*/);
|
|
|
//换电就绪
|
|
|
if (tboxCarInfoModel.HeartBeatMsg?.LockStatus == 1)
|
|
|
{
|
|
|
//查询车辆锁止状态
|
|
|
machine.TboxHandUpFlag = true;
|
|
|
_CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.TBoxSwapReadyFlag,
|
|
|
machine);
|
|
|
machine.BoxCarInfoModel = tboxCarInfoModel;
|
|
|
}
|
|
|
}, () =>
|
|
|
{
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrStartSwapToTBox);
|
|
|
}, false, () => { machine.ExceptionReason = ExceptionReason.StartSwapToTBoxError; }
|
|
|
, 10, InvokeStatus.None);
|
|
|
}
|
|
|
|
|
|
///// <summary>
|
|
|
/////收到抬起到位信号
|
|
|
///// </summary>
|
|
|
///// <returns></returns>
|
|
|
//public InvokeStatus TBoxHandUp(SwappingStateMachine machine)
|
|
|
//{
|
|
|
// return Invoker.Invoke("TBoxHandUp", 500, 5, machine.IsCanceled,
|
|
|
// () => machine.TboxHandUpFlag, () =>
|
|
|
// {
|
|
|
// var carInfo = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin);
|
|
|
|
|
|
// var tboxCarInfoModel = carInfo.Result;
|
|
|
|
|
|
// //货箱抬起
|
|
|
|
|
|
// if (tboxCarInfoModel.HeartBeatMsg?.CrateBrimStatus == 3)
|
|
|
// {
|
|
|
// //查询车辆锁止状态
|
|
|
// machine.TboxHandUpFlag = true;
|
|
|
// // _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.TBoxSwapReadyFlag,
|
|
|
// // machine);
|
|
|
// machine.BoxCarInfoModel = tboxCarInfoModel;
|
|
|
// }
|
|
|
// }, () =>
|
|
|
// {
|
|
|
// // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrUnLockCar.GetLed());
|
|
|
// SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoTboxHandUp);
|
|
|
// }, false, () => { }
|
|
|
// , 5, InvokeStatus.None);
|
|
|
//}
|
|
|
|
|
|
|
|
|
///// <summary>
|
|
|
/////收到下电成功
|
|
|
///// </summary>
|
|
|
///// <returns></returns>
|
|
|
//public InvokeStatus TBoxEnergyDown(SwappingStateMachine machine)
|
|
|
//{
|
|
|
// return Invoker.Invoke("TBoxEnergyDown", 500, 5, machine.IsCanceled,
|
|
|
// () => machine.TboxEnergyDownFlag, () =>
|
|
|
// {
|
|
|
// var carInfo = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin);
|
|
|
|
|
|
// var tboxCarInfoModel = carInfo.Result;
|
|
|
// //换电就绪
|
|
|
// if (tboxCarInfoModel?.HeartBeatMsg?.HighVoltage == 2)
|
|
|
// {
|
|
|
// //查询车辆锁止状态
|
|
|
// machine.TboxEnergyDownFlag = true;
|
|
|
// // _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.TBoxSwapReadyFlag,
|
|
|
// // machine);
|
|
|
// machine.BoxCarInfoModel = tboxCarInfoModel;
|
|
|
// }
|
|
|
// }, () =>
|
|
|
// {
|
|
|
// // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrUnLockCar.GetLed());
|
|
|
// SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoTboxEnergyDown);
|
|
|
// }, false, () => { }
|
|
|
// , 5, InvokeStatus.None);
|
|
|
//}
|
|
|
|
|
|
|
|
|
/// <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();
|
|
|
PlcRealTimeTask.CameraTask = true;//开始记录拍照偏移日志
|
|
|
PlcRealTimeTask.VehicleParkingStatusTask = true;//开始下发车辆驻车状态
|
|
|
|
|
|
if (count % 5 == 0)
|
|
|
{
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.CarTakePhotoInfo);
|
|
|
}
|
|
|
|
|
|
count++;
|
|
|
|
|
|
//1000;拍照OK 1010;拍照NG 1020;拍照超限,请移车
|
|
|
if (channelStatus[0] == 1000 && channelStatus[1] == 1000)
|
|
|
{
|
|
|
machine.ChannelStatusOkFlag = true;
|
|
|
return null;
|
|
|
}
|
|
|
else if(channelStatus.Contains((ushort)1020))
|
|
|
{
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.CarTakePhotoErrRepeat);
|
|
|
//故障 不能继续换电,提示驶离,上报云平台,修改换电订单
|
|
|
machine.SwapStatus = (int)InfoEnum.SwapOrderResult.Fail;
|
|
|
machine.SwapFailReason = "拍照故障 plc故障码1010";
|
|
|
Thread.Sleep(5000);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 收到实体按钮已拍
|
|
|
/// </summary>
|
|
|
/// <param name="machine"></param>
|
|
|
/// <returns></returns>
|
|
|
public InvokeStatus StartButton(SwappingStateMachine machine)
|
|
|
{
|
|
|
return Invoker.Invoke("plc StartButton", 500, 5, machine.IsCanceled,
|
|
|
() => machine.PhysicalButtonState, () =>
|
|
|
{
|
|
|
if (StaticStationInfo.SwapInitiateMode == 2)
|
|
|
{
|
|
|
if (PlcApi.ReadPhysicalButtonState())
|
|
|
{
|
|
|
machine.PhysicalButtonState = true;
|
|
|
}
|
|
|
|
|
|
SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoManualStartSwap);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
machine.PhysicalButtonState = true;
|
|
|
}
|
|
|
|
|
|
}, () => { }, false, () => { }, 10,
|
|
|
InvokeStatus.None);
|
|
|
}
|
|
|
} |