Skip to content

核心输入输出 ​

核心是一个双向数据管道 + 控制面,有四条独立的数据流:上行采集、链式入站、下行控制、控制面(见架构总览)。

输入(5 类) ​

1. 配置文件 ​

yaml
# config.yaml — 启动输入
global:     # 日志、API、缓冲
drivers:    # 南向驱动定义
transports: # 北向传输定义
rules:      # 规则链
入口时机路径
config.Load(path)进程启动cmd/corec/main.go
PUT /configsAPI 热重载hub/route/configs.go
PATCH /configs运行时调参hub/route/configs.go

2. 南向设备数据 ​

轮询模式 — 调度器主动拉取:

go
Read(ctx context.Context, tags []string) ([]TagValue, error)
驱动物理输入
Modbus TCPPLC 保持寄存器、线圈、离散输入
Siemens S7DB 块、Merker、输入(I)、输出(Q)
OPC UANodeID 节点变量

订阅模式 — 设备主动推送(仅 OPC UA):

go
Subscribe(ctx context.Context, tags []string) (<-chan DataPoint, error)

输入数据类型:

go
type TagValue struct {
    Tag       string    // "temperature"
    Value     any       // 42.5
    Type      DataType  // TypeFloat32
    Quality   Quality   // QualityGood
    Timestamp time.Time // 采集时间戳
    Error     error     // 读取错误
}

3. 北向控制指令 ​

云端通过 MQTT command topic 下发写指令:

go
type WriteCommand struct {
    Driver string   // "plc-modbus"
    Device string   // "192.168.1.10"
    Tag    string   // "temperature"
    Value  any      // 50
    Type   DataType // TypeFloat32
    // 以下字段由信任边界(route handler / 命令监听器)盖章,
    // 不信任客户端载荷;均为 omitempty,JSON 中缺省时省略。
    Source string // 来源:"api"(HTTP 直写)或 "command"(传输反向命令)
    Remote string // API 来源写者的网络地址(r.RemoteAddr)
    Raw    bool   // true 时跳过 scale/offset 反变换,按原始设备值写入
}

流向:MQTT 订阅 command-topic → Transport.OnCommand() → startCommandListener → Driver.Write() → PLC

注:每个传输在 AddTransport 注册时启动各自的 startCommandListener goroutine 完成命令分发并参与优雅停机。

4. 控制面 API 请求 ​

请求输入
POST /write直接写设备
POST /write/batch批量写设备(逐条执行,逐条返回结果)
PUT /configs热重载配置
PATCH /configs运行时调参
PATCH /rules/disable禁用规则
WebSocket订阅实时流

完整端点清单(驱动/传输/规则/配置的增删改查、告警确认等)见 API 总览。

5. 链式入站数据(Transport.OnData) ​

传输可通过 Transport.OnData() 接收上游数据点(如另一个 CoreC 实例经 MQTT data-topic 或 HTTP webhook 推送),由 startDataListener goroutine 送入 DataBus 复用处理管道。入站载荷经 Parser 解析为 DataPoint:

go
// core/transport.go — Transport 接口包含 OnData() 入站通道
OnData() <-chan DataPoint

Parser 支持三种模式(transport/parser):

模式说明适用场景
default直接 json.Unmarshal 为 DataPointCoreC→CoreC 链式级联(双方共享同一 JSON schema)
jsonpath通过可配置模板把任意 JSON 字段映射到 DataPoint接入第三方 JSON 数据源
raw把整个载荷当作标量值简单数值上报

流向:上游 → MQTT data-topic / HTTP webhook-addr → Parser.Parse → Transport.OnData() → startDataListener → DataBus.Push → ProcessingLoop

输出(5 类) ​

1. 北向数据发布 ​

主输出流,采集数据经规则匹配后发布到云端:

go
type DataPoint struct {
    Driver    string            // "plc-modbus"
    Device    string            // 驱动采集路径留空(DriverConfig/TagConfig 无 Device 字段);链式入站可由 parser 配置填充
    Group     string            // "sensors"
    Tag       string            // "temperature"
    Value     any               // 42.5
    Type      DataType          // TypeFloat32
    Quality   Quality           // QualityGood
    Timestamp time.Time         // 采集时间
    Metadata  map[string]string // 扩展元数据(发布时注入命中的规则名 "rule")
    IsStale   bool              // 仅由 API 层在缓存值超过 stale 阈值时置位;正常管道处理不设置,不出现在发布载荷
}
传输输出形式目标
MQTTJSON → topic 按 topic-template 渲染(默认模板 corec/&lbrace;&lbrace;.Driver&rbrace;&rbrace;/&lbrace;&lbrace;.Tag&rbrace;&rbrace;;示例 factory/plc-modbus/sensors/temperature 为含 Group 的自定义模板)EMQX / Mosquitto
HTTPJSON batch → POSTMES / Data Lake
Notify模板渲染的消息 → Slack / Teams / Email / Webhook告警通道

规则动作决定路由:

Action行为
forward发到单个 target
mirror发到多个 targets
drop丢弃
alert发 + 触发告警
transform经表达式变换值(可重命名 tag)后发到 target

2. 设备写入结果 ​

go
type WriteResult struct {
    Success bool
    Error   string
}

3. 实时流推送 ​

端点输出
/tags/streamDataPoint JSON 流(可用 ?driver= 过滤)
/logslog.Event JSON 流
/traffic默认按 ?interval= 周期推送速率 {"read_rate":N,"publish_rate":N,"dropped_rate":N};?mode=totals 推送累计值 {"read":N,"publish":N,"dropped":N}
/memory{"alloc":N,"total_alloc":N,"sys":N,"num_gc":N,"goroutines":N}
/alerts/stream告警生命周期事件 JSON 流(激活/清除/确认)

4. API 响应 ​

端点输出
GET /drivers驱动列表 + 状态
GET /tags最新缓存值
GET /statsEngineStats(含 total_dropped、窗口化 points_per_sec)
GET /rules规则列表 + 命中统计
GET /alerts活跃告警 + 有界历史
GET /write/failed死信队列(引擎侧 + 传输入站侧)
GET /write/history写入审计历史(最近 1000 次成败记录)

5. 告警 + 日志 ​

规则匹配 alert 动作(或 on-bad-quality: alert 策略)时触发告警:先记入引擎一等告警注册表(活跃态 + 有界历史,GET /alerts 可查),再逐个调用 OnAlert 注册的 handler。所有 slog 调用经 Observable 双路输出(控制台 + /logs 事件流)。

数据类型流转 ​

输入                    核心处理                    输出
─────────────────────────────────────────────────────────────
TagValue ─Read()──►  onDriverData  ──►  DataPoint  ──Publish()──► MQTT/HTTP
  (设备原始值)         │                 (enriched)      │
                       │                 ├──► cache ──► API JSON
                       │                 ├──► alert ──► slog.Warn
                       │                 └──► (drop)
                       │
DataPoint ─OnData()──► startDataListener ─► DataBus.Push ─► ProcessingLoop
  (链式入站)            (复用同一处理管道)

WriteCommand ─MQTT──►  startCommandListener  ──►  Driver.Write()  ──► PLC
  (云端指令)                                    │
                                                └──► WriteResult ──► API JSON

核心转换:TagValue(输入)→ DataPoint(输出)发生在 onDriverData(),加上 Driver、Group 等路由元数据,使规则引擎能按字段匹配路由。

Released under the MIT License.