观前提醒:本章主要内容是通过web服务发布和订阅MQTT话题,并由此控制水龙头。对水龙头零件进行总装和测试

一、设计要求

  • 使用任意第三方设备都可以访问web页面控制水龙头
  • 图形交互界面
  • web访问由服务器提供,不运行在ESP32上

(1)如何通过Python提供web服务呢:

1、选择合适的框架
Python社区提供了多种Web框架来快速开发Web服务,包括但不限于Flask、Django和FastAPI。每种框架都有其特点:

  • Flask:轻量级、灵活、易于上手,适合小到中型项目。
  • Django:全功能框架,内置了ORM、模板引擎、路由系统等,适合大型项目。
  • FastAPI:现代、快速(高性能)的Web框架,使用Python 3.6+类型提示,支持异步编程。

对于一个简单的Web服务,Flask是一个不错的选择。以下是使用Flask创建Web服务的步骤。

2、安装Flask

pip install Flask

使用pip安装Flask

3、创建你的第一个Web服务

安装完成后,你可以创建一个Python文件来编写你的Web服务。例如,创建一个名为app.py的文件,并添加以下内容:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return "Welcome to my web service!"

if __name__ == '__main__':
    app.run(debug=True)

在这个简单的例子中,我们导入了Flask类,创建了一个Flask应用实例。我们定义了一个路由/,当访问这个URL时,它会触发home函数,并返回一条欢迎信息。

4、运行web服务

保存文件后,你可以通过运行以下命令来启动服务:

python app.py

如果一切设置正确,你应该会看到终端输出,告诉你服务正在运行在localhost的5000端口上。现在,你可以在浏览器中访问http://127.0.0.1:5000/,并看到返回的欢迎信息。

5、扩展web服务

Flask提供了丰富的功能可以帮助你扩展服务,包括处理不同类型的请求、访问请求数据、返回不同格式的响应等。比如,你可以添加一个新的路由来处理POST请求并返回JSON响应:

from flask import Flask, jsonify, request

@app.route('/data', methods=['POST'])
def get_data():
    data = request.json
    return jsonify(data), 200

上面的代码片段展示了如何获取JSON格式的请求体,并将其直接作为JSON响应返回给客户端。

(2)通过python的web服务提供网页并发送POST请求

1、创建flask应用

创建一个app.py文件,代码如下:

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/say-hello', methods=['POST'])
def say_hello():
    return "Hello", 200

if __name__ == '__main__':
     app.run(host='0.0.0.0', port=5000, debug=True)

3、创建HTML网页

在你的Flask应用目录中创建一个名为templates的文件夹。在该文件夹中,创建一个新的HTML文件index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Python Web Button</title>
    <script>
        function sendRequest() {
            fetch('/say-hello', { method: 'POST' })
                .then(response => response.text())
                .then(data => alert(data));
        }
    </script>
</head>
<body>
    <button onclick="sendRequest()">Say Hello</button>
</body>
</html>

在这个HTML文件中,我们创建了一个按钮,当你点击这个按钮时,它会调用名为sendRequest的JavaScript函数。这个函数使用fetch API向/say-hello路径发送POST请求,并通过alert显示从服务器返回的响应。

二、水龙头web控制代码

综合上述的代码我们可以得到:

from flask import Flask, render_template, request, redirect, url_for
import paho.mqtt.client as mqtt

app = Flask(__name__)

# MQTT配置
MQTT_BROKER_URL = "192.168.3.222"  # 替换为你的MQTT代理服务器地址
MQTT_BROKER_PORT = 1883  # 替换为你的MQTT代理服务器端口,默认通常为1883
MQTT_TOPIC = "slt"  # 替换为你想要发布的话题

# 创建MQTT客户端实例
mqtt_client = mqtt.Client()
# 连接MQTT代理服务器
mqtt_client.connect(MQTT_BROKER_URL, MQTT_BROKER_PORT, 60)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/publish/<message>')
def publish_message(message):
    mqtt_client.publish(MQTT_TOPIC, message)
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

以下是代码的详细解释:

from flask import Flask, render_template, request, redirect, url_for
import paho.mqtt.client as mqtt
  • Flask:Flask框架的主要类,用于创建Web应用实例。
  • render_template:Flask函数,用于渲染HTML模板文件。
  • request:包含请求数据的对象,此处未使用。
  • redirect:Flask函数,用于重定向客户端到其他URL。
  • url_for:Flask函数,用于生成应用内的URL。
  • paho.mqtt.client:paho-mqtt库中的模块,用于与MQTT代理服务器通信。
MQTT_BROKER_URL = "192.168.3.222"
MQTT_BROKER_PORT = 1883
MQTT_TOPIC = "slt"
mqtt_client = mqtt.Client()
mqtt_client.connect(MQTT_BROKER_URL, MQTT_BROKER_PORT, 60)

设置MQTT代理服务器的地址、端口和你想要发布消息的主题。这些信息用于连接MQTT服务器和指定消息发布的目标。

创建一个paho-mqtt客户端实例,并连接到配置好的MQTT代理服务器。60是保持连接的超时时间,单位为秒。

@app.route('/')
def index():
    return render_template('index.html')

定义了一个路由/,它关联了index视图函数。当用户访问Web应用的根地址时,这个视图函数会响应并通过render_template函数返回index.html模板文件的内容

@app.route('/publish/<message>')
def publish_message(message):
    mqtt_client.publish(MQTT_TOPIC, message)
    return redirect(url_for('index'))

定义了一个路由/publish/<message>,它关联了publish_message视图函数。这个函数接收message参数,这是URL路径中的动态部分。当这个路由被访问时,它会调用mqtt_client.publish方法,将接收到的message发布到预先配置的MQTT主题。发布消息后,使用redirect函数将客户端重定向回主页。

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

这部分代码检查是否在主程序中执行(而不是作为模块导入),如果是,它将启动Flask应用。host='0.0.0.0'告诉Flask在网络上可见,也就是说,任何设备都可以通过你电脑的IP地址访问应用。port=5000指定了服务运行在哪个端口上。debug=True启用调试模式,这样在开发过程中遇到错误时,可以在网页上看到详细的调试信息。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MQTT Control Panel</title>
    <style>
        .center {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }
        .button {
            font-size: 18px;
            padding: 10px 20px;
            margin: 0 10px;
        }
    </style>
</head>
<body>
    <div class="center">
        <form action="/publish/1" method="get">
            <button class="button" type="submit">开</button>
        </form>
        <form action="/publish/0" method="get">
            <button class="button" type="submit">关</button>
        </form>
    </div>
</body>
</html>

这段HTML代码定义了一个基本的网页结构,用于创建一个控制面板,该面板上有两个按钮,分别用于“开”和“关”。这些按钮通过发送GET请求到/publish/1和/publish/0来与后端的Flask应用进行交互,用于MQTT消息发布。下面是对这段HTML代码各部分的分析:

  • <html>标签定义了整个HTML文档,并使用lang="en"属性指定页面内容的主要语言是英语。
  • 在<head>标签内,包含了文档的元数据:

    <meta charset="UTF-8">指定了字符编码为UTF-8,这是一种广泛使用的字符编码,支持多种语言文本。
    <meta name="viewport" content="width=device-width, initial-scale=1.0">是为了确保适当的缩放和渲染在移动设备上。width=device-width部分设置了视口宽度等于设备的物理宽度,initial-scale=1.0设定了初始缩放比例。
    <title>标签定义了浏览器标签页上显示的标题。

  • 在<style>标签中定义了两种CSS类:

    .center类使用了Flexbox布局来居中<div>容器内的内容。justify-content和align-items属性确保了子元素水平和垂直居中,height设置为100vh意味着<div>的高度将占满视口的100%。
    .button类为按钮添加了样式,包括字体大小、内边距和外边距。

  • <body>标签包含了页面的所有可见内容:

    包含了一个类名为center的<div>元素,这将会使得其内的内容(两个表单)水平和垂直居中显示。
    两个<form>元素,每个表单都有一个提交按钮。当点击这些按钮时,会向服务器的/publish/1或/publish/0端点发送GET请求。这些请求由后端服务器处理,用于通过MQTT发布消息。
    每个按钮都应用了button类样式,这增加了按钮的可读性和点击区域。

三、机械零件安装

安装步骤:

  1. 安装电机支架与电机,并使用两颗m2螺丝固定
  2. 安装从动齿圈和水龙头,使用胶水固定
  3. 安装驱动齿轮和电机,直接用力敲进去即可(过盈配合)
  4. 将电机支架固定在水龙头尾部,安装位置需使驱动轮和从动齿圈咬合
  5. 给电机通电,测试水龙头是否被正确驱动(需注意从动齿圈是否水平安装)

四、电路及其他结构组装

  1. 《保姆级》手把手教你做一个物联网智能水龙头(二)电路设计及EPS32程序设计基础上对电路做好绝缘及固定
  2. 将电路固定在设备壳体中
  3. 连接水龙头与水管

五、设备功能测试

测试步骤:

  1. 固定MQTT服务器 IP、固定ESP32 IP
  2. 启动MQTT服务器,确保MQTT服务已开启,可以使用MQTT.fx工具测试
  3. 启动客户端程序,连接MQTT服务器
  4. 物联网水龙头上电
  5. 依次测试开启、关闭、定时及web控制功能