using Common.Const; using Entity.DbModel.Station; using Entity.DbModel.System; using HybirdFrameworkCore.Autofac.Attribute; using HybirdFrameworkCore.AutoTask; using HybirdFrameworkCore.Entity; using HybirdFrameworkCore.Utils; using log4net; using Repository.Station; using Service.Charger.Client; using Service.Init; namespace Service.Charger.MyTask; [Scope] public class AutoChargeTask : ITask { private static readonly ILog Log = LogManager.GetLogger(typeof(AutoChargeTask)); private volatile bool _stop; public ElecPriceModelVersionRepository elecPriceModelVersionRepository { get; set; } public ElecPriceModelVersionDetailRepository elecPriceModelVersionDetailRepository { get; set; } public BatteryOpModelRepository batteryOpModelRepository { get; set; } public BatteryOpModelDetailRepository batteryOpModelDetailRepository { get; set; } public BinInfoRepository binInfoRepository { get; set; } public EquipInfoRepository EquipInfoRepository { get; set; } public string Name() { return "AutoChargeTask"; } public int Interval() { return 1000 * 10; } public void Handle() { try { DateTime now = DateTime.Now; List allBinInfos = binInfoRepository.Query(); if (allBinInfos.Count < 0) { Log.Info("lack of binInfos"); return; } List chargerList = EquipInfoRepository.QueryListByClause(it => it.TypeCode == (int)EquipmentType.Charger); HashSet autoChargeSet = chargerList.Where(it => it.AutoCharge == 1).Select(it => it.Code).ToHashSet(); var binInfos = allBinInfos.Where(it => autoChargeSet.Contains(it.ChargerNo)).ToList(); if (ObjUtils.IsEmpty(binInfos)) { Log.Info("there is no auto charger"); return; } #region 电价模型 int ceid = StaticStationInfo.Ceid; ElecPriceModelVersion elecPriceModelVersion = elecPriceModelVersionRepository.QueryByClause(i => i.Version == ceid); if (elecPriceModelVersion == null) { Log.Info("lack of effective elecPriceModelVersion"); return; } List elecPriceModelVersionDetails = elecPriceModelVersionDetailRepository.QueryListByClause(it => it.Version == elecPriceModelVersion.Version); /*ElecPriceModelVersionDetail? elecPriceModelVersionDetail = elecPriceModelVersionDetails.Where(i => i.StartHour <= now.Hour && i.StartMinute <= now.Minute && i.EndHour > now.Hour && i.EndMinute > now.Minute).FirstOrDefault();*/ ElecPriceModelVersionDetail? elecPriceModelVersionDetail = null; foreach (var VARIABLE in elecPriceModelVersionDetails) { // 构造开始和结束的DateTime对象,使用当前日期的年月日 DateTime startTime = new DateTime(now.Year, now.Month, now.Day, VARIABLE.StartHour, VARIABLE.StartMinute, 0); DateTime endTime = new DateTime(now.Year, now.Month, now.Day, VARIABLE.EndHour, VARIABLE.EndMinute, 0); if (DateTime.Now >= startTime && DateTime.Now <= endTime) { elecPriceModelVersionDetail = VARIABLE; } } if (elecPriceModelVersionDetail == null) { Log.Info("lack of effective elecPriceModelVersionDetail"); return; } #endregion #region 运营模型 int oid = int.Parse(StaticStationInfo.Oid); BatteryOpModel batteryOpModel = batteryOpModelRepository.QueryByClause(d => d.ModelId == oid); if (batteryOpModel == null) { Log.Info("lack of effective batteryOpModel"); return; } List batteryOpModelDetails = batteryOpModelDetailRepository.QueryListByClause(d => d.ModelId == oid); List opModelDetails = new List(); /*List opModelDetails = batteryOpModelDetails.Where(t => { List start = t.StartTime.Split(":").Select(int.Parse).ToList(); List end = t.EndTime.Split(":").Select(int.Parse).ToList(); return now.Hour >= start[0] && now.Hour < end[0] && now.Minute >= start[1] && now.Minute < end[1] && now.Second >= start[2] && now.Second < end[2]; }).ToList();*/ foreach (var t in batteryOpModelDetails) { if (DateTime.Now >= DateTime.Parse(t.StartTime) && DateTime.Now <= DateTime.Parse(t.EndTime)) { opModelDetails.Add(t); } } if (opModelDetails.Count == 0) { Log.Info("lack of effective batteryOpModelDetails"); return; } int needBatteryCount = opModelDetails[0].BatteryCount ?? 8; List canSwapList = allBinInfos.Where(it => it.Soc != null && Convert.ToSingle(it.Soc) >= StaticStationInfo.SwapSoc && it.CanSwapFlag == 1) .ToList(); /*if (canSwapList.Count == needBatteryCount) { Log.Info($"lack of needBatteryCount {needBatteryCount}"); return; }*/ List chargingList = binInfos.Where(it => it.ChargeStatus == 1).ToList(); if (canSwapList.Count >= needBatteryCount) { int needStopCount = chargingList.Count - (canSwapList.Count - needBatteryCount); //if (needStopCount > 0) if (chargingList.Count > 0) { //停电量低的 chargingList.Sort((a, b) => (a.Soc ?? 0).CompareTo(b.Soc ?? 0)); for (int i = 0; i < chargingList.Count; i++) { Log.Info($"auto stop charge {chargingList[i].No}"); ClientMgr.GetBySn(chargingList[i].No)?.SendRemoteStopCharging(); } } } else { List canChargeList = binInfos.Where(it => it.Soc != null && Convert.ToSingle(it.Soc) < StaticStationInfo.ChargeSoc && it.CanChargeFlag == 1 && it.Exists == 1) .ToList(); //启动电量高的 canChargeList.Sort((a, b) => (b.Soc ?? 0).CompareTo(a.Soc ?? 0)); byte chargeSoc = StaticStationInfo.ChargeSoc; int count = needBatteryCount - canSwapList.Count; int number = 0; foreach (var binInfo in canChargeList) { float? chargePower = EquipInfoRepository.QueryPowerByCode(binInfo.Code); float? power = chargePower == null ? StaticStationInfo.ChargePower : chargePower; Result? result = ClientMgr.GetBySn(binInfo.ChargerNo) ?.StartCharge(chargeSoc, (float)power); if (result is { IsSuccess: true }) { Log.Info($"auto start charge {binInfo.ChargerNo}"); number++; } if (count == number) { Log.Info($"auto start charge count {count}"); break; } } } #region 达到充电SOC自动停 foreach (var VARIABLE in chargingList) { if (StaticStationInfo.ChargeSoc != 100) if (VARIABLE.Soc >= StaticStationInfo.ChargeSoc + 1) { Log.Info($"auto stop charge {VARIABLE.No} soc>=chaegeSoc"); ClientMgr.GetBySn(VARIABLE.No)?.SendRemoteStopCharging(); } } #endregion #endregion } catch (Exception e) { Log.Error("handle with error", e); } } public bool Stoped() { return _stop; } public void Stop() { _stop = true; } public void ResetStop() { _stop = false; } }