如果你家裡有用 MQTT 溝通的裝置,大概也碰過這個問題:裝置在一個主題上發布狀態、從另一個主題接收指令,可是 Apple 的「家庭」App 只認得 HomeKit 配件,看不懂 MQTT。MQTT Thing EX 是一個 Homebridge 外掛,負責把 MQTT 主題變成 HomeKit 配件:燈、感應器、門鎖、恆溫器等等。它是 homebridge-mqttthing 持續維護的後繼版本,現有的設定不用改就能用。
它怎麼運作
MQTT 的世界裡只有主題和訊息;HomeKit 的世界裡則是配件和特性,例如一盞燈的開關與亮度。MQTT Thing EX 在 Homebridge 裡做的事,就是依照你的設定,把每個特性對應到 MQTT 主題,再把配件交給「家庭」App。
主題分成兩個方向。名稱以 set 開頭的是控制主題,由外掛發布,用來改變裝置狀態,例如開燈;以 get 開頭的是狀態主題,由裝置發布,告訴外掛發生了什麼事,例如感應器偵測到動作,或剛才的開燈指令已經完成。
在「家庭」App 點一下開燈,外掛在 set 主題發布指令;裝置在 get 主題回報狀態,畫面跟著更新。
一盞燈的設定
每個配件是 config.json 裡 accessories 陣列中的一個區塊:類型、名稱、broker 位址,再加上一組 topics。下面是產品頁上的客廳檯燈範例,一盞可以開關、也可以調亮度的燈:
{
"accessory": "mqttthing",
"type": "lightbulb",
"name": "Living Room Lamp",
"url": "mqtt://broker.local:1883",
"topics": {
"setOn": "living/lamp/setOn",
"getOn": "living/lamp/getOn",
"setBrightness": "living/lamp/setBrightness",
"getBrightness": "living/lamp/getBrightness"
}
} 示意圖:「家庭」App 裡的開關和亮度,各自對應一組 set/get 主題。
裝置送出的訊息格式不一定剛好符合外掛的預期,這時有幾種做法。布林值預設用 true/false 字串,設定 integerValue 可以改成 1/0,也可以用 onValue、offValue 指定任意值。JSON 格式的訊息可以在主題後面接 JSONPath(topic$.path),只取出需要的欄位;說明文件裡的例子,就是一台 Sonoff 裝置把溫度和濕度包在同一則 JSON 訊息裡,再由兩個感應器配件各取一個欄位。更複雜的轉換可以寫成 apply 運算式,或另外寫一個 codec 檔案,格式特殊的裝置也不必另外寫橋接程式。
能接哪些裝置
HomeKit 有的,幾乎都能接。目前支援 37 種配件類型:
- 燈光:燈泡,支援亮度、彩色、白光與色溫,以及自適應照明
- 開關與插座:開關、插座、無狀態可程式化開關
- 感應器:動作、有人偵測、光線、溫度、濕度、氣壓、氣象站、接觸、煙霧、漏水、空氣品質、二氧化碳、一氧化碳
- 空調:恆溫器、冷暖氣機、除濕機、風扇、風扇 v2、空氣清淨機
- 安全與門禁:保全系統、門鈴、車庫門、門鎖、窗簾、窗戶、門
- 用水:閥門、灑水系統
- 影音與其他:電視、麥克風、揚聲器、電池
第 37 種是自訂(custom)類型,把多個服務組合成一個配件,例如兩個開關加一個動作感應器。溫度、濕度、氣壓、用電量等數據還可以開啟歷史紀錄,顯示在 Eve App 的圖表中。每種類型有哪些主題和選項,都列在所有配件類型(英文)文件裡;原本 homebridge-mqttthing Wiki 上整理的實測設定,因為格式沒變,也可以照用。
從 homebridge-mqttthing 換過來
原本就在用 homebridge-mqttthing 的話,config.json 完全不用動。配件區塊照樣寫 "accessory": "mqttthing",codec 檔案和 apply 運算式也照常運作。換過來只要三步:
- 移除 homebridge-mqttthing。兩個外掛都使用
mqttthing這個名稱,同時只能安裝其中一個。 - 安裝 MQTT Thing EX,從 Homebridge UI 或 npm 都可以。
- 重新啟動 Homebridge 一次。
不需要重新配對。Homebridge 辨識一個橋接配件,靠的是 mqttthing 這個別名加上配件名稱,而不是外掛的套件名稱。別名和名稱都沒變,每個配件就還是同一個,房間、場景和自動化都會保留。
_bridge)裡,保持同樣的 _bridge.username,配對也會保留。平台模式:每個 broker 一條連線
原本的外掛會替每個配件各開一條 MQTT 連線,每條連線都有自己的 socket、keepalive 計時器、重新連線邏輯和 broker 端的工作階段。同一個 broker 上有二十四個配件,就是二十四份。選用的平台模式把所有裝置放進同一個設定區塊(devices 陣列),broker 設定相同的裝置共用一條連線;碰到限制每個使用者連線數的 broker,也不再是問題。
以 6 個配件為例:配件模式每個配件一條連線,平台模式共用一條;身分與出錯時的行為也不同。
除了連線數,平台模式還改了兩件事。第一是身分:配件模式裡名稱就是配件的身分,改名會讓它變成新配件,房間和自動化也跟著不見;平台模式的每個裝置都有固定的 id,名稱只是標籤,想改就改。第二是容錯:設定有誤的裝置會保留在 HomeKit 原本的位置,房間和自動化都在,等你修好;錯誤也會在啟動時寫進日誌。
搬過去不必手改 JSON。在 Homebridge UI 開啟外掛設定,從配件清單底部的「About platform mode」進入,挑選要搬的配件,每個配件會先標示能不能搬;按下頁面上方的「Save all changes」,再重新啟動 Homebridge。設定頁面會把配件原本的 UUID 寫進 id,所以一樣不需要重新配對。配件模式也會持續完整支援,不搬也可以。
_bridge 只能設在整個平台區塊上、不能設在個別裝置上,而每個子橋接器在 HomeKit 裡是各自配對的;設定頁面會拒絕並說明原因,替代做法是把整個平台放進子橋接器。搬過去之後沒有自動搬回的功能。同一個裝置也不要同時寫在 accessories 和 devices 裡。其他改進
MQTT Thing EX 是 David Miller 與貢獻者的 homebridge-mqttthing 從頭改寫而成,以 Apache-2.0 授權釋出。原版能做的都在,另外多了這些:
- 為大量裝置設計的設定頁面:可搜尋的裝置清單、懂得每種類型有哪些主題的編輯器、可以安全編輯的
apply函式、完整支援custom類型,還有連線測試和即時主題探測。舊的設定表單會弄壞含apply函式的設定,這裡不會。 - 發布佇列:設定
publishMinIntervalms後,外掛會控制發布訊息的節奏,同一主題只保留最新的值。場景一次改動很多特性、或拖動亮度滑桿時,低功耗裝置(例如以 ESP8266 為基礎的裝置)不會被淹沒;佇列空閒時,單一指令仍然立刻送出。 - 修好上游的問題:啟動時多送的顏色訊息、自適應照明把燈打開、溫度讀數被設定範圍截斷、萬用字元訂閱、空訊息造成當機等等,完整清單附有上游 issue 編號。
- 為 Homebridge 2 準備好了:以 TypeScript 與 ES 模組寫成,採用新版 HomeKit API(
onGet/onSet),可在 Homebridge 1.8 以上與 2.x 執行。
安裝與設定
- 安裝外掛:在 Homebridge UI 開啟外掛頁面,搜尋 MQTT Thing EX 並安裝。
- 加入裝置:開啟外掛設定,選擇新增,挑選裝置類型,填入 broker 和主題,當場就能測試連線。
- 重新啟動 Homebridge:裝置會出現在「家庭」App 中,可以分配房間、加入場景,也能用 Siri 控制。
需要 Homebridge 1.8 以上(支援 2.x)與 Node.js 18.17 以上。每個設定項目的細節,請看完整設定說明(英文)。
config.json 不會被動到,裝置也照常運作,受影響的只有設定頁面。可以從右上角的選單使用「Restart Homebridge UI」,或重新啟動整個 Homebridge 服務或容器。相關連結
這個外掛免費、沒有廣告也沒有付費版;如果它讓你的裝置順利接上「家庭」App,歡迎請我喝杯珍奶(直接刷卡,不需要 PayPal 帳號),或用 PayPal 贊助。
Apple Home(家庭)與 HomeKit 是 Apple Inc. 的商標;MQTT 是 OASIS 標準;Eve 是 Eve Systems GmbH 的商標。本外掛為非官方專案,與上述組織無關,也未獲其背書。

留言
張貼留言