kakopappa / arduino-esp8266-alexa-multiple-wemo-switch

multiple belkin wemos switch emulator using ESP8266
https://sinric.pro
MIT License
308 stars 196 forks source link

Not an issue......multiple wemo with dynamic wifi credentials and socket configurations #41

Open mutthunaveen opened 6 years ago

mutthunaveen commented 6 years ago

Dear bro...

i ve used your source code of multiple wemo and added android ap code for configuring wifi name pass code and also to configure switches dynamically..

here is the brief description of code i ve developed

  1. Waits for wifi connection during attempt GPIO blinks every 1 sec untill 60sec (60sec because if power failure then my wifi router takes around 50sec to restore with good wifi (i beleive it is same in most cases))

  2. if connection is unsuccessful after 60seconds then GPIO permanently goes off and ap mode auto starts, as shown in below figure

    untitled

  3. now take your mobile and trun on wifi and connect to the name "BUBBLES".. refer screenshot below screenshot_2018-02-17-18-21-17-705_com android settings

  4. connect to ip as mentioned in 2nd step uart log. the mobile screen will look like below mobile

  5. and "Submit" thats it.. wifi id and password will be saved in EEPROM and everything will work fine..

  6. when power reset wifi will get auto connected with ID and password read from EEPROM of ESP8266. and GPIO will be on continuously when wifi is connected "symbol of successful wifi connection"

  7. if you dont want 5 smart switches then leave blank "configure socket name text box". if you leave blanck then switch will not be configured anymore.

Enjoy the code (cheers to kakopappa) - if you want to buy a beer buy for him... :+1:

`

include

#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <functional>
#include "switch.h"
#include "UpnpBroadcastResponder.h"
#include "CallbackFunction.h"

// --------- ap mode -----------
#include <ESP8266mDNS.h>
#include <EEPROM.h>

MDNSResponder mdns;
ESP8266WebServer server(80);

const char* ssid = "BUBBLES";
const char* passphrase = "BUBBLES";
String st;
String content;

// end ap mode------------

// prototypes
boolean connectWifi();

//on/off callbacks 
bool socket_1_on();
bool socket_1_off();
bool socket_2_on();
bool socket_2_off();
bool socket_3_on();
bool socket_3_off();
bool socket_4_on();
bool socket_4_off();
bool socket_5_on();
bool socket_5_off();

bool soc_1_configured= false; 
bool soc_2_configured= false; 
bool soc_3_configured= false; 
bool soc_4_configured= false; 
bool soc_5_configured= false; 

// Change this before you flash
const char* wemo_ssid = "FCI_BB_NAV";
const char* wemo_password = "voohanaveen@voohanaveen";

//---- declare io pin -------------
const int relayPin = 2;
//---- end declare io pin -------------

int icount = 0;
boolean wifiConnected = false;

UpnpBroadcastResponder upnpBroadcastResponder;

Switch *socket1 = NULL;
Switch *socket2 = NULL;
Switch *socket3 = NULL;
Switch *socket4 = NULL;
Switch *socket5 = NULL;

bool is_socket_1_on = false;
bool is_socket_2_on = false;
bool is_socket_3_on = false;
bool is_socket_4_on = false;
bool is_socket_5_on = false;

//--- switch names ------------
String socket_1_name="";
String socket_2_name="";
String socket_3_name="";
String socket_4_name="";
String socket_5_name="";

//--- end of switch names ------------

void setup()
{
  Serial.begin(115200);

  // Setup Relay
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW); 
  icount = 0;
  //---------- read ssid and pass ----------------
      EEPROM.begin(512);
      delay(10);
      Serial.println();
      Serial.println();
      Serial.println("Startup");
      // read eeprom for ssid and pass
      Serial.println("Reading EEPROM ssid");
      String esid;
      for (int i = 0; i < 32; ++i)
        {
          esid += char(EEPROM.read(i));
        }
      Serial.print("SSID: ");
      Serial.println(esid);
      Serial.println("Reading EEPROM pass");
      String epass = "";
      for (int i = 32; i < 96; ++i)
        {
          epass += char(EEPROM.read(i));
        }
      Serial.print("PASS: ");
      Serial.println(epass);  

    // -----------end read ssid and pass ---------------

  // ------- read each switch name and load --------------------
  // each switch name is limited to 20char
  String socket_name_x = "";
    Serial.println("Reading EEPROM device names");
      socket_name_x = "";

  long fetch_eeprom_code = 100;
  //----------------------------------------------------------------
  for (long i = fetch_eeprom_code; i < fetch_eeprom_code + 20; ++i)
        {
          socket_name_x += char(EEPROM.read(i));
        }
    Serial.print("soc 1: ");
      Serial.println(socket_name_x);
    socket_1_name = socket_name_x.c_str();
  //----------------------------------------------------------------
  //----------------------------------------------------------------  
    fetch_eeprom_code += 20;
      socket_name_x = "";      
  for (long i = fetch_eeprom_code; i < fetch_eeprom_code + 20; ++i)
        {
          socket_name_x += char(EEPROM.read(i));
        }
      Serial.print("soc 2: ");
      Serial.println(socket_name_x); 
    socket_2_name = socket_name_x.c_str();  
  //----------------------------------------------------------------  
    fetch_eeprom_code += 20;
      socket_name_x = "";      
  for (long i = fetch_eeprom_code; i < fetch_eeprom_code + 20; ++i)
        {
          socket_name_x += char(EEPROM.read(i));
        }
      Serial.print("soc 3: ");
      Serial.println(socket_name_x);  
    socket_3_name = socket_name_x.c_str();
  //----------------------------------------------------------------  
  //----------------------------------------------------------------  
    fetch_eeprom_code += 20;
      socket_name_x = "";      
  for (long i = fetch_eeprom_code; i < fetch_eeprom_code + 20; ++i)
        {
          socket_name_x += char(EEPROM.read(i));
        }
      Serial.print("soc 4: ");
      Serial.println(socket_name_x);  
        socket_4_name = socket_name_x.c_str();
  //----------------------------------------------------------------  
  //----------------------------------------------------------------  
    fetch_eeprom_code += 20;
      socket_name_x = "";      
  for (long i = fetch_eeprom_code; i < fetch_eeprom_code + 20; ++i)
        {
          socket_name_x += char(EEPROM.read(i));
        }
      Serial.print("soc 5: ");
      Serial.println(socket_name_x);  
        socket_5_name = socket_name_x.c_str();
  //----------------------------------------------------------------  

  // ------- end read each switch name and load --------------------

    wemo_ssid = esid.c_str();
    wemo_password = epass.c_str();

  // Initialise wifi connection
  wifiConnected = connectWifi(); // uncomment this code in final execution
  //
  //wifiConnected = 0; // comment this line in fianl code

  if(wifiConnected){
    upnpBroadcastResponder.beginUdpMulticast();

    // Define your switches here. Max 10
    // Format: Alexa invocation name, local port no, on callback, off callback
    if(socket_1_name.length()>0)
  {
    socket1 = new Switch(socket_1_name, 80, socket_1_on, socket_1_off);
    soc_1_configured = true;
  }

  if(socket_2_name.length()>0)
  {
    socket2 = new Switch(socket_2_name, 81, socket_2_on, socket_2_off);
    soc_2_configured = true;
  }

  if(socket_3_name.length()>0)
  {
    socket3 = new Switch(socket_3_name, 82, socket_3_on, socket_3_off);
    soc_3_configured = true;
  }

  if(socket_4_name.length()>0)
  {
    socket4 = new Switch(socket_4_name, 83, socket_4_on, socket_4_off);
    soc_4_configured = true;
  }
  if(socket_5_name.length()>0)
  {
    socket5 = new Switch(socket_5_name, 84, socket_5_on, socket_5_off);
    soc_5_configured = true;
  }

  //socket1 = new Switch("socket1", 80, socket_2_on, socket_2_off);

    Serial.println("Adding switches upnp broadcast responder");
  if(soc_1_configured) { upnpBroadcastResponder.addDevice(*socket1); }
  if(soc_2_configured) { upnpBroadcastResponder.addDevice(*socket2); }
  if(soc_3_configured) { upnpBroadcastResponder.addDevice(*socket3); }
  if(soc_4_configured) { upnpBroadcastResponder.addDevice(*socket4); }
  if(soc_5_configured) { upnpBroadcastResponder.addDevice(*socket5); }  
  }
  //----- ap mode -----
    else
  {
     setupAP();
  }
  //----- end ap mode -----
}

void loop()
{

   server.handleClient();
   if(wifiConnected){
      digitalWrite(relayPin, HIGH);
      upnpBroadcastResponder.serverLoop();
  if(soc_1_configured) {       socket1->serverLoop(); }
  if(soc_2_configured) {       socket2->serverLoop(); }
  if(soc_3_configured) {       socket3->serverLoop(); }
  if(soc_4_configured) {       socket4->serverLoop(); }
  if(soc_5_configured) {       socket5->serverLoop(); }
  }
}

bool socket_1_on() {
    Serial.println(socket_1_name);
  Serial.println("on");
    is_socket_1_on = true;    
    return is_socket_1_on;
}

bool socket_1_off() {
    Serial.println(socket_1_name);
  Serial.println("off");
    is_socket_1_on = false;
    return is_socket_1_on;
}

bool socket_2_on() {
    Serial.println(socket_2_name);
  Serial.println("on");
    is_socket_2_on = true;    
    return is_socket_2_on;
}

bool socket_2_off() {
    Serial.println(socket_2_name);
  Serial.println("off");
    is_socket_2_on = false;
    return is_socket_2_on;
}

bool socket_3_on() {
    Serial.println(socket_3_name);
  Serial.println("on");
    is_socket_3_on = true;    
    return is_socket_3_on;
}

bool socket_3_off() {
    Serial.println(socket_3_name);
  Serial.println("off");
    is_socket_3_on = false;
    return is_socket_3_on;
}

bool socket_4_on() {
    Serial.println(socket_4_name);
  Serial.println("on");
    is_socket_4_on = true;    
    return is_socket_4_on;
}

bool socket_4_off() {
    Serial.println(socket_4_name);
  Serial.println("off");
    is_socket_4_on = false;
    return is_socket_4_on;
}

bool socket_5_on() {
    Serial.println(socket_5_name);
  Serial.println("on");
    is_socket_5_on = true;    
    return is_socket_5_on;
}

bool socket_5_off() {
    Serial.println(socket_5_name);
  Serial.println("off");
    is_socket_5_on = false;
    return is_socket_5_on;
}

// connect to wifi – returns true if successful or false if not
boolean connectWifi(){
  boolean state = true;
  int i = 0;

  WiFi.mode(WIFI_STA);
  WiFi.begin(wemo_ssid, wemo_password);
  Serial.println("");
  Serial.println("Connecting to WiFi");

  // Wait for connection
///* //- un comment this untill serial print line connection failed
  Serial.print("Connecting ...");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    //--- status led code
    digitalWrite(relayPin, HIGH);
    delay(500);
    digitalWrite(relayPin, LOW);
    //--- end status led code

    if (i > 60){ // try 60 times - 1 min for initilization
      state = false;
      break;
    }
    i++;
  }

  if (state){
    Serial.println("");
    Serial.print("Connected to ");
    Serial.println(wemo_ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  }
  else {

  Serial.println("");
    Serial.println("Connection failed.");
  }
//*/ //- end un comment this untill serial print line connection failed
  //state = 0; // comment this in main code
  return state;
}

//------------------- ap mode code------------------------

void launchWeb(int webtype) {
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("Local IP: ");
  Serial.println(WiFi.localIP());
  Serial.print("SoftAP IP: ");
  Serial.println(WiFi.softAPIP());
  /*if (!mdns.begin("esp8266", WiFi.localIP())) {
    Serial.println("Error setting up MDNS responder!");
    while(1) { 
      delay(1000);
    }
  }
  */
  Serial.println("mDNS responder started"); 
  createWebServer(webtype);
  // Start the server
  server.begin();
  Serial.println("Server started"); 
}

void setupAP(void) {
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
  int n = WiFi.scanNetworks();
  Serial.println("scan done");
  if (n == 0)
    Serial.println("no networks found");
  else
  {
    Serial.print(n);
    Serial.println(" networks found");
    for (int i = 0; i < n; ++i)
     {
      // Print SSID and RSSI for each network found
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
      delay(10);
     }
  }
  Serial.println(""); 
  st = "<ol>";
  for (int i = 0; i < n; ++i)
    {
      // Print SSID and RSSI for each network found
      st += "<li>";
      st += WiFi.SSID(i);
      st += " (";
      st += WiFi.RSSI(i);
      st += ")";
      st += (WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*";
      st += "</li>";
    }
  st += "</ol>";
  delay(100);
  WiFi.softAP(ssid);
  Serial.println("softap");
  launchWeb(1);
  Serial.println("over");
}

void createWebServer(int webtype)
{
  // Check for any mDNS queries and send responses
  mdns.update();

  if ( webtype == 1 ) {
    server.on("/", []() {
        IPAddress ip = WiFi.softAPIP();
        String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
        content = "<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 at ";
        content += ipStr;
        content += "<p>";
        content += st;
        content += "</p><form method='get' action='setting'><label>SSID: </label><input name='ssid' length=32><input name='pass' length=64>";
        content += "</p> <label>Configure socket 1 name ->: </label><input name='soc1' length=20>";
        content += "</p> <label>Configure socket 2 name ->: </label><input name='soc2' length=20>";
        content += "</p> <label>Configure socket 3 name ->: </label><input name='soc3' length=20>";        
        content += "</p> <label>Configure socket 4 name ->: </label><input name='soc4' length=20>";
        content += "</p> <label>Configure socket 5 name ->: </label><input name='soc5' length=20>";
    content += "</p> <input type='submit'></form>";
        content += "</html>";
        server.send(200, "text/html", content);  
    });
    server.on("/setting", []() {
        String qsid = server.arg("ssid");
        String qpass = server.arg("pass");

        String qsoc1 = server.arg("soc1");
        String qsoc2 = server.arg("soc2");
        String qsoc3 = server.arg("soc3");
        String qsoc4 = server.arg("soc4");
        String qsoc5 = server.arg("soc5");

          Serial.println(qsoc1);
          Serial.println(qsoc2);
          Serial.println(qsoc3);
          Serial.println(qsoc4);
          Serial.println(qsoc5);

  boolean written_to_eeprom = false;

    if (qsid.length() > 0 && qpass.length() > 0) {
          Serial.println("clearing eeprom");
          for (int i = 0; i < 96; ++i) { EEPROM.write(i, 0); }

          Serial.println("writing eeprom ssid:");
          for (int i = 0; i < qsid.length(); ++i)
            {
              EEPROM.write(i, qsid[i]);
              Serial.print("Wrote: ");
              Serial.println(qsid[i]); 
            }
          Serial.println("writing eeprom pass:"); 
          for (int i = 0; i < qpass.length(); ++i)
            {
              EEPROM.write(32+i, qpass[i]);
              Serial.print("Wrote: ");
              Serial.println(qpass[i]); 
            }    
      written_to_eeprom = true;
    }

  //------------- write config names into switches-----------------
  long eeprom_var_update = 100;
  if (qsoc1.length() > 0) {
          for (long i = eeprom_var_update; i < eeprom_var_update + 20; ++i) { EEPROM.write(i, 0); }

          Serial.println("writing soc1 name:");
          for (long i = 0; i < qsoc1.length(); ++i)
            {
              EEPROM.write(i+eeprom_var_update, qsoc1[i]);
              //Serial.print("Wrote: ");
              //Serial.println(qsoc1[i]); 
            }
      written_to_eeprom = true;
    }

  eeprom_var_update = 120;
  if (qsoc2.length() > 0) {
          for (long i = eeprom_var_update; i < eeprom_var_update + 20; ++i) { EEPROM.write(i, 0); }

          Serial.println("writing soc2 name:");
          for (long i = 0; i < qsoc2.length(); ++i)
            {
              EEPROM.write(i+eeprom_var_update, qsoc2[i]);
              //Serial.print("Wrote: ");
              //Serial.println(qsoc2[i]); 
            }
      written_to_eeprom = true;
    }

  eeprom_var_update = 140;
  if (qsoc3.length() > 0) {
          for (long i = eeprom_var_update; i < eeprom_var_update + 20; ++i) { EEPROM.write(i, 0); }

          Serial.println("writing soc3 name:");
          for (long i = 0; i < qsoc3.length(); ++i)
            {
              EEPROM.write(i+eeprom_var_update, qsoc3[i]);
              //Serial.print("Wrote: ");
              //Serial.println(qsoc3[i]); 
            }
      written_to_eeprom = true;
    }

    eeprom_var_update = 160;
  if (qsoc4.length() > 0) {
          for (long i = eeprom_var_update; i < eeprom_var_update + 20; ++i) { EEPROM.write(i, 0); }

          Serial.println("writing soc4 name:");
          for (long i = 0; i < qsoc4.length(); ++i)
            {
              EEPROM.write(i+eeprom_var_update, qsoc4[i]);
              //Serial.print("Wrote: ");
              //Serial.println(qsoc4[i]); 
            }
      written_to_eeprom = true;
    }

      eeprom_var_update = 180;
  if (qsoc5.length() > 0) {
          for (long i = eeprom_var_update; i < eeprom_var_update + 20; ++i) { EEPROM.write(i, 0); }

          Serial.println("writing soc5 name:");
          for (long i = 0; i < qsoc5.length(); ++i)
            {
              EEPROM.write(i+eeprom_var_update, qsoc5[i]);
            }
      written_to_eeprom = true;
    }

//------------- end write config names into switches-----------------
    if (written_to_eeprom == true) {
      EEPROM.commit();
      content = "<!DOCTYPE HTML>\r\n<html>";
      content += "<p>saved to eeprom... reset to boot into new wifi</p></html>";
    }
    else {
          content = "Error";
          Serial.println("Sending 404");
        }
        server.send(200, "text/html", content);
    });
  } else {
    server.on("/", []() {
      server.send(200, "text/plain", "this works as well");
    });
    server.on("/setting", []() {
      server.send(200, "text/plain", "setting.");
    });
    server.on("/cleareeprom", []() {
      content = "<!DOCTYPE HTML>\r\n<html>";
      content += "<p>Clearing the EEPROM</p></html>";
      server.send(200, "text/html", content);
      Serial.println("clearing eeprom");
      for (int i = 0; i < 96; ++i) { EEPROM.write(i, 0); }
      EEPROM.commit();
    });
  }
}

//------------------- end ap mode code------------------------

`

i hope the code is useful.... cheers kakopappa.... please include my code in your repositories if you are interested......

ashrambo commented 1 year ago

Hello, If I want to use this code with an old roomba, I must replace:

bool socket_1_on() { Serial.println(socket_1_name); Serial.println("on"); is_socket_1_on = true;
return is_socket_1_on; }

bool socket_1_off() { Serial.println(socket_1_name); Serial.println("off"); is_socket_1_on = false; return is_socket_1_on;

FOR

bool socket_1_on() { Serial.println(socket_1_name); Serial.println("on"); is_socket_1_on = true;
return is_socket_1_on; Serial.write(128); // start command delay(50); Serial.write(131); // safe mod delay(50); Serial.write(135); // clean return true; }

bool socket_1_off() { Serial.println(socket_1_name); Serial.println("off"); is_socket_1_on = false; return is_socket_1_on; Serial.write(128); // start command delay(50); Serial.write(131); // safe mod delay(50); Serial.write(143); // dock return false;

Is this correct? thxs