本学习过程由易到难,分为下面几篇文章:
上一篇文章我们讲到如何选购物联网硬件设备、安装编译软件、编写代码、上传代码到固件以及在Bmob后端云开发者后台中远程控制esp8266设备内置灯的开和关。
然而,在实际情况中,每次都要打开Bmob后端云的中控后台进行开关并不现实。特别是当我们开发的硬件销售给客户之后,肯定要提供相应的工具给用户的。这时候,小程序就成了我们最好的选择。
这篇文章主要是讲如何用小程序控制esp8266内置灯的开和关:
当我们在小程序中打开灯的时候,会远程控制灯的开,当在小程序关闭灯的时候,会远程控制灯的关;
当在其他地方(比如Bmob后端云控制台或者另外的小程序中)打开或者关闭这个灯的时候,这个小程序中的开关图标会相应变化。
一、小程序远程控制原理
要远程实时控制灯的开关、以及实时监听到灯的开关状态,我们这里需要用到MQTT协议。
这里涉及到MQTT的两个概念:订阅(subscribe)和发布(publish)。
-
我们要实时监听到远程灯的开和关,需要订阅MQTT服务器中的某个主题。
-
我们要远程控制灯的开和关,需要往MQTT服务器中的某个主题发布内容。
从上面的基本概念,我们可以知道,小程序启动的开始,我们需要和Bmob后端云的MQTT服务器构建一个连接,连接地址为:wxs://mqtt.bmobcloud.com:8084/mqtt。基于安全考虑,连接的时候,需要提供用户名、密码(Bmob后端云提供)和客户端Id(clientId,标记这个小程序用户)。
二、UI构建
本课程采用的小程序UI是vant-weapp,这对于我这种对UI无感的人来说实在是再简单不过的事情了。不知道如何开发小程序的同学,可以看我之前写的一系列小程序开发入门的课程。
1、安装nodejs
一路next安装,完成之后,node -v如果出现类似于下面的界面,说明安装成功。

2、引入vant-weapp库
在小程序开发工具中,点击 终端 -> 新建终端,然后输入下面的命令,如下图所示:
npm i @vant/weapp -S --production

3、构建npm
在小程序开发工具中,点击 工具 -> 构建 npm,如下图:

一切完成之后,我们会在 资源管理器 中看到node_modules/@vant文件夹,如下图所示:

4、引入UI组件
打开pages/index/index.json文件,修改为如下的内容:
{
"usingComponents": {
"van-switch": "@vant/weapp/switch/index",
"van-cell": "@vant/weapp/cell/index",
"van-cell-group": "@vant/weapp/cell-group/index"
}
}
上面的代码表示我们将要使用Switch开关组件和Cell单元格组件。
5、编写页面文件
打开pages/index/index.wxml文件,修改为如下的内容:
<view >
<van-cell-group>
<van-cell title="灯">
<van-switch checked="{{ checked }}" bind:change="onChange" />
</van-cell>
</van-cell-group>
</view>
上面的代码表示,这个开关选中与否的状态值存储在checked变量中,当我们点击这个开关的时候,会调用onChange方法(见下面代码)。
三、编写代码
1、引入MQTT连接库
下载地址:bmob-cdn-31082.bmobpay.com/iot/mqtt.js
下载之后,把文件放到utils文件夹下,如下图所示:
打开pages/index/index.js文件,在文件的开始部分加上如下的代码:
//加载mqtt库
import mqtt from '../../utils/mqtt.js';
2、变量
data: {
// 用户名,在Bmob后端云的IOT应用中获取
uid:"663ae40d824882e7",
//mqtt服务器的地址
mqtt_server:"wxs://mqtt.bmobcloud.com:8084/mqtt",
// 控制灯的主题,在Bmob后端云设备列表的详情中获取
ledtopic:"devices/LINE/esp8266clientC8:2B:96:2D:9C:10",
// led的状态。默认led关闭
checked: false,
// mqtt客户端,默认为空
client: null,
},
这里需要注意的是,在实际规模化应用中,esp8266clientC8:2B:96:2D:9C:10 这个客户端id是不会直接写入到小程序的代码中的。我们会开发一个通用的小程序,并且在产品包装盒中印刷上这个硬件对应的客户端id的二维码。用户打开我们开发的小程序,扫描二维码之后,程序将客户端id号(如 esp8266clientC8:2B:96:2D:9C:10)自动添加到devices/LINE/的后面,变成 devices/LINE/esp8266clientC8:2B:96:2D:9C:10 这样的主题名称。
2、创建MQTT连接和订阅灯的开关主题
代码如下:
var that = this
//MQTT连接的配置
var options= {
//60s ,表示心跳间隔
keepalive: 60,
//cleanSession不保持持久会话
clean: true,
//MQTT v3.1.1
protocolVersion: 4,
////这里用随机数,在实际使用中,你应该设置为固定值,代表这个小程序用户,比如用openid
clientId:Math.floor(Math.random() * 10+100).toString(),
password: '19a66167a0eadaca',
username: this.data.uid,
}
//初始化mqtt连接
this.data.client = mqtt.connect(this.data.mqtt_server,options)
// 连接mqtt服务器
this.data.client.on('connect', function () {
console.log('连接服务器成功')
//订阅灯的主题
that.data.client.subscribe(that.data.ledtopic, function (err) {
if (err) {
console.log(err)
}
})
})
上面的代码中,当我们connect成功之后,就可以调用subscribe方法订阅对应的主题了。订阅成功之后,我们就可以收到灯的开和关的消息了。
3、处理灯的开和关的消息
代码如下:
//接收消息
that.data.client.on('message', function (topic, message) {
console.log('收到消息:'+msg)
var msg = message.toString()
if(msg=='on'){
that.setData({ //数据赋值给变量
checked:true//设置led状态为true
})
}
else{
that.setData({ //数据赋值给变量
checked:false//设置led状态为true
})
}
})
上面的代码非常简单,我这里就不赘述了。
4、远程控制灯的开和关
代码如下:
//控制灯的函数
onChange({ detail }){
//detail是滑块的值,检查是打开还是关闭,并更换正确图标
this.setData({
checked: detail,
});
if(detail == true){//如果是打开操作
this.data.client.publish(this.data.ledtopic, 'on')//mqtt推送on
}else{
this.data.client.publish(this.data.ledtopic, 'off')//mqtt推送off
}
}
上面的代码中,我们调用了publish方法,往主题中推送消息。所有订阅了这个主题的设备都会立即收到这个消息,并根据代码逻辑做出相应的处理。