From f703b278956736aa14c12d1d25c8e8f23b822760 Mon Sep 17 00:00:00 2001
From: kazelee <1847801760@qq.com>
Date: 星期四, 26 六月 2025 17:27:32 +0800
Subject: [PATCH] 优化国自辅助调度和任务推送逻辑

---
 device/ModbusFactory.cs |  516 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 459 insertions(+), 57 deletions(-)

diff --git a/device/ModbusFactory.cs b/device/ModbusFactory.cs
index 28578f8..83a15ae 100644
--- a/device/ModbusFactory.cs
+++ b/device/ModbusFactory.cs
@@ -8,6 +8,7 @@
 using System.Linq;
 
 using TcpClient = System.Net.Sockets.TcpClient;
+using System.IO;
 
 namespace HH.WCS.Mobox3.DSZSH.device {
     // 瀹氫箟Modbus閫氳鎺ュ彛
@@ -48,13 +49,31 @@
         /// <returns></returns>
         int[] ReadInputRegisters(int startingAddress, int quantity);
         /// <summary>
-        /// 
+        /// 鍐欏叆鍗曚釜绾垮湀
         /// </summary>
         /// <param name="coilAddress"></param>
         /// <param name="value"></param>
         bool WriteSingleCoil(int coilAddress, bool value);
+        /// <summary>
+        /// 鍐欏叆鍗曚釜瀵勫瓨鍣ㄦ暟鎹�+        /// </summary>
+        /// <param name="registerAddress"></param>
+        /// <param name="value"></param>
+        /// <returns></returns>
         bool WriteSingleRegister(int registerAddress, ushort value);
+        /// <summary>
+        /// 鍐欏叆澶氫釜绾垮湀
+        /// </summary>
+        /// <param name="startingAddress"></param>
+        /// <param name="values"></param>
+        /// <returns></returns>
         bool WriteMultipleCoils(int startingAddress, bool[] values);
+        /// <summary>
+        /// 鍐欏叆澶氫釜瀵勫瓨鍣ㄦ暟鎹�+        /// </summary>
+        /// <param name="startingAddress"></param>
+        /// <param name="values"></param>
+        /// <returns></returns>
         bool WriteMultipleRegisters(int startingAddress, int[] values);
     }
 
@@ -80,7 +99,15 @@
         }
 
         static void Test() {
-            var communicator = ModbusFactory.CreateCommunicator(ModbusCommunicationType.TcpSocket);
+            try {
+                var communicator = ModbusFactory.CreateCommunicator(ModbusCommunicationType.TcpSocket);
+
+                communicator.Link("127.0.0.1", 502);
+                var read = communicator.ReadInputRegisters(0, 5);
+            }
+            catch (Exception ex) {
+                LogHelper.InfoEx(ex);
+            }
         }
     }
 
@@ -134,16 +161,19 @@
 
         public bool[] ReadCoils(int startingAddress, int quantity) {
             bool[] res = new bool[0];
+            var client = _modbusClient;
             if (_modbusClient != null && IsConnected) {
+                var ip = client.IPAddress;
+                var port = client.Port;
                 try {
                     res = _modbusClient.ReadCoils(startingAddress, quantity);
                     if (res.Length != 0) {
                         //璇诲彇鎴愬姛
-                        LogHelper.Info($"璇诲彇鎴愬姛锛歊eadCoils");
+                        LogHelper.Info($"璇诲彇鎴愬姛锛歊eadCoils:IP:{ip},Port:{port}");
                     }
                     else {
                         //璇诲彇澶辫触
-                        LogHelper.Info($"璇诲彇澶辫触锛歊eadCoils");
+                        LogHelper.Info($"璇诲彇澶辫触锛歊eadCoils:IP:{ip},Port:{port}");
                     }
                 }
                 catch (Exception ex) {
@@ -151,23 +181,26 @@
                 }
             }
             else {
-                LogHelper.Info($"璁惧鏈繛鎺ワ紝璇诲彇澶辫触锛歊eadCoils");
+                LogHelper.Info($"鏈壘鍒癕odbus璁惧瀹炰緥瀵硅薄锛屾垨瀵硅薄鏈垚鍔熻繛鎺�);
             }
             return res;
         }
 
         public bool[] ReadDiscreteInputs(int startingAddress, int quantity) {
             bool[] res = new bool[0];
+            var client = _modbusClient;
             if (_modbusClient != null && IsConnected) {
+                var ip = client.IPAddress;
+                var port = client.Port;
                 try {
                     res = _modbusClient.ReadDiscreteInputs(startingAddress, quantity);
                     if (res.Length != 0) {
                         //璇诲彇鎴愬姛
-                        LogHelper.Info($"璇诲彇鎴愬姛锛歊eadDiscreteInputs");
+                        LogHelper.Info($"璇诲彇鎴愬姛锛歊eadDiscreteInputs:IP:{ip},Port:{port}");
                     }
                     else {
                         //璇诲彇澶辫触
-                        LogHelper.Info($"璇诲彇澶辫触锛歊eadDiscreteInputs");
+                        LogHelper.Info($"璇诲彇澶辫触锛歊eadDiscreteInputs:IP:{ip},Port:{port}");
                     }
                 }
                 catch (Exception ex) {
@@ -175,7 +208,7 @@
                 }
             }
             else {
-                LogHelper.Info($"璁惧鏈繛鎺ワ紝璇诲彇澶辫触锛歊eadDiscreteInputs");
+                LogHelper.Info($"鏈壘鍒癕odbus璁惧瀹炰緥瀵硅薄锛屾垨瀵硅薄鏈垚鍔熻繛鎺�);
             }
             return res;
         }
@@ -183,26 +216,28 @@
         public int[] ReadHoldingRegisters(int startingAddress, int quantity) {
             int[] res = new int[0];
             var client = _modbusClient;
-            var ip = client.IPAddress;
-            var port = client.Port;
             if (client != null && client.Connected) {
+                var ip = client.IPAddress;
+                var port = client.Port;
                 try {
                     //涓�釜瀵勫瓨鍣ㄦ槸16浣嶏紝杩斿洖2涓猧nt绫诲瀷
                     res = client.ReadHoldingRegisters(startingAddress, quantity);
                     if (res.Length != 0) {
                         //璇诲彇鎴愬姛
+                        LogHelper.Info($"璇诲彇鎴愬姛锛歊eadHoldingRegisters:IP:{ip},Port:{port}");
                     }
                     else {
                         //璇诲彇澶辫触
+                        LogHelper.Info($"璇诲彇澶辫触锛歊eadHoldingRegisters:IP:{ip},Port:{port}");
                     }
                 }
                 catch (Exception ex) {
                     //濡傛灉璇锋眰鏁伴噺瓒呭嚭淇濇寔瀵勫瓨鍣ㄧ殑鏈�ぇ鏁版嵁琛屾暟锛屼細鎶ラ敊
-                    LogHelper.Info($"鍙戠敓浜嗗紓甯�{ex.Message},IP:{ip},Port:{port}", "Error");
+                    LogHelper.InfoEx(ex);
                 }
             }
             else {
-                LogHelper.Info($"鏈壘鍒癕odbus璁惧瀹炰緥瀵硅薄:IP:{ip},Port:{port}");
+                LogHelper.Info($"鏈壘鍒癕odbus璁惧瀹炰緥瀵硅薄锛屾垨瀵硅薄鏈垚鍔熻繛鎺�);
             }
             return res;
         }
@@ -210,24 +245,26 @@
         public int[] ReadInputRegisters(int startingAddress, int quantity) {
             int[] res = new int[0];
             var client = _modbusClient;
-            var ip = client.IPAddress;
-            var port = client.Port;
             if (client != null && client.Connected) {
+                var ip = client.IPAddress;
+                var port = client.Port;
                 try {
                     res = client.ReadInputRegisters(startingAddress, quantity);
                     if (res.Length != 0) {
                         //璇诲彇鎴愬姛
+                        LogHelper.Info($"璇诲彇鎴愬姛锛歊eadInputRegisters:IP:{ip},Port:{port}");
                     }
                     else {
                         //璇诲彇澶辫触
+                        LogHelper.Info($"璇诲彇澶辫触锛歊eadInputRegisters:IP:{ip},Port:{port}");
                     }
                 }
                 catch (Exception ex) {
-
+                    LogHelper.InfoEx(ex);
                 }
             }
             else {
-
+                LogHelper.Info($"鏈壘鍒癕odbus璁惧瀹炰緥瀵硅薄锛屾垨瀵硅薄鏈垚鍔熻繛鎺�);
             }
             return res;
         }
@@ -235,25 +272,27 @@
         public bool WriteSingleCoil(int coilAddress, bool value) {
             var res = false;
             var client = _modbusClient;
-            var ip = client.IPAddress;
-            var port = client.Port;
             if (client != null && client.Connected) {
+                var ip = client.IPAddress;
+                var port = client.Port;
                 try {
                     client.WriteSingleCoil(coilAddress, value);
                     res = value == client.ReadCoils(coilAddress, 1)[0];
                     if (res) {
                         //鍐欏叆鎴愬姛
+                        LogHelper.Info($"鍐欏叆鎴愬姛锛歐riteSingleCoil:IP:{ip},Port:{port}");
                     }
                     else {
                         //鍐欏叆澶辫触
+                        LogHelper.Info($"鍐欏叆澶辫触锛歐riteSingleCoil:IP:{ip},Port:{port}");
                     }
                 }
                 catch (Exception ex) {
-
+                    LogHelper.InfoEx(ex);
                 }
             }
             else {
-
+                LogHelper.Info($"鏈壘鍒癕odbus璁惧瀹炰緥瀵硅薄锛屾垨瀵硅薄鏈垚鍔熻繛鎺�);
             }
             return res;
         }
@@ -261,25 +300,27 @@
         public bool WriteSingleRegister(int registerAddress, ushort value) {
             var res = false;
             var client = _modbusClient;
-            var ip = client.IPAddress;
-            var port = client.Port;
             if (client != null && client.Connected) {
+                var ip = client.IPAddress;
+                var port = client.Port;
                 try {
                     client.WriteSingleRegister(registerAddress, value);
                     res = value == client.ReadHoldingRegisters(registerAddress, 1)[0];
                     if (res) {
                         //鍐欏叆鎴愬姛
+                        LogHelper.Info($"鍐欏叆鎴愬姛锛歐riteSingleRegister:IP:{ip},Port:{port}");
                     }
                     else {
                         //鍐欏叆澶辫触
+                        LogHelper.Info($"鍐欏叆澶辫触锛歐riteSingleRegister:IP:{ip},Port:{port}");
                     }
                 }
                 catch (Exception ex) {
-
+                    LogHelper.InfoEx(ex);
                 }
             }
             else {
-
+                LogHelper.Info($"鏈壘鍒癕odbus璁惧瀹炰緥瀵硅薄锛屾垨瀵硅薄鏈垚鍔熻繛鎺�);
             }
             return res;
         }
@@ -287,26 +328,28 @@
         public bool WriteMultipleCoils(int startingAddress, bool[] values) {
             var res = false;
             var client = _modbusClient;
-            var ip = client.IPAddress;
-            var port = client.Port;
             if (client != null && client.Connected) {
+                var ip = client.IPAddress;
+                var port = client.Port;
                 try {
                     client.WriteMultipleCoils(startingAddress, values);
                     var dataRead = client.ReadCoils(startingAddress, values.Length);
                     res = values.SequenceEqual(dataRead);
                     if (res) {
                         //鍐欏叆鎴愬姛
+                        LogHelper.Info($"鍐欏叆鎴愬姛锛歐riteMultipleCoils:IP:{ip},Port:{port}");
                     }
                     else {
                         //鍐欏叆澶辫触
+                        LogHelper.Info($"鍐欏叆澶辫触锛歐riteMultipleCoils:IP:{ip},Port:{port}");
                     }
                 }
                 catch (Exception ex) {
-
+                    LogHelper.InfoEx(ex);
                 }
             }
             else {
-
+                LogHelper.Info($"鏈壘鍒癕odbus璁惧瀹炰緥瀵硅薄锛屾垨瀵硅薄鏈垚鍔熻繛鎺�);
             }
             return res;
         }
@@ -314,33 +357,34 @@
         public bool WriteMultipleRegisters(int startingAddress, int[] values) {
             var res = false;
             var client = _modbusClient;
-            var ip = client.IPAddress;
-            var port = client.Port;
-            var log = string.Join(",", values.Select(x => x.ToString()));
             if (client != null && client.Connected) {
+                var ip = client.IPAddress;
+                var port = client.Port;
+                var log = string.Join(",", values.Select(x => x.ToString()));
                 try {
                     client.WriteMultipleRegisters(startingAddress, values);
                     var dataRead = client.ReadHoldingRegisters(startingAddress, values.Length);
                     res = values.SequenceEqual(dataRead);
                     if (res) {
-                        LogHelper.Info($"鍐欏叆鎴愬姛,IP:{ip},Port:{port},{log}");
+                        LogHelper.Info($"鍐欏叆鎴愬姛,WriteMultipleRegisters:IP:{ip},Port:{port},{log}");
                     }
                     else {
-                        LogHelper.Info($"鍐欏叆澶辫触,IP:{ip},Port:{port},{log}");
+                        LogHelper.Info($"鍐欏叆澶辫触,WriteMultipleRegisters:IP:{ip},Port:{port},{log}");
                     }
                 }
                 catch (Exception ex) {
-                    LogHelper.Info($"鍙戠敓浜嗗紓甯�{ex.Message},IP:{ip},Port:{port},{log}", "Error");
+                    LogHelper.InfoEx(ex);
                 }
             }
             else {
-                LogHelper.Info($"鏈厤缃殑璁惧淇℃伅,IP:{ip},Port:{port},{log}");
+                LogHelper.Info($"鏈壘鍒癕odbus璁惧瀹炰緥瀵硅薄锛屾垨瀵硅薄鏈垚鍔熻繛鎺�);
             }
             return res;
         }
 
         public void Dispose() {
             //_modbusClient?.Dispose();
+            GC.SuppressFinalize(_modbusClient);
         }
     }
 
@@ -348,9 +392,10 @@
     public class TcpSocketCommunicator : IModbusCommunicator {
         private System.Net.Sockets.TcpClient _tcpClient;
         private NetworkStream _networkStream;
+        private byte unitIdentifier = 1; // 榛樿鍗曞厓鏍囪瘑绗� 
-        //public bool IsConnected => _tcpClient?.Connected ?? false;
-        public bool IsConnected { get { if (_tcpClient != null) { return true; } else { return false; } } }
+        public bool IsConnected => _tcpClient?.Connected ?? false;
+        //public bool IsConnected { get { if (_tcpClient != null) { return _tcpClient.Connected; } else { return false; } } }
 
         public void Link(string ipAddress, int port) {
             _tcpClient = new System.Net.Sockets.TcpClient();
@@ -372,50 +417,407 @@
             }
         }
 
-        // 浠ヤ笅鏂规硶闇�鏍规嵁浣犵殑Modbus TCP鍗忚鍏蜂綋瀹炵幇
         public bool[] ReadCoils(int startingAddress, int quantity) {
-            // 瀹炵幇TCP鏂瑰紡璇诲彇绾垮湀
-            throw new NotImplementedException();
+            if (quantity < 1 || quantity > 2000)
+                throw new ArgumentException("Quantity must be between 1 and 2000");
+
+            // 鏋勫缓璇锋眰鎶ユ枃锛�2瀛楄妭锛�+            byte[] request = new byte[12];
+            request[0] = 0x00; // 浜嬪姟ID楂樺瓧鑺�+            request[1] = 0x01; // 浜嬪姟ID浣庡瓧鑺傦紙绀轰緥鍊硷級
+            request[2] = 0x00; // 鍗忚ID楂樺瓧鑺傦紙鍥哄畾0锛�+            request[3] = 0x00; // 鍗忚ID浣庡瓧鑺傦紙鍥哄畾0锛�+            request[4] = 0x00; // 闀垮害楂樺瓧鑺傦紙鍚庣画6瀛楄妭锛�+            request[5] = 0x06; // 闀垮害浣庡瓧鑺�+            request[6] = unitIdentifier; // 鍗曞厓鏍囪瘑绗�+            request[7] = 0x01; // 鍔熻兘鐮侊紙璇荤嚎鍦堬級
+            request[8] = (byte)(startingAddress >> 8); // 璧峰鍦板潃楂樺瓧鑺�+            request[9] = (byte)startingAddress; // 璧峰鍦板潃浣庡瓧鑺�+            request[10] = (byte)(quantity >> 8); // 鏁伴噺楂樺瓧鑺�+            request[11] = (byte)quantity; // 鏁伴噺浣庡瓧鑺�+
+            // 鍙戦�璇锋眰
+            _networkStream.Write(request, 0, request.Length);
+
+            // 璇诲彇鍝嶅簲澶达紙8瀛楄妭锛�+            byte[] responseHeader = new byte[8];
+            int bytesRead = _networkStream.Read(responseHeader, 0, 8);
+            if (bytesRead != 8)
+                throw new Exception("Invalid response header length");
+
+            // 鏍¢獙浜嬪姟ID銆佸崗璁甀D銆佸崟鍏冩爣璇嗙
+            if (responseHeader[0] != request[0] || responseHeader[1] != request[1] ||
+                responseHeader[2] != 0x00 || responseHeader[3] != 0x00 ||
+                responseHeader[6] != unitIdentifier)
+                throw new Exception("Invalid response header");
+
+            // 妫�煡寮傚父鍝嶅簲锛堝姛鑳界爜 + 0x80锛�+            if (responseHeader[7] == 0x81) {
+                int errorCode = _networkStream.ReadByte();
+                throw new Exception($"Modbus error. Code: {errorCode}");
+            }
+            else if (responseHeader[7] != 0x01)
+                throw new Exception("Invalid function code in response");
+
+            // 璇诲彇鏁版嵁閮ㄥ垎锛堝瓧鑺傛暟 + 瀹為檯鏁版嵁锛�+            byte byteCount = responseHeader[8];
+            byte[] responseData = new byte[byteCount];
+            bytesRead = _networkStream.Read(responseData, 0, byteCount);
+            if (bytesRead != byteCount)
+                throw new Exception("Invalid response data length");
+
+            // 瑙f瀽绾垮湀鐘舵�锛堟瘡涓綅琛ㄧず涓�釜绾垮湀锛�+            bool[] coils = new bool[quantity];
+            for (int i = 0; i < quantity; i++) {
+                int byteIndex = i / 8;
+                int bitIndex = i % 8;
+                coils[i] = (responseData[byteIndex] & (1 << bitIndex)) != 0;
+            }
+
+            return coils;
         }
 
         public bool[] ReadDiscreteInputs(int startingAddress, int quantity) {
-            // 瀹炵幇TCP鏂瑰紡璇诲彇绂绘暎杈撳叆
-            throw new NotImplementedException();
+            // 鎶ユ枃缁撴瀯涓嶳eadCoils鍑犱箮鐩稿悓锛屼粎鍔熻兘鐮佹敼涓�x02
+            byte[] request = new byte[12];
+            request[0] = 0x00; // 浜嬪姟ID楂樺瓧鑺�+            request[1] = 0x01; // 浜嬪姟ID浣庡瓧鑺傦紙绀轰緥鍊硷級
+            request[2] = 0x00; // 鍗忚ID楂樺瓧鑺傦紙鍥哄畾0锛�+            request[3] = 0x00; // 鍗忚ID浣庡瓧鑺傦紙鍥哄畾0锛�+            request[4] = 0x00; // 闀垮害楂樺瓧鑺傦紙鍚庣画6瀛楄妭锛�+            request[5] = 0x06; // 闀垮害浣庡瓧鑺�+            request[6] = unitIdentifier;
+            request[7] = 0x02; // 鍔熻兘鐮侊細璇荤鏁h緭鍏�+            request[8] = (byte)(startingAddress >> 8); // 璧峰鍦板潃楂樺瓧鑺�+            request[9] = (byte)startingAddress; // 璧峰鍦板潃浣庡瓧鑺�+            request[10] = (byte)(quantity >> 8); // 鏁伴噺楂樺瓧鑺�+            request[11] = (byte)quantity; // 鏁伴噺浣庡瓧鑺�+
+            _networkStream.Write(request, 0, request.Length);
+
+            // 鍝嶅簲澶勭悊閫昏緫涓嶳eadCoils涓�嚧
+            byte[] responseHeader = new byte[8];
+            _networkStream.Read(responseHeader, 0, 8);
+
+            // 鏍¢獙鍜屽紓甯稿鐞嗭紙鍙傝�ReadCoils锛�+            if (responseHeader[7] == 0x82) // 寮傚父鍝嶅簲
+            {
+                int errorCode = _networkStream.ReadByte();
+                throw new Exception($"Modbus error. Code: {errorCode}");
+            }
+
+            byte byteCount = responseHeader[8];
+            byte[] responseData = new byte[byteCount];
+            _networkStream.Read(responseData, 0, byteCount);
+
+            // 瑙f瀽绂绘暎杈撳叆鐘舵�
+            bool[] inputs = new bool[quantity];
+            for (int i = 0; i < quantity; i++) {
+                int byteIndex = i / 8;
+                int bitIndex = i % 8;
+                inputs[i] = (responseData[byteIndex] & (1 << bitIndex)) != 0;
+            }
+
+            return inputs;
         }
 
         public int[] ReadHoldingRegisters(int startingAddress, int quantity) {
-            // 瀹炵幇TCP鏂瑰紡璇诲彇淇濇寔瀵勫瓨鍣�-            throw new NotImplementedException();
+            if (quantity < 1 || quantity > 125)
+                throw new ArgumentException("Quantity must be between 1 and 125");
+
+            // 鏋勫缓璇锋眰鎶ユ枃锛�2瀛楄妭锛�+            byte[] request = new byte[12];
+            request[0] = 0x00; // 浜嬪姟ID楂樺瓧鑺傦紙绀轰緥鍊硷級
+            request[1] = 0x01; // 浜嬪姟ID浣庡瓧鑺�+            request[2] = 0x00; // 鍗忚ID楂樺瓧鑺傦紙鍥哄畾0锛�+            request[3] = 0x00; // 鍗忚ID浣庡瓧鑺傦紙鍥哄畾0锛�+            request[4] = 0x00; // 闀垮害楂樺瓧鑺傦紙鍚庣画6瀛楄妭锛�+            request[5] = 0x06; // 闀垮害浣庡瓧鑺�+            request[6] = unitIdentifier; // 鍗曞厓鏍囪瘑绗�+            request[7] = 0x03; // 鍔熻兘鐮侊紙璇讳繚鎸佸瘎瀛樺櫒锛�+            request[8] = (byte)(startingAddress >> 8); // 璧峰鍦板潃楂樺瓧鑺�+            request[9] = (byte)startingAddress; // 璧峰鍦板潃浣庡瓧鑺�+            request[10] = (byte)(quantity >> 8); // 鏁伴噺楂樺瓧鑺�+            request[11] = (byte)quantity; // 鏁伴噺浣庡瓧鑺�+
+            // 鍙戦�璇锋眰
+            _networkStream.Write(request, 0, request.Length);
+
+            // 璇诲彇鍝嶅簲澶达紙8瀛楄妭锛�+            byte[] responseHeader = new byte[8];
+            int bytesRead = _networkStream.Read(responseHeader, 0, 8);
+            if (bytesRead != 8)
+                throw new Exception("Invalid response header length");
+
+            // 鏍¢獙浜嬪姟ID銆佸崗璁甀D銆佸崟鍏冩爣璇嗙
+            if (responseHeader[0] != request[0] || responseHeader[1] != request[1] ||
+                responseHeader[2] != 0x00 || responseHeader[3] != 0x00 ||
+                responseHeader[6] != unitIdentifier)
+                throw new Exception("Invalid response header");
+
+            // 妫�煡寮傚父鍝嶅簲锛堝姛鑳界爜 + 0x80锛�+            if (responseHeader[7] == 0x83) {
+                int errorCode = _networkStream.ReadByte();
+                throw new Exception($"Modbus error. Code: {errorCode}");
+            }
+            else if (responseHeader[7] != 0x03)
+                throw new Exception("Invalid function code in response");
+
+            // 璇诲彇鏁版嵁閮ㄥ垎锛堝瓧鑺傛暟 + 瀹為檯鏁版嵁锛�+            byte byteCount = responseHeader[8];
+            byte[] responseData = new byte[byteCount];
+            bytesRead = _networkStream.Read(responseData, 0, byteCount);
+            if (bytesRead != byteCount)
+                throw new Exception("Invalid response data length");
+
+            // 瑙f瀽瀵勫瓨鍣ㄥ�锛堝ぇ绔簭锛�+            int[] registers = new int[quantity];
+            for (int i = 0; i < quantity; i++) {
+                int offset = i * 2;
+                registers[i] = (ushort)((responseData[offset] << 8) | responseData[offset + 1]);
+            }
+
+            return registers;
         }
 
         public int[] ReadInputRegisters(int startingAddress, int quantity) {
-            // 瀹炵幇TCP鏂瑰紡璇诲彇杈撳叆瀵勫瓨鍣�-            throw new NotImplementedException();
+            if (quantity < 1 || quantity > 125)
+                throw new ArgumentException("Quantity must be between 1 and 125");
+
+            // 鏋勫缓Modbus TCP璇锋眰鎶ユ枃
+            byte[] request = new byte[12];
+
+            // 浜嬪姟鏍囪瘑绗︼紙鍙互绠�崟閫掑锛�+            request[0] = 0x00;
+            request[1] = 0x01;
+
+            // 鍗忚鏍囪瘑绗︼紙Modbus鍥哄畾涓�锛�+            request[2] = 0x00;
+            request[3] = 0x00;
+
+            // 闀垮害瀛楁锛堝悗闈㈣繕鏈�瀛楄妭锛�+            request[4] = 0x00;
+            request[5] = 0x06;
+
+            // 鍗曞厓鏍囪瘑绗�+            request[6] = unitIdentifier;
+
+            // 鍔熻兘鐮侊紙4琛ㄧず璇昏緭鍏ュ瘎瀛樺櫒锛�+            request[7] = 0x04;
+
+            // 璧峰鍦板潃
+            request[8] = (byte)(startingAddress >> 8);
+            request[9] = (byte)startingAddress;
+
+            // 瀵勫瓨鍣ㄦ暟閲�+            request[10] = (byte)(quantity >> 8);
+            request[11] = (byte)quantity;
+
+            // 鍙戦�璇锋眰
+            _networkStream.Write(request, 0, request.Length);
+
+            // 鎺ユ敹鍝嶅簲
+            byte[] responseHeader = new byte[8];
+            int bytesRead = _networkStream.Read(responseHeader, 0, 8);
+
+            if (bytesRead != 8)
+                throw new Exception("Invalid response header length");
+
+            // 妫�煡浜嬪姟ID鍜屽崗璁甀D鏄惁鍖归厤
+            if (responseHeader[0] != request[0] || responseHeader[1] != request[1] ||
+                responseHeader[2] != 0x00 || responseHeader[3] != 0x00)
+                throw new Exception("Invalid response header");
+
+            // 妫�煡鍗曞厓鏍囪瘑绗﹀拰鍔熻兘鐮�+            if (responseHeader[6] != unitIdentifier)
+                throw new Exception("Unit identifier mismatch");
+
+            if (responseHeader[7] != 0x04 && responseHeader[7] != 0x84)
+                throw new Exception("Invalid function code in response");
+
+            // 妫�煡寮傚父鍝嶅簲
+            if (responseHeader[7] == 0x84) {
+                byte errorCode = responseHeader[8];
+                throw new Exception($"Modbus error response. Error code: {errorCode}");
+            }
+
+            // 璇诲彇鍓╀綑鍝嶅簲鏁版嵁
+            byte byteCount = responseHeader[8];
+            byte[] responseData = new byte[byteCount];
+            bytesRead = _networkStream.Read(responseData, 0, byteCount);
+
+            if (bytesRead != byteCount)
+                throw new Exception("Invalid response data length");
+
+            // 瑙f瀽瀵勫瓨鍣ㄥ�
+            int[] registers = new int[quantity];
+            for (int i = 0; i < quantity; i++) {
+                int offset = i * 2;
+                registers[i] = (ushort)((responseData[offset] << 8) | responseData[offset + 1]);
+            }
+
+            return registers;
         }
 
-        public bool WriteSingleCoil(int coilAddress, bool value) {
-            // 瀹炵幇TCP鏂瑰紡鍐欏叆鍗曚釜绾垮湀
-            throw new NotImplementedException();
+        public bool WriteSingleCoil(int address, bool value) {
+            // 璇锋眰鎶ユ枃鍥哄畾闀垮害12瀛楄妭
+            byte[] request = new byte[12];
+            request[0] = 0x00; // 浜嬪姟ID
+            request[1] = 0x01;
+            request[2] = 0x00; // 鍗忚ID
+            request[3] = 0x00;
+            request[4] = 0x00; // 闀垮害
+            request[5] = 0x06;
+            request[6] = unitIdentifier;
+            request[7] = 0x05; // 鍔熻兘鐮�+            request[8] = (byte)(address >> 8); // 鍦板潃楂樺瓧鑺�+            request[9] = (byte)address; // 鍦板潃浣庡瓧鑺�+            request[10] = (byte)(value ? 0xFF : 0x00); // ON=0xFF00, OFF=0x0000
+            request[11] = 0x00;
+
+            _networkStream.Write(request, 0, request.Length);
+
+            // 鍝嶅簲搴斾笌璇锋眰瀹屽叏涓�嚧锛堝洖鏄撅級
+            byte[] response = new byte[12];
+            int bytesRead = _networkStream.Read(response, 0, 12);
+            if (bytesRead != 12)
+                throw new Exception("Invalid response length");
+
+            // 鏍¢獙鍥炴樉鎶ユ枃
+            for (int i = 0; i < 12; i++) {
+                if (response[i] != request[i])
+                    throw new Exception("Response does not match request");
+            }
+            return true;
         }
 
-        public bool WriteSingleRegister(int registerAddress, ushort value) {
-            // 瀹炵幇TCP鏂瑰紡鍐欏叆鍗曚釜瀵勫瓨鍣�-            throw new NotImplementedException();
+        public bool WriteSingleRegister(int address, ushort value) {
+            byte[] request = new byte[12];
+            request[0] = 0x00; // 浜嬪姟ID
+            request[1] = 0x01;
+            request[2] = 0x00; // 鍗忚ID
+            request[3] = 0x00;
+            request[4] = 0x00; // 闀垮害
+            request[5] = 0x06;
+            request[6] = unitIdentifier;
+            request[7] = 0x06; // 鍔熻兘鐮�+            request[8] = (byte)(address >> 8); // 鍦板潃楂樺瓧鑺�+            request[9] = (byte)address;
+            request[10] = (byte)(value >> 8); // 鍊奸珮瀛楄妭
+            request[11] = (byte)value; // 鍊间綆瀛楄妭
+
+            _networkStream.Write(request, 0, request.Length);
+
+            // 妫�煡鍥炴樉鍝嶅簲锛堝悓WriteSingleCoil锛�+            byte[] response = new byte[12];
+            _networkStream.Read(response, 0, 12);
+            if (!response.SequenceEqual(request))
+                throw new Exception("Response mismatch");
+
+            return true;
         }
 
         public bool WriteMultipleCoils(int startingAddress, bool[] values) {
-            // 瀹炵幇TCP鏂瑰紡鍐欏叆澶氫釜绾垮湀
-            throw new NotImplementedException();
+            int quantity = values.Length;
+            if (quantity < 1 || quantity > 1968)
+                throw new ArgumentException("Quantity must be between 1 and 1968");
+
+            // 璁$畻闇�鐨勫瓧鑺傛暟锛堟瘡涓瓧鑺傚瓨鍌�涓嚎鍦堢姸鎬侊級
+            int byteCount = (quantity + 7) / 8;
+            byte[] coilBytes = new byte[byteCount];
+
+            // 灏哹ool鏁扮粍鍘嬬缉涓哄瓧鑺傛暟缁�+            for (int i = 0; i < quantity; i++) {
+                if (values[i]) {
+                    int byteIndex = i / 8;
+                    int bitIndex = i % 8;
+                    coilBytes[byteIndex] |= (byte)(1 << bitIndex);
+                }
+            }
+
+            // 鏋勫缓璇锋眰鎶ユ枃锛�3 + 绾垮湀瀛楄妭鏁帮級
+            byte[] request = new byte[13 + coilBytes.Length];
+            request[0] = 0x00; // 浜嬪姟ID楂樺瓧鑺�+            request[1] = 0x01; // 浜嬪姟ID浣庡瓧鑺�+            request[2] = 0x00; // 鍗忚ID楂樺瓧鑺�+            request[3] = 0x00; // 鍗忚ID浣庡瓧鑺�+            request[4] = (byte)((7 + coilBytes.Length) >> 8); // 闀垮害楂樺瓧鑺�+            request[5] = (byte)(7 + coilBytes.Length); // 闀垮害浣庡瓧鑺�+            request[6] = unitIdentifier;
+            request[7] = 0x0F; // 鍔熻兘鐮侊紙鍐欏涓嚎鍦堬級
+            request[8] = (byte)(startingAddress >> 8); // 璧峰鍦板潃楂樺瓧鑺�+            request[9] = (byte)startingAddress; // 璧峰鍦板潃浣庡瓧鑺�+            request[10] = (byte)(quantity >> 8); // 鏁伴噺楂樺瓧鑺�+            request[11] = (byte)quantity; // 鏁伴噺浣庡瓧鑺�+            request[12] = (byte)byteCount; // 瀛楄妭鏁�+            Buffer.BlockCopy(coilBytes, 0, request, 13, coilBytes.Length);
+
+            // 鍙戦�璇锋眰
+            _networkStream.Write(request, 0, request.Length);
+
+            // 璇诲彇鍝嶅簲锛堝浐瀹�2瀛楄妭锛�+            byte[] response = new byte[12];
+            int bytesRead = _networkStream.Read(response, 0, 12);
+            if (bytesRead != 12)
+                throw new Exception("Invalid response length");
+
+            // 鏍¢獙鍥炴樉鐨勫湴鍧�拰鏁伴噺
+            if (response[8] != request[8] || response[9] != request[9] ||
+                response[10] != request[10] || response[11] != request[11])
+                throw new Exception("Response address/quantity mismatch");
+
+            return true;
         }
 
         public bool WriteMultipleRegisters(int startingAddress, int[] values) {
-            // 瀹炵幇TCP鏂瑰紡鍐欏叆澶氫釜瀵勫瓨鍣�-            throw new NotImplementedException();
+            int quantity = values.Length;
+            if (quantity < 1 || quantity > 123)
+                throw new ArgumentException("Quantity must be between 1 and 123");
+
+            // 灏唘short鏁扮粍杞崲涓哄瓧鑺傛暟缁勶紙澶х搴忥級
+            byte[] valueBytes = new byte[quantity * 2];
+            for (int i = 0; i < quantity; i++) {
+                valueBytes[i * 2] = (byte)(values[i] >> 8);
+                valueBytes[i * 2 + 1] = (byte)values[i];
+            }
+
+            // 鏋勫缓璇锋眰鎶ユ枃锛�3 + 鍊煎瓧鑺傛暟锛�+            byte[] request = new byte[13 + valueBytes.Length];
+            request[0] = 0x00; // 浜嬪姟ID楂樺瓧鑺�+            request[1] = 0x01; // 浜嬪姟ID浣庡瓧鑺�+            request[2] = 0x00; // 鍗忚ID楂樺瓧鑺�+            request[3] = 0x00; // 鍗忚ID浣庡瓧鑺�+            request[4] = (byte)((7 + valueBytes.Length) >> 8); // 闀垮害楂樺瓧鑺�+            request[5] = (byte)(7 + valueBytes.Length); // 闀垮害浣庡瓧鑺�+            request[6] = unitIdentifier;
+            request[7] = 0x10; // 鍔熻兘鐮侊紙鍐欏涓瘎瀛樺櫒锛�+            request[8] = (byte)(startingAddress >> 8); // 璧峰鍦板潃楂樺瓧鑺�+            request[9] = (byte)startingAddress; // 璧峰鍦板潃浣庡瓧鑺�+            request[10] = (byte)(quantity >> 8); // 鏁伴噺楂樺瓧鑺�+            request[11] = (byte)quantity; // 鏁伴噺浣庡瓧鑺�+            request[12] = (byte)(quantity * 2); // 瀛楄妭鏁�+            Buffer.BlockCopy(valueBytes, 0, request, 13, valueBytes.Length);
+
+            // 鍙戦�璇锋眰
+            _networkStream.Write(request, 0, request.Length);
+
+            // 璇诲彇鍝嶅簲锛堝浐瀹�2瀛楄妭锛�+            byte[] response = new byte[12];
+            int bytesRead = _networkStream.Read(response, 0, 12);
+            if (bytesRead != 12)
+                throw new Exception("Invalid response length");
+
+            // 鏍¢獙鍥炴樉鐨勫湴鍧�拰鏁伴噺
+            if (response[8] != request[8] || response[9] != request[9] ||
+                response[10] != request[10] || response[11] != request[11])
+                throw new Exception("Response address/quantity mismatch");
+
+            return true;
         }
 
         public void Dispose() {
             _networkStream?.Dispose();
-            //_tcpClient?.Dispose();
+            _tcpClient?.Dispose();
         }
     }
 }
\ No newline at end of file

--
Gitblit v1.9.1