本次实验有两个物联网设备接入阿里云物联网平台,具体的数据转发流程如下所示:

  • 温湿度传感器:设备上传数据→物联网平台接收→规则引擎转发→小程序接收到数据
  • 台灯:小程序发送指令→物联网平台接收→规则引擎转发→台灯接收指令

其中,规则引擎的作用是进行数据的转发,要进行设备之间的通信,并不是直接进行点对点的通信,而是进行中间平台的转发,下图基本上解释了这个过程。

微信小程序进行温湿度传感器数值的接受与解析,同时具有上传控制台灯指令的功能,下面对小程序的开发进行详细介绍。

创建工程并导入第三方库

如上述的入门小程序开发所示,创建示例工程;在此基础上添加第三方库,才能进行mqtt的数据转发。

然后将这两个放在工程目录里的utils下,如下图所示:

WXML界面设计

本实例实现需要输入框用于输入用户三元组,文本信息的显示以及用户的操作(设备上线、设备下线、开灯、关灯),所以在index.json中添加本次实例构建所需要的组件依赖:

1
2
3
4
5
6
7
8
9
"usingComponents":{
"van-field":"@vant/weapp/dist/field/index",
"van-divider":"@vant/weapp/dist/divider/index",
"van-slider":"@vant/weapp/dist/slider/index",
"van-icon":"@vant/weapp/dist/icon/index",
"van-button":"@vant/weapp/dist/button/index",
"van-row":"@vant/weapp/dist/row/index",
"van-col":"@vant/weapp/dist/col/index"
}

添加三个输入框用于填写设备的三元组信息,其wxml代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<van-cell-group>
<van-field
model:value="{{productKey}}"
label="productKey:"
/>
<van-field
model:value="{{deviceName}}"
label="deviceName:"
/>
<van-field
model:value="{{deviceSecret}}"
label="deviceSecret:"
/>
</van-cell-group>

其在小程序中显示效果如图下所示:

添加Slider滑块用于显示当前的温湿度信息,同时设置disable防止误触修改获取到的信息,其wxml代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
<view>湿度:</view>
<van-slider value="{{shidu}}" use-button-slot disabled>
<view class="custom-button" slot="button">
{{shidu}}%
</view>
</van-slider>
<view>温度:</view>
<van-slider value="{{wendu}}" use-button-slot disabled bar-height="4px" active-color="#ee0a24">
<view class="custom-button" slot="button">
{{wendu}}°C
</view>
</van-slider>

温度、湿度为0时无显示效果,所以将初始值设为50,其效果如下图所示:

接下来设置四个按钮,用于设备上线、设备下线、开灯、关灯;其wxml代码如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<van-row>
<van-col span="5" offset="1">
<van-button type="primary" bind:click="turn_on">开灯</van-button>
</van-col>
<van-col span="6">
<van-button type="info" bind:click="online">设备上线</van-button>
</van-col>
<van-col span="6">
<van-buttontype="danger" bind:click="offline">设备下线</van-button>
</van-col>
<van-col span="5" offset="1">
<van-button type="warning" bind:click="turn_off">关灯</van-button>
</van-col>
</van-row>

其显示效果如图下所示:

JS功能实现

定义全局变量,导入工具类,设置设备三元组信息(将*替换为自己的)

1
2
3
4
5
6
7
8
9
var client;
var mqtt=require('../../utils/mqtt.min.js');
const crypto=require('../../utils/hex_hmac_sha1.js');
const deviceConfig={
productKey:"**********",
deviceName:" **********",
deviceSecret:"**********",
regionId:" **********"
};

设置data,用于与前端页面交互,共设置6个参数。“productKey”、“deviceName”、“deviceSecret”直接初始化定义为“deviceConfig”内的属性,也可以通过客户端输入修改;“wendu”、“shidu”两个个字段分别代表温度、湿度数值;其具体代码如下:

1
2
3
4
5
6
7
data:{
productKey:deviceConfig.productKey,
deviceName:deviceConfig.deviceName,
deviceSecret:deviceConfig.deviceSecret,
wendu:50,
shidu:50,
},

对基本的参数定义后,实现mqtt协议的基础工具类:

IoT平台mqtt连接参数初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
initMqttOptions(deviceConfig){
const params={
productKey:deviceConfig.productKey,
deviceName:deviceConfig.deviceName,
timestamp:Date.now(),
clientId:Math.random().toString(36).substr(2),
}
//CONNECT参数
const options={
keepalive:60, //60s
clean:true, //cleanSession不保持持久会话
protocolVersion:4 //MQTTv3.1.1
}
//1.生成clientId,username,password
options.password=this.signHmacSha1(params, deviceConfig.deviceSecret);
options.clientId=`${params.clientId}|securemode=2,signmethod=hmacsha1,timestamp=${params.timestamp}|`;
options.username=`${params.deviceName}&${params.productKey}`;
return options;
},

生成基于HmacSha1的password,参考文档:https://help.aliyun.com/document_detail/73742.html

1
2
3
4
5
6
7
8
9
10
11
signHmacSha1(params,deviceSecret){
let keys=Object.keys(params).sort();
//按字典序排序
Keys=keys.sort();
const list=[];
keys.map((key)=>{
list.push(`${key}${params[key]}`);
});
const contentStr=list.join('');
return crypto.hex_hmac_sha1(deviceSecret,contentStr);
}

最后实现对按钮的绑定功能事件的实现:

设备上线:对设备三元组信息进行初始化,使用三元组连接阿里云,并通过“client.on()”进行监听,将获取到的温湿度数值绑定“wendu”、“shidu”变量,最后在小程序中显示,其实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
online:function(){
varthat=this;
const options=this.initMqttOptions(deviceConfig);
//连接阿里云
client=mqtt.connect('wxs://'+deviceConfig.productKey+'.iot-as-mqtt.cn-shanghai.aliyuncs.com',options)
client.on('connect',function(){
console.log('连接服务器成功')
//订阅主题(这里的主题可能会不一样,具体请查看后台设备Topic列表或使用自定义主题)
client.subscribe('/sys/'+`${deviceConfig.productKey}`+'/'+`${deviceConfig.deviceName}`+'/thing/service/property/set',function(err){
if(!err){
console.log('订阅成功!');
}
})
})
//接收消息监听
client.on('message',function(topic,message){
message=message.toString()
message=JSON.parse(message)
//将接收到的字符串进行Json格式转换
console.log(message)
that.setData({
wendu:message['items']['temp']['value'],
shidu:message['items']['hum']['value']
})
})
},

设备下线:将“client”连接关闭,并将“wendu”、“shidu”的值初始化为0

1
2
3
4
5
6
7
8
9
offline:function(){
//client连接断开,关闭连接
client.end()
this.setData({
wendu:0,
shidu:0,
})
console.log('设备断开连接')
},

开灯:定义发布链接,设置“Lightswitch”字段为1,通过发布函数将信息提交给阿里云

1
2
3
4
5
6
7
8
9
10
11
turn_on:function(){
let topics='/sys/'+deviceConfig.productKey+'/'+deviceConfig.deviceName+'/thing/event/property/post';
const payloadJson={
id:Date.now(),
params:{
"Lightswitch":"1"
},
method:"thing.event.property.post"
}
client.publish(topics,JSON.stringify(payloadJson))
},

关灯:与开灯基本没有区别,将“Lightswitch”字段设置为0即可

1
2
3
4
5
6
7
8
9
10
11
turn_off:function(){
let topics='/sys/'+deviceConfig.productKey+'/'+deviceConfig.deviceName+'/thing/event/property/post';
const payloadJson={
id:Date.now(),
params:{
"Lightswitch":"0"
},
method:"thing.event.property.post"
}
client.publish(topics,JSON.stringify(payloadJson))
},

实验整体流程

在阿里云物联网平台添加三个设备(台灯、温湿度传感器、微信小程序),设置规则引擎(用于信息流转),将设备开启连接上云,同时微信小程序开启设备实现数据的监听,一段时间后收到云上的数据,在页面显示温湿度数值;同时可以点击开灯、关灯按钮实现对于台灯的控制