32 KiB
修改记录
当前状态说明:本节以 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 修改默认值,增加压力滤波(暂未启用) |
| 工作区状态 | 本文所列修改均尚未提交 |
相对基线,当前增加了三条主要业务链路:
- 辨识前执行
1000 -> 0的绝对行程稳态压力预扫描,上传不含时间字段的 JSON。 - 辨识 9 参数改为从云端 CSV 获取;PRBS 结果保持 CSV 上传,并根据云端数字
0/1显示审核结果。未通过时等待公司更新参数,再重新执行完整辨识。 - 容积测试 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.pytests/test_identification_config.pytests/test_identification_feedback.pytests/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_mgr 和 running_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 参数内容与本轮不同后,才重新执行完整辨识
反馈只接受数字 0 或 1,布尔值和其他数字均拒绝。公司端命令:
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 > 0、dt > 0、p_max > 0、0 <= fit_low < fit_high <= p_max、xa_full > 0、num_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 参数、客户端直接获取”的方案已移除。当前代码不存在 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 |
客户端 | 删除已消费、取消或超时的请求和文件。 |
当前验证结果
已执行:
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、一次请求创建、等待/就绪状态和请求清理。
尚未完成和发布风险
- 尚未连接真实 MT2-AM8、真实云环境和公司端工具完成端到端联调。
- 新
index.js尚未部署;部署前客户端无法使用新增接口。 - 本机没有独立 Node.js,
index.js尚未完成语法检查;上一次借用 VS Code 运行时的检查被中止,不计为通过。 - 云数据库需要允许云函数读写
identification_reviews、volume_config_requests和现有file_records。 - 当前 HTTP 接口主要依赖
deviceId区分客户,没有请求签名或设备令牌;正式发布前需要服务端身份认证。 - 当前
index.js含明文小程序SECRET。不得直接提交或分发,应立即轮换,并改为从云函数环境变量或密钥服务读取。 requirements.txt未声明程序实际使用的PySide6,新机器仅按该文件安装仍不能启动。- 所有改动仍在工作区,尚未形成 Git 提交。
发布顺序建议
- 轮换并移除
index.js中的明文SECRET。 - 在测试云环境部署
index.js,建立并授权新增集合。 - 公司端先上传一份辨识参数 CSV。
- 联调一次容积请求的创建、发现、上传、下载和删除。
- 联调预扫描、PRBS CSV 上传和
0/1反馈重测。 - 补齐运行依赖和打包配置,再生成客户安装包。
历史过程记录(仅供追溯,当前行为以上述整理为准)
项目基线
- 仓库:
https://github.com/azuki-m/pressure_control_gui.git - 分支:
MT2-AM8 - 基线提交:
5841f6d 修改默认值,增加压力滤波(暂未启用) - 本地目录:
C:\Users\31765\.codex\pressure_control_gui_source - 开始日期:2026-07-22
记录规则
每次修改应记录以下内容:
- 修改目标和需求来源。
- 涉及的文件、类和函数。
- 修改前后的行为差异。
- 参数、接口或数据格式变化。
- 验证方法和验证结果。
- 尚未完成的事项与风险。
修改历史
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 个字段:
{
"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 代码位置和改动
-
core/volume_config.pyREQUIRED_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为正整数。
-
config/volume_measurement.json- 新增默认配置模板。
- 该文件中的值是当前测试默认值,部署前应由项目负责人确认。
-
ui/main_window.py- 第 27 行附近:导入
load_volume_config。 _on_volume_measure()(约第 589 行):删除以下 UI 参数读取逻辑:get_identify_params()、get_advanced_params()、控制页流量输入和 PID 周期。- 新流程为:
- 第 27 行附近:导入
点击测试
-> load_volume_config()
-> 校验成功
-> start_volume_measurement(conn_mgr, running_flag_check, **config)
- 配置失败时调用
set_volume_finished(),恢复测试按钮状态,不启动测量线程。
-
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 逻辑没有删除, 仅不再作为容积测试的数据来源。
- 高级设置卡片创建完成后调用
-
core/identification.pystart_volume_measurement()(约第 196 行)接口本身未改名。- 仍接收上述 8 个业务参数,内部继续调用
measure_volume()并上传测量结果。
-
tests/test_volume_config.pytest_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.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 对象,格式如下:
{
"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 两列:
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 客户端代码位置和执行流程
-
core/identification_config.pyREQUIRED_FIELDS(第 7 行附近):定义 9 个必需字段。validate_identification_config()(第 13 行附近):拒绝缺失字段、 多余字段、布尔值、非有限数值和不安全的范围。parse_identification_config_csv():解析parameter,value两列,并将levels的逗号分隔值恢复为 Python 列表。download_identification_config()(第 79 行附近):调用云函数, 获取临时 URL,下载 CSV,并在客户端再次校验。
-
ui/main_window.py_Bridge.identification_config_loaded(第 46 行附近):后台下载完成后, 将结果安全地送回 Qt 主线程。_on_identify_start()(第 555 行附近):点击辨识后启动后台下载线程, 不阻塞界面,也不读取原有 UI 参数。_on_identification_config_loaded()(第 578 行附近):同步PcControl的xa_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 行附近):关闭软件时同样取消待处理请求并停止辨识。
-
core/identification.pystart_identification()(第 274 行附近)的接口和 9 个业务参数保持不变。- 第 320 行附近仍先运行
_run_initial_travel_scan(),随后第 324 行附近 调用原始collect_data_with_prbs();PRBS 调节方式没有替换。
-
setup.py- 将
core/identification_config.py、core/identification_feedback.py和core/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 < 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关联:
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 硬件联调。