設備1
上電自動注冊自己是個1個開關
HASS網頁和手機APP控制
外部開關上升沿中斷控制
天貓精靈語音控制
一鍵配網
記錄以往WIFI信息
設備2
上電后,自動注冊自己有三個開關控制
HASS網頁和手機APP控制
外部開關上升沿中斷控制
天貓精靈語音控制
設備1 代碼
需添加
一鍵配網
記錄以往WIFI信息
需去掉 打印注釋
/***************************************************
****************************************************/
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
/*-------------------------------------------------------------------------------------------
* 配置WIFI信息
*------------------------------------------------------------------------------------------*/
#define WLAN_SSID "dongdong"
#define WLAN_PASS "ldd123456"
/*-------------------------------------------------------------------------------------------
* 配置MQTT服務器信息
*------------------------------------------------------------------------------------------*/
//#define AIO_SERVER "io.adafruit.com" // 不穩定
//#define AIO_SERVER "broker.mqtt-dashboard.com" // 穩定
#define AIO_SERVER "www.dongvdong.top"
#define AIO_SERVERPORT 1883 // use 8883 for SSL
#define AIO_USERNAME ""
#define AIO_KEY ""
/*-------------------------------------------------------------------------------------------
* 配置外接設備
*------------------------------------------------------------------------------------------*/
// 燈的接口 D4口-繼電器
int Light_1 = D4;
// 燈的按鍵 D2- 按鍵開關
int Light_1_btn = D8;
/*-------------------------------------------------------------------------------------------
* 開啟MQTT服務
*------------------------------------------------------------------------------------------*/
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_USERNAME, AIO_KEY);
/*-------------------------------------------------------------------------------------------
-由於MQTT發布信息有長度限制 130個左右,不能一次性發送太多自身配置信息,因此發雜的設備無法注冊
*/
//------------------1 設備自身配置信息 ------------------------
//-------------------新設備 (1)修改在hass中顯示的名字(可以不改)
// 在hass中顯示的名字
#define name_s "rgb"
//-------------------新設備 (2)修改設備分配的話題(必須改) 可修改第二 產品 ID
// 用戶 + 產品 ID + 屬性+ 接收或發送
//接收開關命令話題
#define command_topic_s "DD/rgb/o/c"
// 自身開關狀態發布話題
#define state_topic_s "DD/rgb/o/s"
// 接收亮度命令話
#define brightness_command_topic_s "DD/rgb/b/c"
// 自身亮度發布話題
#define brightness_state_topic_s "DD/rgb/b/s"
// 接收顏色命令話題
#define rgb_command_topic_s "DD/rgb/r/c"
// 自身顏色狀態發布話題
#define rgb_state_topic_s "DD/rgb/r/s"
#define optimistic_c "false"
//-------------------2 hass自動發現MQTT設備話題-------第三參數 ID 必須改------------------
//-------------------新設備 (3)修改設備注冊ID 第三個參數 (不同於名字)
#define MQTT_config_TOPIC "homeassistant/light/rgb_test_v1/config"
//-------------------新設備 (4)修改設備屬性 有什么屬性加入json包
//------------------燈 JSON打包 開關 亮度 顏色------------------------
// 燈必須先有 開關 然后有亮度 然后 再有顏色 (跳過順序將不會正常顯示功能)
String my_config_s=
String("{\"name\":\"")+ name_s
+String("\",\"command_topic\":\"")+command_topic_s
+String("\",\"state_topic\":\"")+state_topic_s
+String("\",\"brightness_command_topic\":\"")+brightness_command_topic_s
+String("\",\"brightness_state_topic\":\"")+brightness_state_topic_s
//+String("\",\"rgb_command_topic_topic\":\"")+rgb_command_topic_s
//+String("\",\"rgb_state_topic\":\"")+rgb_state_topic_s
//+String("\",\"optimistic\":\"")+optimistic_c
+String("\"}");
// 發布自己的配置信息
Adafruit_MQTT_Publish hass_config = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME MQTT_config_TOPIC);
// 發布自己的開關信息
Adafruit_MQTT_Publish state_topic = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME state_topic_s);
//hachina
//發布自己的亮度信息
Adafruit_MQTT_Publish brightness_state_topic = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME brightness_state_topic_s);
//發布自己的顏色信息
Adafruit_MQTT_Publish rgb_state_topic = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME rgb_state_topic_s);
/*-------------------------------------------------------------------------------------------
* 功能:訂閱開關信息
* 輸入:顏色數據
* 輸出:空
*------------------------------------------------------------------------------------------*/
//訂閱開關命令
Adafruit_MQTT_Subscribe command_topic = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME command_topic_s, MQTT_QOS_1);
//訂閱亮度命令
Adafruit_MQTT_Subscribe brightness_command_topic = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME brightness_command_topic_s, MQTT_QOS_1);
//訂閱顏色命令
Adafruit_MQTT_Subscribe rgb_command_topic = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME rgb_command_topic_s, MQTT_QOS_1);
/*************************** 接受信息訂閱函數 ************************************/
void state_topic_send(String state){
if (!mqtt.connected()) {
Serial.println(F("state_topic.publish Failed"));
return;
}
if (! state_topic.publish(state.c_str())) {
Serial.println(F("state_topic.publish Failed"));
} else {
Serial.println(String("state_topic.publish ")+state);
}
}
/*-------------------------------------------------------------------------------------------
* 功能:接收開關命令回掉函數
* on 開燈 off 關燈
* 輸入:接收數據+數據長度
* 輸出:空
*------------------------------------------------------------------------------------------*/
void command_topic_call(char *data, uint16_t len) {
//Serial.print("the button value is: ");
//Serial.println(data);
String msg=String(data);
// 收到 打開
if(msg=="ON") { Serial.println("light is open");
digitalWrite(Light_1, HIGH);
state_topic_send("ON");// 返回 打開狀態
}
if(msg=="OFF") { Serial.println("light is close");
digitalWrite(Light_1, LOW);
state_topic_send("OFF");
}
}
/*-------------------------------------------------------------------------------------------
* 功能:接收亮度命令回掉函數
* 向電腦打印輸出亮度值 0-255
* 輸入:亮度數據
* 輸出:空
*------------------------------------------------------------------------------------------*/
void brightness_command_topic_call(double x) {
Serial.print("Hey we're in a slider callback, the slider value is: ");
Serial.println(x);
if (! brightness_state_topic.publish(x)) {
Serial.println(F("brightness_state_topic.publish Failed"));
} else {
Serial.print(F("brightness_state_topic.publish "));Serial.println(x);
}
}
/*-------------------------------------------------------------------------------------------
* 功能:接收顏色命令回掉函數
* 向電腦打印輸出亮度值 255,255,255
* 輸入:顏色數據
* 輸出:空
*------------------------------------------------------------------------------------------*/
void rgb_command_topic_call(char *data, uint16_t len) {
Serial.print("the button value is: ");
Serial.println(data);
}
/*-------------------------------------------------------------------------------------------
* 功能:外部設備中斷函數
*------------------------------------------------------------------------------------------*/
bool Light_1_state=LOW;// 開關狀態
bool Light_1_stateSend=0; // 是否返回開關數據
void Light_1_btn_highInterrupt(){
Light_1_state=!Light_1_state;// 硬件開關每次按一下,開關狀態反轉一下
Light_1_stateSend=1;// 打開發送標志位,在主函數中調用publish將自己的狀態返回去,在中斷里調用會報錯
digitalWrite(Light_1, Light_1_state);
}
/*-------------------------------------------------------------------------------------------
* 功能:外部設備初始化
*------------------------------------------------------------------------------------------*/
void IO_int(){
//繼電器初始化--燈
pinMode(Light_1, OUTPUT);
digitalWrite(Light_1, LOW);
// 燈的按鍵開關初始化
pinMode(Light_1_btn, INPUT);
attachInterrupt(Light_1_btn, Light_1_btn_highInterrupt, RISING);// 上升沿觸發
}
void setup() {
IO_int();
Serial.begin(115200);
delay(10);
Serial.println(F("Adafruit MQTT demo"));
// Connect to WiFi access point.
Serial.println(); Serial.println();
Serial.print("Connecting to ");
Serial.println(WLAN_SSID);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: "); Serial.println(WiFi.localIP());
// 配置信息轉換
// strcpy( my_config_c, my_config.c_str());
// 回掉函數
command_topic.setCallback(command_topic_call);
brightness_command_topic.setCallback(brightness_command_topic_call);
rgb_command_topic.setCallback(rgb_command_topic_call);
// 訂閱話題注冊
mqtt.subscribe(&command_topic);
mqtt.subscribe(&brightness_command_topic);
mqtt.subscribe(&rgb_command_topic);
}
uint32_t x=0;
void loop() {
MQTT_connect();
// this is our 'wait for incoming subscription packets and callback em' busy subloop
// try to spend your time here:
mqtt.processPackets(1000);
//按鍵對燈的控制以及返回燈的狀態
if(Light_1_stateSend==1){
if(Light_1_state==HIGH)
{state_topic_send("ON");}
else if(Light_1_state==LOW)
{state_topic_send("OFF");}
Light_1_stateSend=0; // 發送置於0 關閉
}
// ping the server to keep the mqtt connection alive
// NOT required if you are publishing once every KEEPALIVE seconds
if(! mqtt.ping()) {
mqtt.disconnect();
}
}
// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
int8_t ret;
// Stop if already connected.
if (mqtt.connected()) {
return;
}
Serial.print("Connecting to MQTT... ");
uint8_t retries = 3;
while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
Serial.println(mqtt.connectErrorString(ret));
Serial.println("Retrying MQTT connection in 3 seconds...");
mqtt.disconnect();
delay(3000); // wait 10 seconds
retries--;
if (retries == 0) {
// basically die and wait for WDT to reset me
while (1);
// ESP.wdtFeed();
}
}
Serial.println("MQTT Connected!");
hass_config.publish(my_config_s.c_str());
// 內存不夠大 ,一直重啟 只能注冊個簡單的有開關功能
Serial.println(my_config_s);
}
