From 95e73fcbe15de4d7c50271a94d93f490d4f3610a Mon Sep 17 00:00:00 2001 From: lxw Date: Tue, 6 Aug 2024 14:33:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8D=A2=E7=94=B5=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Entity/Constant/InfoEnum.cs | 112 ++++++++------- Service/Execute/Api/PlcApi.cs | 59 ++++++-- Service/Execute/Invoker.cs | 1 + Service/Execute/Step/CarCtrlState.cs | 68 +++++++-- Service/Execute/Step/CarPrepareState.cs | 129 +++++++++++++++++- Service/Execute/Step/DoSwappingState.cs | 117 ++-------------- Service/Execute/Step/StationReadyState.cs | 3 +- .../Execute/SwapException/ExceptionReason.cs | 3 +- Service/Execute/SwappingStateMachine.cs | 12 +- Service/Plc/Client/PlcMgr.cs | 93 +++++++++++-- Service/Plc/Msg/PlcToHost.cs | 8 ++ 11 files changed, 408 insertions(+), 197 deletions(-) diff --git a/Entity/Constant/InfoEnum.cs b/Entity/Constant/InfoEnum.cs index 1da050e..5f970b1 100644 --- a/Entity/Constant/InfoEnum.cs +++ b/Entity/Constant/InfoEnum.cs @@ -8,53 +8,63 @@ public class InfoEnum { public enum SwapInfo : ushort { - - - [Info("欢迎光临换电站!(正在营业)","欢迎光临换电站!,本站正在营业中")]WelcomeInfo=1, - [Info("标签读写失败", "标签读写失败")] ErrorReadRfid , - - [Info("车辆连接失败", "车辆连接失败,请联系站务人员")] ErrorTBoxConn , - [Info("云端校验失败", "云端校验失败,请联系站务人员")] ErrorCloudCheck , - [Info("车辆已到位", "车辆已到位")] InfoCarInPosition , + [Info("欢迎光临换电站!(正在营业)", "欢迎光临换电站!,本站正在营业中")] + WelcomeInfo = 1, + [Info("标签读写失败", "标签读写失败")] ErrorReadRfid, + + [Info("车辆连接失败", "车辆连接失败,请联系站务人员")] ErrorTBoxConn, + [Info("云端校验失败", "云端校验失败,请联系站务人员")] ErrorCloudCheck, + [Info("车辆已到位", "车辆已到位")] InfoCarInPosition, + //TODO:: 录音内容已改 [Info("请熄火挂空挡拉手刹", "请熄火挂空挡拉手刹")] ErrorCarInPositionTimeout, - [Info("云平台下发换电失败", "云平台下发换电超时")] CloudSendSwapError , - - - [Info("解锁车辆失败", "解锁车辆失败")] ErrUnLockCar , - [Info("选包失败,请驶离", "选包失败,请驶离")] ErrorSelectPack , - [Info("通道拍照定位失败,请在三分钟内重新调整车辆位置", "通道拍照定位失败,请在三分钟内重新调整车辆位置")]ErrChannelStatus, - - - [Info("电池拆卸中,请稍后", "电池拆卸中,请稍后")] InfoUnPack , - - [Info("电池安装中,请稍后", "电池安装中,请稍后")] InfoPack , - [Info("电池包已安装完成", "电池包已安装完成")] InfoPackFinish , - [Info("航车已回归安全位置", "航车已回归安全位置")] InfoToSafePosition , - [Info("换电已完成,请驶离", "换电已完成,请驶离")] InfoCarLeave , - [Info("换电失败,请驶离", "换电失败,请驶离")] ErrInfoCarLeave , - [Info("电池入仓中,请稍后", "电池入仓中,请稍后")] InfoOldBatteryCarryIn , - [Info("电池出仓中,请稍后", "电池出仓中,请稍后")] InfoNewBatteryCarryOut , - [Info("车辆上锁失败", "车辆上锁失败")] ErrLockCar , - [Info("通道的电池仓无可用换电电池","通道的电池仓无可用换电电池")] NoBatteryErr, - [Info("结束充电电池数量不足","通道的电池仓无可用换电电池")] LessOfFinishChargingErr, - [Info("空仓数量不足","通道的电池仓无可用换电电池")] LessOfEmptyBinErr, - [Info("符合soc限制数量不足","通道的电池仓无可用换电电池")] LessOfSocErr, - [Info("结束充电大于3分钟的数量不足","通道的电池仓无可用换电电池")] LessOf3MinuteErr, - [Info("换电站处于手动模式,不能自动换电","换电站处于手动模式,不能自动换电")] InfoStationModel, - - [Info("换电站处于本地模式,不能远程换电","换电站处于本地模式,不能远程换电")] InfoStationModelRemoteErr, - - [Info("车辆驶入","车辆驶入")] CarInInfo, - [Info("换电任务启动","换电任务启动")] StartSwapInfo, - [Info("航车拍照中,请稍后","航车拍照中,请稍后")] CarTakePhotoInfo, - [Info("启动换电失败,请联系站务人员","启动换电失败,请联系站务人员")] ErrStartSwap, - [Info("即将进行消防移仓,请车辆驶离","即将进行消防移仓,请车辆驶离")] InfoFireRemoveLabel, - [Info("电池移仓中","电池移仓中")] InfoBatteryMove, - [Info("消防移仓中","消防移仓中")] InfoFireRemove, - [Info("拍照失败,请在三分钟内挪车","拍照失败,请在三分钟内挪车")] ErrChannel1020, + [Info("云平台下发换电失败", "云平台下发换电超时")] CloudSendSwapError, + + + [Info("解锁车辆失败,请人工解锁", "解锁车辆失败,请人工解锁")] ErrUnLockCar, + [Info("选包失败,请驶离", "选包失败,请驶离")] ErrorSelectPack, + [Info("停车超限,请使出重新进入", "停车超限,请使出重新进入")] ErrChannelStatus, + [Info("电池拆卸中,请稍后", "电池拆卸中,请稍后")] InfoUnPack, + [Info("电池安装中,请稍后", "电池安装中,请稍后")] InfoPack, + [Info("电池包已安装完成", "电池包已安装完成")] InfoPackFinish, + [Info("航车已回归安全位置", "航车已回归安全位置")] InfoToSafePosition, + [Info("换电已完成,请驶离", "换电已完成,请驶离")] InfoCarLeave, + [Info("换电失败,请驶离", "换电失败,请驶离")] ErrInfoCarLeave, + [Info("电池入仓中,请稍后", "电池入仓中,请稍后")] InfoOldBatteryCarryIn, + [Info("电池出仓中,请稍后", "电池出仓中,请稍后")] InfoNewBatteryCarryOut, + [Info("车辆上锁失败", "车辆上锁失败")] ErrLockCar, + + [Info("通道的电池仓无可用换电电池", "通道的电池仓无可用换电电池")] + NoBatteryErr, + [Info("结束充电电池数量不足", "通道的电池仓无可用换电电池")] LessOfFinishChargingErr, + [Info("空仓数量不足", "通道的电池仓无可用换电电池")] LessOfEmptyBinErr, + [Info("符合soc限制数量不足", "通道的电池仓无可用换电电池")] LessOfSocErr, + + [Info("结束充电大于3分钟的数量不足", "通道的电池仓无可用换电电池")] + LessOf3MinuteErr, + + [Info("换电站处于手动模式,不能自动换电", "换电站处于手动模式,不能自动换电")] + InfoStationModel, + + [Info("换电站处于本地模式,不能远程换电", "换电站处于本地模式,不能远程换电")] + InfoStationModelRemoteErr, + + [Info("车辆驶入", "车辆驶入")] CarInInfo, + [Info("换电任务启动", "换电任务启动")] StartSwapInfo, + [Info("航车拍照中,请稍后", "航车拍照中,请稍后")] CarTakePhotoInfo, + + [Info("启动换电失败,请联系站务人员", "启动换电失败,请联系站务人员")] + ErrStartSwap, + + [Info("即将进行消防移仓,请车辆驶离", "即将进行消防移仓,请车辆驶离")] + InfoFireRemoveLabel, + [Info("电池移仓中", "电池移仓中")] InfoBatteryMove, + [Info("消防移仓中", "消防移仓中")] InfoFireRemove, + + [Info("拍照失败,请在三分钟内挪车", "拍照失败,请在三分钟内挪车")] + ErrChannel1020, } - + public enum SelectBinStatusInfo : byte { @@ -67,7 +77,7 @@ public class InfoEnum [Const("预约电池异常")] AmtError, } - + public enum AmtOrderStatus : byte { [Const("预约成功")] Success = 1, @@ -96,19 +106,20 @@ public class InfoEnum [Const("换电完成(车辆未驶离)")] SwapDoneWithVel, [Const("换电完成(车辆驶离)")] SwapDoneWithoutVel } - + //小步状态 - public enum BusinessSwappingStep + public enum BusinessSwappingStep { [Const("空闲")] Idel, [Const("车辆到站(入口雷达检测到车辆驶入)")] RadarInFlag, [Const("rfid扫描完成")] RfidReadFlag, [Const("云平台车辆认证")] CloudVelCheckFlag, [Const("车辆到位")] CarInPositionFlag, + // [Const("云平台下发换电指令")] CloudCarCanStartFlag, [Const("车辆解锁")] VelUnlockFlag, // [Const("下发plc选包")] DistributeSelectPackFlag, - + [Const("开始换电")] StartSwappingFlag, [Const("拆旧电池完成")] UnOldBatteryFlag, [Const("入库旧电池完成")] StorageOldBatteryFlag, @@ -120,11 +131,8 @@ public class InfoEnum [Const("换电失败(车辆驶离)")] RadarOutFailFlag, } - - - - public enum AmtBatLockStatus + public enum AmtBatLockStatus { UnLock = 0, Lock = 1 diff --git a/Service/Execute/Api/PlcApi.cs b/Service/Execute/Api/PlcApi.cs index 541782b..f4a0f9d 100644 --- a/Service/Execute/Api/PlcApi.cs +++ b/Service/Execute/Api/PlcApi.cs @@ -9,22 +9,18 @@ public class PlcApi private static readonly ILog Log = LogManager.GetLogger("PlcApi"); - /// /// 数据有效时间。单位秒 /// static int DataTimeSeconds = 2; - - /// /// 是否远程模式 /// /// public static bool IsRemote() { - var isRemote = PlcMgr.IsRemote(); Log.Info($"PlcApi IsRemove resp={isRemote}"); return isRemote; @@ -89,6 +85,13 @@ public class PlcApi return writeExistLamp; } + //z轴上升 + public static bool ZPushUp() + { + return PlcMgr.ZPushUp(); + + } + /// /// 下发选包 /// @@ -108,7 +111,6 @@ public class PlcApi /// public static bool StartSwapping(string inBinNo, string outBinNo) { - Log.Info($"PlcApi StartSwapping param= inBinNo={inBinNo}, outBinNo={outBinNo}"); var distributeTask = PlcMgr.DistributeTask(ushort.Parse(inBinNo), ushort.Parse(outBinNo), 1); @@ -129,7 +131,18 @@ public class PlcApi Log.Info($"PlcApi ReadTaskStatus resp={readTaskStatus}"); return readTaskStatus; } - + + /// + /// 查看换电允许 + /// + /// + public static bool ReadSwapReady() + { + PlcMgr.ResetPlc(); + Log.Info($"PlcApi ReadSwapReady "); + return PlcMgr.ReadSwapReady(); + } + /// /// plc上使能 1换电,2移仓,3消防 /// @@ -142,6 +155,17 @@ public class PlcApi return holdOn; } + /// + /// 行车回归初始位置 + /// + /// + public static bool PlcCarInit() + { + Log.Info($"PlcApi Init "); + return PlcMgr.PlcCarInit(); + } + + /// /// 查看拍照状态 /// @@ -154,7 +178,7 @@ public class PlcApi Log.Info($"PlcApi ChannelStatus resp= {channelStatus}"); return channelStatus; } - + /// /// 换电过程状态 /// 0:无效值 @@ -209,5 +233,24 @@ public class PlcApi return readPlcTaskStatus; } -} + //拍照准备 + public static bool ReadyPlcPhoto() + { + Log.Info($"PlcApi start ReadyPlcPhoto "); + return PlcMgr.PhotoPreparation(); + } + //行车在拍照位 + public static bool CarInPhotoPosition() + { + Log.Info($"PlcApi start CarInPhotoPosition "); + return PlcMgr.CarInPhotoPosition(); + } + + //拍照 + public static bool TakPhoto() + { + Log.Info($"PlcApi start TakPhoto "); + return PlcMgr.TakePhoto(); + } +} \ No newline at end of file diff --git a/Service/Execute/Invoker.cs b/Service/Execute/Invoker.cs index 30a04b7..4db8503 100644 --- a/Service/Execute/Invoker.cs +++ b/Service/Execute/Invoker.cs @@ -287,4 +287,5 @@ public enum InvokeStatus Exception, None, ManualSucc, + Fail, } \ No newline at end of file diff --git a/Service/Execute/Step/CarCtrlState.cs b/Service/Execute/Step/CarCtrlState.cs index fe76338..113cbff 100644 --- a/Service/Execute/Step/CarCtrlState.cs +++ b/Service/Execute/Step/CarCtrlState.cs @@ -9,6 +9,7 @@ using Service.Execute.Model.Tbox; using Service.Execute.StaticTools; using Service.Execute.SwapException; using Service.Execute.Utils; +using Service.Plc.Client; using Service.Station; namespace Service.Execute.Step; @@ -20,8 +21,16 @@ public class CarCtrlState : IState public StateResult Handle(SwappingStateMachine machine) { - - + + + + + //写选包 --判断是否允许换电 + InvokeStatus issuedPlcPack = IssuedPlcPack(machine); + if (issuedPlcPack != InvokeStatus.Done) + { + return SwappingStateMachine.ReturnWithInvokeErr(issuedPlcPack, ExceptionReason.None); + } //解锁车辆 InvokeStatus unLockCar = UnLockCar(machine); if (unLockCar != InvokeStatus.Done) @@ -29,14 +38,6 @@ public class CarCtrlState : IState return SwappingStateMachine.ReturnWithInvokeErr(unLockCar, ExceptionReason.None); } - //下发选包 - /*InvokeStatus distributeSelectPack = DistributeSelectPack(machine); - - if (distributeSelectPack != InvokeStatus.Done) - { - return SwappingStateMachine.ReturnWithInvokeErr(distributeSelectPack, ExceptionReason.None); - } - */ return new StateResult() { @@ -44,6 +45,43 @@ public class CarCtrlState : IState }; } + + /// + /// 下发plc選報 + /// + /// + public InvokeStatus IssuedPlcPack(SwappingStateMachine machine) + { + return Invoker.Invoke("IssuedPlcPack", 1000, 5, machine.IsCanceled, + () => machine.StartSwappingFlag, () => + { + //查询当前是否有任务执行 + 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.ReadSwapReady(); + if (startSwapping && readPlcTaskStatus) + { + machine.SwapOrder.SwapBeginTime = DateTime.Now; + _CommonMgr.UpdateSwapOrder(machine); + machine.SwapStatus = 0; + machine.StartSwappingFlag = true; + } + } + else + { + _log.Info("当前有任务在执行"); + } + }, () => { SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrStartSwap); }, false, () => { }, 10, + InvokeStatus.None); + } + /// /// 车辆解锁 /// @@ -54,7 +92,7 @@ public class CarCtrlState : IState () => machine.VelUnlockFlag, () => { Task result = TBoxApi.UnLockCarManyTimes(machine.RfidReadModel.VelVin); - + bool unLock = result.Result; if (unLock) { @@ -69,10 +107,13 @@ public class CarCtrlState : IState _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.VelUnlockFlag, machine); } + } }, () => { - // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrUnLockCar.GetLed()); + //z轴上升 + PlcApi.ZPushUp(); + // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrUnLockCar.GetLed()); SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrUnLockCar); }, false, () => { machine.ExceptionReason = ExceptionReason.UnLockCarError; } , 10, InvokeStatus.None); @@ -99,8 +140,7 @@ public class CarCtrlState : IState // } }, () => { - // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrDistributeSelectPack.GetLed()); - + // 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 4ce1ec5..92b531b 100644 --- a/Service/Execute/Step/CarPrepareState.cs +++ b/Service/Execute/Step/CarPrepareState.cs @@ -89,13 +89,33 @@ public class CarPrepareState : IState return SwappingStateMachine.ReturnWithInvokeErr(selectPack, ExceptionReason.None); } - + //车辆到位 InvokeStatus carInPosition = CarInPosition(machine); if (carInPosition != InvokeStatus.Done) { return SwappingStateMachine.ReturnWithInvokeErr(carInPosition, ExceptionReason.None); } + //读取车辆在拍照位置 + InvokeStatus plcPhotoReady = CarInPhotoPosition(machine); + if (plcPhotoReady != InvokeStatus.Done) + { + return SwappingStateMachine.ReturnWithInvokeErr(plcPhotoReady, ExceptionReason.None); + } + //拍照 + InvokeStatus takePhoto = TakePhoto(machine); + if (takePhoto != InvokeStatus.Done) + { + return SwappingStateMachine.ReturnWithInvokeErr(takePhoto, ExceptionReason.None); + } + + //查看通道状态 + StateResult checkChannelStatus = CheckChannelStatus(machine); + if (checkChannelStatus != null) + { + return checkChannelStatus; + } + return new StateResult() { @@ -103,6 +123,110 @@ public class CarPrepareState : IState }; } + /// + /// 查看通道状态 + /// :0:无效值 + /// 1000;拍照OK + ///1010;拍照NG + ///1020;拍照超限,请移车 + /// + /// + 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分钟 + if (PlcApi.PlcCarInit()) + { + // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrChannelStatus.GetLed()); + SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrChannelStatus); + //等待2分钟 + Thread.Sleep(3 * 60 * 1000); + machine.SwapStatus = (int)InfoEnum.SwapOrderResult.Fail; + machine.SwapFailReason = "拍照故障 plc故障码1020"; + //回归到本阶段的读锁止状态 + return new StateResult() + { + SwappingState = SwappingState.SwapDone + }; + } + } + else if (channelStatus == 1010) + { + //故障 不能继续换电,提示驶离,上报云平台,修改换电订单 + machine.SwapStatus = (int)InfoEnum.SwapOrderResult.Fail; + machine.SwapFailReason = "拍照故障 plc故障码1010"; + //跳转到SwappDone + return new StateResult() + { + SwappingState = SwappingState.SwapDone + }; + } + } + + return null; + } + + /// + /// 拍照准备 + /// + public InvokeStatus CarInPhotoPosition(SwappingStateMachine machine) + { + return Invoker.Invoke("Car In Photo Position", 500, 10, machine.IsCanceled, + () => machine.CarInPhotoPositionFlag, () => + { + machine.CarInPhotoPositionFlag = PlcApi.CarInPhotoPosition(); + }, () => + { + machine.ExceptionReason = ExceptionReason.CarInPhotoPositionError; + // SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorTBoxConn); + }, false, () => + { + machine.ExceptionReason = ExceptionReason.CarInPhotoPositionError; + } + , 20, InvokeStatus.None); + } + + /// + /// 启动拍照 + /// + public InvokeStatus TakePhoto(SwappingStateMachine machine) + { + bool takePhotoFlag = false; + return Invoker.Invoke("Take Photo", 500, 10, machine.IsCanceled, + () => takePhotoFlag, () => + { + takePhotoFlag = PlcApi.TakPhoto(); + }); + } + + /// /// 车辆到位 @@ -123,7 +247,7 @@ public class CarPrepareState : IState TboxCarInfoModel tboxCarInfoModel = result.Result; var status = tboxCarInfoModel?.CarStatus; - + PlcApi.ReadyPlcPhoto(); if (StaticStationInfo.TboxStateFlameout) { if (status?.Keys == 0) @@ -151,6 +275,7 @@ public class CarPrepareState : IState if (succCount == successCount) { + machine.VehiclesInPlaceFlag = true; //写入口等 :红灯 if (PlcApi.WriteEntranceLamp(1020)) diff --git a/Service/Execute/Step/DoSwappingState.cs b/Service/Execute/Step/DoSwappingState.cs index 299c2b8..1ea8b25 100644 --- a/Service/Execute/Step/DoSwappingState.cs +++ b/Service/Execute/Step/DoSwappingState.cs @@ -30,21 +30,6 @@ public class DoSwappingState : IState // 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) { @@ -52,13 +37,6 @@ public class DoSwappingState : IState } - //查看通道状态 - StateResult checkChannelStatus = CheckChannelStatus(machine); - if (checkChannelStatus != null) - { - return checkChannelStatus; - } - //旧电池拆卸 InvokeStatus unPack = UnPack(machine); if (unPack != InvokeStatus.Done) @@ -166,15 +144,14 @@ public class DoSwappingState : IState () => machine.PlcHoldFlag, () => { //查询换电任务状态 - var taskPrepare = PlcApi.ReadTaskStatus(1); - if (taskPrepare) + + bool holdOn = PlcApi.HoldOn(1); + if (holdOn) { - bool holdOn = PlcApi.HoldOn(1); - if (holdOn) - { - SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.StartSwapInfo); - machine.PlcHoldFlag = true; - } + _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.StartSwappingFlag, + machine); + SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.StartSwapInfo); + machine.PlcHoldFlag = true; } }, () => { }); } @@ -262,7 +239,8 @@ public class DoSwappingState : IState _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.OutNewBatteryFlag, machine); } - }, () => { SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoNewBatteryCarryOut); }, false, () => { }, 10, + }, () => { SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoNewBatteryCarryOut); }, false, () => { }, + 10, InvokeStatus.None); } @@ -337,78 +315,6 @@ public class DoSwappingState : IState } - /// - /// 查看通道状态 - /// :0:无效值 - /// 1000;拍照OK - ///1010;拍照NG - ///1020;拍照超限,请移车 - /// - /// - 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; - } - - /// /// 车辆到位 /// @@ -424,7 +330,8 @@ public class DoSwappingState : IState int succCount = 0; List succL = new List() { - StaticStationInfo.TboxStateFlameout, StaticStationInfo.TboxStateBreak, StaticStationInfo.TboxStateN + StaticStationInfo.TboxStateFlameout, StaticStationInfo.TboxStateBreak, + StaticStationInfo.TboxStateN }; var successCount = succL.Where(i => i).Count(); @@ -466,4 +373,4 @@ public class DoSwappingState : IState }, false, () => { } , 20, InvokeStatus.None); } -} +} \ No newline at end of file diff --git a/Service/Execute/Step/StationReadyState.cs b/Service/Execute/Step/StationReadyState.cs index d974162..2c4192e 100644 --- a/Service/Execute/Step/StationReadyState.cs +++ b/Service/Execute/Step/StationReadyState.cs @@ -63,7 +63,8 @@ public class StationReadyState : IState { return SwappingStateMachine.ReturnWithInvokeErr(entranceRadar, ExceptionReason.None); } - + + //开始读rifd var beginRfid = BeginRead(machine); diff --git a/Service/Execute/SwapException/ExceptionReason.cs b/Service/Execute/SwapException/ExceptionReason.cs index 2da6f1d..d0a567a 100644 --- a/Service/Execute/SwapException/ExceptionReason.cs +++ b/Service/Execute/SwapException/ExceptionReason.cs @@ -21,5 +21,6 @@ namespace Service.Execute.SwapException; LockCarError, LvPwrOffError, SelfCheckError, - TimeOutError + TimeOutError, + CarInPhotoPositionError, } diff --git a/Service/Execute/SwappingStateMachine.cs b/Service/Execute/SwappingStateMachine.cs index cac3323..d65e44f 100644 --- a/Service/Execute/SwappingStateMachine.cs +++ b/Service/Execute/SwappingStateMachine.cs @@ -89,6 +89,7 @@ public class SwappingStateMachine : IDisposable ["13"] = new StepModel { StepNo = 13, Status = 0, StepName = "换电完成(车辆驶离)" }, ["14"] = new StepModel { StepNo = 14, Status = 0, StepName = "换电失败(车辆驶离)" }, }; + #region 小步状态 //雷达检测/车辆进入 @@ -106,6 +107,8 @@ public class SwappingStateMachine : IDisposable //Tbox连接 public bool BoxConnectFlag = false; + public bool CarInPhotoPositionFlag = false; + //车辆lock public bool BoxLocalCheckFlag = false; @@ -343,7 +346,7 @@ public class SwappingStateMachine : IDisposable SwapOrderBatteryInfo = null; StepSort = 0; - + foreach (var key in StepModel.Keys.ToList()) { StepModel[key].Status = 0; @@ -374,7 +377,7 @@ public class SwappingStateMachine : IDisposable BoxConnectFlag = false; - + CarInPhotoPositionFlag = false; BoxLocalCheckFlag = false; @@ -441,7 +444,8 @@ public class SwappingStateMachine : IDisposable { if (SwapOrderBatteryInfo?.UpBinInfo != null) ; { - BinInfoRepository.Update(i=>i.AmtLock==(int)InfoEnum.AmtBatLockStatus.UnLock,i=>i.Id==SwapOrderBatteryInfo.UpBinInfo.Id); + BinInfoRepository.Update(i => i.AmtLock == (int)InfoEnum.AmtBatLockStatus.UnLock, + i => i.Id == SwapOrderBatteryInfo.UpBinInfo.Id); } } @@ -482,4 +486,4 @@ public enum SwappingState Exception, Canceled, ManualSucc, -} +} \ No newline at end of file diff --git a/Service/Plc/Client/PlcMgr.cs b/Service/Plc/Client/PlcMgr.cs index f06bd1f..01bda4f 100644 --- a/Service/Plc/Client/PlcMgr.cs +++ b/Service/Plc/Client/PlcMgr.cs @@ -17,11 +17,10 @@ public class PlcMgr public - - /// - /// 数据有效时间。单位秒 - /// - static int DataTimeSeconds = 20; + /// + /// 数据有效时间。单位秒 + /// + static int DataTimeSeconds = 20; /// /// 数据刷新时间 @@ -56,6 +55,49 @@ public class PlcMgr return false; } + /// + /// 拍照准备 + /// + /// + public static bool PhotoPreparation() + { + if (PlcClient != null) + { + HostToPlcData.PhotoPreparation.Value = 1000; + return PlcClient.WriteValue(HostToPlcData.PhotoPreparation); + } + + return false; + } + + /// + /// 车辆在拍照位 + /// + /// + public static bool TakePhoto() + { + if (PlcClient != null) + { + HostToPlcData.StartPhoto.Value = 1000; + return PlcClient.WriteValue(HostToPlcData.StartPhoto); + } + + return false; + } + + /// + /// 拍照 + /// + /// + public static bool CarInPhotoPosition() + { + if (PlcClient != null) + { + return PlcToHostData.CarInPhotoPosition.Value == 1000; + } + + return false; + } public static bool AirBlowerControl(ushort value) { @@ -195,10 +237,11 @@ public class PlcMgr { case 1: if (PlcToHostData.StatusPowerChangeProcess.Value != 0 && - PlcToHostData.StatusPowerChangeProcess.Value!=1000) + PlcToHostData.StatusPowerChangeProcess.Value != 1000) { return true; } + return false; case 2: return PlcToHostData.MovingCondition.Value == 1001; @@ -212,6 +255,11 @@ public class PlcMgr return false; } + public static bool ReadSwapReady() + { + return PlcToHostData.WhetherAllowPowerChange.Value == 1010; + } + /// /// plc上使能 1换电,2移仓,3消防 /// @@ -278,6 +326,22 @@ public class PlcMgr return 0; } + + /// + /// 行车回归安全位置 + /// + /// + public static bool PlcCarInit() + { + if (PlcClient != null) + { + HostToPlcData.Regression.Value = 1000; + return PlcClient.WriteValue(HostToPlcData.Regression); + } + + return false; + } + /// /// 重新读 /// @@ -327,7 +391,7 @@ public class PlcMgr return (-1); } - + /// /// 灯光控制:全部打开 /// @@ -345,6 +409,17 @@ public class PlcMgr return bResult; } + public static bool ZPushUp() + { + if (PlcClient != null) + { + HostToPlcData.BatteryUnlockedState.Value = 1000; + return PlcClient.WriteValue(HostToPlcData.BatteryUnlockedState); + } + + return false; + } + /// /// 获取当前灯光状态 /// @@ -375,6 +450,4 @@ public class PlcMgr return bResult; } - - -} +} \ No newline at end of file diff --git a/Service/Plc/Msg/PlcToHost.cs b/Service/Plc/Msg/PlcToHost.cs index 07d082f..339a277 100644 --- a/Service/Plc/Msg/PlcToHost.cs +++ b/Service/Plc/Msg/PlcToHost.cs @@ -106,6 +106,14 @@ namespace Service.Plc.Msg /// 1000:已拍按钮 /// public ModbusProperty PhysicalButtonState { get; set; } = new(40112); + + + /// + /// 在拍照位 + /// 0:无状态 + /// 1000:已拍按钮 + /// + public ModbusProperty CarInPhotoPosition { get; set; } = new(40113); /// /// 三色灯控制通道状态(入口) /// 0:无颜色