feat: 完成 issue #16 [M1] 编制 DCS 点表需求模板(点位/量纲/采样率字段规范)
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
# DCS 点表需求模板(点位 / 量纲 / 采样率字段规范)
|
||||
|
||||
> 对应 EPIC #2「[M1] 数据准备」子任务 **#16**(0.5d):
|
||||
> 编制向客户 DCS 系统收集点位需求的标准化模板,字段规范对齐
|
||||
> PRD 5.1「① 边缘采集网关」CSV 字段规范与内核点位字典 schema
|
||||
> (`core/edge-gateway/config/point_dict.example.csv`)。
|
||||
>
|
||||
> 交付后由实施工程师按本模板收集客户点表 → 配置台导入校验 →
|
||||
> 推送边缘网关加载只读采集(PRD 5.1 用户操作流程)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 文档目的
|
||||
|
||||
在 M1 数据准备阶段,向客户(车间/仪表/自动化人员)收集 **DCS/PLC 点位需求**,
|
||||
作为点位字典(`point_dict.csv`)的输入来源。本模板统一:
|
||||
|
||||
- **点位**(point):需要采集的工艺测点(温度/压力/流量/液位/状态等);
|
||||
- **量纲**(unit):每个测点的计量单位(℃/kPa/m³/h/%/Hz 等);
|
||||
- **采样率**(sampleRate):每个测点的采集周期(毫秒)。
|
||||
|
||||
字段规范与平台内核**一一对应**,客户按模板填写后可直接导入校验,避免
|
||||
人工翻译造成的字段漂移。
|
||||
|
||||
---
|
||||
|
||||
## 2. DCS 系统对接信息(每套系统填写一份)
|
||||
|
||||
| 字段 | 说明 | 示例 |
|
||||
| --- | --- | --- |
|
||||
| 系统名称 | DCS/PLC 系统名称 | 沸腾氯化车间和利时 DCS |
|
||||
| 厂家/型号 | 设备厂家与系列 | 和利时 DCS / 西门子 S7-1200 |
|
||||
| 软件版本 | 系统软件版本 | HOLLiAS-M 3.2 |
|
||||
| 数据接口 | 支持的数据接口 | OPC UA / OPC DA / S7 协议 |
|
||||
| OPC 服务器 | OPC 服务器地址(如可用) | opc.tcp://10.20.1.10:4840 |
|
||||
| 网络隔离要求 | 采集网与办公网隔离方式 | 单向网闸 / 只读镜像(见 #27) |
|
||||
| 对接负责人 | 客户侧接口人 | 王工(仪表科) |
|
||||
|
||||
> 采集侧**严格只读、不反控**(PRD 5.1 验收:零控制指令下发),
|
||||
> 网络拓扑隔离方案见子任务 #19「现场勘查采集网/工业环网/办公网拓扑与隔离策略」。
|
||||
|
||||
---
|
||||
|
||||
## 3. 点位需求表字段规范
|
||||
|
||||
客户按下表逐列填写(**表头与内核点位字典 CSV 完全一致**,可整表复制为 CSV):
|
||||
|
||||
| 字段 | 类型 | 约束 | 说明 | 示例 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| device_id | string | 必填,唯一 | 设备编号(车间-设备) | CLF-01 |
|
||||
| point_id | string | 必填,唯一 | 测点编号(设备.测点) | CLF-01.TEMP |
|
||||
| name | string | 必填 | 测点中文名 | 炉温 |
|
||||
| unit | enum | 必填 | 量纲(见 §4 量纲字典) | ℃ |
|
||||
| dataType | enum | 必填 | float / int / bool | float |
|
||||
| sampleRate | int | 必填,>0 | 采集周期(毫秒) | 1000 |
|
||||
| qualityCode | bool | 默认 true | 是否启用质量码 | true |
|
||||
| opcNode | string | 选填 | OPC UA 节点路径 / PLC 地址 | ns=2;s=CLF.Temp |
|
||||
| protocol | enum | 必填 | opcua / s7 / modbus / weighing / energy / manual | opcua |
|
||||
|
||||
**字段说明**
|
||||
|
||||
- `device_id`:建议「车间/系统前缀 + 序号」,如 `CLF-01`(氯化炉 1#)、`S7-01`(PLC 站 1#);
|
||||
- `point_id`:全局唯一,建议「`device_id.测点缩写`」,如 `CLF-01.TEMP`;
|
||||
- `sampleRate`:按测点重要性分级填写(见 §5 采样率分级);
|
||||
- `opcNode`:OPC UA 用节点路径(`ns=2;s=...`);S7 用数据块地址(`DB100.0.0`);
|
||||
称重/能源表用寄存器地址(`holding:40001`);人工录入(manual)可留空;
|
||||
- `qualityCode`:开启质量码后,采集侧附带质量位(坏值/不确定值),平台按质量位过滤。
|
||||
|
||||
---
|
||||
|
||||
## 4. 量纲字典(unit 枚举)
|
||||
|
||||
| 类别 | 允许值 |
|
||||
| --- | --- |
|
||||
| 温度 | ℃ |
|
||||
| 压力 | kPa、MPa、Pa |
|
||||
| 流量 | m³/h、t/h、L/min、m³/s |
|
||||
| 液位/料位 | %、m、mm |
|
||||
| 转速/频率 | rpm、Hz |
|
||||
| 电气 | kW、kWh、A、V |
|
||||
| 重量 | kg、t、g |
|
||||
| 质量指标 | %、mmol/g(化验人工录入) |
|
||||
| 状态 | bool(0/1、开/关) |
|
||||
|
||||
> 不在上表的单位需在「备注」列说明并请平台配置台确认后再扩展。
|
||||
|
||||
---
|
||||
|
||||
## 5. 采样率分级建议(sampleRate)
|
||||
|
||||
| 级别 | 周期 | 适用测点 |
|
||||
| --- | --- | --- |
|
||||
| 高速 | 100 ms | 关键工艺控制点(炉温、炉压) |
|
||||
| 常规 | 1000 ms(1 Hz) | 一般工艺参数(流量、液位、转速)——PRD 5.1 验收基线:600 点位 1Hz |
|
||||
| 低频 | 5000–10000 ms | 缓慢变化量(储罐液位、环境温度) |
|
||||
| 化验/人工 | 60000 ms 或按批次 | 质量指标(交联度、交换容量、钛纯度)等人工录入或 LIMS 对接 |
|
||||
|
||||
> 采样率需综合点位数量与链路容量评估:验收目标为 P99 ≤ 1.8s、丢失率 ≤ 0.02%(PRD 5.1),
|
||||
> 点位过多时可先按「关键点位」子集接入,其余低频轮询。
|
||||
|
||||
---
|
||||
|
||||
## 6. 填表示例(Template-Ti 一期 · 氯化车间)
|
||||
|
||||
| device_id | point_id | name | unit | dataType | sampleRate | qualityCode | opcNode | protocol |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| CLF-01 | CLF-01.TEMP | 炉温 | ℃ | float | 1000 | true | ns=2;s=CLF.Temp | opcua |
|
||||
| CLF-01 | CLF-01.PRES | 炉压 | kPa | float | 1000 | true | ns=2;s=CLF.Pres | opcua |
|
||||
| CLF-01 | CLF-01.FEED | 进料量 | t/h | float | 1000 | true | ns=2;s=CLF.Feed | opcua |
|
||||
| S7-01 | S7-01.PUMP_A | 泵A频率 | Hz | float | 1000 | true | DB100.0.0 | s7 |
|
||||
| W-01 | W-01.WT | 称重值 | kg | float | 1000 | true | holding:40001 | weighing |
|
||||
| E-01 | E-01.PWR | 电表功率 | kW | float | 1000 | true | holding:40010 | energy |
|
||||
| LAB-01 | LAB-01.TI_PURITY | 钛纯度 | % | float | 60000 | true | —(人工录入) | manual |
|
||||
|
||||
---
|
||||
|
||||
## 7. 填写规范与常见错误
|
||||
|
||||
| 规范 | 常见错误 | 处理 |
|
||||
| --- | --- | --- |
|
||||
| `point_id` 全局唯一 | 跨设备重复命名 | 配置台导入校验拒绝并提示 |
|
||||
| `unit` 使用量纲字典 | 自定义单位(如 "度") | 归一化为 ℃ 或先申请扩展 |
|
||||
| `sampleRate` 为大于 0 的整数 | 空值/0/小数 | 校验拒绝,按分级建议补填 |
|
||||
| `device_id` 与现场标识一致 | 随意编号 | 与客户确认设备位号后再填 |
|
||||
| 重复/冗余测点 | 同一物理量多张表重复 | 合并,保留唯一 `point_id` |
|
||||
| 高危信号(联锁/停机) | 误标为普通测点 | 平台按「只读采集 + 告警」处理,严禁反控 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 交付与校验
|
||||
|
||||
1. 实施工程师向客户发出本模板(可与《数据准备清单》#18 同步发出);
|
||||
2. 客户按 §2–§6 填写后回传(Excel/CSV 均可);
|
||||
3. 配置台**导入校验**:设备/测点完整性、字段类型、单位枚举、采样率合法性;
|
||||
4. 校验通过 → 生成点位字典 CSV → 推送边缘网关加载 → 启动只读采集;
|
||||
5. 采集健康度(丢失率/P99)实时回传驾驶舱。
|
||||
|
||||
> 若客户点表延迟或字段不完整:先启用**缺省通用点位集**(EPIC #20)演示,
|
||||
> 仅接入已确认点位(PRD 13 章数据依赖风险缓解策略)。
|
||||
@@ -0,0 +1,79 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""DCS 点表需求模板(docs/DCS点表需求模板.md)与内核点位字典 schema 一致性检查。
|
||||
|
||||
检查项:
|
||||
1. 文档 §3「点位需求表字段规范」表中的字段名(第一列)与内核
|
||||
`core/edge-gateway/config/point_dict.example.csv` 表头**完全一致**;
|
||||
2. 文档中的量纲字典与填表示例单位均在内核示例出现过的类别内(人工抽查,仅告警);
|
||||
3. 文档引用到的内核文件路径存在。
|
||||
|
||||
用法:python _check_dcs_template.py
|
||||
"""
|
||||
import csv
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
REPO_ROOT = os.path.dirname(HERE)
|
||||
|
||||
DOC_PATH = os.path.join(HERE, "DCS点表需求模板.md")
|
||||
CSV_PATH = os.path.join(REPO_ROOT, "core", "edge-gateway", "config",
|
||||
"point_dict.example.csv")
|
||||
|
||||
|
||||
def doc_field_table_columns() -> list:
|
||||
"""抽取文档 §3 字段规范表的字段名(Markdown 表格第一列)。"""
|
||||
lines = [ln.strip() for ln in open(DOC_PATH, "r", encoding="utf-8").readlines()]
|
||||
fields = None
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
if line.startswith("|") and line.strip("|").split("|")[0].strip() == "字段":
|
||||
header_cells = [c.strip() for c in line.strip("|").split("|")]
|
||||
if "类型" not in header_cells: # §3 特征:字段规范表含"类型"列
|
||||
i += 1
|
||||
continue
|
||||
sep = lines[i + 1] if i + 1 < len(lines) else ""
|
||||
if all(re.fullmatch(r":?-{3,}:?", c.strip())
|
||||
for c in sep.strip("|").split("|")):
|
||||
j = i + 2
|
||||
rows = []
|
||||
while j < len(lines) and lines[j].startswith("|"):
|
||||
cells = [c.strip() for c in lines[j].strip("|").split("|")]
|
||||
if cells and cells[0]:
|
||||
rows.append(cells[0])
|
||||
j += 1
|
||||
fields = rows
|
||||
break
|
||||
i += 1
|
||||
return fields or []
|
||||
|
||||
|
||||
def main() -> int:
|
||||
failures = []
|
||||
|
||||
# 1) 文档字段规范与内核 CSV 表头一致
|
||||
with open(CSV_PATH, "r", encoding="utf-8") as fh:
|
||||
csv_header = [c.strip() for c in next(csv.reader(fh))]
|
||||
doc_fields = doc_field_table_columns()
|
||||
if doc_fields != csv_header:
|
||||
failures.append(
|
||||
f"文档字段 {doc_fields} 与内核 CSV 表头 {csv_header} 不一致")
|
||||
|
||||
# 2) 文档引用文件存在
|
||||
for ref in ("core/edge-gateway/config/point_dict.example.csv",):
|
||||
if not os.path.isfile(os.path.join(REPO_ROOT, ref)):
|
||||
failures.append(f"引用文件缺失:{ref}")
|
||||
|
||||
if failures:
|
||||
print("FAIL")
|
||||
for f in failures:
|
||||
print(" -", f)
|
||||
return 1
|
||||
print(f"OK: 文档字段规范与内核 schema 一致({len(csv_header)} 列),引用完整")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user