Преглед изворни кода

20260603001 继续完善PLC参数管理功能,目前根绝队列来查询的功能初步制作,待优化中

向羽 孟 пре 2 недеља
родитељ
комит
a6ae70ca59

+ 6 - 5
MvvmScaffoldFrame48.DLL/CommunicationTools/ModbusTcpClient.cs

@@ -10,6 +10,7 @@ namespace MvvmScaffoldFrame48.DLL.CommunicationTools
         #region 实例
         private TcpClient _tcpClient;
         private IModbusMaster _modbusMaster;
+        private const string DefaultByteOrder = "BADC";
         #endregion
 
         #region 连接方法
@@ -141,7 +142,7 @@ namespace MvvmScaffoldFrame48.DLL.CommunicationTools
         /// <param name="count">REAL值的数量</param>
         /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
         /// <returns>REAL值数组</returns>
-        public bool ReadHoldingRegistersAsReal(byte slaveId, ushort startAddress, ushort count, out float[] ReturnValue,string byteOrder = "BADC")
+        public bool ReadHoldingRegistersAsReal(byte slaveId, ushort startAddress, ushort count, out float[] ReturnValue,string byteOrder = DefaultByteOrder)
         {
             bool Result = false;
             ReturnValue = null;
@@ -184,7 +185,7 @@ namespace MvvmScaffoldFrame48.DLL.CommunicationTools
         /// <param name="startAddress">起始地址</param>
         /// <param name="count">REAL值的数量</param>
         /// <returns>REAL值数组</returns>
-        public bool ReadHoldingRegistersAsInt32(byte slaveId, ushort startAddress, ushort count,out UInt32[] ReturnValue, string byteOrder = "BADC")
+        public bool ReadHoldingRegistersAsInt32(byte slaveId, ushort startAddress, ushort count,out UInt32[] ReturnValue, string byteOrder = DefaultByteOrder)
         {
             bool Result = false;
             ReturnValue = null;
@@ -318,7 +319,7 @@ namespace MvvmScaffoldFrame48.DLL.CommunicationTools
         /// <param name="startAddress">起始地址</param>
         /// <param name="value">REAL值</param>
         /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
-        public bool WriteSingleReal(byte slaveId, ushort startAddress, float value, string byteOrder = "BADC")
+        public bool WriteSingleReal(byte slaveId, ushort startAddress, float value, string byteOrder = DefaultByteOrder)
         {
             bool result = false;
             if (_modbusMaster == null)
@@ -352,7 +353,7 @@ namespace MvvmScaffoldFrame48.DLL.CommunicationTools
         /// <param name="startAddress">起始地址</param>
         /// <param name="values">REAL值数组</param>
         /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
-        public bool WriteMultipleReals(byte slaveId, ushort startAddress, float[] values, string byteOrder = "BADC")
+        public bool WriteMultipleReals(byte slaveId, ushort startAddress, float[] values, string byteOrder = DefaultByteOrder)
         {
             bool result = false;
             if (_modbusMaster == null)
@@ -403,7 +404,7 @@ namespace MvvmScaffoldFrame48.DLL.CommunicationTools
         /// <param name="startAddress">起始地址</param>
         /// <param name="value">REAL值</param>
         /// <param name="byteOrder">字节序 (ABCD, CDAB, BADC, DCBA)</param>
-        public bool WriteSingleInt32(byte slaveId, ushort startAddress, UInt32 value, string byteOrder = "BADC")
+        public bool WriteSingleInt32(byte slaveId, ushort startAddress, UInt32 value, string byteOrder = DefaultByteOrder)
         {
             // 将32位整数拆分为两个16位寄存器值
             byte[] bytes = BitConverter.GetBytes(value);

+ 92 - 28
MvvmScaffoldFrame48.DLL/CommunicationTools/PlcCommunManager.cs

@@ -3,6 +3,7 @@ using MvvmScaffoldFrame48.DLL.AlarmTools;
 using MvvmScaffoldFrame48.DLL.LogTools;
 using MvvmScaffoldFrame48.Model.StorageModel.PlcParameter;
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
@@ -12,31 +13,7 @@ namespace MvvmScaffoldFrame48.DLL.CommunicationTools
 {
     public class PlcCommunManager
     {
-        private static readonly Dictionary<int, ushort> BitMasks = new Dictionary<int, ushort>
-        {
-            // 寄存器位掩码
-            {0, (ushort)(1 << 0)},
-            {1, (ushort)(1 << 1)},
-            {2, (ushort)(1 << 2)},
-            {3, (ushort)(1 << 3)},
-            {4, (ushort)(1 << 4)},
-            {5, (ushort)(1 << 5)},
-            {6, (ushort)(1 << 6)},
-            {7, (ushort)(1 << 7)},
-            {8, (ushort)(1 << 8)},
-            {9, (ushort)(1 << 9)},
-            {10, (ushort)(1 << 10)},
-            {11, (ushort)(1 << 11)},
-            {12, (ushort)(1 << 12)},
-            {13, (ushort)(1 << 13)},
-            {14, (ushort)(1 << 14)},
-            {15, (ushort)(1 << 15)},
-        };
-        private static readonly Dictionary<string, PlcParameterModel> RegisterMap = new Dictionary<string, PlcParameterModel>
-        {
-            {"test1",new PlcValueBitParameterModel(0,0) }
-        };
-
+        #region 变量
         private bool isConnect = false;
         public bool IsConnect
         {
@@ -46,13 +23,51 @@ namespace MvvmScaffoldFrame48.DLL.CommunicationTools
             }
         }
 
-        public ModbusTcpClient modbusTcpClient = new ModbusTcpClient();
+        private string IpAddress = "127.0.0.1";
+        #endregion
+
+        #region 实例
+        public static PlcCommunManager Instance => _instance;
+        private static PlcCommunManager _instance = new PlcCommunManager();
+        // 寄存器位掩码
+        private static readonly ConcurrentDictionary<int, ushort> BitMasks = new ConcurrentDictionary<int, ushort>
+        {
+            [0] = (ushort)(1 << 0),
+            [1] = (ushort)(1 << 1),
+            [2] = (ushort)(1 << 2),
+            [3] = (ushort)(1 << 3),
+            [4] = (ushort)(1 << 4),
+            [5] = (ushort)(1 << 5),
+            [6] = (ushort)(1 << 6),
+            [7] = (ushort)(1 << 7),
+            [8] = (ushort)(1 << 8),
+            [9] = (ushort)(1 << 9),
+            [10] = (ushort)(1 << 10),
+            [11] = (ushort)(1 << 11),
+            [12] = (ushort)(1 << 12),
+            [13] = (ushort)(1 << 13),
+            [14] = (ushort)(1 << 14),
+            [15] = (ushort)(1 << 15),
+        };
+        // 寄存器信息
+        public static readonly ConcurrentDictionary<string, PlcParameterModel> RegisterMap = new ConcurrentDictionary<string, PlcParameterModel>
+        {
+            ["test1"] = new PlcValueBitParameterModel(0, 0),
+            ["test2"] = new PlcInt32ParameterModel(1),
+            ["test3"] = new PlcDouble64ParameterModel(3)
+        };
+        private ModbusTcpClient modbusTcpClient = new ModbusTcpClient();
+        #endregion
 
-        public PlcCommunManager(string IpAddress)
+        #region 构造方法
+        private PlcCommunManager()
         {
             ConnectModbus(IpAddress);
         }
-        public void ConnectModbus(string ipAddress)
+        #endregion
+
+        #region 私有方法
+        private void ConnectModbus(string ipAddress)
         {
             int i = 10;
             while (!modbusTcpClient.Connect(ipAddress) && i > 0)
@@ -74,5 +89,54 @@ namespace MvvmScaffoldFrame48.DLL.CommunicationTools
                 isConnect = true;
             }
         }
+        #endregion
+
+        #region 共有方法
+
+
+        /// <summary>
+        /// 根据参数模型读取数据
+        /// </summary>
+        public object ReadParameter(PlcParameterModel param)
+        {
+            // 1. 根据 Address 和 Length 从 PLC/Modbus 读取原始字节数组或寄存器数组
+            // byte[] rawData = ModbusClient.ReadRegisters(param.Address, param.Length);
+
+            switch (param.Type)
+            {
+                case PlcDataType.ValueBit: // ValueBit
+                    if (param is PlcValueBitParameterModel bitParam)
+                    {
+                        // 读取一个字节的位,并根据 bitAddress 提取特定位
+                        // return GetBitFromByte(rawData, bitParam.bitAddress);
+                        return true; // 示例返回
+                    }
+                    break;
+
+                case PlcDataType.Int32: // Int32
+                    if (param is PlcInt32ParameterModel intParam)
+                    {
+                        // 读取2个寄存器 (4字节),转换为 Int32
+                        // int value = BitConverter.ToInt32(rawData, 0);
+
+                        // 可选:进行范围检查
+                        // if (value > intParam.MaxValue || value < intParam.MinValue) { ... }
+
+                        return 123; // 示例返回
+                    }
+                    break;
+
+                case PlcDataType.Double: // Double
+                    if (param is PlcDouble64ParameterModel doubleParam)
+                    {
+                        // 读取4个寄存器 (8字节),转换为 Double
+                        // double value = BitConverter.ToDouble(rawData, 0);
+                        return 36.5; // 示例返回
+                    }
+                    break;
+            }
+            return null;
+        }
+        #endregion
     }
 }

+ 16 - 8
MvvmScaffoldFrame48.MODEL/StorageModel/PlcParameter/PlcParameterModel.cs

@@ -6,6 +6,14 @@ using System.Threading.Tasks;
 
 namespace MvvmScaffoldFrame48.Model.StorageModel.PlcParameter
 {
+    public enum PlcDataType
+    {
+        None = 0,
+        ValueBit = 1,
+        Int32 = 2,
+        Double = 3
+    }
+
     public class PlcParameterModel
     {
         //public string Name { get; set; }
@@ -15,7 +23,7 @@ namespace MvvmScaffoldFrame48.Model.StorageModel.PlcParameter
         /// 2:Int32
         /// 3:Double
         /// </summary>
-        public int Type { get; set; } = -1;
+        public PlcDataType Type { get; set; } = PlcDataType.None;
         public int Length { get; set; } = 1;
         public int Address { get; set; }
     }
@@ -24,7 +32,7 @@ namespace MvvmScaffoldFrame48.Model.StorageModel.PlcParameter
         public int bitAddress { get; set; }
         public PlcValueBitParameterModel(int Address,int bitAddress)
         {
-            this.Type = 1;
+            this.Type = PlcDataType.ValueBit;
             this.Address = Address;
             this.bitAddress = bitAddress;
         }
@@ -37,7 +45,7 @@ namespace MvvmScaffoldFrame48.Model.StorageModel.PlcParameter
 
         public PlcInt32ParameterModel(int Address)
         {
-            this.Type = 2;
+            this.Type = PlcDataType.Int32;
             this.Address = Address;
             this.Length = 2;
             this.MaxValue = Int32.MaxValue;
@@ -45,7 +53,7 @@ namespace MvvmScaffoldFrame48.Model.StorageModel.PlcParameter
         }
         public PlcInt32ParameterModel(int Address,int MaxValue,int MinValue)
         {
-            this.Type = 2;
+            this.Type = PlcDataType.Int32;
             this.Address = Address;
             this.Length = 2;
             this.MaxValue = MaxValue;
@@ -59,7 +67,7 @@ namespace MvvmScaffoldFrame48.Model.StorageModel.PlcParameter
         public double MinValue { get; set; }
         public PlcDouble64ParameterModel(int Address)
         {
-            this.Type = 3;
+            this.Type = PlcDataType.Double;
             this.Address = Address;
             this.Length = 4;
             this.MaxValue = double.MaxValue;
@@ -67,11 +75,11 @@ namespace MvvmScaffoldFrame48.Model.StorageModel.PlcParameter
         }
         public PlcDouble64ParameterModel(int Address,double MaxValue,double MinValue)
         {
-            this.Type = 3;
+            this.Type = PlcDataType.Double;
             this.Address = Address;
             this.Length = 4;
-            this.MaxValue = double.MaxValue;
-            this.MinValue = double.MinValue;
+            this.MaxValue = MaxValue;
+            this.MinValue = MinValue;
         }
     }
 }

+ 1 - 0
MvvmScaffoldFrame48.VIEWMODEL/MvvmScaffoldFrame48.ViewModel.csproj

@@ -64,6 +64,7 @@
   <ItemGroup>
     <Compile Include="ViewModel\AlarmViewModel.cs" />
     <Compile Include="ViewModel\CustomControlViewModel.cs" />
+    <Compile Include="ViewModel\PlcSettingViewModel.cs" />
     <Compile Include="ViewModel\TestViewModel.cs" />
     <Compile Include="ViewModel\BaseViewModel.cs" />
     <Compile Include="ViewModel\MainViewModel.cs" />

+ 1 - 1
MvvmScaffoldFrame48.VIEWMODEL/ViewModel/AlarmViewModel.cs

@@ -24,7 +24,7 @@ namespace MvvmScaffoldFrame48.ViewModel.ViewModel
         #region 绑定用Action方法
         public void AlarmTest(object obj)
         {
-            SystemAlarm.AlarmAlert(AlarmMessageList.系统异常, "ViewModel:ViewModel-AlarmViewModel-AlarmTest");
+            SystemAlarm.AlarmAlert(AlarmMessageList.系统异常,"System Error","系统异常", "ViewModel:ViewModel-AlarmViewModel-AlarmTest");
             var Alarms = SystemAlarm.GetAlarm();
             Alarm.Clear();
             foreach (var alarm in Alarms)

+ 67 - 0
MvvmScaffoldFrame48.VIEWMODEL/ViewModel/PlcSettingViewModel.cs

@@ -0,0 +1,67 @@
+using MvvmScaffoldFrame48.DLL.CommunicationTools;
+using MvvmScaffoldFrame48.DLL.ThreadManager;
+using MvvmScaffoldFrame48.Model.StorageModel.PlcParameter;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace MvvmScaffoldFrame48.ViewModel.ViewModel
+{
+    public class PlcSettingViewModel:BaseViewModel
+    {
+        #region 界面绑定属性
+        private string _ShowValue;
+        public string ShowValue
+        {
+            get { return _ShowValue; }
+            set 
+            {
+                _ShowValue = value;
+                OnPropertyChanged(nameof(ShowValue));
+            }
+        }
+        #endregion
+
+        #region 界面绑定事件
+        public ICommand CheckTestCommand { get; set; }
+        #endregion
+
+        #region 属性
+        private PlcCommunManager PlcCommunManager = null;
+        #endregion
+
+        #region 绑定用Action方法
+        private void CheckTest(object e)
+        {
+            PlcCommunManager.RegisterMap.TryGetValue("test3", out PlcParameterModel Result);
+            if (Result != null)
+            {
+                ShowValue = PlcCommunManager.ReadParameter(Result).ToString();
+            }
+        }
+        #endregion
+
+        #region 绑定用Predicate方法
+        private bool CanTrue(object obj)
+        {
+            return true;
+        }
+        private bool CanFalse(object obj)
+        {
+            return false;
+        }
+        #endregion
+
+        #region 其他方法
+
+        public PlcSettingViewModel()
+        {
+            PlcCommunManager = PlcCommunManager.Instance;
+            CheckTestCommand = new RelayCommand(CheckTest,CanTrue);
+        }
+        #endregion
+    }
+}

+ 7 - 0
MvvmScaffoldFrame48/MvvmScaffoldFrame48.csproj

@@ -86,6 +86,9 @@
     <Compile Include="WPFPage\CustomControlPage.xaml.cs">
       <DependentUpon>CustomControlPage.xaml</DependentUpon>
     </Compile>
+    <Compile Include="WPFPage\PlcSettingPage.xaml.cs">
+      <DependentUpon>PlcSettingPage.xaml</DependentUpon>
+    </Compile>
     <Compile Include="WPFPage\TestPage.xaml.cs">
       <DependentUpon>TestPage.xaml</DependentUpon>
     </Compile>
@@ -121,6 +124,10 @@
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>
     </Page>
+    <Page Include="WPFPage\PlcSettingPage.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
     <Page Include="WPFPage\TestPage.xaml">
       <SubType>Designer</SubType>
       <Generator>MSBuild:Compile</Generator>

+ 1 - 1
MvvmScaffoldFrame48/WPFFroms/MainWindow.xaml.cs

@@ -19,7 +19,7 @@ namespace MvvmScaffoldFrame48
 
         private void Window_Loaded(object sender, RoutedEventArgs e)
         {
-            Uri ShowUri = new Uri("WPFPage\\CustomControlPage.xaml", UriKind.Relative);
+            Uri ShowUri = new Uri("WPFPage\\PlcSettingPage.xaml", UriKind.Relative);
             ShowFrame.Navigate(ShowUri);
         }
     }

+ 16 - 0
MvvmScaffoldFrame48/WPFPage/PlcSettingPage.xaml

@@ -0,0 +1,16 @@
+<Page x:Class="MvvmScaffoldFrame48.WPFPage.PlcSettingPage"
+      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+      xmlns:local="clr-namespace:MvvmScaffoldFrame48.WPFPage"
+      mc:Ignorable="d" 
+      d:DesignHeight="450" d:DesignWidth="800"
+      Title="PlcSettingPage">
+
+    <Grid>
+        <Button Command="{Binding CheckTestCommand}" Content="Button" HorizontalAlignment="Left" Margin="450,158,0,0" VerticalAlignment="Top"/>
+        <TextBox Text="{Binding ShowValue}" HorizontalAlignment="Left" Margin="297,157,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/>
+
+    </Grid>
+</Page>

+ 31 - 0
MvvmScaffoldFrame48/WPFPage/PlcSettingPage.xaml.cs

@@ -0,0 +1,31 @@
+using MvvmScaffoldFrame48.ViewModel.ViewModel;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+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;
+
+namespace MvvmScaffoldFrame48.WPFPage
+{
+    /// <summary>
+    /// PlcSettingPage.xaml 的交互逻辑
+    /// </summary>
+    public partial class PlcSettingPage : Page
+    {
+        public PlcSettingPage()
+        {
+            InitializeComponent();
+            PlcSettingViewModel plcSettingViewModel = new PlcSettingViewModel();
+            this.DataContext = plcSettingViewModel;
+        }
+    }
+}