duheng
2025-02-11 7e0414c91a51219a92515c90ccb803ebade5613a
WaterPredict/IStation.ChEr.WebApi.Predict/ÈÎÎñ/CalcWaterPredictJob.cs
@@ -1,8 +1,11 @@
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
@@ -30,60 +33,151 @@
        /// <returns></returns>
        public Task Execute(IJobExecutionContext context)
        {
            if (DateTime.Now.Hour == 0 && DateTime.Now.Minute == 5)
            if (DateTime.Now.Hour == 0 && DateTime.Now.Minute == 15)
            {
                insert2daysPredictData();
            }
            var TodayRealdataList = ConnectHelper.GetByPumpOneDayWaterData(DateTime.Today, DateTime.Today.AddDays(1)).Where(x => x.DateTime.Hour <= DateTime.Now.Hour).ToList();  //获取当前日期前今天的所有值
            LogHelper.Info("已找到当天时间前所有数据");
            int dayHour = int.Parse(string.Format("{0:00}{1:00}{2:00}", DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour));
            var TwoDaysList = _bll.GetEnd2Days(300);
            var select = TwoDaysList.Where(x => x.DayHour == dayHour).FirstOrDefault();
            if (TodayRealdataList.Last().DateTime.Hour == DateTime.Now.Hour && select != null)
            //    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(600);
            //  LogHelper.Info("数据库取出" + JsonHelper.Object2Json(twoDaysList));
            //选中当前时间对应的数据库数据
            var select = twoDaysList.Find(x => x.DayHour == dayHour);
            //当前的上一个小时的数据
            var lastValue = twoDaysList.Find(x => x.DayHour == lastHour);
            try
            {
                try
                var allRealData = ConnectHelper.GetLatelyOneHourValue("120s", out string error);
                if (error != string.Empty)
                {
                    select.RealValue = TodayRealdataList.Last().Total;
                    select.LastPredictTime = DateTime.Now;
                    _bll.Update(select);
                    LogHelper.Info(error);
                }
                catch
                var line1 = PredictHelper.GetAccWater(allRealData, 0, out string line1error);
                select.States = 1;
                if (line1error != string.Empty)
                {
                    select.RealValue = -1;
                    _bll.Update(select);
                    LogHelper.Info("未能从众毅取到真实数据,时间:" + DateTime.Now.ToString());
                    select.BakData += JsonHelper.Object2Json(allRealData[0]);
                    select.Description += "嘉定一线数据有误" + line1error;
                    select.States = 0;
                }
                var line2 = PredictHelper.GetAccWater(allRealData, 1, out string line2error);
                if (line2error != string.Empty)
                {
                    select.BakData += JsonHelper.Object2Json(allRealData[1]);
                    select.Description += "嘉定二线数据有误" + line2error;
                    select.States = 0;
                }
                var line3 = PredictHelper.GetAccWater(allRealData, 2, out string line3error);
                if (line3error != string.Empty)
                {
                    select.BakData += JsonHelper.Object2Json(allRealData[2]);
                    select.Description += "嘉定三线数据有误" + line3error;
                    select.States = 0;
                }
                var pipe2400 = PredictHelper.GetAccWater(allRealData, 3, out string pipe2400error);
                if (pipe2400error != string.Empty)
                {
                    select.BakData += JsonHelper.Object2Json(allRealData[3]);
                    select.Description += "2400总管数据有误" + pipe2400error;
                    select.States = 0;
                }
                var pipe2700 = PredictHelper.GetAccWater(allRealData, 4, out string pipe2700error);
                if (pipe2700error != string.Empty)
                {
                    select.BakData += JsonHelper.Object2Json(allRealData[4]);
                    select.Description += "2600总管数据有误" + pipe2700error;
                    select.States = 0;
                }
                if (line1 != 0 || line2 != 0 || line3 != 0 || pipe2400 != 0 || pipe2700 != 0)
                {
                    select.RealDifferenceValue = line1 + line2 + line3 + pipe2400 + pipe2700;
                    if (select.RealDifferenceValue < 20000 || select.RealDifferenceValue > 90000)
                    {
                        select.Description += "真实数据偏差过大,请检测数据";
                        select.States = 0;
                    }
                }
                else
                {
                    select.RealDifferenceValue = lastValue.RealDifferenceValue;
                    LogHelper.Info(">>>>五条管内数据有异常");
                };
                //   select.RealDifferenceValue = select.RealTotalValue - lastValue.RealTotalValue;
                LogHelper.Info("替换数据");
                _bll.Update(select);
            }
            catch (Exception ex)
            {
                LogHelper.Info("出现错误,进入catch" + ex.Message);
                select.RealTotalValue = 0;
                select.States = 0;
                select.Description += ",时间:" + DateTime.Now.ToString("HH:mm") + "未能从众毅取到真实数据";
                select.RealDifferenceValue = lastValue.RealDifferenceValue; ;
                var ErrorBakData = ConnectHelper.GetLatelyOneHourValue("120s", out string error);
                select.BakData = JsonHelper.Object2Json(ErrorBakData);
                LogHelper.Info("准备修改数据库");
                _bll.Update(select);
                LogHelper.Info("众毅获取数据出现问题>>>>" + JsonHelper.Object2Json(ErrorBakData));
            }
            LogHelper.Info("开始获取历史数据");
            //开始进行预测
            var beforeTwoDays = _bll.GetEnd2Days(350);
            var beforedata = beforeTwoDays.Where(x => x.DayHour <= dayHour).Take(360).ToList();
            List<Tuple<DateTime, double>> 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, 15, 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 realScadaDatas = ConnectHelper.GetLatelyOneHourValue("120s", out string error);
                        currentdata[i].BakData += JsonHelper.Object2Json(realScadaDatas);
                        currentdata[i].States = 0;
                    }
                    else
                    {
                        if (currentdata[i].States == 0)
                        {
                            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
            {
                select.RealValue = -1;
                select.LastPredictTime = DateTime.Now;
                _bll.Update(select);
                LogHelper.Info("未能从众毅取到真实数据,时间:" + DateTime.Now.ToString());
                LogHelper.Info("今天一天的数据小于24条 ---不全");
            }
            var beforedata = TwoDaysList.Where(x => x.DayHour <= dayHour).Take(240).ToList();
            List<Tuple<DateTime, double>> tupleList = beforedata
    .Select(input =>
    {
        int month = input.DayHour / 10000; // èŽ·å–æ•´æ•°çš„ä¸‡ä½æ•°è¡¨ç¤ºæœˆä»½
        int day = (input.DayHour % 10000) / 100; // èŽ·å–æ•´æ•°çš„ç™¾ä½å’Œåä½è¡¨ç¤ºæ—¥æœŸ
        int hour = input.DayHour % 100; // èŽ·å–æ•´æ•°çš„ä¸ªä½æ•°è¡¨ç¤ºå°æ—¶
        DateTime dateTime = new DateTime(DateTime.Now.Year, month, day, hour, 0, 0);
        return Tuple.Create(dateTime, (double)input.RealValue);
    }).ToList(); //转换为SSA算法所需入参
            tupleList = tupleList.OrderBy(x => x.Item1).ToList();  //按照时间进行排序
            var predictdata = _SSAPredictHelper.Predict(tupleList, 3600, 10, 3600, (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).ToList();
            for (int i = 0; i < currentdata.Count; i++)
            {
                currentdata[i].LastPredictValue = Math.Round(predictdata[i].Total, 1);
                currentdata[i].LastPredictTime = DateTime.Now;
                currentdata[i].PredictValueList = currentdata[i].LastPredictValue.ToString() + "," + currentdata[i].PredictValueList;
            }
            LogHelper.Info("开始替换真实数据");
            _bll.BatSet(currentdata);
            LogHelper.Info("已经替换真实数据");
            return null;
@@ -95,49 +189,56 @@
            List<WaterPredictRecord> waterPredictRecords = new List<WaterPredictRecord>();
            List<SSAInput> ssaInput = new List<SSAInput>();
            var alllist = _bll.GetEnd2Days(300);
            var alllist = _bll.GetEnd2Days(500);
            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();
            var selectList = alllist.Where(x => x.DayHour <= lastdayendhour).ToList().Take(240);
            foreach (var item in selectList)
            {
                // æå–月份、日期和小时部分
                int month = item.DayHour / 10000; // èŽ·å–æ•´æ•°çš„ä¸‡ä½æ•°è¡¨ç¤ºæœˆä»½
                int day = (item.DayHour % 10000) / 100; // èŽ·å–æ•´æ•°çš„ç™¾ä½å’Œåä½è¡¨ç¤ºæ—¥æœŸ
                int hour = item.DayHour % 100; // èŽ·å–æ•´æ•°çš„ä¸ªä½æ•°è¡¨ç¤ºå°æ—¶
                // æž„造 DateTime å¯¹è±¡
                DateTime dateTime = new DateTime(DateTime.Now.Year, month, day, hour, 0, 0);
                ssaInput.Add(new SSAInput { Time = dateTime, Value = (float)item.RealValue });
                var dateTime = WaterPredictRecord.ConvertDatatime(item.DayHour);
                ssaInput.Add(new SSAInput { Time = dateTime, Value = (float)item.RealDifferenceValue });
            }
            ssaInput = ssaInput.OrderBy(x => x.Time).ToList();
            List<Tuple<DateTime, double>> tupleList = ssaInput
      .Select(input => Tuple.Create(input.Time, (double)input.Value))
      .ToList();
            var predictdata = _SSAPredictHelper.Predict(tupleList, 3600, 10, 3600, (float)0.99, 48);
            /*            foreach (var item in predictdata)
                        {
                            int dayHour = int.Parse(string.Format("{0:00}{1:00}{2:00}", item.DateTime.Month, item.DateTime.Day, item.DateTime.Hour));
                            waterPredictRecords.Add(new WaterPredictRecord { DayHour = dayHour, PredictTime = DateTime.Now, LastPredictValue = item.Total });
                        }*/
            var list = alllist.Where(x => x.DayHour >= lastdaystarthour + 100 && x.DayHour <= lastdayendhour + 100).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();
            //找到今天所有的预测数据,并替换
            for (int i = 0; i < predictdata.Count; i++)
            if (list.Count == 0 || list.Count < 24)
            {
                if (i < 24)
                {
                    list[i].LastPredictTime = DateTime.Now;
                    list[i].LastPredictValue = Math.Round(predictdata[i].Total, 1);
                    list[i].PredictValueList = list[i].LastPredictValue.ToString() + "," + list[i].PredictValueList;
                }
                else
                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, 1) });
                    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;
            }
            _bll.BatSet(list);
            LogHelper.Info("时间:" + DateTime.Now + "---预测今明两天数据");
            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 + "---预测今明两天数据");*/
        }
    }
}