# 修改记录 > 当前状态说明:本节以 Git 基线提交 `5841f6d` 为参照,记录 2026-07-23 工作区中的最终代码差异。后面的“历史过程记录”仅用于追溯,若与本节冲突,以本节和当前代码为准。 ## 当前修改总览 | 项目 | 当前值 | | --- | --- | | 仓库 | `https://github.com/azuki-m/pressure_control_gui.git` | | 本地目录 | `C:\Users\31765\.codex\pressure_control_gui_source` | | 分支 | `MT2-AM8` | | 基线提交 | `5841f6d 修改默认值,增加压力滤波(暂未启用)` | | 工作区状态 | 本文所列修改均尚未提交 | 相对基线,当前增加了三条主要业务链路: 1. 辨识前执行 `1000 -> 0` 的绝对行程稳态压力预扫描,上传不含时间字段的 JSON。 2. 辨识 9 参数改为从云端 CSV 获取;PRBS 结果保持 CSV 上传,并根据云端数字 `0/1` 显示审核结果。未通过时等待公司更新参数,再重新执行完整辨识。 3. 容积测试 8 参数改为按请求传递:客户点击“测试”只创建一次请求指令,公司端检测到后上传本次 JSON,客户端持续查询同一个请求,加载参数后删除临时文件和请求记录。 客户调试界面不再读取或显示这些参数输入框。旧控件对象仍保留以兼容现有代码,但不是新流程的数据来源。 ## 当前文件差异 ### 修改的原文件 | 文件 | 当前修改 | | --- | --- | | `core/identification.py` | 增加行程稳态预扫描;上传函数支持文本和字节;PRBS 原始结果改为 CSV 直传;增加上传回调;加强任务线程存活判断和启动返回值。 | | `ui/main_window.py` | 增加辨识参数下载、反馈轮询、未通过后等待新参数、容积请求握手、超时/停止清理及 Qt 线程信号桥。 | | `ui/debug_tab.py` | 隐藏客户不应输入的辨识/容积参数和高级设置;增加辨识审核状态显示。 | | `setup.py` | 将 3 个新增核心模块加入 Cython 编译列表。 | ### 新增业务文件 | 文件 | 用途 | | --- | --- | | `core/identification_config.py` | 下载、解析、校验 9 参数 CSV。 | | `core/identification_feedback.py` | 登记辨识 CSV、查询数字 `0/1`、确认并清理反馈。 | | `core/volume_config.py` | 校验 8 参数 JSON,创建、查询、清理一次容积参数请求。 | | `index.js` | 云函数入口,增加辨识参数、辨识反馈、容积请求接口。 | | `config/identification_config.json` | 旧本地格式迁移提示;客户端不读取。 | | `config/volume_measurement.json` | 旧本地格式迁移提示;客户端不读取。 | ### 新增公司端工具和示例 | 文件 | 用途 | | --- | --- | | `tool/identification_config.example.csv` | 9 参数 CSV 示例。 | | `tool/upload_identification_config.py` | 校验并上传客户的固定辨识参数 CSV。 | | `tool/submit_identification_feedback.py` | 提交辨识审核数字 `1` 或 `0`。 | | `tool/volume_measurement.example.json` | 8 参数 JSON 示例。 | | `tool/upload_volume_config.py` | 等待客户请求,检测到后校验、上传并关联本次 JSON。 | ### 新增测试 - `tests/test_initial_travel_scan.py` - `tests/test_identification_config.py` - `tests/test_identification_feedback.py` - `tests/test_volume_config.py` ## 当前辨识流程 ### 云端 9 参数 CSV 客户点击“开始辨识”后,客户端按许可证中的客户名称读取: ```text ReinLoop_GUI/{客户名称}/identification_config/identification_config.csv ``` CSV 固定使用 `parameter,value` 两列: ```csv parameter,value q_in_val,50.0 dt,0.1 n_order,6 t_c,2.5 levels,"10,20,30,40,50,60,70,80" dead_area,240.0 xa_full,1000.0 V_val,5.0 repeat,2 ``` 客户端要求且只允许这 9 个字段。主要约束: | 参数 | 约束 | | --- | --- | | `q_in_val` | 有限数字且 `>= 0` | | `dt` | 有限数字且 `> 0` | | `n_order` | 整数且 `>= 2` | | `t_c` | 有限数字且 `>= dt` | | `levels` | 至少 2 项,长度为 2 的整数次幂,每项在 `0..100` | | `dead_area` | `0 <= dead_area < xa_full` | | `xa_full` | `>= 1000` | | `V_val` | 有限数字且 `> 0` | | `repeat` | 正整数 | 校验成功后,9 个参数通过 `**config` 传给 `start_identification()`;`conn_mgr` 和 `running_flag_check` 仍由客户端本地创建,不属于 CSV。 公司端上传命令: ```powershell python tool/upload_identification_config.py "客户名称" "公司内部路径\identification_config.csv" ``` 同一路径再次上传会覆盖固定 CSV。客户端只在开始一轮辨识或收到未通过结果后重新读取,不会在本轮运行中途替换参数。 ### `1000 -> 0` 行程稳态预扫描 `start_identification()` 先扫描以下绝对行程,再调用原有 `collect_data_with_prbs()`: ```text 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 0 ``` 每个行程至少等待 5 秒,以 0.1 秒周期采样;使用最近 5 秒窗口,在压力极差 `<= 0.5 kPa`、压力斜率绝对值 `<= 0.05 kPa/s` 且连续稳定 3 秒后记录平均压力。每个行程最长等待 60 秒,超时跳过。停止、异常或结束时尝试把行程写回 `0`。 结果上传到 `ReinLoop_GUI/{客户名称}/ind_data/`,文件名为 `travel_stability_pressures_时间戳.json`。内容只包含行程和稳定压力,不包含相对时间,也不保存压力变化过程数组: ```json { "stable_pressures": [ {"distance": 1000, "pressure": 12.3}, {"distance": 900, "pressure": 15.6} ] } ``` 预扫描 JSON 上传失败只记录日志,不阻止后续 PRBS。 ### PRBS CSV 和 `0/1` 反馈 基线会把 PRBS 结果重新包装为 JSON;当前直接上传 `collect_data_with_prbs()` 返回的 `csv_data` 和 `.csv` 文件名,不改变采集器的原始 CSV 格式。 ```text 上传 PRBS CSV -> registerIdentificationResult 登记本轮 CSV 文件名为 runId -> 客户端每 2 秒查询 getIdentificationFeedback -> 数字 1:显示“已通过”,清理反馈记录,结束 -> 数字 0:显示“未通过”,清理反馈记录,等待云端 CSV 更新 -> 每 2 秒重新获取 identification_config.csv -> 9 参数内容与本轮不同后,才重新执行完整辨识 ``` 反馈只接受数字 `0` 或 `1`,布尔值和其他数字均拒绝。公司端命令: ```powershell python tool/submit_identification_feedback.py "客户名称" 1 python tool/submit_identification_feedback.py "客户名称" 0 ``` 云端集合 `identification_reviews` 对每个客户只保留当前待审核记录,客户端消费后调用 `ackIdentificationFeedback` 删除,防止下一轮误用旧结果。 ## 当前容积测试流程 ### 8 参数 JSON ```json { "q_in_val": 50.0, "dt": 0.05, "p_max": 200.0, "fit_low": 50.0, "fit_high": 150.0, "T_delta": 30.0, "xa_full": 1000.0, "num_runs": 3 } ``` 客户端要求且只允许这 8 个字段。主要约束:`q_in_val > 0`、`dt > 0`、`p_max > 0`、`0 <= fit_low < fit_high <= p_max`、`xa_full > 0`、`num_runs` 为正整数,其他数值必须有限。 ### 最终请求握手 服务器不能主动向客户端或公司端推送,因此采用“一次创建请求 + 两端查询同一请求状态”: ```text 客户点击“测试” -> 客户端只调用一次 createVolumeConfigRequest -> 云端生成 requestId,写入 volume_config_requests,有效期 5 分钟 公司端工具 -> 每 2 秒查询 getPendingVolumeConfigRequest -> 检测到 requestId 后才上传 8 参数 JSON -> submitVolumeConfigFile 把文件与 requestId 关联 客户端等待期间 -> 每 2 秒查询 getVolumeConfigRequest,始终使用同一个 requestId -> 状态查询不会重复创建请求,也不会重复要求公司端上传 -> 检测到本次新文件后下载并校验 JSON -> ackVolumeConfigRequest 删除临时文件和请求记录 -> 执行一次 start_volume_measurement(..., **config) ``` 公司端命令: ```powershell python tool/upload_volume_config.py "客户名称" "公司内部路径\volume.json" --wait-seconds 300 ``` 云端文件固定为: ```text ReinLoop_GUI/{客户名称}/volume_config_requests/{requestId}/volume_measurement.json ``` `submitVolumeConfigFile` 会核对 `file_records` 中的客户目录、`requestId`、文件名和上传时间。只有请求创建后、5 分钟内上传且属于该请求的 JSON 才能加载;旧目录或其他请求的文件不能关联。 ### 临时文件处理 - 创建新请求时,云端清理该客户遗留的旧容积请求及临时 JSON。 - 客户端加载成功、用户停止或请求超时后,删除当前请求、云存储 JSON 和对应 `file_records` 记录。 - 公司端上传或关联失败时,工具尝试删除刚上传的文件。 - 测量开始后不再监听参数变化,也不会因云端更新而自动重测;下一次必须由客户再次点击“测试”。 - 辨识 CSV 是公司维护的固定文件,后续上传会覆盖;容积 JSON 是一次请求的临时文件,消费后删除。 上一版“公司预先写入最新 8 参数、客户端直接获取”的方案已移除。当前代码不存在 `pushVolumeConfig`、`getVolumeConfig` 或 `volume_measurement_configs` 的有效调用路径。 ## 当前客户端和构建修改 - 调试页隐藏辨识、容积参数和高级设置,保留开始/停止按钮及辨识审核状态。 - 网络请求在后台线程中执行,通过 Qt `Signal` 回到主线程更新界面。 - 请求代数编号和 `inflight` 标志用于忽略停止后迟到的结果,并阻止同类请求并发。 - 辨识与容积测试互斥;停止或关闭窗口时停止定时器、使旧请求失效并尝试清理云端状态。 - `IdentificationManager.is_running` 同时检查运行标志和任务线程是否存活。 - `start_identification()` 与 `start_volume_measurement()` 返回布尔值,调用方可判断任务是否启动。 - `setup.py` 新增 `core/identification_config.py`、`core/identification_feedback.py`、`core/volume_config.py` 三个 Cython 编译目标。 ## 当前新增云函数接口 | 接口 | 调用方 | 作用 | | --- | --- | --- | | `getIdentificationConfig` | 客户端 | 获取当前客户固定辨识 CSV 的临时地址。 | | `registerIdentificationResult` | 客户端 | 登记刚上传的 PRBS CSV。 | | `getIdentificationFeedback` | 客户端 | 查询本轮数字 `0/1`。 | | `setIdentificationFeedback` | 公司端 | 提交本轮数字 `0/1`。 | | `ackIdentificationFeedback` | 客户端 | 删除已消费反馈。 | | `createVolumeConfigRequest` | 客户端 | 点击“测试”时创建一次 5 分钟请求。 | | `getPendingVolumeConfigRequest` | 公司端 | 查询客户的待上传请求。 | | `submitVolumeConfigFile` | 公司端 | 把 JSON 与本次请求关联。 | | `getVolumeConfigRequest` | 客户端 | 查询同一请求是否已有有效 JSON。 | | `ackVolumeConfigRequest` | 客户端 | 删除已消费、取消或超时的请求和文件。 | ## 当前验证结果 已执行: ```powershell python -m unittest discover -s tests -p 'test_*.py' -v ``` - 23 项单元测试全部通过。 - 38 个 Python 文件通过 AST 语法解析。 - `git diff --check` 通过,仅有 Windows 的 LF/CRLF 转换提示。 - 测试覆盖 9 参数 CSV、预扫描 JSON 无时间字段、PRBS CSV 直传、数字 `0/1`、8 参数 JSON、一次请求创建、等待/就绪状态和请求清理。 ## 尚未完成和发布风险 1. 尚未连接真实 MT2-AM8、真实云环境和公司端工具完成端到端联调。 2. 新 `index.js` 尚未部署;部署前客户端无法使用新增接口。 3. 本机没有独立 Node.js,`index.js` 尚未完成语法检查;上一次借用 VS Code 运行时的检查被中止,不计为通过。 4. 云数据库需要允许云函数读写 `identification_reviews`、`volume_config_requests` 和现有 `file_records`。 5. 当前 HTTP 接口主要依赖 `deviceId` 区分客户,没有请求签名或设备令牌;正式发布前需要服务端身份认证。 6. 当前 `index.js` 含明文小程序 `SECRET`。不得直接提交或分发,应立即轮换,并改为从云函数环境变量或密钥服务读取。 7. `requirements.txt` 未声明程序实际使用的 `PySide6`,新机器仅按该文件安装仍不能启动。 8. 所有改动仍在工作区,尚未形成 Git 提交。 ## 发布顺序建议 1. 轮换并移除 `index.js` 中的明文 `SECRET`。 2. 在测试云环境部署 `index.js`,建立并授权新增集合。 3. 公司端先上传一份辨识参数 CSV。 4. 联调一次容积请求的创建、发现、上传、下载和删除。 5. 联调预扫描、PRBS CSV 上传和 `0/1` 反馈重测。 6. 补齐运行依赖和打包配置,再生成客户安装包。
历史过程记录(仅供追溯,当前行为以上述整理为准) ## 项目基线 - 仓库:`https://github.com/azuki-m/pressure_control_gui.git` - 分支:`MT2-AM8` - 基线提交:`5841f6d 修改默认值,增加压力滤波(暂未启用)` - 本地目录:`C:\Users\31765\.codex\pressure_control_gui_source` - 开始日期:2026-07-22 ## 记录规则 每次修改应记录以下内容: 1. 修改目标和需求来源。 2. 涉及的文件、类和函数。 3. 修改前后的行为差异。 4. 参数、接口或数据格式变化。 5. 验证方法和验证结果。 6. 尚未完成的事项与风险。 ## 修改历史 ### 0. 基线建立 - 从 GitHub 重新克隆 `MT2-AM8` 分支。 - 保留原始代码,不继承此前测试版 1.0 的工作区修改。 - 对 28 个 Python 文件执行 AST 语法解析,全部通过。 ### 1. 云函数恢复 - 将此前测试版云函数备份到 `pressure_control_gui_test_v1.0/cloud_index.latest-test.js`。 - 恢复 `index.js` 的原始接口分发,仅保留: `uploadDataFile`、`listModels`、`downloadModel`、`deleteFile`、`uploadUserInfo`。 - 测试版新增的参数传输和多轮调试接口不再从云函数入口暴露。 - 已从恢复版 `index.js` 中完整移除测试版新增的参数传输和多轮会话函数。 - 恢复后的 `index.js` 已同步至 `C:\Users\31765\Desktop\index.js`。 ### 2. 容积测试的 8 个参数改为 JSON 输入(历史阶段,已由第 4 节替代) #### 2.1 修改目标 - 客户端不再通过 UI 输入容积测试参数。 - 参数从固定 JSON 文件读取并校验后,传给 `start_volume_measurement()`。 - 参数无效或文件读取失败时禁止启动设备,并在状态栏显示错误。 - 旧 UI 控件对象继续保留,避免影响仍依赖这些属性的历史代码。 #### 2.2 JSON 文件和字段 - 默认文件:`config/volume_measurement.json` - 打包后默认位置:可执行文件同级的 `config/volume_measurement.json` - 可使用环境变量 `REINLOOP_VOLUME_CONFIG` 覆盖默认路径。 - JSON 必须且只能包含下面 8 个字段: ```json { "q_in_val": 50.0, "dt": 0.05, "p_max": 200.0, "fit_low": 50.0, "fit_high": 150.0, "T_delta": 30.0, "xa_full": 1000.0, "num_runs": 3 } ``` 字段与 `start_volume_measurement()` 参数的对应关系: | JSON 字段 | 类型 | 作用 | | --- | --- | --- | | `q_in_val` | float | 进气流量 | | `dt` | float | 控制与采样周期 | | `p_max` | float | 测量压力上限 | | `fit_low` | float | 压力拟合区间下限 | | `fit_high` | float | 压力拟合区间上限 | | `T_delta` | float | 测量过程温升参数 | | `xa_full` | float | 电机总行程/全开行程参数 | | `num_runs` | int | 重复测量次数 | #### 2.3 代码位置和改动 1. `core/volume_config.py` - `REQUIRED_FIELDS`(约第 10 行):定义必须存在的 8 个字段。 - `default_config_path()`(约第 16 行):确定默认路径,并支持环境变量覆盖。 - `load_volume_config()`(约第 27 行):读取 JSON、拒绝缺失或多余字段、 校验数据类型及范围,最后返回可直接展开传参的字典。 - 范围约束包括:`dt > 0`、`p_max > 0`、 `0 <= fit_low < fit_high <= p_max`、`xa_full > 0`、 `num_runs` 为正整数。 2. `config/volume_measurement.json` - 新增默认配置模板。 - 该文件中的值是当前测试默认值,部署前应由项目负责人确认。 3. `ui/main_window.py` - 第 27 行附近:导入 `load_volume_config`。 - `_on_volume_measure()`(约第 589 行):删除以下 UI 参数读取逻辑: `get_identify_params()`、`get_advanced_params()`、控制页流量输入和 PID 周期。 - 新流程为: ```text 点击测试 -> load_volume_config() -> 校验成功 -> start_volume_measurement(conn_mgr, running_flag_check, **config) ``` - 配置失败时调用 `set_volume_finished()`,恢复测试按钮状态,不启动测量线程。 4. `ui/debug_tab.py` - 高级设置卡片创建完成后调用 `adv_card.hide()`(约第 123 行)。 - `_build_ident_section()` 末尾(约第 215 行)遍历布局并隐藏参数控件。 - 保留 `btn_wrap` 和 `seq_wrap`,因此测试和辨识操作按钮仍可见。 - `levels_entry` 单独隐藏。 - `get_identify_params()`、`get_advanced_params()` 和 QSettings 逻辑没有删除, 仅不再作为容积测试的数据来源。 5. `core/identification.py` - `start_volume_measurement()`(约第 196 行)接口本身未改名。 - 仍接收上述 8 个业务参数,内部继续调用 `measure_volume()` 并上传测量结果。 6. `tests/test_volume_config.py` - `test_load_valid_config()`:验证合法配置可以读取。 - `test_rejects_missing_field()`:验证缺少字段时拒绝启动。 - `test_rejects_invalid_range()`:验证非法拟合区间被拒绝。 #### 2.4 修改前后行为 修改前: ```text UI 流量输入 + PID 周期 + 调试页参数 + 高级设置 -> main_window.py 组合参数 -> start_volume_measurement() ``` 修改后: ```text config/volume_measurement.json -> load_volume_config() 严格校验 -> main_window.py 使用 **config -> start_volume_measurement() ``` #### 2.5 验证结果 - `tests/test_volume_config.py`:3 个测试全部通过。 - 30 个 Python 文件通过 AST 语法解析。 - `git diff --check` 通过,仅提示 Windows 的 LF/CRLF 转换警告。 - 未连接真实 MT2-AM8,因此尚未执行设备端容积测量联调。 #### 2.6 当前限制和安全说明 - 该阶段读取本地 JSON;当前实现已由第 4 节的云端单次请求替代。 - “隐藏”仅指参数不在客户 UI 中显示;如果 JSON 明文部署在客户电脑上, 有文件系统访问权限的用户仍可读取它。 - 若参数属于公司机密,后续应增加云端临时下载、身份校验、加密或用后销毁流程。 - 控制页面原有流量输入仍服务于其他控制功能,但容积测试不会读取该输入。 ## 待修改事项 ### 已完成:PRBS 前增加绝对行程稳态预扫描 - 修改文件:`core/identification.py`。 - 新增函数:`IdentificationManager._run_initial_travel_scan()`。 - `start_identification()` 的后台线程先调用新函数,完成后继续执行原有 `collect_data_with_prbs()`;PRBS 的生成、参数和上传逻辑未替换。 - 固定行程序列:`1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 0`。 - 稳态判据:最短等待 5 s、采样周期 0.1 s、滑动窗口 5 s、压力极差 `<= 0.5 kPa`、斜率绝对值 `<= 0.05 kPa/s`、连续稳定 3 s、单行程 最大等待 60 s。 - 每个达到稳态的行程只记录行程和平均稳定压力,不保存相对时间或响应过程。 - 输出为 JSON 对象,格式如下: ```json { "stable_pressures": [ {"distance": 1000, "pressure": 12.3}, {"distance": 900, "pressure": 15.6} ] } ``` - 压力单位为 kPa;未达到稳态或写入失败的行程不会写入结果,但其余记录仍能 通过 `distance` 明确对应行程。 - 预扫描结果单独上传至 `{客户名称}/ind_data/travel_stability_pressures_时间戳.json`。 - 行程指令不通过实时 UI 回调显示;UI 只接收压力。 - 用户停止或发生异常时尝试将行程写回 `0`。 - 预扫描上传失败不会改变后续 PRBS 行为,程序记录日志后继续 PRBS。 - 新增 `tests/test_initial_travel_scan.py`,模拟全部 11 个行程达到稳态,验证 上传文件为 JSON,且每条记录只包含 `distance` 和 `pressure`。 - 验证结果:34 个 Python 文件通过 AST 语法解析;原 `collect_data_with_prbs()` 调用及其 9 个传参保持不变;已有 3 个 JSON 配置单元测试继续通过;`git diff --check` 通过。 - 尚未连接真实 MT2-AM8,稳态等待、行程方向和 `0` 是否为安全位置需要硬件联调。 ### 3. 辨识的 9 个参数改为从云端 CSV 获取 #### 3.1 修改目标 - 客户端点击“开始辨识”后,不再读取调试页、控制页或高级设置中的本地参数。 - 客户端根据许可证中的客户名称,从云端读取固定 CSV 文件。 - CSV 解析和严格校验成功后,将 9 个业务参数一次性传给 `IdentificationManager.start_identification()`。 - `conn_mgr` 和 `running_flag_check` 是客户端运行时对象,仍由本地创建, 不属于云端 CSV。 - 参数不在客户界面显示;之前隐藏的参数控件继续保留用于兼容旧代码, 但辨识流程不会读取这些控件。 - 既有的绝对行程稳态预扫描和原始 PRBS 采集顺序不变。 #### 3.2 云端文件和接口 - 固定云端目录:`{客户名称}/identification_config` - 固定文件名:`identification_config.csv` - 完整对象存储路径: `ReinLoop_GUI/{客户名称}/identification_config/identification_config.csv` - 客户名称来自 `api.py` 的 `the_folder`,生产环境中对应许可证的 `customer` 字段。 - `index.js` 第 318 行附近新增 `getIdentificationConfig(event)`: 校验 `deviceId`,查询 `file_records` 中的固定记录,并返回腾讯云临时下载 URL。 - `index.js` 第 380 行附近新增同名分发入口。 - 仓库中的新版 `index.js` 已将固定查询文件改为 CSV;部署时应以仓库版本为准。 - 公司端仍通过既有 `uploadDataFile` 接口获取直传凭证;同一路径再次上传时, 云函数执行 upsert,客户端下一次辨识将读取覆盖后的版本。 #### 3.3 CSV 格式 `tool/identification_config.example.csv` 是公司端示例模板。实际客户配置应另存为 公司内部文件,不要放进客户安装包;CSV 固定使用 `parameter,value` 两列: ```csv parameter,value q_in_val,50.0 dt,0.1 n_order,6 t_c,2.5 levels,"10,20,30,40,50,60,70,80" dead_area,240.0 xa_full,1000.0 V_val,5.0 repeat,2 ``` | CSV 参数 | `start_identification()` 参数 | 校验要求 | | --- | --- | --- | | `q_in_val` | `q_in_val` | 有限数字,`>= 0` | | `dt` | `dt` | 有限数字,`> 0` | | `n_order` | `n_order` | 整数,`>= 2` | | `t_c` | `t_c` | 有限数字,`>= dt` | | `levels` | `levels` | 至少 2 项,长度为 2 的整数次幂,每项在 0~100 | | `dead_area` | `dead_area` | 有限数字,`0 <= dead_area < xa_full` | | `xa_full` | `xa_full` | 有限数字,`>= 1000` | | `V_val` | `V_val` | 有限数字,`> 0` | | `repeat` | `repeat` | 正整数 | `xa_full >= 1000` 是因为辨识开始前的固定行程预扫描包含 1000; `levels` 的长度要求来自原始 `generate_prbs()` 多电平映射算法。 #### 3.4 客户端代码位置和执行流程 1. `core/identification_config.py` - `REQUIRED_FIELDS`(第 7 行附近):定义 9 个必需字段。 - `validate_identification_config()`(第 13 行附近):拒绝缺失字段、 多余字段、布尔值、非有限数值和不安全的范围。 - `parse_identification_config_csv()`:解析 `parameter,value` 两列,并将 `levels` 的逗号分隔值恢复为 Python 列表。 - `download_identification_config()`(第 79 行附近):调用云函数, 获取临时 URL,下载 CSV,并在客户端再次校验。 2. `ui/main_window.py` - `_Bridge.identification_config_loaded`(第 46 行附近):后台下载完成后, 将结果安全地送回 Qt 主线程。 - `_on_identify_start()`(第 555 行附近):点击辨识后启动后台下载线程, 不阻塞界面,也不读取原有 UI 参数。 - `_on_identification_config_loaded()`(第 578 行附近):同步 `PcControl` 的 `xa_full`,再执行: ```python self.ident_mgr.start_identification( conn_mgr=self.conn_mgr, running_flag_check=lambda: self.engine.is_running, **config, ) ``` - `_on_identify_stop()`(第 597 行附近):停止辨识并使尚未完成的云端请求失效; 即使旧请求稍后返回,也不会再启动设备。 - `closeEvent()`(第 632 行附近):关闭软件时同样取消待处理请求并停止辨识。 3. `core/identification.py` - `start_identification()`(第 274 行附近)的接口和 9 个业务参数保持不变。 - 第 320 行附近仍先运行 `_run_initial_travel_scan()`,随后第 324 行附近 调用原始 `collect_data_with_prbs()`;PRBS 调节方式没有替换。 4. `setup.py` - 将 `core/identification_config.py`、`core/identification_feedback.py` 和 `core/volume_config.py` 加入 Cython 核心模块清单,正式构建时不需要向 客户交付这些模块的 Python 源码。 客户端完整流程: ```text 点击开始辨识 -> 后台调用 getIdentificationConfig(deviceId=许可证客户名称) -> 获取临时 URL 并下载 identification_config.csv -> 解析 parameter,value 两列 -> 严格校验 9 个参数 -> start_identification(conn_mgr, running_flag_check, **config) -> 1000 到 0 的稳态预扫描 -> 原始 PRBS 动态辨识 ``` #### 3.5 公司端上传工具 - 新增 `tool/upload_identification_config.py`。 - 第 41 行附近的 `upload_identification_config()` 在公司电脑上先使用与客户端 相同的规则解析和校验 CSV,再规范化为 UTF-8 CSV,并调用既有 COS 直传流程。 - 文件名和云端子目录由脚本固定,不能误传到模型目录。 - 使用方式: ```powershell python tool/upload_identification_config.py "客户名称" "公司内部路径\identification_config.csv" ``` - 同一客户再次执行会覆盖固定云端文件,用于多轮调整;已经运行中的一轮辨识 不会被中途改参,客户下一次点击辨识才获取新版本。 #### 3.6 验证结果 - 新增 `tests/test_identification_config.py`,覆盖:合法配置归一化、缺少字段、 CSV 解析、非 2 的整数次幂序列、`t_c < dt`、`xa_full < 1000`、死区越界。 - 容积配置、辨识配置和预扫描输出共 16 个单元测试全部通过;其中包含云函数请求参数、 临时 URL 下载和云端拒绝响应的模拟测试,不会访问真实网络。 - 35 个 Python 文件通过 AST 语法解析。 - `git diff --check` 通过,仅有 Git 的 LF/CRLF 转换提示。 - 本机没有 Node.js,因此未运行 `node --check index.js`。 - 当前 Python 环境未安装 `requests`(项目 `requirements.txt` 已声明该依赖), 因此未向真实云环境上传配置;云端流程仅使用模拟响应完成单元测试。 - 未连接 MT2-AM8 做完整硬件联调。 #### 3.7 安全边界和部署注意事项 - 客户 UI 不显示这 9 个参数,客户端本地也不需要保存配置文件;但 Python 客户端解析 CSV 后,参数会在进程内存中存在,不能等同于绝对防提取。 - `tool/identification_config.example.csv` 仅是字段模板;构建客户安装包时不要 打包 `tool` 目录,也不要把填写了真实参数的公司内部 CSV 放进项目分发目录。 - `config/identification_config.json` 仅是旧格式迁移提示,客户端不会读取; 辨识配置只使用云端固定 CSV 文件。 - 云函数返回的是有有效期的临时下载 URL,但源 CSV 会持续保存在云存储中; 当前实现是“同路径覆盖”,不是“客户端下载后销毁”。 - 当前 HTTP 云函数仅按 `deviceId` 查找文件,没有请求签名或设备身份认证。 知道接口和其他客户名称的人理论上可能越权请求,因此正式发布前必须增加 服务端许可证签名/设备令牌校验,不能只依赖 UI 隐藏。 - 修改后的 `index.js` 必须重新部署到当前腾讯云环境,否则客户端会收到 “无效的 type 字段”。 ### 4. 容积测试通过请求指令获取本次云端 8 参数 JSON - 客户点击“测试”后,客户端只调用一次 `createVolumeConfigRequest`,在云端创建 一条带 `requestId` 的请求指令;请求有效期为 5 分钟。 - 客户端随后每 2 秒调用 `getVolumeConfigRequest` 查询同一个 `requestId` 的状态。 这些调用只是监听该请求是否已有文件,不会重复创建请求,也不会重复要求公司端上传。 - 云端使用 `volume_config_requests` 集合保存等待上传、文件就绪和过期状态;创建新请求时 会清理该客户遗留的旧请求及其临时 JSON,避免客户端读取旧参数。 - 公司端工具调用 `getPendingVolumeConfigRequest` 等待客户请求,检测到请求后才校验并上传 8 参数 JSON,再调用 `submitVolumeConfigFile` 把文件与本次 `requestId` 关联: ```powershell python tool/upload_volume_config.py "客户名称" "公司内部路径\volume.json" --wait-seconds 300 ``` - 云端只接受位于 `{客户名称}/volume_config_requests/{requestId}/volume_measurement.json` 的上传记录, 并检查上传时间处于本次请求的创建时间和过期时间之间;其他请求或旧目录中的文件不能关联。 - 客户端检测到本次文件就绪后下载 JSON,严格校验 8 个字段,再执行一次 `start_volume_measurement(conn_mgr, running_flag_check, **config)`。 - 客户端加载完成、用户停止或请求超时后调用 `ackVolumeConfigRequest`,及时删除云端临时 JSON、 `file_records` 记录和请求记录。测量期间不再监听参数变化,也不会自动开始新一轮测量。 - 本地 `config/volume_measurement.json` 不提供业务参数,只保留迁移提示;公司端示例位于 `tool/volume_measurement.example.json`。 - 客户端要求 `q_in_val > 0`,避免容积计算除零;其他 7 个参数继续按原有范围严格校验。 - 当前共 23 个单元测试,38 个 Python 文件通过 AST 语法解析;未连接真实云端和 MT2-AM8 完成端到端联调。 - 更新后的 `index.js` 必须重新部署,新的请求指令接口才会生效。 ### 5. 辨识 CSV 的 0/1 审核与自动重测闭环 - `collect_data_with_prbs()` 生成的 `csv_data` 和 `.csv` 文件名现在直接上传到 `{客户名称}/ind_data`,不再重新包装为辨识结果 JSON。 - CSV 上传成功后,客户端调用 `registerIdentificationResult` 登记本轮文件名 作为 `runId`,然后每 2 秒调用 `getIdentificationFeedback` 查询审核结果。 - 云端使用 `identification_reviews` 集合;每个客户只保留当前一条待审核记录, 新一轮登记会覆盖旧记录并删除重复项。 - 审核结果严格使用数字:`1` 表示通过,`0` 表示未通过。其他值会被服务器和 客户端拒绝,布尔值也不会被当作数字接受。 - 客户端调试页新增持久状态显示:`正在辨识`、`等待反馈`、`已通过`、`未通过`、 `上传失败` 等。 - 收到 `1` 后显示“已通过”,停止反馈轮询并结束辨识流程。 - 收到 `0` 后显示“未通过”,每 2 秒重新下载云端 `identification_config.csv`;如果仍是本轮旧参数则继续等待,检测到 9 参数 内容变化后才重新调用 `start_identification()`,防止旧参数重复执行。 - 客户端消费 `0/1` 后调用 `ackIdentificationFeedback` 删除当前审核记录,避免 旧反馈被下一轮误用。 - 公司端或审核算法可调用 `setIdentificationFeedback`;人工测试命令为: ```powershell python tool/submit_identification_feedback.py "客户名称" 1 python tool/submit_identification_feedback.py "客户名称" 0 ``` - 新增 `tests/test_identification_feedback.py`,并补充辨识管理器 CSV 直传测试; 当前 20 个单元测试全部通过,38 个 Python 文件通过 AST 语法解析。 - 尚未对真实云函数、审核程序和 MT2-AM8 进行端到端联调;更新后的 `index.js` 必须重新部署。 - [x] 明确容积测试的云端 JSON 参数格式和传输流程。 - [x] 明确辨识功能的云端 CSV 参数格式和传输流程。 - [x] 明确绝对行程扫描与 PRBS 辨识的当前执行顺序。 - [x] 隐藏客户调试页中的容积和辨识参数控件。 - [x] 明确测试结果上传、公司端审核和多轮反馈流程。 - [ ] 完成真实 MT2-AM8 硬件联调。