using System.Collections.Concurrent; using System.ComponentModel; using Autofac; using AutoMapper; using Common.Util; using Entity.Api.Resp; using Entity.Constant; using Entity.DbModel.Station; using Entity.Dto; using Entity.Dto.Req; using HybirdFrameworkCore.Autofac; using HybirdFrameworkCore.Autofac.Attribute; using HybirdFrameworkCore.Entity; using log4net; using Newtonsoft.Json; using OfficeOpenXml.FormulaParsing.Excel.Functions.Math; using Repository.Station; using Service.Charger.Client; using Service.Charger.Msg.Host.Req; using Service.Charger.Server; using Service.Execute; using Service.Execute.Api; using Service.Execute.Model; using Service.Execute.Utils; using Service.Init; using Service.Mgr; using Service.Padar.Client; using SqlSugar; namespace Service.Station; [Scope("SingleInstance")] public class MonitorService { private static readonly ILog Log = LogManager.GetLogger(typeof(MonitorService)); public BinInfoRepository BinInfoRepository { get; set; } public SwapOrderRepository SwapOrderRepository { get; set; } public ChargeOrderRepository ChargeOrderRepository { get; set; } public PlcTaskMgr PlcTaskMgr { get; set; } public MoveBinRecordRepository MoveBinRecordRepository { get; set; } public SwapOrderBatteryRepository _SwapOrderBatteryRepository { get; set; } public CommonMgr _CommonMgr { get; set; } //可选仓位 public List> CanSelectPackBin() { //出仓位 SelectPackDto selectPackDtoUpBin = BinInfoRepository.SelectPack(StaticStationInfo.SwapSoc, StaticStationInfo.SwapFinishChargeTime, ""); //入仓位 SelectPackDto selectPackInBin = BinInfoRepository.SelectPackInBin(); return new List>() { selectPackDtoUpBin.CanSwapBinInfo, selectPackInBin.CanSwapBinInfo }; } //手动选包 public Result SelectPackManual(int upBinId, int inBinId) { var upBin = BinInfoRepository.QueryById(upBinId); var inBin = BinInfoRepository.QueryById(inBinId); if (StationSoftMgr.SwappingStateMachine?.SwapOrderBatteryInfo == null) { StationSoftMgr.SwappingStateMachine!.SwapOrderBatteryInfo = new SwapOrderBatteryInfo(); } StationSoftMgr.SwappingStateMachine!.SwapOrderBatteryInfo.InBinInfo = inBin; StationSoftMgr.SwappingStateMachine!.SwapOrderBatteryInfo.UpBinInfo = upBin; return Result.Success(); } [DisplayName("获取移仓分页")] public async Task> Page(PageMoveBinRecordReq input) { RefAsync total = 0; var items = await MoveBinRecordRepository.QueryPageAsync( entity => true, !string.IsNullOrWhiteSpace(input.UpBatterySoc), u => u.UpBatterySoc.Equals(input.UpBatterySoc.Trim()), !string.IsNullOrWhiteSpace(input.UpBinNo), u => u.UpBinNo.Equals(input.UpBinNo.Trim()), !string.IsNullOrWhiteSpace(input.UpBatteryNo), u => u.UpBatteryNo.Equals(input.UpBatteryNo.Trim()), u => u.CreatedTime, OrderByType.Desc, input.PageNum, input.PageSize, total); return new PageResult() { PageNum = input.PageNum, PageSize = input.PageSize, ToTal = total, Rows = items, }; } public async Task Add(AddMoveBinRecordReq input) { string result = ""; MoveBinRecord moveBinRecord = await MoveBinRecordRepository.InsertAsync(input); return "新增id:" + moveBinRecord.Id; } public virtual async Task Update(UpdateMoveBinRecordReq Req) { return await MoveBinRecordRepository.UpdateAsync(Req); } public virtual async Task Delete(DeleteMoveBinRecordReq input) { var user = await MoveBinRecordRepository.QueryByClauseAsync(u => u.Id == input.Id); if (user == null) throw new ArgumentException($"不存在"); return await MoveBinRecordRepository.DeleteAsync(user); } public Result GetSwapMonitorData() { var configBinInfo = new MapperConfiguration(cfg => cfg.CreateMap().ReverseMap()); IMapper mapperBinInfo = configBinInfo.CreateMapper(); List stateInfoList = new List(); ConcurrentDictionary dictionary = StationSoftMgr.SwappingStateMachine.StepModel; stateInfoList = dictionary.Values .OrderBy(model => model.StepNo) .Select(model => mapperBinInfo.Map(model)) .ToList(); var tboxCarInfoModel = StationSoftMgr.SwappingStateMachine.BoxCarInfoModel; List binInfos = BinInfoRepository.QueryListByClause(i => i.Exists == 1 && i.Status == 1); var plcSwapModel = new PlcSwapModelResp(); if (ClientMgr.PlcClient != null) { plcSwapModel.ModelState = ClientMgr.PlcClient.Auto ? 1010 : 1000; plcSwapModel.ControlModel = ClientMgr.PlcClient.Remote ? 1010 : 1000; } SwapMonitorScreenResp monitorScreenResp = new SwapMonitorScreenResp(); monitorScreenResp.PlcSwapModel = plcSwapModel; monitorScreenResp.StateInfo = stateInfoList; monitorScreenResp.VehicleInfo = new SwapVehicleResp(); monitorScreenResp.VehicleInfo.OrderNo = StationSoftMgr.SwappingStateMachine.SwapOrder != null ? StationSoftMgr.SwappingStateMachine.SwapOrder.Sn : null; monitorScreenResp.VehicleInfo.VelMac = StationSoftMgr.SwappingStateMachine.RfidReadModel != null ? StationSoftMgr.SwappingStateMachine.RfidReadModel.VelMac : null; monitorScreenResp.VehicleInfo.LockStatus = tboxCarInfoModel != null ? tboxCarInfoModel.CarStatus?.LockStatus : null; monitorScreenResp.VehicleInfo.KeyStatus = tboxCarInfoModel != null ? tboxCarInfoModel.CarStatus?.Keys : null; monitorScreenResp.VehicleInfo.VelNo = StationSoftMgr.SwappingStateMachine.RfidReadModel != null ? StationSoftMgr.SwappingStateMachine.RfidReadModel.VelNo : null; monitorScreenResp.VehicleInfo.VelVin = StationSoftMgr.SwappingStateMachine.RfidReadModel != null ? StationSoftMgr.SwappingStateMachine.RfidReadModel.VelVin : null; monitorScreenResp.VehicleInfo.Break = StationSoftMgr.SwappingStateMachine.BoxCarInfoModel?.CarStatus?.Break; monitorScreenResp.VehicleInfo.Gear = StationSoftMgr.SwappingStateMachine.BoxCarInfoModel?.CarStatus?.Gear; monitorScreenResp.BatteryInfo = new(); monitorScreenResp.BatteryInfo.BatteryTotalCount = binInfos.Count; monitorScreenResp.BatteryInfo.UsingSwapBatteryCount = binInfos.Select(i => i.ChargeStatus == 2 && i.AmtLock == (int)InfoEnum.AmtBatLockStatus.UnLock && i.Soc > StaticStationInfo.SwapSoc && new TimeSpan(DateTime.Now.Ticks - i.LastChargeFinishTime.ToDateTime().Ticks) .TotalMinutes > StaticStationInfo.SwapFinishChargeTime).Count(); if (monitorScreenResp.VehicleInfo.OrderNo != null) { SwapOrderBattery queryByClauseAsync = _SwapOrderBatteryRepository.QueryByClause(u => u.SwapOrderSn == monitorScreenResp.VehicleInfo.OrderNo); if (queryByClauseAsync != null) { monitorScreenResp.VehicleInfo.DownBatteryBinNo = queryByClauseAsync.DownBatteryBinNo; monitorScreenResp.VehicleInfo.UpBatteryBinNo = queryByClauseAsync.UpBatteryBinNo; } SwapOrder swapOrder = SwapOrderRepository.QueryByClause(u => u.Sn == monitorScreenResp.VehicleInfo.OrderNo); if (swapOrder != null && swapOrder.SwapBeginTime.HasValue && swapOrder.SwapEndTime.HasValue) { TimeSpan duration = swapOrder.SwapEndTime.Value - swapOrder.SwapBeginTime.Value; monitorScreenResp.VehicleInfo.SwapDuration = duration.ToString(@"hh\:mm\:ss"); } else if (swapOrder != null && swapOrder.SwapBeginTime.HasValue) { TimeSpan duration = DateTime.Now - swapOrder.SwapBeginTime.Value; monitorScreenResp.VehicleInfo.SwapDuration = duration.ToString(@"hh\:mm\:ss"); } } monitorScreenResp.DeviceLogs = StationSoftMgr.DeviceLogs; monitorScreenResp.RadarResp = new() { CarStatus = PadarMgr._PadarClient?.CarState }; return Result.Success(monitorScreenResp); } /// /// 模式類 /// /// public Result GetModel() { SwapModelResp resp = new() { StationStatus = StaticStationInfo.StationStatus, StationWay = StaticStationInfo.StationWay, StationModel = StaticStationInfo.StationModel }; return Result.Success(resp); } /// /// 连接状态类 /// /// public Result GetDeviceState() { bool isConnected = StationSoftMgr.SwappingStateMachine.BoxCarInfoModel == null ? false : StationSoftMgr.SwappingStateMachine.BoxCarInfoModel.Connected; DeviceStateResp resp = new() { BoxConnectFlag = isConnected, // CloudConnectFlag = CloudClientMgr.CloudClient == null ? false : CloudClientMgr.CloudClient.Connected, PlcConnectFlag = ClientMgr.PlcClient != null && ClientMgr.PlcClient!.Connected, RfidConnectFlag = StationSoftMgr.SwappingStateMachine!.RfidConnectFlag, RadarConnectFlag = PadarMgr._PadarClient != null && PadarMgr._PadarClient!.Connected }; return Result.Success(resp); } //TODO:: 首页--当月,当日换电量 public Result SwapAndChargingCount() { SwapAndChargingCountResp chargingCountResp = new() { ChargeTodayCount = ChargeOrderRepository.GetCount(i => DateTime.Today <= i.EndTime && i.EndTime <= DateUtils.GetTomorrowFirst()), ChargeTotalCount = ChargeOrderRepository.GetCount(i => i.EndTime != null), SwapTodayCount = SwapOrderRepository.GetCount(i => i.SwapResult != 0 && DateTime.Today <= i.SwapEndTime && i.SwapEndTime <= DateUtils.GetTomorrowFirst()), SwapTotalCount = SwapOrderRepository.GetCount(i => i.SwapResult != 0), }; return Result.Success(chargingCountResp); } /// /// 电池移仓 /// /// /// /// public Result BatteryRelocation(ushort removeBinNo, ushort putBinNo, int type = 0) { MoveBinRecord moveBinRecord = null; try { //校验:出仓位 BinInfo? removeBin = BinInfoRepository.QueryByClause(i => i.No.Equals(removeBinNo) && (i.ChargeStatus != 1) && i.Exists == 1 && i.AmtLock == 0); if (removeBin == null) { return Result.Fail("出仓位状态有误"); } BinInfo? putBin = BinInfoRepository.QueryByClause(i => i.No.Equals(putBinNo) && i.Exists == 0 && i.AmtLock == 0 && i.Status == 1); if (putBin == null) { return Result.Fail("入仓位状态有误"); } //TODO::判断是否存在其他任务 /*if (PlcMgr.PlcClient?.ReadTaskNo() != 0) { Log.Info("当前存在其他任务"); return Result.Fail("当前存在其他任务"); }*/ moveBinRecord = new MoveBinRecord() { UpBinNo = removeBinNo.ToString(), UpBatteryNo = removeBin.BatteryNo, UpBatterySoc = removeBin.Soc.ToString(), InBatteryNo = putBin.BatteryNo, InBatterySoc = putBin.Soc.ToString(), InBinNo = putBinNo.ToString(), Status = 0, Type = type, CreatedTime = DateTime.Now }; moveBinRecord = MoveBinRecordRepository.Insert(moveBinRecord); //发送移仓任务 MoveCommandReq MoveCommandReq = new MoveCommandReq((byte)removeBinNo, (byte)putBinNo); PlcServer PlcServer = new PlcServer(); PlcServer.SendMoveCommandReq(MoveCommandReq); //TODO::判断任务是否执行 } catch (Exception e) { Log.Error($"move battery fail e={e.Message}"); if (moveBinRecord != null) { moveBinRecord.Status = 3; MoveBinRecordRepository.Update(moveBinRecord); } return Result.Fail(); } return Result.Success(); } public Result> GetChargeBinOption() { List queryListByClause = BinInfoRepository.Query(); var configBinInfo = new MapperConfiguration(cfg => cfg.CreateMap().ReverseMap()); IMapper mapperBinInfo = configBinInfo.CreateMapper(); return Result>.Success(mapperBinInfo.Map>(queryListByClause)); } }