using Common.Const; using Entity.DbModel.Station; 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 * 30; } public void Handle() { try { DateTime now = DateTime.Now; List binInfos = binInfoRepository.Query(); if (binInfos.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(); binInfos = binInfos.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(); 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 = 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(); if (opModelDetails.Count == 0) { Log.Info("lack of effective batteryOpModelDetails"); return; } int needBatteryCount = opModelDetails[0].BatteryCount ?? 8; List canSwapList = binInfos.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; } if (canSwapList.Count > needBatteryCount) { List chargingList = binInfos.Where(it => it.ChargeStatus == 1).ToList(); int needStopCount = chargingList.Count - (canSwapList.Count - needBatteryCount); if (needStopCount > 0) { //停电量低的 chargingList.Sort((a, b) => (a.Soc ?? 0).CompareTo(b.Soc ?? 0)); for (int i = 0; i < needStopCount; 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) .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; } } } #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; } }