using Autofac; using AutoMapper; using Entity.Attr; using Entity.Constant; using Entity.DbModel.Station; using Entity.Dto; using HybirdFrameworkCore.Autofac; using log4net; using Repository.Station; using Service.Cloud.Msg.Cloud.Resp; 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.Station; 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 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 cloudCheckVel = CloudCheckVel(machine); if (cloudCheckVel != InvokeStatus.Done) { return SwappingStateMachine.ReturnWithInvokeErr(cloudCheckVel, ExceptionReason.None); } //TBox连接 if (StaticStationInfo.TboxStateConnect) { InvokeStatus tboxConnect = TboxConnect(machine); if (tboxConnect != InvokeStatus.Done) { return SwappingStateMachine.ReturnWithInvokeErr(tboxConnect, 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); } //云端数据上报 // InvokeStatus cloudTBox = CloudTBoxFlag(machine); /*if (cloudTBox != InvokeStatus.Done) { return SwappingStateMachine.ReturnWithInvokeErr(cloudTBox, ExceptionReason.None); }*/ machine.ExceptionReason = ExceptionReason.None; //选包 InvokeStatus selectPack = SelectPack(machine); if (selectPack != InvokeStatus.Done) { return SwappingStateMachine.ReturnWithInvokeErr(selectPack, ExceptionReason.None); } //车辆到位 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, 5, 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.TboxStateBreak) { if (status?.Break == 1) { succCount++; } } if (StaticStationInfo.TboxStateN) { if (status?.Gear == 0) { succCount++; } } if (succCount == successCount) { machine.VehiclesInPlaceFlag = true; //写入口等 :红灯 if (PlcApi.WriteEntranceLamp(1020)) { // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.InfoCarInPosition.GetLed()); SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.InfoCarInPosition); machine.VehiclesInPlaceFlag = true; //告知云平台换电准备完成 machine.BusinessSwappingForCloudState = InfoEnum.BusinessSwappingForCloudState.SwapReady; machine.ExceptionReason = ExceptionReason.None; // CloudApi.SendStateLog(machine.SwapOrder, machine.BusinessSwappingForCloudState); //清除下发的指令,等待新的指令 // CloudApi.ClearCarCanStartInfo(); _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.CarInPositionFlag, machine); machine.BoxCarInfoModel = tboxCarInfoModel; } } }, () => { machine.ExceptionReason = ExceptionReason.CarInPositionError; // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorCarInPositionTimeout.GetLed()); SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorCarInPositionTimeout); }, false, () => { } , 10, InvokeStatus.None); } /// /// 云平台车辆认证 /// /// public InvokeStatus CloudCheckVel(SwappingStateMachine machine) { return Invoker.Invoke("cloud check vehicle", 500, 20, machine.IsCanceled, () => machine.CloudVelCheckFlag, () => { if (StationConstant.StationModel.Remote == BaseEnumExtensions.GetEnumByCode( StaticStationInfo.StationModel)) { VehicleCertificationResp? vehicleCertificationResp = CloudApi.VehicleCheck(machine.RfidReadModel, machine.SwapOrder); if (vehicleCertificationResp == null || vehicleCertificationResp.re != 0) { _log.Info("cloud check vehicle error"); // machine.LedTool?.WriteProgramContent("换电准备中:云平台车辆验证完成"); } else { machine.ExceptionReason = ExceptionReason.None; _log.Info("cloud check vehicle done"); machine.CloudVelCheckFlag = true; // machine.LedTool?.WriteProgramContent("换电准备中:云平台车辆验证完成"); machine.SwapOrder.CloudSn = vehicleCertificationResp.on; _CommonMgr.InsertStep(InfoEnum.BusinessSwappingStep.CloudVelCheckFlag, machine); } } else { machine.CloudVelCheckFlag = true; } }, () => { // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorCloudCheck.GetLed()); SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorCloudCheck); }, false, () => { machine.ExceptionReason = ExceptionReason.CloudCheckError; } , 20, InvokeStatus.None); } /// /// 检查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; } }, () => { machine.ExceptionReason = ExceptionReason.ConnTBoxError; SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorTBoxConn); }, false, () => { machine.ExceptionReason = ExceptionReason.ConnTBoxError; // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorTBoxConn.GetLed()); } , 20, 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; } } } }, () => { machine.ExceptionReason = ExceptionReason.ConnTBoxError; SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorTBoxConn); }, false, () => { machine.ExceptionReason = ExceptionReason.ConnTBoxError; // machine.LedTool?.WriteProgramContent(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; } , 3, 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); }, false, () => { machine.ExceptionReason = ExceptionReason.CloudCarDataUploadError; } , 20, InvokeStatus.None); } /// /// 选包: /// 有预约单: 获取预约单的电池 /// 无预约单: /// 1.仓位状态:启动 /// 2.电池在位 /// 3.充电状态:不在充电中 /// 4.未锁定 /// 5.最后一次结束充电时间> () /// 6.soc >() /// /// public InvokeStatus SelectPack(SwappingStateMachine machine) { 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) { // machine.LedTool?.WriteProgramContent(InfoEnum.SwapInfo.ErrorSelectPack.GetLed()); _log.Info($"SelectPack error CanSwap={machine.SwapOrderBatteryInfo.CanSwap}"); } else { //选包成功 _CommonMgr.LockBinAndUpdateAmt(orderBatteryInfo); machine.SwapOrderBatteryInfo = orderBatteryInfo; _CommonMgr.SaveSwapBattery(machine); machine.SelectPackFlag = true; } }, () => { machine.ExceptionReason = ExceptionReason.SelectPackError; SoundApi.PlayOneSound((int)InfoEnum.SwapInfo.ErrorSelectPack); } , false, () => { }, 10, InvokeStatus.None); } }