不改设备固件,直接让成品LoRaWAN门磁接入腾讯云物联网开发平台

这一生的挚爱 提交于 2020-08-18 07:24:44

前言

在此前的新闻方案中有看到,腾讯云利用其物联网开发平台的设备数据引擎,硬件厂商不用修改设备固件既可以快速对接物联网平台。

腾讯云之所以能快速对接多家设备厂商开发的LoRaWAN智能门磁产品,得益于物联网开发平台的设备数据解析引擎,硬件合作伙伴只需通过编写云端脚本,将其设备协议转化成云平台统一的门磁数据模版。
因此腾讯云在短时间内联合躬远科技、唯传科技、瑞兴恒方等多家优秀的LoRa®设备厂商,借助可即刻搭建、覆盖小区、信号质量稳定可靠的LoRa低功耗广域网(LPWAN),快速推出了安装便捷的隔离监控整体解决方案。

这篇笔记将演示如何实现这个快速对接操作。文中示例为瑞兴恒方 RHF1S020 智能楼宇套件中的门磁传感器,经过厂商确认,设备协议为公开协议,因此可以对外展示。

腾讯云 IoT Explorer 是腾讯云主推的一站式物联网开发平台,IoT 小能手从设备侧开发、平台功能操作、应用侧开发三个部分来进行学习分享,另外还分享了一些动手实践作品及收录官方发布的产业合作案例,帮助读者更好地理解整个开发链路。详情可点此查看

1 控制台创建 LoRa 门磁传感器

1.1 创建项目和产品

创建项目

  1. 登录 物联网开发平台控制台,选择【新建项目】。
  2. 在新建项目页面,填写项目基本信息。
    • 项目名称:输入“LoRa楼宇传感器演示”或其他名称。
    • 项目描述:按照实际需求填写项目描述。
  3. 项目新建成功后,即可新建产品。

新建产品

  1. 进入该项目的产品列表页面,单击【新建产品】。
  2. 在新建产品页面,填写产品基本信息。
    • 产品名称输入“LoRa门磁传感器”或其他产品名称。
    • 产品类型选择“门磁传感器”。
    • 认证方式选择“密钥认证”。
    • 通信方式选择“LoRaWAN”。

产品新建成功后,您可在产品列表页查看到“LoRa门磁传感器”。

创建数据模板

选择“门磁传感器”类型后,自定义产品功能。

示例中,我们仅使用最简单的默认工作模式,更多功能(如电池电量、静默时间等等)大家可以根据传感器的用户手册进行发挥。

  • 绑定 bound
  • 上报周期 period
  • 门窗打开状态 isOpen

配置 LoRaWAN 参数

在设备开发页面中,按需调整 LoRaWAN 参数配置。

1.2 设备数据解析

在设备开发页面中,按需调整 设备数据解析。由于 LoRa 类资源有限设备不适合直接传输 JSON 格式数据,使用“设备数据解析”可以将设备原始数据转化为产品JSON数据。

设备协议分析

在本示例中,采用了门磁传感器5条基础的数据消息:

  1. 上行消息 - 归属状态 0xA1

在未绑定状态, 设备会上行消息内容 A102(十六进制)到服务器,每 20s 一次,发送最大次数 9 次。同时等待接收服务器确认绑定状态更新消息。
如果用户要绑定该设备,则回复消息 A103. 设备收到该消息后, 接着会再上行 A103 确认设备切换到绑定状态。

  1. 上行消息 - 设备基础参数 0x07

设备绑定后开始正常工作即会主动上行一包基础参数信息(其他时候不再上报此基础参数信息) ,用于服务器识别和同步设备参数。

设备归属之后,会上报出周期等参数。

  1. 上行消息 - 周期上报数据帧 0x00

这个周期上报数据帧中会展现门磁传感器的开关状态。

  1. 上行消息 - 报警 0x0F

开关门的实时上报会通过报警帧来上报。

  1. 下行消息 - 设置上报周期(心跳周期) 0x9D

数据解析脚本

在上行数据解析部分,javascript示例代码如下:

function RawToProtocol(fPort, bytes) {
    const COMMAND_A1_UNBOUND = 0x02;
    const COMMAND_A1_BOUND = 0x03;
    const COMMAND_07_FLAG_MODE = 0x05;
    const COMMAND_07_LEN_MODE = 1;
    const COMMAND_07_FLAG_VER = 0x90;
    const COMMAND_07_LEN_VER = 3;
    const COMMAND_07_FLAG_DELAY = 0x9c;
    const COMMAND_07_LEN_DELAY = 2;
    const COMMAND_07_FLAG_ULPRD = 0x9d;
    const COMMAND_0f_ALERT_KIND = 0x20;
    const COMMAND_0f_ALERT_OPEN = 2;
    const COMMAND_0f_ALERT_CLOSE = 4;
    
    var data = {
        "method": "report",
        "clientToken" : new Date(),
        "params" : {}
    };
    switch (bytes[0]) {
        case 0xA1:
        if (bytes[1] == COMMAND_A1_UNBOUND) {
            data.params.bound = 0;
        } else if (bytes[1] == COMMAND_A1_BOUND) {
            data.params.bound = 1;
        }
        break;
        case 0x07:
        for (let i = 1; i < bytes.length; i++) {
            if (bytes[i] == COMMAND_07_FLAG_MODE) {
                i += COMMAND_07_LEN_MODE;
            } else if (bytes[i] == COMMAND_07_FLAG_VER) {
                i += COMMAND_07_LEN_VER;
            } else if (bytes[i] == COMMAND_07_FLAG_DELAY) {
                i += COMMAND_07_LEN_DELAY;
            } else if (bytes[i] == COMMAND_07_FLAG_ULPRD) {
                data.params.period = bytes[i+1] | (bytes[i+2] << 8);
            }
        }
        break;
        case 0x00:
        if (bytes[5] & 0x80) {
            data.params.isOpen = 0;
        } else {
            data.params.isOpen = 1;
        }
        break;
        case 0x0f:
        if (bytes[1] == COMMAND_0f_ALERT_KIND) {
            if (bytes[2] == COMMAND_0f_ALERT_OPEN) {
                data.params.isOpen = 1;
            } else if (bytes[2] == COMMAND_0f_ALERT_CLOSE) {
                data.params.isOpen = 0;
            }
        }
        break;
    }
    return data;
}

在下行数据解析部分,javascript示例代码如下:

function ProtocolToRaw(obj) {
    var data = new Array();
    var i = 0;

    data[i++] = 8;// fport=8
    data[i++] = 1;// confirmed mode
    for (var property in obj.params) {
        if ((property == "bound") && (obj.params[property] == 1)) {
            data[i++] = 0xA1;
            data[i++] = 0x03;
        }
        if (property == "period") {
            data[i++] = 0x9D;
            data[i++] = obj.params[property] & 0x00FF;
            data[i++] = (obj.params[property] >> 8) & 0x00FF;
        }
    }
    return data;
}

脚本模拟测试

这里也可以使用数据解析页面下方的模拟调试工具,如果开发更多的功能,这个模拟脚本将会提供很大帮助。

  1. 上行消息 - 归属状态 0xA1

设备原始数据为 0xA1,0x02,我们将其转化为数组,即上行模拟数据为:[161,2],填入设备上行数据的编辑框中。
点击运行,即可在模拟调试界面右侧看到结果。

  1. 上行消息 - 设备基础参数 0x07

设备原始数据:07 05 06 90 00 08 04 9c 00 00 9d 80 70 9f 13 13 31 53 30 32 30 1f 02 05 20 95
模拟测试数据:[7,5,6,144,0,8,4,156,0,0,157,128,112,159,19,19,49,83,48,50,48,31,2,5,32,149]

  1. 上行消息 - 周期上报数据帧 0x00

设备原始数据:00 06 00 00 00 10 d5
模拟测试数据:[0,6,0,0,0,16,213]

  1. 上行消息 - 报警 0x0F

设备原始数据:0f 20 02 20 02 00 00 10
模拟测试数据:[15,32,2,32,2,0,0,16]
这条消息为开门报警消息。

设备原始数据:0f 20 04 20 05 00 00 90
模拟测试数据:[15,32,4,32,5,0,0,144]
这条消息为关门报警消息。

  1. 下行消息 - 设置上报周期(心跳周期) 0x9D

模拟测试数据如下,将其填入设备下行数据的编辑框中:

{
  "params": {
    "period": 300
  }
}

1.3 创建测试设备

在设备调试页面中,单击【新建设备】,设备名为 dws001。

  • DevEUI,每一个设备有一个唯一的身份识别地址 DEVEUI, 设备据此进行 LoRaWAN 网络入网并身份识别。 信息以二维码的形式体现在产品外壳。
    本示例中为: 8cf957e0000001e7

  • AppKey,设备的密钥。
    可找套件厂家索要。

2 LoRaWAN 门磁传感器实物操作

2.1 传感器复位

根据 《门磁传感器RHF1S020DWS规格书》 中的操作说明,按照章节 3.8 进入无线固件升级, 将磁铁贴近门磁传感器(CE标志面的对面),红色LED从慢闪逐渐常亮后挪开磁铁, 即可让设备会自动重置复位。

2.2 下发门磁归属

门磁传感器在刚复位上电的一两分钟会上报3条归属状态的消息,我们必须在这点时间内尽快下发归属命令。

由于门磁传感器是 LoRaWAN Class A 类设备,这类设备不会立即下发数据,需要在有数据上行后,服务器才会向该设备下行数据。

因此我们下发了归属命令,当传感器上报归属状态消息后,即可收到我们下发的归属命令。这样门磁传感器之后才可正常使用。

注意:设备一旦归属之后,会再上报周期参数上来。如果看到平台的设备属性中没有更新“上报周期”,那说明传感器还未归属成功。此时需要重新下发归属命令,然后再复位传感器。

2.3 开关门操作

根据 《门磁传感器RHF1S020DWS规格书》 中的章节 2.10 操作说明,

磁铁部分外壳底部有一个开槽标识, 安装时请务必保证开槽的一边朝向正对传感器一边。
主体传感部分和用磁铁部分相对方位如下图, 分别安装在门(或窗)固定边和活动边,距离小于 20mm(不需紧贴) , 主体传感器部分和磁铁部分安装的表面高度基本在一个平面上。

如图所示,磁铁开槽方向贴近传感器位置,即触发了一次关门。将磁铁挪开 35 mm 以上,即可触发开门上报。

在控制台的设备调试页面下方则可以看到相应的属性做了更新。

END

That’s all


IoT小能手的其他精彩文章:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!