HTTP 原始消息解析与遥测写入
适用 ThinkLink 2.00.099。两组接口均为有副作用的实际上报:可更新活跃时间、最新值、历史数据,并产生转发、触发器和关联设备通知。页面的**“模拟发送”也会真实处理数据**,不是脚本试运行。执行前确认组织、设备及已保存的模型绑定。
选择接口
| 项目 | 原始消息解析 | 已解析遥测写入 |
|---|---|---|
| 单条 / 批量 | parse-payload / batch-parse-payload | write-telemetry / batch-write-telemetry |
| 输入 | data.msg 是交给脚本的原始 JSON 对象 | data.msg 内包含模型标识和遥测 data 对象 |
| 目标物模型脚本 | 执行选中的已绑定模型 | 不执行目标设备解析脚本 |
| 模型位置 | 请求顶层 thing_model_ids / thing_model_id_names | 每条 msg.thing_model_id / msg.thing_model_id_name |
return_data: true | 本次脚本原始输出 | 本次遥测合并后的快照 |
全部使用 POST、JSON 和现有 token 请求头。组织路径为 /thinklink/device/;系统路径为 /thinklink/system/device/,下接上表操作名。组织从 token 确定,tenant 可省略,填写必须与当前组织一致。系统侧要求 SYSADMIN,并必须显式提供目标组织 tenant_code 作为顶层 tenant;填写 tenant 不会授予权限。
参数与模型选择
- 单条
data为对象;批量data为非空数组,每项有非空字符串eui和对象msg。一个批次只属于一个组织,允许重复 EUI,按输入顺序执行。 - 原始解析把
msg对象直接交给物模型,不再包装 eui/data/tenant,不做额外 JSON.parse,也不注入 MQTT topic。msg不能是字符串、数组或 null;业务字段原样保留。 - 原始解析的
thing_model_ids为数据库 ID 字符串数组,thing_model_id_names为标识名id_name数组,不是显示名称。两者同时提供取并集去重,按设备绑定顺序执行。省略两个字段执行全部绑定模型,空数组或空白标识非法。只可选择已绑定且有使用权限的模型;标识名在可用绑定模型中必须唯一匹配。筛选不改变绑定,也不传递给关联虚拟设备的后续解析。 - 筛选字段只放在请求顶层,放进
data项会报 400。批量共用同一组筛选,每台设备都必须满足绑定要求。页面模拟发送选择器只显示已保存绑定模型,并提交顶层thing_model_ids。 - 直接写入每条
msg至少提供thing_model_id_name或thing_model_id中一个非空字符串;同时提供必须指向同一模型。按名称优先本组织再回退公共模型,仍须校验权限和绑定。误用解析接口的顶层模型筛选返回 400。 - 直接写入要求设备存在且已绑定模型,不自动创建设备或绑定。
msg.data必须是对象,可为空对象,字段值保留0、false、null和嵌套对象;整个msg.data不能是 null、数组或字符串。 - 直接写入按模型合并最新遥测,保留未提供的旧字段,以服务端当前时间更新遥测
update_time和设备活跃时间。历史存储遵循real_time_storage;关闭历史仍更新最新值及通知。沿用转发、触发器、关联设备和既有协议通知,关联设备可继续执行自己的解析。 - 这不是历史回填、属性修改或任意 RPC 入口;时间字段不能将它变成历史回填。普通遥测写入不修改配置时间。
option可省略;option.return_data默认 false,提供时只接受布尔值,不接受字符串"true"。
八种请求示例
先在自己的终端设置 TKL_BASE(例如 https://your-thinklink-host,不含 /thinklink)和 TKL_TOKEN。以下命令会实际提交;先替换 EUI、已绑定模型标识、系统侧 tenant 及相应权限的 token。示例中的 temperature 模型必须预先存在且已绑定;原始解析结果取决于该模型脚本。也可将顶层 thing_model_id_names 换成 thing_model_ids: ["实际模型ID"];直接写入则在 msg 内用 thing_model_id。
组织侧 · parse-payload
curl --request POST "$TKL_BASE/thinklink/device/parse-payload" \
--header "token: $TKL_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"data": {
"eui": "00112233",
"msg": {
"temperature": 23.5
}
},
"thing_model_id_names": [
"temperature"
],
"option": {
"return_data": true
}
}'系统侧 SYSADMIN · parse-payload
curl --request POST "$TKL_BASE/thinklink/system/device/parse-payload" \
--header "token: $TKL_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"tenant": "tenantA",
"data": {
"eui": "00112233",
"msg": {
"temperature": 23.5
}
},
"thing_model_id_names": [
"temperature"
],
"option": {
"return_data": true
}
}'组织侧 · batch-parse-payload
curl --request POST "$TKL_BASE/thinklink/device/batch-parse-payload" \
--header "token: $TKL_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"data": [
{
"eui": "00112233",
"msg": {
"temperature": 23.5
}
},
{
"eui": "00445566",
"msg": {
"temperature": 24.5
}
}
],
"thing_model_id_names": [
"temperature"
],
"option": {
"return_data": true
}
}'系统侧 SYSADMIN · batch-parse-payload
curl --request POST "$TKL_BASE/thinklink/system/device/batch-parse-payload" \
--header "token: $TKL_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"tenant": "tenantA",
"data": [
{
"eui": "00112233",
"msg": {
"temperature": 23.5
}
},
{
"eui": "00445566",
"msg": {
"temperature": 24.5
}
}
],
"thing_model_id_names": [
"temperature"
],
"option": {
"return_data": true
}
}'组织侧 · write-telemetry
curl --request POST "$TKL_BASE/thinklink/device/write-telemetry" \
--header "token: $TKL_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"data": {
"eui": "00112233",
"msg": {
"thing_model_id_name": "temperature",
"data": {
"temperature": 23.5,
"humidity": 60
}
}
},
"option": {
"return_data": true
}
}'系统侧 SYSADMIN · write-telemetry
curl --request POST "$TKL_BASE/thinklink/system/device/write-telemetry" \
--header "token: $TKL_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"tenant": "tenantA",
"data": {
"eui": "00112233",
"msg": {
"thing_model_id_name": "temperature",
"data": {
"temperature": 23.5,
"humidity": 60
}
}
},
"option": {
"return_data": true
}
}'组织侧 · batch-write-telemetry
curl --request POST "$TKL_BASE/thinklink/device/batch-write-telemetry" \
--header "token: $TKL_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"data": [
{
"eui": "00112233",
"msg": {
"thing_model_id_name": "temperature",
"data": {
"temperature": 23.5,
"humidity": 60
}
}
},
{
"eui": "00445566",
"msg": {
"thing_model_id_name": "temperature",
"data": {
"temperature": 24.5,
"humidity": 0
}
}
}
],
"option": {
"return_data": true
}
}'系统侧 SYSADMIN · batch-write-telemetry
curl --request POST "$TKL_BASE/thinklink/system/device/batch-write-telemetry" \
--header "token: $TKL_TOKEN" \
--header "Content-Type: application/json" \
--data '{
"tenant": "tenantA",
"data": [
{
"eui": "00112233",
"msg": {
"thing_model_id_name": "temperature",
"data": {
"temperature": 23.5,
"humidity": 60
}
}
},
{
"eui": "00445566",
"msg": {
"thing_model_id_name": "temperature",
"data": {
"temperature": 24.5,
"humidity": 0
}
}
}
],
"option": {
"return_data": true
}
}'响应与失败边界
不回传数据时成功响应均为 {"result":true},仍已执行处理。单条回传信封如下,示例 ID 和时间仅为示意:
{
"result": true,
"data": {
"eui": "00112233",
"results": [
{
"thing_model_id": "1234567890",
"data": {
"telemetry_data": {
"temperature": 23.5,
"humidity": 60,
"update_time": "2026-10-26T00:00:00.000Z"
}
}
}
]
}
}上例展示直接写入的合并快照:results 仅含本次写入的一个模型,包含旧字段和服务端时间,是首次异步等待前取得的 JSON 深快照。原始解析使用相同信封,但每项 data 是本次脚本的原始输出(对象、数组或 null),按模型绑定顺序排列;不是设备完整状态,正常空输出不算失败。批量响应的外层 data 为结果数组,顺序与输入一致,重复 EUI 不去重。
整批先做参数、组织、设备、模型权限及绑定预检,再按顺序执行,并在每项执行前重新检查。预检失败不开始本批写入;执行阶段不是事务,首个错误会停止后续处理,前序设备、模型或通知不会回滚,失败项也可能已有部分副作用。
保留 HTTP 400(参数、模型或处理错误)、403(组织/权限边界)、404(目标设备不存在)及 AppError 的 message、format、values。旧服务缺少路由也可能返回 404,应结合错误体和实际版本判断,不能自动改用其他写入口。
超时或结果不明时标记“结果待确认”,先核查最新值、历史、通知与设备反馈,再决定针对未完成项补执行;不能盲目重放整批,否则可能重复历史或通知。HTTP 成功不代表数据库缓冲已刷盘、外部通知已送达或物理设备动作已确认。
RPC 共用写入语义,见 writeTelemetry。本地示例校验、平台部署和实际设备验收分别记录,见 2.00.099 升级说明。