Home Assistant
💡 快速導航
Home Assistant 是我家智慧裝置的控制與自動化中樞。它不只是把不同品牌的設備集中到同一個 Dashboard,而是把「人在不在家、現在幾點、設備狀態如何」組合成可以長期維護的生活流程。
我把 Home Assistant 跑在 OMV 的 Docker 環境,讓 OMV 負責運算與容器管理,設定資料則透過持久化掛載保存。這也延續整套 Home Lab 的分層原則:TrueNAS 管資料,OMV 管服務。
🎯 我為什麼用它
不想每個品牌都開一個 App
家裡的燈、空調、空氣清淨機、攝影機、電視和感測器來自不同品牌。若只使用原廠 App,每個設備都各自運作,很難做跨品牌聯動。
Home Assistant 把它們整理成統一的 entity,讓我可以用相同方式控制、監看與自動化。
自動化要依照生活情境,而不是單一排程
固定時間開燈很容易,但真正好用的自動化會同時考慮:
- 家裡是否有人
- 現在是白天還是晚上
- 電視、空調或空氣清淨機目前是否運作
- 空氣品質是否真的允許關閉清淨機
- 動作失敗時是否還能手動控制
優先在本地完成控制
能走區網、Bluetooth、MQTT 或本地 API 的設備,我會優先使用本地整合。即使外網或原廠雲端暫時異常,核心控制和多數自動化仍能繼續運作。
🧱 我的架構
flowchart TD U[手機 / 平板 / 瀏覽器] --> RP[反向代理 / HTTPS] RP --> HA[Home Assistant<br/>OMV / Docker] SSO[OpenID SSO] --> HA LAN[區網探索 / Bluetooth / MQTT] --> HA HA --> IOT[燈光 / 空調 / 清淨機 / 感測器] HA --> CAM[攝影機 / Frigate] HA --> MEDIA[電視 / Cast / Plex] HA --> INFRA[OpenWrt / OMV] HA --> DATA[(Config / Backup)]
部署摘要
| 項目 | 目前做法 | 原因 |
|---|---|---|
| 運行主機 | OMV | 集中承載 Home Lab 的 Docker 服務 |
| 部署方式 | Docker Compose | 設定可追蹤,升級與回滾流程一致 |
| 版本策略 | 固定 image tag | 避免 latest 在重建時意外跨版本 |
| 盤點時版本 | Home Assistant Core 2026.8.2 | 本文記錄的是這個版本的實際狀態 |
| 網路 | network_mode: host | 讓 mDNS、裝置探索與區網整合較直接 |
| 設定資料 | Host path 掛載到 /config | 容器重建後仍保留設定與歷史資料 |
| Bluetooth | 掛載 Host D-Bus | 讓 Home Assistant 使用主機的 Bluetooth stack |
| 對外入口 | 反向代理 + HTTPS + OpenID SSO | 統一入口,不直接公開原始服務端口 |
| 備份 | 每週完整備份 + 升級前備份 | 同時處理日常故障與版本升級風險 |
Docker Compose 摘要
以下是移除私人路徑與環境資訊後的核心配置:
services:
homeassistant:
container_name: homeassistant
image: homeassistant/home-assistant:2026.8.2
environment:
- TZ=<your-timezone>
volumes:
- <config-path>:/config
- ./patches/luci/device_tracker.py:/usr/src/homeassistant/homeassistant/components/luci/device_tracker.py:ro
- /etc/localtime:/etc/localtime:ro
- /run/dbus:/run/dbus:ro
restart: unless-stopped
privileged: true
cap_add:
- NET_ADMIN
network_mode: hostWarning
hostnetwork、privileged: true與NET_ADMIN是我目前為了區網探索、Bluetooth 和既有整合採用的配置,不代表每個環境都需要。它們會擴大容器權限,部署時應逐項確認並盡量縮小權限範圍。
🔌 裝置與整合
我的重點不是追求整合數量,而是把每天真的會互相影響的設備放進同一套狀態模型。
| 類別 | 目前使用的整合與設備 |
|---|---|
| 燈光與開關 | TP-Link / Tapo、Tuya / LocalTuya、Xiaomi、Govee、SwitchBot、ESPHome |
| 空調與環境 | Resideo / Honeywell Home T6 Pro、Blueair、Qingping、天氣與空氣品質資料 |
| 影音設備 | Android TV、Apple TV、Google Cast、Plex |
| 攝影機 | Tapo、Frigate、go2rtc |
| Presence | Home Assistant Companion App、Bluetooth / iBeacon、OpenWrt LuCI |
| Home Lab | OpenMediaVault、MQTT、網路設備狀態 |
| UI | HACS、Mushroom、UI Lovelace Minimalist |
Dashboard 目前依用途分成 Home、Lights、Devices 與 Network 等頁面。首頁只放每天需要確認的狀態;詳細控制和診斷資訊則拆到其他頁面,避免所有 entity 都塞在同一張 Dashboard。
我也建立了 template sensors,集中顯示目前開啟的燈、開關和異常感測器數量。這比逐個巡視設備更適合當作家庭狀態摘要。
❄️ 空調與溫控
家中的冷氣與暖氣由 Resideo(Honeywell Home)T6 Pro thermostat 控制。Home Assistant 透過內建的 HomeKit Controller 在區網內連接 thermostat,不需要經過原廠雲端才能讀取狀態或下達指令。
Home Assistant → HomeKit Controller → T6 Pro Thermostat → HVAC在 Dashboard 的 thermostat card 中,我可以直接查看目前溫度、調整目標溫度,並切換 cool、heat 和 off 模式。相同的 climate entity 也提供給 automation 使用,因此手動控制與自動節能不需要維護兩套狀態。
目前的空調自動化
| 自動化 | 條件 | 動作 |
|---|---|---|
Cooling Midnight Off | 每天凌晨 1:00,且 HVAC 仍在 cool 模式 | 將 HVAC mode 設為 off |
Away HVAC Off | 主要 Presence 離家 10 分鐘,且 HVAC 在 cool 或 heat 模式 | 將 HVAC mode 設為 off |
凌晨自動關閉是一道避免冷氣整夜運作的安全網;離家延遲則用來過濾手機短暫斷線,避免一離線就立刻關機。
Note
目前
Away HVAC Off仍由單一主要 Presence 觸發。多人家庭更完整的做法應改成「所有成員都離家」後再關閉空調,避免家中仍有人時被誤關。
⚡ 我每天真的用到的自動化
| 情境 | Trigger / Condition | Action |
|---|---|---|
| 離家攝影機模式 | 家中成員都離開一段時間 | 關閉隱私模式並啟用需要的監控功能 |
| 回家攝影機模式 | 成員回到家 | 恢復攝影機隱私模式 |
| 空調午夜關閉 | 凌晨 1:00,且空調仍在製冷 | 關閉 HVAC |
| 空調離家節能 | 主要 Presence 離家 10 分鐘,且冷氣或暖氣仍在運作 | 關閉 HVAC |
| 電視情境燈 | 電視開啟或關閉,再判斷日出/日落 | 開啟合適的電視牆燈,關機時關燈 |
| 空氣清淨機 | 固定時段或成員離家,並檢查空氣品質 | 開關清淨機,避免空氣差時過早關閉 |
| NFC 快捷操作 | 掃描已註冊的 NFC tag | 執行關燈等常用動作 |
| 每週備份 | 每週六凌晨 | 建立壓縮完整備份並保留 14 天 |
我的自動化原則
- 先確認狀態,再執行動作:避免設備已經關閉時重複呼叫。
- 離家判斷要有緩衝時間:手機短暫斷線不應立即觸發整套 away automation。
- 多人家庭要看整體 Presence:一個人離開,不代表家裡沒人。
- 保留手動控制:自動化失效時,原本的開關或 App 仍能使用。
- 高風險動作要另外保護:門鎖等操作不能只依賴可複製的 tag,還要考慮手機解鎖、通知與實體安全。
📍 Presence Detection:最值得記錄的坑
Presence 是攝影機隱私模式、空調節能和離家流程的共同基礎。一旦誤判,後面的自動化即使寫得完全正確,結果仍然會錯。
問題:OpenWrt 的 reachable 不是穩定的「人在家」訊號
我使用 OpenWrt LuCI tracker 觀察手機是否連在家中網路。實際上,OpenWrt neighbor table 的 reachable flag 可能短暫變成 false,即使手機仍在家中 Wi-Fi。
原本的 LuCI integration 還有另一個邊界情況:若已註冊的手機沒有出現在第一次 only_reachable=True 掃描中,對應 tracker entity 可能根本不會建立,後續輪詢也無法讓它恢復。
我的處理方式
flowchart LR R[OpenWrt LuCI] --> RAW[Raw device tracker] RAW --> PATCH[本地 LuCI patch] PATCH --> SMOOTH[Template tracker<br/>3-8 分鐘 debounce] SMOOTH --> PERSON[Person entity] PERSON --> AUTO[家庭自動化]
我保留 only_reachable=True,避免把舊 ARP 紀錄誤認為還在家;同時用一個版本綁定的本地 patch,讓已經註冊過的裝置即使第一次掃描缺席,也會先建立為 not_home,之後可在 30 秒輪詢中恢復。
Raw tracker 之上再加一層 template tracker:
- 回到
home時立即更新 - 變成
not_home時等待 3-8 分鐘 - 等待期間若重新連線,就不觸發離家流程
概念化設定如下,實際 entity ID 已隱藏:
template:
- trigger:
- platform: state
entity_id: device_tracker.<phone>
to: "home"
- platform: state
entity_id: device_tracker.<phone>
to: "not_home"
for: "00:05:00"
device_tracker:
- name: phone_smoothed
in_zones: >-
{{ ['zone.home'] if states('device_tracker.<phone>') == 'home' else [] }}Important
這個 patch 直接覆蓋 Home Assistant image 內的 LuCI module,因此每次升級 Home Assistant 都必須先和新版 upstream 檔案比較。若官方已修正,就應移除 patch,而不是永久維護自己的 fork。
🖥️ Dashboard 的定位
Dashboard 是控制與觀察介面,不應成為自動化邏輯本身。

這是目前掛在牆上的 Home Assistant WebUI。硬體本身是一台便宜的 Android 平板,主要用途是把家庭常用控制、溫濕度、空氣品質和空調狀態固定展示在一個隨手可看的位置。
Home:家庭摘要、Presence、天氣和常用控制Lights:依房間整理燈光與群組Devices:空調、清淨機、掃地機器人與影音設備Network:Home Lab 和網路設備狀態
我使用 HACS 安裝部分前端元件,並搭配 Mushroom 與 UI Lovelace Minimalist。UI 可以慢慢調整,但 entity 命名、area 分類與 automation 邏輯要先穩定,否則 Dashboard 做得再漂亮也很難維護。
💾 備份與還原
目前由 Auto Backup automation 在每週六凌晨建立壓縮完整備份,保留 14 天;每次升級前再額外建立一份手動備份。
我會保護的內容
configuration.yaml與拆分出去的 YAML 設定.storage內的 integration、entity registry 和 Dashboard 設定automations.yaml、scripts.yaml與scenes.yamlcustom_components、themes 與前端資源- secrets 與憑證,但不放進公開文件或公開 repository
- Recorder database;它是歷史資料,不應是唯一可用的設定備份
還原順序
- 停止 Home Assistant container。
- 保留故障現場的 config 副本,避免直接覆蓋唯一線索。
- 還原最後一份確認可用的設定與備份。
- 使用原本固定的 image tag 啟動,不要在還原時同時升級。
- 檢查登入、核心 integration、Presence、攝影機隱私模式與空調控制。
- 確認無誤後,再處理版本升級或歷史資料。
我曾留下過損壞的 SQLite Recorder database,這提醒我:備份設定、備份歷史資料和實際做還原演練,是三件不同的事。
⬆️ 升級流程
Home Assistant 更新很快,而我的環境還有 HACS integrations 與 LuCI 本地 patch,所以我不使用 latest 自動追版。
升級前
- 閱讀 release notes,特別注意 deprecated integrations 與 YAML breaking changes。
- 建立完整備份,並記錄目前可回滾的 image tag。
- 確認 HACS custom integrations 支援目標版本。
- 比較新版 LuCI
device_tracker.py與本地 patch。 - 執行
docker compose config --quiet,先排除 Compose 結構或環境變數錯誤。 - 使用 Home Assistant 的 configuration check 驗證設定。
升級後
- 確認 container 正常啟動,檢查 error log。
- 重新載入 LuCI,確認 raw 與 smoothed trackers 都能恢復。
- 測試離家/回家、攝影機隱私、空調、燈光與 TTS。
- 確認 Dashboard 和 HACS cards 沒有前端錯誤。
- 確認下一次排程備份可以正常建立。
若核心功能失敗,我會先回滾 image tag 和設定,而不是在壞掉的 production instance 上連續嘗試多個變更。
🔐 安全與隱私
- 對外存取統一經過 HTTPS 反向代理,不直接公開 Home Assistant 原始端口。
- OpenID SSO 是登入便利層,不能取代 Home Assistant 權限、強密碼與 MFA。
- API key、client secret、精確位置、內網 IP、device ID 和 tag ID 都不應出現在公開筆記。
- YAML 需要憑證時使用
!secret,並確保 secrets 與.env不會進入公開 Git repository。 privileged、NET_ADMIN與 host network 都要定期檢查是否仍有必要。- 攝影機自動化預設以家庭隱私為優先;任何異常都應能手動切回隱私模式。
🧯 我踩過的坑
1. 把 Presence 當成絕對真相
Wi-Fi tracker、Bluetooth 和手機 App 都可能短暫離線。真正穩定的 Presence 需要 debounce、多人條件和失敗時的安全預設。
2. 太早建立複雜自動化
如果一開始就把十幾個條件塞進同一條 automation,後面任何 entity 改名都可能牽一髮動全身。先做 2-3 個每天一定會用到的流程,比一次完成「全屋自動化」可靠。
3. Custom integration 和 patch 都有維護成本
HACS 很方便,但每多一個 custom component,就多一個可能在升級後壞掉的相依項目。本地 patch 更要綁定測試版本並留下移除條件。
4. 只做備份,不做還原測試
看到 backup file 不代表它一定可用。至少要知道如何用固定版本啟動、還原 config,並驗證最重要的幾條 automation。
5. UI 整理不能取代 entity 整理
Dashboard 卡片可以隨時重做,但混亂的命名、area 和 device 關係會直接增加所有自動化的維護成本。
如果你也要這樣做
- 先整理 area、device 和 entity 命名規則。
- 選 2-3 個每天都會用到、失敗風險低的情境開始。
- 為離家判斷加上延遲,並保留手動控制方式。
- 在增加 custom integrations 前,先建立備份與還原流程。
- 穩定運作一段時間後,再加入跨品牌與多人 Presence 自動化。
Home Assistant 最有價值的地方,不是 Dashboard 上有多少按鈕,而是讓設備在正確的時間完成正確的事,同時在出錯時仍然可理解、可維護、可回復。
回到 Home Lab 總覽