using HMI.Base; using HMI.Core.Setting; using HMI.Core.Util; using HMI.IOMonitor.Entity; using HMI.UI.Util; using Microsoft.Win32; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; using System.Timers; using System.Windows; using System.Windows.Controls; using System.Windows.Data; namespace HMI.IOMonitor { /// /// UserControl1.xaml 的交互逻辑 /// public partial class IOMonitor : PluginControl { public string SettingFilePath { get; private set; } public string DataFilePath { get; private set; } /// /// DIO地址 /// private string DITag = string.Empty; private string DQTag = string.Empty; private SystemSetting systemSetting; private Timer MonitorTimer; private OpcInterface.OpcInterface lTSCADAApi = new OpcInterface.OpcInterface(); /// /// The diosde 反序列化的DIO对象 /// private List diosde = new List(); /// The dis /// DI口对象 /// private ObservableCollection _dis = new ObservableCollection(); public ObservableCollection Dis { get => _dis; set { Set(ref _dis, value); } } private ObservableCollection _dos = new ObservableCollection(); public ObservableCollection Dos { get => _dos; set { Set(ref _dos, value); } } private ObservableCollection iPManages = new ObservableCollection(); public ObservableCollection IPManages { get { return iPManages; } set { Set(ref iPManages, value); } } public IOMonitor() { systemSetting = SystemSetting.Instance; MonitorTimer = new Timer() { Interval = 100 }; MonitorTimer.Elapsed += MonitorTimer_Elapsed; DataContext = this; InitializeComponent(); } private void MonitorTimer_Elapsed(object sender, ElapsedEventArgs e) { MonitorTimer.Enabled = false; try { // stopwatch.Start(); if (lTSCADAApi.DoFctReadSingle(DITag, out string resulti, out string errMsgi)) { byte[] stri = HexUtil.ToBytesFromHexString(resulti); Array.Reverse(stri); if (stri != null) { for (int i = 0; i < Dis.Count; i++) { Dis[i].Value = Convert.ToBoolean(GetValue(stri, "bool", Dis[i].DIO_No.ToString())); } } } if (lTSCADAApi.DoFctReadSingle(DQTag, out string resulto, out string errMsgo)) { byte[] stro = HexUtil.ToBytesFromHexString(resulto); if (stro != null) { for (int i = 0; i < Dos.Count; i++) { Dos[i].Value = Convert.ToBoolean(GetValue(stro, "bool", Dos[i].DIO_No.ToString())); } } } //stopwatch.Stop(); } catch (Exception ex) { log.Warn("MonitorTimer_Elapsed Execute Failed.", ex); MonitorTimer.Enabled = true; return; } finally { this.MonitorTimer.Enabled = true; } } /// /// 初始化方法 /// private void LoadData() { diosde.Clear(); //Dis.Clear(); //Dos.Clear(); diName.Items.Clear(); doName.Items.Clear(); diGroup.Items.Clear(); doGroup.Items.Clear(); try { this.diosde = XmlHelper.DeserializeFromXml>(DataFilePath); } catch (Exception ex) { MsgBoxHelper.Error(this, ex.Message); } if (diosde.Count != 0) { for (int i = 0; i < diosde.Count; i++) { switch (diosde[i].DIOType) { case "I": Dis.Add(diosde[i]); break; case "Q": Dos.Add(diosde[i]); break; case "X": Dis.Add(diosde[i]); break; case "Y": Dos.Add(diosde[i]); break; default: break; } } Dis = new ObservableCollection(Dis.OrderByDescending(t => t.DIO_No).ToList()); Dos = new ObservableCollection(Dos.OrderByDescending(t => t.DIO_No).ToList()); List listnew1 = new List(); foreach (var item in Dis) { listnew1.Add(item.Name); } diName.ItemsSource = listnew1; List listnew2 = new List(); foreach (var item in Dos) { listnew2.Add(item.Name); } doName.ItemsSource = listnew2; List listDis = new List(); int digroupmax = int.Parse(Dis[0].DIO_No.ToString().Split('.')[0]); switch (digroupmax % 2) { case 1: for (int i = 0; i < digroupmax; i++) { listDis.Add(i.ToString() + @".&" + (i + 1).ToString() + "."); } break; case 0: if (digroupmax >= 0) { for (int i = 0; i < (digroupmax - 1); i++) { listDis.Add(i.ToString() + @".&" + (i + 1).ToString() + "."); } listDis.Add(digroupmax.ToString() + "."); } break; default: break; } int dogroupmax = int.Parse(Dos[0].DIO_No.ToString().Split('.')[0]); diGroup.ItemsSource = listDis; List listDos = new List(); switch (dogroupmax % 2) { case 1: for (int i = 0; i < dogroupmax; i++) { listDos.Add(i.ToString() + @".&" + (i + 1).ToString() + "."); } break; case 0: if (dogroupmax >= 0) { for (int i = 0; i < (dogroupmax - 1); i++) { listDos.Add(i.ToString() + @".&" + (i + 1).ToString() + "."); } listDos.Add(dogroupmax.ToString() + "."); } break; default: break; } doGroup.ItemsSource = listDos; diCode.ItemsSource = Dis; doCode.ItemsSource = Dos; } else { // } } private void UserControl_Loaded(object sender, RoutedEventArgs e) { LoadData(); Loaded -= UserControl_Loaded; } private void Button_Click(object sender, RoutedEventArgs e) { Button btn = sender as Button; switch (btn.Name) { case "addBtn": OpenAddModal(); break; case "importBtn": ImportFromExcel(); break; case "diSelect": CollectionViewSource disFilter = this.Resources["disFilter"] as CollectionViewSource; disFilter?.View.Refresh(); break; case "diReset": ResetInput("di"); break; case "doSelect": CollectionViewSource dosFilter = this.Resources["dosFilter"] as CollectionViewSource; dosFilter?.View.Refresh(); break; case "doReset": ResetInput("do"); break; default: break; } } private void OpenAddModal() { IPManageModal modal = new IPManageModal(log) { Title = "新增", Owner = Window.GetWindow(this), }; if (modal.Open(-1, new IPManage(), IPManages, SettingFilePath) == true) { this.Success("新增成功"); } } private void ImportFromExcel() { IWorkbook workbook = null; OpenFileDialog dialog = new OpenFileDialog(); ////该值确定是否可以选择多个文件 dialog.Multiselect = false; dialog.Title = "请选择文件"; dialog.Filter = "execl文件(*.xlsx;*.xls)|*.xlsx;*.xls"; if (dialog.ShowDialog() == true) { MonitorTimer.Enabled = false; string file = dialog.FileName; try { FileStream fileStream1 = new FileStream(@file, FileMode.Open, FileAccess.Read); if (file.IndexOf(".xlsx") >= 0) { workbook = new XSSFWorkbook(fileStream1); } else if (file.IndexOf(".xls") >= 0) { workbook = new HSSFWorkbook(fileStream1); } ISheet sheet = workbook.GetSheetAt(0); List dios1 = new List(); IRow row; for (int i = 1; i < (sheet.LastRowNum + 1); i++) { DIO[] dIO = new DIO[sheet.LastRowNum]; row = sheet.GetRow(i); DIO diotest = new DIO(); if (row != null) { dIO[i - 1] = new DIO(); dIO[i - 1].Name = row.GetCell(4).ToString(); dIO[i - 1].No = row.GetCell(3).ToString(); dIO[i - 1].Value = false; dIO[i - 1].DIO_No = Convert.ToDecimal(dIO[i - 1].No.Substring(2)); if (row.GetCell(3).ToString().IndexOf("I") >= 0) { dIO[i - 1].DIOType = "I"; } else if (row.GetCell(3).ToString().IndexOf("Q") >= 0) { dIO[i - 1].DIOType = "Q"; } else if (row.GetCell(3).ToString().IndexOf("X") >= 0) { dIO[i - 1].DIOType = "X"; } else if (row.GetCell(3).ToString().IndexOf("Y") >= 0) { dIO[i - 1].DIOType = "Y"; } dios1.Add(dIO[i - 1]); } } fileStream1.Close(); workbook.Close(); XmlHelper.SerializeToXml(SettingFilePath, dios1); lock (this) { MonitorTimer.Stop(); LoadData(); } } catch (Exception ex) { log.Error("Import Failed.", ex); MsgBoxHelper.Error(this, $"导入失败!{ex.Message}"); } } } private void ResetInput(string flag) { if (flag == "di") { diName.Text = ""; diCode.Text = ""; diGroup.Text = ""; CollectionViewSource source = this.Resources["disFilter"] as CollectionViewSource; source?.View.Refresh(); } else { doName.Text = ""; doCode.Text = ""; doGroup.Text = ""; CollectionViewSource source = this.Resources["dosFilter"] as CollectionViewSource; source?.View.Refresh(); } } private string GetValue(byte[] bt, string valueType, string address) { string[] str = address.Split('.'); switch (valueType.ToLower()) { case "bool": return Snap7.S7.GetBitAt(bt, int.Parse(str[0]), int.Parse(str[1])).ToString(); default: return "false"; } } public override void SetBaseFolder(string folder) { base.SetBaseFolder(folder); this.SettingFilePath = Path.Combine(BaseFolder, "Setting.xml"); this.DataFilePath = Path.Combine(BaseFolder, "Data.xml"); } public override object Active() { try { if (File.Exists(SettingFilePath)) { ObservableCollection datas = XmlHelper.DeserializeFromXml>(SettingFilePath); IPManages = datas; DITag = IPManages[0].DItag; DQTag = IPManages[0].DQtag; } else { IPManage tag = new IPManage(); tag.DItag = ""; tag.DQtag = ""; IPManages.Add(tag); XmlHelper.SerializeToXml(SettingFilePath, IPManages); } if (systemSetting.PlcEnabled) { if (!lTSCADAApi.Connect2("127.0.0.1", 6543, 18888, out string errMsg)) { MsgBoxHelper.Error(this, errMsg); } else { this.MonitorTimer.Start(); } } } catch (Exception ex) { log.Error("Active Execute Failed.", ex); MsgBoxHelper.ErrorMessage(this, $"插件激活失败!{ex.Message}"); } return null; } private void CollectionViewSource_Filter(object sender, System.Windows.Data.FilterEventArgs e) { DIO data = e.Item as DIO; if (data == null) return; CollectionViewSource source = sender as CollectionViewSource; DIO param = new DIO(); if (source.Source == Dis) { param.Name = diName.Text; param.No = diCode.Text; } else { param.Name = doName.Text; param.No = doCode.Text; } if (!string.IsNullOrEmpty(param.Name) && data.Name != param.Name) { e.Accepted = false; return; } if (!string.IsNullOrEmpty(param.No) && data.No != param.No) { e.Accepted = false; return; } e.Accepted = true; } } }