using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; //using RestSharp; namespace CommonBase { public class SolutionSelector { public static string url = null; public class Files { public string inputFile; public string file; } public static DataTable GetBestSolutionDict(bool is界面,string ConfigString,int hostID, out int ValidNum,DateTime dateTime=default(DateTime)) { List FileList = new List(); List files = new List(); List Inputfiles=new List(); ValidNum = 0; if (dateTime==default(DateTime)) { dateTime=DateTime.Now; } //string currentDirectory = Directory.GetCurrentDirectory(); string resultPath = GlobalPath.resultPath;// Path.Combine(GlobalPath.resultPath, "result"); bool flag = false; int lastMinutes = 10; double junfangK = 3; int filter_times = 2; string[] expressStrings = ConfigString.Split(','); if (expressStrings.Length > 0) int.TryParse(expressStrings[0], out lastMinutes); if (expressStrings.Length > 1) double.TryParse(expressStrings[1], out junfangK); if (expressStrings.Length > 2) int.TryParse(expressStrings[2], out filter_times); if (is界面) { IDataObject clipboardData = Clipboard.GetDataObject(); if (clipboardData != null && clipboardData.GetDataPresent(DataFormats.FileDrop)) { files.AddRange((string[])clipboardData.GetData(DataFormats.FileDrop)); files.RemoveAll(f => f.ToLower().IndexOf(".json") < 0); if (files.Count > 0) flag = true; } Clipboard.SetText(" "); if (!flag) { if (MessageBox.Show("自动选择历史输出?\r\n是:自动\r\n否:手动", "方案择优", MessageBoxButtons.YesNo) == DialogResult.No) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.InitialDirectory = resultPath; openFileDialog.Filter = "JSON Files (*.json)|*.json"; openFileDialog.Multiselect = true; if (openFileDialog.ShowDialog() == DialogResult.OK) { string[] selectedFilePaths = openFileDialog.FileNames; files.AddRange(selectedFilePaths); } } else { // 获取当前时间 DateTime currentTime = dateTime; // 计算时间范围,当前时间的十分钟之前 DateTime tenMinutesAgo = currentTime.AddMinutes(-lastMinutes); // 查找目录下的所有.json文件,并根据修改时间进行筛选 string[] jsonFiles = Directory.GetFiles(resultPath, "*.json") .Where(file => File.GetLastWriteTime(file) >= tenMinutesAgo && File.GetLastWriteTime(file) <= currentTime) .ToArray(); string[] inputFiles = Directory.GetFiles(resultPath, "*.input") .Where(file => File.GetLastWriteTime(file) >= tenMinutesAgo && File.GetLastWriteTime(file) <= currentTime) .ToArray(); files = jsonFiles.ToList(); Inputfiles = inputFiles.ToList(); } } } else { // 获取当前时间 DateTime currentTime = dateTime; // 计算时间范围,当前时间的十分钟之前 DateTime tenMinutesAgo = currentTime.AddMinutes(-lastMinutes); // 查找目录下的所有.json文件,并根据修改时间进行筛选 string[] jsonFiles = Directory.GetFiles(resultPath, "*.json") .Where(file => getTimeByFileName(file) >= tenMinutesAgo && getTimeByFileName(file) <= currentTime) .OrderBy(file =>file) .ToArray(); string[] inputFiles = Directory.GetFiles(resultPath, "*.input") .Where(file => getTimeByFileName(file) >= tenMinutesAgo && getTimeByFileName(file) <= currentTime) .OrderBy(file=>file) .ToArray(); files = jsonFiles.ToList(); Inputfiles = inputFiles.ToList(); } string result = null; List points = new List(); DataTable dt = new DataTable(); dt.Columns.Add("时间", typeof(DateTime)); if (Inputfiles.Count!=0) dt.Columns.Add("接口文件"); List RecentScada=null; if (files.Count>0) { LogicModelParams param = null; string file_full = files[files.Count-1]; double[] doubles = new double[5]; string name = new FileInfo(file_full).Name; if (ParamBuffer.dict.ContainsKey(name)) { param = ParamBuffer.dict[name]; } else { try { param = MessageCompressHelper.ReadCompressedBase64FromFile(file_full); } catch { // 读取文件内容 string fileContent = File.ReadAllText(file_full); param = JsonConvert.DeserializeObject(fileContent); } ParamBuffer.dict.TryAdd(name, param.CloneResult()); } param.dict_ID.TryGetValue(hostID, out variable obj); if (obj == null) { obj = param.OFunction.variable; } dict dict = new dict(); dict.LoadFromString(obj.objListString); RecentScada = getScadaPumpStatusList(dict); } else { return new DataTable(); } for (int i=0;i< files.Count;i++) { string file_full = files[i]; LogicModelParams param = null; try { double[] doubles = new double[5]; List currentScadaList = null; string name = new FileInfo(file_full).Name; if (ParamBuffer.dict.ContainsKey(name)) { param = ParamBuffer.dict[name]; } else { try { param = MessageCompressHelper.ReadCompressedBase64FromFile(file_full); } catch { // 读取文件内容 string fileContent = File.ReadAllText(file_full); param = JsonConvert.DeserializeObject(fileContent); } ParamBuffer.dict.TryAdd(name, param.CloneResult()); } param.dict_ID.TryGetValue(hostID,out variable obj); if (obj == null) { obj = param.OFunction.variable; } dict dict = new dict(); dict.LoadFromString(obj.objListString); foreach (var kp in dict) { if (!dt.Columns.Contains(kp.Key)) dt.Columns.Add(kp.Key, typeof(double)); } FileInfo fi = new FileInfo(file_full); string file = fi.Name; DataRow dr = dt.NewRow(); DateTime time = getTimeByFileName(file); dr["时间"] = time; int k = 0; foreach (var kp in dict) { dr[kp.Key] = kp.Value; if (k < doubles.Length) doubles[k] = kp.Value; k++; } currentScadaList = getScadaPumpStatusList(dict); bool flagScadaStatus = true; for (int l=0;l< RecentScada.Count;l++) { if (currentScadaList[l] != RecentScada[l]) { flagScadaStatus = false; break; } } if (!flagScadaStatus) continue; if (i==files.Count-1 && dt.Rows.Count==0 || (double)dr["福永目标"] < 4000 && 水泵未变化时水厂压力变化是否正常(doubles, int.Parse( dr["开关量维度值"].ToString()))) { points.Add(new PointF3D(doubles[0], doubles[1], doubles[2], dt.Rows.Count)); if (Inputfiles.Count != 0) dr["接口文件"] = Inputfiles[i]; dt.Rows.Add(dr); } } catch { continue; } } dt.Columns.Add("标记"); if (Inputfiles.Count != 0) dt.Columns["接口文件"].SetOrdinal(dt.Columns.Count-1); if (points.Count <= 0) return new DataTable(); var filterpoints = points; filterpoints = calcFilterPointsBySets(filterpoints, 1); //filterpoints = filterByScoal(filterpoints); for (int i = 0; i < filter_times; i++) filterpoints = calcFilterPoints(filterpoints, junfangK); var minP = calcMinPoint(filterpoints); for (int i = 0; i < dt.Rows.Count; i++) { dt.Rows[i]["标记"] = "×"; } foreach (var p in filterpoints) { dt.Rows[p.rowIndex]["标记"] = ""; } dt.Rows[minP.rowIndex]["标记"] = "√"; ValidNum=filterpoints.Count; return dt; } static List getScadaPumpStatusList(dict di) { List doubles = new List(); doubles.Add(di["凤凰水厂1#泵状态_SCADA"]); doubles.Add(di["凤凰水厂2#泵状态_SCADA"]); doubles.Add(di["凤凰水厂3#泵状态_SCADA"]); doubles.Add(di["凤凰水厂4#泵状态_SCADA"]); doubles.Add(di["凤凰水厂5#泵状态_SCADA"]); doubles.Add(di["立新水厂1#泵状态_SCADA"]); doubles.Add(di["立新水厂2#泵状态_SCADA"]); doubles.Add(di["立新水厂3#泵状态_SCADA"]); doubles.Add(di["立新水厂4#泵状态_SCADA"]); doubles.Add(di["立新水厂5#泵状态_SCADA"]); return doubles; } static bool 水泵未变化时水厂压力变化是否正常(double[] doubles,int 开关量) { if (开关量 != 0) return true; var 立新变化= Math.Abs(doubles[0] - doubles[3]); var 凤凰变化 = Math.Abs(doubles[1] - doubles[4]); if (立新变化*101.972 > 1.2 || 凤凰变化*101.972 > 1.2) return false; return true; } static DateTime getTimeByFileName(string filename) { if (File.Exists(filename)) filename = new FileInfo(filename).Name; string format = "yyyy'年'MM'月'dd'日'HH'时'mm'分'"; DateTime time = default(DateTime); DateTime.TryParseExact(filename.Split('_')[2], format, null, System.Globalization.DateTimeStyles.None, out time); return time; } public static WdnmoParam GetWdnmoParam(DataView dv,int bestRowIndex) { int recentRowIndex = dv.Count - 1; double num = (double)dv[bestRowIndex][3]; string path = dv[bestRowIndex]["接口文件"].ToString(); string json = File.ReadAllText(path); try { var wp=JsonConvert.DeserializeObject(json); return wp; } catch { return null; } } static List calcFilterPointsBySets(List points, double maxDis) { // 计算每个点与其他所有点之间的距离和 List> sets = new List>(); foreach (var point in points) { bool flag = false; foreach (var set in sets) { if (CalculateDistance(set[0], point) <= maxDis) { set.Add(point); flag = true; break; } } if (!flag) { sets.Add(new List() { point}); } } List maxCountSet=new List(); foreach(var set in sets) { if (maxCountSet.Count<=set.Count) maxCountSet = set; } return maxCountSet; //return ints; } static List calcFilterPoints(List points, double k) { // 计算每个点与其他所有点之间的距离和 List distanceSums = new List(); foreach (var point in points) { double distanceSum = 0; foreach (var otherPoint in points) { if (point != otherPoint) { double distance = CalculateDistance(point, otherPoint); distanceSum += distance; } } distanceSums.Add(distanceSum); } // 计算平均值和标准差 double mean = distanceSums.Average(); double stdDev = CalculateStandardDeviation(distanceSums); // 计算离群点的阈值 double threshold = mean + (k * stdDev); // 剔除离群点 List filteredPoints = new List(); //List ints = new List(); for (int i = 0; i < points.Count; i++) { if (distanceSums[i] <= threshold)// ints.Add(i); filteredPoints.Add(points[i]); } return filteredPoints; //return ints; } static PointF3D calcMinPoint(List points) { // 计算每个点与其他所有点之间的距离和 List distanceSums = new List(); foreach (var point in points) { double distanceSum = 0; foreach (var otherPoint in points) { if (point != otherPoint) { double distance = CalculateDistance(point, otherPoint); distanceSum += distance; } } distanceSums.Add(distanceSum); } // 找到距离和最小的点的索引 int minDistanceIndex = distanceSums.LastIndexOf(distanceSums.Min()); // 获取距离和最小的点 PointF3D minDistancePoint = points[minDistanceIndex]; return minDistancePoint; } // 定义三维点类 // 计算两个点之间的欧氏距离 static double CalculateDistance(PointF3D point1, PointF3D point2) { double distance = Math.Sqrt(Math.Pow(point1.x - point2.x, 2) + Math.Pow(point1.y - point2.y, 2) + Math.Pow(point1.z - point2.z, 2)); return distance; } // 计算标准差 static double CalculateStandardDeviation(List values) { double avg = values.Average(); double sumOfSquares = values.Sum(val => Math.Pow(val - avg, 2)); double stdDev = Math.Sqrt(sumOfSquares / values.Count); return stdDev; } public static string getOrderTxt(DataView dv, int bestRowIndex) { DataRowView row = dv[bestRowIndex]; int recentRowIndex = dv.Count - 1; double num = (double)dv[bestRowIndex][3]; string stateTxt = (num > 0) ? "开启" : "关闭"; int num1 = (int)Math.Abs(num); int PumpNum = num1 / 100; string facTxt = (PumpNum <= 5) ? "立新" : "凤凰"; int PumpNumShow = PumpNum > 5 ? PumpNum - 5 : PumpNum; string pumpChangeTxt = num == 0 ? "水泵开停不变" : $"{facTxt}{stateTxt}{PumpNumShow}#泵"; var time = DateTime.Now; string PumpStateList_lx0 = ""; string PumpStateList_fh0 = ""; string PumpStateList_lx1 = ""; string PumpStateList_fh1 = ""; for (int i = 1; i <= 5; i++) { if ((double)dv[bestRowIndex][5 + i] == 1) { PumpStateList_lx1 += $"{i}#"; if (i != PumpNum) { PumpStateList_lx0 += $"{i}#"; } } else if (i == PumpNum) { PumpStateList_lx0 += $"{i}#"; } } PumpNum = PumpNum - 5; for (int i = 1; i <= 5; i++) { if ((double)dv[bestRowIndex][10 + i] == 1) { PumpStateList_fh1 += $"{i}#"; if (i != PumpNum) { PumpStateList_fh0 += $"{i}#"; } } else if (i == PumpNum) { PumpStateList_fh0 += $"{i}#"; } } string txt = $@"{time:HH:mm} 方案内容:  当前运行方案: 立新:{PumpStateList_lx0} 出厂压力:{dv[recentRowIndex][4]}MPa 凤凰:{PumpStateList_fh0} 出厂压力:{dv[recentRowIndex][5]}MPa  推荐方案: 立新:{PumpStateList_lx1} 出厂压力:{dv[bestRowIndex][1]}MPa 凤凰:{PumpStateList_fh1} 出厂压力:{dv[bestRowIndex][2]}MPa {pumpChangeTxt},压力调整 "; txt = txt.Trim('\n').Trim(' '); return txt; } public static string SendOrder(string txt) { //string url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=ad1996dd-37ac-4476-9f97-30616382593e"; string param = JsonConvert.SerializeObject(new { msgtype = "text", text = new { content = txt } }); using (HttpClient client = new HttpClient()) { client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); HttpContent content = new StringContent(param, Encoding.UTF8, "application/json"); HttpResponseMessage response = client.PostAsync(url, content).Result; if (response.IsSuccessStatusCode) { // 发送成功 return null; } else { // 发送失败 return response.ReasonPhrase; } } } } class PointF3D { public double x; public double y; public double z; public PointF3D(double x, double y, double z, int rowIndex) { this.x = x; this.y = y; this.z = z; this.rowIndex = rowIndex; } public int rowIndex = 0; } }