Files
ReinLoopTest/ReinLoop/修改记录.md
2026-07-30 11:12:31 +08:00

32 KiB
Raw Permalink Blame History

修改记录

当前状态说明:本节以 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 提交辨识审核数字 10
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

客户点击“开始辨识”后,客户端按许可证中的客户名称读取:

ReinLoop_GUI/{客户名称}/identification_config/identification_config.csv

CSV 固定使用 parameter,value 两列:

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_mgrrunning_flag_check 仍由客户端本地创建,不属于 CSV。

公司端上传命令:

python tool/upload_identification_config.py "客户名称" "公司内部路径\identification_config.csv"

同一路径再次上传会覆盖固定 CSV。客户端只在开始一轮辨识或收到未通过结果后重新读取,不会在本轮运行中途替换参数。

1000 -> 0 行程稳态预扫描

start_identification() 先扫描以下绝对行程,再调用原有 collect_data_with_prbs()

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。内容只包含行程和稳定压力,不包含相对时间,也不保存压力变化过程数组:

{
  "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 格式。

上传 PRBS CSV
  -> registerIdentificationResult 登记本轮 CSV 文件名为 runId
  -> 客户端每 2 秒查询 getIdentificationFeedback
  -> 数字 1:显示“已通过”,清理反馈记录,结束
  -> 数字 0:显示“未通过”,清理反馈记录,等待云端 CSV 更新
  -> 每 2 秒重新获取 identification_config.csv
  -> 9 参数内容与本轮不同后,才重新执行完整辨识

反馈只接受数字 01,布尔值和其他数字均拒绝。公司端命令:

python tool/submit_identification_feedback.py "客户名称" 1
python tool/submit_identification_feedback.py "客户名称" 0

云端集合 identification_reviews 对每个客户只保留当前待审核记录,客户端消费后调用 ackIdentificationFeedback 删除,防止下一轮误用旧结果。

当前容积测试流程

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
}

客户端要求且只允许这 8 个字段。主要约束:q_in_val > 0dt > 0p_max > 00 <= fit_low < fit_high <= p_maxxa_full > 0num_runs 为正整数,其他数值必须有限。

最终请求握手

服务器不能主动向客户端或公司端推送,因此采用“一次创建请求 + 两端查询同一请求状态”:

客户点击“测试”
  -> 客户端只调用一次 createVolumeConfigRequest
  -> 云端生成 requestId,写入 volume_config_requests,有效期 5 分钟

公司端工具
  -> 每 2 秒查询 getPendingVolumeConfigRequest
  -> 检测到 requestId 后才上传 8 参数 JSON
  -> submitVolumeConfigFile 把文件与 requestId 关联

客户端等待期间
  -> 每 2 秒查询 getVolumeConfigRequest,始终使用同一个 requestId
  -> 状态查询不会重复创建请求,也不会重复要求公司端上传
  -> 检测到本次新文件后下载并校验 JSON
  -> ackVolumeConfigRequest 删除临时文件和请求记录
  -> 执行一次 start_volume_measurement(..., **config)

公司端命令:

python tool/upload_volume_config.py "客户名称" "公司内部路径\volume.json" --wait-seconds 300

云端文件固定为:

ReinLoop_GUI/{客户名称}/volume_config_requests/{requestId}/volume_measurement.json

submitVolumeConfigFile 会核对 file_records 中的客户目录、requestId、文件名和上传时间。只有请求创建后、5 分钟内上传且属于该请求的 JSON 才能加载;旧目录或其他请求的文件不能关联。

临时文件处理

  • 创建新请求时,云端清理该客户遗留的旧容积请求及临时 JSON。
  • 客户端加载成功、用户停止或请求超时后,删除当前请求、云存储 JSON 和对应 file_records 记录。
  • 公司端上传或关联失败时,工具尝试删除刚上传的文件。
  • 测量开始后不再监听参数变化,也不会因云端更新而自动重测;下一次必须由客户再次点击“测试”。
  • 辨识 CSV 是公司维护的固定文件,后续上传会覆盖;容积 JSON 是一次请求的临时文件,消费后删除。

上一版“公司预先写入最新 8 参数、客户端直接获取”的方案已移除。当前代码不存在 pushVolumeConfiggetVolumeConfigvolume_measurement_configs 的有效调用路径。

当前客户端和构建修改

  • 调试页隐藏辨识、容积参数和高级设置,保留开始/停止按钮及辨识审核状态。
  • 网络请求在后台线程中执行,通过 Qt Signal 回到主线程更新界面。
  • 请求代数编号和 inflight 标志用于忽略停止后迟到的结果,并阻止同类请求并发。
  • 辨识与容积测试互斥;停止或关闭窗口时停止定时器、使旧请求失效并尝试清理云端状态。
  • IdentificationManager.is_running 同时检查运行标志和任务线程是否存活。
  • start_identification()start_volume_measurement() 返回布尔值,调用方可判断任务是否启动。
  • setup.py 新增 core/identification_config.pycore/identification_feedback.pycore/volume_config.py 三个 Cython 编译目标。

当前新增云函数接口

接口 调用方 作用
getIdentificationConfig 客户端 获取当前客户固定辨识 CSV 的临时地址。
registerIdentificationResult 客户端 登记刚上传的 PRBS CSV。
getIdentificationFeedback 客户端 查询本轮数字 0/1
setIdentificationFeedback 公司端 提交本轮数字 0/1
ackIdentificationFeedback 客户端 删除已消费反馈。
createVolumeConfigRequest 客户端 点击“测试”时创建一次 5 分钟请求。
getPendingVolumeConfigRequest 公司端 查询客户的待上传请求。
submitVolumeConfigFile 公司端 把 JSON 与本次请求关联。
getVolumeConfigRequest 客户端 查询同一请求是否已有有效 JSON。
ackVolumeConfigRequest 客户端 删除已消费、取消或超时的请求和文件。

当前验证结果

已执行:

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.jsindex.js 尚未完成语法检查;上一次借用 VS Code 运行时的检查被中止,不计为通过。
  4. 云数据库需要允许云函数读写 identification_reviewsvolume_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 的原始接口分发,仅保留: uploadDataFilelistModelsdownloadModeldeleteFileuploadUserInfo
  • 测试版新增的参数传输和多轮调试接口不再从云函数入口暴露。
  • 已从恢复版 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 个字段:
{
  "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 > 0p_max > 00 <= fit_low < fit_high <= p_maxxa_full > 0num_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 周期。
    • 新流程为:
点击测试
  -> load_volume_config()
  -> 校验成功
  -> start_volume_measurement(conn_mgr, running_flag_check, **config)
  • 配置失败时调用 set_volume_finished(),恢复测试按钮状态,不启动测量线程。
  1. ui/debug_tab.py

    • 高级设置卡片创建完成后调用 adv_card.hide()(约第 123 行)。
    • _build_ident_section() 末尾(约第 215 行)遍历布局并隐藏参数控件。
    • 保留 btn_wrapseq_wrap,因此测试和辨识操作按钮仍可见。
    • levels_entry 单独隐藏。
    • get_identify_params()get_advanced_params() 和 QSettings 逻辑没有删除, 仅不再作为容积测试的数据来源。
  2. core/identification.py

    • start_volume_measurement()(约第 196 行)接口本身未改名。
    • 仍接收上述 8 个业务参数,内部继续调用 measure_volume() 并上传测量结果。
  3. tests/test_volume_config.py

    • test_load_valid_config():验证合法配置可以读取。
    • test_rejects_missing_field():验证缺少字段时拒绝启动。
    • test_rejects_invalid_range():验证非法拟合区间被拒绝。

2.4 修改前后行为

修改前:

UI 流量输入 + PID 周期 + 调试页参数 + 高级设置
  -> main_window.py 组合参数
  -> start_volume_measurement()

修改后:

config/volume_measurement.json
  -> load_volume_config() 严格校验
  -> main_window.py 使用 **config
  -> start_volume_measurement()

2.5 验证结果

  • tests/test_volume_config.py3 个测试全部通过。
  • 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 对象,格式如下:
{
  "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,且每条记录只包含 distancepressure
  • 验证结果: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_mgrrunning_flag_check 是客户端运行时对象,仍由本地创建, 不属于云端 CSV。
  • 参数不在客户界面显示;之前隐藏的参数控件继续保留用于兼容旧代码, 但辨识流程不会读取这些控件。
  • 既有的绝对行程稳态预扫描和原始 PRBS 采集顺序不变。

3.2 云端文件和接口

  • 固定云端目录:{客户名称}/identification_config
  • 固定文件名:identification_config.csv
  • 完整对象存储路径: ReinLoop_GUI/{客户名称}/identification_config/identification_config.csv
  • 客户名称来自 api.pythe_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 两列:

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 行附近):同步 PcControlxa_full,再执行:
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 行附近):关闭软件时同样取消待处理请求并停止辨识。
  1. core/identification.py

    • start_identification()(第 274 行附近)的接口和 9 个业务参数保持不变。
    • 第 320 行附近仍先运行 _run_initial_travel_scan(),随后第 324 行附近 调用原始 collect_data_with_prbs()PRBS 调节方式没有替换。
  2. setup.py

    • core/identification_config.pycore/identification_feedback.pycore/volume_config.py 加入 Cython 核心模块清单,正式构建时不需要向 客户交付这些模块的 Python 源码。

客户端完整流程:

点击开始辨识
  -> 后台调用 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 直传流程。
  • 文件名和云端子目录由脚本固定,不能误传到模型目录。
  • 使用方式:
python tool/upload_identification_config.py "客户名称" "公司内部路径\identification_config.csv"
  • 同一客户再次执行会覆盖固定云端文件,用于多轮调整;已经运行中的一轮辨识 不会被中途改参,客户下一次点击辨识才获取新版本。

3.6 验证结果

  • 新增 tests/test_identification_config.py,覆盖:合法配置归一化、缺少字段、 CSV 解析、非 2 的整数次幂序列、t_c < dtxa_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 关联:
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;人工测试命令为:
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 必须重新部署。

  • 明确容积测试的云端 JSON 参数格式和传输流程。

  • 明确辨识功能的云端 CSV 参数格式和传输流程。

  • 明确绝对行程扫描与 PRBS 辨识的当前执行顺序。

  • 隐藏客户调试页中的容积和辨识参数控件。

  • 明确测试结果上传、公司端审核和多轮反馈流程。

  • 完成真实 MT2-AM8 硬件联调。