tangxu
2024-06-07 18a1a6faf82b1ad00d27f6fc7f5734c34aea32df
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
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
{
    /// <summary>
    ///
    /// </summary>
    [DisallowConcurrentExecution]//此特性标识 必须等待这次任务执行完成后,才能执行下次任务
    public class CalcWaterPredictJob : IJob
    {
        /// <summary>
        /// /
        /// </summary>
        public CalcWaterPredictJob()
        {
        }
 
        private SSAPredictHelper _SSAPredictHelper = new SSAPredictHelper();
        private BLL.WaterPredictRecord _bll = new BLL.WaterPredictRecord();
 
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public Task Execute(IJobExecutionContext context)
        {
            LogHelper.Info(DateTime.Now.ToString());
            if (DateTime.Now.Hour == 0 && DateTime.Now.Minute == 5)
            {
                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);
            var TwoDaysList = _bll.GetEnd2Days(300);
            LogHelper.Info("2");
            var select = TwoDaysList.Where(x => x.DayHour == dayHour).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)
                            {
                                if (PredictHelper.IsOpenState())
                                {
                                    select.Description = "真实数据出现异常";
                                    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;
                                    _bll.Update(select);
                                    return null;
                                }
                            }
                            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)
                            {
                                if (PredictHelper.IsOpenState())
                                {
                                    select.Description = "真实数据出现异常";
                                    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;
                                    _bll.Update(select);
                                }
                            }
                            else
                            {
                                select.States = 1;
                                _bll.Update(select);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        select.RealTotalValue = 0;
                        select.States = 0;
                        select.Description = "为真实数据赋值错误!" + "原因:" + 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("未能从众毅取到真实数据,时间:" + DateTime.Now.ToString());
                    }
                }
                else
                {
                    select.RealTotalValue = 0;
                    select.States = 0;
                    select.RealDifferenceValue = 60000;
                    select.Description = "取到的数据与当前时间不匹配,或找不到与当前时间匹配的预测值";
                    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);
                }
            }
            else
            {
                select.RealTotalValue = 0;
                select.States = 0;
                select.Description = "未能从众毅取到真实数据";
                select.RealDifferenceValue = 60000;
                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<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, 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();
            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 = "预测数据偏差过大";
                    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;
            }
            _bll.BatSet(currentdata);
            LogHelper.Info("已经替换真实数据");
            return null;
        }
 
        //预测两天数据(今天和明天)
        public void insert2daysPredictData()
        {
            List<WaterPredictRecord> waterPredictRecords = new List<WaterPredictRecord>();
            List<SSAInput> ssaInput = new List<SSAInput>();
 
            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<Tuple<DateTime, double>> 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();
            //找到今天所有的预测数据,并替换
            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 + "---预测今明两天数据");
        }
    }
}