You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

362 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<PageResult<MoveBinRecord>> Page(PageMoveBinRecordReq input)
{
RefAsync<int> 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<MoveBinRecord>()
{
PageNum = input.PageNum,
PageSize = input.PageSize,
ToTal = total,
Rows = items,
};
}
public async Task<string> Add(AddMoveBinRecordReq input)
{
string result = "";
MoveBinRecord moveBinRecord = await MoveBinRecordRepository.InsertAsync(input);
return "新增id" + moveBinRecord.Id;
}
public virtual async Task<bool> Update(UpdateMoveBinRecordReq Req)
{
return await MoveBinRecordRepository.UpdateAsync(Req);
}
public virtual async Task<bool> 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<SwapMonitorScreenResp> GetSwapMonitorData()
{
var configBinInfo =
new MapperConfiguration(cfg => cfg.CreateMap<StepModel, SwappingStateInfoResp>().ReverseMap());
IMapper mapperBinInfo = configBinInfo.CreateMapper();
List<SwappingStateInfoResp> stateInfoList = new List<SwappingStateInfoResp>();
ConcurrentDictionary<string, StepModel> dictionary = StationSoftMgr.SwappingStateMachine.StepModel;
stateInfoList = dictionary.Values
.OrderBy(model => model.StepNo)
.Select(model => mapperBinInfo.Map<SwappingStateInfoResp>(model))
.ToList();
var tboxCarInfoModel = StationSoftMgr.SwappingStateMachine.BoxCarInfoModel;
List<BinInfo> 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.CarStatus.LockStatus : null,
KeyStatus = tboxCarInfoModel != null ? tboxCarInfoModel.CarStatus.Keys : 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?.CarStatus?.Break,
Gear = StationSoftMgr.SwappingStateMachine.BoxCarInfoModel?.CarStatus?.Gear,
},
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<SwapMonitorScreenResp>.Success(monitorScreenResp);
}
/// <summary>
/// 模式類
/// </summary>
/// <returns></returns>
public Result<SwapModelResp> GetModel()
{
SwapModelResp resp = new()
{
StationStatus = StaticStationInfo.StationStatus,
StationWay = StaticStationInfo.StationWay,
StationModel = StaticStationInfo.StationModel
};
return Result<SwapModelResp>.Success(resp);
}
/// <summary>
/// 连接状态类
/// </summary>
/// <returns></returns>
public Result<DeviceStateResp> 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<DeviceStateResp>.Success(resp);
}
//TODO:: 首页--当月,当日换电量
public Result<SwapAndChargingCountResp> 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<SwapAndChargingCountResp>.Success(chargingCountResp);
}
/// <summary>
/// 电池移仓
/// </summary>
/// <param name="removeBinNo"></param>
/// <param name="putBinNo"></param>
/// <returns></returns>
public Result<bool> 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<bool>.Fail("出仓位状态有误");
}
BinInfo? putBin = BinInfoRepository.QueryByClause(i =>
i.No.Equals(putBinNo) && i.Exists == 0 && i.AmtLock == 0 &&
i.Status == 1);
if (putBin == null)
{
return Result<bool>.Fail("入仓位状态有误");
}
if (PlcMgr.PlcClient?.ReadTaskNo() != 0)
{
Log.Info("当前存在其他任务");
return Result<bool>.Fail("当前存在其他任务");
}
PlcMgr.PlcClient?.ExChangeTaskNo(2);
var result = PlcMgr.DistributeTask(putBinNo, removeBinNo, 2);
if (!result)
{
PlcMgr.PlcClient?.ExChangeTaskNo(0);
return Result<bool>.Fail();
}
int count = 3;
while (count > 0)
{
result = PlcMgr.ReadTaskStatus(2);
if (result)
{
break;
}
count--;
Thread.Sleep(1000);
}
if (!result)
{
PlcMgr.PlcClient?.ExChangeTaskNo(0);
Log.Error("BatteryRelocation PlcMgr.ReadTaskStatus(2) =false");
return Result<bool>.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<bool>.Fail();
}
Log.Info($"battery move task Manual removeBinNo={removeBinNo}, putBinNo={putBinNo} type={type} ");
moveBinRecord.Status = 1;
MoveBinRecordRepository.Update(moveBinRecord);
var queryPlcTask = PlcTaskMgr.QueryPlcTask(2, 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<bool>.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<bool>.Fail();
}
return Result<bool>.Success();
}
public Result<List<BinInfoResp>> GetChargeBinOption()
{
List<BinInfo> queryListByClause = BinInfoRepository.Query();
var configBinInfo =
new MapperConfiguration(cfg => cfg.CreateMap<BinInfo, BinInfoResp>().ReverseMap());
IMapper mapperBinInfo = configBinInfo.CreateMapper();
return Result<List<BinInfoResp>>.Success(mapperBinInfo.Map<List<BinInfoResp>>(queryListByClause));
}
}