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.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.Cloud.Client; using Service.Execute; using Service.Execute.Api; using Service.Execute.Model; using Service.Execute.Utils; using Service.Init; using Service.Mgr; using Service.Plc.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; } [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); SwapMonitorScreenResp monitorScreenResp = new() { PlcSwapModel = new PlcSwapModelResp() { ModelState = PlcMgr.PlcToHostData.ModeControl.Value, StationInLampSts = PlcMgr.PlcToHostData.LightIn.Value, ControlModel = PlcMgr.PlcToHostData.RemoteLocalControlState.Value, }, StateInfo = stateInfoList, VehicleInfo = new SwapVehicleResp() { OrderNo = StationSoftMgr.SwappingStateMachine.SwapOrder != null ? StationSoftMgr.SwappingStateMachine.SwapOrder.Sn : null, VelMac = StationSoftMgr.SwappingStateMachine.RfidReadModel != null ? StationSoftMgr.SwappingStateMachine.RfidReadModel.VelMac : null, LockStatus = tboxCarInfoModel != null ? tboxCarInfoModel.HeartBeatMsg.LockStatus : null, KeyStatus = tboxCarInfoModel != null ? tboxCarInfoModel.HeartBeatMsg.KeyStatus : null, VelNo = StationSoftMgr.SwappingStateMachine.RfidReadModel != null ? StationSoftMgr.SwappingStateMachine.RfidReadModel.VelNo : null, VelVin = StationSoftMgr.SwappingStateMachine.RfidReadModel != null ? StationSoftMgr.SwappingStateMachine.RfidReadModel.VelVin : null, //Break = StationSoftMgr.SwappingStateMachine.BoxCarInfoModel?.HeartBeatMsg?.handbrake, //Gear = StationSoftMgr.SwappingStateMachine.BoxCarInfoModel?.HeartBeatMsg?.EarPosition, }, BatteryInfo = new() { BatteryTotalCount = binInfos.Count, 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() } }; return Result.Success(monitorScreenResp); } /// /// 模式類 /// /// public Result GetModel() { SwapModelResp resp = new() { StationStatus = StaticStationInfo.StationStatus, StationWay = StaticStationInfo.StationWay, StationModel = StaticStationInfo.StationModel, SwapInitiateMode = StaticStationInfo.SwapInitiateMode, }; 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 = PlcMgr.PlcClient == null ? false : PlcMgr.PlcClient.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("入仓位状态有误"); } bool ipsilateral = false; if ((removeBinNo <=8 && putBinNo <= 8)||( removeBinNo > 8 && putBinNo > 8)) { ipsilateral = true; } if (!ipsilateral) { return Result.Fail("出仓位和入仓位不在同侧"); } if (PlcMgr.PlcClient?.ReadTaskNo() != 0) { Log.Info("当前存在其他任务"); return Result.Fail("当前存在其他任务"); } PlcMgr.PlcClient?.ExChangeTaskNo(6); //var result = PlcMgr.DistributeTask(putBinNo, removeBinNo, 2); var result = PlcMgr.StartSwapping(putBinNo, removeBinNo, 6); if (!result) { PlcMgr.PlcClient?.ExChangeTaskNo(0); return Result.Fail(); } int count = 3; while (count > 0) { result = PlcMgr.ReadTaskStatus(6); if (result) { break; } count--; Thread.Sleep(1000); } if (!result) { PlcMgr.PlcClient?.ExChangeTaskNo(0); Log.Error("BatteryRelocation PlcMgr.ReadTaskStatus(6) =false"); 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); result = PlcMgr.HoldOn(); if (!result) { moveBinRecord.Status = 3; MoveBinRecordRepository.Update(moveBinRecord); PlcMgr.PlcClient?.ExChangeTaskNo(0); Log.Error("BatteryRelocation PlcMgr.HoldOn() =false"); return Result.Fail(); } Log.Info($"battery move task Manual removeBinNo={removeBinNo}, putBinNo={putBinNo} type={type} "); moveBinRecord.Status = 1; MoveBinRecordRepository.Update(moveBinRecord); var queryPlcTask = PlcTaskMgr.QueryPlcTask(6, 1200, 1201); if (!queryPlcTask) { PlcMgr.PlcClient?.ExChangeTaskNo(0); Log.Info($"move battery fail update moveBin={JsonConvert.SerializeObject(moveBinRecord)}"); moveBinRecord.Status = 3; MoveBinRecordRepository.Update(moveBinRecord); return Result.Fail(); } Log.Info($"move battery success update moveBin={JsonConvert.SerializeObject(moveBinRecord)}"); //如果是缓存仓 更新缓存仓的数据 if (putBin.CacheBinFlag == 1) { putBin.Exists = 1; putBin.BatteryNo = removeBin.BatteryNo; putBin.Soc = removeBin.Soc; putBin.Soe = removeBin.Soe; putBin.Soh = removeBin.Soh; putBin.BatteryEnterSeq = removeBin.BatteryEnterSeq; putBin.InTime = removeBin.InTime; BinInfoRepository.Update(putBin); } removeBin.Exists = 0; removeBin.BatteryNo = "-1"; removeBin.Soc = -1; removeBin.Soe = -1; removeBin.Soh = -1; removeBin.BatteryEnterSeq = 0; BinInfoRepository.Update(removeBin); moveBinRecord.Status = 2; Log.Info($"move battery success update moveBin={JsonConvert.SerializeObject(moveBinRecord)}"); MoveBinRecordRepository.Update(moveBinRecord); PlcMgr.PlcClient?.ExChangeTaskNo(0); } catch (Exception e) { Log.Error($"move battery fail e={e.Message}"); if (moveBinRecord != null) { moveBinRecord.Status = 3; MoveBinRecordRepository.Update(moveBinRecord); } PlcMgr.PlcClient?.ResetTaskNo(); 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)); } }