2018-02-20 17:59:06 +01:00
|
|
|
#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;
|
2018-03-12 23:39:14 +01:00
|
|
|
uint8_t type; // 0=DIP, 1=Learned
|
|
|
|
int on_code;
|
|
|
|
int off_code;
|
2018-02-20 17:59:06 +01:00
|
|
|
} PowerSocket;
|
|
|
|
|
|
|
|
PowerSocket sockets[] = {
|
2018-03-12 23:39:14 +01:00
|
|
|
(PowerSocket) {"00000", "10000", "A", false, 0, -1, -1},
|
|
|
|
(PowerSocket) {"00000", "01000", "B", false, 0, -1, -1},
|
|
|
|
(PowerSocket) {"00000", "00100", "C", false, 0, -1, -1},
|
|
|
|
(PowerSocket) {"00000", "00010", "D", false, 0, -1, -1},
|
|
|
|
(PowerSocket) {"", "", "E", false, 1, 530800, 713872},
|
|
|
|
(PowerSocket) {"", "", "F", false, 1, 172340, 409380},
|
|
|
|
(PowerSocket) {"", "", "G", false, 1, 842428, 409388},
|
|
|
|
(PowerSocket) {"", "", "H", false, 1, 713874, 530802}
|
2018-02-20 17:59:06 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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> <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++) {
|
2018-03-11 01:05:17 +01:00
|
|
|
server.on("/" + String(sockets[i].name), handleSocket);
|
2018-02-20 17:59:06 +01:00
|
|
|
}
|
|
|
|
server.begin();
|
|
|
|
Serial.println("HTTP server started");
|
|
|
|
}
|
|
|
|
|
2018-03-11 01:05:17 +01:00
|
|
|
|
2018-02-20 17:59:06 +01:00
|
|
|
void handleSocket() {
|
|
|
|
String data = server.arg("plain");
|
2018-03-11 01:05:17 +01:00
|
|
|
String nameArg = server.uri().substring(1);
|
|
|
|
int socketIdx = findSocketIndex(nameArg);
|
2018-02-20 17:59:06 +01:00
|
|
|
String result;
|
|
|
|
|
2018-03-11 01:05:17 +01:00
|
|
|
Serial.println(nameArg);
|
2018-02-20 17:59:06 +01:00
|
|
|
|
|
|
|
if (data != "") {
|
|
|
|
Serial.println("change request");
|
|
|
|
StaticJsonBuffer<200> newBuffer;
|
|
|
|
JsonObject& json = newBuffer.parseObject(data);
|
|
|
|
|
|
|
|
if (json["active"] == "true") {
|
|
|
|
Serial.println("on");
|
2018-03-11 01:05:17 +01:00
|
|
|
result = setSocket(socketIdx, true);
|
2018-02-20 17:59:06 +01:00
|
|
|
} else if (json["active"] == "false") {
|
|
|
|
Serial.println("off");
|
2018-03-11 01:05:17 +01:00
|
|
|
result = setSocket(socketIdx, false);
|
2018-02-20 17:59:06 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Serial.println("status request");
|
2018-03-11 01:05:17 +01:00
|
|
|
result = generateStatusJson(socketIdx);
|
2018-02-20 17:59:06 +01:00
|
|
|
}
|
|
|
|
server.send(200, "text/json", result);
|
|
|
|
|
|
|
|
Serial.println("");
|
|
|
|
Serial.println("");
|
|
|
|
}
|
|
|
|
|
2018-03-11 01:05:17 +01:00
|
|
|
|
2018-02-20 17:59:06 +01:00
|
|
|
void handleMainpage() {
|
|
|
|
String mainpage = website(header, body);
|
|
|
|
server.send(200, "text/html", mainpage);
|
|
|
|
}
|
|
|
|
|
2018-03-11 01:05:17 +01:00
|
|
|
|
|
|
|
String setSocket(int socketIdx, bool newStatus) {
|
2018-02-20 17:59:06 +01:00
|
|
|
PowerSocket socket;
|
|
|
|
bool oldStatus = false;
|
|
|
|
bool success = false;
|
|
|
|
|
|
|
|
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++) {
|
2018-03-12 23:39:14 +01:00
|
|
|
if (socket.type == 0) {
|
|
|
|
Serial.println("id socket");
|
|
|
|
mySwitch.setProtocol(1);
|
|
|
|
mySwitch.switchOn(socket.channel, socket.id);
|
|
|
|
} else if (socket.type == 1) {
|
|
|
|
Serial.println("learning socket");
|
|
|
|
mySwitch.setProtocol(5);
|
|
|
|
mySwitch.send(socket.on_code, 24);
|
|
|
|
}
|
2018-02-20 17:59:06 +01:00
|
|
|
delay(250);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (char i = 0; i <= 1; i++) {
|
2018-03-12 23:39:14 +01:00
|
|
|
if (socket.type == 0) {
|
|
|
|
Serial.println("id socket");
|
|
|
|
mySwitch.setProtocol(1);
|
|
|
|
mySwitch.switchOff(socket.channel, socket.id);
|
|
|
|
} else if (socket.type == 1) {
|
|
|
|
Serial.println("learning socket");
|
|
|
|
char* off_code = socket.id;
|
|
|
|
mySwitch.setProtocol(5);
|
|
|
|
mySwitch.send(socket.off_code, 24);
|
|
|
|
}
|
2018-02-20 17:59:06 +01:00
|
|
|
delay(250);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return generateChangeJson(success, String(oldStatus), String(socket.powered));
|
|
|
|
}
|
|
|
|
|
2018-03-11 01:05:17 +01:00
|
|
|
|
|
|
|
int findSocketIndex(String name) {
|
2018-02-20 17:59:06 +01:00
|
|
|
for (int socketIdx = 0; socketIdx < numofsockets; socketIdx++) {
|
|
|
|
PowerSocket canidateSocket = sockets[socketIdx];
|
2018-03-11 01:05:17 +01:00
|
|
|
if (canidateSocket.name == name) {
|
2018-02-20 17:59:06 +01:00
|
|
|
return socketIdx;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2018-03-11 01:05:17 +01:00
|
|
|
|
2018-02-20 17:59:06 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2018-03-11 01:05:17 +01:00
|
|
|
|
|
|
|
String generateStatusJson(int socketIdx) {
|
|
|
|
PowerSocket socket = sockets[socketIdx];
|
2018-02-20 17:59:06 +01:00
|
|
|
String status = "{ \"status\" : " + String(socket.powered) + " }";
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
server.handleClient();
|
|
|
|
ArduinoOTA.handle();
|
|
|
|
}
|