基于Home Assistant与电子墨水屏的空气质量监测仪表盘DIY指南

发布时间:2026/8/20 14:01:55
基于Home Assistant与电子墨水屏的空气质量监测仪表盘DIY指南 1. 项目缘起为什么要在家里放一块空气质量“仪表盘”几年前我还在为家里的空气质量问题头疼。新装修的房子虽然通风了很久但总感觉空气有点“闷”特别是关窗开空调的时候。买过几个便携式的空气质量检测仪数据是有了但要么是放在角落里吃灰要么就是得打开手机App才能看到信息非常割裂。我一直想要一个能像时钟一样静静地摆在桌面上随时一瞥就能掌握全屋空气状况的“仪表盘”。它最好还能和家里的智能设备联动比如空气质量变差时自动打开空气净化器。直到我遇到了Home Assistant和电子墨水屏ePaper这两个绝佳的组合。Home Assistant作为本地化的智能家居中枢能聚合几乎所有品牌传感器的数据而电子墨水屏超低功耗、类纸质感、常显不伤眼的特性完美契合了“桌面信息牌”的需求。这个项目就是教你如何亲手搭建一个专属的、高度定制化的空气质量信息面板。它不只是一个显示设备更是你智能家居系统的“前端可视化界面”让你对家居环境了如指掌。2. 核心组件选型硬件与软件的“黄金搭档”搭建这个项目你需要准备硬件和软件两大部分。选型直接决定了项目的成本、复杂度和最终效果。我的选择基于几个原则易得性、性价比、可玩性高。2.1 硬件清单从屏幕到传感器电子墨水屏ePaper Display这是项目的“脸面”。我强烈推荐使用Waveshare微雪的系列产品型号丰富资料齐全。对于空气质量面板7.5英寸或更大的尺寸比较合适显示信息更从容。我选用的是7.5英寸黑白红三色墨水屏型号7.5inch e-Paper HAT。三色黑、白、红足以高亮显示超标的关键数据如PM2.5爆表用红色视觉效果和实用性兼备。它通过SPI接口与主控板通信功耗极低刷新一次屏幕只需几秒之后完全断电也能保持显示。主控板Single-Board Computer负责运行Home Assistant、驱动屏幕和获取传感器数据。主流选择有三个树莓派Raspberry Pi生态之王兼容性最好但近年来价格偏高且难买。如果你的主要目的就是跑Home Assistant它是最省心的选择。Orange Pi 等国产派性价比高性能往往更强。但需要一定的Linux调试能力部分GPIO引脚定义和驱动可能需要额外适配。旧笔记本或迷你主机如果你有闲置的x86设备性能最强扩展性最好但功耗和体积是劣势。我的选择是 Orange Pi 3 LTS。理由很简单在树莓派价格飞涨的时期它提供了接近的性能、更丰富的接口双频WiFi、千兆网口和更低的价格。对于驱动一个墨水屏和连接几个传感器来说性能绰绰有余。空气质量传感器数据的源头。这里分两个层面已有设备如果你家里已经有小米空气净化器、青萍空气检测仪、AQARA温湿度传感器等接入Home Assistant的设备那么恭喜你数据源已经就位。Home Assistant的强大之处就在于能整合这些异构设备的数据。新增传感器如果你想获得更专业或更本地化的数据可以考虑添加独立的传感器模块。例如SGP30TVOC总挥发性有机物和eCO2等效二氧化碳传感器对甲醛等气体敏感非常适合新房监测。PMS5003激光PM2.5/PM10传感器数据准确但需要风扇有一定噪音和体积。BME280高精度温湿度、气压传感器成本低精度足以满足家用。我采用了混合方案利用Home Assistant接入的小米空气净化器提供PM2.5、温湿度并额外通过GPIO连接了一个SGP30到Orange Pi上专门监测TVOC弥补了小米设备在这方面的缺失。其他杜邦线连接传感器、SD卡用于给主控板安装系统、5V电源、一个合适的外壳3D打印或现成盒子。2.2 软件栈Home Assistant 与驱动层Home Assistant Operating System (HAOS)这是最推荐的方式。它是一个完整的、为Home Assistant优化的轻量级操作系统直接刷入SD卡即可。它包含了Supervisor管理面板、Add-on商店方便安装插件和完整的Docker环境管理和扩展都非常方便。我们将把HAOS安装到Orange Pi上。Home Assistant Core如果你选择在已有的Linux系统如Ubuntu上通过Docker安装那就是Core版本。HAOS本质上是一个封装好的Core管理环境。对于这个项目HAOS更简单。Inkplate 或 Waveshare 驱动库为了在Python中控制墨水屏我们需要对应的驱动。Waveshare提供了完善的Python库。我们将把这个驱动库集成到Home Assistant的自动化环境中。ESPHome这是一个神器如果你新增的传感器如SGP30是通过GPIO直接连到主控板你可以选择用Python直接读取但这会增加系统复杂度。更优雅的方式是使用ESPHome在一个便宜的ESP8266/ESP32开发板上运行ESPHome固件用它来读取传感器数据然后通过WiFi以MQTT或直接API的方式上报给Home Assistant。这样实现了传感与控制分离布线更灵活也减轻了主控板的负担。本项目我将采用ESPHome方案来接入SGP30。3. 系统搭建与集成从零到一的完整链路这一部分我们将一步步把硬件组装起来并让软件系统跑通。3.1 硬件连接与初步测试首先断开所有电源进行硬件连接。安装HAOS到Orange Pi前往Home Assistant官网下载对应Orange Pi 3 LTS的HAOS镜像。使用BalenaEtcher等工具将镜像写入SD卡。将SD卡插入Orange Pi连接网线首次启动推荐用有线网络更稳定上电。等待约10-20分钟在浏览器中输入http://orangepi的本地IP:8123你需要在路由器后台查看新设备IP即可完成Home Assistant的初始化设置。连接墨水屏7.5英寸墨水屏HAT通常直接扣在Orange Pi的GPIO引脚上。务必对照引脚图Orange Pi和树莓派的GPIO引脚定义不同盲插可能烧毁屏幕或主板。以Orange Pi 3 LTS为例需要确保屏幕的VCC、GND、DIN、CLK、CS、DC、RST、BUSY引脚与主板的对应引脚连接正确。Waveshare官网通常提供多种主板的连接示例。连接ESPHome传感器节点将SGP30模块的VCC、GND、SCL、SDA引脚连接到ESP32开发板的对应引脚。然后通过USB线将ESP32连接到电脑用于后续烧录固件。3.2 软件环境配置让Home Assistant认识新硬件在HAOS中安装ESPHome插件进入Home Assistant后台侧边栏点击“配置” - “加载项”。在加载项商店中搜索并安装“ESPHome”。安装完成后启动它并勾选“显示在边栏”。现在侧边栏会出现ESPHome的图标。创建并烧录ESPHome固件点击进入ESPHome点击右下角“新建设备”。给你的设备起个名字比如air_quality_sensor选择ESP32开发板型号。在生成的YAML配置文件中我们需要添加SGP30的配置。一个最简化的示例esphome: name: air_quality_sensor platform: ESP32 board: nodemcu-32s i2c: sda: 21 scl: 22 sensor: - platform: sgp30 tvoc: name: TVOC Concentration id: tvoc_sensor eco2: name: eCO2 Concentration id: eco2_sensor update_interval: 10s address: 0x58 wifi: ssid: !secret wifi_ssid password: !secret wifi_password api: encryption: key: !secret api_encryption_key ota: password: !secret ota_password将wifi_ssid,wifi_password等替换成你的实际信息或使用ESPHome的“安装”向导它会引导你通过USB线直接烧录固件到ESP32。烧录成功后ESP32会自动连接WiFi。在Home Assistant中集成设备烧录完成后回到Home Assistant通常几分钟内系统会自动发现这个ESPHome设备并弹出通知点击“配置”即可完成集成。完成后在“配置”-“设备与服务”-“实体”中你应该能看到sensor.tvoc_concentration和sensor.eco2_concentration这两个新实体。同样的如果你接入了小米空气净化器通过安装“Xiaomi Miot Auto”集成也能将它的传感器数据添加进来。3.3 墨水屏驱动集成最关键的“临门一脚”这是整个项目最具技术挑战性也最有成就感的一步。我们需要在Home Assistant环境中运行一个Python脚本这个脚本能调用墨水屏驱动库并能获取Home Assistant的传感器数据。在HAOS中启用SSH访问进入“配置”-“加载项”安装“Terminal SSH”插件并启动。这为我们提供了一个命令行操作界面。安装Python依赖通过SSH连接到你的Orange PiHAOS。HAOS基于Linux但系统是只读的我们需要将驱动库安装到可读写的挂载分区。更推荐的方法是使用Add-on的“自定义仓库”功能但这里介绍一种更直接、理解更深刻的手动方法。首先进入一个可写目录比如/config你的Home Assistant配置目录。cd /config创建一个Python虚拟环境如果系统没有python3-venv可能需要先安装HAOS的终端可能受限这一步有时可以省略直接使用系统Pythonpython3 -m venv epaper_venv source epaper_venv/bin/activate然后安装必要的库。Waveshare的驱动通常需要Pillow图像处理和RPi.GPIOGPIO控制。对于Orange Pi我们需要使用替代库如OPi.GPIO。pip install pillow opi-gpio spidev接下来从Waveshare官网下载对应屏幕型号的Python驱动库解压后将其中的主要驱动文件如epd7in5b_HD.py复制到/config目录下。编写屏幕刷新脚本在/config下创建update_display.py。这个脚本的核心逻辑是通过Home Assistant的RESTful API需要创建长期访问令牌或更优雅的homeassistant_api库获取传感器实体状态。使用Pillow库在内存中绘制一张图片布局各种空气质量数据文字、数值、图表、图标。调用墨水屏驱动库将这张图片发送到屏幕并刷新。一个极度简化的代码框架示例#!/usr/bin/env python3 import requests import json from PIL import Image, ImageDraw, ImageFont import epd7in5b_HD # 你的屏幕驱动文件 import time # Home Assistant配置 HA_URL http://localhost:8123/api HA_TOKEN 你的长期访问令牌 HEADERS { Authorization: fBearer {HA_TOKEN}, content-type: application/json, } # 获取传感器状态 def get_entity_state(entity_id): url f{HA_URL}/states/{entity_id} response requests.get(url, headersHEADERS) if response.status_code 200: return response.json().get(state) else: return N/A # 主函数 def main(): # 初始化屏幕 epd epd7in5b_HD.EPD() epd.init() epd.Clear() # 创建画布 image Image.new(1, (epd.width, epd.height), 255) # 白色背景 draw ImageDraw.Draw(image) # 加载字体需要将字体文件放入/config font_large ImageFont.truetype(/config/arial.ttf, 40) font_small ImageFont.truetype(/config/arial.ttf, 24) # 获取数据 pm25 get_entity_state(sensor.xiaomi_air_purifier_pm25) tvoc get_entity_state(sensor.tvoc_concentration) temp get_entity_state(sensor.xiaomi_air_purifier_temperature) humidity get_entity_state(sensor.xiaomi_air_purifier_humidity) # 绘制文本 draw.text((10, 10), fPM2.5: {pm25} µg/m³, fontfont_large, fill0) draw.text((10, 60), fTVOC: {tvoc} ppb, fontfont_large, fill0) draw.text((10, 110), fTemp: {temp} °C, fontfont_small, fill0) draw.text((10, 140), fHumidity: {humidity} %, fontfont_small, fill0) # ... 可以绘制更多内容如时间、空气质量等级、简易图表等 # 显示图片 epd.display(epd.getbuffer(image)) epd.sleep() # 让屏幕进入睡眠省电模式 if __name__ __main__: main()注意你需要从Home Assistant后台点击你的用户名 - “创建令牌”生成一个长期访问令牌并替换代码中的HA_TOKEN。同时将字体文件如arial.ttf也放入/config目录。创建自动化定时刷新屏幕我们不可能每次都手动运行脚本。在Home Assistant中创建自动化每10分钟或当传感器数据变化时触发脚本执行。 在/config/automations.yaml中添加或在Web界面中配置- alias: Update E-Paper Display trigger: - platform: time_pattern minutes: /10 # 每10分钟触发一次 - platform: state entity_id: - sensor.xiaomi_air_purifier_pm25 - sensor.tvoc_concentration # 当这些传感器状态改变时也触发 action: - service: shell_command.update_epaper然后在/config/configuration.yaml中定义这个shell_commandshell_command: update_epaper: python3 /config/update_display.py重启Home Assistant后自动化便会生效。4. 界面设计与数据可视化让信息一目了然硬件和基础链路打通后下一步就是设计一个美观实用的显示界面。电子墨水屏刷新慢、颜色有限因此设计原则是信息优先、布局清晰、避免频繁刷新。4.1 布局规划与视觉层次我将屏幕分为四个主要区域核心指标区左上占比40%用最大字体显示最关键的PM2.5和TVOC数值并配以直观的空气质量等级文字如“优”、“良”、“轻度污染”并用红色高亮显示“污染”等级。环境参数区右上占比30%显示温度、湿度、二氧化碳eCO2浓度。采用较小的字体排列整齐。趋势图表区下方占比25%绘制过去12小时PM2.5的折线图。虽然墨水屏刷新慢不适合动态图表但每隔一段时间如1小时更新一次静态趋势图对于判断空气变化规律非常有价值。这需要脚本具备简单的数据存储如写入一个CSV文件和绘图能力。状态与时间区底部占比5%显示最后更新时间、WiFi连接状态、屏幕下次刷新倒计时。4.2 使用Pillow进行高级绘图前面的示例只用了简单的文字。为了绘制趋势图和图标需要更深入地使用Pillow。绘制折线图需要计算时间轴和数值轴的坐标映射。假设我们每小时存储一个PM2.5数据到列表pm25_history中。# ... 获取历史数据这里简化为例 history [12, 15, 18, 22, 20, 17, 15, 10, 8, 9, 12, 14] # 模拟12小时数据 chart_width 400 chart_height 150 chart_x 50 chart_y 250 # 计算坐标 max_val max(history) min_val min(history) val_range max_val - min_val if max_val ! min_val else 1 points [] for i, val in enumerate(history): x chart_x (i / (len(history)-1)) * chart_width y chart_y chart_height - ((val - min_val) / val_range) * chart_height points.append((x, y)) # 绘制坐标轴和折线 draw.line([(chart_x, chart_y), (chart_x, chart_ychart_height), (chart_xchart_width, chart_ychart_height)], fill0, width2) if len(points) 1: draw.line(points, fill0, width3) # 在折线点画小圆 for point in points: draw.ellipse([point[0]-3, point[1]-3, point[0]3, point[1]3], fill0)添加图标可以事先准备好表示晴天、雨天、风扇净化器的简单黑白图标PNG格式用Image.open()加载并粘贴到画布指定位置直观表示设备状态或天气。4.3 动态逻辑与条件格式让显示内容更具交互性颜色触发当PM2.5 75 或 TVOC 500 时对应的数值和标签用红色绘制调用draw.text(..., fillepd7in5b_HD.RED)。设备状态查询空气净化器的开关状态如fan.xiaomi_air_purifier如果处于开启状态则在屏幕上显示一个“风扇转动”的图标。建议文本根据空气质量等级显示不同的建议如“建议开窗通风”、“建议开启净化器”、“请佩戴口罩”。5. 优化、排错与进阶玩法项目基本完成后你会遇到一些实际问题这里分享我的踩坑经验和优化思路。5.1 常见问题与解决方案屏幕刷新出现残影或全黑/全白原因墨水屏刷新需要特定的波形序列。如果刷新过程被意外中断如脚本崩溃、断电屏幕可能处于异常状态。解决在驱动中确保每次刷新都遵循init()-Clear()-display()-sleep()的完整流程。在脚本开头加入异常捕获无论如何都尝试执行epd.sleep()或epd.init()来重置屏幕。也可以准备一个“清屏”的脚本在出现问题时手动运行。Home Assistant API调用失败原因令牌失效、IP地址变化如果使用localhost在Docker容器内可能指代错误、网络问题。解决使用HAOS时API地址用http://supervisor/core/api或http://homeassistant:8123/api可能比localhost更可靠。在脚本中增加重试机制和详细的错误日志记录将日志写入/config/display.log便于排查。自动化触发不执行脚本原因shell_command执行环境权限不足或Python虚拟环境未激活。解决一种更稳健的方法是将屏幕刷新脚本封装为一个Home Assistant自定义集成或Python脚本Python Script。但这需要更复杂的开发。简易方案是在shell_command中指定完整的Python路径和激活环境shell_command: update_epaper: /config/epaper_venv/bin/python /config/update_display.pyESPHome传感器数据不稳定或丢失原因WiFi信号弱、I2C总线干扰、传感器预热不足。解决确保ESP32部署位置信号良好。SGP30等气体传感器需要长时间预热可能长达24小时才能达到最佳稳定性期间数据会有漂移这是正常的。在ESPHome配置中增加滤波和校准选项。5.2 功耗与稳定性优化减少不必要的刷新墨水屏每刷新一次都有寿命损耗通常几十万次。不要设置太短的刷新间隔如1分钟。空气质量数据变化相对缓慢10-30分钟刷新一次完全足够。我的自动化采用了“时间触发每30分钟 重要传感器状态变化触发”的双重策略。使用屏幕睡眠模式刷新完成后务必调用epd.sleep()。这是驱动屏幕进入深度省电模式的关键此时屏幕仅维持显示内容功耗可低至接近零。脚本健壮性在Python脚本中使用try...except...finally结构确保任何错误下都能执行epd.sleep()防止屏幕锁死。5.3 进阶扩展思路这个项目是一个强大的基础框架你可以在此基础上无限扩展多数据源融合除了空气质量还可以显示天气预报、日历日程、待办事项、系统监控CPU温度、内存使用率等。只需在脚本中调用更多Home Assistant实体或外部API。交互功能在屏幕周围增加几个物理按钮接GPIO通过脚本检测按键实现切换显示页面、手动刷新、控制智能设备如开关灯等功能。多房间监测如果你有多个ESPHome传感器部署在不同房间可以在一个屏幕上通过分区域或翻页的形式轮播显示所有房间的数据。美观化升级使用更优雅的字体如思源黑体、设计更专业的图标和布局甚至可以模仿一些商业天气时钟的UI让你的面板不仅是工具也是家居装饰。这个项目从构思到实现我花了几个周末的时间期间遇到了驱动兼容、API调用、布局调整等各种问题。但当那块墨水屏第一次清晰地显示出家里的PM2.5数值时那种“创造之物”开始工作的满足感是购买任何成品都无法替代的。它不仅仅是一个显示器更是我个人对智能家居理解的一个物理化身。整个系统完全本地运行数据隐私掌握在自己手中响应速度快且可以根据自己的需求随时调整。如果你也对智能家居和硬件DIY有兴趣强烈建议动手尝试一下从获取第一个传感器数据开始你会打开一扇新世界的大门。