- 点位字典 CSV schema/加载/自动校验(缺失字段/量纲/重复点号,PRD 5.1) - 协议可插拔只读驱动:OPC UA(S7-1200 适配)/S7/Modbus/称重/能源/模拟 - 周期采集引擎:只读+背压保护+健康度指标(丢失率/P99/可用性) - Kafka 流式上行 + 本地 spool 断点续传(丢失率≤0.02% 保障) - 模板配置外置(gateway.yaml + 点位字典 CSV),换行业零改码 - 18 个单元测试全绿;端到端运行 SLA 达标
60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""采集驱动抽象基类 —— 模板化封装的协议插槽。
|
|
|
|
安全约束(PRD 9 章:边缘网关严格只读、零控制指令下发):
|
|
- 驱动仅暴露只读接口 `read_points()`,没有任何写/控制方法;
|
|
- 引擎只依赖本抽象,具体协议由子类实现,新增协议不改引擎代码。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import Dict, List, Optional, Union
|
|
|
|
from point_dict.loader import Point
|
|
|
|
SampleValue = Union[float, int, bool, None]
|
|
|
|
|
|
class Driver(ABC):
|
|
"""只读采集驱动基类。"""
|
|
|
|
protocol: str = "base" # 协议名:opcua / s7 / modbus / weighing / energy / simulator
|
|
|
|
def __init__(self, config: Optional[dict] = None):
|
|
self.config = config or {}
|
|
|
|
@abstractmethod
|
|
def connect(self) -> None:
|
|
"""建立连接(幂等)。失败应抛出 ConnectionError 供引擎重试。"""
|
|
|
|
@abstractmethod
|
|
def read_points(self, points: List[Point]) -> Dict[str, SampleValue]:
|
|
"""批量读取测点值(只读)。
|
|
|
|
Args:
|
|
points: 本驱动负责的测点列表。
|
|
|
|
Returns:
|
|
{point_id: value};读失败的点可返回 None 或省略,
|
|
由引擎按“未读到”计入丢失率。
|
|
"""
|
|
|
|
@abstractmethod
|
|
def close(self) -> None:
|
|
"""关闭连接,释放资源。"""
|
|
|
|
# ------------------------------------------------------------------
|
|
# 模板化辅助
|
|
# ------------------------------------------------------------------
|
|
@classmethod
|
|
def from_template(cls, protocol: str, config: Optional[dict] = None) -> "Driver":
|
|
"""按模板配置实例化驱动(协议 → 实现类注册表)。"""
|
|
from . import _DRIVER_REGISTRY
|
|
|
|
if protocol not in _DRIVER_REGISTRY:
|
|
raise KeyError(
|
|
f"未注册的采集协议: '{protocol}',已注册: {sorted(_DRIVER_REGISTRY)}。"
|
|
f"如需支持新协议,实现 Driver 子类并注册。"
|
|
)
|
|
return _DRIVER_REGISTRY[protocol](config)
|