diff --git a/solarApp/Model/errMain_model.cs b/solarApp/Model/errMain_model.cs new file mode 100644 index 0000000..35f1d60 --- /dev/null +++ b/solarApp/Model/errMain_model.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace solarApp.Model +{ + public class errMain_model + { + public int id { get; set; } + public string site_id { get; set; } + public int timestamp { get; set; } + public string datestamp { get; set; } + public int uuidHash { get; set; } + public string uuid { get; set; } + public string isOpen {get; set;} + public string sourceState { get; set; } + public string ackState { get; set; } + public Int16 ackRequired { get; set; } + public int alarmClass { get; set; } + public int priority { get; set; } + public int normalTime { get; set; } + public int ackTime { get; set; } + public string userAccount { get; set; } + public int alarmTransition { get; set; } + public int lastUpdate { get; set; } + public string errDevice { get; set; } + public string err_valuekind { get; set; } + public string errValue { get; set; } + public string errMsg { get; set; } + public string errCode { get; set; } + public string errDeviceBrand { get; set; } + public string errDeviceModel { get; set; } + } +} diff --git a/solarApp/Service/procSyncError.cs b/solarApp/Service/procSyncError.cs new file mode 100644 index 0000000..b58b48b --- /dev/null +++ b/solarApp/Service/procSyncError.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MySql.Data.MySqlClient; +using Dapper; +using solarApp.Model; +using System.Configuration; + +namespace solarApp.Service +{ + public class procSyncError + { + string Connection1 = string.Empty; + + public procSyncError(string Connection_parame = null) + { + if (!string.IsNullOrEmpty(Connection_parame)) + { + Connection1 = Connection_parame; + } + else + { + Connection1 = ConfigurationManager.ConnectionStrings["mySql"].ConnectionString; + } + } + + public bool syncErrData() + { + bool result = false; + procArchiveLog arclog = new procArchiveLog(); + try + { + using (MySqlConnection conn = new MySqlConnection(Connection1)) + { + DateTime dt_start = DateTime.Now; + conn.Open(); + #region 同步最新狀態 改到 trigger + dt_start = DateTime.Now; + string sql = $@" update`err_main` a join alarmorion_orionalarmrecord b on a.id = b.id set + a.`sourcestate` = b.`sourcestate`, + a.`ackstate` = b.`ackstate`, + a.`priority` = b.`priority`, + a.`normaltime` = b.`normaltime`, + a.`acktime` = b.`acktime`, + a.`lastupdate` = b.`lastupdate` + where a.sourcestate =1 and and a.site_id is not null "; // b.datestamp >= '{ System.DateTime.Now.AddDays(-90).ToString("yyyy-mm-dd")}' ;"; + int rowCount = conn.Execute(sql); + TimeSpan durationSec = DateTime.Now - dt_start; + arclog.insert_log("0", "syncError s2 normaltime", durationSec.TotalSeconds, "orionAlarmRecord", "err_main", "0", "", rowCount.ToString(), conn, null); + + #endregion + + #region 取得 昨天到今天的尚未同步的異常資料 + sql = $@" select * from alarmorion_orionalarmrecord + where id not in (select id from err_main ) + and datestamp >= '{System.DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd")}'"; + var ds = conn.Query(sql).AsList(); + StringBuilder sb = new StringBuilder(); + bool isfirst = true; + foreach (var item in ds) + { + if (isfirst) + { + isfirst = false; + sb.Append(item.id); + } + else { + sb.Append($", {item.id}"); + } + } + #endregion + if (ds.Count > 0) + { + #region 新增異常值 err_main + string sql_header = "INSERT INTO `err_main`(`id`, `timestamp`, `datestamp`, `uuidHash`, `uuid`, `isOpen`, `sourceState`, `ackState`, `ackRequired`, `alarmClass`, `priority`, `normalTime`, `ackTime`, `userAccount`, `alarmTransition`, `lastUpdate`) "; + foreach (var item in ds) + { + sql = sql_header + $@" VALUES ({item.id}, {item.timestamp}, '{item.datestamp}', {item.uuidHash}, {item.uuid}, {item.isOpen}, {item.sourceState} + , {item.ackState}, {item.ackRequired}, {item.alarmClass}, {item.priority}, {item.normalTime}, {item.ackTime} + , '{item.userAccount}', {item.alarmTransition}, {item.lastUpdate}); "; + } + int rowCT = conn.Execute(sql); + TimeSpan duration = DateTime.Now - dt_start; + arclog.insert_log("0", "syncError s1", duration.TotalSeconds, "orionAlarmRecord", "err_main", "0", "", rowCT.ToString(), conn, null); + #endregion + + #region update site_id, inverterID + dt_start = DateTime.Now; + sql = $@"update err_main a join alarmorion_orionalarmfacetvalue b on a.id = b.alarm + set err_valuekind = left(`value`, 1), + errValue = SUBSTRING_INDEX( + SUBSTRING_INDEX(`value`, '@', 1) # @前面所有string --> e:7 + , ':', -1) + where facetName = 4 and alarm in ({sb.ToString()});"; + rowCT = conn.Execute(sql); + duration = DateTime.Now - dt_start; + arclog.insert_log("0", "syncError s3 errValue", duration.TotalSeconds, "facetvalue4", "err_main", "0", "", rowCT.ToString(), conn, null); + #endregion + + + #region update device_id + dt_start = DateTime.Now; + sql = $@"update err_main a join alarmorion_orionalarmfacetvalue b on a.id = b.alarm + set err_valuekind = left(`value`, 1), + errDevice = SUBSTRING_INDEX(SUBSTRING_INDEX(new.`value`, ':', -1) # : 後面所有string + ,'S', -1) + where facetName = 8 and alarm in ({sb.ToString()});"; + rowCT = conn.Execute(sql); + duration = DateTime.Now - dt_start; + arclog.insert_log("0", "syncError s4 errDevice", duration.TotalSeconds, "facetValue8", "err_main", "0", "", rowCT.ToString(), conn, null); + + #endregion + + #region update site_id, 設備廠牌 + dt_start = DateTime.Now; + sql = $@"update err_main a join v_company_inv b on a.errDevice = b.INVERTERID set + site_id = substring(errDevice , 1, 9), + errDeviceBrand = b.brand, + errDeviceModel = b.Model + where errDevice is not null and id in ({sb.ToString()});"; + rowCT = conn.Execute(sql); + duration = DateTime.Now - dt_start; + arclog.insert_log("0", "syncError s5 site_id", duration.TotalSeconds, "v_company_inv", "err_main", "0", "", rowCT.ToString(), conn, null); + #endregion + + #region 更新全部的燈號 + dt_start = DateTime.Now; + sql = $@"drop table temp_healthStatus; + create table temp_healthStatus + select v.siteName, z.* from ( + select ROW_NUMBER() OVER (PARTITION BY site_id ORDER BY HealthStatus desc) row_num, + site_id, alarmID, datestamp, HealthStatus + from ( + select site_id, datestamp, sourceState, id alarmID, + case when alarmClass = 4 then 3 # Network 控制盒斷線 - 紅燈 + when alarmClass != 4 then 2 end HealthStatus # inv, sensor 異常 黃燈 + from err_main + where sourceState = 1 and left(site_id , 1) = '0' + and datestamp > '{ System.DateTime.Now.AddDays(-60).ToString("yyyy-mm-dd")}' + order by HealthStatus desc + limit 100 + ) x + )z join v_station v on z.site_id = v.siteid + where row_num = 1;"; + conn.Execute(sql); + + + sql = $@"update power_station set healthstatus = 1; + update power_station a join temp_healthstatus b on a.code = b.site_id + set a.healthstatus = b.healthstatus;"; + rowCT = conn.Execute(sql); + duration = DateTime.Now - dt_start; + arclog.insert_log("0", "syncError s6 site health", duration.TotalSeconds, "temp_healthstatus", "err_main", "0", "", rowCT.ToString(), conn, null); + + #endregion + + #region 更新 Inverter 燈號 + dt_start = DateTime.Now; + sql = $@"update inv_status set status = 1; + update inv_status a join + ( + select errDevice, 2 errStatus + from err_main -- 有資料 = 異常 + where sourceState = 1 and left(errDevice, 1) = '0' + group by errDevice + )b on a.inverterid = b.errDevice + set status = errStatus;"; + rowCT = conn.Execute(sql); + duration = DateTime.Now - dt_start; + arclog.insert_log("0", "syncError s7 inv health", duration.TotalSeconds, "", "err_main", "0", "", rowCT.ToString(), conn, null); + + #endregion + } + conn.Close(); + } + result = true; + } + catch (Exception ex) + { + throw ex; + } + return result; + } + } +} diff --git a/solarApp/fmArchive.Designer.cs b/solarApp/fmArchive.Designer.cs index 64cdef2..1c0c10e 100644 --- a/solarApp/fmArchive.Designer.cs +++ b/solarApp/fmArchive.Designer.cs @@ -85,7 +85,9 @@ namespace solarApp this.btSendMail = new System.Windows.Forms.Button(); 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.tabControl1.SuspendLayout(); this.tabPage1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); @@ -102,6 +104,7 @@ namespace solarApp this.panel2.SuspendLayout(); this.gbox.SuspendLayout(); this.tabPage3.SuspendLayout(); + this.tabPage4.SuspendLayout(); this.SuspendLayout(); // // tabControl1 @@ -110,6 +113,7 @@ namespace solarApp this.tabControl1.Controls.Add(this.tabPage1); this.tabControl1.Controls.Add(this.tabPage2); this.tabControl1.Controls.Add(this.tabPage3); + this.tabControl1.Controls.Add(this.tabPage4); this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill; this.tabControl1.Location = new System.Drawing.Point(0, 0); this.tabControl1.Name = "tabControl1"; @@ -713,10 +717,31 @@ namespace solarApp this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click_1); // + // tabPage4 + // + this.tabPage4.Controls.Add(this.btSyncErr); + this.tabPage4.Location = new System.Drawing.Point(4, 31); + this.tabPage4.Name = "tabPage4"; + this.tabPage4.Padding = new System.Windows.Forms.Padding(3); + this.tabPage4.Size = new System.Drawing.Size(1774, 918); + this.tabPage4.TabIndex = 3; + this.tabPage4.Text = "tabPage4"; + this.tabPage4.UseVisualStyleBackColor = true; + // // timer1 // this.timer1.Interval = 1000; // + // btSyncErr + // + this.btSyncErr.Location = new System.Drawing.Point(135, 83); + this.btSyncErr.Name = "btSyncErr"; + this.btSyncErr.Size = new System.Drawing.Size(158, 60); + this.btSyncErr.TabIndex = 0; + this.btSyncErr.Text = "同步異常資料"; + this.btSyncErr.UseVisualStyleBackColor = true; + this.btSyncErr.Click += new System.EventHandler(this.btSyncErr_Click); + // // fmArchive // this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 19F); @@ -746,6 +771,7 @@ namespace solarApp this.gbox.ResumeLayout(false); this.gbox.PerformLayout(); this.tabPage3.ResumeLayout(false); + this.tabPage4.ResumeLayout(false); this.ResumeLayout(false); } @@ -807,5 +833,7 @@ namespace solarApp private System.Windows.Forms.Button button2; private System.Windows.Forms.Label label2; private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.TabPage tabPage4; + private System.Windows.Forms.Button btSyncErr; } } \ No newline at end of file diff --git a/solarApp/fmArchive.cs b/solarApp/fmArchive.cs index 173ff09..a5f41a2 100644 --- a/solarApp/fmArchive.cs +++ b/solarApp/fmArchive.cs @@ -701,6 +701,12 @@ namespace solarApp lbMsgTitle.Text = System.DateTime.Now.ToString() + " invdayhour - 完成!"; } + private void btSyncErr_Click(object sender, EventArgs e) + { + procSyncError svc = new procSyncError(); + svc.syncErrData(); + } + //test for email format //private void button3_Click(object sender, EventArgs e) //{ diff --git a/solarApp/fmArchive.resx b/solarApp/fmArchive.resx index d731088..85e6494 100644 --- a/solarApp/fmArchive.resx +++ b/solarApp/fmArchive.resx @@ -60,4 +60,7 @@ 17, 17 + + 35 + \ No newline at end of file diff --git a/solarApp/sqlDoc/trigger-2022-08-15-decodev1.sql b/solarApp/sqlDoc/trigger-2022-08-15-decodev1.sql index a1033b8..ed64af6 100644 --- a/solarApp/sqlDoc/trigger-2022-08-15-decodev1.sql +++ b/solarApp/sqlDoc/trigger-2022-08-15-decodev1.sql @@ -1,12 +1,9 @@ -# 0816 trigger OK - + --- 刪除 trigger drop trigger tt_insert_record; -drop trigger tt_update_record; # error +drop trigger tt_update_record; # udpate record drop trigger tt_before_facetvalue; -drop trigger tt_insert_faceValue; - - - +drop trigger tt_insert_faceValue; # facetvalue + ---1 --- trigger 建立-------------------------- @@ -22,13 +19,12 @@ DELIMITER $$ end$$ DELIMITER ; ----2 -------------------------------------------- - DROP TRIGGER IF EXISTS tt_update_record; - DELIMITER $$ - create trigger tt_update_record - after update on alarmorion_orionalarmrecord - FOR EACH ROW - begin +---2 -------------------------------------------- + DELIMITER $$ + create trigger tt_update_record + after update on alarmorion_orionalarmrecord + FOR EACH ROW + begin DECLARE _siteID varchar(20); DECLARE _devID varchar(20); UPDATE`err_main` SET `timestamp` = new.`timestamp`, `datestamp` = new.`datestamp`, `uuidHash` = new.`uuidHash`, `uuid` = new.`uuid`, `isOpen` = new.`isOpen`, `sourceState` = new.`sourceState`, `ackState` = new.`ackState`, @@ -47,78 +43,33 @@ DELIMITER $$ # 燈號 HealthStatus: 1:設備正常 Green, 2.設備異常 Yellow , 3:設備斷線 Red # update 主表燈號 --------------- 主要作為恢復使用 ---------------------------- - #select site_id into _siteID from err_main where id = new.`id`; --- select SUBSTRING_INDEX(SUBSTRING_INDEX(new.`value`, ':', -1) # : 後面所有string --- ,'S', -1) into _devID; # S 後面所有string --- from alarmorion_orionalarmfacetvalue a --- where a.alarm = new.`id` and a.facetName = 8; - - select SUBSTRING_INDEX(a.`value`,'S', -1) into _devID - from alarmorion_orionalarmfacetvalue a - where a.alarm = new.`id` and a.facetName = 8; + select site_id into _siteID from err_main where id = new.`id`; - set _siteID = substring(_devID , 1, 9); --- select substring(SUBSTRING_INDEX(a.errmsg,'S', -1) , --- 1, 9) into _siteID --- from alarmorion_orionalarmfacetvalue a --- where a.alarm = new.`id` and a.facetName = 8; - - IF(_siteID is not null) THEN - # 看看是否有舊有的其他異常 - update power_station a join ( - select a.id, sourceState, alarmClass, normalTime, site_id, - case when (sourceState = 1 and alarmClass = 4) then 3 # Network 控制盒斷線 - 紅燈 - when (sourceState = 1 and alarmClass != 4) then 2 # inv, sensor 異常 黃燈 - when sourceState = 0 then 1 end healthStatus - #, FROM_UNIXTIME(TIMESTAMP/1000, '%Y-%m-%d %H:%i:%s') time1 - from alarmorion_orionalarmrecord a - join ( - select id, alarm, substring( - errmsg - , 2, 9) site_id - from alarmorion_orionalarmfacetvalue - where facetName = 8 and substring( errmsg , 2, 9) = _siteID - order by 1 desc limit 100 - ) b on a.id = b.alarm - where sourcestate = 1 # a.id = 185966 #185954 - order by healthStatus desc limit 1 - )b on a.code = b.site_id + IF(_siteID is not null) THEN + update power_station a join ( + select site_id, case when (sourceState = 1 and alarmClass = 4) then 3 # Network 控制盒斷線 - 紅燈 + when (sourceState = 1 and alarmClass != 4) then 2 # inv, sensor 異常 黃燈 + when sourceState = 0 then 1 end healthStatus + from err_main + where site_id = _siteID + group by site_id, alarmClass, sourceState + order by 2 desc # 以燈號嚴重性為主要顯示 + limit 1 + ) b on a.`code` = b.`site_id` set a.HealthStatus = b.healthStatus; - - -- update power_station a join ( - -- select site_id, case when (sourceState = 1 and alarmClass = 4) then 3 # Network 控制盒斷線 - 紅燈 - -- when (sourceState = 1 and alarmClass != 4) then 2 # inv, sensor 異常 黃燈 - -- when sourceState = 0 then 1 end healthStatus - -- from err_main - -- where site_id = _siteID - -- group by site_id, alarmClass, sourceState - -- order by 2 desc # 以燈號嚴重性為主要顯示 - -- limit 1 - -- ) b on a.`code` = b.`site_id` - -- set a.HealthStatus = b.healthStatus; - end if; - - # log - INSERT INTO `log_trigger`(`site_id`, `device_id`, `HealthStatus`, alarm_id, `triggerFrom`) - VALUES ( _siteID, _devID, case new.sourceState when 1 then 2 # # Network 控制盒斷線 - 紅燈 - when 0 then 1 end , - new.id, 'record'); + end if; + #end; + # update 紅綠燈 for Inverter - update inv_status set + update inv_status set `status` = case new.sourceState when 1 then 2 # 異常黃燈 when 0 then 1 end # 異常復歸 where inverterid = _devID; --- IF (NEW.alarmClass = 1 ) THEN # alarmclass = 1 Inverter --- #取出設備 ID --- update inv_status set --- `status` = case new.sourceState when 1 then 2 # 異常黃燈 --- when 0 then 1 end # 異常復歸 --- where inverterid = _devID; --- --- end if; + end$$ DELIMITER ; ----- 3 ------------------------------------------------------------ + +----------3 ------------------------------------------------------ DROP TRIGGER IF EXISTS tt_before_facetvalue; DELIMITER $$ create trigger tt_before_facetvalue @@ -127,17 +78,21 @@ DELIMITER $$ begin set new.errmsg = unicode_decode(new.`value`); + IF (NEW.facetName = 8) THEN # 8 異常設備 + set new.device_id = SUBSTRING_INDEX(new.`value`,'S', -1); + set new.site_id = substring(new.device_id , 1, 9); + end if; end$$ DELIMITER ; ---4 ------------------------------------------------------------- - DROP TRIGGER IF EXISTS tt_insert_faceValue; - DELIMITER $$ - create trigger tt_insert_faceValue - after insert on alarmorion_orionalarmfacetvalue - FOR EACH ROW - begin +DROP TRIGGER IF EXISTS tt_insert_faceValue; +DELIMITER $$ +create trigger tt_insert_faceValue +after insert on alarmorion_orionalarmfacetvalue +FOR EACH ROW +begin # 022020001 s:S022020001010011 --> 022020001010011 DECLARE _siteID varchar(20); DECLARE _devID varchar(20); DECLARE _msg varchar(30); @@ -176,9 +131,66 @@ DELIMITER $$ where inverterid = _devID ; #log 8 - INSERT INTO `log_trigger`(`site_id`, `device_id`, `HealthStatus`, alarm_id, `triggerFrom`) - VALUES ( _siteID, _devID, null, new.`alarm`, 'facetvalue8'); +-- INSERT INTO `log_trigger`(`site_id`, `device_id`, `HealthStatus`, alarm_id, `triggerFrom`) +-- VALUES ( _siteID, _devID, null, new.`alarm`, 'facetvalue8'); end if; end$$ -DELIMITER ; +DELIMITER; + + + + +------------------------------------------------------------------------------ + + +DROP FUNCTION IF EXISTS unicode_decode; +DELIMITER $$ +CREATE FUNCTION unicode_decode(content text) +RETURNS text +BEGIN + DECLARE code1,code2 varchar(20); + DECLARE n_index,s_index smallint unsigned default 0; + DECLARE result,tmp_txt text; + DECLARE temp varchar(1); + SET s_index=LOCATE('$u', content,1); + set result =''; + while s_index>0 DO + set code1 = conv(substring(content,s_index+2,2),16,10); + set code2 = conv(substring(content,s_index+4,2),16,10); + set temp = convert(char(code1,code2) USING 'ucs2'); + set tmp_txt = substring(content,n_index+1,s_index - (n_index+1)); + set result = concat(result,tmp_txt,temp); + set n_index = s_index+5; + set s_index = LOCATE("$u", content, s_index+1); + END while ; + set tmp_txt = substring(content,n_index+1); + set result = concat(result,tmp_txt); + RETURN result; +END $$ + + + +DROP FUNCTION IF EXISTS unicodeNum_decode; +DELIMITER $$ +CREATE FUNCTION unicodeNum_decode(content text) +RETURNS text +begin +-- DECLARE i INT DEFAULT 1; +-- DECLARE v_char VARCHAR(1); + DECLARE result VARCHAR(255) DEFAULT ''; +-- +-- WHILE (i <= LENGTH(content) ) DO +-- +-- SET v_char = SUBSTR(content,i,1); +-- IF v_char REGEXP '^[A-Za-z0-9 ]+$' THEN #alphanumeric +-- +-- SET v_parseStr = CONCAT(v_parseStr,v_char); +-- +-- END IF; +-- SET i = i + 1; +-- END WHILE; +select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace( + SUBSTRING_INDEX(content, ':', -1) ,'$20',' '),'$2d','-'),'$2f','/'),'$28','('),'$29',')'),'$7b','{'), '$7d','}'),'$25','%'),'$40','@'),'$2e','.'),'$3a',':') into result; + RETURN trim(result); +END \ No newline at end of file