量監(jiān)測儀表盤DIY指南)
1. 項目緣起為什么要在家里放一塊空氣質(zhì)量“儀表盤”幾年前我還在為家里的空氣質(zhì)量問題頭疼。新裝修的房子雖然通風(fēng)了很久但總感覺空氣有點“悶”特別是關(guān)窗開空調(diào)的時候。買過幾個便攜式的空氣質(zhì)量檢測儀數(shù)據(jù)是有了但要么是放在角落里吃灰要么就是得打開手機(jī)App才能看到信息非常割裂。我一直想要一個能像時鐘一樣靜靜地擺在桌面上隨時一瞥就能掌握全屋空氣狀況的“儀表盤”。它最好還能和家里的智能設(shè)備聯(lián)動比如空氣質(zhì)量變差時自動打開空氣凈化器。直到我遇到了Home Assistant和電子墨水屏ePaper這兩個絕佳的組合。Home Assistant作為本地化的智能家居中樞能聚合幾乎所有品牌傳感器的數(shù)據(jù)而電子墨水屏超低功耗、類紙質(zhì)感、常顯不傷眼的特性完美契合了“桌面信息牌”的需求。這個項目就是教你如何親手搭建一個專屬的、高度定制化的空氣質(zhì)量信息面板。它不只是一個顯示設(shè)備更是你智能家居系統(tǒng)的“前端可視化界面”讓你對家居環(huán)境了如指掌。2. 核心組件選型硬件與軟件的“黃金搭檔”搭建這個項目你需要準(zhǔn)備硬件和軟件兩大部分。選型直接決定了項目的成本、復(fù)雜度和最終效果。我的選擇基于幾個原則易得性、性價比、可玩性高。2.1 硬件清單從屏幕到傳感器電子墨水屏ePaper Display這是項目的“臉面”。我強(qiáng)烈推薦使用Waveshare微雪的系列產(chǎn)品型號豐富資料齊全。對于空氣質(zhì)量面板7.5英寸或更大的尺寸比較合適顯示信息更從容。我選用的是7.5英寸黑白紅三色墨水屏型號7.5inch e-Paper HAT。三色黑、白、紅足以高亮顯示超標(biāo)的關(guān)鍵數(shù)據(jù)如PM2.5爆表用紅色視覺效果和實用性兼?zhèn)?。它通過SPI接口與主控板通信功耗極低刷新一次屏幕只需幾秒之后完全斷電也能保持顯示。主控板Single-Board Computer負(fù)責(zé)運行Home Assistant、驅(qū)動屏幕和獲取傳感器數(shù)據(jù)。主流選擇有三個樹莓派Raspberry Pi生態(tài)之王兼容性最好但近年來價格偏高且難買。如果你的主要目的就是跑Home Assistant它是最省心的選擇。Orange Pi 等國產(chǎn)派性價比高性能往往更強(qiáng)。但需要一定的Linux調(diào)試能力部分GPIO引腳定義和驅(qū)動可能需要額外適配。舊筆記本或迷你主機(jī)如果你有閑置的x86設(shè)備性能最強(qiáng)擴(kuò)展性最好但功耗和體積是劣勢。我的選擇是 Orange Pi 3 LTS。理由很簡單在樹莓派價格飛漲的時期它提供了接近的性能、更豐富的接口雙頻WiFi、千兆網(wǎng)口和更低的價格。對于驅(qū)動一個墨水屏和連接幾個傳感器來說性能綽綽有余??諝赓|(zhì)量傳感器數(shù)據(jù)的源頭。這里分兩個層面已有設(shè)備如果你家里已經(jīng)有小米空氣凈化器、青萍空氣檢測儀、AQARA溫濕度傳感器等接入Home Assistant的設(shè)備那么恭喜你數(shù)據(jù)源已經(jīng)就位。Home Assistant的強(qiáng)大之處就在于能整合這些異構(gòu)設(shè)備的數(shù)據(jù)。新增傳感器如果你想獲得更專業(yè)或更本地化的數(shù)據(jù)可以考慮添加獨立的傳感器模塊。例如SGP30TVOC總揮發(fā)性有機(jī)物和eCO2等效二氧化碳傳感器對甲醛等氣體敏感非常適合新房監(jiān)測。PMS5003激光PM2.5/PM10傳感器數(shù)據(jù)準(zhǔn)確但需要風(fēng)扇有一定噪音和體積。BME280高精度溫濕度、氣壓傳感器成本低精度足以滿足家用。我采用了混合方案利用Home Assistant接入的小米空氣凈化器提供PM2.5、溫濕度并額外通過GPIO連接了一個SGP30到Orange Pi上專門監(jiān)測TVOC彌補了小米設(shè)備在這方面的缺失。其他杜邦線連接傳感器、SD卡用于給主控板安裝系統(tǒng)、5V電源、一個合適的外殼3D打印或現(xiàn)成盒子。2.2 軟件棧Home Assistant 與驅(qū)動層Home Assistant Operating System (HAOS)這是最推薦的方式。它是一個完整的、為Home Assistant優(yōu)化的輕量級操作系統(tǒng)直接刷入SD卡即可。它包含了Supervisor管理面板、Add-on商店方便安裝插件和完整的Docker環(huán)境管理和擴(kuò)展都非常方便。我們將把HAOS安裝到Orange Pi上。Home Assistant Core如果你選擇在已有的Linux系統(tǒng)如Ubuntu上通過Docker安裝那就是Core版本。HAOS本質(zhì)上是一個封裝好的Core管理環(huán)境。對于這個項目HAOS更簡單。Inkplate 或 Waveshare 驅(qū)動庫為了在Python中控制墨水屏我們需要對應(yīng)的驅(qū)動。Waveshare提供了完善的Python庫。我們將把這個驅(qū)動庫集成到Home Assistant的自動化環(huán)境中。ESPHome這是一個神器如果你新增的傳感器如SGP30是通過GPIO直接連到主控板你可以選擇用Python直接讀取但這會增加系統(tǒng)復(fù)雜度。更優(yōu)雅的方式是使用ESPHome在一個便宜的ESP8266/ESP32開發(fā)板上運行ESPHome固件用它來讀取傳感器數(shù)據(jù)然后通過WiFi以MQTT或直接API的方式上報給Home Assistant。這樣實現(xiàn)了傳感與控制分離布線更靈活也減輕了主控板的負(fù)擔(dān)。本項目我將采用ESPHome方案來接入SGP30。3. 系統(tǒng)搭建與集成從零到一的完整鏈路這一部分我們將一步步把硬件組裝起來并讓軟件系統(tǒng)跑通。3.1 硬件連接與初步測試首先斷開所有電源進(jìn)行硬件連接。安裝HAOS到Orange Pi前往Home Assistant官網(wǎng)下載對應(yīng)Orange Pi 3 LTS的HAOS鏡像。使用BalenaEtcher等工具將鏡像寫入SD卡。將SD卡插入Orange Pi連接網(wǎng)線首次啟動推薦用有線網(wǎng)絡(luò)更穩(wěn)定上電。等待約10-20分鐘在瀏覽器中輸入http://orangepi的本地IP:8123你需要在路由器后臺查看新設(shè)備IP即可完成Home Assistant的初始化設(shè)置。連接墨水屏7.5英寸墨水屏HAT通常直接扣在Orange Pi的GPIO引腳上。務(wù)必對照引腳圖Orange Pi和樹莓派的GPIO引腳定義不同盲插可能燒毀屏幕或主板。以O(shè)range Pi 3 LTS為例需要確保屏幕的VCC、GND、DIN、CLK、CS、DC、RST、BUSY引腳與主板的對應(yīng)引腳連接正確。Waveshare官網(wǎng)通常提供多種主板的連接示例。連接ESPHome傳感器節(jié)點將SGP30模塊的VCC、GND、SCL、SDA引腳連接到ESP32開發(fā)板的對應(yīng)引腳。然后通過USB線將ESP32連接到電腦用于后續(xù)燒錄固件。3.2 軟件環(huán)境配置讓Home Assistant認(rèn)識新硬件在HAOS中安裝ESPHome插件進(jìn)入Home Assistant后臺側(cè)邊欄點擊“配置” - “加載項”。在加載項商店中搜索并安裝“ESPHome”。安裝完成后啟動它并勾選“顯示在邊欄”。現(xiàn)在側(cè)邊欄會出現(xiàn)ESPHome的圖標(biāo)。創(chuàng)建并燒錄ESPHome固件點擊進(jìn)入ESPHome點擊右下角“新建設(shè)備”。給你的設(shè)備起個名字比如air_quality_sensor選擇ESP32開發(fā)板型號。在生成的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的“安裝”向?qū)鼤龑?dǎo)你通過USB線直接燒錄固件到ESP32。燒錄成功后ESP32會自動連接WiFi。在Home Assistant中集成設(shè)備燒錄完成后回到Home Assistant通常幾分鐘內(nèi)系統(tǒng)會自動發(fā)現(xiàn)這個ESPHome設(shè)備并彈出通知點擊“配置”即可完成集成。完成后在“配置”-“設(shè)備與服務(wù)”-“實體”中你應(yīng)該能看到sensor.tvoc_concentration和sensor.eco2_concentration這兩個新實體。同樣的如果你接入了小米空氣凈化器通過安裝“Xiaomi Miot Auto”集成也能將它的傳感器數(shù)據(jù)添加進(jìn)來。3.3 墨水屏驅(qū)動集成最關(guān)鍵的“臨門一腳”這是整個項目最具技術(shù)挑戰(zhàn)性也最有成就感的一步。我們需要在Home Assistant環(huán)境中運行一個Python腳本這個腳本能調(diào)用墨水屏驅(qū)動庫并能獲取Home Assistant的傳感器數(shù)據(jù)。在HAOS中啟用SSH訪問進(jìn)入“配置”-“加載項”安裝“Terminal SSH”插件并啟動。這為我們提供了一個命令行操作界面。安裝Python依賴通過SSH連接到你的Orange PiHAOS。HAOS基于Linux但系統(tǒng)是只讀的我們需要將驅(qū)動庫安裝到可讀寫的掛載分區(qū)。更推薦的方法是使用Add-on的“自定義倉庫”功能但這里介紹一種更直接、理解更深刻的手動方法。首先進(jìn)入一個可寫目錄比如/config你的Home Assistant配置目錄。cd /config創(chuàng)建一個Python虛擬環(huán)境如果系統(tǒng)沒有python3-venv可能需要先安裝HAOS的終端可能受限這一步有時可以省略直接使用系統(tǒng)Pythonpython3 -m venv epaper_venv source epaper_venv/bin/activate然后安裝必要的庫。Waveshare的驅(qū)動通常需要Pillow圖像處理和RPi.GPIOGPIO控制。對于Orange Pi我們需要使用替代庫如OPi.GPIO。pip install pillow opi-gpio spidev接下來從Waveshare官網(wǎng)下載對應(yīng)屏幕型號的Python驅(qū)動庫解壓后將其中的主要驅(qū)動文件如epd7in5b_HD.py復(fù)制到/config目錄下。編寫屏幕刷新腳本在/config下創(chuàng)建update_display.py。這個腳本的核心邏輯是通過Home Assistant的RESTful API需要創(chuàng)建長期訪問令牌或更優(yōu)雅的homeassistant_api庫獲取傳感器實體狀態(tài)。使用Pillow庫在內(nèi)存中繪制一張圖片布局各種空氣質(zhì)量數(shù)據(jù)文字、數(shù)值、圖表、圖標(biāo)。調(diào)用墨水屏驅(qū)動庫將這張圖片發(fā)送到屏幕并刷新。一個極度簡化的代碼框架示例#!/usr/bin/env python3 import requests import json from PIL import Image, ImageDraw, ImageFont import epd7in5b_HD # 你的屏幕驅(qū)動文件 import time # Home Assistant配置 HA_URL http://localhost:8123/api HA_TOKEN 你的長期訪問令牌 HEADERS { Authorization: fBearer {HA_TOKEN}, content-type: application/json, } # 獲取傳感器狀態(tài) 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 # 主函數(shù) def main(): # 初始化屏幕 epd epd7in5b_HD.EPD() epd.init() epd.Clear() # 創(chuàng)建畫布 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) # 獲取數(shù)據(jù) 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/m3, 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) # ... 可以繪制更多內(nèi)容如時間、空氣質(zhì)量等級、簡易圖表等 # 顯示圖片 epd.display(epd.getbuffer(image)) epd.sleep() # 讓屏幕進(jìn)入睡眠省電模式 if __name__ __main__: main()注意你需要從Home Assistant后臺點擊你的用戶名 - “創(chuàng)建令牌”生成一個長期訪問令牌并替換代碼中的HA_TOKEN。同時將字體文件如arial.ttf也放入/config目錄。創(chuàng)建自動化定時刷新屏幕我們不可能每次都手動運行腳本。在Home Assistant中創(chuàng)建自動化每10分鐘或當(dāng)傳感器數(shù)據(jù)變化時觸發(fā)腳本執(zhí)行。 在/config/automations.yaml中添加或在Web界面中配置- alias: Update E-Paper Display trigger: - platform: time_pattern minutes: /10 # 每10分鐘觸發(fā)一次 - platform: state entity_id: - sensor.xiaomi_air_purifier_pm25 - sensor.tvoc_concentration # 當(dāng)這些傳感器狀態(tài)改變時也觸發(fā) action: - service: shell_command.update_epaper然后在/config/configuration.yaml中定義這個shell_commandshell_command: update_epaper: python3 /config/update_display.py重啟Home Assistant后自動化便會生效。4. 界面設(shè)計與數(shù)據(jù)可視化讓信息一目了然硬件和基礎(chǔ)鏈路打通后下一步就是設(shè)計一個美觀實用的顯示界面。電子墨水屏刷新慢、顏色有限因此設(shè)計原則是信息優(yōu)先、布局清晰、避免頻繁刷新。4.1 布局規(guī)劃與視覺層次我將屏幕分為四個主要區(qū)域核心指標(biāo)區(qū)左上占比40%用最大字體顯示最關(guān)鍵的PM2.5和TVOC數(shù)值并配以直觀的空氣質(zhì)量等級文字如“優(yōu)”、“良”、“輕度污染”并用紅色高亮顯示“污染”等級。環(huán)境參數(shù)區(qū)右上占比30%顯示溫度、濕度、二氧化碳eCO2濃度。采用較小的字體排列整齊。趨勢圖表區(qū)下方占比25%繪制過去12小時PM2.5的折線圖。雖然墨水屏刷新慢不適合動態(tài)圖表但每隔一段時間如1小時更新一次靜態(tài)趨勢圖對于判斷空氣變化規(guī)律非常有價值。這需要腳本具備簡單的數(shù)據(jù)存儲如寫入一個CSV文件和繪圖能力。狀態(tài)與時間區(qū)底部占比5%顯示最后更新時間、WiFi連接狀態(tài)、屏幕下次刷新倒計時。4.2 使用Pillow進(jìn)行高級繪圖前面的示例只用了簡單的文字。為了繪制趨勢圖和圖標(biāo)需要更深入地使用Pillow。繪制折線圖需要計算時間軸和數(shù)值軸的坐標(biāo)映射。假設(shè)我們每小時存儲一個PM2.5數(shù)據(jù)到列表pm25_history中。# ... 獲取歷史數(shù)據(jù)這里簡化為例 history [12, 15, 18, 22, 20, 17, 15, 10, 8, 9, 12, 14] # 模擬12小時數(shù)據(jù) chart_width 400 chart_height 150 chart_x 50 chart_y 250 # 計算坐標(biāo) 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)) # 繪制坐標(biāo)軸和折線 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)添加圖標(biāo)可以事先準(zhǔn)備好表示晴天、雨天、風(fēng)扇凈化器的簡單黑白圖標(biāo)PNG格式用Image.open()加載并粘貼到畫布指定位置直觀表示設(shè)備狀態(tài)或天氣。4.3 動態(tài)邏輯與條件格式讓顯示內(nèi)容更具交互性顏色觸發(fā)當(dāng)PM2.5 75 或 TVOC 500 時對應(yīng)的數(shù)值和標(biāo)簽用紅色繪制調(diào)用draw.text(..., fillepd7in5b_HD.RED)。設(shè)備狀態(tài)查詢空氣凈化器的開關(guān)狀態(tài)如fan.xiaomi_air_purifier如果處于開啟狀態(tài)則在屏幕上顯示一個“風(fēng)扇轉(zhuǎn)動”的圖標(biāo)。建議文本根據(jù)空氣質(zhì)量等級顯示不同的建議如“建議開窗通風(fēng)”、“建議開啟凈化器”、“請佩戴口罩”。5. 優(yōu)化、排錯與進(jìn)階玩法項目基本完成后你會遇到一些實際問題這里分享我的踩坑經(jīng)驗和優(yōu)化思路。5.1 常見問題與解決方案屏幕刷新出現(xiàn)殘影或全黑/全白原因墨水屏刷新需要特定的波形序列。如果刷新過程被意外中斷如腳本崩潰、斷電屏幕可能處于異常狀態(tài)。解決在驅(qū)動中確保每次刷新都遵循init()-Clear()-display()-sleep()的完整流程。在腳本開頭加入異常捕獲無論如何都嘗試執(zhí)行epd.sleep()或epd.init()來重置屏幕。也可以準(zhǔn)備一個“清屏”的腳本在出現(xiàn)問題時手動運行。Home Assistant API調(diào)用失敗原因令牌失效、IP地址變化如果使用localhost在Docker容器內(nèi)可能指代錯誤、網(wǎng)絡(luò)問題。解決使用HAOS時API地址用http://supervisor/core/api或http://homeassistant:8123/api可能比localhost更可靠。在腳本中增加重試機(jī)制和詳細(xì)的錯誤日志記錄將日志寫入/config/display.log便于排查。自動化觸發(fā)不執(zhí)行腳本原因shell_command執(zhí)行環(huán)境權(quán)限不足或Python虛擬環(huán)境未激活。解決一種更穩(wěn)健的方法是將屏幕刷新腳本封裝為一個Home Assistant自定義集成或Python腳本Python Script。但這需要更復(fù)雜的開發(fā)。簡易方案是在shell_command中指定完整的Python路徑和激活環(huán)境shell_command: update_epaper: /config/epaper_venv/bin/python /config/update_display.pyESPHome傳感器數(shù)據(jù)不穩(wěn)定或丟失原因WiFi信號弱、I2C總線干擾、傳感器預(yù)熱不足。解決確保ESP32部署位置信號良好。SGP30等氣體傳感器需要長時間預(yù)熱可能長達(dá)24小時才能達(dá)到最佳穩(wěn)定性期間數(shù)據(jù)會有漂移這是正常的。在ESPHome配置中增加濾波和校準(zhǔn)選項。5.2 功耗與穩(wěn)定性優(yōu)化減少不必要的刷新墨水屏每刷新一次都有壽命損耗通常幾十萬次。不要設(shè)置太短的刷新間隔如1分鐘??諝赓|(zhì)量數(shù)據(jù)變化相對緩慢10-30分鐘刷新一次完全足夠。我的自動化采用了“時間觸發(fā)每30分鐘 重要傳感器狀態(tài)變化觸發(fā)”的雙重策略。使用屏幕睡眠模式刷新完成后務(wù)必調(diào)用epd.sleep()。這是驅(qū)動屏幕進(jìn)入深度省電模式的關(guān)鍵此時屏幕僅維持顯示內(nèi)容功耗可低至接近零。腳本健壯性在Python腳本中使用try...except...finally結(jié)構(gòu)確保任何錯誤下都能執(zhí)行epd.sleep()防止屏幕鎖死。5.3 進(jìn)階擴(kuò)展思路這個項目是一個強(qiáng)大的基礎(chǔ)框架你可以在此基礎(chǔ)上無限擴(kuò)展多數(shù)據(jù)源融合除了空氣質(zhì)量還可以顯示天氣預(yù)報、日歷日程、待辦事項、系統(tǒng)監(jiān)控CPU溫度、內(nèi)存使用率等。只需在腳本中調(diào)用更多Home Assistant實體或外部API。交互功能在屏幕周圍增加幾個物理按鈕接GPIO通過腳本檢測按鍵實現(xiàn)切換顯示頁面、手動刷新、控制智能設(shè)備如開關(guān)燈等功能。多房間監(jiān)測如果你有多個ESPHome傳感器部署在不同房間可以在一個屏幕上通過分區(qū)域或翻頁的形式輪播顯示所有房間的數(shù)據(jù)。美觀化升級使用更優(yōu)雅的字體如思源黑體、設(shè)計更專業(yè)的圖標(biāo)和布局甚至可以模仿一些商業(yè)天氣時鐘的UI讓你的面板不僅是工具也是家居裝飾。這個項目從構(gòu)思到實現(xiàn)我花了幾個周末的時間期間遇到了驅(qū)動兼容、API調(diào)用、布局調(diào)整等各種問題。但當(dāng)那塊墨水屏第一次清晰地顯示出家里的PM2.5數(shù)值時那種“創(chuàng)造之物”開始工作的滿足感是購買任何成品都無法替代的。它不僅僅是一個顯示器更是我個人對智能家居理解的一個物理化身。整個系統(tǒng)完全本地運行數(shù)據(jù)隱私掌握在自己手中響應(yīng)速度快且可以根據(jù)自己的需求隨時調(diào)整。如果你也對智能家居和硬件DIY有興趣強(qiáng)烈建議動手嘗試一下從獲取第一個傳感器數(shù)據(jù)開始你會打開一扇新世界的大門。