├── README.md └── WemosRelaySwitch.ino /README.md: -------------------------------------------------------------------------------- 1 | # WemosWithPushbutton2 2 | 3 | This project is an extension of Aruna Tennakoon's Wemos Relay switch. Specifically it adds a manual pushbutton switch to toggle the relay. 4 | 5 | Hardware setup: 6 | 1. Connect a 10k resistor between 3.3v and D0 7 | 2. Connect a momentary pushbutton switch between D0 and GND 8 | 9 | To toggle the switch, simply press the pushbutton. 10 | -------------------------------------------------------------------------------- /WemosRelaySwitch.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void prepareIds(); 7 | boolean connectWifi(); 8 | boolean connectUDP(); 9 | void startHttpServer(); 10 | void turnOnRelay(); 11 | void turnOffRelay(); 12 | 13 | const char* ssid = "YOUR_SSID"; 14 | const char* password = "YOUR_PASSWORD"; 15 | 16 | unsigned int localPort = 1900; // local port to listen on 17 | 18 | WiFiUDP UDP; 19 | boolean udpConnected = false; 20 | IPAddress ipMulti(239, 255, 255, 250); 21 | unsigned int portMulti = 1900; // local port to listen on 22 | 23 | ESP8266WebServer HTTP(80); 24 | 25 | boolean wifiConnected = false; 26 | 27 | char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet, 28 | 29 | String serial; 30 | String persistent_uuid; 31 | String device_name; 32 | 33 | const int relayPin = D1; 34 | const int switchPin = D0; 35 | 36 | boolean cannotConnectToWifi = false; 37 | 38 | int switchState = 0; 39 | 40 | void setup() { 41 | Serial.begin(115200); 42 | 43 | // Setup Relay 44 | pinMode(relayPin, OUTPUT); 45 | 46 | // Setup Switch 47 | pinMode(switchPin, INPUT); 48 | 49 | turnOffRelay(); 50 | switchState = 0; 51 | Serial.println("Setting relay to off - setting value to 0"); 52 | 53 | prepareIds(); 54 | 55 | // Initialise wifi connection 56 | wifiConnected = connectWifi(); 57 | 58 | // only proceed if wifi connection successful 59 | if(wifiConnected){ 60 | udpConnected = connectUDP(); 61 | 62 | if (udpConnected){ 63 | // initialise pins if needed 64 | startHttpServer(); 65 | } 66 | } 67 | } 68 | 69 | void loop() { 70 | 71 | 72 | if (digitalRead(switchPin)){ 73 | Serial.println("On switch"); 74 | delay(250); 75 | if (!digitalRead(switchPin)){ 76 | switchState = !switchState; 77 | Serial.print("Switch Pressed - Relay now "); 78 | 79 | // Show and change Relay State 80 | if (switchState){ 81 | Serial.println("ON"); 82 | turnOnRelay(); 83 | } 84 | else 85 | { 86 | Serial.println("OFF"); 87 | turnOffRelay(); 88 | } 89 | delay(500); 90 | } 91 | } 92 | 93 | HTTP.handleClient(); 94 | delay(1); 95 | 96 | 97 | // if there's data available, read a packet 98 | // check if the WiFi and UDP connections were successful 99 | if(wifiConnected){ 100 | if(udpConnected){ 101 | // if there’s data available, read a packet 102 | int packetSize = UDP.parsePacket(); 103 | 104 | if(packetSize) { 105 | Serial.println(""); 106 | Serial.print("Received packet of size "); 107 | Serial.println(packetSize); 108 | Serial.print("From "); 109 | IPAddress remote = UDP.remoteIP(); 110 | 111 | for (int i =0; i < 4; i++) { 112 | Serial.print(remote[i], DEC); 113 | if (i < 3) { 114 | Serial.print("."); 115 | } 116 | } 117 | 118 | Serial.print(", port "); 119 | Serial.println(UDP.remotePort()); 120 | 121 | int len = UDP.read(packetBuffer, 255); 122 | 123 | if (len > 0) { 124 | packetBuffer[len] = 0; 125 | } 126 | 127 | String request = packetBuffer; 128 | //Serial.println("Request:"); 129 | //Serial.println(request); 130 | 131 | if(request.indexOf('M-SEARCH') > 0) { 132 | if(request.indexOf("urn:Belkin:device:**") > 0) { 133 | Serial.println("Responding to search request ..."); 134 | respondToSearch(); 135 | } 136 | } 137 | } 138 | 139 | delay(10); 140 | } 141 | } else { 142 | // Turn on/off to indicate cannot connect .. 143 | } 144 | } 145 | 146 | void prepareIds() { 147 | uint32_t chipId = ESP.getChipId(); 148 | char uuid[64]; 149 | sprintf_P(uuid, PSTR("38323636-4558-4dda-9188-cda0e6%02x%02x%02x"), 150 | (uint16_t) ((chipId >> 16) & 0xff), 151 | (uint16_t) ((chipId >> 8) & 0xff), 152 | (uint16_t) chipId & 0xff); 153 | 154 | serial = String(uuid); 155 | persistent_uuid = "Socket-1_0-" + serial; 156 | device_name = "NAME_YOUR_DEVICE_HERE"; 157 | } 158 | 159 | void respondToSearch() { 160 | Serial.println(""); 161 | Serial.print("Sending response to "); 162 | Serial.println(UDP.remoteIP()); 163 | Serial.print("Port : "); 164 | Serial.println(UDP.remotePort()); 165 | 166 | IPAddress localIP = WiFi.localIP(); 167 | char s[16]; 168 | sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]); 169 | 170 | String response = 171 | "HTTP/1.1 200 OK\r\n" 172 | "CACHE-CONTROL: max-age=86400\r\n" 173 | "DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n" 174 | "EXT:\r\n" 175 | "LOCATION: http://" + String(s) + ":80/setup.xml\r\n" 176 | "OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n" 177 | "01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n" 178 | "SERVER: Unspecified, UPnP/1.0, Unspecified\r\n" 179 | "ST: urn:Belkin:device:**\r\n" 180 | "USN: uuid:" + persistent_uuid + "::urn:Belkin:device:**\r\n" 181 | "X-User-Agent: redsonic\r\n\r\n"; 182 | 183 | UDP.beginPacket(UDP.remoteIP(), UDP.remotePort()); 184 | UDP.write(response.c_str()); 185 | UDP.endPacket(); 186 | 187 | Serial.println("Response sent !"); 188 | } 189 | 190 | void startHttpServer() { 191 | HTTP.on("/index.html", HTTP_GET, [](){ 192 | Serial.println("Got Request index.html ...\n"); 193 | HTTP.send(200, "text/plain", "Bedroom Light"); 194 | }); 195 | 196 | HTTP.on("/upnp/control/basicevent1", HTTP_POST, []() { 197 | Serial.println("########## Responding to /upnp/control/basicevent1 ... ##########"); 198 | 199 | //for (int x=0; x <= HTTP.args(); x++) { 200 | // Serial.println(HTTP.arg(x)); 201 | //} 202 | 203 | String request = HTTP.arg(0); 204 | Serial.print("request:"); 205 | Serial.println(request); 206 | 207 | if(request.indexOf("1") > 0) { 208 | Serial.println("Got Turn on request"); 209 | turnOnRelay(); 210 | } 211 | 212 | if(request.indexOf("0") > 0) { 213 | Serial.println("Got Turn off request"); 214 | turnOffRelay(); 215 | } 216 | 217 | HTTP.send(200, "text/plain", ""); 218 | }); 219 | 220 | HTTP.on("/eventservice.xml", HTTP_GET, [](){ 221 | Serial.println(" ########## Responding to eventservice.xml ... ########\n"); 222 | String eventservice_xml = "" 223 | "" 224 | "" 225 | "SetBinaryState" 226 | "" 227 | "" 228 | "" 229 | "BinaryState" 230 | "BinaryState" 231 | "in" 232 | "" 233 | "" 234 | "" 235 | "" 236 | "BinaryState" 237 | "Boolean" 238 | "0" 239 | "" 240 | "" 241 | "level" 242 | "string" 243 | "0" 244 | "" 245 | "" 246 | "" 247 | "\r\n" 248 | "\r\n"; 249 | 250 | HTTP.send(200, "text/plain", eventservice_xml.c_str()); 251 | }); 252 | 253 | HTTP.on("/setup.xml", HTTP_GET, [](){ 254 | Serial.println(" ########## Responding to setup.xml ... ########\n"); 255 | 256 | IPAddress localIP = WiFi.localIP(); 257 | char s[16]; 258 | sprintf(s, "%d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]); 259 | 260 | String setup_xml = "" 261 | "" 262 | "" 263 | "urn:Belkin:device:controllee:1" 264 | ""+ device_name +"" 265 | "Belkin International Inc." 266 | "Emulated Socket" 267 | "3.1415" 268 | "uuid:"+ persistent_uuid +"" 269 | "221517K0101769" 270 | "0" 271 | "" 272 | "" 273 | "urn:Belkin:service:basicevent:1" 274 | "urn:Belkin:serviceId:basicevent1" 275 | "/upnp/control/basicevent1" 276 | "/upnp/event/basicevent1" 277 | "/eventservice.xml" 278 | "" 279 | "" 280 | "" 281 | "\r\n" 282 | "\r\n"; 283 | 284 | HTTP.send(200, "text/xml", setup_xml.c_str()); 285 | 286 | Serial.print("Sending :"); 287 | Serial.println(setup_xml); 288 | }); 289 | 290 | HTTP.begin(); 291 | Serial.println("HTTP Server started .."); 292 | } 293 | 294 | 295 | 296 | // connect to wifi – returns true if successful or false if not 297 | boolean connectWifi(){ 298 | boolean state = true; 299 | int i = 0; 300 | 301 | WiFi.mode(WIFI_STA); 302 | WiFi.begin(ssid, password); 303 | Serial.println(""); 304 | Serial.println("Connecting to WiFi"); 305 | 306 | // Wait for connection 307 | Serial.print("Connecting ..."); 308 | while (WiFi.status() != WL_CONNECTED) { 309 | delay(500); 310 | Serial.print("."); 311 | if (i > 10){ 312 | state = false; 313 | break; 314 | } 315 | i++; 316 | } 317 | 318 | if (state){ 319 | Serial.println(""); 320 | Serial.print("Connected to "); 321 | Serial.println(ssid); 322 | Serial.print("IP address: "); 323 | Serial.println(WiFi.localIP()); 324 | } 325 | else { 326 | Serial.println(""); 327 | Serial.println("Connection failed."); 328 | } 329 | 330 | return state; 331 | } 332 | 333 | boolean connectUDP(){ 334 | boolean state = false; 335 | 336 | Serial.println(""); 337 | Serial.println("Connecting to UDP"); 338 | 339 | if(UDP.beginMulticast(WiFi.localIP(), ipMulti, portMulti)) { 340 | Serial.println("Connection successful"); 341 | state = true; 342 | } 343 | else{ 344 | Serial.println("Connection failed"); 345 | } 346 | 347 | return state; 348 | } 349 | 350 | void turnOnRelay() { 351 | digitalWrite(relayPin, HIGH); // turn on relay with voltage HIGH 352 | switchState = 1; 353 | } 354 | 355 | void turnOffRelay() { 356 | digitalWrite(relayPin, LOW); // turn off relay with voltage LOW 357 | switchState = 0; 358 | } 359 | --------------------------------------------------------------------------------