Home Assistant 设备接入实践

2025-03-15 · 返回首页

为什么选择 Home Assistant

Home Assistant(简称 HA)是目前最流行的开源智能家居平台之一。它的优势在于:

对于 DIY 爱好者来说,最吸引人的是它对 MQTT 自动发现的支持——只需按照约定发送配置消息,HA 就能自动识别你的设备。

MQTT 自动发现机制

传统的设备接入需要在 HA 的 configuration.yaml 中手动配置每个设备。而 MQTT 自动发现让这个过程完全自动化。

工作原理

  1. 设备向 homeassistant/<组件类型>/<设备ID>/config 发送配置消息
  2. HA 收到消息后,自动创建设备实体
  3. 设备通过状态主题上报数据
  4. 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 做了一个智能插座,下面展示完整的接入流程。

硬件清单

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

常见问题

设备没有显示

状态不更新

相关项目

基于这些实践经验,我开源了一个 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 强大的自动化功能,可以实现很多有趣的场景,比如:

如果你也在玩智能家居,欢迎交流经验。

← 返回首页