如果给你一个硬件设备,在没有文档、没有前开发人员的情况下,你会怎么处理?
是的,在前些天我经历了这么一次,下面会将我自己处理这件事情的整个流程给记录下来。
当接到这个需求的时候,大家的反应应该都是一样的,首先是张嘴就来:“有文档吗?”。
嘿,巧了,没有。不过没关系,咱可以先自己研究一下,至少咱得知道最终目的是什么。
我们现在有两个设备,分别是蓝牙心率手环和蓝牙网关,需要做的事情也很简单,就是将手环的各项指标存入数据库。听起来是不是很简单,那咱就开始吧。
文档
首先没有文档那咱就找文档呗,我是先在硬件设备上寻找厂家 Logo,虽然已经被划掉了,但是还是能看到一些信息,比如厂家的名称,然后在某度搜索厂家的名称,找到了厂家的官网。
我们点开 Introduction 后了解到这个手环的型号是 Imyfit C5,这是一项很大的收获。
咱继续在官网中寻找看到了 Download 菜单,正当我以为这样就结束了的时候,我发现厂家的官网上并没有提供任何的文档(提供了文档下载页面但下载地址并没有),这下我就懵了,我该怎么办呢?
我抄起键盘就是一顿咔咔乱打给厂家发一份邮件,说了一堆我想要的东西,然后就等待回复了。
这时候我想到了万能的淘宝,于是我打开我的App直接搜索关键字,结果是什么鬼啥也没有啥也不是(这里其实写这篇记录的时候我又搜索了一次点开了商家tab是找到了,但给客服发送消息并没有得到回复)
虽然没有得到回复,但是我还是继续尝试在百度搜索。
功夫不负有心人,居然找到了官方文档,咱就是说,这个东西就不能链接在官网里吗。
这下好了,一顿翻阅后,找到了我们需要的东西: 物联网网关接口。
点开文档后我们就可以看到网关的接口文档了,于是我就跟着文档一步一步的操作,这里就成功的将网关的MQTT客户端配置好了。
数据上报
到目前为止我们的网关已经配置好了,接下来就是将手环的数据上报到网关,然后网关再将数据上报到我们的服务器。
这里由于我在前面踩了个坑,使用 Mistep App 连接手环过手环,导致手环的数据广播并没有生效,一顿折腾自己的 MQTT 环境却没发现问题,
但是呢,到了下班点我还是得下班的,有什么事情睡一觉再说。
第二天我突然想到了 Mistep 这件事,我尝试解除绑定后再测试数据广播。
嘿,还真成功了。(看吧,没有什么事情是睡一觉解决不了的)
我们用一个客户端去订阅一下消息看看吧
数据大概就是这个样子吧,我们主要关注的就是pack 字段,它就是我们手环上报过来的16进制数据。
协议解析
这里就来到了紧张又刺激的编码环节了。
还记得上面我们找到的文档吗?里面有一个 “终端局域广播接口 -> 蓝牙终端常规广播API“ 文档。
看到这么多协议,我们到底应该使用哪一个呢?
还记得前面我们打开的 Introduction 吗?里面是不是有一个设备型号 C5 呢?
那好,那就试试 终端C5/C5S 这个协议吧。
根据图中的表格我们可以知道每个字节对应的消息类型,
然后我们就可以根据这个表格来解析我们的数据了。
(但是我没有看懂”5|bit6“是什么意思,不过没关系咱用不上这个数据)
直接上核心代码
// 将16进制数据包转换为字节数组
byte[] bytes = ByteBufUtil.decodeHexDump("578B000000FF00000000049D67356450003357");
System.out.println(bytes.length);
// 使用 Netty 的 ByteBuf 来读取数据
ByteBuf buf = Unpooled.wrappedBuffer(bytes);
System.out.println("1-心率值: " + buf.readUnsignedByte());
System.out.println("2-4-步数低字节: " + buf.readMediumLE());
System.out.println("5-动静状态: " + buf.readByte());
System.out.println("6-睡眠状态: " + buf.readUnsignedByte());
System.out.println("7-血压舒张压: " + buf.readUnsignedByte());
System.out.println("8-血压收缩压: " + buf.readUnsignedByte());
System.out.println("9-血氧: " + buf.readUnsignedByte());
System.out.println("10-保留: " + buf.readUnsignedByte());
System.out.println("11-广播版本: " + buf.readUnsignedByte());
System.out.println("12-15-UTC: " + buf.readIntLE());
System.out.println("16-静息心率: " + buf.readUnsignedByte());
System.out.println("17-保留: " + buf.readUnsignedByte());
System.out.println("18-电池电量: " + buf.readUnsignedByte());
System.out.println("19-异或校验值: " + buf.readUnsignedByte());
总结
大家可以看到,编码环节其实只占用了很小的一部分,大部分时间都在为历史原因而折腾,
所以大家在编码环节尽可能的保留开发文档,给后人减少一些困难。
这里我想说的是,如果你在做一个项目的时候,遇到了一些问题,不要着急,
先把问题记录下来,然后再去解决,这样你就可以把时间花在更重要的事情上。
(此段来自 Github Copilot 自动生成)