- moved user specific data to env.h

- added new webinterface
- some cleanup
This commit is contained in:
Dorian Zedler 2019-03-16 20:21:00 +01:00
parent 6cf67334c5
commit e293617749
3 changed files with 103 additions and 60 deletions

1
Arduino/DasSchmalter/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
env.h

View file

@ -1,68 +1,65 @@
const byte led = D1;
const byte button = D5;
bool LEDstate = false;
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#define WIFI_MODE_CLIENT //can be WIFI_MODE_MASTER // !!IMPORTANT!!
// You need to rename the file 'env.h.example' to 'env.h' otherwise this line will throw an error !!
// All user specific variables (like wifi password and ssid) are configured in that file !!
// Replace with your network credentials #include "env.h"
char* ssid = "WIV"; //"DasSchmalter";
char* password = "DF~12qa.40"; //"12345678";
// helper vars
String header;
bool LEDstate = false;
volatile unsigned long oldTime = 0, debounceTime = 200;
// the HTML code for the whole ebinterface, can be called with http://<ip-adress>/
String webInterface = "<!DOCTYPE html>\n<html lang=\"de\">\n\n<head>\n\n<meta charset=\"utf-8\" />\n\n<title>Das Schmalter</title>\n\n<style>\n\t.test{\n\t\tmargin-left:auto;\n\t\tmargin-right:auto;\n\t}\n h1{\n text-align: center;\n }\n\t.switch {\t\n position: relative;\n display: inline-block;\n width: 120px;\n height: 68px;\n}\n\n.switch input {\n opacity: 0;\n width: 0;\n height: 0;\n}\n\n.slider {\n position: absolute;\n cursor: pointer;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: #ccc;\n -webkit-transition: .4s;\n transition: .4s;\n}\n\n.slider:before {\n position: absolute;\n content: \"\";\n height: 52px;\n width: 52px;\n left: 8px;\n bottom: 8px;\n background-color: white;\n -webkit-transition: .4s;\n transition: .4s;\n}\n\ninput:checked + .slider {\n background-color: #2196F3;\n}\n\ninput:focus + .slider {\n box-shadow: 0 0 1px #2196F3;\n}\n\ninput:checked + .slider:before {\n -webkit-transform: translateX(52px);\n -ms-transform: translateX(52px);\n transform: translateX(52px);\n}\n\n/* Rounded sliders */\n.slider.round {\n border-radius: 34px;\n}\n\n.slider.round:before {\n border-radius: 50%;\n}\n\t\n\tdiv{\n\ttext-align:center;\n\tcolor:red;\n\tfont-size: 150%;\n\tmargin-top: 40px;\n\t}\n\t\n</style>\n\n<script>\n\nvar currentState=\"\";\nvar ipAdress = window.location.host;\nfunction getState(){\n\tsendRequest(\"http://\"+ipAdress+\"/api/state\");\n}\n\nfunction requestFinished(){\n\tif(this.readyState === 4 && this.status === 200){\n\t\tif(this.responseText !== \"\"){\n\t\t\n\t\t\tresponseObj = JSON.parse(this.responseText);\n\t\t\t\n\t\t\tif(responseObj[\"command\"] == \"state\"){\n\t\t\t\t\n\t\t\t\tcurrentState = responseObj[\"response\"];\n\t\t\t\t\n\t\t\t\tif(currentState == 'OFF'){\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").classList.remove(\"disabled\");\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").checked = false;\n\t\t\t\n\t\t\t\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"\";\n\t\t\t\t}\n\t\t\t\n\t\t\t\telse if(currentState == 'ON'){\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").classList.remove(\"disabled\");\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").checked = true;\n\t\t\t\n\t\t\t\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"\";\n\t\t\t\t}\n\t\t\t\n\t\t\t\telse{\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").classList.add(\"disabled\");\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").innerHTML = \"ERROR\";\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"Unkwon error while connecting to Das Schmalter\";\n\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"\";\n\t\t\n\t\t}\n\t}\n\telse if(this.readyState == 4){\n\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"Error while connecting to Das Schmalter: \"+this.status\n\t}\n}\n\nfunction toggleLigth(){\n\tif(document.getElementById(\"toggleLightBt\").classList.contains(\"disabled\")){\n\t\treturn;\n\t}\n\tif(currentState == 'OFF'){\n\t\tsendRequest(\"http://\"+ipAdress+\"/api/on\")\n\t}\n\telse if(currentState == 'ON'){\n\t\tsendRequest(\"http://\"+ipAdress+\"/api/off\")\n\t}\n\telse{\n\t\talert(\"ERROR! \" + currentState);\n\t}\n\tgetState();\n}\nfunction sendRequest(link){\n xmlhttp = new XMLHttpRequest();\n xmlhttp.onreadystatechange = requestFinished;\n xmlhttp.open(\"GET\", link, true);\n xmlhttp.send();\n}\n\nsetInterval(function(){getState();},200)\n\n</script>\n\n</head>\n\n<body>\n\n<h1>Das Schmalter</h1>\n<div class=\"test\">\n<label class=\"switch\">\n <input type=\"checkbox\" onclick=\"toggleLigth()\" id=\"toggleLightBt\" class=\"test\">\n <span class=\"slider round\" class=\"test\"></span>\n</label>\n<div>\n\n<div id=\"errorDiv\"></div>\n\n</body>\n\n</html>";
// older version of the web interface, can be called with http://<ip-adress>/old
String oldWebInterface = "<!DOCTYPE html>\n<html lang=\"de\">\n\n<head>\n\n<meta charset=\"utf-8\" />\n\n<title>Das Schmalter</title>\n\n<style>\n\t\n h1{\n text-align: center;\n }\n\t\n button{\n\t\twidth: 40%;\n\t height: 100px;\n\t\tdisplay: block;\n\t\tmargin-left: auto;\n\t\tmargin-right: auto;\n\t\tbackground-color: white;\n\t\tcolor:black;\n\t\tborder: 4px solid #4CAF50;\n\t\tborder-radius: 100px;\n\t\ttransition-duration: 0.8s;\n\t\tfont-size: 200%;\n }\n button:hover{\n background-color:#4CAF50;\n color:white;\n }\n\t\n\t.disabled{\n\t\topacity: 0.6;\n\t\tcursor: not-allowed;\n\t}\n\t\n\tdiv{\n\ttext-align:center;\n\tcolor:red;\n\tfont-size: 200%;\n\tmargin-top: 40px;\n\t}\n\t\n</style>\n\n<script>\n\nvar currentState=\"\";\nvar ipAdress = window.location.host;\nfunction getState(){\n\tsendRequest(\"http://\"+ipAdress+\"/api/state\");\n}\n\nfunction requestFinished(){\n\tif(this.readyState === 4 && this.status === 200){\n\t\tif(this.responseText !== \"\"){\n\t\t\n\t\t\tresponseObj = JSON.parse(this.responseText);\n\t\t\t\n\t\t\tif(responseObj[\"command\"] == \"state\"){\n\t\t\t\t\n\t\t\t\tcurrentState = responseObj[\"response\"];\n\t\t\t\t\n\t\t\t\tif(currentState == 'OFF'){\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").classList.remove(\"disabled\");\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").innerHTML = \"Turn on\";\n\t\t\t\n\t\t\t\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"\";\n\t\t\t\t}\n\t\t\t\n\t\t\t\telse if(currentState == 'ON'){\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").classList.remove(\"disabled\");\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").innerHTML = \"Turn off\";\n\t\t\t\n\t\t\t\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"\";\n\t\t\t\t}\n\t\t\t\n\t\t\t\telse{\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").classList.add(\"disabled\");\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").innerHTML = \"ERROR\";\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"Unkwon error while connecting to Das Schmalter\";\n\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\n\t\t}\n\t}\n\telse if(this.readyState == 4){\n\t\tdocument.getElementById(\"toggleLightBt\").classList.add(\"disabled\");\n\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"Error while connecting to Das Schmalter: \"+this.status\n\t}\n}\n\nfunction toggleLigth(){\n\tif(document.getElementById(\"toggleLightBt\").classList.contains(\"disabled\")){\n\t\treturn;\n\t}\n\tif(currentState == 'OFF'){\n\t\tsendRequest(\"http://\"+ipAdress+\"/api/on\")\n\t}\n\telse if(currentState == 'ON'){\n\t\tsendRequest(\"http://\"+ipAdress+\"/api/off\")\n\t}\n\telse{\n\t\talert(\"ERROR! \" + currentState);\n\t}\n\tgetState();\n}\nfunction sendRequest(link){\n xmlhttp = new XMLHttpRequest();\n xmlhttp.onreadystatechange = requestFinished;\n xmlhttp.open(\"GET\", link, true);\n xmlhttp.send();\n}\n\nsetInterval(function(){getState();},200)\n\n</script>\n\n</head>\n\n<body>\n\n<h1>Das Schmalter</h1>\n\n<div style=\"height:50px\"></div>\n\n<a><button id=\"toggleLightBt\" class=\"disabled\" onclick=\"toggleLigth()\">Turn on</button></a>\n\n<div id=\"errorDiv\"></div>\n\n</body>\n\n</html>";
// Set web server port number to 80 // Set web server port number to 80
WiFiServer server(80); WiFiServer server(80);
String header;
// the code for the whole ebinterface
String webInterface = "<!DOCTYPE html>\n<html lang=\"de\">\n\n<head>\n\n<meta charset=\"utf-8\" />\n\n<title>Das Schmalter</title>\n\n<style>\n\t\n h1{\n text-align: center;\n }\n\t\n button{\n\t\twidth: 40%;\n\t height: 100px;\n\t\tdisplay: block;\n\t\tmargin-left: auto;\n\t\tmargin-right: auto;\n\t\tbackground-color: white;\n\t\tcolor:black;\n\t\tborder: 4px solid #4CAF50;\n\t\tborder-radius: 100px;\n\t\ttransition-duration: 0.8s;\n\t\tfont-size: 200%;\n }\n button:hover{\n background-color:#4CAF50;\n color:white;\n }\n\t\n\t.disabled{\n\t\topacity: 0.6;\n\t\tcursor: not-allowed;\n\t}\n\t\n\tdiv{\n\ttext-align:center;\n\tcolor:red;\n\tfont-size: 200%;\n\tmargin-top: 40px;\n\t}\n\t\n</style>\n\n<script>\n\nvar currentState=\"\";\nvar ipAdress = window.location.host;\nfunction getState(){\n\tsendRequest(\"http://\"+ipAdress+\"/api/state\");\n}\n\nfunction requestFinished(){\n\tif(this.readyState === 4 && this.status === 200){\n\t\tif(this.responseText !== \"\"){\n\t\t\n\t\t\tresponseObj = JSON.parse(this.responseText);\n\t\t\t\n\t\t\tif(responseObj[\"command\"] == \"state\"){\n\t\t\t\t\n\t\t\t\tcurrentState = responseObj[\"response\"];\n\t\t\t\t\n\t\t\t\tif(currentState == 'OFF'){\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").classList.remove(\"disabled\");\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").innerHTML = \"Turn on\";\n\t\t\t\n\t\t\t\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"\";\n\t\t\t\t}\n\t\t\t\n\t\t\t\telse if(currentState == 'ON'){\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").classList.remove(\"disabled\");\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").innerHTML = \"Turn off\";\n\t\t\t\n\t\t\t\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"\";\n\t\t\t\t}\n\t\t\t\n\t\t\t\telse{\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").classList.add(\"disabled\");\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"toggleLightBt\").innerHTML = \"ERROR\";\n\t\t\t\t\t\n\t\t\t\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"Unkwon error while connecting to Das Schmalter\";\n\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\n\t\t}\n\t}\n\telse if(this.readyState == 4){\n\t\tdocument.getElementById(\"toggleLightBt\").classList.add(\"disabled\");\n\t\tdocument.getElementById(\"errorDiv\").innerHTML = \"Error while connecting to Das Schmalter: \"+this.status\n\t}\n}\n\nfunction toggleLigth(){\n\tif(document.getElementById(\"toggleLightBt\").classList.contains(\"disabled\")){\n\t\treturn;\n\t}\n\tif(currentState == 'OFF'){\n\t\tsendRequest(\"http://\"+ipAdress+\"/api/on\")\n\t}\n\telse if(currentState == 'ON'){\n\t\tsendRequest(\"http://\"+ipAdress+\"/api/off\")\n\t}\n\telse{\n\t\talert(\"ERROR! \" + currentState);\n\t}\n\tgetState();\n}\nfunction sendRequest(link){\n xmlhttp = new XMLHttpRequest();\n xmlhttp.onreadystatechange = requestFinished;\n xmlhttp.open(\"GET\", link, true);\n xmlhttp.send();\n}\n\nsetInterval(function(){getState();},200)\n\n</script>\n\n</head>\n\n<body>\n\n<h1>Das Schmalter</h1>\n\n<div style=\"height:50px\"></div>\n\n<a><button id=\"toggleLightBt\" class=\"disabled\" onclick=\"toggleLigth()\">Turn on</button></a>\n\n<div id=\"errorDiv\"></div>\n\n</body>\n\n</html>";
// Configure the static ip adress void handleInterrupt() {
#ifdef WIFI_MODE_CLIENT // function to handle the external hardware switch
IPAddress local_IP(192, 168, 4, 10);
#endif
#ifdef WIFI_MODE_MASTER
IPAddress local_IP(192, 168, 4, 1);
#endif
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);
volatile unsigned long oldTime = 0, debounceTime = 200;
void toggleLED() {
if ((millis() - oldTime) > debounceTime) { if ((millis() - oldTime) > debounceTime) {
if (digitalRead(button) == LOW) { if (digitalRead(button) == LOW) {
LEDstate = ! LEDstate; LEDstate = ! LEDstate;
digitalWrite(led, LEDstate); digitalWrite(led, LEDstate);
} }
} }
oldTime = millis(); oldTime = millis();
} }
void setup() { void setup() {
// put your setup code here, to run once: // configure all pins
pinMode(led, OUTPUT); pinMode(led, OUTPUT);
pinMode(button, INPUT_PULLUP); pinMode(button, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(button), toggleLED, FALLING);
// attach an interrupt for the hardware switch
attachInterrupt(digitalPinToInterrupt(button), handleInterrupt, FALLING);
// start the serial monitor
Serial.begin(9600); Serial.begin(9600);
/*if (!WiFi.config(local_IP, gateway, subnet)) {
//Serial.println("STA Failed to configure");
} */
#ifdef WIFI_MODE_MASTER #ifdef WIFI_MODE_MASTER
//Serial.print("Configuring access point..."); // wifi mode master -> configure an access point
//WiFi.softAPConfig(local_IP, gateway, subnet); Serial.print("Configuring access point...");
WiFi.softAP(ssid, password); WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP(); IPAddress myIP = WiFi.softAPIP();
//Serial.print("AP IP address: "); Serial.print("AP IP address: ");
//Serial.println(myIP); Serial.println(myIP);
#endif #endif
#ifdef WIFI_MODE_CLIENT #ifdef WIFI_MODE_CLIENT
// wifi mode client -> connect to given wifi network
WiFi.begin(ssid, password); WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi.."); Serial.print("Connecting to WiFi..");
while (WiFi.status() != WL_CONNECTED) { while (WiFi.status() != WL_CONNECTED) {
delay(1000); delay(1000);
Serial.print("."); Serial.print(".");
@ -73,79 +70,99 @@ void setup() {
Serial.println(WiFi.localIP()); Serial.println(WiFi.localIP());
#endif #endif
// start the web server
server.begin(); server.begin();
} }
void loop() { void loop() {
// put your main code here, to run repeatedly: // check if a client has sent a request
WiFiClient client = server.available(); // Listen for incoming clients WiFiClient client = server.available();
if (client) { // If a new client connects, if (client) {
//Serial.println("New Client."); // print a message out in the serial port // if a client has connected
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected // string to hold incoming data from the client
if (client.available()) { // if there's bytes to read from the client, String currentLine = "";
char c = client.read(); // read a byte, then while (client.connected()) {
//Serial.write(c); // print it out the serial monitor // while the client is connected we're in this loop
if (client.available()) {
// if the client has sent some data
// read id
char c = client.read();
header += c; header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row. if (c == '\n') {
// that's the end of the client HTTP request, so send a response: // if the data was a new line char
if (currentLine.length() == 0) { if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // if the current line is empty -> client request (HTTP header) is over
// and a content-type so the client knows what's coming, then a blank line: // => send response to client
// send HTTP header
client.println("HTTP/1.1 200 OK"); client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html"); client.println("Content-type:text/html");
client.println("Access-Control-Allow-Origin: *"); client.println("Access-Control-Allow-Origin: *");
client.println("Connection: close"); client.println("Connection: close");
client.println(); client.println();
// turns the GPIOs on and off // check what the client wants ...
if (header.indexOf("GET /api/on") >= 0) { if (header.indexOf("GET /api/on") >= 0) {
//Serial.println("LAMP on"); // ... turn the lamp on
LEDstate = true; LEDstate = true;
digitalWrite(led, HIGH); digitalWrite(led, HIGH);
client.println("{\"command\":\"on\",\"response\":\"OK\"}"); client.println("{\"command\":\"on\",\"response\":\"OK\"}");
} else if (header.indexOf("GET /api/off") >= 0) { } else if (header.indexOf("GET /api/off") >= 0) {
//Serial.println("LAMP off"); // ... turn the lamp off
LEDstate = false; LEDstate = false;
digitalWrite(led, LOW); digitalWrite(led, LOW);
client.println("{\"command\":\"off\",\"response\":\"OK\"}"); client.println("{\"command\":\"off\",\"response\":\"OK\"}");
} else if (header.indexOf("GET /api/state") >= 0) { } else if (header.indexOf("GET /api/state") >= 0) {
// ... get the state of the lamp
if(LEDstate) { if(LEDstate) {
client.println("{\"command\":\"state\",\"response\":\"ON\"}"); client.println("{\"command\":\"state\",\"response\":\"ON\"}");
} }
else { else {
client.println("{\"command\":\"state\",\"response\":\"OFF\"}"); client.println("{\"command\":\"state\",\"response\":\"OFF\"}");
} }
//Serial.println("LAMP status");
} else if (header.indexOf("GET /old") >= 0) {
// ... get the old HTML web page
client.println(oldWebInterface);
} }
else { else {
// Display the HTML web page // ... get the HTML web page
client.println(webInterface); client.println(webInterface);
} }
// The HTTP response ends with another blank line // The HTTP response ends with another blank line
client.println(); client.println();
// Break out of the while loop // Break out of the while loop
break; break;
} else { // if you got a newline, then clear currentLine
}
else {
// if we got a newline -> clear currentLine
currentLine = ""; currentLine = "";
} }
} else if (c != '\r') { // if you got anything else but a carriage return character, } else if (c != '\r') {
currentLine += c; // add it to the end of the currentLine // if the data was anything but a carriage return character -> add it to the end of the currentLine
currentLine += c;
} }
} }
} }
// Clear the header variable // Clear the header variable
header = ""; header = "";
// Close the connection // Close the connection
client.stop(); client.stop();
//Serial.println("Client disconnected.");
//Serial.println("");
} }
} }

View file

@ -0,0 +1,25 @@
// -------------------------------
// --- DasSchmalter enviroment ---
// -------------------------------
// all user specific variables are defined here
#ifndef ENV_H
#define ENV_H
// --- wifi
//can be set to WIFI_MODE_MASTER so that the schmalter will emit its own wifi network
#define WIFI_MODE_CLIENT
// wifi ssid
char* ssid = "<your SSID>";
// wifi password
char* password = "<your password>";
// --- other
const byte led = D1;
const byte button = D5;
#endif // ENV_H