- 物联网
- 后端
- 数据可视化
- 消息队列
【免费下载链接】thingsboard
All-in-one IoT Platform - Device management, data collection, processing and visualization.
导读
本文以 ThingsBoard 帮助系统中的 扩展 Converter 输出示例 为骨架,系统讲解 V2 版 Uplink 数据转换器(Decoder/Converter)的扩展输出 JSON 结构:在基础的实体名、属性、遥测之上,如何通过entityType、profile、label、customer、group等字段一次性完成实体分类、配置文件绑定、客户归属与实体分组。读者读完本文后,将能编写出可直接运行于 ThingsBoard 集成场景的扩展 Converter 输出,并理解其底层解析逻辑(见AbstractUplinkDataConverter与DedicatedConverterUtil的实现)。
背景:Decoder 与 Converter 两种输出
在 ThingsBoard 的集成(Integration)体系中,Uplink 数据转换器负责把来自各类集成(如 ChirpStack、The Things Stack、MQTT 等)的上行消息解析并转换为平台通用的数据格式。官方帮助文档 decoder_fn_v2.md 明确指出存在两种输出:
- Converter output(转换器输出):由预配置的设置与解码函数的执行结果共同组合而成。初始配置定义默认的键和值,解码函数可在必要时覆盖这些键。这种灵活的机制确保预配置信息与动态数据都能无缝整合进最终的 JSON 输出中。
- Decoder output(解码器输出):解码函数返回的直接结果,即从原始报文解码得到的数据,不经额外配置或加工,必须是一个合法 JSON 对象,并且至少要包含一个非空的
attributes对象和一个非空的telemetry对象或数组。
本文聚焦的是 Converter 输出中更完整的"扩展形态"——即在基础字段之外,通过label、customer、group等可选字段,把实体创建阶段的归属关系一次性表达出来。
扩展 Converter 输出示例(核心 JSON)
仓库中的 extended_converter_output.md 给出了如下完整示例(该示例在 UI 帮助弹窗中被tb-help-popup="converter/examples/decoder_v2/extended_converter_output"引用,标题为 "Converter output with entity label, group, customer"):
{ "entityType": "DEVICE", "name": "Device 1000000000000001", "profile": "default", "label": "Device name", "customer": "MyCustomer", "group": "SensorsGroup", "telemetry": [{ "ts": 1742770246830, "values": { "temperature": 50 } }, { "fCnt": 4, "rssi": -35 }], "attributes": { "fPort": 85, "tenantName": "ChirpStack", "applicationName": "Chirpstack application", "tenantId": "52f14cd4-c6f1-4fbd-8f87-4025e1d49242", "eui": 1000000000000001, "applicationId": "ca739e26-7b67-4f14-b69e-d568c22a5a75" } }注意该示例中的几个特征,它们是"扩展"形态与"简单"形态(见 simple_converter_output.md)的关键区别:
- 顶层多出了
entityType、profile、label、customer、group五个字段; telemetry是一个数组,其中第一个元素带显式ts时间戳,第二个元素不带ts(将由平台自动填充服务端时间戳);attributes中包含了 ChirpStack 集成注入的元数据键值对(tenantName、applicationId、eui等)。
扩展字段逐项解析
根据 decoder_fn_v2.md 的官方定义,各字段的语义如下:
| 字段 | 必填性 | 说明 |
|---|---|---|
entityType | 可选 | 取值必须是Asset或Device,指明实体的性质,确保平台数据模型中的分类正确。 |
name | 可选 | 在租户作用域内唯一标识设备/资产。常使用 eui、MAC 地址等硬件唯一标识作为名称。平台用它查找已有实体;若未找到且集成允许创建实体,则新建。 |
profile | 可选 | 与设备/资产关联的配置文件(Profile)。若预配置和解码函数中都没有设置,则自动应用默认值default。 |
label | 可选 | 非唯一、用户友好的标签,可在仪表板上显示;仅在本集成创建实体时生效。 |
customer | 可选 | 平台会自动把实体分配到该客户名下,若不存在则新建该客户。仅在当前集成创建实体时生效;实体已存在则忽略。 |
group | 可选 | 平台会自动把实体分配到指定实体组,不存在则新建。组默认创建在租户作用域内;若同时提供了customer,则创建在客户作用域下。仅在创建实体时生效,实体已存在则忽略。 |
与 Decoder 输出的差异
为了对照,解码器输出的扩展形态见 extended_decoder_output.md:
{ "label": "MyLabel", "customer": "MyCustomer", "group": "SensorsGroup", "attributes": { "sn": "S567483" }, "telemetry": [{ "ts": 1742770610971, "values": { "temperature": 50, "humidity": 45 } }] }对比可见:Decoder 输出使用label、customer、group表达同样的归属信息(简单形态见 simple_decoder_output.md,只有attributes和telemetry),但 Converter 输出中额外使用entityType(DEVICE/ASSET)与profile来刻画实体类型与配置文件。这正是"转换器把预配置与解码结果合并"的能力体现。
源码级验证:输出字段如何被解析
传统 Converter 输出:AbstractUplinkDataConverter
ThingsBoard 的 Uplink 转换框架由 AbstractUplinkDataConverter.java 实现。其convertUplink方法把解码函数返回的原始 JSON 字符串交给parseUplinkData逐条处理:若顶层是 JSON 数组则遍历每个对象,若是单个对象则直接解析。parseUplinkData中的关键行为包括:
- 实体类型判定(
getIsAssetAndVerify):要求deviceName与assetName恰好出现其一,二者同时出现或都不出现都会抛出JsonParseException;作为资产时必须显式提供assetType。 - 默认设备类型:当
deviceType缺失时自动填入常量DEFAULT_DEVICE_TYPE = "default"。 - 可选字段:
deviceLabel/assetLabel、customerName、groupName均为可选,存在即解析。 - 数据承载:
telemetry通过parseTelemetry转成PostTelemetryMsg,attributes通过parseAttributesUpdate转成PostAttributeMsg。
需要注意的是:这种"脚本模式"的 Converter 输出中实体命名键为deviceName/assetName、deviceType/assetType,这与 V2 专用(Dedicated)Converter 使用的name/type/profile键名略有不同——这正是两个版本输出格式的差异来源。
扩展 Converter 输出(entityType/profile等)的专用解析器
V2 版 Converter 的entityType、profile、label、customer、group等扩展字段由 DedicatedConverterUtil.java 统一解析:
entityType取自顶层type字段(EntityType::valueOf),并允许用预配置兜底;name、profile、label、customer、group均遵循"输出优先、配置兜底"的策略:如果解码输出中存在对应键,则优先采用,否则回落到 Converter 预配置(config.getProfile()等),其中 profile 字段还可执行模板渲染processTemplate(config.getProfile(), kvMap)(kvMap 来自集成 metadata);profile缺省时使用常量DEFAULT_PROFILE = "default",与官方文档"默认值 default 自动应用"的表述一致;telemetry与attributes会与预配置中定义的键合并,且都支持ts与values结构。
随后 DedicatedScriptUplinkDataConverter.java 把解析出的DedicatedUplinkData映射回统一UplinkData模型:资产情况下profile被映射为assetType,设备情况下被映射为deviceType,label/customer/group则映射为对应的*Label、customerName、groupName。
遥测与属性的底层转换:JsonConverter
AbstractUplinkDataConverter.parseTelemetry最终调用 JsonConverter.java 的convertToTelemetryProto。其parseObject逻辑验证了示例中两种遥测元素的合法性:
- 若对象同时包含
ts与values,则使用ts作为该数据点的时间戳(Unix 毫秒),values中的键值对被转换为KeyValueProto; - 若对象没有
ts,则自动采用系统当前时间(System.currentTimeMillis()); - 标量值按 JSON 类型自动映射为 STRING/BOOLEAN/DOUBLE/LONG 等 KeyValueType,字符串可开启数字字符串的自动类型转换。
convertToAttributesProto则要求输入必须是 JSON 对象,并遍历其键值对生成属性更新消息。这正是示例中"带ts的数据点 + 不带ts的数据点"混合出现在telemetry数组中能够正常入库的底层原因。
配套示例:Simple Binary 与 Simple JSON 的 Converter 输出对照
为了更直观理解扩展输出的定位,可对照 V2 目录下两个完整示例(均含 payload、metadata、解码函数、Decoder 输出、Converter 输出):
- simple-binary/converter_output.md:解析二进制报文(设备序列号、电量、温度、饱和度),Converter 输出为含
name、profile、telemetry(带ts)、attributes的完整 JSON; - simple-json/converter_output.md:解析 ChirpStack 风格 JSON,输出中
telemetry以对象形态({"ts": ..., "values": {...}})呈现,attributes携带sn、fPort、dr、frequency、eui等字段。
从源码结构看,这些文档对应的解码函数与输出示例共同构成了一套"输入 → 解码 → 输出"的完整教学链路,读者可以逐个对照验证自己的解码函数行为。TBEL(ThingsBoard Expression Language)版本的示例位于 converter/tbel/examples/decoder_v2 目录,而 converter/examples/decoder_v2 目录则对应 JavaScript 版本,两者内容结构一一对应,便于横向比较。
实战建议与注意事项
- 保持
attributes与telemetry非空:Decoder 输出至少需要一个非空的attributes键值对和一个telemetry数据点;Converter 输出同样应保证两者可解析。 name的幂等性:建议使用 eui、MAC 等稳定唯一标识作为实体名,平台据此做查重与自动创建,避免重复实体。customer/group仅在创建时生效:实体已存在时这些字段会被忽略,因此不适合用它做持续的归属迁移。profile默认default:若输出与预配置中都未指定,会回落到default配置文件,需确保该配置存在或刻意为之。- 时间戳语义:
ts必须是 Unix 毫秒时间戳;不带ts的遥测数据点使用服务端接收时间,适用于对到达时序不敏感的场景。 entityType取值约束:只能是DEVICE或ASSET,写错会导致解析失败,转换结果无法生成。
延伸阅读
- 官方帮助文档总览:decoder_fn_v2.md(含 Converter 输出与 Decoder 输出的完整字段要求及示例目录)
- 简单形态对照:simple_converter_output.md
- 解码器扩展形态对照:extended_decoder_output.md
- 解码器简单形态对照:simple_decoder_output.md
- 二进制示例:simple-binary/converter_output.md
- JSON 示例:simple-json/converter_output.md
- 核心实现:AbstractUplinkDataConverter.java、DedicatedConverterUtil.java、DedicatedScriptUplinkDataConverter.java、JsonConverter.java
- 物联网
- 后端
- 数据可视化
- 消息队列
【免费下载链接】thingsboard
All-in-one IoT Platform - Device management, data collection, processing and visualization.
相关推荐
ThingsBoard Uplink Decoder 进阶输出格式:在解码结果中携带 label、customer 与 group 的完整 JSON 结构指南
ThingsBoard Uplink Decoder 进阶输出格式:在解码结果中携带 label、customer 与 group 的完整 JSON 结构指南
物联网后端数据可视化消息队列ThingsBoard JSON Payload 解码实战:TBEL Uplink Converter 解析 simple-json 示例
ThingsBoard JSON Payload 解码实战:TBEL Uplink Converter 解析 simple json 示例 导读 本文以 Thi
物联网后端数据可视化消息队列ThingsBoard TBEL 二进制解码实战:Simple Binary Uplink Converter 解析教程
ThingsBoard TBEL 二进制解码实战:Simple Binary Uplink Converter 解析教程 ThingsBoard 数据转换器(D
物联网后端数据可视化消息队列
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考