|
|
|
|
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<BinInfo> binInfos = binInfoRepository.Query();
|
|
|
|
|
if (binInfos.Count < 0)
|
|
|
|
|
{
|
|
|
|
|
Log.Info("lack of binInfos");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<EquipInfo> chargerList =
|
|
|
|
|
EquipInfoRepository.QueryListByClause(it => it.TypeCode == (int)EquipmentType.Charger);
|
|
|
|
|
HashSet<string> 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<ElecPriceModelVersionDetail> 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<BatteryOpModelDetail> batteryOpModelDetails =
|
|
|
|
|
batteryOpModelDetailRepository.QueryListByClause(d => d.ModelId == oid);
|
|
|
|
|
List<BatteryOpModelDetail> opModelDetails = batteryOpModelDetails.Where(t =>
|
|
|
|
|
{
|
|
|
|
|
List<int> start = t.StartTime.Split(":").Select(int.Parse).ToList();
|
|
|
|
|
List<int> 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<BinInfo> 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<BinInfo> 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<BinInfo> 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<bool>? 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;
|
|
|
|
|
}
|
|
|
|
|
}
|