/* ESP8266 Pingcheck Wifi Module Pings three IP Addresses. If one of them responses, the light is on. 2016 www.frag-duino.de */ #include #include #include #include extern "C" { #include "user_interface.h" #include "ping.h" } ESP8266WebServer server(80); /* * To set the new Wifi, enter credentials in the two variables and set RESET_EEPROM to true. * During the next start it will save it into the EEPROM. * Then set RESET_EEPROM to false and flash it again. * When wifi changes, remember to first change the name over the webinterface. */ #define RESET_EEPROM false #define WIFI_SSID "Freifunk" #define WIFI_PASSWORD "" // Settings const int PING_INTERVAL = 5000; const int PIN_LED = 2; const int count_hosts = 3; int connection_try = 15; char host1[15]; char host2[15]; char host3[15]; boolean host_is_online[] = {false, false, false}; // EEPROM Addresses const int ADDRESS_IP1 = 0; const int ADDRESS_IP2 = 15; const int ADDRESS_IP3 = 30; const int ADDRESS_INIT = 105; // - 99 const int ADDRESS_PASSWORD = 45; // - 75 const int ADDRESS_SSID = 75; // - 105 const int EEPROM_SIZE = 106; // Variables IPAddress network_ip; char network_ssid[30]; char network_password[30]; struct ping_option pingopt; unsigned long last_ping = 0; unsigned long last_seen_online = 0; unsigned long currentMillis = 0; int currentHost = 0; int state_LED = LOW; boolean got_new_hosts; boolean save_wifi; // Save the current config void writeIPtoEEPROM() { for (int i = 0; i < 15; i++) { EEPROM.write(ADDRESS_IP1 + i, host1[i]); EEPROM.write(ADDRESS_IP2 + i, host2[i]); EEPROM.write(ADDRESS_IP3 + i, host3[i]); } EEPROM.commit(); } void writeSSIDtoEEPROM(String new_ssid) { for (int i = 0; i < 30; i++) { if (i < new_ssid.length()) EEPROM.write(ADDRESS_SSID + i, new_ssid[i]); else EEPROM.write(ADDRESS_SSID + i, '\0'); } EEPROM.commit(); } void writePASSWORDtoEEPROM(String new_password) { for (int i = 0; i < 30; i++) { if (i < new_password.length()) EEPROM.write(ADDRESS_PASSWORD + i, new_password[i]); else EEPROM.write(ADDRESS_PASSWORD + i, '\0'); } EEPROM.commit(); } // Reply is called, when response arrives static void callback_reply (void* arg, void *pdata) { struct ping_resp *pingresp = (struct ping_resp *)pdata; if (pingresp->resp_time > 0) { Serial.println(" Response"); last_seen_online = currentMillis; host_is_online[currentHost] = true; } else { Serial.println(" Timeout"); host_is_online[currentHost] = false; } } // Sends an echo request to an IP-Address void ping(uint32 ip) { pingopt.ip = ip; pingopt.count = 1; pingopt.coarse_time = 200; pingopt.recv_function = &callback_reply; // pingopt.sent_function = NULL; ping_start(&pingopt); } boolean checkIPsyntax(String ip) { // Only 0-9 and dots for (int i = 0; i <= 33; i++) if (ip.indexOf(i) != -1) return false; if (ip.indexOf(0x2F) != -1) return false; for (int i = 0x3A; i <= 0x7F; i++) if (ip.indexOf(i) != -1) return false; // Count the amount of dots int dots = 0; for (int i = 0; i < ip.length(); i++) if (ip[i] == '.') dots++; if (dots != 3) return false; // Check the range of the oktets int dot_1 = ip.indexOf('.'); int dot_2 = ip.indexOf('.', dot_1 + 1); int dot_3 = ip.indexOf('.', dot_2 + 1); int oktet_1 = ip.substring(0, dot_1).toInt(); int oktet_2 = ip.substring(dot_1 + 1, dot_2).toInt(); int oktet_3 = ip.substring(dot_2 + 1, dot_3).toInt(); int oktet_4 = ip.substring(dot_3 + 1).toInt(); if (oktet_1 >= 0 && oktet_1 <= 255 && oktet_2 >= 0 && oktet_2 <= 255 && oktet_3 >= 0 && oktet_3 <= 255 && oktet_4 >= 0 && oktet_4 <= 255 ) return true; else return false; } void handleRoot() { Serial.print(currentMillis); Serial.print(": HTTP-Request with "); got_new_hosts = false; save_wifi = false; String temp_ssid; String temp_password; if (server.args() > 0) { Serial.print(server.args()); Serial.print(" args: "); for (int a = 0; a < server.args(); a++) { Serial.print("["); Serial.print(server.argName(a)); Serial.print("="); Serial.print(server.arg(a)); Serial.print("]"); if (server.arg(a) == "Restart") // Restart ESP8266 system_restart(); else if (server.arg(a) == "Save-Wifi") { Serial.println("OK, Save-Wifi"); save_wifi = true; } else if (server.argName(a) == "ssid") { for (int i = 0; i < 30; i++) { if (i < server.arg(a).length()) network_ssid[i] = server.arg(a)[i]; else network_ssid[i] = '\0'; } } else if (server.argName(a) == "password") { for (int i = 0; i < 30; i++) { if (i < server.arg(a).length()) network_password[i] = server.arg(a)[i]; else network_password[i] = '\0'; } } else if (server.argName(a) == "ip1" && checkIPsyntax(server.arg(a))) { memset(host1, 0, sizeof(host1)); for (int i = 0; i < server.arg(a).length(); i++) host1[i] = server.arg(a)[i]; got_new_hosts = true; Serial.print(" OK1 "); } else if (server.argName(a) == "ip2" && checkIPsyntax(server.arg(a))) { memset(host2, 0, sizeof(host2)); for (int i = 0; i < server.arg(a).length(); i++) host2[i] = server.arg(a)[i]; got_new_hosts = true; Serial.print(" OK2 "); } else if (server.argName(a) == "ip3" && checkIPsyntax(server.arg(a))) { memset(host3, 0, sizeof(host3)); for (int i = 0; i < server.arg(a).length(); i++) host3[i] = server.arg(a)[i]; got_new_hosts = true; Serial.print(" OK3 "); } else Serial.print(" NACK; "); } } else Serial.print("no args"); Serial.println("."); // Save it if (got_new_hosts) writeIPtoEEPROM(); if (save_wifi) { writeSSIDtoEEPROM(network_ssid); if (temp_password != "notchanged") writePASSWORDtoEEPROM(network_password); } // Print the HTML-Page String result = "PingCheck\r\n\r\n"; result += "PingCheck 2.0 (2015 Marcel Imig www.frag-duino.de)

\r\n\r\n"; result += "
Wifi status
"; result += "\r\n"; result += "\r\n"; result += "\r\n\r\n"; result += "\r\n"; result += "\r\n\r\n"; result += "\r\n\r\n
Network SSID:
Network Password:
\r\n"; result += "\r\n"; result += "
\r\n\r\n
\r\n
\r\n"; result += "
Hosts\r\nMonitoring IPs:

\r\n\r\n"; result += "
"; result += "IP1:
\r\n"; result += "IP2:
\r\n"; result += "IP3:
\r\n"; result += " \r\n"; result += "\r\n\r\n
\r\n"; result += "\r\n"; server.send(200, "text / html", result); } void handleDump() { Serial.println("EEPROM:"); for (int i = 0; i < EEPROM_SIZE; i++) { Serial.print(i); Serial.print(": "); Serial.println((char) EEPROM.read(i)); } Serial.println("END"); server.send(200, "text / html", "DUMPED ON SERIAL OUTPUT"); } void setup() { // Initialize Serial and LEDs Serial.begin(115200); delay(20); Serial.println("\r\n Ready "); pinMode(PIN_LED, OUTPUT); digitalWrite(PIN_LED, HIGH); // Read IPs and Wifi-credentials from EEPROM EEPROM.begin(EEPROM_SIZE); if (RESET_EEPROM) { // First start, initialize EEPROM strncpy(host1, "192.168.123.1", 13); strncpy(host2, "8.8.8.8", 7); strncpy(host3, "8.8.4.4", 7); writeSSIDtoEEPROM(WIFI_SSID); writePASSWORDtoEEPROM(WIFI_PASSWORD); writeIPtoEEPROM(); Serial.println("EEPROM initialized"); while (true) { digitalWrite(PIN_LED, HIGH); delay(100); digitalWrite(PIN_LED, LOW); delay(100); } } else { // Read from EEPROM for (int i = 0; i < 15; i++) { host1[i] = EEPROM.read(ADDRESS_IP1 + i); host2[i] = EEPROM.read(ADDRESS_IP2 + i); host3[i] = EEPROM.read(ADDRESS_IP3 + i); } for (int i = 0; i < 30; i++) // SSID network_ssid[i] = EEPROM.read(ADDRESS_SSID + i); for (int i = 0; i < 30; i++) // Password network_password[i] = EEPROM.read(ADDRESS_PASSWORD + i); } // Print hosts Serial.println("Hosts from EEPROM:"); Serial.print("[1]: "); Serial.println(host1); Serial.print("[2]: "); Serial.println(host2); Serial.print("[3]: "); Serial.println(host3); Serial.print("Wifi from EEPROM: \""); Serial.print(network_ssid); Serial.print("\" \""); Serial.print(network_password); Serial.println("\"\r\n"); // Connect to AP WiFi.mode(WIFI_STA); // Set to client WiFi.begin(network_ssid, network_password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.println("."); if (state_LED == HIGH) state_LED = LOW; else state_LED = HIGH; digitalWrite(PIN_LED, state_LED); } Serial.print("Connected to "); Serial.println(network_ssid); Serial.print("IP address: "); network_ip = WiFi.localIP(); Serial.println(network_ip); // Start the server server.on("/", handleRoot); server.on("/dump/", handleDump); server.begin(); digitalWrite(PIN_LED, HIGH); delay(250); digitalWrite(PIN_LED, LOW); } void loop() { server.handleClient(); currentMillis = millis(); // Read current runtime if (WiFi.status() != WL_CONNECTED) { Serial.println("Not connected anymore, restarting"); system_restart(); } if (last_ping + PING_INTERVAL < currentMillis) { Serial.print(currentMillis); const char* host; currentHost = (currentHost + 1) % count_hosts; if (currentHost == 0) host = host1; else if (currentHost == 1) host = host2; else host = host3; uint32 address = ipaddr_addr(host); if (host[0] == '0' && host[2] == '0' && host[4] == '0' && host[6] == '0') Serial.println(": Skipping"); else { Serial.print(": Pinging \""); Serial.print(host); Serial.print("\" - "); ping(address); last_ping = currentMillis; } } if (last_seen_online + (count_hosts * PING_INTERVAL) > currentMillis) state_LED = HIGH; else state_LED = LOW; digitalWrite(PIN_LED, state_LED); }