M6-T07: add metering billing engine + period job + summary + recompute

- app/services/energy_cost.py: register_at (register values at a UTC boundary),
  compute_period (register deltas x active-version strategy, snapshot price +
  contract_version_id, immutable unless overwrite), compute_closed_periods
  (bounded lookback), recompute_range (explicit overwrite), summarize
  (sum net + standing fees month/30 - heffingskorting year/365).
- Missing tibber price -> skip; missing reading -> degraded (zeroed amounts,
  null version), consistently on both create and recompute paths.
- main.py: 1-minute energy-cost job (existing jobs/MQTT untouched). Tests added.
This commit is contained in:
2026-06-23 22:26:56 +02:00
parent ef48032adb
commit d35ac7d752
4 changed files with 1801 additions and 1 deletions
+1 -1
View File
@@ -378,7 +378,7 @@ Phase DAPI + 前端)
- **Reviewer checklist**: on_message 网络线程内只做短事务、吞异常不崩连接;整帧存(含 gas/各相);null 容错;`source_id` 幂等;10s 降采样正确。
### M6-T07 — 计费引擎 + 周期 job + 汇总 + 重算
- **Status**: `todo` · **Depends**: M6-T01, M6-T03, M6-T04, M6-T05, M6-T06
- **Status**: `done` · **Depends**: M6-T01, M6-T03, M6-T04, M6-T05, M6-T06
- **Context**: 每 15min 用寄存器差 × active 合同 strategy 算计量电费(快照、不可变);汇总加固定费 − 抵扣;周期 job + 重算。
- **Files**: `create app/services/energy_cost.py``modify app/main.py`(周期 job);`create tests/test_energy_cost.py`
- **Steps**: