zoukankan      html  css  js  c++  java
  • (二 -3-1) 天猫精灵接入Home Assistant-自动发现Mqtt设备--灯系列 esp8266程序

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

      

  • 相关阅读:
    “学霸系统”app——NABC
    Scrum Meeting NO.1
    团队成员角色
    团队作业 #2
    团队作业 #1
    Qt, 我回来了。。。
    boost: tcp client sample
    makefile 中定义宏位置需要注意一下
    libpcap报文解析: ipv4、ipv6 @ 2014.7.2
    编程网站收集
  • 原文地址:https://www.cnblogs.com/kekeoutlook/p/9491237.html
Copyright © 2011-2022 走看看