alielie
2025-06-12 c1c3772a11b1f3fbad8846cc714120771d85fa53
Plugin.DOControl/DOControl.xaml.cs
@@ -1,30 +1,481 @@
using HMI.Base;
using ConnectionUtil;
using HMI.Base;
using HMI.Core.Setting;
using HMI.Core.Util;
using HMI.UI;
using HMI.UI.Util;
using log4net;
using Panuon.WPF.UI;
using Plugin.DOControl.Entity;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace HMI.DOControl
namespace Plugin.DOControl
{
    /// <summary>
    /// UserControl1.xaml 的交互逻辑
    /// </summary>
    public partial class DOControl : PluginControl
    {
        /// <summary>
        /// 实例化服务器接口函数
        /// </summary>
        //private OpcInterface.OpcInterface lTSCADAApi = new OpcInterface.OpcInterface();
        private PipeClient pipeClient = new PipeClient("DAService");
        private ObservableCollection<string> groups;
        public ObservableCollection<string> Groups
        {
            get => groups;
            set
            {
                Set(ref groups, value);
            }
        }
        private string selectedGroup;
        public string SelectedGroup
        {
            get => selectedGroup;
            set
            {
                Set(ref selectedGroup, value);
                if (string.IsNullOrEmpty(value))
                {
                    selectedControls.Clear();
                }
                else if (GroupMap.ContainsKey(value))
                {
                    selectedControls = GroupMap[value];
                }
                RefreshControl();
            }
        }
        private ObservableCollection<DOControlData> datasource;
        public ObservableCollection<DOControlData> Datasource
        {
            get => datasource;
            set
            {
                Set(ref datasource, value);
            }
        }
        private Dictionary<string, List<DOControlData>> GroupMap = new Dictionary<string, List<DOControlData>>();
        private List<FrameworkElement> visiableControls = new List<FrameworkElement>();
        private List<DOControlData> selectedControls = new List<DOControlData>();
        private System.Timers.Timer motorMonitorTimer;
        public DOControl()
        {
            DataContext = this;
            motorMonitorTimer = new System.Timers.Timer();
            motorMonitorTimer.Interval = 200;
            motorMonitorTimer.AutoReset = false;
            motorMonitorTimer.Elapsed += MotorMonitorTimer_Elapsed;
            InitializeComponent();
        }
        public override void Active()
        {
            motorMonitorTimer.Enabled = true;
            base.Active();
        }
        public override void DeActive()
        {
            motorMonitorTimer.Enabled = false;
            base.DeActive();
        }
        public override void DoClose(object sender, EventArgs e)
        {
            motorMonitorTimer.Enabled = false;
            base.DoClose(sender, e);
        }
        public static string FilePath { get; private set; }
        public static ILog Logger { get; private set; }
        public override void SetBaseFolder(string folder)
        {
            FilePath = Path.Combine(folder, "DOControlData.data");
            base.SetBaseFolder(folder);
        }
        public override void SetLogger(ILog logger)
        {
            Logger = logger;
            base.SetLogger(logger);
        }
        public override void InitFinish()
        {
            base.InitFinish();
        }
        private void LoadData()
        {
            ObservableCollection<DOControlData> datas = new ObservableCollection<DOControlData>();
            try
            {
                motorMonitorTimer.Enabled = false;
                if (File.Exists(FilePath))
                {
                    datas = XmlHelper.DeserializeFromXml<ObservableCollection<DOControlData>>(FilePath);
                }
                GroupMap = datas.GroupBy(x => x.Group)
                   .ToDictionary(
                       group => group.Key,
                       group => group.ToList()
                   );
                Groups = new ObservableCollection<string>(GroupMap.Keys);
                if (string.IsNullOrEmpty(SelectedGroup) && Groups.Count > 0)
                {
                    SelectedGroup = Groups[0];
                }
                else
                {
                    RefreshControl();
                }
            }
            catch (Exception ex)
            {
                log.Error("Load Data Failed.", ex);
                ToastHelper.Error(this, ex.Message);
            }
            finally
            {
                motorMonitorTimer.Enabled = true;
            }
            Datasource = datas;
        }
        private void MotorMonitorTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            try
            {
                motorMonitorTimer.Enabled = false;
                for (int i = visiableControls.Count - 1; i >= 0; i--)
                {
                    var ui = visiableControls[i];
                    ui.Dispatcher.Invoke(() =>
                    {
                        DOControlData data = ui.Tag as DOControlData;
                        if (data == null) return;
                        string value = GetPlcValue(data.Address);
                        switch (data.ControlType)
                        {
                            case ControlType.BOOL:
                                var color = Application.Current.FindResource("VerBar") as Brush;
                                if (value == data.PressDownValue)
                                {
                                    color = Application.Current.FindResource("GreenVerBar") as Brush;
                                }
                            ((Button)ui).Background = color;
                                ((Button)ui).Content = value;
                                break;
                            case ControlType.INT:
                            case ControlType.WORD:
                            case ControlType.REAL:
                            case ControlType.LREAL:
                            case ControlType.STRING:
                            case ControlType.WSTRING:
                                ((Button)ui).Content = value;
                                break;
                            default:
                                break;
                        }
                    });
                }
            }
            finally
            {
                motorMonitorTimer.Enabled = true;
            }
        }
        private void RefreshControl()
        {
            try
            {
                motorMonitorTimer.Enabled = false;
                panel0.Children.Clear();
                panel1.Children.Clear();
                visiableControls.Clear();
                int index = 0;
                foreach (string group in GroupMap.Keys)
                {
                    int num = index % 2;
                    WrapPanel panel = new WrapPanel
                    {
                        Orientation = Orientation.Horizontal
                    };
                    GroupBox gb = new GroupBox
                    {
                        Header = group,
                        Content = panel,
                        Margin = new Thickness(0, 0, 0, 10)
                    };
                    var datas = GroupMap[group];
                    foreach (var data in datas)
                    {
                        FrameworkElement ui = null;
                        switch (data.ControlType)
                        {
                            case ControlType.BOOL:
                            case ControlType.PULSE:
                                ui = CreateButton(data);
                                break;
                            case ControlType.TIME:
                                break;
                            default:
                                ui = CreateInput(data);
                                break;
                        }
                        if (ui != null)
                        {
                            FormGroup fg = new FormGroup
                            {
                                Header = data.Name,
                                Content = ui,
                                Orientation = Orientation.Vertical,
                                Margin = new Thickness(10, 0, 0, 10)
                            };
                            panel.Children.Add(fg);
                            visiableControls.Add(ui);
                        }
                    }
                    if (num == 0)
                    {
                        panel0.Children.Add(gb);
                    }
                    else
                    {
                        panel1.Children.Add(gb);
                    }
                    index++;
                }
            }
            catch
            {
            }
            finally
            {
                motorMonitorTimer.Enabled = true;
            }
        }
        private Button CreateButton(DOControlData data)
        {
            Style btnStyle = Application.Current.FindResource("PrimaryButton") as Style;
            var btn = new Button
            {
                Tag = data,
                Style = btnStyle,
                MinWidth = 180,
                MinHeight = 40
            };
            if (data.ControlType == ControlType.BOOL)
            {
                btn.Click += ControlButton_Click;
            }
            else if (data.ControlType == ControlType.PULSE)
            {
                btn.Content = data.Address;
                btn.PreviewMouseLeftButtonDown += Btn_MouseLeftButtonDown;
                btn.PreviewMouseLeftButtonUp += Btn_MouseLeftButtonUp;
            }
            return btn;
        }
        private void Btn_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Button btn = sender as Button;
            DOControlData data = btn.Tag as DOControlData;
            try
            {
                var color = Application.Current.FindResource("GreenVerBar") as Brush;
                btn.Background = color;
                SetPlcValue(data.Address, data.PressDownValue);
            }
            catch (Exception ex)
            {
                log.Error("PressDownClick", ex);
                ToastHelper.Error($"{data.Name}: {ex.Message}");
            }
        }
        private void Btn_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Button btn = sender as Button;
            DOControlData data = btn.Tag as DOControlData;
            try
            {
                var color = Application.Current.FindResource("VerBar") as Brush;
                btn.Background = color;
                SetPlcValue(data.Address, data.PressUpValue);
            }
            catch (Exception ex)
            {
                log.Error("PressUpClick", ex);
                ToastHelper.Error($"{data.Name}: {ex.Message}");
            }
        }
        private Button CreateInput(DOControlData data)
        {
            Style btnStyle = Application.Current.FindResource("PrimaryButton") as Style;
            var tb = new Button
            {
                Tag = data,
                Style = btnStyle,
                MinWidth = 180,
                MinHeight = 40,
                BorderBrush = Brushes.Black,
                BorderThickness = new Thickness(1),
                Background = Brushes.White,
                Foreground = Brushes.Black
            };
            if (data.ReadOnly)
            {
                tb.Background = Brushes.LightGray;
                return tb;
            }
            if (data.ControlType == ControlType.STRING || data.ControlType == ControlType.WSTRING)
            {
                tb.Click += StringInput_Click;
            }
            else
            {
                tb.Click += NumberInput_Click;
            }
            return tb;
        }
        /// <summary>
        /// 设置plc值
        /// </summary>
        /// <param name="address">地址</param>
        /// <param name="valueType">类型</param>
        /// <param name="value">值</param>
        private void SetPlcValue(string key, string value)
        {
            //if (!lTSCADAApi.DoFctWriteSingle(key, value, out string errMsg))
            //{
            //    ToastHelper.Error(this, errMsg);
            //}
            pipeClient.SendMessage("asdsadasda", out _);
        }
        private string GetPlcValue(string key)
        {
            //if (lTSCADAApi.DoFctReadSingle(key, out string Val, out string errMsg))
            //{
            //    return Val;
            //}
            //else
            //{
            //    return null;
            //}
            return null;
        }
        private void ControlButton_Click(object sender, RoutedEventArgs args)
        {
            Button btn = sender as Button;
            DOControlData data = btn.Tag as DOControlData;
            try
            {
                string value = btn.Content?.ToString() == data.PressDownValue ? data.PressUpValue : data.PressDownValue;
                SetPlcValue(data.Address, value);
            }
            catch (Exception ex)
            {
                log.Error("ControlButton_Click", ex);
                ToastHelper.Error($"{data.Name}: {ex.Message}");
            }
        }
        private void StringInput_Click(object sender, RoutedEventArgs args)
        {
            Button tb = sender as Button;
            DOControlData data = tb.Tag as DOControlData;
            KeyboardWindow kw = new KeyboardWindow
            {
                Title = data.Name,
                Owner = Window.GetWindow(this)
            };
            if (kw.Open(tb.Content?.ToString()) == true)
            {
                SetPlcValue(data.Address, kw.Data?.ToString());
            }
        }
        private void NumberInput_Click(object sender, RoutedEventArgs args)
        {
            Button tb = sender as Button;
            DOControlData data = tb.Tag as DOControlData;
            NumberPanel np = new NumberPanel
            {
                Title = data.Name,
                Owner = Window.GetWindow(this),
                DotEnabled = data.ControlType == ControlType.REAL || data.ControlType == ControlType.LREAL
            };
            if (np.Open(tb.Content?.ToString()) == true)
            {
                SetPlcValue(data.Address, np.Data?.ToString());
            }
        }
        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            LoadData();
            if (SystemSetting.Instance.PlcEnabled)
            {
                //if (lTSCADAApi.Connect2("127.0.0.1", 6543, 18888, out string errMsg))
                //{
                //    motorMonitorTimer.Enabled = true;
                //    RefreshControl();
                //}
                //else
                //{
                //    MsgBoxHelper2.Error(errMsg);
                //}
                try
                {
                    pipeClient.OnConnected += PipeClient_OnConnected;
                    pipeClient.Connect();
                }
                catch (Exception ex)
                {
                    MsgBoxHelper.Error(this, ex.Message);
                }
            }
            Loaded -= UserControl_Loaded;
        }
        private void PipeClient_OnConnected(object sender, EventArgs e)
        {
        }
        private void Button_Click(object sender, RoutedEventArgs e)
@@ -32,9 +483,14 @@
            Button btn = sender as Button;
            switch (btn.Name)
            {
                case "queryBtn":
                case "addBtn":
                    OpenDataModal(null);
                    break;
                case "settingBtn":
                    OpenDataList();
                    break;
                case "resetBtn":
                    LoadData();
                    break;
                case "exportBtn":
                    break;
@@ -42,5 +498,30 @@
                    break;
            }
        }
        private void OpenDataModal(DOControlData data)
        {
            DataModal modal = new DataModal
            {
                Title = data == null ? this.lang("App.Add") : this.lang("App.Edit"),
                Owner = Window.GetWindow(this)
            };
            if (modal.Open(data ?? new DOControlData(), Datasource) == true)
            {
                LoadData();
            }
        }
        private void OpenDataList()
        {
            ControlList list = new ControlList
            {
                Owner = Window.GetWindow(this)
            };
            if (list.Open(Datasource) == true)
            {
                LoadData();
            }
        }
    }
}