alielie
2025-03-03 1fca2167068e9ef2c079ec742f20313fc6697ab1
HMI.IOMonitor/IOMonitor.xaml.cs
@@ -1,8 +1,26 @@
using System.Windows;
using System.Collections.Generic;
using System.Configuration;
using System;
using System.Windows;
using System.Windows.Controls;
using HMI.Base;
using HMI.Core.Api;
using HMI.IOMonitor.Entity;
using log4net;
using System.Linq;
using System.IO;
using HMI.Core.Util;
using System.Collections.ObjectModel;
using HMI.Core.Setting;
using HMI.UI.Util;
using System.Timers;
using System.Windows.Media;
using System.Threading.Tasks;
using System.Windows.Data;
using Microsoft.Win32;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;
namespace HMI.IOMonitor
{
@@ -11,19 +29,474 @@
    /// </summary>
    public partial class IOMonitor : PluginControl
    {
        public string SettingFilePath { get; private set; }
        public string DataFilePath { get; private set; }
        /// <summary>
        /// DIO地址
        /// </summary>
        private string DITag = string.Empty;
        private string DQTag = string.Empty;
        private SystemSetting systemSetting;
        private Timer MonitorTimer;
        private OpcInterface.OpcInterface lTSCADAApi = new OpcInterface.OpcInterface();
        /// <summary>
        /// The diosde 反序列化的DIO对象
        /// </summary>
        private List<DIO> diosde = new List<DIO>();
        /// <summary>The dis
        /// DI口对象
        /// </summary>
        private ObservableCollection<DIO> _dis = new ObservableCollection<DIO>() {
            new DIO(null,null,null,false),
            new DIO(null,null,null,true),
        };
        public ObservableCollection<DIO> Dis
        {
            get => _dis;
            set { Set(ref _dis, value); }
        }
        private ObservableCollection<DIO> _dos = new ObservableCollection<DIO>() {
            new DIO(null,null,null,false),
            new DIO(null,null,null,true),
        };
        public ObservableCollection<DIO> Dos
        {
            get => _dos;
            set { Set(ref _dos, value); }
        }
        private ObservableCollection<IPManage> iPManages = new ObservableCollection<IPManage>();
        public ObservableCollection<IPManage> 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;
            }
        }
        /// <summary>
        /// 初始化方法
        /// </summary>
        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<List<DIO>>(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<DIO>(Dis.OrderByDescending(t => t.DIO_No).ToList());
                Dos = new ObservableCollection<DIO>(Dos.OrderByDescending(t => t.DIO_No).ToList());
                List<string> listnew1 = new List<string>();
                foreach (var item in Dis)
                {
                    listnew1.Add(item.Name);
                }
                diName.ItemsSource = listnew1;
                List<string> listnew2 = new List<string>();
                foreach (var item in Dos)
                {
                    listnew2.Add(item.Name);
                }
                doName.ItemsSource = listnew2;
                List<string> listDis = new List<string>();
                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<string> listDos = new List<string>();
                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<DIO> dios1 = new List<DIO>();
                    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<IPManage> datas =
                        XmlHelper.DeserializeFromXml<ObservableCollection<IPManage>>(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;
        }
    }
}