本文提供LoRa温湿度传感器通过Link WAN接入,同时采用阿里云物联网平台实现端到端应用。
背景信息
- 开通物联网络管理平台
完成账号的注册之后,使用账号登录Link WAN 开通服务。

- LoRa节点设备接入
- 搭建与管理网络
参见搭建与管理网络搭建和管理网络、创建节点组并添加节点。
- 配置数据流转
目前数据流转支持阿里云物联网平台、消息队列MQ两种方式,这里选择将数据流转至阿里云物联网平台,详情请参见数据接入物联网平台-1对1。
- 物联网平台LoRa节点设备接入
本章介绍如何在物联网平台开发平台上进行设备接入的开发。主要的开发内容包括:
本文以一个空气温湿度传感器为例,同时可以配置温湿度的阈值,在温湿度超出阈值时上报事件。
创建产品和设备
- 登录物联网平台控制台。
- 在左侧导航栏上选择,单击创建产品, 填写产品信息后单击保存。详情请参见数据接入物联网平台-1对1。
参数 |
描诉 |
产品名称 |
可填写任意名称 |
所属品类 |
自定义品类 |
节点类型 |
直连设备 |
连网方式 |
LoRaWAN |
入网凭证 |
从表单选择,如无可单击创建凭证 |
数据格式 |
透传/自定义 |
- 为产品添加LoRa设备。
在左侧导航栏上单击设备,参见单个创建设备添加设备。
说明 使用LoRaWAN设备的DevEUI需小写作为deviceName。
- 添加完成后,显示如下,此时设备状态为未激活。

- 数据流转已自动同步 产品创建完成后,可在Link WAN里看到自动同步的数据流转设置。
说明 在网管平台只能查阅,新增终端请移步至物联网平台维护。
平台脚本开发
- 进入产品的数据解析标签页,可以添加解析脚本。由于数据是以自定义格式透传到平台,所以需要添加脚本来解析自定义协议。
- 将下列代码添加到上图的脚本编辑区。
var ALINK_ID = "12345";
var ALINK_VERSION = "1.1";
var ALINK_PROP_POST_METHOD = 'thing.event.property.post';
var ALINK_EVENT_TEMPERR_METHOD = 'thing.event.TempError.post';
var ALINK_EVENT_HUMIERR_METHOD = 'thing.event.HumiError.post';
var ALINK_PROP_SET_METHOD = 'thing.service.property.set';
var ALINK_SERVICE_THSET_METHOD = 'thing.service.SetTempHumiThreshold';
/*
* 示例数据:
* 传入参数 ->
* 000102 // 共3个字节
* 输出结果 ->
* {"method":"thing.event.property.post", "id":"12345", "params":{"Temperature":1,"Humidity":2}, "version":"1.1"}
* 传入参数 ->
* 0102 // 共2个字节
* 输出结果 ->
* {"method":"thing.event.TempError.post","id":"12345","params":{"Temperature":2},"version":"1.1"}
* 传入参数 ->
* 0202 // 共2个字节
* 输出结果 ->
* {"method":"thing.event.HumiError.post","id":"12345","params":{"Humidity":2},"version":"1.1"}
*/
function rawDataToProtocol(bytes)
{
var uint8Array = new Uint8Array(bytes.length);
for (var i = 0; i < bytes.length; i++)
{
uint8Array[i] = bytes[i] & 0xff;
}
var params = {};
var jsonMap = {};
var dataView = new DataView(uint8Array.buffer, 0);
var cmd = uint8Array[0]; // command
if (cmd === 0x00)
{
params['Temperature'] = dataView.getInt8(1);
params['Humidity'] = dataView.getInt8(2);
jsonMap['method'] = ALINK_PROP_POST_METHOD;
}
else if (cmd == 0x01)
{
params['Temperature'] = dataView.getInt8(1);
jsonMap['method'] = ALINK_EVENT_TEMPERR_METHOD;
}
else if (cmd == 0x02)
{
params['Humidity'] = dataView.getInt8(1);
jsonMap['method'] = ALINK_EVENT_HUMIERR_METHOD;
}
else
{
return null;
}
jsonMap['version'] = ALINK_VERSION;
jsonMap['id'] = ALINK_ID;
jsonMap['params'] = params;
return jsonMap;
}
/*
* 示例数据:
* 传入参数 ->
* {"method":"thing.service.SetTempHumiThreshold", "id":"12345", "version":"1.1", "params":{"MaxTemp":50, "MinTemp":8, "MaxHumi":90, "MinHumi":10}}
* 输出结果 ->
* 0x5d0a000332085a0a
*/
function protocolToRawData(json)
{
var id = json['id'];
var method = json['method'];
var version = json['version'];
var payloadArray = [];
// 追加下行帧头部
payloadArray = payloadArray.concat(0x5d);
payloadArray = payloadArray.concat(0x0a);
payloadArray = payloadArray.concat(0x00);
if (method == ALINK_SERVICE_THSET_METHOD)
{
var params = json['params'];
var maxtemp = params['MaxTemp'];
var mintemp = params['MinTemp'];
var maxhumi = params['MaxHumi'];
var minhumi = params['MinHumi'];
payloadArray = payloadArray.concat(0x03);
if (maxtemp !== null)
{
payloadArray = payloadArray.concat(maxtemp);
}
if (mintemp !== null)
{
payloadArray = payloadArray.concat(mintemp);
}
if (maxhumi !== null)
{
payloadArray = payloadArray.concat(maxhumi);
}
if (minhumi !== null)
{
payloadArray = payloadArray.concat(minhumi);
}
}
return payloadArray;
}
// 以下是部分辅助函数
function buffer_uint8(value)
{
var uint8Array = new Uint8Array(1);
var dv = new DataView(uint8Array.buffer, 0);
dv.setUint8(0, value);
return [].slice.call(uint8Array);
}
function buffer_int16(value)
{
var uint8Array = new Uint8Array(2);
var dv = new DataView(uint8Array.buffer, 0);
dv.setInt16(0, value);
return [].slice.call(uint8Array);
}
function buffer_int32(value)
{
var uint8Array = new Uint8Array(4);
var dv = new DataView(uint8Array.buffer, 0);
dv.setInt32(0, value);
return [].slice.call(uint8Array);
}
function buffer_float32(value)
{
var uint8Array = new Uint8Array(4);
var dv = new DataView(uint8Array.buffer, 0);
dv.setFloat32(0, value);
return [].slice.call(uint8Array);
}
脚本解析下行数据的函数 protocolToRawData 中必须设定输出结果的起始三个字节(用于指定下行的端口号以及下行消息类型),否则系统会丢掉下行帧。另外,节点实际接收到的数据将不会包含起始的三个字节。
起始三字节的说明如下表所示。
Size(bytes) |
LoRa Downlink |
描述 |
1 |
DFlag |
固定为 0x5D |
1 |
FPort |
下行端口号 |
1 |
DHDR |
- 0 表示 “Unconfirmed Data Down”数据帧
- 1 表示 “Confirmed Data Down”数据帧
|
示例:0x5D 0x0A 0x00
表示:下行帧端口号为10,数据帧为Unconfirmed Data Down。
- 脚本模拟运行。
- 设备上报数据调试。
在
脚本调试区1里输入下面数据,
模拟类型选择
设备上报数据后,单击
运行按钮。
说明 000102 中的 00 表示后面的两个字节分别表示温度和湿度,01 表示温度为1摄氏度,02表示湿度为2%。
- 设备接收数据调试。
在脚本调试区1里输入以下数据,模拟类型选择设备接收数据后,单击运行按钮。
{
"method": "thing.service.SetTempHumiThreshold",
"id": "12345",
"version": "1.1",
"params": {
"MaxTemp": 50,
"MinTemp": 8,
"MaxHumi": 90,
"MinHumi": 10
}
}
查看脚本调试区2的运行结果如下:

- 脚本脚本调试无误后,单击提交按钮提交脚本。
固件升级
LoRa节点设备可以通过本地端烧录方式升级固件,目前不支持网络在线升级(FUOTA)。
在文档使用中是否遇到以下问题
更多建议
匿名提交