Add initial version

This commit is contained in:
sqozz 2018-02-20 17:59:06 +01:00
commit e45991de2f
2 changed files with 252 additions and 0 deletions

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
*__pycache__*
secrets.h
.*.swp
.*.swo
build.py

247
espower.ino Normal file
View file

@ -0,0 +1,247 @@
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <RCSwitch.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <ArduinoJson.h>
#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 <head>
String css = "body {background-color:#ffffff; color: #000000;}h1 {font-size: 2em;}";
String head1 = "<!DOCTYPE html> <html> <head> <title>Steckdosensteuerung</title> <style>";
String head2 = "</style></head><body><center>";
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 = "<h1>Steckdosensteuerung</h1>";
// 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 + "<p>" + name + " <a href=\"socket" + String(i) + "On\"><button>ON</button></a>&nbsp;<a href=\"socket" + String(i) + "Off\"><button>OFF</button></a></p>";
//}
body += "</center></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();
}