#include #include #include #include void prepareIds(); boolean connectWifi(); boolean connectUDP(); void startHttpServer(); void turnOnRelay(); void turnOffRelay(); void sendRelayState(); const char* ssid = "xxxxxxxxxxx"; const char* password = "xxxxxxxxxxxxxx"; String friendlyName = "box"; // Alexa device name unsigned int localPort = 1900; // local port to listen on WiFiUDP UDP; boolean udpConnected = false; IPAddress ipMulti(239, 255, 255, 250); unsigned int portMulti = 1900; // local port to listen on ESP8266WebServer HTTP(80); boolean wifiConnected = false; boolean relayState = false; char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet, String serial; String persistent_uuid; const int relayPin = D1; boolean cannotConnectToWifi = false; void setup() { Serial.begin(115200); // Setup Relay pinMode(relayPin, OUTPUT); prepareIds(); // Initialise wifi connection wifiConnected = connectWifi(); // only proceed if wifi connection successful if(wifiConnected){ Serial.println("Ask Alexa to discover devices"); udpConnected = connectUDP(); if (udpConnected){ // initialise pins if needed startHttpServer(); } } } void loop() { HTTP.handleClient(); delay(1); // if there's data available, read a packet // check if the WiFi and UDP connections were successful if(wifiConnected){ if(udpConnected){ // if there�s data available, read a packet int packetSize = UDP.parsePacket(); if(packetSize) { //Serial.println(""); //Serial.print("Received packet of size "); //Serial.println(packetSize); //Serial.print("From "); IPAddress remote = UDP.remoteIP(); for (int i =0; i < 4; i++) { Serial.print(remote[i], DEC); if (i < 3) { Serial.print("."); } } Serial.print(", port "); Serial.println(UDP.remotePort()); int len = UDP.read(packetBuffer, 255); if (len > 0) { packetBuffer[len] = 0; } String request = packetBuffer; //Serial.println("Request:"); //Serial.println(request); if(request.indexOf('M-SEARCH') > 0) { if(request.indexOf("upnp:rootdevice") > 0) { Serial.println("Responding to search request ..."); respondToSearch(); } } } delay(10); } } else { // Turn on/off to indicate cannot connect .. } } void prepareIds() { uint32_t chipId = ESP.getChipId(); char uuid[64]; sprintf_P(uuid, PSTR("38323636-4558-4dda-9188-cda0e6%02x%02x%02x"), (uint16_t) ((chipId >> 16) & 0xff), (uint16_t) ((chipId >> 8) & 0xff), (uint16_t) chipId & 0xff); serial = String(uuid); persistent_uuid = "Socket-1_0-" + serial; } void respondToSearch() { Serial.println(""); Serial.print("Sending response to "); Serial.println(UDP.remoteIP()); Serial.print("Port : "); Serial.println(UDP.remotePort()); IPAddress localIP = WiFi.localIP(); char s[16]; sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]); String response = "HTTP/1.1 200 OK\r\n" "CACHE-CONTROL: max-age=86400\r\n" "DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n" "EXT:\r\n" "LOCATION: http://" + String(s) + ":80/setup.xml\r\n" "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" "01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n" "SERVER: Unspecified, UPnP/1.0, Unspecified\r\n" "ST: urn:Belkin:device:**\r\n" "USN: uuid:" + persistent_uuid + "::upnp:rootdevice\r\n" "X-User-Agent: redsonic\r\n\r\n"; UDP.beginPacket(UDP.remoteIP(), UDP.remotePort()); UDP.write(response.c_str()); UDP.endPacket(); Serial.println("Response sent !"); } void startHttpServer() { HTTP.on("/index.html", HTTP_GET, [](){ Serial.println("Got Request index.html ...\n"); HTTP.send(200, "text/plain", "Hello World!"); }); HTTP.on("/upnp/control/basicevent1", HTTP_POST, []() { Serial.println("########## Responding to /upnp/control/basicevent1 ... ##########"); //for (int x=0; x <= HTTP.args(); x++) { // Serial.println(HTTP.arg(x)); //} String request = HTTP.arg(0); Serial.print("request:"); Serial.println(request); if(request.indexOf("SetBinaryState") >= 0) { if(request.indexOf("1") >= 0) { Serial.println("Got Turn on request"); turnOnRelay(); } if(request.indexOf("0") >= 0) { Serial.println("Got Turn off request"); turnOffRelay(); } } if(request.indexOf("GetBinaryState") >= 0) { Serial.println("Got binary state request"); sendRelayState(); } HTTP.send(200, "text/plain", ""); }); HTTP.on("/eventservice.xml", HTTP_GET, [](){ Serial.println(" ########## Responding to eventservice.xml ... ########\n"); String eventservice_xml = "" "" "" "SetBinaryState" "" "" "" "BinaryState" "BinaryState" "in" "" "" "" "" "GetBinaryState" "" "" "" "BinaryState" "BinaryState" "out" "" "" "" "" "" "" "BinaryState" "Boolean" "0" "" "" "level" "string" "0" "" "" "\r\n" "\r\n"; HTTP.send(200, "text/plain", eventservice_xml.c_str()); }); HTTP.on("/setup.xml", HTTP_GET, [](){ Serial.println(" ########## Responding to setup.xml ... ########\n"); IPAddress localIP = WiFi.localIP(); char s[16]; sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]); String setup_xml = "" "" "" "urn:Belkin:device:controllee:1" ""+ friendlyName +"" "Belkin International Inc." "Socket" "3.1415" "Belkin Plugin Socket 1.0\r\n" "uuid:"+ persistent_uuid +"" "221517K0101769" "0" "" "" "urn:Belkin:service:basicevent:1" "urn:Belkin:serviceId:basicevent1" "/upnp/control/basicevent1" "/upnp/event/basicevent1" "/eventservice.xml" "" "" "" "\r\n" "\r\n"; HTTP.send(200, "text/xml", setup_xml.c_str()); Serial.print("Sending :"); Serial.println(setup_xml); }); HTTP.begin(); Serial.println("HTTP Server started .."); } // 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(ssid, password); Serial.println(""); Serial.println("Connecting to WiFi"); // Wait for connection Serial.print("Connecting ..."); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); if (i > 10){ state = false; break; } i++; } if (state){ Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); } else { Serial.println(""); Serial.println("Connection failed."); } return state; } boolean connectUDP(){ boolean state = false; Serial.println(""); Serial.println("Connecting to UDP"); if(UDP.beginMulticast(WiFi.localIP(), ipMulti, portMulti)) { Serial.println("Connection successful"); state = true; } else{ Serial.println("Connection failed"); } return state; } void turnOnRelay() { digitalWrite(relayPin, HIGH); // turn on relay with voltage HIGH relayState = true; String body = "\r\n" "\r\n" "1\r\n" "\r\n" " "; HTTP.send(200, "text/xml", body.c_str()); Serial.print("Sending :"); Serial.println(body); } void turnOffRelay() { digitalWrite(relayPin, LOW); // turn off relay with voltage LOW relayState = false; String body = "\r\n" "\r\n" "0\r\n" "\r\n" " "; HTTP.send(200, "text/xml", body.c_str()); Serial.print("Sending :"); Serial.println(body); } void sendRelayState() { String body = "\r\n" "\r\n" ""; body += (relayState ? "1" : "0"); body += "\r\n" "\r\n" " \r\n"; HTTP.send(200, "text/xml", body.c_str()); }