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; } }