| | |
| | | } |
| | | public static DataTable GetBestSolutionDict(bool is界面,string ConfigString,int hostID, out int ValidNum,DateTime dateTime=default(DateTime)) |
| | | { |
| | | List<Files> FileList = new List<Files>(); |
| | | List<string> files = new List<string>(); |
| | | List<string> Inputfiles=new List<string>(); |
| | | ValidNum = 0; |
| | | if (dateTime==default(DateTime)) { dateTime=DateTime.Now; } |
| | | //string currentDirectory = Directory.GetCurrentDirectory(); |
| | | string resultPath = GlobalPath.resultPath;// Path.Combine(GlobalPath.resultPath, "result"); |
| | | string currentDirectory = Directory.GetCurrentDirectory(); |
| | | //string resultPath = GlobalPath.resultPath; |
| | | string userPathFile = resultPath + "UserPath.ini"; |
| | | string userPath = null; |
| | | if (File.Exists(userPathFile)) |
| | | { |
| | | userPath = File.ReadAllText(userPathFile); |
| | | } |
| | | if (userPath == null || !Directory.Exists(userPath)) |
| | | { |
| | | userPath = resultPath; |
| | | } |
| | | 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 = userPath; |
| | | 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(userPath, "*.json") |
| | | .Where(file => File.GetLastWriteTime(file) >= tenMinutesAgo && File.GetLastWriteTime(file) <= currentTime) |
| | | .ToArray(); |
| | | string[] inputFiles = Directory.GetFiles(userPath, "*.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(userPath, "*.json") |
| | | .Where(file => getTimeByFileName(file) >= tenMinutesAgo && getTimeByFileName(file) <= currentTime) |
| | | .OrderBy(file =>file) |
| | | .ToArray(); |
| | | |
| | | string[] inputFiles = Directory.GetFiles(userPath, "*.input") |
| | | .Where(file => getTimeByFileName(file) >= tenMinutesAgo && getTimeByFileName(file) <= currentTime) |
| | | .OrderBy(file=>file) |
| | | .ToArray(); |
| | | |
| | | files = jsonFiles.ToList(); |
| | | Inputfiles = inputFiles.ToList(); |
| | | } |
| | | |
| | | string result = null; |
| | | |
| | | List<PointF3D> points = new List<PointF3D>(); |
| | | DataTable dt = new DataTable(); |
| | | dt.Columns.Add("时间", typeof(DateTime)); |
| | | if (Inputfiles.Count != 0) |
| | | { |
| | | dt.Columns.Add("接口文件"); |
| | | dt.Columns.Add("结果文件"); |
| | | } |
| | | List<double> 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<LogicModelParams>(file_full); |
| | | } |
| | | catch |
| | | { |
| | | // 读取文件内容 |
| | | string fileContent = File.ReadAllText(file_full); |
| | | param = JsonConvert.DeserializeObject<LogicModelParams>(fileContent); |
| | | } |
| | | ParamBuffer.dict.TryAdd(name, param.CloneResult()); |
| | | if (ParamBuffer.dict.Count> lastMinutes*3) |
| | | { |
| | | foreach(var key in ParamBuffer.dict.Keys.ToList()) |
| | | { |
| | | if (getTimeByFileName(key) < DateTime.Now.AddMinutes(-lastMinutes)) ParamBuffer.dict.TryRemove(key,out LogicModelParams v); |
| | | } |
| | | } |
| | | } |
| | | |
| | | param.dict_ID.TryGetValue(hostID, out variable obj); |
| | | if (obj == null) { obj = param.OFunction.variable; } |
| | | |
| | | dict<string,double> dict = new dict<string, double>(); |
| | | 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<double> currentScadaList = null; |
| | | string name = new FileInfo(file_full).Name; |
| | | if (ParamBuffer.dict.ContainsKey(name)) |
| | | { |
| | | param = ParamBuffer.dict[name]; |
| | | } |
| | | else |
| | | { |
| | | //try |
| | | //{ |
| | | // param = MessageCompressHelper.ReadCompressedBase64FromFile<LogicModelParams>(file_full); |
| | | //} |
| | | //catch |
| | | //{ |
| | | |
| | | //} |
| | | string fileContent = File.ReadAllText(file_full); |
| | | param = JsonConvert.DeserializeObject<LogicModelParams>(fileContent); |
| | | // 读取文件内容 |
| | | |
| | | ParamBuffer.dict.TryAdd(name, param.CloneResult()); |
| | | } |
| | | param.dict_ID.TryGetValue(hostID,out variable obj); |
| | | if (obj == null) { obj = param.OFunction.variable; } |
| | | |
| | | dict<string, double> dict = new dict<string, double>(); |
| | | 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]; |
| | | dr["结果文件"] = files[i]; |
| | | } |
| | | dt.Rows.Add(dr); |
| | | } |
| | | } |
| | | catch |
| | | { |
| | | continue; |
| | | } |
| | | } |
| | | dt.Columns.Add("标记"); |
| | | if (Inputfiles.Count != 0) |
| | | { |
| | | dt.Columns["结果文件"].SetOrdinal(dt.Columns.Count - 1); |
| | | 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; |
| | | return null; |
| | | } |
| | | static List<double> getScadaPumpStatusList(dict<string,double> di) |
| | | { |
| | | List<double> doubles = new List<double>(); |
| | | 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 立新变化= doubles[0] - doubles[3]; |
| | | var 凤凰变化 = doubles[1] - doubles[4]; |
| | | |
| | | if (立新变化* 凤凰变化<0 && (Math.Abs(立新变化) *101.972 > 1.2 || Math.Abs(凤凰变化) *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<WdnmoParam>(json); |
| | | return wp; |
| | | } |
| | | catch { return null; } |
| | | } |
| | | static List<PointF3D> calcFilterPointsBySets(List<PointF3D> points, double maxDis) |
| | | { |
| | | // 计算每个点与其他所有点之间的距离和 |
| | | List<List<PointF3D>> sets = new List<List<PointF3D>>(); |
| | | 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<PointF3D>() { point}); |
| | | } |
| | | |
| | | } |
| | | List<PointF3D> maxCountSet=new List<PointF3D>(); |
| | | foreach(var set in sets) |
| | | { |
| | | if (maxCountSet.Count<=set.Count) |
| | | maxCountSet = set; |
| | | } |
| | | return maxCountSet; |
| | | //return ints; |
| | | } |
| | | static List<PointF3D> calcFilterPoints(List<PointF3D> points, double k) |
| | | { |
| | | // 计算每个点与其他所有点之间的距离和 |
| | | List<double> distanceSums = new List<double>(); |
| | | 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<PointF3D> filteredPoints = new List<PointF3D>(); |
| | | //List<int> ints = new List<int>(); |
| | | 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<PointF3D> points) |
| | | { |
| | | // 计算每个点与其他所有点之间的距离和 |
| | | List<double> distanceSums = new List<double>(); |
| | | 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<double> values) |
| | | { |
| | | double avg = values.Average(); |
| | | double sumOfSquares = values.Sum(val => Math.Pow(val - avg, 2)); |
| | | double stdDev = Math.Sqrt(sumOfSquares / values.Count); |
| | | return stdDev; |
| | | } |
| | | static string getOptString(double x) |
| | | { |
| | | if (x < 0) return "关闭"; |
| | | else return "开启"; |
| | | } |
| | | public static string getOrderTxt(DataView dv, int bestRowIndex) |
| | | { |
| | | if (bestRowIndex < 0) return null; |
| | | DataRowView row = dv[bestRowIndex]; |
| | | int recentRowIndex = dv.Count - 1; |
| | | double num = (double)dv[bestRowIndex][3]; |
| | | |
| | | bool isChangePump = false; |
| | | if (num<-1000) |
| | | { |
| | | isChangePump = true; |
| | | } |
| | | 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}#泵"; |
| | | string pumpChangeTxt_lx = ""; |
| | | string pumpChangeTxt_fh = ""; |
| | | var time = DateTime.Now; |
| | | string PumpStateList_lx0 = ""; |
| | | string PumpStateList_fh0 = ""; |
| | | string PumpStateList_lx1 = ""; |
| | | string PumpStateList_fh1 = ""; |
| | | for (int i = 1; i <= 5; i++) |
| | | { |
| | | double d = 0; |
| | | if ((d = (double)dv[bestRowIndex][15 + i]) == 1) PumpStateList_lx0 += $"{i}#"; |
| | | if ((d = (double)dv[bestRowIndex][20 + i]) == 1) PumpStateList_fh0 += $"{i}#"; |
| | | if ((d = (double)dv[bestRowIndex][5 + i]) == 1) PumpStateList_lx1 += $"{i}#"; |
| | | if ((d = (double)dv[bestRowIndex][10 + i]) == 1) PumpStateList_fh1 += $"{i}#"; |
| | | if ((d=(double)dv[bestRowIndex][25 + i]) != 0) pumpChangeTxt_lx += $"{getOptString(d)}{i}#"; |
| | | if ((d = (double)dv[bestRowIndex][30 + i]) != 0) pumpChangeTxt_fh += $"{getOptString(d)}{i}#"; |
| | | } |
| | | if (pumpChangeTxt_lx != "") pumpChangeTxt_lx = "立新" + pumpChangeTxt_lx; |
| | | if (pumpChangeTxt_fh != "") pumpChangeTxt_fh = "凤凰" + pumpChangeTxt_fh; |
| | | |
| | | string txt = $@"{time:HH:mm} |
| | | 方案内容: |
| | | 当前运行方案: |
| | | 立新:{PumpStateList_lx0} 出厂压力:{dv[recentRowIndex][4]:0.000}MPa |
| | | 凤凰:{PumpStateList_fh0} 出厂压力:{dv[recentRowIndex][5]:0.000}MPa |
| | | 推荐方案: |
| | | 立新:{PumpStateList_lx1} 出厂压力:{dv[bestRowIndex][1]:0.000}MPa |
| | | 凤凰:{PumpStateList_fh1} 出厂压力:{dv[bestRowIndex][2]:0.000}MPa |
| | | {pumpChangeTxt_lx}{pumpChangeTxt_fh} |
| | | "; |
| | | 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 |
| | | } |
| | | }); |
| | | if (url == null) return "url is null"; |
| | | foreach(var url0 in url.Split(';')) |
| | | { |
| | | 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(url0, content).Result; |
| | | |
| | | if (!response.IsSuccessStatusCode) |
| | | { |
| | | // 发送失败 |
| | | return response.ReasonPhrase; |
| | | } |
| | | } |
| | | } |
| | | // 发送成功 |
| | | return null; |
| | | |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | class PointF3D |
| | | { |