feat: 完成 issue #20 [M1] 搭建缺省通用点位集(演示用,不依赖客户数据)

This commit is contained in:
2026-08-04 22:44:20 +08:00
parent 91bb0c5912
commit 366311abdc
3 changed files with 135 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
# iAOP-Template-Ti 一期 · 缺省通用点位集(Demo 点位字典)
对应 EPIC #2「[M1] 数据接入准备」子任务 **#20**(0.5d):
搭建**缺省通用点位集**(演示用,不依赖客户数据),供 PRD 13 章
「缺省数据策略」使用——客户 DCS 点表延迟/字段不完整时,
启用本点位集完成**演示与框架验证**,点表到位后无缝切换真实点位字典。
## 用途(PRD 13 章)
| 场景 | 处理 |
| --- | --- |
| 客户 DCS 点表延迟 | 启用 `point_dict.default.csv` 先行演示(M1 截止日仍未收到完整点表时触发) |
| 点表字段不完整 | 仅接入已确认点位;未确认部分保持缺省点位占位 |
| 点表到位后 | 由配置台导入真实点位字典,**无缝切换**,网关零改动 |
点位范围对齐 PRD 7.2「点位字典范围(一期)」:
- **沸腾氯化炉**(`CLF-01`):炉温、炉压、氯气流量、CO/CO₂、炉层状态、进料量;
- **精制/还原工序**(`RF-01`):还原温度、真空度、TiCl₄ 纯度、杂质含量;
- **能源/公用工程**(`E-01` / `ST-01` / `CW-01`):电、蒸汽、循环水。
## 资产说明
| 资产 | 说明 |
| --- | --- |
| `point_dict.default.csv` | 缺省通用点位字典(对齐内核 CSV schema:9 列,与 `core/edge-gateway/config/point_dict.example.csv` 一致) |
## 设计说明
- **不依赖客户数据**:所有点位 `protocol = simulator`,由内核模拟采集驱动
(`core/edge-gateway/drivers/simulator_driver.py`)按点位生成确定性伪随机值,
本地即可端到端联调(采集→spool→Kafka),无需任何现场设备/点表;
- **schema 对齐**:表头、量纲、数据类型、采样率、协议与内核点位字典
schema(`core/edge-gateway/point_dict/schema.py`)完全一致,
`python core/edge-gateway/point_dict/validator.py` 可直接校验通过;
- **opcNode 占位**:`opcNode` 列保留典型 OPC UA 节点路径(如 `ns=2;s=CLF.Temp`),
模拟现场点表结构;真实点表导入时按配置台校验后替换;
- **采样率**:工艺快变量 1000ms(1Hz),质量类慢变量(纯度/杂质)60000ms(1min)。
## 校验
```bash
python templates/ti-cl4/point-dict/_sanity_check.py
```
校验:CSV 表头与内核 schema 对齐(9 列)、非空、无空行、行内列数一致、
protocol 全部为合法协议(simulator 等)、sampleRate 为正整数。
@@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
"""iAOP-Template-Ti 一期 · 缺省通用点位集 sanity 检查(离线基本验证)。
检查项:
1. 点位字典 CSV:表头与内核 `core/edge-gateway/config/point_dict.example.csv`
对齐(9 列),且非空、无空行、每行列数一致;
2. protocol 列为合法采集协议(对齐内核 schema.VALID_PROTOCOLS);
3. sampleRate 为正整数。
用法:python _sanity_check.py
"""
import csv
import os
import sys
HERE = os.path.dirname(os.path.abspath(__file__))
# 对齐 core/edge-gateway/config/point_dict.example.csv 表头
EXPECTED_COLUMNS = [
"device_id", "point_id", "name", "unit", "dataType",
"sampleRate", "qualityCode", "opcNode", "protocol",
]
# 对齐内核 schema.VALID_PROTOCOLS(缺省点位集全部使用 simulator 演示驱动)
VALID_PROTOCOLS = {
"opcua", "s7", "modbus", "weighing", "energy", "simulator",
}
def main() -> int:
failures: list[str] = []
# 1) 点位字典 CSV
csv_path = os.path.join(HERE, "point_dict.default.csv")
with open(csv_path, "r", encoding="utf-8") as fh:
rows = list(csv.reader(fh))
if not rows:
failures.append("point_dict.default.csv 为空")
else:
header = [c.strip() for c in rows[0]]
if header != EXPECTED_COLUMNS:
failures.append(
f"CSV 表头与内核 schema 不一致:{header} != {EXPECTED_COLUMNS}")
if len(rows) < 2:
failures.append("CSV 缺少数据行")
for i, row in enumerate(rows[1:], 2):
if not row or all(not c for c in row):
failures.append(f"CSV 第 {i} 行为空行")
elif len(row) != len(EXPECTED_COLUMNS):
failures.append(f"CSV 第 {i} 行列数异常:{len(row)}")
else:
# 2) protocol 合法
proto = row[8].strip().lower()
if proto not in VALID_PROTOCOLS:
failures.append(
f"CSV 第 {i} 行非法协议:'{proto}'(合法值见内核 schema.VALID_PROTOCOLS)")
# 3) sampleRate 正整数
rate = row[5].strip()
if not rate.isdigit() or int(rate) <= 0:
failures.append(f"CSV 第 {i} 行 sampleRate 必须为正整数:'{rate}'")
if failures:
print("FAIL")
for f in failures:
print(" -", f)
return 1
print(f"OK: 点位 {len(rows) - 1} 条,表头/协议/采样率校验通过")
return 0
if __name__ == "__main__":
sys.exit(main())
@@ -0,0 +1,17 @@
device_id,point_id,name,unit,dataType,sampleRate,qualityCode,opcNode,protocol
CLF-01,CLF-01.TEMP,炉温,℃,float,1000,true,ns=2;s=CLF.Temp,simulator
CLF-01,CLF-01.PRES,炉压,kPa,float,1000,true,ns=2;s=CLF.Pres,simulator
CLF-01,CLF-01.CL2,氯气流量,m³/h,float,1000,true,ns=2;s=CLF.Cl2,simulator
CLF-01,CLF-01.CO,CO含量,%,float,1000,true,ns=2;s=CLF.CO,simulator
CLF-01,CLF-01.CO2,CO₂含量,%,float,1000,true,ns=2;s=CLF.CO2,simulator
CLF-01,CLF-01.BED,炉层状态,%,float,1000,true,ns=2;s=CLF.Bed,simulator
CLF-01,CLF-01.FEED,进料量,t/h,float,1000,true,ns=2;s=CLF.Feed,simulator
RF-01,RF-01.REDT,还原温度,℃,float,1000,true,ns=2;s=RF.RedT,simulator
RF-01,RF-01.VAC,还原真空度,kPa,float,1000,true,ns=2;s=RF.Vac,simulator
RF-01,RF-01.PURITY,TiCl₄纯度,%,float,60000,true,ns=2;s=RF.Purity,simulator
RF-01,RF-01.IMP,杂质含量,%,float,60000,true,ns=2;s=RF.Imp,simulator
E-01,E-01.PWR,车间电功率,kW,float,1000,true,holding:40010,simulator
E-01,E-01.KWH,车间累计电耗,kWh,float,1000,true,holding:40012,simulator
ST-01,ST-01.STEAM,蒸汽流量,t/h,float,1000,true,ns=2;s=ST.Steam,simulator
CW-01,CW-01.FLOW,循环水流量,m³/h,float,1000,true,ns=2;s=CW.Flow,simulator
CW-01,CW-01.TEMP,循环水温度,℃,float,1000,true,ns=2;s=CW.Temp,simulator
1 device_id point_id name unit dataType sampleRate qualityCode opcNode protocol
2 CLF-01 CLF-01.TEMP 炉温 ℃ float 1000 true ns=2;s=CLF.Temp simulator
3 CLF-01 CLF-01.PRES 炉压 kPa float 1000 true ns=2;s=CLF.Pres simulator
4 CLF-01 CLF-01.CL2 氯气流量 m³/h float 1000 true ns=2;s=CLF.Cl2 simulator
5 CLF-01 CLF-01.CO CO含量 % float 1000 true ns=2;s=CLF.CO simulator
6 CLF-01 CLF-01.CO2 CO₂含量 % float 1000 true ns=2;s=CLF.CO2 simulator
7 CLF-01 CLF-01.BED 炉层状态 % float 1000 true ns=2;s=CLF.Bed simulator
8 CLF-01 CLF-01.FEED 进料量 t/h float 1000 true ns=2;s=CLF.Feed simulator
9 RF-01 RF-01.REDT 还原温度 ℃ float 1000 true ns=2;s=RF.RedT simulator
10 RF-01 RF-01.VAC 还原真空度 kPa float 1000 true ns=2;s=RF.Vac simulator
11 RF-01 RF-01.PURITY TiCl₄纯度 % float 60000 true ns=2;s=RF.Purity simulator
12 RF-01 RF-01.IMP 杂质含量 % float 60000 true ns=2;s=RF.Imp simulator
13 E-01 E-01.PWR 车间电功率 kW float 1000 true holding:40010 simulator
14 E-01 E-01.KWH 车间累计电耗 kWh float 1000 true holding:40012 simulator
15 ST-01 ST-01.STEAM 蒸汽流量 t/h float 1000 true ns=2;s=ST.Steam simulator
16 CW-01 CW-01.FLOW 循环水流量 m³/h float 1000 true ns=2;s=CW.Flow simulator
17 CW-01 CW-01.TEMP 循环水温度 ℃ float 1000 true ns=2;s=CW.Temp simulator