using IStation.Application; using IStation.ChEr.Application; using IStation.ChEr.Model; using IStation.Service; using Quartz; using System.Data; using Yw; using Yw.Dto; using static IStation.Service.SSAPredictHelper; namespace IStation.ChEr.WebApi { /// /// /// [DisallowConcurrentExecution]//此特性标识 必须等待这次任务执行完成后,才能执行下次任务 public class CalcWaterPredictJob : IJob { /// /// / /// public CalcWaterPredictJob() { } private SSAPredictHelper _SSAPredictHelper = new SSAPredictHelper(); private BLL.WaterPredictRecord _bll = new BLL.WaterPredictRecord(); /// /// /// /// /// public Task Execute(IJobExecutionContext context) { if (DateTime.Now.Hour == 0 && DateTime.Now.Minute == 15) { insert2daysPredictData(); } var TodayRealdataList = ConnectHelper.GetByPumpOneDayWaterData(DateTime.Today, DateTime.Today.AddDays(1), "1h").Where(x => x.DateTime.Hour <= DateTime.Now.Hour).ToList(); //获取当前日期前今天的所有值 int dayHour = WaterPredictRecord.ConvertIntDay(DateTime.Now); int lastHour = WaterPredictRecord.ConvertIntDay(DateTime.Now.AddHours(-1)); var TwoDaysList = _bll.GetEnd2Days(300); var select = TwoDaysList.Where(x => x.DayHour == dayHour).FirstOrDefault(); var lastDifferenceValue = TwoDaysList.Where(x => x.DayHour == lastHour).FirstOrDefault(); if (TodayRealdataList != null) { LogHelper.Info("已找到当前时间前所有数据"); if (TodayRealdataList.Last().DateTime.Hour == DateTime.Now.Hour && select != null) { try { if (TodayRealdataList.Count >= 2) { var lastElementTotal = TodayRealdataList.Last().Total; var secondLastElementTotal = TodayRealdataList[TodayRealdataList.Count - 2].Total; select.RealTotalValue = TodayRealdataList.Last().Total; select.RealDifferenceValue = lastElementTotal - secondLastElementTotal; if (select.RealDifferenceValue == 0 || select.RealDifferenceValue < 0 || select.RealDifferenceValue > 100000) { if (PredictHelper.IsOpenState()) { select.Description += ",时间:" + DateTime.Now.ToString("HH:mm") + "众毅提供真实数据出现异常"; var ErrorBakData = ConnectHelper.GetByPumpOneDayWaterData(DateTime.Today, DateTime.Today.AddDays(1), "300s").Where(x => x.DateTime.Hour <= DateTime.Now.Hour).ToList(); //获取当前日期前今天的所有值 select.BakData = JsonHelper.Object2Json(ErrorBakData); select.States = 0; if (lastDifferenceValue.RealDifferenceValue > 0) { select.RealDifferenceValue = lastDifferenceValue.RealDifferenceValue; } else { select.RealDifferenceValue = 60000; } _bll.Update(select); } else { if (lastDifferenceValue.RealDifferenceValue > 0) { select.RealDifferenceValue = lastDifferenceValue.RealDifferenceValue; } else { select.RealDifferenceValue = 60000; } select.States = 0; _bll.Update(select); } } else { select.States = 1; _bll.Update(select); } } else { select.RealTotalValue = TodayRealdataList.Last().Total; select.RealDifferenceValue = TodayRealdataList.Last().Total - _bll.GetEnd2Days(240).Where(x => x.DayHour == WaterPredictRecord.ConvertIntDay(DateTime.Now.AddHours(-1))).Last().RealTotalValue; if (select.RealDifferenceValue == 0 || select.RealDifferenceValue < 0 || select.RealDifferenceValue > 100000) { if (PredictHelper.IsOpenState()) { select.Description += ",时间:" + DateTime.Now.ToString("HH:mm") + "众毅提供真实数据出现异常"; var ErrorBakData = ConnectHelper.GetByPumpOneDayWaterData(DateTime.Today, DateTime.Today.AddDays(1), "300s").Where(x => x.DateTime.Hour <= DateTime.Now.Hour).ToList(); //获取当前日期前今天的所有值 select.BakData = JsonHelper.Object2Json(ErrorBakData); select.States = 0; if (lastDifferenceValue.RealDifferenceValue > 0) { select.RealDifferenceValue = lastDifferenceValue.RealDifferenceValue; } else { select.RealDifferenceValue = 60000; } _bll.Update(select); } else { if (lastDifferenceValue.RealDifferenceValue > 0) { select.RealDifferenceValue = lastDifferenceValue.RealDifferenceValue; } else { select.RealDifferenceValue = 60000; } select.States = 1; _bll.Update(select); } } else { select.States = 1; _bll.Update(select); } } } catch (Exception e) { select.RealTotalValue = TodayRealdataList.Last().Total; select.States = 0; select.RealDifferenceValue = lastDifferenceValue.RealDifferenceValue; ; select.Description += ",时间:" + DateTime.Now.ToString("HH:mm") + "遇到未知错误!" + "原因:" + e; var ErrorBakData = ConnectHelper.GetByPumpOneDayWaterData(DateTime.Today, DateTime.Today.AddDays(1), "300s").Where(x => x.DateTime.Hour <= DateTime.Now.Hour).ToList(); //获取当前日期前今天的所有值 select.BakData = JsonHelper.Object2Json(ErrorBakData); _bll.Update(select); LogHelper.Info("遇到未知错误!" + "原因:" + e); } } else { /* select.RealTotalValue = 0; select.States = 0; select.RealDifferenceValue = 60000; select.Description += ",时间:" + DateTime.Now.ToString("HH:mm") + "取到的数据与当前时间不匹配,或找不到与当前时间匹配的预测值"; var ErrorBakData = ConnectHelper.GetByPumpOneDayWaterData(DateTime.Today, DateTime.Today.AddDays(1), "300s").Where(x => x.DateTime.Hour <= DateTime.Now.Hour).ToList(); //获取当前日期前今天的所有值 select.BakData = JsonHelper.Object2Json(ErrorBakData); _bll.Update(select);*/ LogHelper.Info("找不到对应当前时间对应数据 时间:" + DateTime.Now); return null; } } else { select.RealTotalValue = 0; select.States = 0; select.Description += ",时间:" + DateTime.Now.ToString("HH:mm") + "未能从众毅取到真实数据"; select.RealDifferenceValue = lastDifferenceValue.RealDifferenceValue; ; var ErrorBakData = ConnectHelper.GetByPumpOneDayWaterData(DateTime.Today, DateTime.Today.AddDays(1), "300s").Where(x => x.DateTime.Hour <= DateTime.Now.Hour).ToList(); //获取当前日期前今天的所有值 select.BakData = JsonHelper.Object2Json(ErrorBakData); _bll.Update(select); LogHelper.Info("未能从众毅取到真实数据,时间:" + DateTime.Now.ToString()); } var beforeTwoDays = _bll.GetEnd2Days(350); var beforedata = beforeTwoDays.Where(x => x.DayHour <= dayHour).Take(240).ToList(); List> tupleList = beforedata .Select(input => { var dateTime = WaterPredictRecord.ConvertDatatime(input.DayHour); return Tuple.Create(dateTime, (double)input.RealDifferenceValue); }).ToList(); //转换为SSA算法所需入参 tupleList = tupleList.OrderBy(x => x.Item1).ToList(); //按照时间进行排序 var predictdata = _SSAPredictHelper.Predict(tupleList, 3600, 10, 2880, (float)0.99, 24); var starthour = int.Parse(string.Format("{0:00}{1:00}{2:00}", DateTime.Now.Month, DateTime.Now.Day, 0)); var endhour = int.Parse(string.Format("{0:00}{1:00}{2:00}", DateTime.Now.Month, DateTime.Now.Day, 23)); var currentdata = TwoDaysList.Where(x => x.DayHour >= starthour && x.DayHour <= endhour).OrderBy(x => x.DayHour).ToList(); if (currentdata.Count == 24) { for (int i = 0; i < currentdata.Count; i++) { currentdata[i].LastPredictValue = Math.Round(predictdata[i].Total, 0); if (currentdata[i].LastPredictValue > 90000 || currentdata[i].LastPredictValue < 20000) { currentdata[i].Description += ",时间:" + DateTime.Now.ToString("HH:mm") + "预测数据偏差过大"; var ErrorBakData = ConnectHelper.GetByPumpOneDayWaterData(DateTime.Today, DateTime.Today.AddDays(1), "300s").Where(x => x.DateTime.Hour <= DateTime.Now.Hour).ToList(); //获取当前日期前今天的所有值 currentdata[i].BakData = JsonHelper.Object2Json(ErrorBakData); currentdata[i].States = 0; } else { currentdata[i].States = 1; } currentdata[i].LastPredictTime = DateTime.Now; currentdata[i].PredictValueList = currentdata[i].LastPredictValue.ToString() + "," + currentdata[i].PredictValueList; } } else { LogHelper.Info("今天一天的数据小于24条 ---不全"); } _bll.BatSet(currentdata); LogHelper.Info("已经替换真实数据"); return null; } //预测两天数据(今天和明天) public void insert2daysPredictData() { List waterPredictRecords = new List(); List ssaInput = new List(); var alllist = _bll.GetEnd2Days(300); var lastdaystarthour = int.Parse(string.Format("{0:00}{1:00}{2:00}", DateTime.Today.AddDays(-1).Month, DateTime.Today.AddDays(-1).Day, 0)); var lastdayendhour = int.Parse(string.Format("{0:00}{1:00}{2:00}", DateTime.Today.AddDays(-1).Month, DateTime.Today.AddDays(-1).Day, 23)); var selectList = alllist.Where(x => x.DayHour <= lastdayendhour).ToList().Take(240); foreach (var item in selectList) { var dateTime = WaterPredictRecord.ConvertDatatime(item.DayHour); ssaInput.Add(new SSAInput { Time = dateTime, Value = (float)item.RealDifferenceValue }); } ssaInput = ssaInput.OrderBy(x => x.Time).ToList(); List> tupleList = ssaInput .Select(input => Tuple.Create(input.Time, (double)input.Value)) .ToList(); var predictdata = _SSAPredictHelper.Predict(tupleList, 3600, 10, 2880, (float)0.99, 48); var list = alllist.Where(x => x.DayHour >= lastdaystarthour + 100 && x.DayHour <= lastdayendhour + 100).OrderBy(x => x.DayHour).ToList(); //找到今天所有的预测数据,并替换 if (list.Count == 0 || list.Count < 24) { LogHelper.Info("替换当日完整预测数据时找不到对应时间--"); for (int i = 24; i < predictdata.Count; i++) { int dayHour = int.Parse(string.Format("{0:00}{1:00}{2:00}", predictdata[i].DateTime.Month, predictdata[i].DateTime.Day, predictdata[i].DateTime.Hour)); list.Add(new WaterPredictRecord { DayHour = dayHour, PredictTime = DateTime.Now, LastPredictValue = Math.Round(predictdata[i].Total, 0), States = 1 }); } _bll.BatSet(list); LogHelper.Info("时间:" + DateTime.Now + "---预测今明两天数据"); return; } if (list.Count == 24) { for (int i = 0; i < predictdata.Count; i++) { if (i < 24) { list[i].LastPredictTime = DateTime.Now; list[i].LastPredictValue = Math.Round(predictdata[i].Total, 0); list[i].PredictValueList = list[i].LastPredictValue.ToString() + "," + list[i].PredictValueList; list[i].States = 1; } else { int dayHour = int.Parse(string.Format("{0:00}{1:00}{2:00}", predictdata[i].DateTime.Month, predictdata[i].DateTime.Day, predictdata[i].DateTime.Hour)); list.Add(new WaterPredictRecord { DayHour = dayHour, PredictTime = DateTime.Now, LastPredictValue = Math.Round(predictdata[i].Total, 0), States = 1 }); } } _bll.BatSet(list); LogHelper.Info("时间:" + DateTime.Now + "---预测今明两天数据"); } /* _bll.BatSet(list); LogHelper.Info("时间:" + DateTime.Now + "---预测今明两天数据");*/ } } }