|
/*
ESP32通过wifi连接MQTT,并订阅发布信息控制相应的设备
*/
#include <WiFi.h>
#include <PubSubClient.h>
//Wifi参数
const char* ssid = "finance office"; //设置Wi-Fi名
const char* password = "XXX"; //设置Wi-Fi密码
// Mqtt Broker参数
const char* mqtt_server = "192.168.9.XXX"; //设置MQTT服务器地址
const char* mqtt_username = "mqtt" ;
const char* mqtt_password = "XXX" ;
const int mqtt_port = 1883 ;
// 定义MQTT主题前缀
// 设备标识
const char* deviceName = "Esp32_Mqtt_Controller"; //设备名
const char* deviceId = "Esp32S3_16R8-2BB77"; //设备ID
const char* discoveryPrefix = "homeassistant"; // HA自动发现前缀
// 定义开关数量和引脚
const int switchCount = 2; // 开关数量
// 定义MQTT 实体参数
struct SwitchConfig {
const char* name;
const char* uniqueId;
const char* commandTopic;
const char* stateTopic;
int gpioPin;
bool state;
};
SwitchConfig switches[2] = {
{
"Esp32_Switch1", // 开关1名称
"Esp32_Mqtt_Switch1", // 唯一ID
"homeassistant/switch/switch1/cmd",// 命令主题
"homeassistant/switch/switch1/state",// 状态主题
1, // GPIO引脚
false // 初始状态
},
{
"Esp32_Switch2", // 开关2名称
"Esp32_Mqtt_Switch2", // 唯一ID
"homeassistant/switch/switch2/cmd",// 命令主题
"homeassistant/switch/switch2/state",// 状态主题
2, // GPIO引脚
false // 初始状态
}
};
//
WiFiClient espClient;
PubSubClient client(espClient);
//连接wifi
void setup_wifi() {
delay(10);
Serial.println("Connect WiFi: " + String(ssid));
WiFi.begin(ssid, password);
//等待WiFi连接
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print("connect Wifi... ");
}
//wifi连接成功后输出成功信息
Serial.println("WiFi Connected! "); //显示wifi连接成功
Serial.println("IP: " + String(WiFi.localIP())); //返回wifi分配的IP
Serial.println("MAC: " + String(WiFi.macAddress())); //返回设备的MAC地址
Serial.println("");
randomSeed(micros());
}
//回调函数
void callback(char* topic, byte* payload, unsigned int length) {
// 将payload转换为字符串
String message;
for (int i = 0; i < length; i++) {
message += (char)payload;
}
Serial.print("Received[");
Serial.print(topic);
Serial.print("] ");
Serial.println(message);
// 检查所有控制主题
for (int i = 0; i < switchCount; i++) {
if (String(topic) == switches.commandTopic) {
if (message == "on" || message == "1") {
digitalWrite(switches.gpioPin, HIGH);
switches.state = true;
Serial.println("开关" + String(switches.name) + " 打开");
client.publish(switches.stateTopic, (String(switches.uniqueId) + ": ON").c_str());
}
else if (message == "off" || message == "0") {
digitalWrite(switches.gpioPin, LOW);
switches.state = false;
Serial.println("开关" + String(switches.name) + " 关闭");
client.publish(switches.stateTopic, (String(switches.uniqueId) + ": OFF").c_str());
}
else if (message == "toggle") {
digitalWrite(switches.gpioPin, !digitalRead(switches.gpioPin));
String state = digitalRead(switches.gpioPin) ? "ON" : "OFF";
Serial.println("开关" + String(switches.name) + " 切换: " + state);
client.publish(switches.stateTopic, (String(switches.uniqueId) + ": " + state).c_str());
}
break; // 找到匹配主题后退出循环
}
}
}
void reconnect() {
while (!client.connected()) {
Serial.print("Try Mqtt Connect... ");
if (client.connect(deviceId, mqtt_username, mqtt_password)) {
Serial.println("Mqtt Connected");
// 订阅所有控制主题
for (int i = 0; i < switchCount; i++) {
client.subscribe(switches.commandTopic);
Serial.println("Subscribe topic: " + String(switches.commandTopic));
}
// 发送自动发现配置
sendAutoDiscoveryConfig();
// 发布初始状态
for (int i = 0; i < 2; i++) {
client.publish(switches.stateTopic, switches.state ? "ON" : "OFF", true);
}
} else {
Serial.print("失败, rc=");
Serial.print(client.state());
Serial.println(" 5秒后重试...");
delay(5000);
}
}
}
void sendAutoDiscoveryConfig() {
for (int i = 0; i < switchCount; i++) {
char discoveryTopic[150];
snprintf(discoveryTopic, sizeof(discoveryTopic), "%s/switch/%s/%s/config",
discoveryPrefix, deviceId, switches.name);
String payload = "{";
payload += "\"name\":\"" + String(switches.name) + "\",";
payload += "\"unique_id\":\"" + String(switches.uniqueId) + "\",";
payload += "\"command_topic\":\"" + String(switches.commandTopic) + "\",";
payload += "\"state_topic\":\"" + String(switches.stateTopic) + "\",";
payload += "\"availability_topic\":\"homeassistant/status\",";
payload += "\"payload_available\":\"online\",";
payload += "\"payload_not_available\":\"offline\",";
payload += "\"device\":{";
payload += "\"identifiers\":[\"" + String(deviceId) + "\"],";
payload += "\"name\":\"" + String(deviceName) + "\",";
payload += "\"model\":\"ESP32S3\",";
payload += "\"sw_version\":\"1.0\"";
payload += "}";
payload += "}";
Serial.println(discoveryTopic);
Serial.println(payload.c_str());
client.publish(discoveryTopic, payload.c_str(), true);
Serial.printf("Discovery config sent for %s\n", switches.name);
}
// 发布在线状态
client.publish("homeassistant/status", "online", true);
}
void setup() {
// 初始化所有GPIO引脚
for (int i = 0; i < switchCount; i++) {
pinMode(switches.gpioPin, OUTPUT);
digitalWrite(switches.gpioPin, LOW); // 初始状态为关闭
}
Serial.begin(115200);
setup_wifi(); //连接wifi
client.setServer(mqtt_server, mqtt_port); //设置MQTT服务器
client.setCallback(callback); //设置回调函数
}
void loop() {
if (!client.connected()) {
reconnect(); //尝试连接MQTT服务器并接收信息
}
client.loop();
}
|
|