Skip to main content Link Menu Expand (external link) Document Search Copy Copied

创客利器之ESP32(四)- 使用MicroPython与MQTT一起控制小灯

前言

前面两篇文章介绍了如何通过MicroPython固件控制ESP32,以及如何自动连接家里的局域网。有了这些基础我们可以将ESP32接入智能家庭系统HomeAssistant,可以通过HomeAssistant实现智能化控制电器等功能。不过目前没有现成的组件能够让MicroPython与HomeAssistant相连接,我们需要通过MQTT作为中间协议,HomeAssistant和MicroPython都作为Client与MQTT Broker通信。这一篇我们展示如何通过MQTT协议来与ESP32通信。

MQTT协议

MQTT协议是一个物联网环境里常用的消息协议。MQTT系统往往由Broker和Client组成,Broker类似服务器,并维护很多地址和地址的内容;Client通过MQTT协议可以创建,改变地址的内容和读取地址的内容,Client还可以监听地址内容的变化。这里的地址格式类似Unix文件系统中的路径,可以有多级路径,比如 home/bedroom/lighthome/bedroom/air-conditioner 等。支持通过设计一定的结构来方便地址的管理,并且支持对相同前置层级的地址进行批量操作。

Mosquitto - MQTT Broker

Eclipse Mosquitto是一个MQTT Broker的开源实现,被很多物联网项目使用。可以在Download地址下载和安装。这里我们介绍通过docker来安装一个Mosquitto服务,docker安装可以参考这个地址。安装好docker之后,先在~目录下创建一个mosquitto目录,并创建如下配置文件,用于指定服务端口和允许匿名访问,待会用于启动Mosquitto。

user1@blackbox:~$ cat <<EOF > ~/mosquitto/mosquitto.conf
listener 9001
allow_anonymous true
EOF

执行下面的命令,来创建一个Mosquitto容器。再通过 docker ps 命令可以查看容器STATUS是否正常。

docker run -d -p 9001:9001 -v ~/mosquitto/mosquitto.conf:/mosquitto/config/mosquitto.conf -v ~/mosquitto/data:/mosquitto/data -v ~/mosquitto/log:/mosquitto/log eclipse-mosquitto
user1@blackbox:~$ docker ps -a
CONTAINER ID   IMAGE               COMMAND                   CREATED          STATUS          PORTS                                                 NAMES
47cf8835787e   eclipse-mosquitto   "/docker-entrypoint.…"   46 seconds ago   Up 46 seconds   1883/tcp, 0.0.0.0:9001->9001/tcp, :::9001->9001/tcp   quirky_easley

有了Broker后,我们就可以使用mosquitto_pub和mosquitto_sub测试一下MQTT发布和订阅。如果没有mosquitto_pub/mosquitto_sub,debian/ubuntu用户可以通过 apt uinstall mosquitto-clients 安装,其他操作系统请使用对应的包管理工具安装。我们先使用mosquitto_sub订阅地址 home/bedroom/light

mosquitto_sub -h <mqtt_broker_ip> -p 9001 -t home/bedroom/light

再打开一个命令行窗口,用下面的命令向 home/bedroom/light 发布值 on 。再返回mosquitto_sub对应的窗口,如果一切正常,应该看到我们在另一个窗口发布的值 on

mosquitto_pub -h <mqtt_broker_ip> -p 9001 -t home/bedroom/light -m on

准备好了MQTT Broker之后,下面我们使用MicroPython订阅某一个地址,通过控制这个地址关联的值就可以通知ESP32完成预设的任务。

MicroPython做为MQTT Client

为ESP32准备好MicroPython固件,并设置好网络连接,以访问我们准备好的MQTT Broker。具体步骤可以参考上一篇博文“创客利器之ESP32(三)- 使用MicroPython自动连接WiFi”。MicroPython在执行完boot.py文件之后,还会检查并执行main.py文件,我们将在main.py中实现我们的代码。我们使用地址 home/bedroom/light , 如果关联的值是 on 就打开GPIO5端口连接的小灯;如果是其他的值就关闭小灯。代码如下,需要将全局变量server、port_num、switch_topic根据实际情况进行调整。

import time
from umqtt.simple import MQTTClient
from machine import Pin

    # Publish test messages e.g. with:
    # mosquitto_pub -t foo_topic -m hello

    server = "<mqtt_broker_ip>"
    port_num = 9001
    swith_topic = b"home/bedroom/light"
    p5 = Pin(5, Pin.OUT)
    p5.off()

    # 如果值是on,打开小灯;否则关掉小灯
    def sub_cb(topic, msg):
        if msg.decode().lower() == "on":
            p5.on()
        else:
            p5.off()

def main():
    print("main started ...")
    c = MQTTClient("umqtt_client", server, port=port_num)
    c.set_callback(sub_cb)
    c.connect()
    c.subscribe(swith_topic)
    while True:
        try:
            if True:
                # Blocking wait for message
                c.wait_msg()
        except Exception:
            print("wait message fail")
    c.disconnect()

print("will enter main")
if __name__ == "__main__":
    main()

编辑好main.py, 打开浏览器,输入 http://<esp32_ip>:8266 ,使用webrepl上传main.py。连接好小灯,如下图这样。

img

下面使用mosquitto_pub向地址发送值 onoff ,开是否可以打开和关闭小灯。

user1@blackbox:~$ mosquitto_pub -h 192.168.3.102 -p 9001 -t home/bedroom/light -r -m on

如果正常这时小灯应该已经亮了,用下面的命令关闭小灯,是不是很容易?当然过程可能不那么顺利,如果有异常用screen查看串口的输出,可能main.py的语法有点问题,修改好再试试。

user1@blackbox:~$ mosquitto_pub -h 192.168.3.102 -p 9001 -t home/bedroom/light -r -m off

总结

今天我们介绍了怎么使用MQTT协议控制ESP32,我们已经可以用MicroPython完成一些比较复杂的任务,下一篇文章我们将HomeAssistant、Mosquitto和ESP32串起来实现自动化打开和关闭小灯。