|
|
MQTT 是智慧家庭的萬用膠水。
懂了它,你可以把任何東西接進 HA。

基本概念
MQTT 是一個「訊息轉發」的協定。
- Broker(中介) —— 中央的郵局,通常是 Mosquitto
- Publish(發布) —— 寄信到某個主題
- Subscribe(訂閱) —— 我要收某個主題的信
主題(Topic)的樣子:
- zigbee2mqtt/客廳溫濕度
- home/浴室/濕度
- esphome/門口/狀態
複製代碼
用 / 分層,可以用萬用字元訂閱:
- zigbee2mqtt/+ 所有直屬的裝置(一層)
- zigbee2mqtt/# 所有底下的(任意層)
複製代碼
為什麼要懂它
- Zigbee2MQTT、ESPHome(部分)、Tasmota 都用它
- 可以接任何能發 HTTP 或 MQTT 的東西
- 可以自己造實體(下面的重點)
- 可以跟其他系統橋接(Node-RED、Python 腳本、NAS)
安裝
- 設定 → 附加元件 → Mosquitto broker
- 安裝、啟動
- 設定 → 裝置與服務 → MQTT 整合(通常會自動出現)
建立一個專用帳號:
- 設定 → 人員 → 使用者 → 新增使用者
- 取名 mqtt,設一個密碼
- 取消勾選「可以登入」(如果有這個選項)
Mosquitto 附加元件預設會用 HA 的使用者帳號做驗證。

MQTT Discovery:自己造一個實體
這是最強大的部分。
只要發一則特定格式的訊息,HA 就會自動建立一個實體。
主題的格式:
- homeassistant/<類型>/<物件ID>/config
複製代碼
範例:建立一個溫度感測器
主題:
- homeassistant/sensor/我的溫度計/config
複製代碼
內容:
- {
- "name": "我的溫度計",
- "unique_id": "my_temp_001",
- "state_topic": "home/客房/溫度",
- "unit_of_measurement": "°C",
- "device_class": "temperature",
- "state_class": "measurement",
- "device": {
- "identifiers": ["my_device_001"],
- "name": "客房感測器",
- "manufacturer": "自己做的",
- "model": "v1"
- }
- }
複製代碼
發出去之後,HA 裡就會出現 sensor.我的溫度計。
然後發數值:
就這樣。
retain 旗標一定要開
發 config 的時候要加 retain:
- 這樣 broker 會記住這則訊息
- HA 重啟之後會重新收到,實體不會消失
- 沒有 retain 的話,HA 重啟後實體就不見了
用開發者工具測試
- 開發者工具 → 動作
- 找 mqtt.publish
- action: mqtt.publish
- data:
- topic: homeassistant/sensor/我的溫度計/config
- retain: true
- payload: >-
- {"name":"我的溫度計","unique_id":"my_temp_001",
- "state_topic":"home/客房/溫度","unit_of_measurement":"°C",
- "device_class":"temperature","state_class":"measurement"}
複製代碼

可以造哪些實體
- sensor 數值
- binary_sensor 開/關的狀態
- switch 開關(可控制)
- light 燈
- climate 冷氣
- cover 窗簾
- fan 風扇
- lock 鎖
- button 按鈕
- number 數字輸入
- select 下拉選單
- text 文字
- device_tracker 位置追蹤
- camera 攝影機(圖片)
- event 事件
複製代碼
造一個可以控制的開關
- {
- "name": "我的開關",
- "unique_id": "my_switch_001",
- "state_topic": "home/裝置/開關/狀態",
- "command_topic": "home/裝置/開關/設定",
- "payload_on": "ON",
- "payload_off": "OFF",
- "optimistic": false
- }
複製代碼
- state_topic —— HA 從這裡讀狀態
- command_topic —— HA 對這裡發指令
- 你的程式訂閱 command_topic,收到之後做事,然後發回 state_topic
用 Python 接任何東西進 HA
- import json
- import paho.mqtt.client as mqtt
- c = mqtt.Client()
- c.username_pw_set("mqtt", "密碼")
- c.connect("192.168.1.10", 1883)
- # 1. 宣告一個感測器
- config = {
- "name": "伺服器溫度",
- "unique_id": "server_temp",
- "state_topic": "myserver/temp",
- "unit_of_measurement": "°C",
- "device_class": "temperature",
- "state_class": "measurement",
- }
- c.publish("homeassistant/sensor/server_temp/config",
- json.dumps(config, ensure_ascii=False), retain=True)
- # 2. 定期發數值
- import time
- while True:
- 溫度 = 讀取溫度() # 你自己的函式
- c.publish("myserver/temp", str(溫度))
- time.sleep(60)
複製代碼
用途:
- 把 NAS 的溫度、硬碟狀態接進 HA
- 把路由器的流量接進來
- 把任何有 API 的服務接進來
- 自己寫的程式回報狀態
可用性(availability):讓 HA 知道裝置離線
- {
- "name": "我的裝置",
- "state_topic": "home/device/state",
- "availability_topic": "home/device/status",
- "payload_available": "online",
- "payload_not_available": "offline"
- }
複製代碼
搭配「遺囑(Last Will)」:
- c.will_set("home/device/status", "offline", retain=True)
- c.connect(...)
- c.publish("home/device/status", "online", retain=True)
複製代碼
遺囑的意思是「我斷線的時候,請 broker 幫我發這則訊息」 ——
程式當掉或斷網,HA 會自動知道那個裝置離線了。
這是 MQTT 最優雅的設計之一。

除錯工具
一、HA 的 MQTT 整合有監聽功能
- 設定 → 裝置與服務 → MQTT → 設定
- 監聽主題:填 # 可以看到所有訊息
二、MQTT Explorer(電腦軟體)
- 視覺化的主題樹
- 可以看歷史、可以手動發訊息
- 免費,強烈推薦
三、命令列
- # 訂閱所有訊息
- mosquitto_sub -h 192.168.1.10 -u mqtt -P 密碼 -t '#' -v
- # 發一則訊息
- mosquitto_pub -h 192.168.1.10 -u mqtt -P 密碼 \
- -t 'home/測試' -m 'hello'
複製代碼
常見問題
一、實體出現但永遠是 unknown
- state_topic 打錯
- 還沒發過數值(config 只是宣告,要另外發值)
- 發的數值格式不對(例如 JSON 但沒設 value_template)
二、HA 重啟之後實體不見了
三、實體重複出現
- unique_id 改了,HA 當成新裝置
- 要刪舊的:發一則空訊息到那個 config 主題(帶 retain)
- action: mqtt.publish
- data:
- topic: homeassistant/sensor/舊的ID/config
- retain: true
- payload: ""
複製代碼
四、JSON 格式的資料怎麼拆
很多裝置會發一整包 JSON:
- {"temperature": 26.5, "humidity": 60, "battery": 85}
複製代碼
用 value_template 取值:
- {
- "name": "溫度",
- "state_topic": "home/裝置",
- "value_template": "{{ value_json.temperature }}"
- }
複製代碼
一則訊息可以餵好幾個實體,
各自用不同的 value_template 取不同的欄位。
這是 Zigbee2MQTT 的做法 —— 一個裝置發一包 JSON,HA 拆成好幾個實體。
---
下一篇:智慧家庭的第一年 ——
如果重來一次,我會用什麼順序。 |
|