From e3868d4d61ded0e76fc8fe3fdacdd9e6d9113cf1 Mon Sep 17 00:00:00 2001
From: alielie <alielie@git.com>
Date: 星期一, 13 十月 2025 08:50:15 +0800
Subject: [PATCH] 优化HMI;

---
 Plugin.ServoManage/ServoManage.xaml.cs |  753 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 741 insertions(+), 12 deletions(-)

diff --git a/Plugin.ServoManage/ServoManage.xaml.cs b/Plugin.ServoManage/ServoManage.xaml.cs
index d816844..10e593d 100644
--- a/Plugin.ServoManage/ServoManage.xaml.cs
+++ b/Plugin.ServoManage/ServoManage.xaml.cs
@@ -1,39 +1,768 @@
-锘縰sing HMI.Base;
+锘縰sing ConnectionUtil;
+using HMI.Base;
+using HMI.Core.Entity;
+using HMI.Core.Manager;
+using HMI.Core.Setting;
+using HMI.Core.Util;
+using HMI.UI;
+using HMI.UI.Util;
+using OPCConnection;
+using Plugin.ServoManage.Entity;
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
 using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Reflection;
+using System.Threading;
+using System.Timers;
 using System.Windows;
 using System.Windows.Controls;
-using System.Windows.Data;
-using System.Windows.Documents;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Imaging;
-using System.Windows.Navigation;
-using System.Windows.Shapes;
+using System.Windows.Threading;
 
 namespace Plugin.ServoManage
 {
+    [AttributeUsage(AttributeTargets.Property)]
+    public class IsStatusAttribute : Attribute
+    {
+    }
+
     /// <summary>
     /// UserControl1.xaml 鐨勪氦浜掗�昏緫
     /// </summary>
-    public partial class ServoManage: UserControl
+    public partial class ServoManage : PluginControl
     {
+        public static string FilePath { get; private set; }
+        public static string ProductFilePath { get; private set; }
+
+        private ObservableCollection<ServoData> servos;
+        public ObservableCollection<ServoData> Servos
+        {
+            get => servos;
+            set
+            {
+                Set(ref servos, value);
+            }
+        }
+
+        private ServoData selectedServo;
+        public ServoData SelectedServo
+        {
+            get => selectedServo;
+            set
+            {
+                Set(ref selectedServo, value);
+                Set("HasSelectedServo");
+                RefreshServoStatus();
+            }
+        }
+
+        public bool HasSelectedServo
+        {
+            get => SelectedServo != null;
+        }
+
+        private string selectedProduct;
+        [IsStatus]
+        public string SelectedProduct
+        {
+            get => selectedProduct;
+            set
+            {
+                if (value != selectedProduct)
+                {
+                    Set(ref selectedProduct, value);
+                    if (SelectedServo != null)
+                    {
+                        SetBitValue($"{SelectedServo.Name}_sRecipeCode", value);
+                    }
+                }
+            }
+        }
+
+        private ObservableCollection<ServoProductData> servoProducts;
+        public ObservableCollection<ServoProductData> ServoProducts
+        {
+            get => servoProducts;
+            set
+            {
+                Set(ref servoProducts, value);
+            }
+        }
+
+        /// <summary>
+        /// 瀹炰緥鍖栨湇鍔″櫒鎺ュ彛鍑芥暟
+        /// </summary>
+        private SCADAApi lTSCADAApi = new OPCClient();
+        private bool isActived = false;
+        private System.Timers.Timer motorMonitorTimer;
+
+        #region ServoData
+        private string enable;
+        [IsStatus]
+        public string Enable
+        {
+            get => enable;
+            set
+            {
+                Set(ref enable, value);
+            }
+        }
+
+        private string currentPosition;
+        [IsStatus]
+        public string CurrentPosition
+        {
+            get => $"{currentPosition}{SelectedServo?.Unit}";
+            set
+            {
+                Set(ref currentPosition, value);
+            }
+        }
+
+        private string currentSpeed;
+        [IsStatus]
+        public string CurrentSpeed
+        {
+            get => $"{currentSpeed}{SelectedServo?.Unit}/s";
+            set
+            {
+                Set(ref currentSpeed, value);
+            }
+        }
+
+        private string overAcc;
+        [IsStatus]
+        public string OverAcc
+        {
+            get => $"{overAcc}{SelectedServo?.Unit}/s虏";
+            set
+            {
+                Set(ref overAcc, value);
+            }
+        }
+
+        private string overDec;
+        [IsStatus]
+        public string OverDec
+        {
+            get => $"{overDec}{SelectedServo?.Unit}/s虏";
+            set
+            {
+                Set(ref overDec, value);
+            }
+        }
+
+        private string hmiPosition;
+        [IsStatus]
+        public string HMIPosition
+        {
+            get => $"{hmiPosition}{SelectedServo?.Unit}";
+            set
+            {
+                Set(ref hmiPosition, value);
+            }
+        }
+
+        private string hmiSpeed;
+        [IsStatus]
+        public string HMISpeed
+        {
+            get => $"{hmiSpeed}{SelectedServo?.Unit}/s";
+            set
+            {
+                Set(ref hmiSpeed, value);
+            }
+        }
+
+        private string jogVelocity;
+        [IsStatus]
+        public string JogVelocity
+        {
+            get => $"{jogVelocity}%";
+            set
+            {
+                Set(ref jogVelocity, value);
+            }
+        }
+
+        private string inchDistance;
+        [IsStatus]
+        public string InchDistance
+        {
+            get => $"{inchDistance}{SelectedServo?.Unit}";
+            set
+            {
+                Set(ref inchDistance, value);
+            }
+        }
+
+        private string dir;
+        [IsStatus]
+        public string Dir
+        {
+            get => dir;
+            set
+            {
+                Set(ref dir, value);
+            }
+        }
+
+        private string alarmCode = "0";
+        [IsStatus]
+        public string AlarmCode
+        {
+            get => alarmCode;
+            set
+            {
+                Set(ref alarmCode, value);
+            }
+        }
+
+        private string warnCode = "0";
+        [IsStatus]
+        public string WarnCode
+        {
+            get => warnCode;
+            set
+            {
+                Set(ref warnCode, value);
+            }
+        }
+
+        private string faultCode = "0";
+        [IsStatus]
+        public string FaultCode
+        {
+            get => faultCode;
+            set
+            {
+                Set(ref faultCode, value);
+            }
+        }
+
+        private string positiveLimit;
+        [IsStatus]
+        public string PositiveLimit
+        {
+            get => positiveLimit;
+            set
+            {
+                Set(ref positiveLimit, value);
+            }
+        }
+
+        private string homeSwitch;
+        [IsStatus]
+        public string HomeSwitch
+        {
+            get => homeSwitch;
+            set
+            {
+                Set(ref homeSwitch, value);
+            }
+        }
+
+        private string negativeLimit;
+        [IsStatus]
+        public string NegativeLimit
+        {
+            get => negativeLimit;
+            set
+            {
+                Set(ref negativeLimit, value);
+            }
+        }
+
+        private string axisEnabled;
+        [IsStatus]
+        public string AxisEnabled
+        {
+            get => axisEnabled;
+            set
+            {
+                Set(ref axisEnabled, value);
+            }
+        }
+
+        private string readyOK;
+        [IsStatus]
+        public string ReadyOK
+        {
+            get => readyOK;
+            set
+            {
+                Set(ref readyOK, value);
+            }
+        }
+
+        private string running;
+        [IsStatus]
+        public string Running
+        {
+            get => running;
+            set
+            {
+                Set(ref running, value);
+            }
+        }
+
+        private string homed;
+        [IsStatus]
+        public string Homed
+        {
+            get => homed;
+            set
+            {
+                Set(ref homed, value);
+            }
+        }
+
+        private string axisError;
+        [IsStatus]
+        public string AxisError
+        {
+            get => axisError;
+            set
+            {
+                Set(ref axisError, value);
+            }
+        }
+
+        private string axisWarn;
+        [IsStatus]
+        public string AxisWarn
+        {
+            get => axisWarn;
+            set
+            {
+                Set(ref axisWarn, value);
+            }
+        }
+
+        private string posCode = "0";
+        [IsStatus]
+        public string PosCode
+        {
+            get => posCode;
+            set
+            {
+                Set(ref posCode, value);
+            }
+        }
+        #endregion
+
         public ServoManage()
         {
+            DataContext = this;
+            motorMonitorTimer = new System.Timers.Timer();
+            motorMonitorTimer.Elapsed += MotorMonitorTimer_Elapsed;
+            motorMonitorTimer.Interval = 100;
             InitializeComponent();
+        }
+
+        private void MotorMonitorTimer_Elapsed(object sender, ElapsedEventArgs e)
+        {
+            RefreshServoStatus();
+        }
+
+        public override void SetBaseFolder(string folder)
+        {
+            FilePath = Path.Combine(folder, "Servo.data");
+            ProductFilePath = Path.Combine(folder, "ServoProduct.data");
+            base.SetBaseFolder(folder);
+        }
+
+        public override void Active()
+        {
+            base.Active();
+            if (!isActived)
+            {
+                try
+                {
+                    if (SystemSetting.Instance.PlcEnabled)
+                    {
+                        if (lTSCADAApi.Connect2("127.0.0.1", 6543, 18888, out string errMsg))
+                        {
+                            motorMonitorTimer.Enabled = true;
+                            isActived = true;
+                        }
+                        else
+                        {
+                            MsgBoxHelper2.Error(errMsg);
+                        }
+                    }
+                    else
+                    {
+
+                        isActived = true;
+                    }
+                }
+                catch (Exception ex)
+                {
+                    log.Error("Active Failed.", ex);
+                    MsgBoxHelper2.Error(ex.Message);
+                }
+            }
+            else
+            {
+                motorMonitorTimer.Enabled = true;
+            }
+        }
+
+        public override void DeActive()
+        {
+            motorMonitorTimer.Enabled = false;
+            base.DeActive();
         }
 
         private void UserControl_Loaded(object sender, RoutedEventArgs e)
         {
-
+            LoadData();
+            LoadProductData();
+            this.Loaded -= UserControl_Loaded;
         }
 
         private void Button_Click(object sender, RoutedEventArgs e)
         {
+            Button btn = sender as Button;
+            ServoData data = btn.DataContext as ServoData;
+            switch (btn.Name)
+            {
+                case "addServoBtn":
+                    OpenServoModal(null);
+                    break;
+                case "editServoBtn":
+                    OpenServoModal(data);
+                    break;
+                case "delServoBtn":
+                    TryDeleteServo(data);
+                    break;
+                case "rfhServoBtn":
+                    LoadData();
+                    break;
+                case "addProductBtn":
+                    OpenProductModal(null);
+                    break;
+                default:
+                    break;
+            }
+        }
 
+        #region Servo
+        private void LoadData()
+        {
+            try
+            {
+                ObservableCollection<ServoData> data = new ObservableCollection<ServoData>();
+                if (File.Exists(FilePath))
+                {
+                    data = XmlHelper.DeserializeFromXml<ObservableCollection<ServoData>>(FilePath);
+                }
+                Servos = data;
+            }
+            catch (Exception ex)
+            {
+                log.Error("Load Servo Data Failed.", ex);
+                ToastHelper.Error(this.lang("App.LoadFailed"));
+            }
+        }
+
+        private void OpenServoModal(ServoData data)
+        {
+            bool isUpdate = data != null;
+            try
+            {
+
+                ServoModal modal = new ServoModal
+                {
+                    Title = isUpdate ? this.lang("App.Edit") : this.lang("App.Add"),
+                    Owner = Window.GetWindow(this)
+                };
+                if (modal.Open(data ?? new ServoData(), Servos) == true)
+                {
+                    LoadData();
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error($"Add Or Edit Data Failed.", ex);
+                var title = isUpdate ? this.lang("App.EditFailed") : this.lang("App.AddFailed");
+                MsgBoxHelper2.Error($"{title}: {ex.Message}");
+            }
+        }
+
+        private void TryDeleteServo(ServoData data)
+        {
+            try
+            {
+                if (MsgBoxHelper2.WarnChoose(this.lang("HMI.MakeSureDeleteSingle", data.Name)) == MessageBoxResult.OK)
+                {
+                    int index = Servos.IndexOf(data);
+                    if (index > 0)
+                    {
+                        var temp = XmlHelper.DeepClone(Servos);
+                        temp.RemoveAt(index);
+                        XmlHelper.SerializeToXml(FilePath, temp);
+                    }
+                    LoadData();
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error($"Delete Servo Failed.", ex);
+                MsgBoxHelper2.Error($"{this.lang("App.DeleteFailed")}: {ex.Message}");
+            }
+        }
+        #endregion
+
+        #region product
+        public ObservableCollection<ServoProductData> ReadCommonProducts()
+        {
+            ObservableCollection<ServoProductData> datas = new ObservableCollection<ServoProductData>();
+            List<ProductData> products = ProductManager.GetProducts<List<ProductData>>();
+            if (products != null && products.Count > 0)
+            {
+                foreach (var product in products)
+                {
+                    var parameter = ProductManager.GetParametersByProductName(product.Name)
+                         ?.FirstOrDefault(p => p.Name == "ProgramCode");
+                    if (parameter != null)
+                    {
+                        datas.Add(new ServoProductData
+                        {
+                            Model = product.Name,
+                            ProgramCode = parameter.Value,
+                        });
+                    }
+                }
+            }
+            return datas;
+        }
+
+        private void LoadProductData()
+        {
+            try
+            {
+                //ObservableCollection<ServoProductData> datas = new ObservableCollection<ServoProductData>();
+                //if (File.Exists(FilePath))
+                //{
+                //    datas = XmlHelper.DeserializeFromXml<ObservableCollection<ServoProductData>>(ProductFilePath);
+                //}
+                ServoProducts = ReadCommonProducts();
+            }
+            catch (Exception ex)
+            {
+                log.Error("Load Servo Product Data Failed.", ex);
+                ToastHelper.Error(this.lang("App.LoadFailed"));
+            }
+        }
+
+        private void OpenProductModal(ServoProductData data)
+        {
+            bool isUpdate = data != null;
+            try
+            {
+
+                ServoProductModal modal = new ServoProductModal
+                {
+                    Title = isUpdate ? this.lang("App.Edit") : this.lang("App.Add"),
+                    Owner = Window.GetWindow(this)
+                };
+                if (modal.Open(data ?? new ServoProductData(), ServoProducts) == true)
+                {
+                    LoadProductData();
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error($"Add Or Edit Product Data Failed.", ex);
+                var title = isUpdate ? this.lang("App.EditFailed") : this.lang("App.AddFailed");
+                MsgBoxHelper2.Error($"{title}: {ex.Message}");
+            }
+        }
+        #endregion
+
+        private void RefreshServoStatus()
+        {
+            this.motorMonitorTimer.Enabled = false;
+            try
+            {
+                if (SelectedServo == null) return;
+                PropertyInfo[] properties = this.GetType().GetProperties();
+                foreach (var prop in properties)
+                {
+                    if (!Attribute.IsDefined(prop, typeof(IsStatusAttribute)))
+                    {
+                        continue;
+                    }
+                    Dispatcher.InvokeAsync(new Action(() =>
+                    {
+                        if (prop.Name == "SelectedProduct")
+                        {
+                            var data = GetBitValue($"{SelectedServo.Name}_sRecipeCode");
+                            SelectedProduct = data;
+                        }
+                        else
+                        {
+                            var data = GetBitValue($"{SelectedServo.Name}_{prop.Name}");
+                            prop.SetValue(this, data);
+                        }
+                    }), DispatcherPriority.SystemIdle);
+                }
+            }
+            catch (Exception ex)
+            {
+
+            }
+            finally
+            {
+                this.motorMonitorTimer.Enabled = true;
+            }
+        }
+
+        /// <summary>
+        /// 璁剧疆DB鍦板潃bool鍊�
+        /// </summary>
+        /// <param name="subbuttonX">瀛愭寜閽�</param>
+        /// <param name="address">鍦板潃</param>
+        /// <param name="bol">鍊�</param>
+        private void SetBitValue(string tag, string val)
+        {
+            if (!lTSCADAApi.DoFctWriteSingle(tag, val, out string errMsg))
+            {
+                log.Error($"Set Bit Value Failed.{errMsg}");
+                MsgBoxHelper2.Error(errMsg);
+            }
+        }
+
+        /// <summary>
+        /// 閫氳繃褰撳墠鏍囩璇诲彇鍊�
+        /// </summary>
+        /// <param name="tag">鏍囩</param>
+        /// <returns>杩斿洖鍊�</returns>
+        private string GetBitValue(string tag)
+        {
+            if (lTSCADAApi.DoFctReadSingle(tag, out string res, out string err))
+            {
+                return res;
+            }
+            else
+            {
+                return "";
+            }
+        }
+
+        private void Servo_Click(object sender, RoutedEventArgs e)
+        {
+            if (SelectedServo == null)
+            {
+                ToastHelper.Warning(this.lang("svo.selectAServo"));
+                return;
+            }
+            Button btn = sender as Button;
+            try
+            {
+                switch (btn.Tag)
+                {
+                    case "Enable":
+                        EnableDoClick(btn.Tag.ToString());
+                        break;
+                    case "Dir":
+                        EnableDoClick(btn.Tag.ToString());
+                        break;
+                    default:
+                        //DoSignClick(btn.Tag?.ToString());
+                        break;
+                }
+            }
+            catch (Exception ex)
+            {
+                log.Error($"Servo Opt Failed, BtnName is {btn.Name}", ex);
+                MsgBoxHelper2.Error(ex.Message);
+            }
+            finally
+            {
+            }
+        }
+
+        private void DoSignClick(string tag)
+        {
+            if (!string.IsNullOrEmpty(tag))
+            {
+                SetBitValue($"{SelectedServo?.Name}_{tag}", "true");
+                Thread.Sleep(50);
+                SetBitValue($"{SelectedServo?.Name}_{tag}", "false");
+            }
+        }
+
+        /// <summary>
+        /// 浣胯兘/鏂娇鑳� 鎸夐挳
+        /// </summary>
+        /// <param name="btnName"></param>
+        private void EnableDoClick(string btnName)
+        {
+            bool val = GetBitValue($"{SelectedServo?.Name}_{btnName}") == "1";
+            SetBitValue($"{SelectedServo?.Name}_{btnName}", $"{(!val ? 1 : 0)}");
+        }
+
+        private void Label_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
+        {
+            if (SelectedServo == null)
+            {
+                ToastHelper.Warning(this.lang("svo.selectAServo"));
+                return;
+            }
+            Label label = sender as Label;
+            var tag = label.Tag.ToString();
+            NumberPanel np = new NumberPanel()
+            {
+                Title = this.lang($"svo.{tag}"),
+                Owner = Window.GetWindow(this)
+            };
+            string value = label.Content.ToString();
+            if (value.Contains("%"))
+            {
+                value = value.Replace("%", "");
+            }
+            else if (SelectedServo != null)
+            {
+                value = value.Split(new string[] { SelectedServo.Unit }, StringSplitOptions.None)[0];
+            }
+            if (np.Open(value) == true)
+            {
+                SetBitValue($"{SelectedServo?.Name}_{tag}", np.Data?.ToString());
+            }
+        }
+
+        private void Button_PreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
+        {
+            Button btn = sender as Button;
+            var tag = btn.Tag.ToString();
+            try
+            {
+                motorMonitorTimer.Enabled = false;
+                SetBitValue($"{SelectedServo?.Name}_{tag}", "true");
+            }
+            finally
+            {
+                motorMonitorTimer.Enabled = true;
+            }
+        }
+
+        private void Button_PreviewMouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
+        {
+            Button btn = sender as Button;
+            var tag = btn.Tag.ToString();
+            try
+            {
+                motorMonitorTimer.Enabled = false;
+                SetBitValue($"{SelectedServo?.Name}_{tag}", "false");
+            }
+            finally
+            {
+                motorMonitorTimer.Enabled = true;
+            }
         }
     }
 }

--
Gitblit v1.9.1