diff --git a/solarApp/Model/sensor_model.cs b/solarApp/Model/sensor_model.cs index 0d02783..f5ec768 100644 --- a/solarApp/Model/sensor_model.cs +++ b/solarApp/Model/sensor_model.cs @@ -153,6 +153,8 @@ namespace solarApp.Model public string InstallDate { get { return Convert.ToDateTime(installDate).ToString("yyyy-MM-dd"); } set { installDate = value; } } //安裝日期 public string BrandNum { get; set; }//廠商序號 public string WarrantyDate { get { return Convert.ToDateTime(warrantyDate).ToString("yyyy-MM-dd"); } set { warrantyDate = value; } } //保固日期 + public int SensorTypeId { get; set; } + public int SensorTypeDetailId { get; set; } } public class Device : DeviceInfo @@ -174,6 +176,30 @@ namespace solarApp.Model public double Dust { get; set; } //落塵計 public double WingDirection { get; set; } //風向計 public double IrrDay { get; set; } //累計日照量 + public double IrrDayHour { get; set; }//每小時的累積日照差 + } + + public class SensorTypeInfo + { + public int id { get; set; }//流水號 + public string uid { get; set; }//設備編號 + public int PowerStationID { get; set; }//電站編號 + public int Enabled { get; set; }//啟用 + public string SerialNumber { get; set; }//型號 + public string name { get; set; }//名稱 + /// + /// type = 設備 EName 例: PYR + /// + public string type { get; set; }//類別 + public int SensorTypeId { get; set; }//設備型態編號 + public int sensorTypeDetailid { get; set; }//設備細項編號 + public string DBName { get; set; }//資料庫名稱 + public string TableName { get; set; }//資料表名稱 + public string ColName { get; set; }//欄位名稱 + public string HourType { get; set; }//小時的型態 + public string DayType { get; set; }//天的型態 + public string MonthType { get; set; }//月的型態 + public string SetWhat { get; set; }//要寫入的欄位 } } diff --git a/solarApp/Service/procArchiveSensorHourly.cs b/solarApp/Service/procArchiveSensorHourly.cs new file mode 100644 index 0000000..ad64454 --- /dev/null +++ b/solarApp/Service/procArchiveSensorHourly.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MySql.Data.MySqlClient; +using Dapper; +using solarApp.Model; +using System.Configuration; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; + +namespace solarApp.Service +{ + public class procArchiveSensorHourly + { + string Connection1 = string.Empty; + ILogger _logger; + public string _siteID { get; set; } + public string _siteDB { get; set; } + public string _siteID01 { get; set; } + public string _date1 { get; set; } + //public string _date2 { get; set; } + public string _powerStationID { get; set; } + public procArchiveSensorHourly(string Connection_parame = null, ILogger logger = null) + { + if (!string.IsNullOrEmpty(Connection_parame)) + { + Connection1 = Connection_parame; + } + else + { + Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString; + } + + if (logger != null) + { + _logger = logger; + } + } + + public bool get_siteInfo() + { + bool result = false; + try + { + using (MySqlConnection conn = new MySqlConnection(Connection1)) + { + conn.Open(); + + if (_logger != null) + { + _logger.LogInformation("【ProcArchiveSensorHourly】開始執行[{0}]在{1}逆變器取得電站編號", _siteID, _date1); + } + + #region 取得 PowerStationID + string sql = @" select id , `code` siteID, siteDB, `name` siteName + from solar_master.power_station where `code` = @siteID"; + var ds = conn.Query(sql, new { siteID = _siteID }).AsList(); + foreach (var item in ds) + { + _powerStationID = item.id; + _siteDB = item.SiteDB; + _siteID01 = item.SiteID + "01"; + } + + if (_logger != null) + { + _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}逆變器取得電站編號 - {2}", _siteID, _date1, _powerStationID); + } + + #endregion + conn.Close(); + } + result = true; + } + catch (Exception ex) + { + if (_logger != null) + { + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}逆變器取得電站編號", _siteID, _date1); + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}逆變器取得電站編號 - [Exception]:{2}", _siteID, _date1, ex.ToString()); + } + + throw ex; + } + return result; + } + + public bool insertData(string code, string t1) + { + _siteID = code; + _date1 = t1; + get_siteInfo(); + bool result = false; + try + { + using (MySqlConnection conn = new MySqlConnection(Connection1)) + { + conn.Open(); + + if (_logger != null) + { + _logger.LogInformation("【ProcArchiveSensorHourly】開始執行[{0}]在{1}設備寫入資料表的資料", _siteID, _date1); + } + string sql = $@" + select x.*, z.itemname, z.HourType, z.DayType, z.MonthType,z.SetWhat + from ( + -- No sharedevice + select a.id, uid, a.PowerStationID, + Enabled, SerialNumber, name, type, SensorTypeId, sensorTypeDetailid, + DBName, TableName, ColName + from solar_com0002.device a + where a.powerstationid = {_powerStationID} + and deleted = 0 and Enabled = 1 + -- has sharedevice + union + select a.id, uid, b.PowerStationID, + Enabled, SerialNumber, name, type, SensorTypeId, sensorTypeDetailid, + DBName, TableName, ColName + from solar_com0002.device a + join solar_com0002.`SHAREdevice` b on a.id = b.deviceid + where b.powerstationid = {_powerStationID} + and deleted = 0 and Enabled = 1 + ) x join sensor_type y on x.sensortypeid = y.id + join sensor_type_detail z on y.id = z.SensorTypeId"; + var ds = conn.Query(sql); + StringBuilder sb_inserr = new StringBuilder(); + StringBuilder sb_select = new StringBuilder(); + + sb_select.Append($@"select {_powerStationID}, DATE_FORMAT(left(`crdTime`, 13),'%Y-%m-%d %H:%i:%s'), "); + string irrColName = ""; + bool isFirst = true; + foreach (var item in ds) + { + if(item.type == "PYR") + { + irrColName = item.ColName; + continue; + } + if (isFirst) + { + sb_inserr.Append($@"{item.SetWhat}"); + sb_select.Append($@"{item.HourType}({item.ColName})"); + isFirst = false; + } + else + { + sb_inserr.Append($@", {item.SetWhat}"); + sb_select.Append($@", {item.HourType}({item.ColName}) "); + } + } + + var tb = ds.AsList(); + sb_select.Append($@" from {tb[0].DBName}.{tb[0].TableName} where Left(crdTime, 13) = '{t1}'"); + string dblocation = tb[0].DBName+"."+tb[0].TableName; + sb_inserr.Insert(0, "insert into solar_master.sensor_history_hour(PowerStationId, TIMESTAMP, "); + sb_inserr.Append(") "); + string ss = sb_inserr.Append(sb_select.ToString()).ToString(); + conn.Execute(ss); + if (irrColName != "") + { + bool a = countIrr(dblocation, irrColName, t1); + } + //計算累積日照小時差 + updateIrrDayHourData(code, t1); + + if (_logger != null) + { + _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}設備寫入資料表的資料", _siteID, _date1); + } + + conn.Close(); + } + result = true; + } + catch (Exception ex) + { + if (_logger != null) + { + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}設備寫入資料表的資料", _siteID, _date1); + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}設備寫入資料表的資料 - [Exception]:{2}", _siteID, _date1, ex.ToString()); + } + throw ex; + } + return result; + } + + /// + /// 更新日照計 + /// + /// + /// + /// + /// + private bool countIrr(string dbName, string sensorColNum, string t1) { + bool result = false; + try + { + using (MySqlConnection conn = new MySqlConnection(Connection1)) + { + conn.Open(); + string ss = $@"UPDATE solar_master.sensor_history_hour b + join(select {_powerStationID} as powerstationid, concat(Left(crdTime, 13), ':00:00') ctime , ifnull(avg({sensorColNum}), 0) Irr + from {dbName} + where Left(crdTime, 13) = '{t1}' and {sensorColNum} <> 0 + ) a ON a.ctime = b.TIMESTAMP AND a.powerstationid = b.powerstationId + SET Irradiance = a.Irr"; + conn.Execute(ss); + conn.Close(); + } + result = true; + } + catch (Exception ex) + { + if (_logger != null) + { + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}日照計更新至資料表的資料", _siteID, _date1); + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}日照計更新至資料表的資料 - [Exception]:{2}", _siteID, _date1, ex.ToString()); + } + throw ex; + } + return result; + } + public double updateIrrDayHourData(string code, string t1) + { + _siteID = code; + get_siteInfo(); + string result = ""; + double IrrDayHour = 0; + double IrrDay = 0; + double twoHourAgoIrrDay = 0; + string d1 = t1 + ":00:00"; + try + { + using (MySqlConnection conn = new MySqlConnection(Connection1)) + { + conn.Open(); + + if (_logger != null) + { + _logger.LogInformation("【ProcArchiveSensorHourly】開始執行[{0}]在{1}累積日照差更新至資料表的資料", _siteID, _date1); + } + //取前累積日照 + string sql = $@" select IrrDay + from solar_master.sensor_history_hour z + where powerstationID = {_powerStationID} and LEFT(z.`TIMESTAMP`, 13 ) = '{Convert.ToDateTime(d1).ToString("yyyy-MM-dd HH")}' "; + result = conn.QueryFirstOrDefault(sql, commandTimeout: 600); + if (result != null) + { + IrrDay = double.Parse(result); + } + else + { + IrrDay = 0; + } + + string sql2 = $@" select IrrDay + from solar_master.sensor_history_hour z + where powerstationID = {_powerStationID} and LEFT(z.`TIMESTAMP`, 13 ) = '{Convert.ToDateTime(d1).AddHours(-1).ToString("yyyy-MM-dd HH")}' "; + result = conn.QueryFirstOrDefault(sql2, commandTimeout: 600); + if (result != null) + { + twoHourAgoIrrDay = double.Parse(result); + } + else + { + twoHourAgoIrrDay = 0; + } + + if (Convert.ToDateTime(d1).AddHours(-1).Hour == 0)//半夜12點的值 + { + IrrDayHour = 0; + } + else + { + IrrDayHour = IrrDay - twoHourAgoIrrDay;// 前一小時的IrrDay - 前兩小時的IrrDay + } + + string ss = $@"UPDATE solar_master.sensor_history_hour + SET IrrDayHour = {IrrDayHour} + WHERE LEFT(TIMESTAMP, 13) = '{t1}' AND PowerStationId = {_powerStationID}"; + conn.Execute(ss); + if (_logger != null) + { + _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}累積日照差更新至資料表的資料", _siteID, _date1); + } + conn.Close(); + } + } + catch (Exception ex) + { + if (_logger != null) + { + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}累積日照差更新資料表的資料", _siteID, _date1); + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}累積日照差更新資料表的資料 - [Exception]:{2}", _siteID, _date1, ex.ToString()); + } + throw ex; + } + return IrrDayHour; + } + + public bool clearData() + { + bool result = false; + try + { + using (MySqlConnection conn = new MySqlConnection(Connection1)) + { + conn.Open(); + + if (_logger != null) + { + _logger.LogInformation("【ProcArchiveSensorHourly】開始執行[{0}]在{1}設備清除資料表的資料", _siteID, _date1); + } + string d1 = _date1 + ":00:00"; + string clearTime = Convert.ToDateTime(d1).ToString("yyyy-MM-dd"); + string sql = @"delete from solar_master.sensor_history_hour where powerstationID = @powerStationID and left(TIMESTAMP, 10) = @date1"; + MySqlCommand cmd = new MySqlCommand(); + cmd.Connection = conn; + cmd.CommandTimeout = 360; + cmd.Parameters.AddWithValue("@date1", clearTime); + cmd.Parameters.AddWithValue("@PowerStationID", _powerStationID); + cmd.CommandText = sql; + cmd.ExecuteNonQuery(); + cmd.Parameters.Clear(); + + if (_logger != null) + { + _logger.LogInformation("【ProcArchiveSensorHourly】執行完成[{0}]在{1}設備清除資料表的資料", _siteID, _date1); + } + + conn.Close(); + } + result = true; + } + catch (Exception ex) + { + if (_logger != null) + { + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}設備清除資料表的資料", _siteID, _date1); + _logger.LogError("【ProcArchiveSensorHourly】執行失敗[{0}]在{1}設備清除資料表的資料 - [Exception]:{2}", _siteID, _date1, ex.ToString()); + } + throw ex; + } + return result; + } + + } +} diff --git a/solarApp/fmArchive.Designer.cs b/solarApp/fmArchive.Designer.cs index 1c0c10e..1c81943 100644 --- a/solarApp/fmArchive.Designer.cs +++ b/solarApp/fmArchive.Designer.cs @@ -35,6 +35,7 @@ namespace solarApp this.tabControl1 = new System.Windows.Forms.TabControl(); this.tabPage1 = new System.Windows.Forms.TabPage(); this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.button3 = new System.Windows.Forms.Button(); this.label2 = new System.Windows.Forms.Label(); this.textBox1 = new System.Windows.Forms.TextBox(); this.button2 = new System.Windows.Forms.Button(); @@ -86,8 +87,8 @@ namespace solarApp this.tabPage3 = new System.Windows.Forms.TabPage(); this.button1 = new System.Windows.Forms.Button(); this.tabPage4 = new System.Windows.Forms.TabPage(); - this.timer1 = new System.Windows.Forms.Timer(this.components); this.btSyncErr = new System.Windows.Forms.Button(); + this.timer1 = new System.Windows.Forms.Timer(this.components); this.tabControl1.SuspendLayout(); this.tabPage1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); @@ -141,6 +142,7 @@ namespace solarApp // splitContainer1.Panel1 // this.splitContainer1.Panel1.BackColor = System.Drawing.SystemColors.ActiveCaption; + this.splitContainer1.Panel1.Controls.Add(this.button3); this.splitContainer1.Panel1.Controls.Add(this.label2); this.splitContainer1.Panel1.Controls.Add(this.textBox1); this.splitContainer1.Panel1.Controls.Add(this.button2); @@ -172,6 +174,17 @@ namespace solarApp this.splitContainer1.SplitterWidth = 10; this.splitContainer1.TabIndex = 0; // + // button3 + // + this.button3.Font = new System.Drawing.Font("Microsoft JhengHei UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.button3.Location = new System.Drawing.Point(297, 686); + this.button3.Name = "button3"; + this.button3.Size = new System.Drawing.Size(94, 43); + this.button3.TabIndex = 20; + this.button3.Text = "每小時設備"; + this.button3.UseVisualStyleBackColor = true; + this.button3.Click += new System.EventHandler(this.button3_Click); + // // label2 // this.label2.AutoSize = true; @@ -728,10 +741,6 @@ namespace solarApp this.tabPage4.Text = "tabPage4"; this.tabPage4.UseVisualStyleBackColor = true; // - // timer1 - // - this.timer1.Interval = 1000; - // // btSyncErr // this.btSyncErr.Location = new System.Drawing.Point(135, 83); @@ -742,6 +751,10 @@ namespace solarApp this.btSyncErr.UseVisualStyleBackColor = true; this.btSyncErr.Click += new System.EventHandler(this.btSyncErr_Click); // + // timer1 + // + this.timer1.Interval = 1000; + // // fmArchive // this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 19F); @@ -835,5 +848,6 @@ namespace solarApp private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.TabPage tabPage4; private System.Windows.Forms.Button btSyncErr; + private System.Windows.Forms.Button button3; } } \ No newline at end of file diff --git a/solarApp/fmArchive.cs b/solarApp/fmArchive.cs index 2f41d56..25c89ef 100644 --- a/solarApp/fmArchive.cs +++ b/solarApp/fmArchive.cs @@ -186,6 +186,11 @@ namespace solarApp yield return day; } + public IEnumerable EachHour(DateTime from, DateTime thru) + { + for (var time = from.Date; time.Date <= thru.Date; time = time.AddHours(1)) + yield return time; + } private void bt_Inv_Click(object sender, EventArgs e) { @@ -712,6 +717,33 @@ namespace solarApp lbMsgTitle.Text = System.DateTime.Now.ToString() + " invdayhour - 完成!"; } + private void button3_Click(object sender, EventArgs e) + { + string date1 = dtSelect1.Value.ToString("yyyy-MM-dd"); + string date2 = dtSelect2.Value.ToString("yyyy-MM-dd"); + procArchiveSensorHourly sensorSvc = new procArchiveSensorHourly(); + //單跑一次 + //string t1 = DateTime.Now.AddHours(-1).ToString("yyyy-MM-dd HH"); + //sensorSvc.insertData(lbSiteID_sensor.Text.Substring(0, 9), t1); + //執行期間內每個小時 + foreach (DateTime time in EachHour(DateTime.Parse(date1), DateTime.Parse(date2))) + { + sensorSvc.insertData(lbSiteID_sensor.Text.Substring(0, 9), time.ToString("yyyy-MM-dd HH")); + } + lbMsgTitle.Text = System.DateTime.Now.ToString() + " 完成!"; + + + //跑全站,期間內每個小時 + //var site_list = stationSvc.get_station_list(); + //foreach (var item in site_list) + //{ + // foreach (DateTime time in EachHour(DateTime.Parse(date1), DateTime.Parse(date2))) + // { + // sensorSvc.insertData(lbSiteID_sensor.Text.Substring(0, 9), time.ToString("yyyy-MM-dd HH")); + // } + //} + } + private void btSyncErr_Click(object sender, EventArgs e) {