在 Home Assistant 中通过 MQTT 集成接入灯控制器
前面我们已经实现了 ESP8266 通过 MQTT 控制继电器灯的开关。 接下来,我们将设备接入 Home Assistant(HA),这样就可以在 HA 的界面中直接控制灯的开关。
我们需要在 Home Assistant(HA) 中安装一个 MQTT Broker。 这个 Broker 相当于一个消息中间桥梁,ESP8266 和 HA 都通过它进行通信。

ESP8266 和 HA 都会连接到同一个 MQTT Broker:
- ESP8266 订阅控制灯开关的主题(Topic)
- HA 向该主题发布开关指令
当 ESP8266 收到来自 Broker 的控制指令时,就会执行相应的操作(例如打开或关闭继电器),并将当前灯的状态通过 MQTT 回传给 HA。
通过这种 发布 / 订阅(Publish / Subscribe)机制,HA 就可以实时控制并获取设备的状态。
配置MQTT集成
- 进入:Settings > Devices & Services

- 点击右下角的“Add Integration”按钮,在弹出框中搜索并选择“MQTT”

- 在弹出的配置框中选择“Use the official Mosquitto Mqtt Broker add-on”选项。该选项会自动安装 Mosquitto MQTT Broker,无需手动配置 Broker 的 IP 地址和端口号等。

添加灯实体
在 Home Assistant 中,可以通过两种方式添加设备实体:
- 手动配置
- MQTT Discovery 自动发现
方法一、手动配置
- 安装File Editor
- 进入:Settings > Add-ons > Add-on Store 搜索 File Editor 并安装
- 勾选“Show in sidebar”以便在侧边栏中快速访问

- 通过File Editor编辑configuration.yaml
在侧边栏中点击 File Editor,打开 configuration.yaml 文件。这是 Home Assistant 的主配置文件,我们将在这里添加 MQTT 相关的配置。
mqtt:
light:
- name: "书房灯" # 在 HA 中显示的名字
unique_id: "study_room_light_01" # 随便起个唯一 ID
state_topic: "home/study/status" # 灯上报状态的主题
command_topic: "home/study/switch" # HA 发送指令的主题
payload_on: "on" # 开启指令(通常是 ON 或 1)
payload_off: "off" # 关闭指令(通常是 OFF 或 0)
optimistic: false # 如果没有状态反馈主题,请设为 true
qos: 1
retain: true
方法二、MQTT Discovery 自动发现
Home Assistant 支持 MQTT Discovery 自动发现设备,无需手动修改 configuration.yaml。
MQTT Discovery 使用以下主题结构:
<discovery_prefix>/<component>/[<node_id>/]<object_id>/config
- discovery_prefix: 默认为 homeassistant。
- component: 设备类型,如 sensor(传感器)、switch(开关)、light(灯)。
- object_id: 设备的唯一标识(通常使用 ESP8266 的 MAC 地址)。
ESP8266 只需向对应主题发布设备配置,HA 就会自动创建实体。
代码示例
void setup_discovery() {
// 构建发现主题
String chipId = String(ESP.getChipId());
String topic = "homeassistant/switch/esp8266_" + chipId + "/config";
//构建 JSON 配置信息
StaticJsonDocument<512> doc;
doc["name"] = "书房灯";
doc["state_topic"] = state_topic;
doc["command_topic"] = command_topic;
doc["unique_id"] = "esp8266_study_room_light_01_" + chipId;
doc["payload_on"] = "on";
doc["payload_off"] = "off";
char buffer[512];
serializeJson(doc, buffer);
// 发布配置信息 (必须设置为 retain: true)
client.publish(topic.c_str(), buffer, true);
}
创建 MQTT 用户
为了安全起见,建议在 MQTT Broker 中创建一个专门的用户账号,用于 Home Assistant 连接。
- 进入: Settings->person->Add User 创建一个新用户,设置用户名和密码,并记住这些信息。
后续 ESP8266 连接 MQTT Broker 时需要使用该账号。
修改 ESP8266 代码连接 MQTT Broker
首先查看 MQTT Broker 所在设备的 IP 地址:
进入:
Settings → System → Network
找到 Home Assistant 主机的 IP 地址。
然后修改 ESP8266 代码中的 MQTT 配置:
- MQTT Broker IP
- 用户名
- 密码
同时在代码中加入 状态回传,当灯状态改变时,向 HA 上报当前状态。
示例代码如下:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// 定义继电器连接的引脚为 GPIO 4
#define RELAY 4
// WiFi 配置
const char *ssid = ""; // 输入你的 WiFi 名称
const char *password = ""; // 输入 WiFi 密码
// MQTT 服务器配置
const char *mqtt_broker = ""; // 输入 MQTT Broker 的 IP 地址
const char *command_topic = "home/study/switch";
const char *state_topic = "home/study/status";
const char *mqtt_username = ""; // 输入 MQTT 用户名(刚才创建的用户账号的用户名)
const char *mqtt_password = ""; // 输入 MQTT 密码(刚才创建的用户账号的密码)
const int mqtt_port = 1883;
bool relayState = false; // 记录继电器状态
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
// 设置串口波特率为 9600
Serial.begin(9600);
delay(1000); // 等待系统稳定
// 连接 WiFi 网络
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("正在连接 WiFi...");
}
Serial.println("WiFi 已连接");
// 设置继电器引脚为输出模式
pinMode(RELAY, OUTPUT);
digitalWrite(RELAY, LOW); // 初始状态关闭继电器(或 LED)
// 设置 MQTT 服务器并配置回调函数
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(callback);
// 循环直到连接上 MQTT 服务器
while (!client.connected()) {
String client_id = "esp8266-client-";
client_id += String(WiFi.macAddress());
Serial.printf("客户端 %s 正在连接HA MQTT 服务器...\n", client_id.c_str());
if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
Serial.println("已连接到 HA MQTT 服务器");
} else {
Serial.print("连接失败,错误状态码:");
Serial.print(client.state());
delay(2000);
}
}
// 发布配置信息
setup_discovery();
// 订阅主题
client.publish(state_topic, "off");
client.subscribe(command_topic);
}
// 收到 MQTT 消息时的回调函数
void callback(char *topic, byte *payload, unsigned int length) {
Serial.print("收到主题消息: ");
Serial.println(topic);
Serial.print("消息长度: ");
Serial.println(length);
Serial.print(" 内容: ");
String message;
for (int i = 0; i < length; i++) {
message += (char) payload[i]; // 将字节数据转换为字符串
}
Serial.println(message);
// 如果收到 "on" 且当前是关闭状态,则开启继电器
if ((message == "on") && !relayState) {
digitalWrite(RELAY, HIGH); // 开启继电器(点亮)
relayState = true;
client.publish(state_topic, "on");
Serial.println(" -> 执行:开启");
}
// 如果收到 "off" 且当前是开启状态,则关闭继电器
if ((message == "off") && relayState) {
digitalWrite(RELAY, LOW); // 关闭继电器(熄灭)
relayState = false;
client.publish(state_topic, "off");
Serial.println(" -> 执行:关闭");
}
Serial.println();
Serial.println("-----------------------");
}
void loop() {
// 保持 MQTT 客户端的心跳处理
client.loop();
delay(100); // 每次循环轻微延迟
}
通过Home Assistant控制
完成上述配置后, HA 的界面中,你应该能够看到一个新的灯控实体,点击它就可以控制继电器灯的开关了!

通过HomeKit控制
如果已经安装了 Homebridge 插件, 该设备还可以同步到 Apple HomeKit。
在 Home App 中同样可以看到 书房灯, 并且可以通过 Siri 语音控制:
例如:
“Hey Siri,打开书房灯。”
更多推荐

所有评论(0)