平台在链路里扮演什么角色

当设备从几十台涨到几万台,你会发现真正难的不再是“怎么把数据发出去”,而是这几件事:谁在什么时候注册过这台设备、它有哪些能力、数据应该存到哪里、异常由谁触发、固件怎么批量升级。物联网平台就是把这些横切关注点集中起来的那一层。

选平台本质上是选“数据模型能力和规则表达能力”。设备接入协议大家都能做到,真正决定你后续开发量的,是物模型能不能描述清楚你的设备,规则引擎能不能替你完成大部分数据流转。
物联网平台配图:平台仪表盘面板与设备节点连接
物模型是把物理设备翻译成平台可理解语言的字典,选平台先看物模型表达能力

下面围绕四件事展开:设备怎么进来、能力怎么描述、数据怎么流转、以及怎么在能力相近的平台之间做取舍。

设备接入:身份从哪里来

设备接入的第一道关是身份。几乎所有平台都采用“一机一密”的思路:设备出厂时携带唯一标识与密钥,首次连接时用它们换取会话凭据。常见的字段命名是产品标识 + 设备名 + 设备密钥这组三元组,接入时用它计算签名或换取 Token。

# 设备首次连接:用三元组换会话凭据(示意,字段名按平台文档替换)
import hashlib, hmac, json, time

def sign(product_key, device_name, device_secret, ts):
    # 常见做法:对 "deviceName + timestamp" 之类的内容做 HMAC 摘要
    msg = ("%s%s" % (device_name, ts)).encode("utf-8")
    return hmac.new(device_secret.encode("utf-8"), msg, hashlib.sha256).hexdigest()

ts = int(time.time() * 1000)
auth = {
    "productKey": "a1JjyXXXXXX",
    "deviceName": "dev-0001",
    "timestamp": ts,
    "sign": sign("a1JjyXXXXXX", "dev-0001", "s3cr3t-per-device", ts)
}
print(json.dumps(auth, ensure_ascii=False))
接入方式怎么选
  • 一机一密每台设备烧录唯一密钥,安全性最好,适合量产设备,代价是产线需要写入与追溯。
  • 一型一密同型号共用产品密钥,首次连接时动态注册获取设备密钥;开箱即用,但要为密钥泄漏准备好吊销流程。
  • 网关子设备设备本身没有联网能力(如 RS485 设备),由网关代理注册与上下线,平台侧要开启子设备拓扑管理。

物模型:把设备翻译成平台能懂的语言

物模型(各平台叫法不同,有的叫 TSL)规定了三类能力:属性(可读可写的状态)、事件(上报发生的事情)、服务(平台可调用的动作)。它决定了下游一切:数据怎么存、控制指令怎么下、可视化怎么配。

{
  "properties": [
    { "identifier": "temperature", "name": "温度", "dataType": { "type": "float", "specs": { "min": -40, "max": 125, "unit": "℃", "step": 0.1 } }, "accessMode": "r" },
    { "identifier": "switchState", "name": "开关状态", "dataType": { "type": "bool" },                            "accessMode": "rw" },
    { "identifier": "mode",        "name": "运行模式", "dataType": { "type": "enum", "specs": { "0": "待机", "1": "制冷", "2": "制热" } }, "accessMode": "rw" }
  ],
  "events": [
    { "identifier": "highTempAlarm", "name": "高温告警", "type": "alert",
      "outputData": [ { "identifier": "value", "dataType": { "type": "float" } } ] }
  ],
  "services": [
    { "identifier": "setMode", "name": "设置模式",
      "inputData": [ { "identifier": "mode", "dataType": { "type": "int" } } ] }
  ]
}

物模型设计有三条经验:属性描述状态、事件描述突变、服务描述动作,不要把“设置温度”做成属性写操作又做成服务,否则日志里会出现两套语义相同的记录;枚举比字符串更好用,平台侧做聚合和告警时更省事;单位与量程一定要写全,它是后续可视化刻度与告警阈值的默认值来源。

规则引擎与数据流转

设备上报的数据如果全部原样入库,存储成本会很快失控。规则引擎的作用是在数据进来时顺手做一次加工:过滤、转换、投递到不同目的地。

-- 典型规则引擎写法(SQL 风格):订阅上报主题,筛选后转发
SELECT
  deviceName()            AS device,
  timestamp()             AS ts,
  temperature             AS temp,
  switchState             AS sw
FROM
  '/a1JjyXXXXXX/+/thing/event/property/post'
WHERE
  temperature > 80

-- 命中后按顺序执行动作:
-- 1) 写入时序数据库(长期趋势)
-- 2) 投递到消息队列 / 函数计算(触发业务逻辑与告警通知)
-- 3) 调用另一个服务端 API(如工单系统开单)

-- 补充一条“全部数据落冷存储”的规则,用于回溯与训练
SELECT * FROM '/a1JjyXXXXXX/+/thing/event/property/post'

两个实践要点:把“告警判定”和“数据落库”拆成两条规则,避免一次改动影响两件事;规则里的时间统一用平台时间戳,设备本地时间只能作为附加字段,否则跨时区站点会乱成一团。

平台横向对比:看哪几个维度

平台之间的差异没有宣传里那么大,也不像某些测评写得那么不可比较。抓住下面六个维度,基本能做出适合自己的选择。

维度需要确认的问题影响
协议支持是否原生支持 MQTT、CoAP、HTTP、Modbus 网关接入;是否支持自定义协议透传决定现场改造工作量
物模型能力数据类型是否覆盖 struct/array;是否支持属性读写与事件服务决定后续开发是否需要大量自建映射
规则引擎是否支持 SQL/函数式加工;可否投递到自有数据库与消息队列决定数据链路是否需要额外中间层
设备管理批量注册、标签分组、OTA、远程配置、在线诊断决定运维阶段的自动化上限
成本结构按连接数、消息量还是存储量计费;免费额度怎么算决定规模化后的成本曲线
可迁移性是否支持私有化部署;导出数据与配置是否容易决定被单家平台锁定的风险

一个容易被忽略的维度是“本地化与合规”:如果数据不能出境或不能出厂区,那么支持私有化部署(或提供本地版本)就成了硬性条件,这时候功能清单再漂亮也没用。