ThingsBoard TBEL 解码函数实战:用 Simple JSON 示例编写 Uplink Data Converter Decoder

发布时间:2026/10/2 13:38:34

ThingsBoard TBEL 解码函数实战:用 Simple JSON 示例编写 Uplink Data Converter Decoder 物联网后端数据可视化消息队列【免费下载链接】thingsboardAll-in-one IoT Platform - Device management, data collection, processing and visualization.项目地址https://gitcode.com/GitHub_Trending/th/thingsboard点击查看免费下载本文围绕 ThingsBoard 官方帮助文档中的Simple JSON Decoder 示例位于 decoder_fn.md完整讲解 TBELThingsBoard Expression Language解码函数的写法、输入输出契约与底层机制。读完本文你将掌握如何把一条 JSON 格式的 LoRaWAN/设备上行消息解析为平台标准格式attributes telemetry并理解 Decoder 输出与 Converter 输出之间的差异与覆盖规则可直接照搬到自己的集成Integration配置中使用。一、Uplink Data Converter 与 Decoder 函数在 ThingsBoard 中的定位在 ThingsBoard 中Uplink Data Converter上行数据转换器负责把来自各种集成Integration如 LORIOT、ChirpStack、TTN 等的上行消息解析、转换成平台统一的数据格式。转换器由两部分组成一部分是预配置项如实体类型、名称、profile、customer、group 等另一部分是Decoder 解码函数——一段用 TBEL 语言编写的 JavaScript 函数用于解析原始 payload 并产出结构化结果。官方帮助文档 decoder_fn_v2.md 给出了标准函数签名function payloadDecoder(payload, metadata): object | object[]两个入参的含义如下payloadany集成消息中携带的编码数据字节数组。默认以二进制Base64形式传入但部分集成也会直接传入已经解码的 JSON 数据。本示例中的 payload 即为 JSON 对象。metadata{[key: string]: object}来自集成消息的键值对元数据通常包含ts毫秒时间戳、设备标识如eui、信号质量如rssi、snr等。每个集成的详情页中还可以配置额外元数据。函数的返回值有两条下游消费路径Decoder 输出解码函数直接返回的结果是未经任何附加配置处理的“纯解码”数据必须是一个合法的 JSON 对象。Converter 输出预配置项与解码函数结果的合并体。预配置定义了默认的键与值解码函数可以按需覆盖这些键实现“默认配置 动态数据”的灵活合并。本文的 Simple JSON 示例正是演示这一机制的最小闭环JSON payload 输入 → TBEL 解码 → Decoder 输出 → Converter 输出。二、示例输入JSON Payload 与集成 Metadata2.1 JSON 格式的原始负载示例对应的输入 payload 见 payload.md{ sn: 32310067, battery: 95, temperature: 36.6, saturation: 99 }这是一个非常典型的设备上报数据sn设备序列号、battery电量百分比、temperature温度浮点数、saturation饱和度百分比。解码函数的目标就是把这类“裸数据”整理成平台认可的 attributes 与 telemetry 结构。2.2 集成元数据 Metadata解码函数运行时的metadata对象本示例取自 LORIOT 集成见 metadata.md常见键及其含义如下KeyValue说明integrationNameTest LORIOT集成名称includeGatewayInfofalse是否包含网关信息rssi-21接收信号强度指示dBmseqno3040序列号fPort85LoRaWAN FPortdata01ed03335f0e4c63原始上行数据十六进制toa206Time on Air空中占用时间ackfalse是否应答battery94设备电量drSF9 BW125 4/5数据速率Spreading Factorfrequency867500000载波频率Hzofflinefalse是否离线snr10信噪比dBeui1000000000000001设备 EUIcmdrx命令类型接收fCnt2LoRaWAN 帧计数ts1684478801936毫秒时间戳其中metadata.ts是本示例中解码函数使用的关键字段——它作为遥测数据的时间戳保证时间戳由集成侧消息到达时间提供而非解码函数自行new Date()生成从而保证时序一致性。三、TBEL 解码函数逐行拆解完整的解码函数见 decoder_fn.mdfunction decodePayload(input) { var result { attributes: {}, telemetry: {}}; var data decodeToJson(input); var timestamp metadata.ts; result.attributes.sn data.sn; var values {}; values.battery data.battery; values.temperature data.temperature; values.saturation data.saturation; result.telemetry { ts: timestamp, values: values }; return result; } var result decodePayload(payload); return result; /** Helper function to decode raw payload bytes to string**/ function decodeToString(payload) { return String.fromCharCode.apply(String, payload); } /** Helper function to decode raw payload bytes to JSON object**/ function decodeToJson(payload) { return JSON.parse(decodeToString(payload)); }3.1 关键步骤说明步骤一初始化输出结构。var result { attributes: {}, telemetry: {} };先声明一个同时包含attributes与telemetry的容器。这是 Decoder 输出的核心骨架二者缺一不可详见第四节。步骤二解析 JSON。var data decodeToJson(input);将传入的 payload 解析为可读写的 JavaScript 对象。这里的decodeToJson是 TBEL 内置工具函数它既接受 JSON 字符串也接受字节列表先按字符转换为字符串再JSON.parse。这一点可以从 TBEL 编辑器自动补全定义 tbel-utils.models.ts 中得到印证——编辑器内建补全中decodeToJson的签名是Parses a JSON string or converts a list of bytes to a string and parses it as JSON.入参类型为string | list。因此即使集成传入的是 Base64 解码后的字节数组同一段代码也能正确工作。步骤三取时间戳。var timestamp metadata.ts;从元数据中读取毫秒级时间戳本示例为1684478801936直接作为遥测数据点的时间基准。若集成未提供ts也可以回退为new Date()但在有真实到达时间的场景下应优先使用metadata.ts。步骤四写属性attributes。result.attributes.sn data.sn;将设备序列号写入属性平台会将其保存为设备/资产的属性键值对。步骤五组装遥测telemetry。把battery、temperature、saturation三个键值放入values对象并与ts一起构成标准遥测点result.telemetry { ts: timestamp, values: values };步骤六执行并返回。脚本末尾的var result decodePayload(payload); return result;是 TBEL 脚本的固定执行模式定义处理函数后立即调用并返回结果。文件末尾附带的decodeToString/decodeToJson辅助函数既是对“字节数组 ↔ 字符串 ↔ JSON”转换链路的直观示意也可以在实际脚本中直接复用因为二者本身就是 TBEL 内建函数示例中重复定义仅用于教学演示。3.2 时间戳的两种表示值得注意本示例中result.telemetry是一个对象{ ts, values }而官方模板 js-decoder-v2.raw 中telemetry则是对象数组[{ ts, values }]。这两种写法平台都接受——官方文档明确要求 telemetry 是“object or array”对象或数组多数据点批量上报时应使用数组形式output.telemetry [{ ts: 1730898982391, values: { telemetryKey: telemetryValue } }];四、Decoder 输出的结构约束与可选覆盖项解码函数产出的Decoder 输出本示例见 decoder_output.md如下{ attributes: { sn: 32310067 }, telemetry: { ts: 1684478801936, values: { battery: 95, temperature: 36.6, saturation: 99 } } }按 decoder_fn_v2.md 的规定该输出必须满足以下要求属性必填/可选约束attributes必填保存设备/资产详情至少包含一个键值对不允许为空对象telemetry必填对象或数组保存设备/资产的时间序列数据至少包含一个数据点name可选可覆盖在租户范围内唯一标识设备/资产常用eui、MAC 地址等硬件标识平台据此查找既有实体若未找到且集成允许创建实体则新建实体type可选可覆盖必须是Asset或Device决定实体类型分类profile可选可覆盖关联的设备/资产配置文件Profile若预配置与解码函数均未设置自动应用默认值defaultcustomer可选可覆盖按名称自动归属客户不存在则创建仅在当前集成创建实体时生效实体已存在则忽略group可选可覆盖自动加入指定实体组不存在则创建默认在租户范围创建若同时指定customer则在客户下创建仅在首次创建时生效label可选可覆盖非唯一的用户友好标签可用于仪表盘展示仅在当前集成创建时生效对照本示例Decoder 输出仅返回了必填的attributes.sn和telemetrybattery/temperature/saturation未返回name/type/profile等可选属性——它们完全交给预配置去兜底。这种“解码函数只关注数据解析、实体元信息交给预配置”的分工正是官方推荐的最小化写法。五、从 Decoder 输出到 Converter 输出预配置如何参与合并Converter 输出本示例见 converter_output.md才是真正落到平台数据模型中的最终 JSON{ entityType: DEVICE, name: Device 1000000000000001, profile: default, telemetry: { ts: 1684478801936, values: { battery: 95, temperature: 36.6, saturation: 99, rssi: -21, data: 01ed03335f0e4c63, snr: 10, fСnt: 2 } }, attributes: { sn: 32310067, fPort: 85, dr: SF9 BW125 4/5, frequency: 867500000, eui: 1000000000000001 } }逐项对比可以清晰地看出两层合并逻辑预配置层Converter 配置区提供了entityType: DEVICE、name: Device 1000000000000001、profile: default。这些在解码函数中完全没有出现全部来自转换器的预配置字段。解码结果层Decoder 输出贡献了attributes.sn与telemetry.values中的battery、temperature、saturation。元数据透传层rssi、data、snr、fCnt等遥测值以及fPort、dr、frequency、eui等属性来自集成消息的 metadata 或预配置的默认值——说明转换器还可以把元数据与预配置键合入最终输出。这也印证了 decoder_fn_v2.md 的机制说明预配置定义了默认键值解码函数可以覆盖同名键最终 JSON 是“预配置设置 动态解码数据”的无缝融合。更完整的示例额外包含label、customer、group字段以及多数据点数组形式的 telemetry可参考 extended_converter_output.md 与 extended_decoder_output.md。六、TBEL 内置工具函数编辑器补全中能直接使用的转换能力在 ThingsBoard 的 TBEL 编辑器中解码函数可以自由调用一批内建工具函数这些函数在 tbel-utils.models.ts 中注册为编辑器的自动补全项。与本示例直接相关的有decodeToString(data)将字节列表转换为字符串list → string。decodeToJson(data)将 JSON 字符串或将字节列表先转字符串再解析为 JSON 对象string | list → object。此外还有大量解析与转换函数可用于更复杂的二进制或十六进制场景例如整数/长整型解析parseInt(str, radix)、parseLong(str, radix)、parseBytesToInt(data, offset, length, bigEndian)长度上限 4、parseBytesToLong(...)长度上限 8十六进制解析parseHexToInt(hex, bigEndian)、parseLittleEndianHexToInt(hex)、parseBigEndianHexToInt(hex)浮点/双精度解析parseFloat(str, radix)、parseBytesToFloat(...)、parseBytesToDouble(...)、parseBytesIntToFloat(...)字节与编码转换hexToBytes(hex)、bytesToHex(data)、base64ToHex(str)、hexToBase64(hex)、base64ToBytes(str)、base64ToBytesList(str)、bytesToBase64(data)、stringToBytes(str, charset)、bytesToString(data, charset)数值处理toFixed(value, precision)、toInt(value)、printUnsignedBytes(data)异常与辅助raiseError(str)、isBinary(data)、toFlatMap(json, excludeKeys, pathInKey)。这些补全定义同时给出了参数的类型、是否可选与默认值例如parseBytesToInt的offset默认 0、bigEndian默认 true是排查解析结果不正确时的重要参考。七、在 ThingsBoard UI 中套用本示例的实操步骤在 ThingsBoard 中进入Integrations → 选择你的集成 → Uplink converter打开转换器编辑页。将上文第三节的完整 TBEL 脚本复制到Decoder function解码函数编辑区。编辑器自带语法高亮与内建函数自动补全。在转换器页面的Converter预配置区设置默认实体信息entityType选DEVICEname填如Device 1000000000000001profile填default如有需要可补充label、customer、group。使用编辑器内置的Test测试功能把第二节的 JSON payload 粘贴到输入框若集成分发字节数组则使用 Base64/十六进制形式并模拟 metadata至少包含ts运行后分别检查Decoder output与Converter output两个结果视图是否符合第四节、第五节的预期 JSON。验证通过后保存转换器重启/重新保存集成使其生效即可在设备列表中看到自动创建或匹配已有的实体及其属性与遥测数据。八、同类示例对比Simple Binary 与 Simple JSON 的写法差异同一套“sn battery temperature saturation”业务语义在 simple-binary/decoder_fn.md 中则面对二进制 payload解码逻辑从JSON.parse变成了按字节偏移取值result.attributes.sn parseBytesToInt(input, 0, 4); // 前 4 字节 → 序列号 values.battery parseBytesToInt(input, 4, 1); // 第 5 字节 → 电量 values.temperature parseBytesToInt(input, 5, 2) / 100.0; // 第 6~7 字节 → 温度除以 100 values.saturation parseBytesToInt(input, 7, 1); // 第 8 字节 → 饱和度对比可见两种示例共享完全一致的输出契约attributestelemetry{ts, values}结构、metadata.ts取时间戳、末尾decodePayload(payload)并 return差别只在 payload 的解码方式JSON 场景用decodeToJson二进制场景用parseBytesToInt。因此当你面对新的集成协议时只需要替换中间“如何把原始字节变成业务字段”的一段代码外围的容器结构与返回方式可以直接复用本示例。两个示例连同 payload、metadata、decoder_output、converter_output 的完整闭环文件都位于 examples/decoder_v2 目录下可作为对照学习的完整参考集。小结本文以官方 Simple JSON Decoder 示例为骨架完整还原了 ThingsBoard Uplink Data Converter 的解码链路JSON payload 与 metadata 输入 →decodeToJson解析 → attributes/telemetry 结构组装 → Decoder 输出 → 与预配置合并为最终 Converter 输出。通过仓库内的 decoder_fn_v2.md函数签名与输出约束、tbel-utils.models.ts内建函数补全、js-decoder-v2.raw官方空白模板以及 simple-binary二进制对照示例你可以将这套“结构固定、解析可变”的写法规整地迁移到任意集成场景中快速实现设备数据接入。赞分享物联网后端数据可视化消息队列【免费下载链接】thingsboardAll-in-one IoT Platform - Device management, data collection, processing and visualization.项目地址https://gitcode.com/GitHub_Trending/th/thingsboard点击查看免费下载相关推荐ThingsBoard JSON Payload 解码实战TBEL Uplink Converter 解析 simple-json 示例ThingsBoard JSON Payload 解码实战TBEL Uplink Converter 解析 simple json 示例 导读 本文以 Thi物联网后端数据可视化消息队列ThingsBoard TBEL 解码器函数实战以 simple-json 示例拆解 Uplink 数据转换ThingsBoard TBEL 解码器函数实战以 simple json 示例拆解 Uplink 数据转换 导读 本文围绕 ThingsBoard 集成框架物联网后端数据可视化消息队列ThingsBoard TBEL 二进制解码实战Simple Binary Uplink Converter 解析教程ThingsBoard TBEL 二进制解码实战Simple Binary Uplink Converter 解析教程 ThingsBoard 数据转换器D物联网后端数据可视化消息队列上一篇Langchain-Chatchat 服务端公共工具层 utils.py 全解析异步协作、模型客户端工厂、统一响应模型与离线文档下一篇3分钟搞定3D地形建模Heightmapper免费高度图工具终极指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/10/2 14:38:38

Redis 接入 AI 能力全解析:向量检索、会话管理与多 Agent 协作实践

1. 从一条更新日志说起:Redis 接入 AI 到底意味着什么 前几天刷社区的时候看到一条消息,说 Redis 官方在最新版本里正式把 AI 相关的能力做进了核心链路。第一反应是"又一个蹭热点的营销词",但把更新说明和几个相关提案翻完之后&am…

2026/10/2 14:38:38

6DOF-GraspNet六自由度抓取:从点云到机械臂位姿估计实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/2 14:38:38

RK平台YTPHY驱动移植全流程:解压验包到设备树避坑指南

简介:面向RK3568平台的YT8521S以太网PHY驱动补丁包,主要服务于嵌入式Linux开发者和内核驱动适配工程师,解决YT8521S在RK3568平台上驱动缺失或无法正常识别的问题,省去从零移植和调试的重复工作。压缩包共11个文件,主要…

2026/10/2 14:38:38

RK平台YTPHY PHY驱动移植实战:从拆包、配置到验证

简介:面向RK3568平台的YT8521S以太网PHY驱动补丁,专为嵌入式驱动开发与系统移植工程师设计,重点是解决YT8521S在RK3568平台上的驱动适配与PHY芯片调试问题。资源按kernel4.19与kernel4.4两个内核版本分目录组织,各自包含PHY驱动源…

2026/10/2 14:38:38

舰船卫星图目标检测数据集:VOC格式解析与YOLOv8训练实操

简介:舰船卫星可见光目标检测数据集(第一批)正式发布,面向计算机视觉、遥感图像分析与目标检测算法研究者,可用于模型训练、算法验证与性能评估。数据集提供1000张10241024像素的RGB彩色卫星图像,覆盖舰船与…

2026/10/2 8:16:46

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/10/1 17:09:46

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 10:48:55

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/2 0:02:57

PWN入门:从栈溢出原理到ROP链实战

1. 这不是“学PWN”,是重新理解你每天敲的每一行C代码我第一次在CTF赛场上写出能控制程序流的exp时,手抖得连gdb的c命令都输错三次。那道题只有23行C代码,一个gets()调用,一个printf(),一个return——它甚至没开NX&…

2026/10/2 0:02:57

Windows下cudaMallocHost显存占用之谜:WDDM与TCC模式差异及优化方案

1. 一个反直觉的显存占用现象第一次在 Windows 上看到cudaMallocHost把显存吃掉的时候,我的反应是打开任务管理器反复确认了三遍。明明调用的是主机端锁页内存分配,按 CUDA 文档的说法,这块内存应该落在系统 RAM 里,跟 GPU 的显存…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑