public static object Acc(PE pe, List <Station.DataItem> rawdata, Expression expression, int CountAcc) { var result = CountAcc; // init 計算式 Expression _e = new Expression(expression.ParsedExpression, EvaluateOptions.NoCache); DateTime currentTIM = pe.CurrentTIM; List <Station.DataItem> lastrawdata = rawdata.Where(x => x.TIM <= currentTIM).Select(s => s).OrderByDescending(t => t.TIM).Take(CountAcc + 1).ToList(); Station.DataItem lastDataItem = lastrawdata.FirstOrDefault(); // 處理客制 function _e.EvaluateFunction += delegate(string name, FunctionArgs args) { switch (name) { case "diff": args.Result = Diff(lastrawdata, args.Parameters[0], currentTIM); break; } }; return(_e.Evaluate()); }
public static object Diffv1(PE pe, List <Station.DataItem> rawdata, Expression expression) { var result = 0; // 取得前一筆資料 Station.DataItem lastDataItem = rawdata.Where(x => x.TIM < pe.CurrentTIM).OrderByDescending(t => t.TIM).FirstOrDefault(); if (lastDataItem != null) { int lastColIndex = lastDataItem.Header.IndexOf(expression.ParsedExpression.ToString().Replace("[", "").Replace("]", "")); // 取得欄位 Index if (lastColIndex != -1) { decimal lastColNum = decimal.TryParse(lastDataItem.Line[lastColIndex], out lastColNum) ? lastColNum : 0; decimal thisColNum = decimal.TryParse(expression.Evaluate().ToString(), out thisColNum) ? thisColNum : 0; // 如果前一筆大於此筆則不相減 if (lastColNum > thisColNum) { lastColNum = 0; } return(thisColNum - lastColNum); } } else { return(result); } return(result); }
public static object Diff(List <Station.DataItem> rawdata, Expression expression, DateTime currentTIM) { decimal totalAcc = 0; Station.DataItem lastDataItem = rawdata.FirstOrDefault(); expression.EvaluateParameter += delegate(string name, ParameterArgs args) { foreach (Station.DataItem _rawdata in rawdata) { if (currentTIM != default(DateTime)) { Station.DataItem thisDataItem = _rawdata; int thisColIndex = thisDataItem.Header.IndexOf(name); int lastColIndex = lastDataItem.Header.IndexOf(name); if (lastColIndex != -1) { decimal lastColNum = decimal.TryParse(thisDataItem.Line[lastColIndex], out lastColNum) ? lastColNum : 0; decimal thisColNum = decimal.TryParse(lastDataItem.Line[thisColIndex], out thisColNum) ? thisColNum : 0; // 如果前一筆大於此筆則不相減 if (lastColNum > thisColNum) { lastColNum = 0; } totalAcc = totalAcc + (thisColNum - lastColNum); } lastDataItem = thisDataItem; } } args.Result = totalAcc; }; return(expression.Evaluate()); }
private void CSVInput(Station sta) { logView.Add("讀取資料."); // 讀取 CSV file DirectoryInfo dir = new DirectoryInfo(sta.InputPath); String sLastFileName72Hr = default(DateTime).ToString("yyyyMMddHHmmss") + ".txt"; if (sta.lastFileTime != default(DateTime)) { sLastFileName72Hr = sta.lastFileTime.AddHours(-72).ToString("yyyyMMddHHmmss") + ".txt"; } // 1.找出最後一筆記錄及之前 72 小時記錄 FileInfo[] files = dir.GetFiles("*", SearchOption.AllDirectories) .Where(x => x.Name.Contains(".csv") && string.Compare(x.Name, sLastFileName72Hr) >= 0) .OrderBy(x => x.Name).ToArray(); // 增加到 staion foreach (FileInfo file in files) { try { // 2.Open the text file using a stream reader. List <dynamic> records; using (var reader = new StreamReader(file.FullName)) { using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture)) { records = csv.GetRecords <dynamic>().ToList(); var record = records[0]; var obj1 = record as System.Dynamic.ExpandoObject; DateTime tim = default(DateTime); Station.DataItem dataitem = new Station.DataItem() { Header = obj1.Select(a => a.Key).ToList(), Line = obj1.Select(a => a.Value.ToString()).ToList() }; // 加入 tim DateTime.TryParseExact(dataitem.Line[dataitem.Header.IndexOf("TIM")], "yyyy-MM-ddTHH:mm:ss+08:00", null, System.Globalization.DateTimeStyles.None, out tim); dataitem.TIM = tim; dataitem.FileName = file.Name; sta.DataItems.Add(dataitem); } } // 記錄最後一次檔名 sta.newLastFileName = file.Name; } catch (IOException err) { logView.Add("讀取CGI檔案錯誤: " + file.Name + ", ERROR." + err.Message); } } PE pe = new PE(); pe.Tag = "E1_TEST_OW"; //pe.Titles = new string[] { "編號", "日期", "時間", "雨量刻度", "10分鐘雨量", "每小時雨量", "3小時累積雨量", "6小時累積雨量", "12小時累積雨量", "24小時累積雨量", "48小時累積雨量", "72小時累積雨量" }; //pe.Cols = new string[] { "TEST_001", "TIMD", "TIMT", "DI_0 Cnt", @"calc(diff([DI_0 Cnt]))", @"calc(acc(diff([DI_0 Cnt])#6))", @"calc(acc(diff([DI_0 Cnt])#18))", @"calc(acc(diff([DI_0 Cnt])#36))", @"calc(acc(diff([DI_0 Cnt])#72))", @"calc(acc(diff([DI_0 Cnt])#144))", @"calc(acc(diff([DI_0 Cnt])#288))", @"calc(acc(diff([DI_0 Cnt])#432))" }; pe.Titles = sTitles.Split(',').Select(p => p.Trim()).ToArray(); pe.Cols = sCols.Split(',').Select(p => p.Trim()).ToArray(); string[] processCols = pe.Cols; logView.Add("統計資料中..."); List <Station.DataItem> processDataItem = sta.DataItems.Where(x => string.Compare(x.FileName, sta.lastFileName) > 0).ToList(); // 1.讀取資料 foreach (Station.DataItem dataitem in processDataItem) { List <string> _outline = new List <string>(); DateTime tim = default(DateTime); // 處理 TIM if (dataitem.Header.IndexOf("TIM") != -1) { DateTime.TryParseExact(dataitem.Line[dataitem.Header.IndexOf("TIM")], "yyyy-MM-ddTHH:mm:ss+08:00", null, System.Globalization.DateTimeStyles.None, out tim); pe.CurrentTIM = tim; } foreach (string col in processCols) { int colIndex = 0; string colData = ""; colIndex = dataitem.Header.IndexOf(col); // 處理特殊欄位 if (col == "TIMD") { colIndex = dataitem.Header.IndexOf("TIM"); colData = dataitem.Line[colIndex].Substring(0, 10); } else if (col == "TIMT") { colIndex = dataitem.Header.IndexOf("TIM"); colData = dataitem.Line[colIndex].Substring(11, 8); } else if (colIndex == -1) { // 關鍵字 calc() 為 string exp = Regex.Match(col, @"(?<=calc\()(.*)(?=\))").Groups[1].Value; if (string.IsNullOrEmpty(exp)) { // 輸入文字,直接輸入 colData = col; } else { // 檢查是否為 acc, 得到 #筆數 bool isAcc = (Regex.Match(col, @"(?<=acc\()(.*)(?=\))").Groups[1].Value != ""); int countAcc = 0; if (isAcc) { countAcc = int.TryParse(Regex.Match(col, @"(?<=#)([^\)]*)").Groups[1].Value, out countAcc) ? countAcc : 0; exp = exp.Replace("#" + countAcc.ToString(), ""); } // init 計算式 Expression e = new Expression(exp, EvaluateOptions.NoCache); // 處理參數 e.EvaluateParameter += delegate(string name, ParameterArgs args) { int _colIndex = dataitem.Header.IndexOf(name); if (_colIndex != -1) { args.Result = dataitem.Line[_colIndex].Trim(); } }; // 處理客制 function e.EvaluateFunction += delegate(string name, FunctionArgs args) { switch (name) { case "diff": //args.Result = Diff(pe, sta.DataItems, args.Parameters[0]); DateTime currentTIM = pe.CurrentTIM; List <Station.DataItem> lastrawdata = sta.DataItems.Where(x => x.TIM <= currentTIM).Select(s => s).OrderByDescending(t => t.TIM).Take(2).ToList(); Station.DataItem lastDataItem = lastrawdata.FirstOrDefault(); args.Result = Diff(lastrawdata, args.Parameters[0], currentTIM); break; case "acc": args.Result = Acc(pe, sta.DataItems, args.Parameters[0], countAcc); break; } }; // 計算式,數字去尾數 0.100 -> 0.1 colData = DoExpressionEvaluate(e); } } else { // 一般取值,不計算 colData = dataitem.Line[colIndex].Trim(); } _outline.Add(colData); } if (_outline.Count > 0) { pe.Lines.Add(new PE.Line { TIM = tim, ColItems = _outline }); } } logView.Add("開始寫入HH檔案..."); if (pe.Lines.Count > 0) { // 2.正式寫入檔案 HH DateTime MinTIM = pe.Lines.Min(x => x.TIM); DateTime MaxTIM = pe.Lines.Max(x => x.TIM); TimeSpan timeSpan = MaxTIM - MinTIM; for (int ihour = 0; ihour <= Math.Ceiling((MaxTIM - MinTIM).TotalHours); ihour++) { string filename = MinTIM.AddHours(ihour).ToString("yyyyMMddHH") + ".txt"; DateTime dtFrom = MinTIM.AddHours(ihour).TruncateToHourStart(); DateTime dtTo = MinTIM.AddHours(ihour + 1).TruncateToHourStart(); List <List <string> > lines = (pe.Lines.Where(x => x.TIM >= dtFrom && x.TIM < dtTo).Select(l => l.ColItems)).ToList(); if (lines.Count > 0) { CSVWriteFile(pe.Titles, lines, sta.OutputPath + @"\" + filename); } } logView.Add("寫入 HH 檔案完成."); } else { logView.Add("無 HH 資料更新. "); } // 最新最後資料 cgiLastFiles.UpdateLastFile(sta.Tag, sta.newLastFileName); // 正式寫入檔案 month }