From 2aef482fa7431fb47eef94081ff23ec220f89820 Mon Sep 17 00:00:00 2001
From: hutongqing <hutongqing@hnkhzn.com>
Date: 星期五, 24 一月 2025 09:10:31 +0800
Subject: [PATCH] 1

---
 WIDESEAWCS_Server/WIDESEAWCS_Communicator/Siemens/SiemensS7Communicator.cs |  563 ++++++++++++++++++++++++++++++-------------------------
 1 files changed, 306 insertions(+), 257 deletions(-)

diff --git a/WIDESEAWCS_Server/WIDESEAWCS_Communicator/Siemens/SiemensS7Communicator.cs b/WIDESEAWCS_Server/WIDESEAWCS_Communicator/Siemens/SiemensS7Communicator.cs
index a96406a..c695b74 100644
--- a/WIDESEAWCS_Server/WIDESEAWCS_Communicator/Siemens/SiemensS7Communicator.cs
+++ b/WIDESEAWCS_Server/WIDESEAWCS_Communicator/Siemens/SiemensS7Communicator.cs
@@ -20,12 +20,15 @@
 using HslCommunication.LogNet;
 using HslCommunication.Profinet.Siemens;
 using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
 using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using System.Net;
+using System.Net.NetworkInformation;
 using System.Reflection;
 using System.Text;
 using System.Threading.Tasks;
@@ -37,7 +40,7 @@
     /// 瑗块棬瀛怱7閫氳绫�
     /// </summary>
     [Description("瑗块棬瀛怱7")]
-    public class SiemensS7 : BaseCommunicator, IDisposable
+    public class SiemensS7 : BaseCommunicator
     {
         #region Private Member
         /// <summary>
@@ -60,9 +63,14 @@
         /// </summary>
         private bool _connected;
 
+        /// <summary>
+        /// PLC鍚嶇О
+        /// </summary>
         private string _name;
 
         private ILogNet _logNet;
+
+        private bool _isPing = true;
         #endregion Private Member
 
         #region Public Member
@@ -71,8 +79,14 @@
         /// </summary>
         public override bool IsConnected => _connected;
 
+        /// <summary>
+        /// PLC鍚嶇О
+        /// </summary>
         public override string Name => _name;
 
+        /// <summary>
+        /// PLC璇诲啓鏃ュ織璁板綍
+        /// </summary>
         public override ILogNet LogNet => _logNet;
         #endregion Public Member
 
@@ -82,10 +96,11 @@
         /// </summary>
         /// <param name="ipAddress">璁惧鐨処P鍦板潃</param>
         /// <param name="port">杩炴帴浣跨敤鐨勭鍙e彿</param>
+        /// <param name="name">璁惧鍚嶇О</param>
         public SiemensS7(string ipAddress, int port, string name)
         {
             string path = AppDomain.CurrentDomain.BaseDirectory + $"Log_PLCReadWrite\\{name}";
-            _logNet = new LogNetFileSize(path, 3 * 1024 * 1024, 100);
+            _logNet = new LogNetFileSize(path, 10 * 1024 * 1024, 100);
 
             bool ipCheck = IPAddress.TryParse(ipAddress, out IPAddress? address);
             if (!ipCheck)
@@ -108,7 +123,7 @@
         /// <param name="operateResult">HSLCommunication璇诲彇鐨凮perateResult<T>瀵硅薄</param>
         /// <returns>濡傛灉璇诲彇鎴愬姛锛岃繑鍥炶鍙栫粨鏋滐紝璇诲彇澶辫触锛屾姏鍑鸿嚜瀹氫箟閫氳寮傚父</returns>
         /// <exception cref="CommunicationException">鑷畾涔夐�氳寮傚父绫�</exception>
-        private object? GetContent<T>(OperateResult<T> operateResult, string address)
+        private object GetContent<T>(OperateResult<T> operateResult, string address)
         {
             try
             {
@@ -116,14 +131,13 @@
                 {
                     throw new CommunicationException(string.Format(CommunicationExceptionMessage.ReadFailedException, typeof(T).Name, address, operateResult.Message), CommunicationErrorType.ReadFailed);
                 }
-                return operateResult.Content;
+                return operateResult.Content ?? throw new CommunicationException(string.Format(CommunicationExceptionMessage.ReadDataIsNull, address), CommunicationErrorType.ReadFailed);
             }
             catch (Exception ex)
             {
-                LogNet.WriteException(Name, $"銆恵Name}銆慞LC璇诲彇寮傚父锛屽湴鍧�锛氥�恵address}銆戯紝閿欒淇℃伅锛氥�恵ex.Message}銆�", ex);
-                throw new CommunicationException(ex.Message, CommunicationErrorType.ReadException, innerException: ex);
+                LogNet.WriteException(Name, ex.Message, ex);
+                throw new CommunicationException(ex.Message, CommunicationErrorType.ReadFailed, innerException: ex);
             }
-
         }
 
         /// <summary>
@@ -137,10 +151,14 @@
         /// <exception cref="CommunicationException"></exception>
         private bool GetResult<T>(OperateResult operateResult, string address, T value) where T : notnull
         {
-            string logMsg = "";
+            if (value is Array)
+            {
+                return operateResult.IsSuccess;
+            }
+            StringBuilder stringBuilder = new StringBuilder();
             try
             {
-                logMsg += $"銆恵Name}銆慞LC鍐欏叆鏁版嵁锛屽湴鍧�锛氥�恵address}銆戯紝鍐欏叆鐨勬暟鎹細銆恵value}銆憑Environment.NewLine}";
+                stringBuilder.AppendLine(string.Format(CommunicationInfoMessage.WriteData, address, value));
                 if (!operateResult.IsSuccess)
                 {
                     throw new CommunicationException(string.Format(CommunicationExceptionMessage.WriteFailedException, typeof(T).Name, address, value, operateResult.Message), CommunicationErrorType.WriteFailed);
@@ -151,30 +169,31 @@
                     for (int i = 0; i < 5; i++)
                     {
                         T readValue = Read<T>(address);
-                        logMsg += $"銆恵Name}銆慞LC鍐欏叆鍚庤鍙栨暟鎹紝鍦板潃锛氥�恵address}銆戯紝璇诲彇鐨勬暟鎹細銆恵value}銆憑Environment.NewLine}";
+                        stringBuilder.AppendLine(string.Format(CommunicationInfoMessage.WriteAfterRead, address, value));
                         obj = readValue;
                         if (readValue.Equals(value))
                         {
-                            logMsg += $"銆恵Name}銆慞LC鍐欏叆鍚庤鍙栨暟鎹牎楠屾垚鍔燂紝鍦板潃锛氥�恵address}銆戯紝璇诲彇鐨勬暟鎹細銆恵value}銆戯紝鍐欏叆鐨勬暟鎹細銆恵value}銆憑Environment.NewLine}";
+                            stringBuilder.AppendLine(string.Format(CommunicationInfoMessage.WriteAndReadCheckSuccess, address, value, readValue));
                             return true;
                         }
-                        else if(i < 4)
+                        else if (i < 4)
                         {
                             Write(address, value);
                         }
                     }
-
-                    logMsg += $"銆恵Name}銆慞LC鍐欏叆鍚庤鍙栨暟鎹牎楠屽け璐ワ紝鍦板潃锛氥�恵address}銆戯紝璇诲彇鐨勬暟鎹細銆恵value}銆戯紝鍐欏叆鐨勬暟鎹細銆恵value}銆憑Environment.NewLine}";
-
-                    throw new CommunicationException(string.Format(CommunicationExceptionMessage.ReadWriteDifferentException, typeof(T).Name, address, value, obj), CommunicationErrorType.WriteFailed);
+                    stringBuilder.AppendLine(string.Format(CommunicationExceptionMessage.WriteAndReadCheckFaild, address, value, obj));
+                    throw new CommunicationException(stringBuilder.ToString(), CommunicationErrorType.WriteFailed);
                 }
             }
             catch (Exception ex)
             {
-                LogNet.WriteException(Name, $"銆恵Name}銆慞LC鍐欏叆寮傚父锛屽湴鍧�锛氥�恵address}銆戯紝鍐欏叆鐨勬暟鎹細銆恵value}銆戯紝閿欒淇℃伅锛氥�恵ex.Message}銆�", ex);
+                LogNet.WriteException(Name, ex.Message, ex);
                 throw new CommunicationException(ex.Message, CommunicationErrorType.WriteFailed, innerException: ex);
             }
-
+            finally
+            {
+                LogNet.WriteInfo(Name, stringBuilder.ToString());
+            }
         }
 
         /// <summary>
@@ -211,64 +230,138 @@
                     case TypeCode.Char:
                         return plc.Write(address, Convert.ToChar(value));
                     default:
+                        if (value is int[])
+                        {
+                            return plc.Write(address, value as int[]);
+                        }
+                        else if (value is uint[])
+                        {
+                            return plc.Write(address, value as uint[]);
+                        }
+                        else if (value is short[])
+                        {
+                            return plc.Write(address, value as short[]);
+                        }
+                        else if (value is ushort[])
+                        {
+                            return plc.Write(address, value as ushort[]);
+                        }
+                        else if (value is bool[])
+                        {
+                            return plc.Write(address, value as bool[]);
+                        }
+                        else if (value is float[])
+                        {
+                            return plc.Write(address, value as float[]);
+                        }
+                        else if (value is double[])
+                        {
+                            return plc.Write(address, value as double[]);
+                        }
+                        else if (value is byte[])
+                        {
+                            return plc.Write(address, value as byte[]);
+                        }
                         throw new CommunicationException(string.Format(CommunicationExceptionMessage.DataTypeErrorException, type.Name, address), CommunicationErrorType.TypeError);
                 }
-
-
             }
             catch (CommunicationException ex)
             {
-                throw new CommunicationException($"鍐欏叆閿欒锛�" + ex.Message, ex.ErrorType, ex.ErrorCode, ex.InnerException);
+                throw new CommunicationException(ex.Message, ex.ErrorType);
             }
             catch (Exception ex)
             {
                 //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-            }
-            finally
-            {
-
+                throw new CommunicationException(string.Format(CommunicationExceptionMessage.DataTypeErrorException, address, value), CommunicationErrorType.TypeError, innerException: ex);
             }
         }
 
-        private object Read(string address, TypeCode typeCode)
+        private object Read(string address, TypeCode typeCode, ushort length = 1)
         {
             try
             {
                 switch (typeCode)
                 {
                     case TypeCode.Int32:
-                        return (int)GetContent(plc.ReadInt32(address), address);
+                        if (length > 1)
+                            return (int[])GetContent(plc.ReadInt32(address, length), address);
+                        else
+                            return (int)GetContent(plc.ReadInt32(address), address);
                     case TypeCode.UInt32:
-                        return (uint)GetContent(plc.ReadUInt32(address), address);
+                        if (length > 1)
+                            return (uint[])GetContent(plc.ReadUInt32(address, length), address);
+                        else
+                            return (uint)GetContent(plc.ReadUInt32(address), address);
                     case TypeCode.Int16:
-                        return (short)GetContent(plc.ReadInt16(address), address);
+                        if (length > 1)
+                            return (short[])GetContent(plc.ReadInt16(address, length), address);
+                        else
+                            return (short)GetContent(plc.ReadInt16(address), address);
                     case TypeCode.UInt16:
-                        return (ushort)GetContent(plc.ReadUInt16(address), address);
+                        if (length > 1)
+                            return (ushort[])GetContent(plc.ReadUInt16(address, length), address);
+                        else
+                            return (ushort)GetContent(plc.ReadUInt16(address), address);
                     case TypeCode.Single:
-                        return (float)GetContent(plc.ReadFloat(address), address);
+                        if (length > 1)
+                            return (float[])GetContent(plc.ReadFloat(address, length), address);
+                        else
+                            return (float)GetContent(plc.ReadFloat(address), address);
                     case TypeCode.Boolean:
-                        return (bool)GetContent(plc.ReadBool(address), address);
+                        if (length > 1)
+                            return (bool[])GetContent(plc.ReadBool(address, length), address);
+                        else
+                            return (bool)GetContent(plc.ReadBool(address), address);
                     case TypeCode.Byte:
+                        if (length > 1)
+                            return (byte)GetContent(plc.Read(address, length), address);
                         return (byte)GetContent(plc.ReadByte(address), address);
                     case TypeCode.String:
-                        return (string)GetContent(plc.ReadString(address), address);
+                        if (length > 1)
+                            return (string)GetContent(plc.ReadString(address, length), address);
+                        else
+                            return (string)GetContent(plc.ReadString(address), address);
                     case TypeCode.Char:
+                        if (length > 1)
+                            return (char)GetContent(plc.Read(address, length), address);
                         return (char)GetContent(plc.ReadByte(address), address);
                     default:
-                        throw new CommunicationException($"璇诲彇鏁版嵁澶辫触,鏈畾涔夋暟鎹被鍨�:銆恵typeCode}銆�,鍦板潃:銆恵address}銆�", CommunicationErrorType.TypeError);
+                        throw new CommunicationException(string.Format(CommunicationExceptionMessage.DataTypeErrorException, typeCode.ToString(), address), CommunicationErrorType.TypeError);
                 }
             }
             catch (CommunicationException ex)
             {
                 //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw ex;
+                throw new CommunicationException(ex.Message, ex.ErrorType);
             }
             catch (Exception ex)
             {
                 //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
                 throw new CommunicationException($"璇诲彇鏁版嵁寮傚父,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.ReadException, innerException: ex);
             }
+        }
+
+        private void Ping()
+        {
+            Task.Run(() =>
+            {
+                while (_isPing)
+                {
+                    try
+                    {
+                        IPStatus status = plc.IpAddressPing();
+                        if (status == IPStatus.Success)
+                            _connected = true;
+                        else
+                            _connected = false;
+                    }
+                    finally
+                    {
+                        Thread.Sleep(100);
+                    }
+                }
+            });
+
         }
         #endregion
 
@@ -292,15 +385,15 @@
                 _connected = operateResult.IsSuccess;//灏嗚繛鎺ユ槸鍚︽垚鍔熻祴鍊肩粰褰撳墠閫氳鍣ㄦ槸鍚﹀凡杩炴帴鍒癙LC
 
                 if (_connected)
-                    LogNet.WriteInfo(Name, $"銆恵Name}銆慞LC杩炴帴鎴愬姛锛孖P銆恵_ipAddress}銆戯紝Port銆恵_port}銆�");
+                    LogNet.WriteInfo(Name, string.Format(CommunicationInfoMessage.ConnectSuccess, _ipAddress, _port));
                 else
-                    LogNet.WriteError(Name, $"銆恵Name}銆慞LC杩炴帴澶辫触锛孖P銆恵_ipAddress}銆戯紝Port銆恵_port}銆戯紝閿欒淇℃伅锛歿operateResult.Message}");
-
+                    LogNet.WriteError(Name, string.Format(CommunicationExceptionMessage.ConnectFaild, _ipAddress, _port, operateResult.Message));
+                Ping();
                 return operateResult.IsSuccess;
             }
             catch (Exception ex)
             {
-                LogNet.WriteException(Name, $"銆恵Name}銆慞LC杩炴帴寮傚父锛孖P銆恵_ipAddress}銆戯紝Port銆恵_port}銆�", ex);
+                LogNet.WriteException(Name, string.Format(CommunicationExceptionMessage.ConnectFaild, _ipAddress, _port, ex.Message), ex);
                 //杩炴帴寮傚父鏃舵姏鍑鸿嚜瀹氫箟寮傚父绫�
                 throw new CommunicationException(ex.Message, CommunicationErrorType.ConnectionFailed, innerException: ex);
             }
@@ -341,20 +434,7 @@
         /// <exception cref="CommunicationException">鑷畾涔夐�氳寮傚父绫�</exception>
         public override byte[] Read(string address, int length)
         {
-            try
-            {
-                return (byte[])GetContent(plc.Read(address, (ushort)length), address);
-            }
-            catch (CommunicationException ex)
-            {
-                //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw ex;
-            }
-            catch (Exception ex)
-            {
-                //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw new CommunicationException($"璇诲彇鏁版嵁寮傚父:{ex.Message}", CommunicationErrorType.ReadFailed, innerException: ex);
-            }
+            return (byte[])GetContent(plc.Read(address, (ushort)length), address);
         }
 
         /// <summary>
@@ -367,22 +447,14 @@
         /// <exception cref="CommunicationException">鑷畾涔夐�氳寮傚父绫�</exception>
         public override T Read<T>(string address)
         {
-            try
-            {
-                Type type = typeof(T);
-                return (T)Read(address, Type.GetTypeCode(type));
+            Type type = typeof(T);
+            return (T)Read(address, Type.GetTypeCode(type));
+        }
 
-            }
-            catch (CommunicationException ex)
-            {
-                //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw ex;
-            }
-            catch (Exception ex)
-            {
-                //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw new CommunicationException($"璇诲彇鏁版嵁寮傚父,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.ReadException, innerException: ex);
-            }
+        public override T[] Read<T>(string address, ushort length)
+        {
+            Type type = typeof(T);
+            return (T[])Read(address, Type.GetTypeCode(type), length);
         }
 
         /// <summary>
@@ -394,20 +466,7 @@
         /// <exception cref="CommunicationException">鑷畾涔夐�氳寮傚父绫�</exception>
         public override object ReadAsObj(string address, string dataType)
         {
-            try
-            {
-                return Read(address, SiemensDBDataType.GetTypeCode(dataType));
-            }
-            catch (CommunicationException ex)
-            {
-                //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw ex;
-            }
-            catch (Exception ex)
-            {
-                //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw new CommunicationException($"璇诲彇鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.ReadException, innerException: ex);
-            }
+            return Read(address, SiemensDBDataType.GetTypeCode(dataType));
         }
         #endregion
 
@@ -437,7 +496,7 @@
             catch (Exception ex)
             {
                 //鍐欏叆寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鍦板潃:銆恵address}銆�,閿欒淇℃伅: {ex.Message}", CommunicationErrorType.ReadFailed, innerException: ex);
+                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鍦板潃:銆恵address}銆�,閿欒淇℃伅: {ex.Message}", CommunicationErrorType.WriteFailed, innerException: ex);
             }
         }
 
@@ -451,20 +510,13 @@
         /// <exception cref="NotImplementedException"></exception>
         public override bool Write<T>(string address, T value)
         {
-            try
-            {
-                return GetResult(Write(address, value), address, value);
-            }
-            catch (CommunicationException ex)
-            {
-                //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw ex;
-            }
-            catch (Exception ex)
-            {
-                //璇诲彇寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw new CommunicationException($"璇诲彇鏁版嵁寮傚父,鍦板潃:銆恵address}銆�,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-            }
+            return GetResult(Write(address, value), address, value);
+        }
+
+
+        public override bool Write<T>(string address, T[] values)
+        {
+            return GetResult(Write(address, values), address, values);
         }
 
         /// <summary>
@@ -475,172 +527,141 @@
         /// <param name="value">瑕佸啓鍏ョ殑鏁版嵁銆�</param>
         /// <returns>濡傛灉鍐欏叆鎴愬姛鍒欒繑鍥瀟rue锛屽け璐ュ垯鎶涘嚭鑷畾涔夐�氳寮傚父銆�</returns>
         /// <exception cref="CommunicationException"></exception>
-        public override bool WriteObj(string address, string dataType, object value)
+        public override bool WriteObj(string address, string dataType, [NotNull] object value)
         {
-            try
+            bool obj = false;
+            switch (dataType.ToLower())
             {
-                bool obj = false;
-                switch (dataType.ToLower())
-                {
-                    case SiemensDBDataType.DataType_DInt:
+                case SiemensDBDataType.DataType_DInt:
+                    {
+                        int writeVal;
+                        try
                         {
-                            int writeVal;
-                            try
-                            {
-                                writeVal = Convert.ToInt32(value);
-                            }
-                            catch (Exception ex)
-                            {
-                                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�,鏁版嵁绫诲瀷杞崲閿欒,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-                            }
-                            obj = GetResult(Write(address, writeVal), address, writeVal);
+                            writeVal = Convert.ToInt32(value);
                         }
-                        break;
-                    case SiemensDBDataType.DataType_DW:
+                        catch (Exception ex)
                         {
-                            uint writeVal;
-                            try
-                            {
-                                writeVal = Convert.ToUInt32(value);
-                            }
-                            catch (Exception ex)
-                            {
-                                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�,鏁版嵁绫诲瀷杞崲閿欒,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-                            }
-                            obj = GetResult(Write(address, writeVal), address, writeVal);
+                            throw new CommunicationException(string.Format(CommunicationExceptionMessage.TypeConvertError, dataType, address, value, ex.Message), CommunicationErrorType.TypeError, innerException: ex);
                         }
-                        break;
-                    case SiemensDBDataType.DataType_Int:
+                        obj = GetResult(Write(address, writeVal), address, writeVal);
+                    }
+                    break;
+                case SiemensDBDataType.DataType_DW:
+                    {
+                        uint writeVal;
+                        try
                         {
-                            short writeVal;
-                            try
-                            {
-                                writeVal = Convert.ToInt16(value);
-                            }
-                            catch (Exception ex)
-                            {
-                                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�,鏁版嵁绫诲瀷杞崲閿欒,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-                            }
-                            obj = GetResult(Write(address, writeVal), address, writeVal);
+                            writeVal = Convert.ToUInt32(value);
                         }
-
-                        break;
-                    case SiemensDBDataType.DataType_W:
+                        catch (Exception ex)
                         {
-                            ushort writeVal;
-                            try
-                            {
-                                writeVal = Convert.ToUInt16(value);
-                            }
-                            catch (Exception ex)
-                            {
-                                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�,鏁版嵁绫诲瀷杞崲閿欒,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-                            }
-                            obj = GetResult(Write(address, writeVal), address, writeVal);
+                            throw new CommunicationException(string.Format(CommunicationExceptionMessage.TypeConvertError, dataType, address, value, ex.Message), CommunicationErrorType.TypeError, innerException: ex);
                         }
-
-                        break;
-                    case SiemensDBDataType.DataType_Float:
+                        obj = GetResult(Write(address, writeVal), address, writeVal);
+                    }
+                    break;
+                case SiemensDBDataType.DataType_Int:
+                    {
+                        short writeVal;
+                        try
                         {
-                            float writeVal;
-                            try
-                            {
-                                writeVal = Convert.ToSingle(value);
-                            }
-                            catch (Exception ex)
-                            {
-                                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�,鏁版嵁绫诲瀷杞崲閿欒,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-                            }
-                            obj = GetResult(Write(address, writeVal), address, writeVal);
+                            writeVal = Convert.ToInt16(value);
                         }
-
-                        break;
-                    case SiemensDBDataType.DataType_Bool:
+                        catch (Exception ex)
                         {
-                            bool writeVal;
-                            try
-                            {
-                                writeVal = Convert.ToBoolean(value);
-                            }
-                            catch (Exception ex)
-                            {
-                                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�,鏁版嵁绫诲瀷杞崲閿欒,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-                            }
-                            obj = GetResult(Write(address, writeVal), address, writeVal);
+                            throw new CommunicationException(string.Format(CommunicationExceptionMessage.TypeConvertError, dataType, address, value, ex.Message), CommunicationErrorType.TypeError, innerException: ex);
                         }
-
-                        break;
-                    case SiemensDBDataType.DataType_Byte:
+                        obj = GetResult(Write(address, writeVal), address, writeVal);
+                    }
+                    break;
+                case SiemensDBDataType.DataType_W:
+                    {
+                        ushort writeVal;
+                        try
                         {
-                            byte writeVal;
-                            try
-                            {
-                                writeVal = Convert.ToByte(value);
-                            }
-                            catch (Exception ex)
-                            {
-                                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�,鏁版嵁绫诲瀷杞崲閿欒,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-                            }
-                            obj = GetResult(Write(address, writeVal), address, writeVal);
+                            writeVal = Convert.ToUInt16(value);
                         }
-
-                        break;
-                    case SiemensDBDataType.DataType_ByteArray:
+                        catch (Exception ex)
                         {
-                            byte[] writeVal;
-                            try
-                            {
-                                writeVal = (byte[])value;
-                            }
-                            catch (Exception ex)
-                            {
-                                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�,鏁版嵁绫诲瀷杞崲閿欒,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-                            }
-                            obj = GetResult(Write(address, writeVal), address, writeVal);
+                            throw new CommunicationException(string.Format(CommunicationExceptionMessage.TypeConvertError, dataType, address, value, ex.Message), CommunicationErrorType.TypeError, innerException: ex);
                         }
-
-                        break;
-                    case SiemensDBDataType.DataType_String:
+                        obj = GetResult(Write(address, writeVal), address, writeVal);
+                    }
+                    break;
+                case SiemensDBDataType.DataType_Float:
+                    {
+                        float writeVal;
+                        try
                         {
-                            string writeVal;
-                            try
-                            {
-                                writeVal = value.ToString();
-                            }
-                            catch (Exception ex)
-                            {
-                                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�,鏁版嵁绫诲瀷杞崲閿欒,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-                            }
-                            obj = GetResult(Write(address, writeVal), address, writeVal);
+                            writeVal = Convert.ToSingle(value);
                         }
+                        catch (Exception ex)
+                        {
+                            throw new CommunicationException(string.Format(CommunicationExceptionMessage.TypeConvertError, dataType, address, value, ex.Message), CommunicationErrorType.TypeError, innerException: ex);
+                        }
+                        obj = GetResult(Write(address, writeVal), address, writeVal);
+                    }
+                    break;
+                case SiemensDBDataType.DataType_Bool:
+                    {
+                        bool writeVal;
+                        try
+                        {
+                            writeVal = Convert.ToBoolean(value);
+                        }
+                        catch (Exception ex)
+                        {
+                            throw new CommunicationException(string.Format(CommunicationExceptionMessage.TypeConvertError, dataType, address, value, ex.Message), CommunicationErrorType.TypeError, innerException: ex);
+                        }
+                        obj = GetResult(Write(address, writeVal), address, writeVal);
+                    }
+                    break;
+                case SiemensDBDataType.DataType_Byte:
+                    {
+                        byte writeVal;
+                        try
+                        {
+                            writeVal = Convert.ToByte(value);
+                        }
+                        catch (Exception ex)
+                        {
+                            throw new CommunicationException(string.Format(CommunicationExceptionMessage.TypeConvertError, dataType, address, value, ex.Message), CommunicationErrorType.TypeError, innerException: ex);
+                        }
+                        obj = GetResult(Write(address, writeVal), address, writeVal);
+                    }
+                    break;
+                case SiemensDBDataType.DataType_String:
+                    {
+                        string writeVal;
+                        try
+                        {
+                            writeVal = value.ToString();
+                        }
+                        catch (Exception ex)
+                        {
+                            throw new CommunicationException(string.Format(CommunicationExceptionMessage.TypeConvertError, dataType, address, value, ex.Message), CommunicationErrorType.TypeError, innerException: ex);
+                        }
+                        obj = GetResult(Write(address, writeVal), address, writeVal);
+                    }
 
-                        break;
-                    case SiemensDBDataType.DataType_Char:
+                    break;
+                case SiemensDBDataType.DataType_Char:
 
-                        //obj = GetResult(plc.Write(address, (int)value), address, (int)value);
-                        break;
-                    case SiemensDBDataType.DataType_CharArray:
-
-                        break;
-                    default:
-                        throw new CommunicationException($"鍐欏叆鏁版嵁澶辫触,鏈畾涔夋暟鎹被鍨�:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�", CommunicationErrorType.TypeError);
-                }
-                return obj;
+                    break;
+                default:
+                    throw new CommunicationException(string.Format(CommunicationExceptionMessage.DataTypeErrorException, dataType, address), CommunicationErrorType.TypeError);
             }
-            catch (CommunicationException ex)
-            {
-                //鍐欏叆寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw ex;
-            }
-            catch (Exception ex)
-            {
-                //鍐欏叆寮傚父鏃舵姏鍑鸿嚜瀹氫箟閫氳寮傚父绫�
-                throw new CommunicationException($"鍐欏叆鏁版嵁寮傚父,鏁版嵁绫诲瀷:銆恵dataType}銆�,鍦板潃:銆恵address}銆�,鏁版嵁:銆恵value}銆�,閿欒淇℃伅:{ex.Message}", CommunicationErrorType.TypeError, innerException: ex);
-            }
+            return obj;
         }
         #endregion
 
         #region ReadCustomer
+        /// <summary>
+        /// 璇诲彇鑷畾涔夌殑鏁版嵁绫诲瀷锛岄渶瑕佺户鎵胯嚜IDataTransfer鎺ュ彛锛岃繑鍥炰竴涓柊鐨勭被鍨嬬殑瀹炰緥瀵硅薄銆�
+        /// </summary>
+        /// <typeparam name="T">鑷畾涔夌殑鏁版嵁绫诲瀷娉涘瀷銆�</typeparam>
+        /// <param name="address">婧愬湴鍧�锛屽叿浣撴牸寮忓彇鍐充簬浣跨敤鐨勫伐涓氬崗璁��</param>
+        /// <returns>鎴愬姛杩斿洖鑷畾涔夌被鍨嬫暟鎹紝澶辫触鎶涘嚭寮傚父銆�</returns>
         public override T ReadCustomer<T>(string address)
         {
             try
@@ -652,63 +673,91 @@
                 LogNet.WriteException(Name, $"銆恵Name}銆慞LC璇诲彇寮傚父锛屽湴鍧�锛氥�恵address}銆戯紝閿欒淇℃伅锛氥�恵ex.Message}銆�", ex);
                 throw new CommunicationException(ex.Message, CommunicationErrorType.ReadException, innerException: ex);
             }
-
         }
         #endregion
 
         #region WriteCustomer
-        public override bool WriteCustomer<T>(string address, T value)
+        /// <summary>
+        /// 鍐欏叆鑷畾涔夌被鍨嬬殑鏁版嵁锛岃绫诲瀷蹇呴』缁ф壙鑷狪DataTransfer鎺ュ彛銆�
+        /// </summary>
+        /// <typeparam name="T">鑷畾涔夌殑鏁版嵁绫诲瀷娉涘瀷銆�</typeparam>
+        /// <param name="address">婧愬湴鍧�锛屽叿浣撴牸寮忓彇鍐充簬浣跨敤鐨勫伐涓氬崗璁��</param>
+        /// <param name="value">瑕佸啓鍏ユ暟鎹��</param>
+        /// <returns>濡傛灉鍐欏叆鎴愬姛鍒欒繑鍥瀟rue锛屽け璐ュ垯鎶涘嚭寮傚父銆�</returns>
+        public override bool WriteCustomer<T>(string address, [NotNull] T value)
         {
+            StringBuilder stringBuilder = new StringBuilder();
             try
             {
                 OperateResult operateResult = plc.WriteCustomer(address, value);
+                stringBuilder.AppendLine(string.Format(CommunicationInfoMessage.WriteData, address, JsonConvert.SerializeObject(value)));
                 if (operateResult.IsSuccess)
                 {
+                    object? obj = null;
                     for (int i = 0; i < 5; i++)
                     {
                         T readValue = ReadCustomer<T>(address);
+                        stringBuilder.AppendLine(string.Format(CommunicationInfoMessage.WriteAfterRead, address, JsonConvert.SerializeObject(readValue)));
+                        obj = readValue;
                         PropertyInfo[] propertyInfos = typeof(T).GetProperties();
-                        foreach (var item in propertyInfos)
+                        for (int j = 0; j < propertyInfos.Length; j++)
                         {
-                            object writeValueItem = item.GetValue(value);
-                            if (writeValueItem != null)
+                            object? writeValueItem = propertyInfos[j].GetValue(value);
+                            object? readValueItem = propertyInfos[j].GetValue(readValue);
+                            if (writeValueItem?.Equals(readValueItem) ?? false)
                             {
-                                object readValueItem = item.GetValue(readValue);
-                                if (writeValueItem.Equals(readValueItem))
-                                {
-                                    break;
-                                }
-                                else
-                                {
-                                    plc.WriteCustomer(address, value);
-                                }
-                                throw new CommunicationException(string.Format(CommunicationExceptionMessage.ReadWriteDifferentException, typeof(T).Name, address, JsonConvert.SerializeObject(value), JsonConvert.SerializeObject(readValue)), CommunicationErrorType.WriteFailed);
+                                stringBuilder.AppendLine(string.Format(CommunicationInfoMessage.WriteAndReadCheckSuccess, address, JsonConvert.SerializeObject(value), JsonConvert.SerializeObject(readValue)));
                             }
+                            else
+                            {
+                                break;
+                            }
+                            if (j == propertyInfos.Length - 1)
+                                return true;
                         }
+
+                        plc.WriteCustomer(address, value);
                     }
+                    stringBuilder.AppendLine(string.Format(CommunicationExceptionMessage.WriteAndReadCheckFaild, address, JsonConvert.SerializeObject(value), JsonConvert.SerializeObject(obj)));
+                    throw new CommunicationException(string.Format(CommunicationExceptionMessage.WriteAndReadCheckFaild, address, JsonConvert.SerializeObject(value), JsonConvert.SerializeObject(obj)), CommunicationErrorType.WriteFailed);
                 }
                 else
                 {
                     throw new CommunicationException(string.Format(CommunicationExceptionMessage.WriteFailedException, typeof(T).Name, address, JsonConvert.SerializeObject(value), operateResult.Message), CommunicationErrorType.WriteFailed);
                 }
-                return operateResult.IsSuccess;
             }
             catch (Exception ex)
             {
-                LogNet.WriteException(Name, $"銆恵Name}銆慞LC鍐欏叆寮傚父锛屽湴鍧�锛氥�恵address}銆戯紝鍐欏叆鐨勬暟鎹細銆恵JsonConvert.SerializeObject(value)}銆戯紝閿欒淇℃伅锛氥�恵ex.Message}銆�", ex);
+                LogNet.WriteException(Name, ex.Message, ex);
                 throw new CommunicationException(ex.Message, CommunicationErrorType.WriteFailed, innerException: ex);
             }
-
+            finally
+            {
+                LogNet.WriteInfo(Name, stringBuilder.ToString());
+            }
         }
         #endregion
 
-        // 鏄惧紡瀹炵幇IDisposable鎺ュ彛浠ユ彁渚涘瀮鍦惧洖鏀舵椂鐨勬竻鐞�  
-        public void Dispose()
+        /// <summary>
+        /// 鏄惧紡瀹炵幇IDisposable鎺ュ彛浠ユ彁渚涘瀮鍦惧洖鏀舵椂鐨勬竻鐞�
+        /// </summary>
+        public override void Dispose()
         {
+            _isPing = false;
             Disconnect();
+            plc.Dispose();
             GC.SuppressFinalize(this);
         }
 
+        /// <summary>
+        /// 绛夊緟鎸囧畾鍦板潃鐨勬硾鍨嬬被鍨嬪�间负鎸囧畾鐨勫��
+        /// </summary>
+        /// <typeparam name="T">鎸囧畾鐨勫�肩殑绫诲瀷娉涘瀷銆�</typeparam>
+        /// <param name="address">婧愬湴鍧�锛屽叿浣撴牸寮忓彇鍐充簬浣跨敤鐨勫伐涓氬崗璁��</param>
+        /// <param name="readInterval">璇诲彇鐨勯鐜囥��</param>
+        /// <param name="waitTimeout">绛夊緟鐨勮秴鏃舵椂闂达紝濡傛灉瓒呮椂鏃堕棿涓�-1鐨勮瘽锛屽垯鏄棤鏈熼檺绛夊緟銆�</param>
+        /// <param name="value">绛夊緟妫�娴嬬殑鍊�</param>
+        /// <returns>鏄惁绛夊緟鎴愬姛鐨勭粨鏋滃璞★紝涓�鏃﹂�氫俊澶辫触锛屾垨鏄瓑寰呰秴鏃跺氨杩斿洖澶辫触銆傚惁鍒欒繑鍥炴垚鍔燂紝骞跺憡鐭ヨ皟鐢ㄦ柟绛夊緟浜嗗涔呫��</returns>
         public override OperateResult<TimeSpan> Wait<T>(string address, int readInterval, int waitTimeout, T value)
         {
             TypeCode typeCode = Type.GetTypeCode(typeof(T));

--
Gitblit v1.9.3