为什么选择 Home Assistant
Home Assistant(简称 HA)是目前最流行的开源智能家居平台之一。它的优势在于:
- 完全本地化,数据不经过云端
- 支持数千种设备接入
- 强大的自动化引擎
- 活跃的社区和丰富的插件
对于 DIY 爱好者来说,最吸引人的是它对 MQTT 自动发现的支持——只需按照约定发送配置消息,HA 就能自动识别你的设备。
MQTT 自动发现机制
传统的设备接入需要在 HA 的 configuration.yaml 中手动配置每个设备。而 MQTT 自动发现让这个过程完全自动化。
工作原理
- 设备向
homeassistant/<组件类型>/<设备ID>/config发送配置消息 - HA 收到消息后,自动创建设备实体
- 设备通过状态主题上报数据
- HA 通过命令主题下发控制指令
配置消息格式
以一个简单的温湿度传感器为例:
主题:homeassistant/sensor/living_room_climate/config
{
"name": "客厅温湿度",
"unique_id": "living_room_climate_001",
"device_class": "temperature",
"state_topic": "home/living_room/climate/state",
"unit_of_measurement": "°C",
"value_template": "{{ value_json.temperature }}"
}
状态消息格式
主题:home/living_room/climate/state
{
"temperature": 25.3,
"humidity": 60
}
实际案例:DIY 智能插座
我用 ESP8266 做了一个智能插座,下面展示完整的接入流程。
硬件清单
- ESP8266 模块(NodeMCU)
- 继电器模块(5V,低电平触发)
- HLK-PM01 电源模块(220V 转 5V)
- 外壳和插座面板
Arduino 代码
#include
#include
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
const char* mqtt_server = "192.168.1.100";
WiFiClient espClient;
PubSubClient client(espClient);
const int relayPin = D1;
const char* device_id = "smart_plug_001";
void setup() {
Serial.begin(115200);
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, HIGH); // 继电器低电平触发,初始关闭
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void setup_wifi() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
void sendDiscovery() {
String config_topic = "homeassistant/switch/" + String(device_id) + "/config";
String config_payload = "{";
config_payload += "\"name\":\"智能插座\",";
config_payload += "\"unique_id\":\"" + String(device_id) + "\",";
config_payload += "\"state_topic\":\"home/plug/" + String(device_id) + "/state\",";
config_payload += "\"command_topic\":\"home/plug/" + String(device_id) + "/set\",";
config_payload += "\"payload_on\":\"ON\",";
config_payload += "\"payload_off\":\"OFF\",";
config_payload += "\"device\":{\"identifiers\":[\"" + String(device_id) + "\"],\"name\":\"智能插座\"}";
config_payload += "}";
client.publish(config_topic.c_str(), config_payload.c_str(), true);
}
void callback(char* topic, byte* payload, unsigned int length) {
String message = "";
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
String command_topic = "home/plug/" + String(device_id) + "/set";
if (String(topic) == command_topic) {
if (message == "ON") {
digitalWrite(relayPin, LOW); // 开
client.publish(("home/plug/" + String(device_id) + "/state").c_str(), "ON");
} else if (message == "OFF") {
digitalWrite(relayPin, HIGH); // 关
client.publish(("home/plug/" + String(device_id) + "/state").c_str(), "OFF");
}
}
}
void reconnect() {
while (!client.connected()) {
if (client.connect(device_id)) {
sendDiscovery();
client.subscribe(("home/plug/" + String(device_id) + "/set").c_str());
} else {
delay(5000);
}
}
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
进阶:传感器设备
对于有多个数据的设备,HA 支持将多个实体关联到同一个设备。
温湿度传感器配置
// 发送温度传感器配置
{
"name": "客厅温度",
"unique_id": "living_room_temp",
"device_class": "temperature",
"state_topic": "home/sensor/living_room/state",
"unit_of_measurement": "°C",
"value_template": "{{ value_json.temperature }}",
"device": {
"identifiers": ["living_room_sensor"],
"name": "客厅传感器",
"model": "DHT22",
"manufacturer": "DIY"
}
}
// 发送湿度传感器配置
{
"name": "客厅湿度",
"unique_id": "living_room_humidity",
"device_class": "humidity",
"state_topic": "home/sensor/living_room/state",
"unit_of_measurement": "%",
"value_template": "{{ value_json.humidity }}",
"device": {
"identifiers": ["living_room_sensor"],
"name": "客厅传感器"
}
}
注意两个传感器的 device.identifiers 相同,这样 HA 会将它们识别为同一设备的不同实体。
调试技巧
使用 MQTT 客户端查看消息
推荐使用 MQTT Explorer 或 mosquitto_sub 命令行工具来调试:
# 订阅所有 homeassistant 相关主题
mosquitto_sub -h 192.168.1.100 -t "homeassistant/#" -v
# 订阅所有设备状态
mosquitto_sub -h 192.168.1.100 -t "home/#" -v
常见问题
设备没有显示
- 检查 MQTT Broker 连接是否正常
- 确认配置消息的 JSON 格式正确
- 查看 HA 日志(配置 -> 系统 -> 日志)
状态不更新
- 确认
state_topic与发送的主题一致 - 检查
value_template是否能正确解析 JSON
相关项目
基于这些实践经验,我开源了一个 Arduino 库 HAMqttDiscoveryHandler,用于简化 Home Assistant 的设备接入流程。
使用方法:
#include
HADevice device("smart_plug_001", "智能插座");
HASwitch switch1("relay", "继电器");
void setup() {
device.addEntity(&switch1);
device.begin(mqttClient);
}
总结
MQTT 自动发现机制大大简化了设备接入流程,让 DIY 设备可以像商业产品一样无缝集成到 Home Assistant 中。配合 HA 强大的自动化功能,可以实现很多有趣的场景,比如:
- 温度超过 28 度自动开空调
- 离家时一键关闭所有电器
- 日落时自动开灯
如果你也在玩智能家居,欢迎交流经验。