快速上手
本章带你用一份最小配置跑通 CoreC 的完整数据链路:从 Modbus 设备采集一个温度点位,经规则路由,推送到 MQTT Broker。
场景假设
Modbus TCP 设备 (192.168.1.100:502) ──采集──▶ CoreC ──推送──▶ MQTT Broker (公共测试服务器)我们将采集一个保持寄存器中的 float32 温度值,每秒一次,推送到 EMQX 公共 Broker 的 corec/demo/temperature 主题。
第一步:编写最小配置
在工作目录下创建 config.yaml:
# config.yaml —— CoreC 最小可用配置
global:
log-level: info
api:
listen: 0.0.0.0:9090
secret: "corec-secret-token"
# 南向:一台 Modbus TCP 设备
drivers:
- name: demo-plc
type: modbus-tcp
settings:
host: 192.168.1.100
port: 502
slave-id: 1
timeout: 3s
tags:
- name: temperature
address: "40001" # 保持寄存器 0
type: float32
group: sensors
interval: 1s
# 北向:MQTT 公共测试 Broker
transports:
- name: cloud-mqtt
type: mqtt
settings:
broker: tcp://broker.emqx.io:1883
client-id: corec-quickstart-01
qos: 1
topic-template: "corec/demo/{{.Tag}}"
# 规则:所有数据转发到 MQTT
rules:
- name: forward-all
match: "ALL"
action: forward
target: cloud-mqtt
priority: 999配置结构解读
| 段落 | 作用 | 必填 |
|---|---|---|
global | 日志级别、API 监听地址与鉴权密钥 | 否 |
drivers | 南向设备连接与点位定义 | 否 |
transports | 北向数据目的地 | 否 |
rules | 数据路由规则,决定哪些数据发往哪里 | 否 |
空配置与规则缺省行为
空配置(无驱动、无传输)是一个合法的启动状态:CoreC 以空闲模式运行并输出 WARN 提示,操作者随后通过 Dashboard 或 PUT /configs 补全配置。注意两点:配置了驱动就必须至少配置一个点位(校验规则);若没有匹配的规则,数据点将不会被推送到任何传输。因此实践中始终建议配置一条 match: "ALL" 的兜底规则。
第二步:启动 CoreC
./corec -c config.yaml启动成功后会看到如下日志:
INFO registered drivers types=[modbus-tcp modbus-rtu modbus-rtuovertcp modbus-udp modbus-rtuoverudp modbus-tls s7 opcua]
INFO registered transports types=[mqtt http notify]
INFO CoreC engine starting drivers=1 transports=1 rules=1
INFO mqtt transport initialized name=cloud-mqtt broker=tcp://broker.emqx.io:1883 client-id=corec-quickstart-01 tls=false
INFO mqtt connected name=cloud-mqtt broker=tcp://broker.emqx.io:1883
INFO transport added name=cloud-mqtt type=mqtt
INFO modbus-tcp driver initialized name=demo-plc host=192.168.1.100 port=502 slave-id=1 tags=1
INFO modbus connected driver=modbus-tcp name=demo-plc url=tcp://192.168.1.100:502
INFO driver started type=modbus-tcp name=demo-plc
INFO task added id=demo-plc_1s driver=demo-plc interval=1s tags=1
INFO driver added name=demo-plc type=modbus-tcp tags=1
INFO CoreC engine started successfully
INFO CoreC is running config=config.yaml引擎先初始化传输(数据消费者),再初始化驱动(数据生产者),因此传输日志先于驱动日志出现。
types=列表来自注册表的 map 遍历,每次启动顺序不固定。
关键日志含义:
registered drivers/transports—— 所有插件工厂已通过init()注册完成task added—— 调度器已为demo-plc驱动的 1s 周期点位创建采集任务mqtt connected—— 北向传输已成功连接 Broker
第三步:验证数据流
方式 A:订阅 MQTT 主题
使用任意 MQTT 客户端(如 mosquitto_sub)订阅目标主题:
mosquitto_sub -h broker.emqx.io -p 1883 -t "corec/demo/#" -v每秒应收到一条 JSON 消息:
corec/demo/temperature {"driver":"demo-plc","device":"","group":"sensors","tag":"temperature","value":42.5,"type":"float32","quality":0,"timestamp":"2024-01-15T10:30:01.234Z"}这就是 CoreC 的标准数据点 DataPoint 结构——从设备读出的原始 TagValue 经引擎富化后,补充了 driver、group 等路由元信息。
type字段序列化为可读字符串(如"float32"),与 YAML 配置中的type: float32一致。 写命令(/writeAPI、MQTT command topic)的type字段同时接受字符串"float32"和历史整数形式9。
方式 B:验证 API
CoreC 启动后会在 :9090 暴露控制面 API,使用 Bearer Token 鉴权:
# 查看引擎整体状态
curl -s -H "Authorization: Bearer corec-secret-token" http://localhost:9090/stats | jq预期响应:
{
"status": "running",
"uptime": 15000000000,
"drivers": 1,
"transports": 1,
"rules": 1,
"total_read": 15,
"total_publish": 15,
"total_errors": 0,
"total_dropped": 0,
"points_per_sec": 1.0,
"driver_stats": {
"demo-plc": {
"name": "demo-plc",
"type": "modbus-tcp",
"state": 2,
"last_read": "2024-01-15T10:30:15Z",
"last_error": "",
"tag_count": 1,
"read_count": 15,
"error_count": 0,
"reconnect_count": 0
}
},
"transport_stats": {
"cloud-mqtt": {
"name": "cloud-mqtt",
"type": "mqtt",
"state": 2,
"published": 15,
"failed": 0,
"received": 0,
"last_publish": "2024-01-15T10:30:15Z",
"queue_size": 0,
"dropped_commands": 0
}
}
}查看驱动状态:
curl -s -H "Authorization: Bearer corec-secret-token" \
http://localhost:9090/drivers/demo-plc | jq{
"name": "demo-plc",
"type": "modbus-tcp",
"state": 2,
"last_read": "2024-01-15T10:30:15Z",
"last_error": "",
"tag_count": 1,
"read_count": 15,
"error_count": 0,
"reconnect_count": 0
}方式 C:WebSocket 实时数据流
使用 websocat 或浏览器连接 WebSocket 端点,实时接收数据点:
websocat "ws://localhost:9090/tags/stream?token=corec-secret-token"鉴权方式
API 支持两种鉴权写法,各自适用范围不同:
- Header:
Authorization: Bearer <secret>—— 所有常规 HTTP 请求必须使用这种方式 - Query:
?token=<secret>—— 仅对 WebSocket 升级请求开放(浏览器 WebSocket API 无法自定义 Header);普通 HTTP 请求带 query token 会被拒绝
第四步:你的第一个数据点
查询该驱动点位的最新缓存值(缓存由调度器每次采集后刷新,无需等待下一次采集周期即可读取当前缓存):
curl -s -H "Authorization: Bearer corec-secret-token" \
"http://localhost:9090/drivers/demo-plc/tags" | jq返回的是 LatestCache 中缓存的该驱动所有点位最新值:
{
"tags": {
"temperature": {
"driver": "demo-plc",
"tag": "temperature",
"value": 42.5,
"type": "float32",
"quality": 0,
"timestamp": "2024-01-15T10:30:15.234Z",
"device": "",
"group": "sensors"
}
}
}按驱动查询点位
GET /drivers/{name}/tags 返回指定驱动下所有点位的最新缓存值。GET /tags(不带路径参数)返回全部驱动全部点位的最新值,并支持三个可选查询参数做服务端过滤:?driver=<name>(按驱动筛选)、?tag=<子串>(按测点名子串匹配)、?prefix=<前缀>(按测点名前缀匹配)。
反向下发:写入设备
如果该点位是可写的保持寄存器,可以通过 API 下发控制值:
curl -s -X POST -H "Authorization: Bearer corec-secret-token" \
-H "Content-Type: application/json" \
-d '{"driver":"demo-plc","tag":"temperature","value":50.0,"type":"float32"}' \
http://localhost:9090/write | jq{ "success": true }写入语义
POST /write 会直接调用驱动的 Write 方法将值写入设备寄存器,绕过规则引擎。这是即时控制指令,不会进入数据总线。写入后的新值会在下一次调度读取时回流到缓存与北向传输。
type 字段接受可读字符串("float32"、"int16"、"bool" …,与 YAML 配置一致)或历史整数形式(9 = float32)。推荐使用字符串形式。
使用模拟设备验证
如果没有真实 Modbus 设备,可以使用仓库自带的模拟 PLC demo/chained/mock-plc:它内置一个在 25°C 附近波动的 float32 "temperature"(保持寄存器 0,即 CoreC 地址 "40001")、一个每秒自增的 uint16 "counter"("40003"),并支持写入——与本节的示例点位完全对应。
# 方式一:用 Docker 构建 & 运行(监听 :502,slave-id 1)
docker build -t mock-plc demo/chained/mock-plc
docker run -p 502:502 mock-plc
# 方式二:直接用 Go 运行
go run ./demo/chained/mock-plc然后将配置中的 host 改为 127.0.0.1,即可在本地跑通完整链路。
常见问题
启动时输出 "no data source configured" 警告
配置中没有数据源。这不是启动错误:空管道是合法的空闲启动状态,CoreC 照常运行并输出 WARN("running in idle mode"),等待通过 Dashboard 或 PUT /configs 补全配置。要消除该警告,至少配置一个驱动(drivers),或——纯转发(链式核心)节点——至少有一个传输配置了入站:MQTT 的 data-topic 或 HTTP 的 webhook-addr,或者启用了拓扑自动发现(node.id + node.subscribe 非空)。
启动报错 "driver xxx: unknown type ..."
type 字段拼写错误,或对应的驱动子包未被导入。配置校验会直接拒绝并列出全部已注册类型:
config validation failed: driver demo-plc: unknown type "modbus-tcp1" (registered: modbus-tcp, modbus-rtu, modbus-rtuovertcp, modbus-udp, modbus-rtuoverudp, modbus-tls, s7, opcua)内置支持的类型:modbus-tcp、modbus-rtu、modbus-rtuovertcp、modbus-udp、modbus-rtuoverudp、modbus-tls、s7、opcua。
设备连接失败但程序未退出
这是预期行为。CoreC 采用后台重连策略——初始连接失败不会导致启动失败,而是进入 connecting 状态并按指数退避重试。设备恢复后会自动重连并恢复采集。通过 /drivers/{name} API 可查看 state 字段确认连接状态。
MQTT 收不到消息
依次排查:
- Broker 地址是否可达:
mosquitto_sub -h broker.emqx.io -p 1883 -t test能否连通 - 规则是否匹配:检查
/stats中total_publish是否在增长 - 主题模板是否正确:
topic-template使用 Go text/template 语法,变量为{{.Driver}}、{{.Group}}、{{.Tag}}等