M7-T07: finalize M7 docs (roadmap entry, design index, status done, meter-epochs module doc)
frontend / frontend (push) Successful in 2m10s
pytest / test (push) Successful in 8m34s

This commit is contained in:
2026-06-25 17:01:54 +02:00
parent 33f5de0591
commit e3d0d17cac
4 changed files with 168 additions and 8 deletions
+44 -1
View File
@@ -2,7 +2,7 @@
本文档记录 `home-automation``v1.0.3` 之后的下一阶段规划。这一阶段不是小修补,而是几次较大的结构性改动:单库化、前端重写、以及远期的移动端试水。
> 每个里程碑的**可执行原子任务**展开在 [`docs/design/`](./design/README.md)M1 [`m1-db-consolidation.md`](./design/m1-db-consolidation.md)、M2 [`m2-frontend-v2.md`](./design/m2-frontend-v2.md)、M3 [`m3-token-mobile.md`](./design/m3-token-mobile.md)、M4 [`m4-login-hardening.md`](./design/m4-login-hardening.md)、M5 [`m5-iot-energy.md`](./design/m5-iot-energy.md)、M6 [`m6-tibber-dynamic-energy.md`](./design/m6-tibber-dynamic-energy.md)。这些文档为 Orchestrator→Implementer→Reviewer 的多模型流水线设计。
> 每个里程碑的**可执行原子任务**展开在 [`docs/design/`](./design/README.md)M1 [`m1-db-consolidation.md`](./design/m1-db-consolidation.md)、M2 [`m2-frontend-v2.md`](./design/m2-frontend-v2.md)、M3 [`m3-token-mobile.md`](./design/m3-token-mobile.md)、M4 [`m4-login-hardening.md`](./design/m4-login-hardening.md)、M5 [`m5-iot-energy.md`](./design/m5-iot-energy.md)、M6 [`m6-tibber-dynamic-energy.md`](./design/m6-tibber-dynamic-energy.md)、M7 [`m7-meter-epochs-archival.md`](./design/m7-meter-epochs-archival.md)。这些文档为 Orchestrator→Implementer→Reviewer 的多模型流水线设计。
## 当前基线(v1.0.3
@@ -39,6 +39,7 @@
| **M4** ✅ | 登录加固 | 防爆破/指数退避 + CLI 逃生通道 + 可选 TOTP 二次验证(**先于 M5** |
| **M5** ✅ | IoT / 能耗采集 | 通用 Modbus 采集(YAML profile + JSON readings+ MQTT/HA Discovery + 前端侧边栏 + Energy 视图 |
| **M6** ✅ | 通用电价层 + DSMR 接入 + 实时电费计算 | 通用电价层(manual/tibber profile + 合同版本)+ DSMR 实时电表接入 + 每 15min 寄存器差×价计量电费(不可变快照)+ 日/月/年汇总 + 反哺 HA Energy + 前端合同/价格/费用视图 |
| **M7** ✅ | 电表生命周期 / 换表归档 | 引入 Meter epoch,计费永不跨表算 delta,跨表/无表/异常 delta 一律降级,累计按当前表归零,追溯换表可重算,Meter CRUD API + 前端管理 UI |
| **M3** | 开放与移动端(远期试水) | token 鉴权 + React Native 移动端 |
排序原则:**先清地基,再在干净结构上盖楼。** M2 的新 API 和 React 必须建立在合并后的单库之上;M4 是公网安全加固,在 M5 IoT 集成之前先堵住裸密码这个洞;M5 在安全基座就绪后再做 IoT 接入。
@@ -214,6 +215,48 @@ httpx / paho-mqtt / pyyaml / apscheduler 均为 M5 已有依赖,M6 复用,
---
## M7 — 电表生命周期 / 换表归档(✅ 已完成)
### 目标
让计费系统正确处理**电表更换**这一必然事件:荷兰 2G 智能电表退网后,电网公司会把表换成 4G 表(同址换表);搬家继承新表也是同类。引入显式的 **Meter(电表)epoch** 概念,标记"某时刻起属于哪一块物理表",使引擎**永不跨表算 delta**,并让累计量按表归零、历史可追溯可查。
### 关键能力
- **Meter epoch 数据模型**:一条 `meter` 记录 = 一块物理电表的一段安装期 `[started_at, ended_at)`。换表 = 关闭旧 active 表(`ended_at=T`+ 新建 `started_at=T` 的表。每 `commodity` 至多一个 active 表;`commodity` 字段预留 `gas`/`heating`
- **计费永不跨表**`compute_period` 先查 t0/t1 两端的 `meter_at`;无表覆盖或跨表边界 → **降级**(成本置 0),绝不产负成本或巨额假成本。
- **delta 护栏**:任一寄存器 delta `< 0``> _MAX_DELTA_KWH`100 kWh/15min,远超住宅用量)→ 降级。兜底表重置 / DSMR 回绕 / 数据毛刺,与换表无关的异常也一并防住。
- **累计按当前表归零(D2**`expose.py` 累计 `import_cost_total`/`export_revenue_total` 锚点 = 当前 active electricity meter 的 `started_at`;换表后累计从零起新序列,不维护跨表偏移。
- **追溯换表可重算**`started_at` 可在过去;PATCH 修正日期后,触发受影响窗口 `recompute_range` 重判跨表周期归属。
- **Meter CRUD API + 前端管理 UI**`GET/POST/PATCH /api/energy/meters`+ 追溯 recompute);Energy 页新增 Meters tab,展示电表时间线,支持"换表/继承"表单与编辑。
### 新增表与列(单库 app 链,migration `20260625_13_meter_table`
| 表/列 | 关键设计 |
| --- | --- |
| `meter` | `id``label``commodity`(默认 `electricity`)、`started_at``ended_at`null=active)、`reason``initial`/`meter_swap`/`home_move`/`other`)、`note``created_at` |
| `energy_cost_period.meter_id` | nullable FK → `meter.id`;记录每周期归属,便于审计/按表查询/归档 |
迁移含回填:有历史数据时自动创建一条 `reason="initial"` 的初始表,并回填现有 `energy_cost_period.meter_id`;幂等 + 对账(非降级周期回填后 `meter_id IS NULL` 数必须为 0)。
### 已锁定决策摘要
- **D1**Meter 不绑定 home`label` 编址 + `commodity` 区分品类。
- **D2**:换表后累计量归零(锚当前表起点),不维护跨表偏移。
- **D3**:合同与电表是独立时间线,合同不引用电表;同址换表时合同自动沿用。
- **D4**`started_at` 可在过去;有效计费起点 = `max(started_at, 数据起点)`
- **D5**:跨表边界周期判 degraded(换表常伴随长时间无数据,可接受)。
- **D6**:负/异常大 delta → degraded,通用兜底。
- **D7**gas/heating 计费不在本里程碑;`commodity` 字段为未来扩展预留。
**已知行为(可接受)**:累计 `_total``state_class: total`,换表归零时 HA 长期统计可能在换表那一刻记一次性负 blip。已与用户确认先这样、观察后按需处理(`last_reset` 信号见设计文档 §9 留痕,本里程碑不做)。
> 详细设计与任务卡:[`docs/design/m7-meter-epochs-archival.md`](./design/m7-meter-epochs-archival.md)
>
> 模块概念说明:[`docs/meter-epochs.md`](./meter-epochs.md)
---
## M3 — 开放与移动端(远期试水)
### 目标