using Autofac; using Entity.Attr; using Entity.Constant; using Entity.DbModel.Station; using HybirdFrameworkCore.Autofac; using log4net; using Newtonsoft.Json; using Repository.Station; using Service.Execute.Api; using Service.Execute.Model; using Service.Execute.Model.Tbox; using Service.Execute.SwapException; using Service.Execute.Utils; using Service.Init; using Service.Led; using Service.Padar.Client; using Service.RealTime; using Service.Sound.SoundClient; using Service.Station; using System.Runtime.CompilerServices; using Newtonsoft.Json; namespace Service.Execute.Step; public class CarPrepareState : IState { private readonly ILog _log = LogManager.GetLogger(typeof(CarPrepareState)); private readonly CommonMgr _CommonMgr = AppInfo.Container.Resolve(); private readonly SwapOrderBatteryRepository _swapOrderBatteryRepository = AppInfo.Container.Resolve(); public static SoundClient? SoundClient { get; set; } public StateResult Handle(SwappingStateMachine machine) { Thread.Sleep(500); RfidReadModel? rfidReadModel = machine.RfidReadModel; if (rfidReadModel == null) { _log.Error("rfid is null"); return new StateResult() { SwappingState = SwappingState.StationReady }; } ////调整车辆 var adjustCarByRadar = AdjustCarByRadar(machine); if (InvokeStatus.Done != adjustCarByRadar) { return SwappingStateMachine.ReturnWithInvokeErr(adjustCarByRadar, ExceptionReason.None); } //检查tbox链接状态 InvokeStatus checkTBoxConnect = CheckTBoxConnectFlag(machine); if (checkTBoxConnect != InvokeStatus.Done) { return SwappingStateMachine.ReturnWithInvokeErr(checkTBoxConnect, ExceptionReason.None); } //车辆本地验证 InvokeStatus checkTBoxVelLocal = CheckTBoxVelLocalFlag(machine); if (checkTBoxVelLocal != InvokeStatus.Done) { return SwappingStateMachine.ReturnWithInvokeErr(checkTBoxVelLocal, ExceptionReason.None); } machine.ExceptionReason = ExceptionReason.None; //选包 InvokeStatus selectPack = SelectPack(machine); if (selectPack != InvokeStatus.Done) { return SwappingStateMachine.ReturnWithInvokeErr(selectPack, ExceptionReason.None); } //在充电的包停止充电 InvokeStatus stopChargingForUpBin = StopChargingForUpBin(machine); if (stopChargingForUpBin != InvokeStatus.Done) { return SwappingStateMachine.ReturnWithInvokeErr(selectPack, ExceptionReason.StopChargingError); } _CommonMgr.SaveSwapBattery(machine); //车辆到位 InvokeStatus carInPosition = CarInPosition(machine); if (carInPosition != InvokeStatus.Done) { return SwappingStateMachine.ReturnWithInvokeErr(carInPosition, ExceptionReason.None); } return new StateResult() { SwappingState = SwappingState.CarCtrl }; } /// /// 车辆到位 /// /// public InvokeStatus CarInPosition(SwappingStateMachine machine) { return Invoker.Invoke("check CarInPosition", 500, 10, machine.IsCanceled, () => machine.VehiclesInPlaceFlag, () => { var result = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin); int succCount = 0; List succL = new List() { StaticStationInfo.TboxStateFlameout, StaticStationInfo.TboxStateBreak, StaticStationInfo.TboxStateN }; var successCount = succL.Where(i => i).Count(); TboxCarInfoModel tboxCarInfoModel = result.Result; var status = tboxCarInfoModel?.CarStatus; if (StaticStationInfo.TboxStateFlameout) { if (status?.Keys == 0) { succCount++; } } if (StaticStationInfo.TboxStateN) { if (status?.Gear == 0) { succCount++; } } if (succCount == successCount) { machine.VehiclesInPlaceFlag = true; _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.CarInPositionFlag, machine,param:JsonConvert.SerializeObject(tboxCarInfoModel)); } }, () => { SoundClient = AppInfo.Container.Resolve(); //SoundClient.SoundPlay(AppSettingsHelper.GetContent("SoundAddr", "Address06")); //TODO::播报请熄火挂N挡拉手刹 // SoundClient.SoundPlay(SoundEnum.music06); machine.ExceptionReason = ExceptionReason.CarInPositionError; // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorCarInPositionTimeout.GetLed()); //SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorCarInPositionTimeout); }, false, () => { } , 20, InvokeStatus.None); } public InvokeStatus AdjustCarByRadar(SwappingStateMachine machine) { int che = 0; return Invoker.Invoke("begin Radar", 1000, 20, machine.IsCanceled, () => { LedClient.SendMsgByKey(InfoEnum.SwapInfo.InfoCarInPosition.GetLed()); if (PadarMgr._PadarClient?.CarState == 6 || machine.ManualSkipRadar) { LedClient.SendMsgByKey(InfoEnum.SwapInfo.diparkir.GetLed()); _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.Carradar, machine,type: machine.ManualSkipRadar? (int)SwapConstant.StepType.MANUAL :(int)SwapConstant.StepType.AUTO); } return PadarMgr._PadarClient?.CarState == 6 || machine.ManualSkipRadar; }, () => { switch (PadarMgr._PadarClient?.CarState) { case 1: _log.Info("radar 无车"); break; case 2: _log.Info("radar 无电池"); break; case 3: _log.Info("radar 角度偏移过大"); if (che == 0) { LedClient.SendMsgByKey(InfoEnum.SwapInfo.upcar.GetLed()); SoundClient.SoundPlay(SoundEnum.music100); Thread.Sleep(3000); SoundClient.SoundPlay(SoundEnum.music101); che = 1; } break; case 4: _log.Info("radar 车辆靠后"); LedClient.SendMsgByKey(InfoEnum.SwapInfo.Muka.GetLed()); break; case 5: _log.Info("radar 车辆靠前"); LedClient.SendMsgByKey(InfoEnum.SwapInfo.Mundur.GetLed()); break; } }); } /// /// 检查tbox连接状态 /// public InvokeStatus CheckTBoxConnectFlag(SwappingStateMachine machine) { return Invoker.Invoke("check TBox connect", 1000, 10, machine.IsCanceled, () => machine.BoxConnectFlag, () => { Task result = TBoxApi.IsConnected(machine.RfidReadModel.VelVin); bool isConnect = result.Result; if (isConnect) { machine.BoxConnectFlag = true; } }, () => { SoundClient = AppInfo.Container.Resolve(); SoundClient.SoundPlay(SoundEnum.music102); Thread.Sleep(3000); SoundClient.SoundPlay(SoundEnum.music103); }, false, () => { _log.Error("CheckTBoxConnectFlag err"); } , 30, InvokeStatus.None); } /// /// 连接TBox /// public InvokeStatus TboxConnect(SwappingStateMachine machine) { return Invoker.Invoke("TBox connect", 1000, 10, machine.IsCanceled, () => machine.BoxConnectFlag, () => { Task result = TBoxApi.Connect(machine.RfidReadModel.VelVin); bool isConnect = result.Result; if (isConnect) { //读取车辆carNo=carVin Task carInfoResult = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin); var tboxCarInfoModel = carInfoResult.Result; var carInfo = tboxCarInfoModel?.CarInfo; if (carInfo != null) { if (carInfo.CarNo.Equals(carInfo.CarVin)) { machine.BoxConnectFlag = true; } } } }, () => { SoundClient = AppInfo.Container.Resolve(); //SoundClient.SoundPlay(AppSettingsHelper.GetContent("SoundAddr", "Address03")); //SoundClient.SoundPlay(SoundEnum.music43); //machine.ExceptionReason = ExceptionReason.ConnTBoxError; //SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorTBoxConn); }, false, () => { machine.ExceptionReason = ExceptionReason.ConnTBoxError; // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorTBoxConn.GetLed()); LedClient.SendMsgByKey(InfoEnum.SwapInfo.ErrorTBoxConn.GetLed()); } , 20, InvokeStatus.None); } /// /// 车辆本地验证:车牌校验 /// /// public InvokeStatus CheckTBoxVelLocalFlag(SwappingStateMachine machine) { return Invoker.Invoke("check TBox VelLocal", 1000, 20, machine.IsCanceled, () => machine.BoxLocalCheckFlag, () => { Task carInfo = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin); var tBoxCarInfoModel = carInfo.Result; if (tBoxCarInfoModel.CarNo!.Trim().Equals(machine.RfidReadModel!.VelVin.Trim())) { machine.BoxLocalCheckFlag = true; machine.BoxCarInfoModel = tBoxCarInfoModel; } }, () => { machine.ExceptionReason = ExceptionReason.LocalCheckVarError; }, true, () => { machine.ExceptionReason = ExceptionReason.LocalCheckVarError; SoundClient = AppInfo.Container.Resolve(); SoundClient.SoundPlay(SoundEnum.music108); Thread.Sleep(3000); SoundClient.SoundPlay(SoundEnum.music109); Thread.Sleep(3000); } , 30, InvokeStatus.TimeOut); } /// /// 蓝牙数据云平台上报 /// /// public InvokeStatus CloudTBoxFlag(SwappingStateMachine machine) { return Invoker.Invoke("cloud TBox upload", 500, 20, machine.IsCanceled, () => machine.CloudTBoxFlag, () => { Task result = TBoxApi.GetCarInfo(machine.RfidReadModel.VelVin); TboxCarInfoModel tBoxCarInfoModel = result.Result; machine.BoxCarInfoModel = tBoxCarInfoModel; if (tBoxCarInfoModel != null) { if (tBoxCarInfoModel.Connected) { //将数据上报云平台 // CloudApi.UploadTBoxCarInfo(machine.SwapOrder!, machine.BoxCarInfoModel); } } }, () => { // machine.LedTool?.WriteProgramContent("车辆电池数据上报异常,请联系站务人员"); // SoundApi.PlayOneSound(InfoEnum.SwapInfo.ErrorSelectPack); LedClient.SendMsgByKey(InfoEnum.SwapInfo.ErrorSelectPack.GetLed()); SoundClient = AppInfo.Container.Resolve(); //SoundClient.SoundPlay(AppSettingsHelper.GetContent("SoundAddr", "Address09")); SoundClient.SoundPlay(SoundEnum.music09); }, false, () => { machine.ExceptionReason = ExceptionReason.CloudCarDataUploadError; } , 20, InvokeStatus.None); } /// /// 选包: /// 有预约单: 获取预约单的电池 /// 无预约单: /// 1.仓位状态:启动 /// 2.电池在位 /// 3.充电状态:不在充电中 /// 4.未锁定 /// 5.最后一次结束充电时间> () /// 6.soc >() /// /// public InvokeStatus SelectPack(SwappingStateMachine machine) { int e = 0; SwapAmtOrder? swapAmtOrder = _CommonMgr.QueryAmtOrder(machine); return Invoker.Invoke("selectPack", 1000, 10, machine.IsCanceled, () => machine.SelectPackFlag, () => { SwapOrderBatteryInfo orderBatteryInfo = null; if (swapAmtOrder != null) { orderBatteryInfo = _CommonMgr.SelectPackArm(swapAmtOrder, machine); } else { orderBatteryInfo = _CommonMgr.SelectPackNotArm(machine); } if (orderBatteryInfo.CanSwap == InfoEnum.SelectBinStatusInfo.Success) { //选包成功 _CommonMgr.LockBinAndUpdateAmt(orderBatteryInfo); machine.SwapOrderBatteryInfo = orderBatteryInfo; bool isManual = StaticStationInfo.SelectPackManually == (int)SwapConstant.AutoOrManual.Manual; machine.SelectPackFlag = true; _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.SelectPackSuccess, machine,isManual?"手动选包":"自动选包",param: JsonConvert.SerializeObject(machine.SwapOrderBatteryInfo) ,type:isManual?(int)SwapConstant.StepType.MANUAL:(int)SwapConstant.StepType.AUTO); } }, () => { LedClient.SendMsgByKey(InfoEnum.SwapInfo.ErrorSelectPack.GetLed()); SoundClient = AppInfo.Container.Resolve(); SoundClient.SoundPlay(SoundEnum.music106); Thread.Sleep(3000); SoundClient.SoundPlay(SoundEnum.music107); machine.ExceptionReason = ExceptionReason.SelectPackError; } , false, () => { }, 20, InvokeStatus.None); } public InvokeStatus StopChargingForUpBin(SwappingStateMachine machine) { return Invoker.Invoke("select pack - stop charging", 1000, 60, machine.IsCanceled, () => machine.SelectPackStopChargingFlag, () => { if (machine is { SelectPackFlag: true, SwapOrderBatteryInfo.UpBinInfo.ChargeStatus: 1 }) { var binNo = machine.SwapOrderBatteryInfo?.UpBinInfo.No; BinInfo? binInfo = _CommonMgr._binInfoRepository.SelectByBinNo(binNo); if (binInfo is { ChargeStatus: 4 }) { machine.SwapOrderBatteryInfo.UpBinInfo = binInfo; machine.SelectPackStopChargingFlag = true; HubHolder.S2CMsg(JsonConvert.SerializeObject(new RtMsg { Cmd = "BeginStopChargingDone", Msg = $"{binNo}" })).Wait(); return; } //停止充电 HubHolder.S2CMsg(JsonConvert.SerializeObject(new RtMsg { Cmd = "BeginStopCharging", Msg = $"{binNo}" })).Wait(); Task stopCharge = ChargeApi.StopCharge(binNo); stopCharge.Wait(TimeSpan.FromSeconds(10)); } else { machine.SelectPackStopChargingFlag = true; } }); } }