فهرست منبع

G1-1/T1.4 根因纠正 + HAL 借用健壮性补强

★纠正前一提交(87c9cad)错误结论:ScanDevices 非"全仓零调用",实已接入
MainWindow.xaml.cs:112(operate 登录成功后调)。codegraph_callers 漏报了
Instance.ScanDevices() 静态单例链式调用、误导了结论。真因=T1.4 测试时
用户未登录(只用工程师口令 tl13579 进调试页)→采集启动 Task 被 account 空
守卫(MainWindow:82-86)跳过→采集+ScanDevices 都没跑→_houses 空→借用拿
空句柄。非代码 bug,是测试少了"登录"这步。
教训:codegraph "零调用"类结论必须 grep 交叉验证。

补强(健壮性,非根因修复):IHardwareAccessLayer+HardwareAccessLayer 加
RegisterHouse(仅补 ScanDevices 现场漏扫的舱、不覆盖已发现的);HouseBin
构造调 RegisterHouse(ccdIndex 取 House.ccdId,与采集端 GetCamera 一致)。
作用:现场某舱握手瞬时失败被 ScanDevices 漏扫但采集端有服务器配置时,
补 _houses 使该舱借用仍可用。dotnet build operate 0 error。
复验需登录 operate 起采集后进调试页选舱。文档已纠正。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
huangjie 4 روز پیش
والد
کامیت
bd6943bb7a

+ 5 - 0
ivf_tl_operate_2.0/control/IvfTl.Hardware/IHardwareAccessLayer.cs

@@ -38,6 +38,11 @@ namespace IvfTl.Hardware
         /// <summary>全进程统一相机原生调用锁(替代三套各自 static locker)。</summary>
         ICameraGate CameraGate { get; }
 
+        /// <summary>采集端补登记一个舱的设备信息(houseSn→port→相机 index)到 _houses。
+        /// ScanDevices()(登录后由 MainWindow 调)现场枚举若漏扫某舱(握手失败),采集端用服务器配置补登记,
+        /// 使该舱按舱借用 GetHouse/GetHouseGate 仍可用(T1.4 双保险;已被 ScanDevices 发现的舱不覆盖)。</summary>
+        void RegisterHouse(int houseSn, string portName, int ccdIndex);
+
         /// <summary>统一关闭路径:关闭并释放所有串口/相机句柄,杜绝句柄泄漏(替代各调试页自己的 ClosePort/UnInit)。</summary>
         void ShutdownAll();
     }

+ 20 - 0
ivf_tl_operate_2.0/control/IvfTl.Hardware/Impl/HardwareAccessLayer.cs

@@ -221,6 +221,26 @@ namespace IvfTl.Hardware.Impl
             return result;
         }
 
+        // ── 采集端补登记设备表(ScanDevices 现场漏扫某舱时的双保险;T1.4)──
+        public void RegisterHouse(int houseSn, string portName, int ccdIndex)
+        {
+            if (string.IsNullOrEmpty(portName)) return;
+            lock (_lock)
+            {
+                // ScanDevices(登录后由 MainWindow 调)若已发现本舱,以其现场实时枚举结果为准、不覆盖;
+                // 仅补 ScanDevices 漏扫(如该舱握手失败)但采集端有服务器配置的舱,使其借用仍可用。
+                if (_houses.ContainsKey(houseSn)) return;
+                _houses[houseSn] = new HouseDeviceInfo
+                {
+                    HouseSn = houseSn,
+                    PortName = portName,
+                    CcdSn = null,
+                    CcdIndex = ccdIndex
+                };
+                _gates.Remove(houseSn);
+            }
+        }
+
         // ── 统一关闭 ──
         public void ShutdownAll()
         {

+ 4 - 0
ivf_tl_operate_2.0/control/ivf_tl_Com/HouseBin.cs

@@ -171,6 +171,10 @@ namespace ivf_tl_Com
             // M1-03 HAL: 向统一硬件访问层借用该 COM 口的唯一 ComBin(杜绝同口重复 Open)。
             // RawComBin 返回 HAL 内部包装的具体 ComBin,保留采集端原有事件/调用面不变(代码隔离)。
             this.ComBin = (ComBin)HardwareAccessLayer.Instance.GetSerial(_house.houseSn, _house.housePort).RawComBin;
+            // T1.4 双保险:把本舱 houseSn→port→相机 index 补登记到 HAL _houses。正常路径由 ScanDevices()
+            // (登录后 MainWindow 调)填表;此处补 ScanDevices 现场漏扫(握手失败)的舱,使其借用仍可用,不覆盖已发现的舱。
+            HardwareAccessLayer.Instance.RegisterHouse(_house.houseSn, _house.housePort,
+                (_house.openCcd == 1 && _house.ccdId != -1) ? _house.ccdId : -1);
             ComBin.CommandLogEvent += ComBin_CommandLogEvent;
             ComBin.ErrorLogEvent += ComBin_ErrorLogEvent;
             ComBin.ExceptionLogEvent += ComBin_ExceptionLogEvent;

+ 6 - 0
项目文档/进度/交接卡.md

@@ -609,3 +609,9 @@
 - **本质**:M1 合并时 HAL 借用框架(Gate/Acquire/lease/暂停恢复采集 T1.2-T1.3)全搭好,但**设备发现入口 ScanDevices() 没接进采集启动流程**(类注释 HardwareAccessLayer.cs:11 要求"在 control StartRun 之前 ScanDevices()",实际没接)。采集端实走旧 B 栈 SerialBin,HAL(A 栈)与采集两套未打通(= G1-2 ComBin 去重的根)。**调试页借用机制从未真正工作过**。
 - **修复方向**:在采集端启动(StartMain/StartRun 之前)调 `HardwareAccessLayer.Instance.ScanDevices()` 填充 _houses,借用方能拿真实句柄。属 G1 串口收尾。⚠ 需真机(ScanDevices 会扫 COM 口握手 + 枚举相机)。
 - 待回写:待验证清单 V-012/V-013(借用复用句柄)标【真机验证失败·根因 ScanDevices 未接入】。
+
+## 2026-06-21 · ★★重要纠正:T1.4 根因非"ScanDevices 零调用",而是"测试时没登录"★★
+- **纠正上一段错误结论**:上条说"HardwareAccessLayer.ScanDevices() 全仓零调用"——**错**。grep `\.ScanDevices\(\)` + 读码确认:ScanDevices **实际在 `MainWindow.xaml.cs:112` 调用**(operate 登录成功后、StartRun 之前)。`codegraph_callers` 报 no callers 是**漏报**(没识别 `IvfTl.Hardware.Impl.HardwareAccessLayer.Instance.ScanDevices()` 这种静态单例属性链式调用)。★教训:codegraph callers 对属性链/静态单例调用可能漏报,关键"零调用"类结论必须 grep 交叉验证再下笔。前一提交 87c9cad 的结论据此纠正。★
+- **真根因**:T1.4 测试时**用户没登录 operate**——只用工程师口令 tl13579 进了设置页/调试页(`Setting_Click` 直接 LoadPage,不需登录;MiMa 工程师口令≠登录)。MainWindow 采集启动 Task(line 67) 有守卫:`account/password 空 → 记日志"control 后台启动跳过:operate 登录账号/密码为空" → return`(line 82-86)。故采集 StartRun + ScanDevices 全被跳过 → _houses 空 → 调试页借用 lease.Serial==null。**非代码 bug,是测试少了"登录"这步**(调试页 Start() 用独立 SerialBin 枚举不依赖采集,所以能进调试页枚举到 7 舱,但 ComHouseInit 借用依赖采集句柄→失败)。
+- **本次代码改动(健壮性补强,非根因修复)**:① IHardwareAccessLayer + HardwareAccessLayer 加 `RegisterHouse(houseSn,port,ccdIndex)`,**仅当 _houses 无该舱时补登记、不覆盖 ScanDevices 已发现的舱**;② HouseBin 构造(GetSerial 后)调 RegisterHouse(ccdIndex 取 `openCcd==1&&ccdId!=-1 ? ccdId : -1`,与采集端 GetCamera(House.ccdId) 一致)。**作用**:ScanDevices 现场漏扫某舱(如握手瞬时失败)但采集端有服务器配置时,补 _houses 使该舱借用仍可用。`dotnet build operate` 0 error + codegraph sync done。
+- **复验(需登录)**:启动 operate → **登录**(User 按钮→LoginWindow→账号密码,触发采集+ScanDevices) → 等采集起(_houses 填) → 进调试页(tl13579)选舱 → 借用应复用句柄成功、可读温压/动电机。★登录账号密码需用户提供/操作★。

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
项目文档/进度/待验证清单.md


+ 10 - 10
项目文档/进度/进度状态.yaml

@@ -1,17 +1,17 @@
 # 续接断点状态(机器可解析)。换会话/换电脑后首先读它定位。
 # 状态取值: 未开始 / 进行中 / 完成 / 代码完成待验证
 # 纪律:本字段只存【当前断点】,历史细节进 交接卡.md(见 CLAUDE.md 第三节)。
-更新时间: 2026-06-21 G1-1/T1.4 真机验证完成——发现借用机制根因缺陷(ScanDevices 未接入)
+更新时间: 2026-06-21 G1-1/T1.4 真机验证+根因纠正:真因=测试未登录(非ScanDevices缺陷),已加补强待复验
 当前任务: >
-  【★G1-1/T1.4 真机验证完成·发现根因缺陷★】自主驱动 operate GUI(管理员提权常驻代理,因 requireAdministrator+UIPI)
-  +日志判定。结果:①进调试页 Start 枚举不报端口占用=✅通过(oplog 272 行+RunRecord COM3/4/5/9/11/18/19 全打开成功零占用);
-  ②选舱借用复用句柄=❌失败:消息"借用到的串口句柄为空(HAL 未 ScanDevices 到本舱)"。
-  · ★根因(代码级确证):HardwareAccessLayer.ScanDevices() 全仓零调用(codegraph callers 接口+实现均 no callers)→
-    _houses 字典恒空→GetHouseGate 得 info=null→gate serialFactory ()=>null→Acquire 成功但 lease.Serial==null→
-    ComHouseInit 电机运动前 return(故电机未动)。M1 借用框架(Gate/lease/暂停恢复)全搭好,但设备发现入口 ScanDevices
-    没接进采集启动(类注释要求"control StartRun 之前调")。采集实走旧 B 栈 SerialBin,HAL 未打通=G1-2 ComBin 根。★
-  下一步:修复=采集 StartMain/StartRun 前调 HardwareAccessLayer.Instance.ScanDevices() 填 _houses(需查 control 启动流程接入点);
-    修后真机复验 V-012。文档已回写(交接卡+待验证清单 V-012+本文件)。⚠ 临时代理/截图在 C:\Temp_aivfo_shot(可清)。
+  【★T1.4 真机验证·根因已纠正·补强已加待复验★】①进调试页 Start 枚举不报端口占用=✅通过(oplog 272 行串口全成功零占用);
+  ②选舱借用失败"借用到的串口句柄为空"。
+  · ★根因纠正:前结论"ScanDevices 全仓零调用"=错(codegraph_callers 漏报静态单例链式调用)。grep+读码确认
+    ScanDevices 实已接入 MainWindow.xaml.cs:112(登录后调)。真因=测试时未登录(只用工程师口令 tl13579 进调试页,
+    Setting_Click 不需登录)→采集启动 Task 被 account 空守卫(line82-86)跳过→采集+ScanDevices 都没跑→_houses 空→借用拿空句柄。
+    非代码 bug,是测试少了登录步。教训:codegraph "零调用"类结论必 grep 交叉验证。★
+  · 代码改动(健壮性补强非根因修复,已编译0err):HAL 加 RegisterHouse(仅补 ScanDevices 漏扫的舱、不覆盖)+HouseBin 构造补登记。
+  下一步:★复验需登录★——启动 operate→登录(User→LoginWindow→账号密码,触发采集+ScanDevices)→进调试页(tl13579)选舱→借用应成功。
+    登录账号密码需用户提供/操作。本次代码+文档待 git 提交。⚠ 临时代理/截图在 C:\Temp_aivfo_shot(可清)。
   续接读:《工作计划表》+《当前开发计划》+ 本文件 + 交接卡末尾。
 说明: >
   M0-M5 全部【可写源码】已完成,C#合并端 0 error + M2-02 单测 15/15。工具链就位(JDK11.0.25 + Maven3.9.9

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است