功能:扩展开放平台氢耗溯源与合作站数据

This commit is contained in:
lingniu
2026-09-02 14:05:34 +08:00
parent 8759668d39
commit c6875fbb98
33 changed files with 5692 additions and 475 deletions
+22 -14
View File
@@ -343,35 +343,40 @@ PUT /portal-api/account/password
## 用氢量统计
当天数据由 `vehicle-stat-writer` 直接消费 GB32960 fields Kafka 流,统一采用压力法:
用氢量只接收 `GB32960` 帧,不读取 JT808、宇通 MQTT 或其他协议。统一采用压力法:
```text
剩余氢量 kg = NIST氢气密度(最高氢压 MPa, 最高氢温 ℃) × 车型氢瓶容量 L / 1000
```
- 不使用广东扩展直接上报的剩余氢量、飞驰剩余百分比或百公里氢耗推算质量;
- `vehicle-stat-writer` 每六小时从 `ln_asset_management.vehicle_info → vehicle_model.tank_capacity` 同步 VIN 容积到本地 `vehicle_hydrogen_tank_capacity`
- 同步完成后一次性加载到进程内存,高频帧计算不访问资产库、Redis或MySQL;缺少VIN容积时拒绝生成氢量
- 压力法使用 NIST 实氢气密度方程,允许 070 MPa、220–1000 K 的输入范围。
- 不使用广东扩展直接上报的剩余氢量、飞驰剩余百分比、宇通 MQTT 剩余氢量或百公里氢耗推算质量;
- `vehicle-stat-writer` 启动时及每六小时从 `ln_asset_management.vehicle_info → vehicle_model` 同步车型参数:`tank_capacity` VIN 投影到 `vehicle_hydrogen_tank_capacity``battery_capacity` 按 VIN 投影到 `vehicle_hydrogen_energy_parameter`
- 额定电量按车辆关联的具体车型读取,不按吨位写死;后续生效日期更晚的人工业务参数仍可覆盖自动同步基线
- 储氢容积同步后一次性加载到统计进程内存,高频帧计算不访问资产库、Redis或MySQL;额定电量由日氢耗任务按VIN和统计日期读取;缺少VIN容积时拒绝生成氢量;
- 压力法使用 NIST 实氢气密度方程,允许 070 MPa、220–1000 K 的输入范围;
- GB32960 上报的是“最高氢压”和“最高氢温”,两者不保证来自同一探头,也不保证代表静置平衡后的储氢瓶状态。因此压力法结果是车载信号估算值,不能用加氢站计量值直接反标公式系数。
每个有效样本在同一个 MySQL 事务中更新
`vehicle_open_hydrogen_stream_state`,并投影到
当天准实时数据由 `vehicle-stat-writer` 消费 GB32960 fields Kafka 流。每个有效样本在同一个 MySQL 事务中更新
`vehicle_open_hydrogen_segment_stream_state`,并投影到
`vehicle_open_daily_energy`。Kafka offset 只在事务提交成功后提交,因此服务重启或消息重放不会重复累计。状态按
`VIN + 日期 + source_endpoint` 保存,每条消息只做常数次数据库操作,不扫描当天历史数据。
`VIN + 日期` 保存并合并全部连接端点;每条消息只做常数次数据库操作,不扫描当天历史数据。
统计规则:
- 先按 VIN `source_endpoint` 分别统计,避免多个采集源的序列交错产生虚假变化
- 同一 VIN 优先采用质量正常、样本数量更多的数据源,并记录入库
- 每次加氢之间维护质量低水位,只累计新的有效最低质量,避免压力温度波动反复计量;
- 已结束日期先按 VIN 合并全部 `source_endpoint`,同一事件时间只保留一条可信样本;连接端口仅用于追踪,不再作为互斥统计来源
- 只有相邻两条样本都确认燃料电池处于工作状态时,才纳入工作段;优先采用广东扩展 `engine_work_state=2`,缺失时以燃料电池电流大于 `1 A` 作为回退;完全没有工作区间的日期标记为 `NO_DATA`
- 加氢、超过 5 分钟的数据断点、燃料电池停机和异常跳变会切分工作段;每段开始与结束各取 5 条样本的氢质量中位数做差,再累加为当日用氢量;
- 每个可计算工作段至少需要 10 条有效样本;段首尾差值未超过动态噪声阈值时不累计;
- 燃料电池未工作时,下降的压力质量只更新防重复计算的低水位,不降低对外剩余氢量;压力或质量恢复上升后再更新剩余量;
- 抖动阈值按该VIN容积对应的 `0.2 MPa` 质量变化动态计算,最小 `0.05 kg`、最大 `1 kg`
- 质量相对本轮低水位上升超过 `max(1 kg, 当前质量×5%)` 时识别为加氢并重置低水位;
- 相邻样本在 60 秒内无工作耗氢却恢复至少 `8 MPa` 时,按压力信号恢复处理,重置低水位但不增加加氢次数;
- 单次下降超过 `OPEN_STAT_HYDROGEN_MAX_DROP_KG` 时过滤并标记 `SUSPECT`,默认 `20 kg`
- 至少两条有效样本才标记 `OK`
- 对外只返回 `quality_status=OK` 的结果。
当天接口结果是准实时的进行中累计值。乱序、重复和迟到样本不会覆盖更新的状态;跨日迟到数据由
`open-platform-stat` 夜间批处理兜底。批处理默认重算昨天和前天,以修正迟到上报,并作为已结束日期的权威结果。
分段计算由流式状态机直接执行:每车仅保留当前段的首 5 帧、尾 5 帧、低水位、上一帧和事件时间水位,状态不会随当天帧数增长。水位只覆盖当前自然日 `00:00:0024:00:00`,不向前后日期扩窗,也不借用次日帧;早于或等于当前事件时间水位的延迟帧直接忽略。流式结果采用与日终相同的工作段、中位数、加氢和异常跳变规则;已结束日期仍由 `open-platform-stat` 重算,作为最终对账结果。
历史重放只接收事件时间和接收时间同时落在统计日内的 GB32960 帧。每个统计日先读取有数据且配置了氢瓶容积的 VIN,再在同一进程内按单车单日并行查询;默认 4 个工作线程,全部车辆成功后才一次性事务替换当天结果。单车帧按 `event_time` 排序并单遍去重;JSON 只读取压力、温度和工作状态字段,不展开整帧,从而减少全车排序与反序列化开销。可通过 `-vin-workers``OPEN_STAT_VIN_WORKERS` 调整工作线程数。
```bash
/opt/lingniu-vehicle-platform/current/open-platform-stat \
@@ -380,3 +385,6 @@ PUT /portal-api/account/password
systemctl enable --now lingniu-vehicle-open-stat.timer
```
流式算法首次切换时,先停止 `lingniu-go-stat-writer.service`,再对当天执行一次
`-seed-stream-state`。该参数会在同一个 MySQL 事务中替换当天结果并写入每车最后事件时间水位;恢复 Kafka 消费后,已经包含在重算结果中的 backlog 不会再次累计。正常日终任务不使用此参数。