设备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); }