基于ESP32与Home Assistant的智能厕所占用监测系统实战
1. 项目概述与核心需求解析
在任何一个人员密集的办公环境里,共享设施的排队问题总是让人头疼,尤其是卫生间。我们公司就曾深受其扰:员工数量增长,但厕所隔间数量固定,导致大家经常在走廊里“望门兴叹”,既浪费时间又影响心情。物理上增加隔间成本太高,但我们可以换个思路——优化信息传递的效率。与其让员工亲自走到门口才发现里面有人,不如提前告诉他们哪个隔间是空闲的。这就是我们决定动手搭建这套“智能厕所占用状态监测系统”的初衷。
简单来说,这个项目就是一个典型的物联网(IoT)应用,它把物理世界的状态(厕所门是否锁上)转化为数字信号,并通过网络实时展示出来。整个系统的核心由三部分组成:安装在每个厕所门上的状态检测模块、分布在办公室各处的状态指示灯,以及一个负责统一管理和逻辑处理的中央控制服务器。我们选择了ESP32作为前端的“感知与控制大脑”,因为它集成了Wi-Fi和蓝牙,性能足够且开发资源丰富;后端则采用了开源的Home Assistant平台,它就像一个智能家居的“操作系统”,能轻松集成各种设备并编写自动化规则。通过这套系统,员工在工位上就能通过醒目的指示灯,或者甚至手机上的App,一眼看清哪个厕所正在使用,哪个空闲可用,从而做出最优选择,彻底告别盲目排队。
2. 系统整体架构与方案选型
2.1 为什么是ESP32 + Home Assistant?
在项目启动前,我们评估了几种方案。最简单的可能是用红外对射传感器,但厕所环境复杂,误触发率高。也考虑过压力垫,但安装和维护麻烦。最终,我们选择了最直接可靠的信号源:门锁状态。当一个人在厕所内锁上门时,这是一个明确且私密的“占用”信号。检测这个状态,我们用了最经典的电路闭合原理,成本极低且极其可靠。
对于处理单元,ESP32几乎是当前物联网项目的首选。原因有三:第一,它原生支持Wi-Fi和低功耗蓝牙(BLE),无需额外模块就能联网;第二,其双核处理器和充足的内存足以应对简单的逻辑判断和网络通信任务;第三,围绕ESP32的生态极其繁荣,特别是ESPHome这个项目,它能让我们用简单的YAML配置文件来定义设备的功能和自动化,无需编写复杂的嵌入式C++代码,大大降低了开发门槛。
对于中央控制平台,Home Assistant(HA)是我们的不二之选。它是一个高度可定制化的开源家庭自动化平台,但其能力远不止于家庭。HA的优势在于:强大的集成能力(支持数千种设备)、本地化运行(数据无需上传云端,隐私和响应速度有保障)、灵活的自动化引擎(可以用图形化界面或YAML编写复杂的触发-动作逻辑)。我们将ESP32设备通过ESPHome无缝接入HA,由HA来统一接收所有厕所的状态,并决定如何控制各个指示灯。
2.2 系统架构详解
整个系统的数据流和工作逻辑是这样的:
- 感知层:每个厕所门内安装一个“主模块”。它本质上是一个包含了ESP32开发板、继电器模块和LED灯条的盒子。模块的核心传感器是一个自制门磁:在门框和门板上各贴一小片导电极片(我们用的是弹簧片和亚克力板制作的简易接触开关)。当门锁上时,锁舌会压迫这两个极片使其接触,电路闭合。
- 网络层:ESP32通过公司的Wi-Fi网络,将“电路闭合”(门锁住)或“电路断开”(门打开)这个状态变化,实时发送到家庭助理服务器。
- 控制层:Home Assistant服务器(我们安装在树莓派4B上)持续监听所有ESP32设备的状态。我们编写了一条自动化规则:“当某个厕所门状态变为‘锁定’时,触发对应事件”。
- 执行层:这个事件会同时做两件事:
- 通知该厕所门上的“主模块”:让其继电器动作,将门上的指示灯从绿色切换为红色。
- 通知部署在办公区(如茶水间、走廊)的“指示灯模块”:点亮代表该厕所的LED灯段(例如,男厕用红色,女厕用蓝色)。
- 展示层:最终,员工通过两种方式获知状态:一是走到厕所区域时,直接看门上的红/绿灯;二是在办公区,抬头看集中指示灯面板,就知道哪个厕所有人在用。
这个架构清晰地将数据采集、逻辑判断和状态展示解耦,使得系统非常稳定且易于扩展。比如,未来如果想增加手机推送通知,只需要在HA里再添加一个通知动作即可。
3. 硬件准备与核心模块制作
3.1 物料清单与选型考量
硬件部分分为“主模块”和“指示灯模块”两类,物料需要分别准备。
主模块(每个厕所门一个):
- 核心控制器:ESP32开发板(推荐带板载天线和USB口的型号,如ESP32-WROOM-32)。选择它是因为其GPIO口丰富,且3.3V逻辑电平与后续模块匹配。
- 状态检测单元:自制接触开关。你需要准备两小片有弹性的金属片(我们从旧电池座拆的弹簧)、一小块绝缘板(如亚克力)以及导线。注意:这里我们使用低电压(3.3V)、小电流的直流信号进行检测,绝对安全。
- 状态指示单元:
- 高亮度LED灯珠(1W),绿色和红色各一颗。1W的LED亮度足够在白天清晰可见。
- 1通道继电器模块(低电平触发)。为什么用继电器控制LED而不是直接用ESP32的GPIO?因为1W的LED工作电流约300mA,远超ESP32单个GPIO最大输出电流(通常40mA),直接驱动会损坏主板。继电器起到了“用小电流开关控制大电流电路”的作用。
- 电源单元:
- Mean Well RS-15-5开关电源(5V/3A输出)。这是一个工业级品牌,稳定可靠。它将220V交流电转换为5V直流电。
- 5V转3.3V降压模块(如果ESP32板子没有自带)。因为继电器模块和ESP32的逻辑电压是3.3V。
- 接线端子、电线、电工胶布等辅材。
- 外壳:3D打印外壳。我们从Thingiverse找了一个基础模型,并根据自己的元件尺寸用Fusion 360进行了修改。材料使用PLA(聚乳酸)即可,它易于打印且强度足够。主模块外壳需要设计两个透光孔位用于安装LED。
指示灯模块(办公区放置):
- 核心控制器:同样使用ESP32开发板。
- 指示单元:使用多颗1W LED灯珠(红、蓝或其他颜色),或者直接使用低电压的LED灯带。需要两个独立的电路通道,分别指示不同厕所。
- 驱动单元:2通道继电器模块。因为需要独立控制两路LED。
- 电源单元:5V/4A的开关电源,为ESP32和两路LED供电。如果指示灯亮度高、数量多,需计算总电流(每颗1W LED约200-300mA),确保电源功率充足。
- 外壳:同样3D打印。我们设计了一个分层扩散结构,将LED光均匀柔和地散发出来,避免刺眼。外壳材料使用了透光性好的PETG(聚对苯二甲酸乙二醇酯) filament,分别用红色透明和蓝色透明材料打印对应部分,效果很棒。
注意:安全第一! 整个项目中,只有从市电插座到开关电源输入端涉及220V交流电。请务必确保这部分线路连接牢固,使用绝缘良好的电线,并最好将开关电源固定在绝缘外壳内。开关电源输出端之后,全部是安全的5V/3.3V直流低压电路,即使触摸也不会触电。如果你是电子新手,建议先在网上学习基本的焊接和电路连接知识。
3.2 主模块(门状态检测器)制作详解
主模块是整个系统的信息源头,它的可靠性和准确性至关重要。
第一步:制作门状态传感器。 这不是购买成品门磁,而是自制一个“锁舌触发开关”。原理很简单:当门锁上时,锁舌伸出,会物理按压两个分离的导电触点,使其连接。
- 取一小块薄亚克力板(约2x3厘米)作为基底。
- 在亚克力板上固定两个有弹性的金属弹簧片,它们彼此非常接近但绝不接触(间隔1-2毫米)。可以用热熔胶或螺丝固定。
- 将两个弹簧片分别焊接上导线,一根导线连接到ESP32的一个GPIO口(我们记为
DOOR_SENSOR_PIN),另一根导线连接到ESP32的GND(地)。 - 将这个传感器单元安装在门框上,位置要精确对准门锁锁舌伸出的地方。调整弹簧片的高度,使得只有当门完全锁上时,锁舌才刚好能同时碰到两个弹簧片并将其压合。
- 在ESP32程序中,将
DOOR_SENSOR_PIN设置为上拉输入模式。这样,当弹簧片断开(门开)时,引脚被内部电阻拉高,读到高电平(1);当弹簧片闭合(门锁)时,引脚直接接地,读到低电平(0)。通过检测这个引脚的电平变化,就能判断门的状态。
第二步:连接LED与继电器。
- 继电器接线:继电器模块通常有3个控制端:VCC(接3.3V)、GND(接GND)、IN(接ESP32的GPIO,我们记为
RELAY_PIN)。以及3个被控端:COM(公共端)、NO(常开端)、NC(常闭端)。我们使用常开模式。 - LED接线:准备两颗1W的LED(一红一绿)。每颗LED需要串联一个限流电阻。电阻值计算:
R = (电源电压 - LED正向电压) / LED工作电流。假设使用5V电源,红色LED正向电压约2.0V,工作电流300mA,则R = (5V - 2.0V) / 0.3A ≈ 10Ω,功率P = I²R = 0.09 * 10 = 0.9W,因此需要选择10Ω/1W以上的电阻。绿色LED正向电压约3.2V,计算得R ≈ 6Ω/1W。务必为每颗LED独立计算并焊接限流电阻,否则LED会瞬间烧毁。 - 将绿色LED的正极(通过限流电阻)接到继电器1的COM端,红色LED的正极接到继电器1的NO端。两颗LED的负极都接到电源的GND。这样,当继电器不动作时(
RELAY_PIN为高电平),COM与NO断开,绿色LED回路不通,红色LED回路也不通(实际上我们希望此时绿灯亮,所以这个接法需要调整,详见下文“逻辑设计”)。 - 实际上,我们希望实现“空闲亮绿灯,占用亮红灯”。更合理的接法是:将绿灯接在继电器的常闭端(NC),红灯接在常开端(NO),公共端(COM)接5V正极。这样,继电器断电时(门空闲),COM与NC连通,绿灯亮;继电器吸合时(门占用),COM与NO连通,红灯亮。这才是正确的逻辑。
第三步:供电与组装。
- 将5V开关电源的输出,正极(+5V)同时接到继电器模块的VCC(注意继电器模块若是5V供电则直接接,若是3.3V供电则需通过降压模块)和LED电路的电源正极。负极(GND)连接到所有模块的GND,形成共地。
- 将ESP32、继电器模块、LED及限流电阻、门传感器全部焊接并连接好后,使用万用表通断档仔细检查所有连接,特别是电源正负极不能短路。
- 将所有元件小心地装入3D打印的外壳中,固定好。将门传感器导线从外壳引出,并留出足够长度连接到门框。外壳的透光窗要对准LED。
3.3 指示灯模块制作详解
指示灯模块的电路相对简单,因为它只接收指令,不检测状态。
- 使用一个2通道继电器模块。每个通道独立控制一路LED(例如,通道1控制“男厕占用”红色LED组,通道2控制“女厕占用”蓝色LED组)。
- LED组的接线方式与主模块类似:每路LED串联对应的限流电阻后,正极接对应继电器通道的COM端,COM端接5V正极;LED负极接GND。继电器的NO端悬空不用,NC端空置。这样,当HA发送“开”指令时,ESP32给继电器IN脚低电平,继电器吸合,COM与NO连通,但由于NO未接线,LED回路实际是断开的(灯灭)。等等,这逻辑反了。
- 纠正:为了实现“收到占用信号时灯亮”,我们应该将LED正极接5V,负极接到继电器的COM端,继电器的NO端接GND。当继电器不动作(空闲),COM与NO断开,LED电路不通,灯灭。当继电器吸合(占用),COM与NO连通,LED负极接地,形成回路,灯亮。这才是正确的“高边开关”接法(控制负极)。
- 将两个继电器模块的IN控制引脚分别连接到ESP32的两个GPIO口(如GPIO4, GPIO5)。
- 同样,做好绝缘和固定,装入设计好的指示灯外壳。这个外壳可以做得更有设计感,比如做成公司Logo形状或者简洁的方形面板。
4. 软件配置:ESPHome与Home Assistant联动
硬件是躯体,软件才是灵魂。我们通过ESPHome和Home Assistant的配置,让所有硬件“活”起来并协同工作。
4.1 ESPHome设备配置
ESPHome的配置以YAML文件形式存在,非常直观。以下是一个主模块的示例配置文件 toilet_door_sensor.yaml:
关键点解析:
filters: - invert::这是一个关键处理。因为我们的传感器是“常开”型(门开断开,门关闭合),且配置了INPUT_PULLUP(引脚默认高电平)。当门关闭合时,引脚被拉低到GND,读数为LOW(0)。invert过滤器将其反转,使得传感器状态在门锁时为ON(True),更符合直觉。on_state::这是一个自动化块,定义当传感器状态改变时要执行的本地动作。这里实现了本地逻辑:门锁(占用)时,打开红灯继电器、关闭绿灯继电器;门开(空闲)时反之。这样即使网络暂时中断,门上的指示灯逻辑依然正确。inverted: true:这个设置取决于你的继电器模块。常见的继电器模块是低电平触发(信号脚给低电平时吸合)。如果设置inverted: true,则ESPHome内部“打开”开关的命令会输出低电平。如果不确定,可以先不设置,测试一下开关动作是否与预期相反再调整。
对于指示灯模块,配置更简单,它只需要定义两个继电器开关,并接收来自HA的命令。配置文件 toilet_indicator.yaml:
将这两个配置文件分别通过ESPHome的编辑器编译并烧录到对应的ESP32设备中。设备启动后,会自动连接到Wi-Fi,并出现在Home Assistant的集成列表中。
4.2 Home Assistant自动化配置
当所有ESP32设备都成功接入Home Assistant后,我们可以在HA的“配置 -> 设备与服务”中看到它们,并且每个实体(如开关、传感器)都可以使用。
现在,我们需要创建自动化,将门传感器的状态变化,传递到指示灯模块。在HA中,有图形化和YAML两种方式,这里展示更强大清晰的YAML方式。在configuration.yaml 或单独的 automations.yaml 文件中添加:
这个自动化实现了核心逻辑:任何一个厕所门的开关状态发生变化,都会触发自动化,然后根据两个门当前的实际状态,去设置对应的两个指示灯的开关。这样,办公室的指示灯就能实时、准确地反映厕所的占用情况。
5. 安装、调试与优化心得
5.1 现场安装注意事项
硬件安装是项目成功的关键一步,细节决定成败。
- 门传感器安装精度:这是整个系统最易出错的环节。自制接触开关的弹簧片弹性和位置必须精心调整。我们踩过的坑是:初期安装后,发现有时门关上了但显示未占用。原因是锁舌没有完全压紧两个弹簧片,导致接触电阻过大,ESP32无法可靠识别为低电平。解决方法:使用万用表的“通断档”或“电阻档”在安装时实时测量。确保门锁上时,两弹簧片间电阻小于10欧姆;门打开时,电阻为无穷大。可以使用带背胶的铜箔或专门的微型簧片开关来提升可靠性。
- 电源与走线:厕所内通常没有现成的电源插座。我们是从天花板的照明电路取电(请注意,此操作涉及强电,务必由持有电工证的专业人员操作,或使用已通过安全认证的低压电源适配器从远处引电)。使用PVC线槽将5V直流电线整洁地布设到模块安装位置。所有接线点都必须用焊锡焊接牢固,并套上热缩管绝缘,防止潮气导致短路。
- Wi-Fi信号强度:ESP32需要稳定的网络连接。在安装主模块前,用手机测试一下厕所内的Wi-Fi信号强度。如果信号弱(小于-70dBm),考虑在附近增加一个无线中继器,或者选用带有外部天线接口的ESP32模块,并延长天线到信号更好的位置。
- 指示灯模块的摆放:指示灯应放置在办公室的视觉中心点,如主要通道的墙面、茶水间入口上方。确保其亮度在白天环境光下也清晰可辨,但又不能过于刺眼。我们使用了磨砂的PETG外壳和扩散板,让光线柔和均匀。
5.2 系统调试与故障排查
即使硬件和软件配置都正确,初次运行时也可能遇到问题。下面是一个快速排查清单:
| 现象 | 可能原因 | 排查步骤与解决方案 |
|---|---|---|
| ESP32设备无法连接Wi-Fi | 1. SSID/密码错误。 2. Wi-Fi信号太弱。 3. 路由器设置了MAC地址过滤。 |
1. 通过串口监视器查看ESPHome日志,确认连接错误信息。 2. 检查配置文件中的Wi-Fi信息。可先配置为手机热点测试。 3. 将ESP32的MAC地址加入路由器的允许列表。 |
| Home Assistant中看不到设备 | 1. ESPHome的api:配置缺失或错误。2. 防火墙/网络策略阻止了通信(端口6053)。 3. ESP32与HA主机不在同一局域网段。 |
1. 确认ESPHome配置文件中包含了api:部分。2. 在HA的ESPHome加载项中,尝试“手动添加”设备,输入其IP地址。 3. 确保它们IP地址前三位相同(如192.168.1.x)。 |
| 门状态变化,但指示灯不更新 | 1. HA自动化未正确触发或动作配置错误。 2. 指示灯模块的继电器接线逻辑错误。 3. 实体ID在自动化中写错。 |
1. 在HA的“开发者工具 -> 状态”中,手动触发门传感器实体,看状态是否变化。 2. 在“开发者工具 -> 服务”中,手动调用 switch.turn_on服务测试指示灯实体,看灯是否亮。3. 仔细核对自动化YAML中的每一个 entity_id,确保与设备实体名称完全一致(区分大小写和空格)。 |
| 指示灯状态与门状态相反 | 1. 门传感器逻辑定义反了(常开/常闭)。 2. 继电器触发模式(高/低电平)设置反了。 |
1. 调整ESPHome配置中binary_sensor的filters,增加或移除invert:。2. 调整ESPHome配置中 switch的inverted:参数(true改为false或反之)。 |
| 系统运行一段时间后ESP32重启 | 1. 电源功率不足,带不动LED和继电器。 2. Wi-Fi信号不稳定导致看门狗重启。 3. 代码中存在内存泄漏(ESPHome通常不会)。 |
1. 测量5V电源在LED全亮时的实际输出电压,如果低于4.8V,请换用功率更大的电源(如5V/5A)。 2. 优化Wi-Fi信号,或在ESPHome配置中增加 reboot_timeout: 0s禁用因Wi-Fi断开而重启的功能(不推荐,仅作测试)。 |
5.3 优化与扩展思路
基础系统运行稳定后,可以考虑一些增强功能:
- 增加占用超时提醒:有些人可能忘记解锁门。可以在HA自动化中增加条件:如果门状态为“占用”超过15分钟,则通过TTS(文字转语音)在办公室广播系统或该厕所的蓝牙音箱上播放轻柔的提醒音。
- 集成到公司内部通讯软件:利用Home Assistant的Webhook或通知功能,当厕所状态变为空闲时,可以向特定的Slack或钉钉频道发送消息。
- 数据统计与可视化:利用HA的“历史统计”传感器和Grafana等工具,统计每个厕所每天的使用高峰时段、平均使用时长等,为后勤管理提供数据支持。
- 低功耗优化(电池版):如果布线困难,可以考虑电池供电。使用ESP32的深度睡眠模式,仅在门状态变化时唤醒并发送数据,可以大大延长电池寿命。但这需要重新设计传感器电路,使其能产生中断信号唤醒ESP32。
- 提升传感器可靠性:可以增加冗余传感器,例如在门锁传感器的基础上,再加一个毫米波雷达传感器(如LD2410)检测室内是否真的有人,避免因门未锁好或传感器故障导致的误报。
这套系统自部署以来,已经无故障运行了两年多,实实在在地解决了我们办公室的老大难问题。从技术上看,它并不复杂,但将ESP32的灵活性、ESPHome的便捷性以及Home Assistant的强大整合能力结合在了一起,形成了一个稳定、实用且可扩展的解决方案。最让我有成就感的是,它从一个具体的痛点出发,用可及的硬件和开源软件,创造出了看得见摸得着的效率提升。如果你也在受类似问题困扰,不妨动手试试,这个过程本身就是一个极佳的物联网学习项目。