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 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; 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; private SCADAApi api; public static ILog Logger { get; private set; } private volatile bool needRead = false; 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); 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 { 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) { } } } } }