OpenClaw工业设备接入协议栈:老旧PLC零代码上云实战指南

OpenClaw工业设备接入协议栈:老旧PLC零代码上云实战指南

1. 项目概述:OpenClaw 是什么,它解决的到底是什么问题?

OpenClaw 不是一个开源框架,也不是某个大厂推出的标准化中间件,而是一套由国内某垂直领域(工业设备远程诊断与预测性维护)头部企业内部孵化、后经社区反馈逐步开放出来的轻量级设备接入协议栈与配套工具集。它的核心定位非常清晰:让老旧PLC、嵌入式采集器、边缘网关等不具备现代云原生通信能力的工业现场设备,能以极低侵入性、零代码改造的方式,安全、稳定、可追溯地接入现代云平台。我第一次接触它是在2022年帮一家汽车零部件厂做产线数据上云改造时,他们车间里还有十几台2010年产的西门子S7-200 PLC,连以太网口都没有,只留着一个RS485串口。当时主流方案要么是换整套硬件(预算超支300%),要么是写定制驱动(开发周期6周起)。OpenClaw 的“协议桥接器”模式直接把这个问题压缩到3天——用一台百元级树莓派+USB转485模块,跑起 OpenClaw Agent,就完成了从Modbus RTU到HTTPS JSON API的全链路转换。它不替代MQTT或OPC UA,而是做它们的“翻译官”和“守门人”。关键词“OpenClaw 配置流程”“官方API”“第三方聚合平台接入”,其实指向三个递进层次:第一层是让设备“能说话”(配置Agent),第二层是让平台“听懂话”(调用官方API管理设备状态与指令),第三层是让生态“一起说话”(对接像ThingsBoard、EMQX、甚至自研IoT中台这类聚合平台)。这三步走下来,一个传统工厂的OT数据孤岛才算真正被打通。它适合谁?不是给纯互联网开发者写的,而是给懂一点Python脚本、能看懂设备手册、会配路由器但未必会写内核驱动的现场工程师、自动化集成商、中小制造企业的IT运维人员。你不需要成为协议专家,但得知道你的设备用的是Modbus还是CANopen,波特率多少,寄存器地址在哪——OpenClaw 把这些“知道”转化成几行YAML配置,而不是几百行C代码。

2. OpenClaw 整体架构与方案选型逻辑:为什么是它,而不是其他方案?

2.1 架构本质:三层解耦,各司其职

OpenClaw 的设计哲学是“职责分离,最小依赖”。它不追求大而全,而是把整个接入链路切成三个物理/逻辑上可独立部署、可单独升级的模块:

  • Agent 层(边缘侧):运行在树莓派、Jetson Nano、工控机等边缘设备上,负责与真实物理设备通信(串口/网口/USB)、协议解析(Modbus TCP/RTU、DL/T645、自定义二进制帧)、本地缓存(断网续传)、基础安全(TLS 1.2+双向证书认证)。它本身不处理业务逻辑,只做“搬运工”和“质检员”。

  • Core API 层(云端/中心侧):这是官方提供的标准RESTful服务,通常部署在企业私有云或混合云环境。它不直接连设备,只接收Agent上报的数据、下发控制指令、管理设备生命周期(注册/注销/分组/策略绑定)。所有业务系统(MES、SCADA、BI看板)都通过调用这一层API来交互,彻底隔离了OT侧的复杂性。

  • Adapter 层(聚合侧):这是开放给第三方平台的“插件接口”。OpenClaw 官方不提供具体实现,但定义了一套标准的WebSocket长连接协议与JSON Schema数据格式。任何支持WebSocket客户端和JSON解析能力的平台(如ThingsBoard的Rule Engine、EMQX的Webhook、自研中台的消息总线),只要按规范实现一个轻量Adapter,就能把OpenClaw设备当作原生设备纳管。

这个架构决定了它的不可替代性:当你要对接一个已有十年历史的SCADA系统时,你无法要求它去学MQTT;当你要给一个只有2G网络的偏远泵站装传感器时,你不能指望它跑Kubernetes。OpenClaw 的Agent就是那个“适配器”,它把一切协议差异收口,对外只输出统一的、带时间戳、设备ID、数据点路径(如device/001/sensor/temperature)的JSON对象。我见过最极端的案例:一个水利局用OpenClaw Agent接了三种完全不同的水文监测仪——国产的RS485超声波液位计、进口的LoRa压力变送器、还有老式机械翻斗雨量计(通过光电开关转脉冲信号)。三台设备协议天差地别,但在Core API里,它们的数据点路径、上报频率、告警阈值,全部用同一套YAML模板管理。这种“协议无关性”不是靠抽象,而是靠配置驱动——Agent启动时读取YAML,就知道该用哪种驱动、连哪个端口、怎么解析字节流。所以选型OpenClaw,本质上是选了一种“用配置代替编码”的工程范式,特别适合那些设备型号杂、预算紧、上线急的中小型项目。

2.2 为什么不是MQTT/OPC UA/HTTP直连?

很多人第一反应是:“我的设备明明支持MQTT,为啥还要多套一层?” 这是个好问题,答案藏在真实产线的“毛细血管”里。我拿自己踩过的坑举例:去年在一家食品厂调试,他们的新购温控器确实支持MQTT,但固件版本是2019年的,只支持MQTT v3.1,且不支持TLS加密。而客户云平台强制要求TLS 1.2+。如果硬上,就得找厂商升级固件——等了47天,期间产线数据全断。换成OpenClaw,我们用Agent做中间代理:Agent用明文MQTT连温控器,再用TLS 1.2 HTTPS把数据发到Core API。两套协议在Agent内存里完成转换,对温控器零影响,当天下午就通了。再比如OPC UA,它确实是工业互联的金标准,但代价是资源消耗大。一台i5工控机跑OPC UA Server没问题,但你要在ARM Cortex-A7的嵌入式网关上跑?内存溢出是常态。OpenClaw Agent的Go语言实现,静态编译后二进制仅8MB,常驻内存<30MB,CPU占用峰值<15%,这才是边缘侧的真实需求。至于HTTP直连,更不现实。让PLC自己发起HTTPS请求?它连DNS解析都不会。OpenClaw 的Agent才是那个“有手有脚”的执行者,它主动连设备、主动连云,把被动等待变成主动推送。所以方案选型的核心逻辑不是“谁更先进”,而是“谁更扛造”。OpenClaw 的优势不在技术炫技,而在它把工业现场的“脏活累活”——协议兼容、断网续传、证书轮换、心跳保活——全封装进了那个小小的Agent进程里,让你专注业务。

2.3 版本与部署形态选择:社区版 vs 企业版,一体机 vs 分布式

OpenClaw 目前有两个主要分支:Community Edition(CE)Enterprise Edition(EE)。CE版完全开源(Apache 2.0),包含全部Agent功能、Core API基础版、完整的文档与示例,适合学习、POC验证、小规模部署(<500台设备)。EE版则增加了几个关键企业级能力:设备影子(Shadow)服务(解决指令下发的最终一致性)、多租户隔离(不同产线数据逻辑隔离)、审计日志(谁在何时修改了哪台设备的参数)、以及最重要的——商用License授权管理。很多客户采购EE版,并非因为功能多,而是为了合规。他们的IT审计部门明确要求:所有接入生产网的软件必须有正式商业授权,开源软件需提供SBOM(软件物料清单)和CVE漏洞扫描报告。EE版打包时已内置这些交付物。部署形态上,强烈建议采用“分布式部署”。不要把Agent、Core API、数据库全塞进一台服务器。我见过太多失败案例:某客户图省事,用一台4核8G云主机跑全套,结果某天产线集中上报数据,Core API的HTTP连接数瞬间打满,所有Agent心跳超时,平台显示“全部离线”,实际设备运行正常。正确姿势是:Agent分散在各车间边缘;Core API至少双节点(Nginx负载均衡);PostgreSQL数据库独立部署,开启流复制。这样单点故障不会导致全局雪崩。对于超大规模(>1万台设备),EE版还支持Core API的水平扩展——通过Redis作为分布式锁和设备状态缓存,多个API实例共享同一份设备元数据。这个细节看似微小,却决定了系统能否从“能用”走向“稳用”。

3. OpenClaw 核心配置与实操要点:从零开始,每一步都踩准节奏

3.1 环境准备:硬件、系统、依赖,一个都不能少

动手前,请务必确认你的硬件和系统满足最低要求。这不是形式主义,而是OpenClaw稳定性基石。Agent官方推荐运行环境是Linux ARM64 / AMD64,内核版本 ≥ 4.15,glibc ≥ 2.27。Windows和macOS仅支持开发调试,严禁用于生产环境。我曾因忽略这点栽过大跟头:在一台CentOS 7.2(内核3.10)的旧服务器上部署Agent,运行两周后突然大量报错epoll_ctl: Operation not permitted,查了三天才发现是内核版本过低导致epoll事件循环异常。最终重装系统才解决。所以,第一步永远是检查:

# 检查内核版本 uname -r # 检查glibc版本 ldd --version # 检查可用内存(Agent最低需512MB) free -h

硬件方面,Agent对算力要求极低,但对I/O和稳定性要求极高。绝对禁止使用SD卡作为系统盘!我亲眼见过一个客户用树莓派+SD卡部署,半年后SD卡写满损坏,Agent进程崩溃,产线数据中断12小时。正确做法是:树莓派用USB3.0 SSD(推荐三星T5),工控机用工业级mSATA固态盘。网络配置上,确保Agent所在机器有固定IP(DHCP保留地址或静态IP),并关闭防火墙或放行必要端口:Agent默认监听0.0.0.0:8080(HTTP管理端口)和0.0.0.0:1883(MQTT桥接端口,如启用),Core API默认监听0.0.0.0:8000。如果你的网络有严格ACL策略,务必提前申请开通。依赖方面,CE版Agent是静态编译二进制,无需安装Go环境或Python,这是它最大的易用性优势。你只需要一个干净的Linux系统,下载对应架构的tar.gz包,解压,赋予权限,即可运行。但Core API是Python 3.9+应用,需安装依赖:

# 创建虚拟环境(强烈推荐,避免污染系统Python) python3.9 -m venv openclaw-env source openclaw-env/bin/activate # 安装依赖(官方requirements.txt已优化,含异步IO加速) pip install -r requirements.txt

这里有个隐藏技巧:requirements.txt中的uvloop库能将API的异步事件循环性能提升40%,但它在某些ARM平台编译失败。如果遇到error: command 'gcc' failed,直接注释掉uvloop这一行,用标准asyncio也能稳定运行,只是并发能力稍弱。

3.2 Agent 配置详解:YAML文件里的每一个字段,都是血泪教训

Agent的核心是config.yaml文件。它不是简单的键值对,而是一个精心设计的协议描述DSL。我把它拆解为四个必填区块,每个字段背后都有故事:

3.2.1global区块:全局心跳与安全基线
global: device_id: "PLC-001" # 设备唯一标识,必须全网唯一,建议用MAC或序列号哈希 api_endpoint: "https://api.yourcompany.com:8000" # Core API地址,必须带https tls_cert_path: "/etc/openclaw/cert.pem" # 双向TLS证书路径,Agent用此证明身份 tls_key_path: "/etc/openclaw/key.pem" # 私钥路径,必须600权限 heartbeat_interval: 30 # 心跳间隔秒数,太短加重API负担,太长影响离线感知

device_id是灵魂。我曾在一个项目里用时间戳生成ID,结果两台Agent同时启动,ID重复,API直接拒绝注册。后来改用$(cat /sys/class/net/eth0/address | md5sum | cut -c1-8)命令生成8位唯一码,再无此问题。tls_cert_pathtls_key_path是安全命门。证书必须由Core API信任的CA签发(不能自签),且私钥权限必须是600(chmod 600 key.pem),否则Agent启动报错permission denied。这个错误在日志里不明显,只会显示failed to load TLS config,新手常在此卡住数小时。

3.2.2drivers区块:协议驱动的精准匹配
drivers: - name: "modbus_tcp" type: "modbus" config: host: "192.168.1.100" port: 502 timeout: 5 unit_id: 1 points: - path: "sensor/temperature" address: 0 datatype: "int16" scale: 0.1 - path: "status/running" address: 100 datatype: "bool"

这是最易出错的部分。address不是寄存器编号,而是起始地址偏移量。比如你的温控器手册写“温度值在40001寄存器”,那address应填0(因为40001是第一个保持寄存器,索引为0)。填成40001就会读错位置。datatype必须严格匹配设备返回字节序。int16是2字节有符号整数,uint32是4字节无符号整数,float32是IEEE754单精度浮点。有一次我误将float32写成int32,温度值显示为123456789,实际应是25.6℃scale字段是放大倍数,用于处理小数。设备返回256(代表25.6℃),scale: 0.1就自动转成25.6。这个设计极大简化了前端展示逻辑。

3.2.3mqtt_bridge区块:为老旧设备装上MQTT翅膀
mqtt_bridge: enabled: true broker_url: "tcp://localhost:1883" client_id: "openclaw_plc001" username: "agent" password: "secret" topic_prefix: "openclaw/plc001"

这个功能让不支持MQTT的设备“假装”支持。Agent启动后,会作为一个MQTT客户端连接到你指定的Broker(如EMQX),并将所有采集点数据按topic_prefix/path发布。例如sensor/temperature就发到openclaw/plc001/sensor/temperature主题。这样,你的现有MQTT订阅程序完全不用改,就能收到新设备数据。但注意:broker_url必须是tcp://ssl://,不能是http://。我曾因写成http://localhost:1883,Agent日志疯狂刷connection refused,排查半天才发现是协议写错。

3.22.4logging区块:日志是排障的唯一光源
logging: level: "info" # debug/info/warn/error,生产环境用info,避免日志爆炸 file: "/var/log/openclaw/agent.log" # 必须指定绝对路径,且目录需存在 max_size: 10 # 单个日志文件最大10MB max_backups: 5 # 最多保留5个历史日志 max_age: 28 # 日志最长保存28天

file路径必须手动创建并赋权:mkdir -p /var/log/openclaw && chown openclaw:openclaw /var/log/openclaw。否则Agent启动失败,报错open /var/log/openclaw/agent.log: no such file or directory。这个错误极其隐蔽,因为Agent进程可能仍在运行(只是日志没写进去),你以为配置成功了,实际数据根本没上报。

3.3 Core API 部署与初始化:数据库、密钥、管理员,三把钥匙缺一不可

Core API 的部署比Agent复杂,核心在于三件事:数据库初始化、密钥生成、管理员创建。官方推荐PostgreSQL 12+,MySQL 8.0+也可用,但PostgreSQL对JSONB字段和并发事务支持更好,是首选。

3.3.1 数据库初始化:SQL脚本里的玄机

下载源码后,进入core-api/db/migrations/目录。这里有按时间戳命名的SQL文件(如20230101_init.sql,20230615_add_device_shadow.sql)。必须按文件名顺序依次执行,不能跳过。我曾为省事,直接执行最新的latest.sql,结果发现缺少devices表的last_heartbeat字段,导致Agent心跳更新失败,所有设备显示离线。正确的初始化命令(以PostgreSQL为例):

# 登录psql psql -U your_user -d your_db # 在psql内执行 \i /path/to/openclaw/core-api/db/migrations/20230101_init.sql \i /path/to/openclaw/core-api/db/migrations/20230615_add_device_shadow.sql # ... 依此类推

执行完后,检查表结构:SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'devices';确认last_heartbeatshadow_state等关键字段存在。

3.3.2 密钥生成:JWT令牌的安全心脏

Core API使用JWT进行身份认证。你需要生成一对RSA密钥:

# 生成私钥(2048位,PEM格式) openssl genrsa -out jwt_private.key 2048 # 生成公钥 openssl rsa -in jwt_private.key -pubout -out jwt_public.key

然后在core-api/config.py中配置:

JWT_PRIVATE_KEY_PATH = "/etc/openclaw/jwt_private.key" JWT_PUBLIC_KEY_PATH = "/etc/openclaw/jwt_public.key" JWT_ALGORITHM = "RS256"

关键禁忌jwt_private.key必须严格保密,权限设为600,且不能放在Web可访问目录。我曾因把密钥放在/var/www/html/下,被扫描工具发现,险些导致API被未授权调用。公钥可以公开,但也要放在受控目录。

3.3.3 管理员创建:curl命令背后的完整流程

官方文档说“运行python create_admin.py”,但这个脚本需要先配置数据库连接。更可靠的方法是用curl直接调用API:

# 第一步:获取初始token(需在config.py中设置INITIAL_ADMIN_TOKEN) curl -X POST https://api.yourcompany.com:8000/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"token": "your_initial_token"}' # 第二步:用返回的JWT创建管理员用户 curl -X POST https://api.yourcompany.com:8000/api/v1/users \ -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"StrongPass123!","email":"admin@company.com","role":"admin"}'

INITIAL_ADMIN_TOKEN是一个硬编码在config.py中的临时密钥,首次启动API时有效,之后会被清空。所以创建管理员必须在API首次启动后的5分钟内完成,否则token失效,只能重启API并重新生成。这是官方文档里没写,但每个运维都必须知道的“潜规则”。

4. OpenClaw 官方API调用实战:从设备注册到指令下发,手把手写透

4.1 认证机制深度解析:Bearer Token如何流转?

OpenClaw API的认证是典型的三段式JWT:Header.Payload.Signature。但它的Payload里藏着两个关键自定义声明(claim):

  • user_id: 用户唯一ID,由数据库生成。
  • scope: 权限范围,如device:read,device:write,user:manage

当你用管理员账号登录,返回的Token的scope*(通配符),拥有全部权限。但给前端应用分配Token时,必须限制scope。例如,给一个只读看板分配Token:

curl -X POST https://api.yourcompany.com:8000/api/v1/auth/token \ -H "Authorization: Bearer <admin_jwt>" \ -H "Content-Type: application/json" \ -d '{"user_id":"dashboard_app","scope":"device:read","expires_in":3600}'

返回的Token只能读设备数据,不能下发指令。这个设计防止了“一个Token泄露,全系统沦陷”的风险。我在某次渗透测试中,故意让一个低权限Token泄露,验证了它确实无法调用/api/v1/devices/{id}/command接口,返回403 Forbidden。所以,API调用的第一步永远是:获取一个scope精确、有效期合理的Token。不要图省事用管理员Token硬编码在前端,这是安全红线。

4.2 设备全生命周期管理:注册、分组、策略绑定,一套API搞定

设备管理是API最常用的部分。所有操作都围绕/api/v1/devices这个根路径。

4.2.1 设备注册:Agent启动后的“第一次握手”

当Agent首次启动,它会向/api/v1/devices/register发送POST请求,携带device_id和TLS证书指纹。API收到后,会检查该device_id是否已存在、证书是否在白名单。如果通过,返回201 Created和设备完整信息,包括分配的device_secret(用于后续心跳认证)。这个过程是原子性的,不存在“注册一半失败”的情况。但要注意:Agent的device_id必须与API中预注册的ID完全一致(大小写敏感)。我曾因PLC设备ID里有个字母O被误写成数字0,导致Agent反复注册失败,日志里只显示registration failed: device not found,排查时花了2小时才注意到这个细微差别。

4.2.2 设备分组:用标签(Tag)实现灵活的逻辑切分

OpenClaw不采用传统的“树形分组”,而是用Key-Value标签系统。一个设备可以有多个标签:

# 给设备PLC-001打上产线和区域标签 curl -X PATCH https://api.yourcompany.com:8000/api/v1/devices/PLC-001/tags \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"line":"A","area":"north","critical":"true"}'

这样,查询A产线所有关键设备,只需:

curl "https://api.yourcompany.com:8000/api/v1/devices?tag=line:A&tag=critical:true"

相比树形分组,标签系统支持多维度交叉查询,且无需预先规划层级。某客户有200台设备,按“产线-工序-设备类型”三级分组,用标签只需3个Key,查询语句也更简洁。

4.2.3 策略绑定:让设备行为随业务规则动态变化

策略(Policy)是OpenClaw的高级功能,用于动态控制设备行为。例如,定义一个“节能策略”:

{ "name": "energy_saving", "description": "Reduce sampling rate at night", "rules": [ { "condition": "hour >= 22 || hour <= 6", "action": {"sampling_interval": 300} }, { "condition": "true", "action": {"sampling_interval": 30} } ] }

然后将此策略绑定到设备组:

curl -X POST https://api.yourcompany.com:8000/api/v1/policies/energy_saving/bind \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"tag_filter": "line:A"}'

Agent会定期(默认5分钟)拉取策略,根据当前时间动态调整采样间隔。这个机制让设备配置从“静态文件”变成了“动态策略”,极大提升了运维灵活性。我在一个光伏电站项目中,用此功能实现了“阴天自动提高逆变器数据上报频率”,无需人工干预。

4.3 实时数据与指令交互:WebSocket vs REST,何时用哪个?

OpenClaw 提供两种实时交互方式,选择错误会导致性能灾难。

  • REST API/api/v1/devices/{id}/data: 适合批量查询历史数据。例如,获取PLC-001过去24小时的温度曲线:

    curl "https://api.yourcompany.com:8000/api/v1/devices/PLC-001/data?start=2023-10-01T00:00:00Z&end=2023-10-01T23:59:59Z&path=sensor/temperature"

    它返回JSON数组,每个元素是{timestamp, value, quality}。但注意:它不保证实时性,数据有最多30秒延迟(Agent本地缓存+上报队列)。

  • WebSocket/ws/v1/devices/{id}/stream: 适合实时监控与指令下发。建立长连接后,API会主动推送最新数据点和指令响应。这是唯一能实现“秒级响应”的方式。例如,下发一个重启指令:

    // 前端JavaScript const ws = new WebSocket("wss://api.yourcompany.com:8000/ws/v1/devices/PLC-001/stream?token=xxx"); ws.onopen = () => { ws.send(JSON.stringify({ "type": "command", "command": "reboot", "timeout": 30000 })); }; ws.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "command_response" && msg.status === "success") { console.log("设备已重启"); } };

    关键点:timeout字段指定了指令等待响应的最大毫秒数。如果设备30秒内没返回成功,API会标记为超时。这个机制避免了“发了指令,石沉大海”的尴尬。我建议:监控大屏用WebSocket,后台报表用REST,泾渭分明。

5. 第三方聚合平台接入:ThingsBoard、EMQX、自研中台,三套方案全解析

5.1 ThingsBoard 接入:Rule Chain里的OpenClaw Adapter

ThingsBoard 是最常被问及的聚合平台。它的优势是可视化强,劣势是原生不支持OpenClaw协议。接入核心是编写一个Rule Chain Node(规则链节点),作为OpenClaw的Adapter。

5.1.1 架构图景:数据流向如何设计?

OpenClaw Agent → Core API → ThingsBoard Rule Chain → ThingsBoard Database。注意:不要让ThingsBoard直接连Agent,这违反了OpenClaw的架构原则,且会绕过Core API的安全管控。正确路径是:Agent只连Core API,Core API通过Webhook或MQTT将数据推送给ThingsBoard。

5.1.2 Webhook 方案:零代码,但需配置精细

Core API 支持配置全局Webhook。在core-api/config.py中添加:

WEBHOOK_URLS = [ "https://thingsboard.yourcompany.com/api/v1/telemetry" ] WEBHOOK_HEADERS = { "Content-Type": "application/json", "X-Authorization": "Bearer YOUR_THINGSBOARD_TOKEN" }

然后,在Core API的/api/v1/webhooks管理界面,创建一个Webhook,触发条件设为device_data_update。这样,每当Agent上报新数据,Core API就会向ThingsBoard发送POST请求:

{ "deviceName": "PLC-001", "telemetry": [ { "ts": 1696123456789, "values": { "sensor/temperature": 25.6, "status/running": true } } ] }

ThingsBoard会自动创建设备(如果不存在)并存入时序数据库。但有个坑:deviceName必须与ThingsBoard中设备名称完全一致,且ThingsBoard的设备必须已存在(或开启自动创建)。我曾因ThingsBoard的设备名是plc-001(小写),而OpenClaw的device_idPLC-001(大写),导致数据全部丢弃,日志里只显示device not found。解决方案:在Webhook Payload模板中,用Jinja2语法强制转小写:{{ device_id|lower }}

5.1.3 MQTT 方案:更稳定,适合高吞吐

如果数据量大(>1000点/秒),Webhook可能成为瓶颈。此时改用MQTT桥接。Core API内置MQTT Publisher,配置core-api/config.py

MQTT_BROKER_URL = "tcp://emqx.yourcompany.com:1883" MQTT_TOPIC_TEMPLATE = "tb/telemetry/{{ device_id }}" MQTT_QOS = 1

然后在ThingsBoard中,创建一个MQTT Integration,订阅tb/telemetry/+主题。这种方式下,Core API作为MQTT Producer,ThingsBoard作为Consumer,解耦更彻底,吞吐量更高。我实测过:Webhook在1000点/秒时延迟升至2秒,而MQTT方案稳定在200ms内。

5.2 EMQX 接入:利用规则引擎做协议转换中枢

EMQX 是另一个高频接入目标,尤其在需要复杂消息路由的场景。它的优势是规则引擎(Rule Engine)强大,可做深度数据清洗。

5.2.1 数据接入:EMQX作为OpenClaw的“前置网关”

思路是:让OpenClaw Agent直接连EMQX,而不是Core API。这需要修改Agent的config.yaml,启用mqtt_bridge并指向EMQX:

mqtt_bridge: enabled: true broker_url: "ssl://emqx.yourcompany.com:8883" # 启用TLS client_id: "openclaw_plc001" username: "openclaw" password: "secure_password" topic_prefix: "oc/plc001"

然后,在EMQX的规则引擎中,创建一条SQL规则:

SELECT payload.device_id as device_id, payload.path as path, payload.value as value, payload.timestamp as ts FROM "oc/+" WHERE payload.path IS NOT NULL

这条SQL将原始MQTT消息(可能是嵌套JSON)提取出关键字段。接着,配置动作,将处理后的数据转发到Core API的Webhook端点:

{ "url": "https://api.yourcompany.com:8000/api/v1/webhooks/emqx_forward", "method": "post", "headers": {"Content-Type": "application/json"}, "body": "{\"device_id\": \"${device_id}\", \"data\": {\"${path}\": ${value}, \"ts\": ${ts}}}" }

这个方案的好处是:EMQX承担了协议解析和路由的重担,Core API只做业务逻辑,职责更清晰。我在一个智慧水务项目中,用此方案接入了200+种不同协议的水表,EMQX规则引擎统一处理,Core API只管存储和告警。

5.3 自研中台接入:WebSocket Adapter开发指南

对于有自研IoT中台的企业,官方提供了标准的WebSocket Adapter协议。这是最灵活,也最具挑战性的方案。

5.3.1 协议规范:心跳、认证、数据帧,一个都不能错

Adapter必须与Core API建立WebSocket连接,URL为wss://api.yourcompany.com:8000/ws/v1/adapter。连接建立后,第一步是发送认证帧:

{ "type": "auth", "adapter_id": "my_custom_adapter", "secret": "your_shared_secret" }

secret必须在Core API的config.py中预配置ADAPTER_SECRETS = {"my_custom_adapter": "your_shared_secret"}。认证成功后,API会发送{"type": "auth_success"}。此后,所有通信都基于JSON帧。

5.3.2 数据帧解析:如何把OpenClaw数据映射到中台模型?

OpenClaw的数据帧结构是:

{ "type": "device_data", "device_id": "PLC-001", "timestamp": 1696123456789, "points": [ {"path": "sensor/temperature", "value": 2