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 = this.lang("App.Add"),
Owner = Window.GetWindow(this),
};
if (modal.Open(-1, new IPManage(), IPManages, SettingFilePath) == true)
{
this.Success(this.lang("App.AddSuccess"));
}
}
private void ImportFromExcel()
{
IWorkbook workbook = null;
OpenFileDialog dialog = new OpenFileDialog();
////该值确定是否可以选择多个文件
dialog.Multiselect = false;
dialog.Title = this.lang("App.SelectFile");
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, $"{this.lang("App.ImportFailed")}: {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 void 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, $"{this.lang("DIO.ActivateFailed")}: {ex.Message}");
}
}
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;
}
}
}