ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ThingsBoard TBEL 解码函数实战:用 parseBytesToInt 解析二进制设备上行报文(simple-binary 示例详解)

ThingsBoard TBEL 解码函数实战:用 parseBytesToInt 解析二进制设备上行报文(simple-binary 示例详解) 物联网后端数据可视化消息队列【免费下载链接】thingsboardAll-in-one IoT Platform - Device management, data collection, processing and visualization.项目地址https://gitcode.com/GitHub_Trending/th/thingsboard点击查看免费下载导读本文围绕 ThingsBoard 数据转换器Uplink Data Converter中 TBEL 解码函数的典型场景——解析二进制设备上行报文展开以仓库内置帮助文档simple-binary示例为骨架完整讲解报文逐字节拆解、parseBytesToInt的用法与字节序语义、解码函数返回值结构以及平台对解码输出的全部约束。读完本文你将能独立编写一个把 8 字节二进制帧解析为设备名、电量、温度、血氧饱和度的可运行 TBEL 解码函数并理解其在 HTTP、MQTT、LoRaWAN 等集成中的实际应用方式。一、示例场景一条 8 字节的二进制上行帧在 ThingsBoard 的集成Integration体系中Uplink Data Converter 负责把来自设备或第三方网络如 SigFox、LORIOT、ChirpStack、The Things Stack的上行消息解析并转换为平台通用格式。当设备以二进制协议上报数据时载荷就是一串原始字节需要用 TBEL 内置的字节解析函数把它们切分、解释成有业务含义的字段。本文的主角simple-binary示例描述了这样一个设备体温计/血氧仪每次上报 8 个字节依次包含字节偏移长度含义本示例取值04 字节设备序列号big-endian 整数00BC614E→ 十进制1234567841 字节电池电量5F→ 十进制9552 字节温度值×100 后的整数0E4C→ 十进制3660→ 实际温度36.6℃71 字节血氧饱和度63→ 十进制99对应的 HEX 报文为00BC614E5F0E4C63对应的 Base64 表示为ALxhTl8OTGMBase64 形式在转换器或集成开启 debug 时会出现在调试事件Debug Events中方便排查报文内容。上述报文拆解、HEX/Base64 两种表达以及字段对照表均出自仓库帮助文档 simple-binary 示例的 payload 说明。二、解码函数源码逐行剖析完整示例代码位于 simple-binary 示例的 decoder_fn.md核心逻辑如下// Use first 4 bytes as device name var deviceName SN- parseBytesToInt(payload, 0, 4); var result { deviceName: deviceName, deviceType: Thermometer, telemetry: { // Use 5th byte as a battery level battery: parseBytesToInt(payload, 4, 1), // Use bytes 6 and 7 as a temperature temperature: parseBytesToInt(payload, 5, 2) / 100.0, // Use 8th byte as a saturation level saturation: parseBytesToInt(payload, 7, 1) } }; return result;逐行解读parseBytesToInt(payload, 0, 4)—— 从字节数组payload的第 0 个字节起连续读取 4 个字节按大端序big-endian解释为整数得到设备序列号12345678。前缀SN-使设备名变为SN-12345678既直观又可读。parseBytesToInt(payload, 4, 1)—— 读取第 5 个字节偏移 4得到电量95。parseBytesToInt(payload, 5, 2) / 100.0—— 读取第 6、7 两个字节偏移 5长度 2得到3660再除以 100 还原出真实温度36.6。这是典型的“定点数”编码设备端把浮点温度放大 100 倍后以整数传输解码端再缩放回来避免浮点字节序问题。parseBytesToInt(payload, 7, 1)—— 读取第 8 个字节偏移 7得到饱和度99。函数返回包含deviceName、deviceType与telemetry的 JSON 对象作为转换器输出。提示文档代码中出现的{:code-stylemax-height: 500px;}与{:copy-code}是 UI 帮助弹窗的渲染标记并非 TBEL 语法实际编写转换器时无需保留。三、预期输出平台统一 JSON 格式解码函数运行后得到的结果与文档 output.md 完全一致{ deviceName: SN-12345678, deviceType: Thermometer, telemetry: { battery: 95, temperature: 36.6, saturation: 99 } }平台收到该结果后会按deviceName租户范围内唯一查找设备SN-12345678若不存在且集成开启了“允许创建设备/资产”选项则自动创建设备类型为Thermometer。telemetry中的三个键值对将作为时序数据time-series data写入默认使用服务器时间为时间戳详见下文第五节。四、解码函数签名与输出格式的完整约束在动手写自己的解码函数前需要了解平台对函数签名与返回值的硬性要求。这些约束在通用帮助文档 TBEL 解码函数说明decoder_fn.md 中有系统化描述。函数签名function Decoder(payload, metadata): object | object[]payloadany包含集成上报原始消息的字节数组。集成产生的 payload 内容类型可能是 JSON、TEXT 或 BINARYBase64但内容类型只是调试事件存储的提示不影响解码函数的行为——解码函数收到的始终是字节数组可用decodeToString、decodeToJson把字节数组转为字符串或 JSON 对象后再处理。metadata{[key: string]: string}集成消息携带的键值元数据可在每个集成的详情中配置额外的 metadata 字段供解码函数读取使用。返回值的必须与可选字段返回值必须是合法 JSON且满足必须包含deviceNamedeviceType或assetNameassetType成对属性用于标识设备/资产名称在租户范围内唯一。平台用它们查找已有实体找不到且集成允许创建时自动新建。实践中常用 DevEUI、MAC 地址等唯一标识作为设备名。可选attributes对象为设备/资产设置的服务端属性集合。可选telemetry对象/数组设备/资产的时序数据。可选customerName自动把设备归属到指定客户客户不存在时自动创建仅在该设备/资产由当前集成创建时生效已存在的实体忽略此参数。可选groupName自动把设备加入实体组组默认创建在租户范围若同时提供了customerName则创建在客户范围同样仅在实体由当前集成首次创建时生效。可选deviceLabel/assetLabel非唯一的用户友好标签可在仪表盘上替代设备名展示。若需自定义时间戳可在 telemetry 数据中加入平台约定的时间戳字段格式为Unix epoch 毫秒否则使用服务器时间。另外解码函数可以返回对象数组每个元素描述一台设备/资产且每台设备可携带多条不同时间戳的时序数据点适用于一个上行消息包含多设备数据的中继/网关场景。五、decoder_v2 变体attributes/telemetry 结构与显式时间戳除上述 v1 扁平结构外ThingsBoard 还提供了 decoder_v2 风格的同主题示例同样解析“序列号 电量 温度 饱和度”的二进制帧但返回值采用更结构化的格式并支持显式时间戳。见 decoder_v2/simple-binary 的 decoder_fn.mdfunction decodePayload(input) { var result { attributes: {}, telemetry: {}}; result.attributes.sn parseBytesToInt(input, 0, 4); var timestamp metadata.ts; var values {}; values.battery parseBytesToInt(input, 4, 1); values.temperature parseBytesToInt(input, 5, 2) / 100.0; values.saturation parseBytesToInt(input, 7, 1); result.telemetry { ts: timestamp, values: values }; return result; } var result decodePayload(payload); return result;该变体对应的报文为01ed03335f0e4c63Base64Ae0DM18OTGM其中01ED0333对应序列号32310067其余字段含义与 v1 相同。解码输出见 decoder_output.md{ attributes: { sn: 32310067 }, telemetry: { ts: 1684478801936, values: { battery: 95, temperature: 36.6, saturation: 99 } } }可见 decoder_v2 的约束与 v1 不同主要体现在attributes为必填且至少包含一个键值对telemetry为必填对象或数组至少包含一条数据telemetry.ts取自metadata.ts集成注入的消息时间戳即显式时间戳为 Unix epoch 毫秒实体名、类型、设备档案profile、客户、组、标签等可通过转换器的预配置设定也可在解码函数中覆写。最终 Converter 输出会把预配置信息与解码结果合并见 converter_output.md其形态包含entityType: DEVICE、name、profile、合并后的telemetry与attributes其中 LoRaWAN 网关元数据rssi、snr、fCnt、dr、frequency、eui等也被一并合入——这正是前面所说的“LoRaWAN 网络服务器常把二进制设备载荷连同 RSSI/SNR 等元数据一起包装成 JSON”的真实场景。六、parseBytesToInt 等 TBEL 内置函数的源码级定义parseBytesToInt并非 JavaScript 原生函数而是 ThingsBoard 向 TBEL 运行时注入的内置工具函数。其精确定义在 UI 前端源码 tbel-utils.models.ts 中parseBytesToInt(data, offset, length, bigEndian)参数说明来自源码定义datalist | array待解析的字节列表/数组即传入的payload。offsetnumber可选起始字节索引默认 0。lengthnumber可选要解析的字节数最大 4即最大 32 位整数。bigEndianboolean可选是否按大端序解释默认 true。该函数返回解析后的整数number。与之配套的字节解析函数还有parseBytesToLong(data, offset, length, bigEndian)解析长整数length最大 864 位适用于需要 8 字节整数的设备字段如计数器、时间戳定义见 tbel-utils.models.ts。parseBytesToFloat(data, offset, length, bigEndian)按 IEEE 754 格式解析为浮点数定义见 tbel-utils.models.ts。parseHexToLong(hex, bigEndian)/parseBigEndianHexToLong(hex)/parseLittleEndianHexToLong(hex)从十六进制字符串直接解析长整数可指定字节序适用于 payload 中内嵌 HEX 字符串字段的协议。decodeToString(data)把字节列表转换为字符串见 tbel-utils.models.ts。decodeToJson(data)把 JSON 字符串或字节列表解析为 JSON 对象见 tbel-utils.models.ts。stringToBytes、bytesToBase64等用于编码方向的工具函数如 encoder 场景。从源码结构看这些内置函数统一定义于TBEL_UTILS等模型常量中在加载 TBEL 脚本时注入执行环境因此它们与 ECMAScript 标准函数一样可直接在 Decoder/Encoder 中调用。七、实战要点与调试建议先定协议后写代码二进制解码的第一步永远是逐字节定义字段表偏移、长度、缩放系数、字节序就像示例文档在 payload 说明里对00BC614E、5F、0E4C、63逐段标注的做法。字节序保持一致parseBytesToInt默认大端序。若设备端按小端序发送如常见的01ED0333类帧需显式传入falseparseBytesToInt(payload, 0, 4, false)。定点数缩放遇到“温度 ×100”“湿度 ×10”这类协议解码时记得除回缩放因子避免把整数值误当真实测量值。善用元数据LoRaWAN 网络服务器的 JSON 包装中通常带有RSSI、SNR、frequency等元数据可像 decoder_v2 示例那样通过metadata读取并合并进最终输出。开启 Debug 验证在转换器或集成上启用 debug 后调试事件中会记录 Base64 形式的原始载荷与解码输出可对照 payload/expected output 逐步验证字节解析是否正确。设备唯一性设备名在租户范围内唯一示例用序列号加SN-前缀生成稳定名称是避免重复创建设备的良好实践需要仪表盘友好展示时再使用deviceLabel。八、本文引用的仓库文档与源码清单示例主文档simple-binary/decoder_fn.md报文拆解说明simple-binary/payload.md预期输出simple-binary/output.md解码函数通用约束converter/tbel/decoder_fn.mddecoder_v2 规范converter/tbel/decoder_fn_v2.mddecoder_v2 二进制示例decoder_v2/simple-binary/decoder_fn.mdTBEL 内置函数定义tbel-utils.models.ts仓库中同目录还提供了 Simple JSON、Simple CSV、JSON with multiple hex encoded values、Use metadata fields 等更多解码示例见 examples/decoder 目录可作为编写不同内容类型转换器时的参考模板。赞分享物联网后端数据可视化消息队列【免费下载链接】thingsboardAll-in-one IoT Platform - Device management, data collection, processing and visualization.项目地址https://gitcode.com/GitHub_Trending/th/thingsboard点击查看免费下载相关推荐ThingsBoard 上行数据解码实战simple-binary 二进制报文解码与输出示例深度解析ThingsBoard 上行数据解码实战simple binary 二进制报文解码与输出示例深度解析 本文基于 ThingsBoard 官方帮助文档中 sim物联网后端数据可视化消息队列Open edX AuthZ 集成指南openedx.core.djangoapps.authz 应用与 authz_permission_required 装饰器实战Open edX AuthZ 集成指南 openedx.core.djangoapps.authz 应用与 authz_permission_required物联网后端数据可视化消息队列使用 visx/wordcloud 构建 React 词云图API 全解析与实战指南使用 visx/wordcloud 构建 React 词云图API 全解析与实战指南 词云Word Cloud是一种以文字大小、颜色直观反映文本数据权重物联网后端数据可视化消息队列上一篇mdx-bundler组件替换魔法如何自定义MDX渲染行为的完整教程下一篇flutter-mapbox-gl 地图插件推荐创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表