commit e45991de2ff5ad130a6f1b5b809d536e0352a83a Author: sqozz Date: Tue Feb 20 17:59:06 2018 +0100 Add initial version diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1effebc --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*__pycache__* +secrets.h +.*.swp +.*.swo +build.py diff --git a/espower.ino b/espower.ino new file mode 100644 index 0000000..9c2b2a8 --- /dev/null +++ b/espower.ino @@ -0,0 +1,247 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "secrets.h" + +const char pin_r = 5; +const char pin_g = 6; +const char pin_b = 8; + +RCSwitch mySwitch = RCSwitch(); +MDNSResponder mdns; + +ESP8266WebServer server(80); + +// CSS and HTML +String css = "body {background-color:#ffffff; color: #000000;}h1 {font-size: 2em;}"; +String head1 = " Steckdosensteuerung
"; +String header = head1 + css + head2; +String body = ""; +String website(String h, String b){ + String complete = h+b; + return complete; +} + +typedef struct { + char* channel; + char* id; + String name; + bool powered; +} PowerSocket; + +PowerSocket sockets[] = { + (PowerSocket) {"00000", "10000", "A", false}, + (PowerSocket) {"00000", "01000", "B", false}, + (PowerSocket) {"00000", "00100", "C", false}, + (PowerSocket) {"00000", "00010", "D", false} +}; + +int numofsockets = sizeof(sockets)/sizeof(sockets[0]); + +void setup() { + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + + // if you want to modify body part of html start here + body = "

Steckdosensteuerung

"; + // socket names and buttons are created dynamical + // TODO: generate buttons for webui + //for(int i = 0; i < numofsockets; i++){ + // String name = sockets[i].name; + // body = body + "

" + name + "  

"; + //} + body += "
"; + + mySwitch.enableTransmit(2); + delay(1000); + + // setup serial and network + Serial.begin(115200); + WiFi.begin(ssid, password); + + Serial.println("Serial interface initialized"); + Serial.print("Connecting to wifi "); + Serial.print(ssid); + + // Wait for connection + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + + // serial output of connection details + Serial.println(""); + Serial.print("Connected to "); + Serial.println(ssid); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + if (mdns.begin("esp8266", WiFi.localIP())) { + Serial.println("MDNS responder started"); + } + + // Port defaults to 8266 + // ArduinoOTA.setPort(8266); + ArduinoOTA.setHostname("kinderschreck"); + + // No authentication by default + // ArduinoOTA.setPassword("admin"); + + // Password can be set with it's md5 value as well + // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 + // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3"); + + ArduinoOTA.onStart([]() { + String type; + if (ArduinoOTA.getCommand() == U_FLASH) + type = "sketch"; + else // U_SPIFFS + type = "filesystem"; + + // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() + Serial.println("Start updating " + type); + }); + + ArduinoOTA.onEnd([]() { + Serial.println("\nEnd"); + }); + + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + Serial.printf("Progress: %u%%\r", (progress / (total / 100))); + }); + + ArduinoOTA.onError([](ota_error_t error) { + Serial.printf("Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); + else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); + else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); + else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); + else if (error == OTA_END_ERROR) Serial.println("End Failed"); + }); + + ArduinoOTA.begin(); + Serial.println("ArduinoOTA ready"); + + // create HTTP server + server.on("/", handleMainpage); + for (int i = 0; i < numofsockets; i++) { + server.on("/" + String(sockets[i].channel), handleSocket); + } + server.begin(); + Serial.println("HTTP server started"); +} + +void handleSocket() { + String data = server.arg("plain"); + String channelArg = server.uri().substring(1); + String idArg = server.arg("id"); + String result; + + char channel[5]; + strncpy(channel, channelArg.c_str(), 5); + + char id[5]; + strncpy(id, idArg.c_str(), 5); + + Serial.println(channel); + Serial.println(id); + + if (data != "") { + Serial.println("change request"); + StaticJsonBuffer<200> newBuffer; + JsonObject& json = newBuffer.parseObject(data); + + if (json["active"] == "true") { + Serial.println("on"); + result = setSocket(channel, id, true); + } else if (json["active"] == "false") { + Serial.println("off"); + result = setSocket(channel, id, false); + } + } else { + Serial.println("status request"); + if (server.arg("id") != "") { + result = generateStatusJson(channel, id); + } else { + Serial.println("ERROR: no id"); + result = "{ error: \"no id\" }"; + } + } + server.send(200, "text/json", result); + + Serial.println(""); + Serial.println(""); +} + +void handleMainpage() { + String mainpage = website(header, body); + server.send(200, "text/html", mainpage); +} + +String setSocket(const char* channel, const char* id, bool newStatus) { + PowerSocket socket; + bool oldStatus = false; + bool success = false; + + int socketIdx = findSocketIndex(channel, id); + if (socketIdx >= 0) { + success = true; + socket = sockets[socketIdx]; + oldStatus = socket.powered; + socket.powered = newStatus; + sockets[socketIdx] = socket; // write back to status array + if (newStatus == true) { + for (char i = 0; i <= 1; i++) { + mySwitch.switchOn(socket.channel, socket.id); + delay(250); + } + } else { + for (char i = 0; i <= 1; i++) { + mySwitch.switchOff(socket.channel, socket.id); + delay(250); + } + } + } + + return generateChangeJson(success, String(oldStatus), String(socket.powered)); +} + +int findSocketIndex(const char* channel, const char* id) { + for (int socketIdx = 0; socketIdx < numofsockets; socketIdx++) { + PowerSocket canidateSocket = sockets[socketIdx]; + if (strncmp(canidateSocket.channel, channel, 5) == 0 && + strncmp(canidateSocket.id, id, 5) == 0) + { + return socketIdx; + } + } + + return -1; +} + +String generateChangeJson(bool success, String oldStatus, String newStatus) { + String status = ""; + if (success) { + status = ", \"status\" : { \"old\" : " + oldStatus + ", \"new\" : " + newStatus + " }"; + } + String retJson = "{ \"success\" : " + String(success) + status + " }"; + + return retJson; +} + +String generateStatusJson(const char* channel, const char* id) { + int idx = findSocketIndex(channel, id); + PowerSocket socket = sockets[idx]; + String status = "{ \"status\" : " + String(socket.powered) + " }"; + return status; +} + +void loop() { + server.handleClient(); + ArduinoOTA.handle(); +}