using IStation.DAL;
using System.Reflection;
namespace IStation.Algorithm
{
///
/// 分析泵项
///
public class AnaPumpItem
{
public AnaPumpItem() { }
public AnaPumpItem(Pump rhs)
{
this.ID = rhs.ID;
this.Name = rhs.Name;
this.Code = rhs.Code;
this.IsBp = rhs.IsBp;
this.Qr = rhs.Qr;
this.Hr = rhs.Hr;
this.Nr = rhs.Nr;
this.Pr = rhs.Pr;
this.Er = rhs.Er;
if (rhs.CurveQH != null && rhs.CurveQP != null)
{
this.CurveQH = rhs.CurveQH.Clone();
this.CurveQP = rhs.CurveQP.Clone();
this.AllowCalc = true;
}
}
public AnaPumpItem(Pump rhs, double freDef, double freMin, double freMax, double freSpace) : this(rhs)
{
this.CalcFrequencyItems(freDef, freMin, freMax, freSpace);
}
public int ID { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public double Qr { get; set; }
public double Hr { get; set; }
public double Nr { get; set; }
public double Pr { get; set; }
public double Er { get; set; }
public bool IsBp { get; set; }
public Curve.CurveExpress CurveQH { get; set; }
public Curve.CurveExpress CurveQP { get; set; }
public List AnaFrequencyItems { get; set; }
public bool AllowCalc { get; set; }
void CalcFrequencyItems(double freDef, double freMin, double freMax, double freSpace)
{
if (!this.AllowCalc)
return;
this.AnaFrequencyItems = new List();
//var freItemDef = new AnaFrequencyItem();
//freItemDef.Frequency = freMax;
//freItemDef.CurveQH = this.CurveQH.Clone();
//freItemDef.CurveQP = this.CurveQP.Clone();
//this.AnaFrequencyItems.Add(freItemDef);
for (double fre = freMax; fre >= freMin; fre -= freSpace)
{
var freItem = new AnaPumpFreItem();
freItem.Frequency = fre;
freItem.CurveQH = Curve.PumpCalculateHelper.CalculateSimilarQH(this.CurveQH, freDef, fre);
freItem.CurveQP = Curve.PumpCalculateHelper.CalculateSimilarQP(this.CurveQP, freDef, fre);
this.AnaFrequencyItems.Add(freItem);
}
}
}
///
/// 分析泵变频项
///
public class AnaPumpFreItem
{
public double Frequency { get; set; }
public Curve.CurveExpress CurveQH { get; set; }
public Curve.CurveExpress CurveQP { get; set; }
}
///
/// 调度分析辅助类
///
public class SchedulingAnaHelper
{
double _frequency_def = 50;
double _frequency_min = 25;
double _frequency_max = 50;
double _frequency_space = 0.1;//频率间隔
double _head_space = 0.1;
ParallelConnectionHelper _parallelConnectionHelper = new ParallelConnectionHelper();
#region TableName
string _tableFrePumpTag = "B";
string _tableFixPumpTag = "G";
string _tableSpaceMark = "_";
string GetTableName(List pumpItems)
{
var tableName = string.Empty;
var count = pumpItems.Count;
pumpItems = pumpItems.OrderBy(p => p.ID).ToList();
for (int i = 0; i < count; i++)
{
var pumpItem = pumpItems[i];
tableName += GetTableName(pumpItem);
if ((i + 1) != count)
{
tableName += _tableSpaceMark;
}
}
return tableName;
}
string GetTableName(AnaPumpItem pumpItem)
{
return (pumpItem.IsBp ? _tableFrePumpTag : _tableFixPumpTag) + pumpItem.ID;
}
#endregion
public bool AnaOptList(List pumps)
{
if (pumps == null || pumps.Count < 1)
return false;
var fre_def = _frequency_def;
var anaPumpItems = new List();
foreach (var pump in pumps)
{
if (pump.IsBp)
{
//变频泵
var anaPump = new AnaPumpItem(pump, fre_def, _frequency_min, _frequency_max, _frequency_space);
if (anaPump.AllowCalc)
anaPumpItems.Add(anaPump);
}
else
{
//固频泵
var anaPump = new AnaPumpItem(pump);
if (anaPump.AllowCalc)
anaPumpItems.Add(anaPump);
}
}
if (anaPumpItems.Count < 1)
return false;
var maxRunCount = 3;
var anaPumpItemsArray = anaPumpItems.ToArray();
for (int runCount = 1; runCount <= maxRunCount; runCount++)
{
var pumpCombineList = PermutationAndCombination.GetCombination(anaPumpItemsArray, runCount);
//if (runCount == 1)
//{
// foreach (var pumpCombine in pumpCombineList)
// {
// var start = DateTime.Now;
// AnaSinglePump(pumpCombine[0], _head_space);
// var end = DateTime.Now;
// var tabName = GetTableName(pumpCombine[0]);
// Db.Insert(tabName, 1, start, end);
// }
//}
//else
if (runCount == 2)
{
foreach (var pumpCombine in pumpCombineList)
{
var start = DateTime.Now;
var list = pumpCombine.ToList();
AnaTwoPumps(list, _head_space);
var end = DateTime.Now;
var tabName = GetTableName(list);
Db.Insert(tabName, 1, start, end);
}
}
//else if (runCount == 3)
//{
// foreach (var pumpCombine in pumpCombineList)
// {
// var start = DateTime.Now;
// var list = pumpCombine.ToList();
// AnaThreePumps(list, _head_space);
// var end = DateTime.Now;
// var tabName = GetTableName(list);
// Db.Insert(tabName, 1, start, end);
// }
//}
}
return true;
}
private void AnaSinglePump(AnaPumpItem anaPump, double headSpace)
{
if (anaPump == null)
return;
if (!anaPump.AllowCalc)
return;
//var runFlag = (int)Math.Pow(2, anaPump.ID);//运行标志
var runFlag = GetTableName(anaPump);//运行标志
var scheduleCombineList = new List();
var anaFreItems = anaPump.AnaFrequencyItems;
foreach (var anaFreItem in anaFreItems)
{
var curveQH = anaFreItem.CurveQH;
var curveQP = anaFreItem.CurveQP;
var bol = curveQH.GetMinMaxPointY(out double maxY, out double minY);
if (!bol)
continue;
var maxHead = Math.Ceiling(maxY);
var minHead = Math.Floor(minY);
for (double head = minHead; head <= maxHead; head += headSpace)
{
var flow = curveQH.GetInterPointLastX(head);
if (!flow.HasValue)
continue;
var scheduleCombine = new ScheduleCombine();
scheduleCombine.RunFlag = runFlag;
scheduleCombine.Pump1 = anaFreItem.Frequency;
scheduleCombine.Head = head;
scheduleCombine.Flow = flow.Value;
scheduleCombine.Power = curveQP.GetFitPointY(flow.Value);
scheduleCombine.UWP = PumpCalculateHelper.CalculateUWP(scheduleCombine.Power, scheduleCombine.Flow, scheduleCombine.Head);
scheduleCombine.WP = PumpCalculateHelper.CalculateWP(scheduleCombine.Power, scheduleCombine.Flow);
scheduleCombine.Round();
scheduleCombineList.Add(scheduleCombine);
}
}
var success = Db.BulkInserts(scheduleCombineList);
if (!success)
{
}
}
private void AnaTwoPumps(List anaPumps, double headSpace)
{
if (anaPumps == null || anaPumps.Count != 2)
return;
if (anaPumps.Exists(x => !x.AllowCalc))
return;
string runFlag = GetTableName(anaPumps); //运行标志
//foreach (var anaPump in anaPumps)
//{
// runFlag = runFlag | (int)Math.Pow(2, anaPump.ID);
//}
var scheduleCombineList = new List();
var anaFreItems1 = anaPumps[0].AnaFrequencyItems;
var anaFreItems2 = anaPumps[1].AnaFrequencyItems;
for (int anaIndex1 = 0; anaIndex1 < anaFreItems1.Count; anaIndex1++)
{
for (int anaIndex2 = 0; anaIndex2 < anaFreItems2.Count; anaIndex2++)
{
var anaFreItem1 = anaFreItems1[anaIndex1];
var anaFreItem2 = anaFreItems2[anaIndex2];
_parallelConnectionHelper.ClearCurve();
_parallelConnectionHelper.AddCurve(anaFreItem1.CurveQH, anaFreItem1.CurveQP);
_parallelConnectionHelper.AddCurve(anaFreItem2.CurveQH, anaFreItem2.CurveQP);
var allowParallel = _parallelConnectionHelper.CalculateParallel(out List pointQH, out List pointQE, out List pointQP);
if (!allowParallel)
continue;
var bol = pointQH.GetMinMaxPointY(out double maxY, out double minY);
if (!bol)
continue;
var maxHead = Math.Ceiling(maxY);
var minHead = Math.Floor(minY);
for (double head = minHead; head <= maxHead; head += headSpace)
{
var flow = pointQH.GetInterPointX(head)?.LastOrDefault();
if (!flow.HasValue)
continue;
var scheduleCombine = new ScheduleCombine();
scheduleCombine.RunFlag = runFlag;
scheduleCombine.Pump1 = anaFreItem1.Frequency;
scheduleCombine.Pump2 = anaFreItem2.Frequency;
scheduleCombine.Head = head;
scheduleCombine.Flow = flow.Value;
scheduleCombine.Power = pointQP.GetFitPointY(flow.Value);
scheduleCombine.UWP = PumpCalculateHelper.CalculateUWP(scheduleCombine.Power, scheduleCombine.Flow, scheduleCombine.Head);
scheduleCombine.WP = PumpCalculateHelper.CalculateWP(scheduleCombine.Power, scheduleCombine.Flow);
scheduleCombine.Round();
scheduleCombineList.Add(scheduleCombine);
}
}
}
var success = Db.BulkInserts(scheduleCombineList);
if (!success)
{
}
}
private void AnaThreePumps(List anaPumps, double headSpace)
{
if (anaPumps == null || anaPumps.Count != 3)
return;
if (anaPumps.Exists(x => !x.AllowCalc))
return;
string runFlag = GetTableName(anaPumps);//运行标志
//foreach (var anaPump in anaPumps)
//{
// runFlag = runFlag | (int)Math.Pow(2, anaPump.ID);
//}
var scheduleCombineList = new List();
var anaFreItems1 = anaPumps[0].AnaFrequencyItems;
var anaFreItems2 = anaPumps[1].AnaFrequencyItems;
var anaFreItems3 = anaPumps[2].AnaFrequencyItems;
for (int anaIndex1 = 0; anaIndex1 < anaFreItems1.Count; anaIndex1++)
{
for (int anaIndex2 = 0; anaIndex2 < anaFreItems2.Count; anaIndex2++)
{
for (int anaIndex3 = 0; anaIndex3 < anaFreItems3.Count; anaIndex3++)
{
var anaFreItem1 = anaFreItems1[anaIndex1];
var anaFreItem2 = anaFreItems2[anaIndex2];
var anaFreItem3 = anaFreItems3[anaIndex3];
_parallelConnectionHelper.ClearCurve();
_parallelConnectionHelper.AddCurve(anaFreItem1.CurveQH, anaFreItem1.CurveQP);
_parallelConnectionHelper.AddCurve(anaFreItem2.CurveQH, anaFreItem2.CurveQP);
var allowParallel = _parallelConnectionHelper.CalculateParallel(out List pointQH, out List pointQE, out List pointQP);
if (!allowParallel)
continue;
var bol = pointQH.GetMinMaxPointY(out double maxY, out double minY);
if (!bol)
continue;
var maxHead = Math.Ceiling(maxY);
var minHead = Math.Floor(minY);
for (double head = minHead; head <= maxHead; head += headSpace)
{
var flow = pointQH.GetInterPointX(head)?.LastOrDefault();
if (!flow.HasValue)
continue;
var scheduleCombine = new ScheduleCombine();
scheduleCombine.RunFlag = runFlag;
scheduleCombine.Pump1 = anaFreItem1.Frequency;
scheduleCombine.Pump2 = anaFreItem2.Frequency;
scheduleCombine.Pump3 = anaFreItem3.Frequency;
scheduleCombine.Head = head;
scheduleCombine.Flow = flow.Value;
scheduleCombine.Power = pointQP.GetFitPointY(flow.Value);
scheduleCombine.UWP = PumpCalculateHelper.CalculateUWP(scheduleCombine.Power, scheduleCombine.Flow, scheduleCombine.Head);
scheduleCombine.WP = PumpCalculateHelper.CalculateWP(scheduleCombine.Power, scheduleCombine.Flow);
scheduleCombine.Round();
scheduleCombineList.Add(scheduleCombine);
}
}
}
}
var success = Db.BulkInserts(scheduleCombineList);
if (!success)
{
}
}
}
///
/// 数据库
///
public class Db
{
///
/// 连接配置
///
public static ConnectionConfig ConnectionConfig
{
get
{
var filePath = DbInitial.DbFilePath;
if (!System.IO.File.Exists(filePath))
{
DAL.DbInitial.InitTables();
}
var config = new ConnectionConfig()
{
ConnectionString = $"DataSource={filePath}",
IsAutoCloseConnection = true,
DbType = SqlSugar.DbType.Sqlite
};
return config;
}
}
///
/// 大批量插入
///
public static bool BulkInserts(List list)
{
if (list == null || list.Count < 1)
return default;
using (SqlSugarClient db = new SqlSugarClient(ConnectionConfig))
{
///自己来制定定义的规则
db.CurrentConnectionConfig.ConfigureExternalServices.SplitTableService = new RunFlagSubTableService();
db.CodeFirst
.SplitTables()//标识分表
.InitTables(); //程序启动时加这一行,如果一张表没有会初始化一张
//大数据写入+表不存在会建表
//自动找表大数据写入
return db.Fastest().SplitTable().BulkCopy(list) > 0;
}
}
///
/// 插入
///
public static bool Insert(string flag, int count, DateTime start, DateTime end)
{
var log = new ScheduleAnaLog(flag, count, start, end);
using (SqlSugarClient db = new SqlSugarClient(ConnectionConfig))
{
return db.Insertable(log).ExecuteCommand() > 0;
}
}
internal static object SplitHelper()
{
throw new NotImplementedException();
}
}
///
/// 分表规则
///
public class RunFlagSubTableService : ISplitTableService
{
///
/// 获取所有的数据库中的表
///
///
///
///
///
///
public List GetAllTables(ISqlSugarClient db, EntityInfo EntityInfo, List tableInfos)
{
List result = new List();
foreach (var item in tableInfos)
{
if (item.Name.Contains("_Run_")) //区分标识如果不用正则符复杂一些,防止找错表
{
SplitTableInfo data = new SplitTableInfo()
{
TableName = item.Name //要用item.name不要写错了
};
result.Add(data);
}
}
return result.OrderBy(it => it.TableName).ToList();//打断点看一下有没有查出所有分表
}
///
///
///
///
///
///
///
///
public object GetFieldValue(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object entityValue)
{
var splitColumn = entityInfo.Columns.FirstOrDefault(it => it.PropertyInfo.GetCustomAttribute() != null);
return splitColumn.PropertyInfo.GetValue(entityValue, null);
}
///
///
///
///
///
///
public string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo)
{
return EntityInfo.DbTableName + "_Run";
}
public string GetTableName(ISqlSugarClient db, EntityInfo EntityInfo, SplitType type)
{
return EntityInfo.DbTableName + "_Run";
}
///
/// 确定生成数据库表的时候,表的名称
///
///
///
///
///
///
public string GetTableName(ISqlSugarClient db, EntityInfo entityInfo, SplitType splitType, object fieldValue)
{
return entityInfo.DbTableName + "_Run_" + fieldValue.ToString();
}
}
///
/// 调度组合
///
[SplitTable(SplitType._Custom01)]
public class ScheduleCombine
{
public ScheduleCombine() { }
public ScheduleCombine(ScheduleCombine rhs)
{
this.Pump1 = rhs.Pump1;
this.Pump2 = rhs.Pump2;
this.Pump3 = rhs.Pump3;
this.Head = rhs.Head;
this.Flow = rhs.Flow;
this.Power = rhs.Power;
this.WP = rhs.WP;
this.UWP = rhs.UWP;
}
public void Round()
{
this.Pump1 = Math.Round(this.Pump1, 1);
this.Pump2 = Math.Round(this.Pump2, 1);
this.Pump3 = Math.Round(this.Pump3, 1);
this.Head = Math.Round(this.Head, 1);
this.Flow = Math.Round(this.Flow, 1);
this.Power = Math.Round(this.Power, 1);
this.WP = Math.Round(this.WP, 1);
this.UWP = Math.Round(this.UWP, 1);
}
///
/// 运行标志 (标志枚举)
///
[SplitField]
public string RunFlag { get; set; }
///
/// 泵1
///
public double Pump1 { get; set; }
///
/// 泵2
///
public double Pump2 { get; set; }
///
/// 泵3
///
public double Pump3 { get; set; }
///
/// 扬程
///
public double Head { get; set; }
///
/// 总流量
///
public double Flow { get; set; }
///
/// 总功率
///
public double Power { get; set; }
///
/// 千吨水能耗
///
public double WP { get; set; }
///
/// 单位能耗
///
public double UWP { get; set; }
///
/// 创建时间
///
public DateTime CreateTime { get; set; } = DateTime.Now;
}
}