using CommunityToolkit.Mvvm.ComponentModel;
using ConnectionUtil;
using HMI.Base;
using HMI.Core.Setting;
using HMI.Core.Util;
using HMI.UI.Util;
using HMI.Util;
using HslCommunication.Profinet.Siemens;
using log4net;
using Microsoft.Win32;
using Plugin.CurrentSensorControl.Entity;
using System.Collections.ObjectModel;
using System.IO;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Xml.Linq;
namespace Plugin.CurrentSensorControl
{
///
/// ControlPage.xaml 的交互逻辑
///
[ObservableObject]
public partial class ControlPage : SimpleMaskControl
{
[ObservableProperty]
private ObservableCollection datasource = new ObservableCollection();
private List controls = new List();
private System.Timers.Timer timer;
private System.Timers.Timer opcTimer;
public static ILog Logger { get; private set; }
private volatile bool needRead = false;
private SiemensS7Net api;
private bool plcMute = false;
public bool PlcMute
{
get => plcMute;
set
{
try
{
string name = $"PLC_Mute";
if (S7Context.WriteData(api, name, value))
{
plcMute = value;
OnPropertyChanged(nameof(PlcMute));
}
}
catch (Exception ex)
{
}
}
}
public ControlPage()
{
timer = new System.Timers.Timer();
timer.Elapsed += Timer_Elapsed;
timer.AutoReset = false;
timer.Interval = 1000;
opcTimer = new System.Timers.Timer();
opcTimer.Elapsed += OpcTimer_Elapsed; ;
opcTimer.AutoReset = false;
opcTimer.Interval = 1000;
S7Context.Init(SystemSetting.Instance.PlcIp, SystemSetting.Instance.PlcPort);
api = S7Context.Get($"1");
DataContext = this;
InitializeComponent();
}
private void OpcTimer_Elapsed(object sender, ElapsedEventArgs e)
{
opcTimer.Enabled = false;
try
{
var time = DateTime.Now;
ovenCollection.Refresh();
log.Debug($"Time Cast: {(DateTime.Now - time).TotalMilliseconds}ms");
}
catch (Exception ex)
{
}
finally
{
if (needRead) opcTimer.Enabled = true;
}
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
timer.Enabled = false;
try
{
if (S7Context.GetData(api, "PLC_Mute", out object val))
{
plcMute = (bool)val;
OnPropertyChanged("PlcMute");
}
}
catch (Exception ex)
{
}
try
{
foreach (var ctl in controls)
{
if (!needRead) return;
if (ctl is SingleSensor ss)
{
ss.ReadCurrent();
Thread.Sleep(50);
}
}
}
catch (Exception ex)
{
}
finally
{
if (needRead) timer.Enabled = true;
}
}
public override void InitFinish()
{
Logger = log;
}
public override void Active()
{
StartReadCurrent();
}
public override void DeActive()
{
StopReadCurrent();
}
public override void DoClose(object sender, EventArgs e)
{
StopReadCurrent();
base.DoClose(sender, e);
}
public void StartReadCurrent()
{
needRead = true;
timer.Enabled = true;
opcTimer.Enabled = true;
}
public void StopReadCurrent()
{
needRead = false;
timer.Enabled = false;
opcTimer.Enabled = false;
}
private void LoadSensorData()
{
string path = Path.Combine(BaseFolder, "sensor.data");
var list = new ObservableCollection();
try
{
if (File.Exists(path))
{
list = XmlHelper.DeserializeFromXml>(path);
}
}
catch (Exception ex)
{
log.Error("Load Sensor Data Failed.", ex);
}
Datasource = list;
}
private void ClearSensorControl()
{
foreach (var ctl in diWrap.Children)
{
if (ctl is SingleSensor ss)
{
ss.Close();
}
}
diWrap.Children.Clear();
controls.Clear();
}
private void RefreshSensorControl(bool start)
{
StopReadCurrent();
ClearSensorControl();
foreach (var data in Datasource)
{
SingleSensor ss = new SingleSensor(data.Name, data.Ip, data.Port, data.Address, data.Channel)
{
Width = 240
};
diWrap.Children.Add(ss);
controls.Add(ss);
Task.Factory.StartNew(() =>
{
ss.Connect();
});
}
if (start) StartReadCurrent();
}
private void ConnectAllSensor()
{
foreach (var ctl in diWrap.Children)
{
if (ctl is SingleSensor ss)
{
ss.Connect();
}
}
}
private void DisconnectAllSensor()
{
foreach (var ctl in diWrap.Children)
{
if (ctl is SingleSensor ss)
{
ss.Close();
}
}
}
private void SimpleMaskControl_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
LoadSensorData();
RefreshSensorControl(needRead);
LoadBurnInSetting();
Loaded -= SimpleMaskControl_Loaded;
}
private void OpenDataModal(SensorData data)
{
DataModal modal = new DataModal()
{
Title = "新增",
Owner = Window.GetWindow(this)
};
if (modal.Open(data, Datasource) == true)
{
string path = Path.Combine(BaseFolder, "sensor.data");
try
{
XmlHelper.SerializeToXml(path, Datasource);
LoadSensorData();
RefreshSensorControl(needRead);
}
catch (Exception ex)
{
ToastHelper.Error("保存失败");
log.Error("Save Sensor Data Failed.", ex);
}
}
}
private void DoExport()
{
try
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "Excel 文件 (*.xls)|*.xls";
if (sfd.ShowDialog() == true)
{
ExcelHelper.ExportExcel(sfd.FileName, Datasource);
}
ToastHelper.Success(this.lang("App.ExportSuccess"));
}
catch (Exception ex)
{
log.Error("Export Failed.", ex);
ToastHelper.Error(this.lang("App.ExportFailed"));
}
}
private void DoImport()
{
try
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Excel 文件 (*.xls)|*.xls";
if (ofd.ShowDialog() == true)
{
var datas = ExcelHelper.ReadFromExcel(ofd.FileName);
string path = Path.Combine(BaseFolder, "sensor.data");
XmlHelper.SerializeToXml(path, datas);
DoRefresh();
ToastHelper.Success(this.lang("App.ExportSuccess"));
}
}
catch (Exception ex)
{
log.Error("Export Failed.", ex);
ToastHelper.Error(this.lang("App.ExportFailed"));
}
}
private void SaveDatasouce(object datasource)
{
string path = Path.Combine(BaseFolder, "sensor.data");
XmlHelper.SerializeToXml(path, datasource);
}
private void DoRefresh()
{
ShowMask(() =>
{
Dispatcher.BeginInvoke(new Action(() =>
{
LoadSensorData();
RefreshSensorControl(needRead);
}));
}, (ex) =>
{
log.Error("Refresh Sensor Data Failed.", ex);
}, "请稍后", "正在加载...");
}
private void DoDelete(SensorData data)
{
if (MsgBoxHelper2.WarnChoose("确定要删除吗?") == MessageBoxResult.OK)
{
var index = Datasource.IndexOf(data);
if (index >= 0)
{
Datasource.RemoveAt(index);
SaveDatasouce(Datasource);
DoRefresh();
}
}
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
var btn = sender as Button;
var tag = btn?.Tag;
switch (btn?.Name)
{
case "addBtn":
OpenDataModal(new SensorData());
break;
case "rfhBtn":
DoRefresh();
break;
case "editBtn":
OpenDataModal((SensorData)tag);
break;
case "delBtn":
DoDelete((SensorData)tag);
break;
case "connectAllBtn":
ConnectAllSensor();
break;
case "disConnectAllBtn":
DisconnectAllSensor();
break;
case "exportBtn":
DoExport();
break;
case "importBtn":
DoImport();
break;
case "burnInSettingBtn":
OpenBurnSettingModal();
break;
default:
break;
}
}
[ObservableProperty]
private ObservableCollection burnInSettingData;
private void LoadBurnInSetting()
{
S7Context.dataCache.Clear();
ObservableCollection datas;
try
{
string path = Path.Combine(BaseFolder, "BurnInSettingData.data");
if (File.Exists(path))
{
datas = XmlHelper.DeserializeFromXml>(path);
}
else
{
datas = new ObservableCollection();
}
}
catch (Exception ex)
{
datas = new ObservableCollection();
}
BurnInSettingData = datas;
LoadBurnInSettingCache();
}
private void LoadBurnInSettingCache()
{
foreach (var data in BurnInSettingData)
{
S7Context.dataCache[data.Name] = data;
}
}
private void OpenBurnSettingModal()
{
BurnInSettingModal modal = new BurnInSettingModal
{
Owner = Window.GetWindow(this)
};
if (modal.Open(BurnInSettingData) == true)
{
var datas = modal.Datasource;
try
{
string path = Path.Combine(BaseFolder, "BurnInSettingData.data");
XmlHelper.SerializeToXml(path, datas);
BurnInSettingData = datas;
LoadBurnInSettingCache();
}
catch (Exception ex)
{
}
}
}
}
}