【ESP32+MicroPython】构建智能家居控制中枢:热点模式与网页交互实战
1. ESP32与MicroPython的完美组合如果你正在寻找一种简单高效的方式来搭建智能家居控制系统ESP32搭配MicroPython绝对是个不错的选择。ESP32这款芯片我用了好几年最大的感受就是性价比超高 - 双核处理器、WiFi蓝牙双模、丰富的GPIO接口价格却只要一杯奶茶钱。而MicroPython更是让开发变得异常简单不需要复杂的开发环境几行代码就能实现强大功能。记得我第一次用ESP32做智能灯控时原本准备用Arduino开发结果被各种库依赖和编译问题折腾得够呛。后来切换到MicroPython从零开始到点亮第一个LED只用了不到10分钟。这种开发效率对于智能家居原型开发特别友好毕竟我们更关注功能实现而不是底层细节。2. 快速搭建热点模式2.1 为什么选择热点模式在智能家居项目中我经常遇到没有外网的环境。比如给老家装智能灯控或者在一些临时场所搭建控制系统。这时候ESP32的热点模式(AP模式)就派上大用场了。它可以让手机、平板等设备直接连接到ESP32创建的WiFi网络完全不需要路由器。实测下来ESP32的热点稳定性相当不错。我曾经同时连接5台设备进行控制延迟都在可接受范围内。不过要注意的是热点模式的有效距离比STA模式要短一些室内大约15米左右隔墙信号衰减比较明显。2.2 具体实现代码让我们来看看具体怎么实现。首先是最基础的热点创建代码import network def create_ap(ssidSmartHome_AP, passwordhome1234): ap network.WLAN(network.AP_IF) ap.active(True) ap.config(essidssid, passwordpassword) print(f热点已创建IP地址{ap.ifconfig()[0]}) create_ap()这段代码我优化了几个地方设置了默认的SSID和密码避免每次都要输入使用f-string格式化输出更直观显示IP地址密码设置得更安全不再是简单的12345678在实际项目中我建议把SSID和密码存储在配置文件里这样修改起来更方便。也可以考虑使用ESP32的蓝牙先进行配网让用户自己设置热点名称和密码。3. 构建网页控制界面3.1 基础HTTP服务器有了热点之后我们需要创建一个Web服务器。这里我推荐使用microdot这个轻量级框架比直接用socket方便多了。先安装import upip upip.install(microdot)然后创建一个简单的控制页面from microdot import Microdot from machine import Pin app Microdot() led Pin(2, Pin.OUT) app.route(/) def index(request): return f html headtitle智能家居控制/title/head body h1客厅灯光控制/h1 p当前状态{开 if led.value() else 关}/p a href/togglebutton切换状态/button/a /body /html , 200, {Content-Type: text/html} app.route(/toggle) def toggle(request): led.value(not led.value()) return index(request) app.run(port80)这个实现比原始文章的更简洁而且使用了现代Python的f-string特性。页面会自动显示当前灯的状态点击按钮可以切换开关状态。3.2 增强用户体验为了让控制界面更友好我通常会加入一些CSS样式和JavaScript。比如下面这个改进版app.route(/) def index(request): return html head title智能控制/title style body {font-family: Arial; text-align: center; margin-top: 50px;} button {padding: 12px 24px; font-size: 18px; background: #4CAF50; color: white; border: none; border-radius: 4px;} .off {background: #f44336;} /style script function toggle() { fetch(/toggle) .then(() location.reload()) } /script /head body h1客厅主灯/h1 button onclicktoggle() class (off if not led.value() else ) (关闭 if led.value() else 开启) /button /body /html , 200, {Content-Type: text/html}这个版本有几个改进添加了现代CSS样式按钮更大更美观使用JavaScript的fetch API实现无刷新切换按钮颜色会根据灯的状态变化绿色表示开红色表示关按钮文字也会相应变化4. 多设备联动控制4.1 控制多个GPIO设备真正的智能家居不可能只有一个灯。下面我们扩展代码控制多个设备from machine import Pin import json devices { living_light: Pin(2, Pin.OUT), bedroom_light: Pin(4, Pin.OUT), fan: Pin(5, Pin.OUT) } app.route(/api/devices, methods[GET]) def get_devices(request): return { name: pin.value() for name, pin in devices.items() } app.route(/api/devices/name/state, methods[POST]) def set_device(request, name, state): if name in devices: devices[name].value(1 if state on else 0) return {status: success} return {status: device not found}, 404这样我们就创建了一个简单的REST API可以查询和控制多个设备。前端页面可以调用这些API实现更复杂的控制逻辑。4.2 定时与自动化智能家居的核心是自动化。我们可以添加定时任务import utime from machine import Timer def auto_off(timer): devices[living_light].value(0) timer Timer(-1) timer.init(period3600000, modeTimer.ONE_SHOT, callbackauto_off)这段代码会在1小时后自动关闭客厅灯。在实际项目中我会把这些定时规则存储在文件系统中重启后也能保持。5. 进阶功能与优化5.1 状态持久化ESP32重启后设备状态会丢失。我们可以使用文件系统保存状态import ujson def save_state(): with open(state.json, w) as f: ujson.dump({ name: pin.value() for name, pin in devices.items() }, f) def load_state(): try: with open(state.json, r) as f: state ujson.load(f) for name, value in state.items(): if name in devices: devices[name].value(value) except: pass # 第一次运行没有状态文件然后在设备状态变化时调用save_state()在启动时调用load_state()。5.2 能耗优化为了节省电量我们可以让ESP32在不使用时进入深度睡眠import machine def go_to_sleep(seconds): # 配置唤醒源 machine.RTC().irq(triggermachine.RTC.ALARM0, wakemachine.DEEPSLEEP) # 设置唤醒时间 machine.RTC().alarm(machine.RTC.ALARM0, seconds * 1000) # 进入深度睡眠 machine.deepsleep()这对于电池供电的智能设备特别有用可以大大延长续航时间。5.3 安全增强基础的安全措施也很重要from microdot import Request app.before_request def check_auth(request): if request.path.startswith(/api): auth request.headers.get(Authorization) if auth ! Bearer mysecretkey: return Unauthorized, 401这样就给API接口添加了简单的认证保护。在实际项目中你可能需要更复杂的安全方案比如使用HTTPS。