从零开始学物联网:远程控制esp8266内置灯的开和关(二)

525 阅读6分钟

本学习过程由易到难,分为下面几篇文章:

上一篇文章我们讲到如何选购物联网硬件设备、安装编译软件、编写代码、上传代码到固件以及在Bmob后端云开发者后台中远程控制esp8266设备内置灯的开和关。

然而,在实际情况中,每次都要打开Bmob后端云的中控后台进行开关并不现实。特别是当我们开发的硬件销售给客户之后,肯定要提供相应的工具给用户的。这时候,小程序就成了我们最好的选择。

这篇文章主要是讲如何用小程序控制esp8266内置灯的开和关:

当我们在小程序中打开灯的时候,会远程控制灯的开,当在小程序关闭灯的时候,会远程控制灯的关;

当在其他地方(比如Bmob后端云控制台或者另外的小程序中)打开或者关闭这个灯的时候,这个小程序中的开关图标会相应变化。

image.png

一、小程序远程控制原理

要远程实时控制灯的开关、以及实时监听到灯的开关状态,我们这里需要用到MQTT协议。

这里涉及到MQTT的两个概念:订阅(subscribe)和发布(publish)。

  • 我们要实时监听到远程灯的开和关,需要订阅MQTT服务器中的某个主题。

  • 我们要远程控制灯的开和关,需要往MQTT服务器中的某个主题发布内容。

从上面的基本概念,我们可以知道,小程序启动的开始,我们需要和Bmob后端云的MQTT服务器构建一个连接,连接地址为:wxs://mqtt.bmobcloud.com:8084/mqtt。基于安全考虑,连接的时候,需要提供用户名密码(Bmob后端云提供)和客户端Id(clientId,标记这个小程序用户)。

二、UI构建

本课程采用的小程序UI是vant-weapp,这对于我这种对UI无感的人来说实在是再简单不过的事情了。不知道如何开发小程序的同学,可以看我之前写的一系列小程序开发入门的课程

1、安装nodejs

下载地址:nodejs.org/en/download…

一路next安装,完成之后,node -v如果出现类似于下面的界面,说明安装成功。

image.png

2、引入vant-weapp库

在小程序开发工具中,点击 终端 -> 新建终端,然后输入下面的命令,如下图所示:

npm i @vant/weapp -S --production

image.png

3、构建npm

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

屏幕截图 2024-06-18 104020.png

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

image.png

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文件夹下,如下图所示:

image.png

打开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方法,往主题中推送消息。所有订阅了这个主题的设备都会立即收到这个消息,并根据代码逻辑做出相应的处理。

四、源码下载

源码下载地址: bmob-cdn-31082.bmobpay.com/iot/bmob_io…