ESP-RFID与MQTT智能门禁系统:解耦架构与Tasmota/Shelly联动实战
1. 项目缘起当ESP-RFID需要更强的“手”和“脑”如果你玩过ESP8266/ESP32的RFID门禁大概率对ESP-RFID这个开源项目不陌生。它把一块小小的开发板变成了一个独立的读卡器Web服务器刷一下卡网页上就能记录还能控制一个继电器去开门。这很酷但它的“能力圈”也仅限于此——继电器直接连在ESP的GPIO上逻辑控制全在ESP内部。一旦你想做点复杂的比如“刷卡后不仅要开门还要点亮走廊灯同时给手机发个通知并且记录到云端数据库”原生ESP-RFID就有点力不从心了。这就是“ESP-RFID with External Tasmota/Shelly”这个组合诞生的背景。它的核心思想是解耦与扩展。我们不再让ESP-RFID亲自去“动手”控制硬件而是让它专心做好“感知”和“决策”这两件事感知卡片信息然后通过一个高效的通信协议MQTT把“谁在什么时候刷了卡”这个决策指令广播出去。至于具体由谁来执行开门、开灯、发通知这些“动手”的活儿就交给更专业的“执行者”——比如刷了Tasmota固件的智能插座或者Shelly品牌的智能继电器模块。简单来说我们把一个集成的“单片机门禁”升级成了一个分布式的“智能家居触发中枢”。ESP-RFID是那个敏锐的“哨兵”而Tasmota/Shelly设备则是听令行事的“士兵”。MQTT协议就是它们之间高效、可靠的“无线电”。这个架构的灵活性是惊人的你可以在不修改ESP-RFID任何代码的情况下通过增减或重新配置Tasmota/Shelly设备来无限扩展门禁系统的功能边界。2. 核心组件选型与角色定位要实现这个架构我们需要三类核心组件每一类都有其明确的职责和选型考量。2.1 感知与决策中心ESP-RFID固件ESP-RFID在这里扮演大脑和感官的角色。你需要将它刷写到一块ESP8266或ESP32开发板上并连接RC522或其他兼容的RFID读卡模块。注意务必从官方GitHub仓库获取最新稳定版固件。在配置时除了常规的Wi-Fi设置最关键的部分在“硬件”和“MQTT”配置页。在硬件页建议将“继电器控制”设置为“无”。因为我们不再使用ESP板载的GPIO去控制继电器而是通过MQTT来控制外部设备。这一步是思维转换的关键意味着ESP-RFID从此“放手”只做命令的发布者。2.2 通信骨干MQTT代理服务器MQTT是一个基于发布/订阅模式的轻量级消息协议完美适配物联网设备间通信。它需要一个“中转站”即MQTT代理服务器。选型推荐家用/测试Mosquitto。这是最流行、最轻量的开源MQTT代理可以轻松部署在树莓派、NAS甚至一台常年开机的旧电脑上。Docker部署是首选一条命令即可完成。云端/省心EMQX Cloud、阿里云物联网平台、腾讯云IoT Hub。这些云服务提供了免运维的MQTT代理通常有免费的额度适合不想自建服务器的用户。它们还额外提供了设备管理、监控看板等增值功能。关键概念主题可以理解为“频道”或“地址”。ESP-RFID和Tasmota/Shelly设备通过订阅和发布到特定的主题来交换信息。例如ESP-RFID可以将刷卡事件发布到esp-rfid/door/access主题。消息在主题中传递的数据内容通常是JSON或简单字符串格式。2.3 执行终端Tasmota与Shelly设备这是实际执行物理操作的“手”。两者都可以通过MQTT接收指令并控制继电器。特性Tasmota (固件)Shelly (硬件产品)本质一个开源固件需要刷入支持的硬件如Sonoff、Shelly等一个集成了硬件和官方固件的商业产品灵活性极高。可刷入大量廉价Wi-Fi模块完全开源功能可深度定制。中等。开箱即用官方固件功能稳定但相对固定部分型号支持自定义脚本。上手难度较高。需要寻找兼容硬件、刷机、配置模板。极低。插电、配网、设置MQTT即可使用。稳定性依赖社区和硬件质量配置得当后非常稳定。商业产品稳定性通常有保障。成本通常更低硬件成本低。稍高为便利性和稳定性付费。如何选择如果你是极客享受折腾过程手头有闲置的Sonoff Basic等模块Tasmota是不二之选它能给你最大的控制权和性价比。如果你追求快速部署、稳定可靠希望用最少的时间让系统跑起来Shelly系列产品如Shelly 1, Shelly Plus 1是你的最佳伙伴。它的官方固件已经原生支持MQTT配置过程非常直观。在本方案中我们将一个Shelly 1作为执行开门动作的继电器。它的角色非常纯粹订阅ESP-RFID发出的特定MQTT主题当收到“开”指令时闭合继电器1秒钟模拟开门动作。3. 实战部署从零搭建完整链路现在我们假设在一个典型的家庭实验室环境使用Mosquitto作为本地MQTT服务器Shelly 1作为执行器来搭建整个系统。3.1 第一步部署MQTT服务器如果你使用树莓派安装Mosquitto非常简单sudo apt update sudo apt install mosquitto mosquitto-clients sudo systemctl enable mosquitto sudo systemctl start mosquitto安装后Mosquitto默认就在1883端口运行了。为了测试我们可以用mosquitto_sub和mosquitto_pub命令进行本地订阅和发布测试确保服务正常。对于生产环境强烈建议配置用户名密码认证。编辑/etc/mosquitto/mosquitto.conf文件取消相关注释并设置密码文件allow_anonymous false password_file /etc/mosquitto/passwd然后创建密码文件sudo mosquitto_passwd -c /etc/mosquitto/passwd your_username输入密码后重启Mosquitto服务。3.2 第二步配置ESP-RFID连接MQTT在ESP-RFID的Web配置界面通常通过IP地址访问找到MQTT设置页面。MQTT服务器填入你的Mosquitto服务器IP地址例如192.168.1.100。端口默认1883如果用了TLS加密则是8883。用户名/密码填写上一步在Mosquitto中创建的凭据。客户端ID起一个唯一的名字如ESP-RFID_Garage。主题配置这是核心主主题设定一个基础主题如home/access。所有相关消息都会以此为基础。门禁主题ESP-RFID会在检测到刷卡后向一个特定的主题发布消息。通常格式是[主主题]/[门禁点名称]。例如我们设置为home/access/door1。消息格式选择JSON。这会发布一个结构化的消息例如{tag:A1B2C3D4, granted:true}其中包含卡号tag和是否授权granted。这比简单的“ON/OFF”字符串包含更多信息为后续复杂逻辑处理留有余地。保存配置后ESP-RFID会重启并尝试连接MQTT服务器。你可以在Mosquitto服务器上用命令行工具订阅home/access/##是通配符来监听所有相关消息刷卡测试是否能看到JSON数据。3.3 第三步配置Shelly 1执行动作将Shelly 1接上电源和你要控制的电锁注意安全操作强电请断电进行。通过手机App或网页Shelly设备会创建一个Wi-Fi热点将其连接到你的家庭Wi-Fi。启用MQTT在Shelly的Web界面通过IP访问找到Internet Security - Advanced - Developer Settings。启用MQTT勾选启用填写MQTT服务器地址、端口、用户名、密码与ESP-RFID使用的相同。配置动作这是最关键的一步。我们需要让Shelly订阅ESP-RFID发布的主题并在收到授权成功的消息时触发继电器。在Shelly的Web界面找到Scripts或Actions页面不同固件版本位置可能不同。创建一个新的脚本。脚本语言通常是JavaScriptShelly Script。脚本逻辑// 订阅ESP-RFID发布的主题 MQTT.subscribe(home/access/door1, function(topic, message, retained) { // 解析收到的JSON消息 let msg JSON.parse(message); // 判断是否是授权通过的刷卡事件 if (msg.granted true) { // 控制继电器0Shelly 1的第一个继电器打开1秒 Shelly.call(Switch.Set, { id:0, on:true }); // 设置一个1秒后关闭的定时器 Timer.set(1000, false, function() { Shelly.call(Switch.Set, { id:0, on:false }); }); } });这个脚本做了几件事订阅特定主题、解析消息、判断条件、执行动作。Shelly.call是调用设备内部API的方法Switch.Set用于控制继电器开关。保存并启用脚本。现在当你用授权的卡在ESP-RFID上刷卡时Shelly 1的继电器就会“咔哒”一声闭合一秒再断开完美模拟了开门动作。3.4 第四步功能扩展与联动思路至此基础的门禁功能已经实现。但这个架构的魅力在于其扩展性。以下是一些进阶玩法多门禁点联动你可以部署多个ESP-RFID读卡器厨房门、车库门每个发布到类似home/access/kitchen,home/access/garage的主题。然后配置一个Shelly 2.5双路继电器分别订阅这两个主题控制不同的门锁。灯光与通知联动在Node-RED一个图形化的低代码物联网集成工具中订阅home/access/#主题。当收到刷卡消息时Node-RED可以同时执行多个动作通过MQTT命令打开Tasmota控制的走廊灯通过HTTP请求调用手机推送服务如Pushover、Bark发送通知甚至将刷卡记录写入Google Sheets或本地数据库。条件化执行在Shelly脚本或Node-RED中增加逻辑判断。例如只在晚上8点到早上7点之间刷卡时才联动打开灯光或者当刷特定管理员卡片时触发一个5秒的长开信号用于维护。状态反馈让Shelly在动作执行后发布一个状态消息到如home/access/door1/status主题内容为{relay:on}或{relay:off}。ESP-RFID或其他设备可以订阅此主题实现状态同步甚至在Web界面上显示“门已开启”的提示。4. 深度排错从理论到信号的完整链路检查系统不工作别慌。物联网项目的调试就是逐层验证通信链路。请按照以下顺序排查这能帮你系统地定位问题。4.1 第一层网络连通性这是所有问题的基础。确保ESP-RFID、Shelly设备和运行Mosquitto的服务器或电脑都在同一个局域网段如192.168.1.x并且可以互相ping通。防火墙需要放行MQTT端口默认1883。一个常见的坑是电脑的防火墙阻止了入站连接导致设备无法连接到电脑上运行的Mosquitto。4.2 第二层MQTT服务器与认证在服务器上使用sudo systemctl status mosquitto检查服务是否运行。查看Mosquitto的日志sudo tail -f /var/log/mosquitto/mosquitto.log当设备尝试连接时日志会显示连接成功或失败的原因如“认证失败”、“错误的协议版本”等。使用MQTT客户端工具如MQTT Explorer、Desktop进行手动测试。用正确的服务器地址、端口、用户名密码连接然后手动向home/access/door1主题发布一个JSON消息{tag:test, granted:true}。同时订阅#主题看能否收到Shelly设备上线或下线的状态消息通常Shelly会发布shellies/[device-id]/online消息。这个步骤能彻底分离“服务器问题”和“设备配置问题”。4.3 第三层ESP-RFID配置与发布进入ESP-RFID的Web界面查看状态页确认MQTT显示为“已连接”。如果显示断开检查配置的IP、端口、用户名密码是否正确。ESP-RFID的日志功能有限但你可以通过监听它的串口输出如果方便接线来查看启动和连接时的详细信息。在MQTT客户端工具中订阅home/access/#主题。用一张已知的授权卡刷卡观察是否能收到消息。如果收不到问题出在ESP-RFID的MQTT配置或网络连接上。如果收到了但格式不对比如不是JSON检查ESP-RFID中MQTT设置的消息格式选项。4.4 第四层Shelly订阅与脚本逻辑这是最复杂的一环。首先在Shelly的Web界面检查MQTT连接状态是否正常。然后验证脚本是否正确保存和启用。Shelly Script的调试比较麻烦但你可以通过增加日志输出来辅助MQTT.subscribe(home/access/door1, function(topic, message, retained) { console.log(Received:, topic, message); // 打印接收到的消息 let msg JSON.parse(message); console.log(Parsed granted:, msg.granted); if (msg.granted true) { console.log(Access granted, triggering relay.); Shelly.call(Switch.Set, { id:0, on:true }); Timer.set(1000, false, function() { Shelly.call(Switch.Set, { id:0, on:false }); console.log(Relay turned off.); }); } });在Shelly的Web界面的“日志”或“事件”查看器中观察是否有这些console.log的输出。如果没有输出说明脚本没有触发可能是主题名拼写错误或者MQTT消息没有成功送达Shelly。如果有输出但继电器没动作检查Shelly.call的语法特别是继电器id是否正确Shelly 1通常是0。4.5 第五层电源与硬件不要忽略最简单的硬件问题。确保Shelly 1的供电稳定。测量一下继电器的输出端在脚本触发时是否有电压变化。如果控制的是12V电锁确保Shelly的继电器输出端正确连接到电锁的电源回路中。有时候问题仅仅是接线松动或电源功率不足。5. 安全加固与生产环境考量家庭实验室可以玩得随意些但如果你打算将其用于真正的门禁安全必须放在首位。网络隔离将物联网设备ESP-RFID, Shelly放在一个独立的VLAN或访客网络中与你的主用电脑、手机网络隔离。防止某个设备被攻破后危及整个内网。MQTT加密端口加密使用MQTT over TLS端口8883。这需要在Mosquitto服务器上配置SSL证书可以使用Let‘s Encrypt的免费证书或自签名证书。然后在ESP-RFID和Shelly的MQTT配置中启用TLS并上传或信任证书。传输加密如果觉得配置TLS麻烦至少要在MQTT连接中使用用户名和强密码并禁用匿名访问。主题权限在Mosquitto中可以使用ACL访问控制列表文件精细控制每个客户端能订阅和发布哪些主题。例如只允许ESP-RFID客户端发布到home/access/door1只允许Shelly客户端订阅这个主题和自己的状态主题。设备认证为每个物联网设备使用独特的客户端ID和密码避免使用通用密码。逻辑防呆在Shelly脚本中增加防误触发逻辑。例如收到“开”指令后设置一个3秒的“冷却期”在此期间忽略所有同类指令防止因网络波动导致消息重发造成的继电器快速通断。后备电源考虑为ESP-RFID、网络交换机和Mosquitto服务器如果是小型设备如树莓派配置UPS避免停电导致门禁系统完全失效。对于Shelly控制的电锁需了解其断电时的状态是开还是关并选择符合安全要求的锁具。将ESP-RFID与外部Tasmota/Shelly通过MQTT整合远不止是换了一种控制继电器的方式。它代表了一种架构思维的升级从单体固件走向分布式系统从硬编码逻辑走向可编程的、事件驱动的自动化。这个方案给了你一个坚实的、可扩展的基础框架。一旦跑通你会发现给这个系统增加一个新功能往往不再是去修改复杂的嵌入式代码而只是在Node-RED里拖拽几个节点或者在Shelly里写几行简单的脚本。这种灵活性和效率的提升才是这个项目带来的最大价值。我自己的车库门和室内几个智能灯联动就是基于这个架构稳定运行了超过一年期间增减设备、修改逻辑都无比顺畅。