using ConnectionUtil; using HMI.AlarmInfoManage.Entity; using HMI.Base; using HMI.Core.Api; using HMI.Core.Setting; using HMI.Core.Util; using HMI.UI.Util; using HMI.Util; using Microsoft.Win32; using OPCConnection; using Sharp7; using SimensDriver; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.IO; using System.Linq; using System.Timers; using System.Windows; using System.Windows.Controls; namespace HMI.AlarmInfoManage { /// /// UserControl1.xaml 的交互逻辑 /// public partial class AlarmInfoManage : PluginControl { private string blockPath; private string markPath; private string alarmTextPath; private string opcIP = "127.0.0.1"; private int opcPort = 6543; private int localPort = 18888; private volatile bool isClosing = false; private string dbPath; private Simens plc = new Simens(); private bool isHaveAlarm; private bool isNewAlarm; private SqliteHelper sqliteHelper; private Timer MonitorTimer; private Timer PcTimer; /// /// pc警告数字信号 /// private int isPcAlarmnumber = 0; /// /// 当前报警信息 /// private string currentInfo = null; /// /// 接收报警的队列 /// private MSMQHelper alarmQueue = new MSMQHelper("HMI_Alarm"); /// /// 日志生成器 /// private MSMQHelper loggeralarm = new MSMQHelper("LTHMI_Logger"); /// /// 刷新报警的队列 /// private MSMQHelper alarmRefershToMain = new MSMQHelper("LTHMI_Alarm_Rrfresh"); private SCADAApi lTSCADAApi = new OPCClient(); /// /// 报警 /// private byte[] alarmCodeBytes; /// /// 报警信息缓存 /// private List currentAlarmCachePlc = new List(); /// /// PLC报警信息缓存 /// private List preAlarmCachePlc = new List(); /// /// 报警信息缓存 /// private List currentAlarmCachePc = new List(); /// /// 代码管理 /// private ObservableCollection alarmSettings = new ObservableCollection(); // /// 标志位报警管理 /// private ObservableCollection markAlarmSetting = new ObservableCollection(); /// /// 传至主窗体的报警信息 /// private List currentAlarmCachePlcToMain = new List(); private AlarmText alarm; private SystemSetting systemSetting; private ObservableCollection datasource = new ObservableCollection(); public ObservableCollection Datasource { get { return datasource; } set { Set(ref datasource, value); } } /// /// 报警文本列表 /// private ObservableCollection alarmTexts = new ObservableCollection(); public ObservableCollection AlarmTexts { get { return alarmTexts; } set { Set(ref alarmTexts, value); } } public Dictionary textMap = new Dictionary(); private double size = 30; private int currentPage = 0; public int CurrentPage { get => currentPage; set { Set(ref currentPage, value); RefreshData(); } } private int maxPage = 0; public int MaxPage { get => maxPage; set { Set(ref maxPage, value); } } public AlarmInfoManage() { DataContext = this; systemSetting = SystemSetting.Instance; InitializeComponent(); } public override void SetBaseFolder(string folder) { base.SetBaseFolder(folder); dbPath = Path.Combine(BaseFolder, "alarm.db"); alarmTextPath = Path.Combine(BaseFolder, "AlarmText.data"); blockPath = Path.Combine(BaseFolder, "BlockSetting.xml"); markPath = Path.Combine(BaseFolder, "MarkSetting.xml"); } public override void InitFinish() { if (!File.Exists(dbPath)) { SqliteHelper.CreateDatabase(dbPath); } sqliteHelper = new SqliteHelper(dbPath); sqliteHelper.ExecuteSql(@"CREATE TABLE IF NOT EXISTS Alarm ( id INTEGER PRIMARY KEY AUTOINCREMENT, source TEXT NOT NULL, alarmcode TEXT, alarminfo TEXT, time DATETIME);"); LoadAlarmSetting(); LoadAlarmText(); MonitorTimer = new Timer { Interval = 100, }; MonitorTimer.Elapsed += MonitorTimer_Elapsed; if (!lTSCADAApi.Connect2(opcIP, opcPort, localPort, out string errMsg)) { //MsgBoxHelper.Error(this, errMsg); } else { this.MonitorTimer.Start(); } PcTimer = new Timer { Interval = 100, AutoReset = false }; PcTimer.Elapsed += PcTimer_Elapsed; PcTimer.Enabled = true; } public override void DoClose(object sender, EventArgs e) { isClosing = true; PcTimer.Enabled = false; PcTimer?.Dispose(); MonitorTimer.Enabled = false; MonitorTimer?.Dispose(); } private void Button_Click(object sender, RoutedEventArgs e) { Button btn = sender as Button; switch (btn.Name) { case "settingBtn": OpenSettingWindow(); break; case "refreshBtn": LoadAlarmText(); RefreshPage(CurrentPage); break; case "importBtn": ImportText(); break; default: break; } } private void OpenSettingWindow() { AlarmSettingList listModal = new AlarmSettingList(blockPath, markPath,alarmSettings,markAlarmSetting, log) { Owner = Window.GetWindow(this) }; listModal.ShowDialog(); alarmSettings = listModal.Datasource; markAlarmSetting = listModal.MarkDatasource; } private void RefreshPage(int? page = null) { var sql = "SELECT COUNT (*) as num FROM Alarm;"; var dt = sqliteHelper.GetDataTable(sql); if (dt.Rows.Count <= 0) { CurrentPage = 1; MaxPage = 1; return; } int count = int.Parse(dt.Rows[0]["num"].ToString()); MaxPage = (int)Math.Ceiling(count / size); if (page != null) { CurrentPage = page.Value; } else if (CurrentPage > MaxPage) { CurrentPage = MaxPage; } } private void RefreshData() { var list = new ObservableCollection(); var sql = $"SELECT source, alarmcode, alarminfo, time FROM Alarm ORDER BY time DESC LIMIT ({CurrentPage - 1} * {size}), {size};"; var dt = sqliteHelper.GetDataTable(sql); if (dt.Rows.Count > 0) { foreach (DataRow dr in dt.Rows) { var at = new AlarmText { Source = dr["source"].ToString(), AlarmCode = dr["alarmcode"].ToString(), AlarmInfo = dr["alarminfo"].ToString(), Time = dr["time"].ToString(), }; list.Add(at); } } Datasource = list; } private void ImportText() { try { OpenFileDialog openDialog = new OpenFileDialog(); openDialog.Filter = "Files (*.xlsm)|*.xlsm"; if (openDialog.ShowDialog() == true) { this.ImportExcelAlarmText(openDialog.FileName); } } catch (Exception ex) { log.Error("AlarmText Import Failed.", ex); ToastHelper.Error(Window.GetWindow(this), $"{this.lang("App.ImportFailed")}: {ex.Message}"); } } /// /// 导入报警代码文本 /// /// 电子设计表格文件 //private void ImportExcelAlarmText(string excelFile) //{ // int index = 0; // try // { // if (excelFile.IndexOf(".xlsm") < 0) // { // this.Warning(this.lang("Alm.OnlySupportXlsm")); // return; // } // this.alarmTexts.Clear(); // XSSFWorkbook workbook = new XSSFWorkbook(excelFile); // XSSFSheet sheet = (XSSFSheet)workbook.GetSheet("sheet1"); // XSSFRow row = null; // for (int i = 2; i < (sheet.LastRowNum + 1); i++) // { // index = i; // row = (XSSFRow)sheet.GetRow(i); // if (row != null) // { // AlarmText alarm = new AlarmText(); // alarm.AlarmCode = row.Cells[0].StringCellValue; // alarm.OpNo = row.Cells[1].StringCellValue; // alarm.ModuleNo = row.Cells[2].StringCellValue; // alarm.ModuleName_CN = row.Cells[3].StringCellValue; // alarm.ModuleName_EN = row.Cells[4].StringCellValue; // alarm.MAlarmCode = row.Cells[5].StringCellValue; // alarm.MAlarmText_CN = row.Cells[6].StringCellValue; // alarm.MAlarmText_EN = row.Cells[7].StringCellValue; // this.alarmTexts.Add(alarm); // } // } // if (sheet.LastRowNum > 0) // { // XmlHelper.SerializeToXml(textSettingPath, this.alarmTexts); // } // this.Success(this.lang("App.ImportSuccess")); // } // catch (Exception ex) // { // log.Error($"Row {index} AlarmText Import Failed.", ex); // this.Error($"{this.lang("Alm.RowImportFailed", index)}: {ex.Message}"); // } //} /// /// 导入报警代码文本 /// /// 电子设计表格文件 private void ImportExcelAlarmText(string excelFile) { int index = 0; try { if (excelFile.IndexOf(".xlsm") < 0) { this.Warning(this.lang("Alm.OnlySupportXlsm")); return; } this.alarmTexts = new ObservableCollection (ExcelHelper.ReadFromExcel(excelFile)); if (alarmTexts.Count > 0) { XmlHelper.SerializeToXml(alarmTextPath, this.alarmTexts); } LoadAlarmText(); this.Success(this.lang("App.ImportSuccess")); } catch (Exception ex) { log.Error($"Row {index} AlarmText Import Failed.", ex); this.Error($"{this.lang("Alm.RowImportFailed", index)}: {ex.Message}"); } } private void LoadAlarmText() { try { textMap.Clear(); AlarmTexts = XmlHelper.DeserializeFromXml>(alarmTextPath); foreach (var text in AlarmTexts) { textMap[text.AlarmCode] = text; } } catch (Exception ex) { log.Error("LoadAlarmText Error.", ex); AlarmTexts = new ObservableCollection(); } } private void LoadAlarmSetting() { try { alarmSettings = XmlHelper.DeserializeFromXml>(blockPath); } catch (Exception ex) { log.Error("LoadAlarmSetting Error.", ex); alarmSettings = new ObservableCollection(); } try { markAlarmSetting = XmlHelper.DeserializeFromXml>(markPath); } catch (Exception ex) { log.Error("LoadAlarmText Error.", ex); markAlarmSetting = new ObservableCollection(); } } private void UserControl_Loaded(object sender, RoutedEventArgs e) { //if (!string.IsNullOrEmpty(systemSetting.PlcIp)) //{ // if (this.plc.isConnection) // { // this.plc.Simens_S7_ConnectPLC(systemSetting.PlcIp, 102, 0, 1, string.Empty); // } //} RefreshPage(1); Loaded -= UserControl_Loaded; } private void PcTimer_Elapsed(object sender, ElapsedEventArgs e) { try { PcTimer.Enabled = false; this.alarmQueue.Receive(100, out string MessageID, out string MsgStr); if (MessageID != string.Empty) { switch (MessageID) { case "Clear": this.currentAlarmCachePc.Clear(); this.RefershAlarm(); break; case "AlarmCode": AlarmText aalarm = AlarmTexts.FirstOrDefault(alarm => alarm.AlarmCode == MsgStr); if (aalarm == null) break; var data = new AlarmText { Source = "PC", AlarmCode = aalarm.AlarmCode, AlarmInfo = aalarm.MAlarmText_CN, Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }; //aalarm.Source = "PC"; //aalarm.Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") if (this.currentAlarmCachePc.Find(alarm => alarm.AlarmCode == aalarm.AlarmCode) == null) { this.currentAlarmCachePc.Add(data); this.RefershAlarm(); this.isPcAlarmnumber = this.currentAlarmCachePc.Count; } break; default: string[] arr = MsgStr.Split(','); string source = "PC"; string info = string.Empty; if (arr.Length > 1) { source = arr[0]; info = arr[1]; } else { info = MsgStr; } AlarmText newAlarm = new AlarmText { Source = source, AlarmInfo = info, Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }; if (this.currentAlarmCachePc .Find(alarm => alarm.Source == newAlarm.Source && alarm.AlarmInfo == newAlarm.AlarmInfo) == null) { this.currentAlarmCachePc.Add(newAlarm); this.RefershAlarm(); this.isPcAlarmnumber = this.currentAlarmCachePc.Count; } break; } } } catch (Exception ex) { log.Error("PcTimer Execute Failed", ex); } finally { if (!isClosing) PcTimer.Enabled = true; } } //private void MonitorTimer_Elapsed_bak(object sender, ElapsedEventArgs e) //{ // try // { // this.MonitorTimer.Enabled = false; // isHaveAlarm = false; // foreach (var item in signAlarmSetting) // { // //isHaveAlarm = isHaveAlarm || // // this.plc.Simens_S7_ReadBool_DB(item.DBAddress, item.StartAddress, item.Length); // } // ////有报警 // if (isHaveAlarm) // { // this.isNewAlarm = false; // this.currentAlarmCachePlc.Clear(); // RefreshDBSetting(); // for (int i = 0; i < ((int)alarmCodeBytes.Length / 4); i++) // { // int code = S7.GetDIntAt(alarmCodeBytes, 4 * i); // ////有报警 // if (code != 0) // { // string acode = string.Format("{0:d10}", code); // alarm = AlarmTexts.FirstOrDefault(item => item.AlarmCode == acode); // if (alarm != null) // { // alarm.Source = "PLC"; // alarm.Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); // this.currentAlarmCachePlc.Add(alarm); // ////有新报警 // if (this.preAlarmCachePlc.Find(alarm => alarm.AlarmCode == acode) == null) // { // this.isNewAlarm = true; // this.SendLogMsg(alarm.ModuleName_CN + alarm.MAlarmText_CN); // } // } // } // } // ////有新报警和报警减少时刷新报警表 // if (this.isNewAlarm || (this.currentAlarmCachePlc.Count != this.preAlarmCachePlc.Count)) // { // this.currentAlarmCachePlcToMain = XmlHelper.DeepClone(this.currentAlarmCachePlc); // this.RefershAlarm(); // } // this.preAlarmCachePlc.Clear(); // this.preAlarmCachePlc = XmlHelper.DeepClone(this.currentAlarmCachePlc); // } // else // { // if (this.preAlarmCachePlc.Count != 0 || this.currentAlarmCachePlcToMain.Count != 0 || this.currentAlarmCachePlc.Count != 0) // { // this.preAlarmCachePlc.Clear(); // this.currentAlarmCachePlcToMain.Clear(); // this.currentAlarmCachePlc.Clear(); // this.RefershAlarm(); // } // } // } // catch (Exception ex) // { // log.Error("sdadsa", ex); // } // finally // { // this.MonitorTimer.Enabled = true; // } //} private void MonitorTimer_Elapsed(object sender, ElapsedEventArgs e) { try { this.MonitorTimer.Enabled = false; if (!lTSCADAApi.IsConnected(out string errMsg)) { log.Warn($"OPCServer Connection Error. {errMsg}"); if (!lTSCADAApi.Connect2(opcIP, opcPort, localPort, out errMsg)) { log.Warn($"OPCServer Try ReConnection Error. {errMsg}"); return; } } isHaveAlarm = false; List cache = new List(); foreach (var item in alarmSettings) { var name = $"{item.DBAddress}.{item.StartAddress}"; if (lTSCADAApi.DoFctReadSingle(name, out string alarmCode, out errMsg) && alarmCode != "0") { isHaveAlarm = true; if (!textMap.TryGetValue(alarmCode, out alarm)) { continue; } var newAlarm = new AlarmText { Source = "PLC", AlarmCode = alarm.AlarmCode, ModuleName_CN = alarm.ModuleName_CN, MAlarmText_CN = alarm.MAlarmText_CN, Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), AlarmInfo = $"{alarm.ModuleName_CN} {alarm.MAlarmText_CN}" }; if (this.currentAlarmCachePlc .Find(alarm => alarm.AlarmCode == newAlarm.AlarmCode) == null) { this.currentAlarmCachePlc.Add(newAlarm); } } } foreach (var item in markAlarmSetting) { var name = $"{item.DBAddress}.{item.StartAddress}"; if (lTSCADAApi.DoFctReadSingle(name, out string alarmCode, out errMsg) && alarmCode != "0") { isHaveAlarm = true; var newAlarm = new AlarmText { Source = "PLC", AlarmCode = alarmCode, Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), AlarmInfo = item.Description }; if (this.currentAlarmCachePlc .Find(d => d.AlarmInfo == newAlarm.AlarmInfo) == null) { this.currentAlarmCachePlc.Add(newAlarm); } } } this.RefershAlarm(); this.isPcAlarmnumber = this.currentAlarmCachePc.Count; if (!isHaveAlarm) currentAlarmCachePlc.Clear(); } catch (Exception ex) { log.Error("Read OPCServer Data Error.", ex); } finally { if(!isClosing) this.MonitorTimer.Enabled = true; } } /// /// 刷新报警块信息 /// private void RefreshDBSetting() { List bytes = new List(); foreach (var item in alarmSettings) { //byte[] itemalarmCodeBytes = this.plc.Simens_S7_ReadBytes_DB("DB", item.DBAddress, item.StartAddress, item.Length); //bytes.AddRange(itemalarmCodeBytes.ToList()); } alarmCodeBytes = bytes.ToArray(); } /// /// 刷新报警信息 /// private void RefershAlarm() { this.alarmRefershToMain.Send("AlarmRefersh", string.Empty); foreach (AlarmText alarm in this.currentAlarmCachePlc) { var currentInfo = alarm.AlarmInfo; string sqladd = string.Format("INSERT INTO Alarm (source, alarmcode, alarminfo, time) VALUES('{0}','{1}','{2}','{3}');", alarm.Source, alarm.AlarmCode, currentInfo, alarm.Time); if (AlarmShowHelper.ShowAlarm(currentInfo)) { sqliteHelper.ExecuteSql(sqladd); } } //this.currentAlarmCachePlc.Clear(); foreach (AlarmText alarm in this.currentAlarmCachePc) { string sqladd2 = string.Format("INSERT INTO Alarm (source, alarmcode, alarminfo, time) VALUES('{0}','{1}','{2}','{3}');", alarm.Source, alarm.AlarmCode, alarm.AlarmInfo, alarm.Time); if (AlarmShowHelper.ShowAlarm(alarm.AlarmInfo)) { sqliteHelper.ExecuteSql(sqladd2); } } this.currentAlarmCachePc.Clear(); } /// /// 发送日志消息 /// /// 日志消息 private void SendLogMsg(string Msg) { string LogMsg = "{\"Type\":\"Alarm\",\"Source\":\"" + alarm.Source + "\",\"Msg\":\"" + Msg + "\",\"Time\":\"" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\"}"; this.loggeralarm.Send("Log", LogMsg); } } }