feat: 完成 issue #20 [M1] 搭建缺省通用点位集(演示用,不依赖客户数据)
This commit is contained in:
@@ -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
|
||||
|
Reference in New Issue
Block a user