From da5d613a85d97ecd826e343eae6d901806120a05 Mon Sep 17 00:00:00 2001
From: wanshenmean <cathay_xy@163.com>
Date: 星期三, 18 三月 2026 14:18:36 +0800
Subject: [PATCH] fix: 修复输送线目标地址选择器并完善机械手任务地址映射

---
 Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Server/S7ServerInstance.cs |  169 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 158 insertions(+), 11 deletions(-)

diff --git a/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Server/S7ServerInstance.cs b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Server/S7ServerInstance.cs
index f29afa6..59c6aa3 100644
--- a/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Server/S7ServerInstance.cs
+++ b/Code/WCS/WIDESEAWCS_S7Simulator/WIDESEAWCS_S7Simulator.Core/Server/S7ServerInstance.cs
@@ -1,4 +1,6 @@
-using System.Collections.Concurrent;
+锘縰sing System.Collections.Concurrent;
+using System.Linq;
+using System.Net.NetworkInformation;
 using HslCommunication;
 using HslCommunication.Profinet.Siemens;
 using HslCommunication.Reflection;
@@ -34,6 +36,11 @@
         /// 瀹㈡埛绔繛鎺ヨ拷韪�
         /// </summary>
         private readonly ConcurrentDictionary<string, S7ClientConnection> _clients = new();
+
+        /// <summary>
+        /// 杩炴帴鐩戞帶瀹氭椂鍣�
+        /// </summary>
+        private System.Threading.Timer? _connectionMonitorTimer;
 
         /// <summary>
         /// 鏋勯�犲嚱鏁�
@@ -114,6 +121,13 @@
                     State.StartTime = DateTime.Now;
                     State.ErrorMessage = null;
 
+                    // 鍚姩杩炴帴鐩戞帶瀹氭椂鍣紙姣�5绉掓鏌ヤ竴娆★級
+                    _connectionMonitorTimer = new System.Threading.Timer(
+                        _ => MonitorConnections(),
+                        null,
+                        TimeSpan.FromSeconds(5),
+                        TimeSpan.FromSeconds(5));
+
                     _logger.LogInformation("S7鏈嶅姟鍣ㄥ疄渚� {InstanceId} 宸叉垚鍔熷惎鍔紝鐩戝惉绔彛: {Port}", Config.Id, Config.Port);
                     return true;
                 }
@@ -139,6 +153,10 @@
 
                 try
                 {
+                    // 鍋滄杩炴帴鐩戞帶瀹氭椂鍣�
+                    _connectionMonitorTimer?.Dispose();
+                    _connectionMonitorTimer = null;
+
                     if (_server != null)
                     {
                         // 鍋滄鍓嶅悓姝ユ湇鍔″櫒鏁版嵁鍒癕emoryStore
@@ -183,7 +201,7 @@
                 State.ClientCount = _clients.Count;
                 State.Clients = _clients.Values.ToList();
 
-                // 杩斿洖鐘舵�佸壇鏈�
+                // 杩斿洖鐘舵�佸壇鏈紝鍖呭惈閰嶇疆淇℃伅
                 return new InstanceState
                 {
                     InstanceId = State.InstanceId,
@@ -193,6 +211,34 @@
                     StartTime = State.StartTime,
                     LastActivityTime = State.LastActivityTime,
                     Clients = new List<S7ClientConnection>(State.Clients),
+                    ErrorMessage = State.ErrorMessage
+                };
+            }
+        }
+
+        /// <summary>
+        /// 鑾峰彇瀹屾暣鐘舵�侊紙鍖呭惈閰嶇疆淇℃伅锛�
+        /// </summary>
+        public object GetFullState()
+        {
+            lock (_lock)
+            {
+                // 鏇存柊瀹㈡埛绔繛鎺ユ暟
+                State.ClientCount = _clients.Count;
+                State.Clients = _clients.Values.ToList();
+
+                return new
+                {
+                    InstanceId = State.InstanceId,
+                    Name = Config.Name,
+                    PLCType = Config.PLCType.ToString(),
+                    Port = Config.Port,
+                    Status = State.Status.ToString(),
+                    ClientCount = State.ClientCount,
+                    TotalRequests = State.TotalRequests,
+                    StartTime = State.StartTime,
+                    LastActivityTime = State.LastActivityTime,
+                    Clients = State.Clients,
                     ErrorMessage = State.ErrorMessage
                 };
             }
@@ -217,11 +263,11 @@
                     }
 
                     // 娓呯┖DB鍧�
-                    for (ushort db = 1; db <= Config.MemoryConfig.DBBlockCount; db++)
+                    foreach (var db in ResolveConfiguredDbNumbers())
                     {
                         for (int i = 0; i < 10; i++)
                         {
-                            _server.Write($"DB{db}.DBD{i}", (byte)0);
+                            _server.Write($"DB{db}.DBB{i}", (byte)0);
                         }
                     }
                 }
@@ -272,7 +318,7 @@
             try
             {
                 // 鏍规嵁閰嶇疆娣诲姞DB鍧�
-                for (ushort i = 1; i <= Config.MemoryConfig.DBBlockCount; i++)
+                foreach (var i in ResolveConfiguredDbNumbers())
                 {
                     _server.AddDbBlock(i, Config.MemoryConfig.DBBlockSize);
                     _logger.LogDebug("宸叉坊鍔燚B鍧�: DB{DbNumber}, 澶у皬: {Size}", i, Config.MemoryConfig.DBBlockSize);
@@ -331,14 +377,18 @@
                 {
                     var dbBytes = data["DB"];
                     int offset = 0;
-                    for (ushort db = 1; db <= Config.MemoryConfig.DBBlockCount; db++)
+                    foreach (var db in ResolveConfiguredDbNumbers())
                     {
-                        int blockSize = Math.Min(Config.MemoryConfig.DBBlockSize, dbBytes.Length - offset);
+                        int blockSize = Math.Min(Config.MemoryConfig.DBBlockSize, Math.Max(0, dbBytes.Length - offset));
                         for (int i = 0; i < blockSize; i++)
                         {
-                            _server.Write($"DB{db}.DBD{i}", dbBytes[offset + i]);
+                            _server.Write($"DB{db}.DBB{i}", dbBytes[offset + i]);
                         }
                         offset += Config.MemoryConfig.DBBlockSize;
+                        if (offset >= dbBytes.Length)
+                        {
+                            break;
+                        }
                     }
                 }
 
@@ -385,12 +435,22 @@
 
                 // 璇诲彇DB鍖�
                 var dbBytes = new List<byte>();
-                for (ushort db = 1; db <= Config.MemoryConfig.DBBlockCount; db++)
+                foreach (var db in ResolveConfiguredDbNumbers())
                 {
-                    var dbResult = _server.Read($"DB{db}.DBD0", (ushort)Config.MemoryConfig.DBBlockSize);
-                    if (dbResult.IsSuccess)
+                    var remaining = Config.MemoryConfig.DBBlockSize;
+                    var blockOffset = 0;
+                    while (remaining > 0)
                     {
+                        var chunkLen = Math.Min(ushort.MaxValue, remaining);
+                        var dbResult = _server.Read($"DB{db}.DBB{blockOffset}", (ushort)chunkLen);
+                        if (!dbResult.IsSuccess)
+                        {
+                            break;
+                        }
+
                         dbBytes.AddRange(dbResult.Content);
+                        blockOffset += chunkLen;
+                        remaining -= chunkLen;
                     }
                 }
                 data["DB"] = dbBytes.ToArray();
@@ -407,8 +467,95 @@
         }
 
         /// <summary>
+        /// 鐩戞帶瀹㈡埛绔繛鎺ワ紙閫氳繃妫�鏌CP杩炴帴锛�
+        /// </summary>
+        private void MonitorConnections()
+        {
+            try
+            {
+                if (_server == null || State.Status != InstanceStatus.Running)
+                    return;
+
+                var currentConnections = new HashSet<string>();
+                var now = DateTime.Now;
+
+                // 鑾峰彇褰撳墠鎵�鏈塗CP杩炴帴
+                var tcpConnections = IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections();
+
+                // 绛涢�夊嚭鐩戝惉绔彛鐨勫凡寤虹珛杩炴帴
+                var connectionsOnPort = tcpConnections.Where(c =>
+                    c.LocalEndPoint.Port == Config.Port &&
+                    c.State == TcpState.Established);
+
+                foreach (var connection in connectionsOnPort)
+                {
+                    var endPoint = connection.RemoteEndPoint.ToString();
+                    currentConnections.Add(endPoint);
+
+                    // 妫�鏌ユ槸鍚︽槸鏂拌繛鎺�
+                    if (!_clients.ContainsKey(endPoint))
+                    {
+                        var clientConnection = new S7ClientConnection
+                        {
+                            ClientId = endPoint,
+                            RemoteEndPoint = endPoint,
+                            ConnectedTime = now,
+                            LastActivityTime = now
+                        };
+
+                        _clients[endPoint] = clientConnection;
+                        _logger.LogInformation("瀹炰緥 {InstanceId} 妫�娴嬪埌鏂板鎴风杩炴帴: {EndPoint}, 褰撳墠杩炴帴鏁�: {Count}",
+                            Config.Id, endPoint, _clients.Count);
+                    }
+                    else
+                    {
+                        // 鏇存柊娲诲姩鏃堕棿
+                        _clients[endPoint].LastActivityTime = now;
+                    }
+                }
+
+                // 绉婚櫎鏂紑鐨勮繛鎺�
+                var disconnectedClients = _clients.Keys.Where(k => !currentConnections.Contains(k)).ToList();
+                foreach (var disconnected in disconnectedClients)
+                {
+                    if (_clients.TryRemove(disconnected, out var client))
+                    {
+                        _logger.LogInformation("瀹炰緥 {InstanceId} 瀹㈡埛绔柇寮�: {EndPoint}, 褰撳墠杩炴帴鏁�: {Count}",
+                            Config.Id, disconnected, _clients.Count);
+                    }
+                }
+
+                // 鏇存柊鐘舵��
+                State.ClientCount = _clients.Count;
+                State.LastActivityTime = now;
+            }
+            catch (Exception ex)
+            {
+                _logger.LogWarning(ex, "鐩戞帶瀹㈡埛绔繛鎺ユ椂鍙戠敓閿欒");
+            }
+        }
+
+        /// <summary>
         /// 澧炲姞璇锋眰璁℃暟骞舵洿鏂版椿鍔ㄦ椂闂�
         /// </summary>
+        private IReadOnlyList<ushort> ResolveConfiguredDbNumbers()
+        {
+            if (Config.MemoryConfig.DBBlockNumbers != null && Config.MemoryConfig.DBBlockNumbers.Count > 0)
+            {
+                return Config.MemoryConfig.DBBlockNumbers
+                    .Where(x => x > 0 && x <= ushort.MaxValue)
+                    .Distinct()
+                    .OrderBy(x => x)
+                    .Select(x => (ushort)x)
+                    .ToList();
+            }
+
+            var count = Math.Max(1, Config.MemoryConfig.DBBlockCount);
+            return Enumerable.Range(1, count)
+                .Select(x => (ushort)x)
+                .ToList();
+        }
+
         private void IncrementRequestCount()
         {
             State.TotalRequests++;

--
Gitblit v1.9.3