Splitted large code into multiple modules

This commit is contained in:
0xFEEDC0DE
2018-05-02 20:42:52 +02:00
parent 6ad22dedfd
commit a524b8862d
11 changed files with 427 additions and 274 deletions

View File

@@ -0,0 +1,42 @@
#include "controlclient.h"
#include "relais.h"
ControlClient::ControlClient(const char* host, const int port, const char* name, Relais &relais) :
m_host(host),
m_port(port),
m_name(name),
m_relais(relais)
{
}
void ControlClient::begin()
{
}
void ControlClient::handleClient()
{
if(!m_client.connected()) {
if (m_client.connect(m_host, m_port)) {
m_client.println(m_name);
sendStatus();
}
}
if(m_client.connected()) {
while(m_client.available()) {
switch(m_client.read()) {
case '1': m_relais.on(); break;
case '0': m_relais.off(); break;
case 't': m_relais.toggle(); break;
case 's': sendStatus(); break;
case 'r': m_client.println("rebooting"); ESP.restart(); break;
}
}
}
}
void ControlClient::sendStatus()
{
m_client.println(m_relais.status() ? "on" : "off");
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include <WiFiClient.h>
class Relais;
class ControlClient {
public:
explicit ControlClient(const char *host, const int port, const char *name, Relais &relais);
void begin();
void handleClient();
void sendStatus();
private:
WiFiClient m_client;
const char *m_host;
const int m_port;
const char *m_name;
Relais &m_relais;
};

View File

@@ -0,0 +1,97 @@
#include "controlwebserver.h"
#include "relais.h"
const char* ControlWebserver::m_content =
"<!doctype html>"
"<html lang=\"de-AT\">"
"<head>"
"<meta charset=\"utf-8\" />"
"<meta http-equiv=\"x-ua-compatible\" content=\"ie=edge\" />"
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />"
"<title>Relais Control</title>"
"<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css\" integrity=\"sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm\" crossorigin=\"anonymous\" />"
"<style>.hidden { display: none; }</style>"
"</head>"
"<body>"
"<!--[if lte IE 9]>"
"<p class=\"browserupgrade\">You are using an <strong>outdated</strong> browser. Please <a href=\"https://browsehappy.com/\">upgrade your browser</a> to improve your experience and security.</p>"
"<![endif]-->"
"<div class=\"container\">"
"<h1>Relais Control</h1>"
"<switch onUrl=\"on0\" offUrl=\"off0\" statusUrl=\"status0\" />"
"<switch onUrl=\"on1\" offUrl=\"off1\" statusUrl=\"status1\" />"
"</div>"
"<script src=\"https://code.jquery.com/jquery-3.3.1.min.js\" integrity=\"sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT\" crossorigin=\"anonymous\"></script>"
"<script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js\" integrity=\"sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl\" crossorigin=\"anonymous\"></script>"
"<script src=\"https://brunner.ninja/relais.js\"></script>"
"</body>"
"</html>";
ControlWebserver::ControlWebserver(IPAddress addr, int port) :
UpdateWebserver(addr, port)
{
init();
}
ControlWebserver::ControlWebserver(int port) :
UpdateWebserver(port)
{
init();
}
ControlWebserver::~ControlWebserver()
{
}
void ControlWebserver::addRelais0(Relais &relais)
{
addRelais("/on0", "/off0", "/toggle0", "/status0", relais);
}
void ControlWebserver::addRelais1(Relais &relais)
{
addRelais("/on1", "/off1", "/toggle1", "/status1", relais);
}
void ControlWebserver::addRelais(const char *onUrl, const char *offUrl, const char *toggleUrl, const char *statusUrl, Relais &relais)
{
on(onUrl, HTTP_GET, [this, &relais]() {
relais.on();
sendHeader("Connection", "close");
send(200, "text/plain", "success");
});
on(offUrl, HTTP_GET, [this, &relais]() {
relais.off();
sendHeader("Connection", "close");
send(200, "text/plain", "success");
});
on(toggleUrl, HTTP_GET, [this, &relais]() {
relais.toggle();
sendHeader("Connection", "close");
send(200, "text/plain", "success");
});
on(statusUrl, HTTP_GET, [this, &relais]() {
sendHeader("Connection", "close");
send(200, "text/plain", relais.status() ? "on" : "off");
});
}
void ControlWebserver::init()
{
on("/", HTTP_GET, [this]() {
sendHeader("Connection", "close");
send(200, "text/html", m_content);
});
}

View File

@@ -0,0 +1,22 @@
#pragma once
#include "updatewebserver.h"
class Relais;
class ControlWebserver : public UpdateWebserver
{
static const char* m_content;
public:
explicit ControlWebserver(IPAddress addr, int port = 80);
explicit ControlWebserver(int port = 80);
virtual ~ControlWebserver();
void addRelais0(Relais &relais);
void addRelais1(Relais &relais);
void addRelais(const char *onUrl, const char *offUrl, const char *toggleUrl, const char *statusUrl, Relais &relais);
private:
void init();
};

View File

@@ -1,289 +1,46 @@
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <WiFiClient.h> #include <WiFiClient.h>
#include <ESP8266WebServer.h>
const char* ssid = "McDonalds Free WiFi 2.4GHz"; #include "relais.h"
const char* password = "Passwort_123"; #include "controlclient.h"
const char* host = "192.168.0.2"; #include "switchwatcher.h"
#include "controlwebserver.h"
const char* success = "success"; Relais relais0(D1);
Relais relais1(D2);
const char* indexContent = "<!doctype html>" ControlClient controlClient0("192.168.0.2", 1234, "vorzimmer_decke", relais0);
"<html lang=\"de-AT\">" ControlClient controlClient1("192.168.0.2", 1234, "wohnzimmer_decke", relais1);
"<head>" SwitchWatcher watcher0(D5, relais0);
"<meta charset=\"utf-8\" />" SwitchWatcher watcher1(D6, relais1);
"<meta http-equiv=\"x-ua-compatible\" content=\"ie=edge\" />" ControlWebserver webserver;
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />"
"<title>Relais Control</title>"
"<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css\" integrity=\"sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm\" crossorigin=\"anonymous\" />"
"<style>.hidden { display: none; }</style>"
"</head>"
"<body>"
"<!--[if lte IE 9]>"
"<p class=\"browserupgrade\">You are using an <strong>outdated</strong> browser. Please <a href=\"https://browsehappy.com/\">upgrade your browser</a> to improve your experience and security.</p>"
"<![endif]-->"
"<div class=\"container\">"
"<h1>Relais Control</h1>"
"<switch onUrl=\"on0\" offUrl=\"off0\" statusUrl=\"status0\" />"
"<switch onUrl=\"on1\" offUrl=\"off1\" statusUrl=\"status1\" />"
"</div>"
"<script src=\"https://code.jquery.com/jquery-3.3.1.min.js\" integrity=\"sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT\" crossorigin=\"anonymous\"></script>"
"<script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js\" integrity=\"sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl\" crossorigin=\"anonymous\"></script>"
"<script src=\"https://brunner.ninja/relais.js\"></script>"
"</body>"
"</html>";
const char* updateContent = "<!doctype html>"
"<html lang=\"de-AT\">"
"<head>"
"<meta charset=\"utf-8\" />"
"<meta http-equiv=\"x-ua-compatible\" content=\"ie=edge\" />"
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />"
"<title>Update</title>"
"<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css\" integrity=\"sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm\" crossorigin=\"anonymous\" />"
"<style>.hidden { display: none; }</style>"
"</head>"
"<body>"
"<!--[if lte IE 9]>"
"<p class=\"browserupgrade\">You are using an <strong>outdated</strong> browser. Please <a href=\"https://browsehappy.com/\">upgrade your browser</a> to improve your experience and security.</p>"
"<![endif]-->"
"<div class=\"container\">"
"<h1>Update</h1>"
"<form method=\"POST\" action=\"/update\" enctype=\"multipart/form-data\">"
"<input type=\"file\" name=\"update\" />"
"<button type=\"submit\">Install</button>"
"</form>"
"</div>"
"<script src=\"https://code.jquery.com/jquery-3.3.1.min.js\" integrity=\"sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT\" crossorigin=\"anonymous\"></script>"
"<script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js\" integrity=\"sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl\" crossorigin=\"anonymous\"></script>"
"</body>"
"</html>";
class ControlClient {
public:
explicit ControlClient(const char *name, const int pin) :
m_name(name),
m_pin(pin)
{
}
void begin() {
Serial.println(m_pin);
Serial.println("begin()");
pinMode(m_pin, OUTPUT);
digitalWrite(m_pin, HIGH);
}
void handleClient() {
if(!m_client.connected()) {
Serial.println("Connecting to server...");
if (m_client.connect(host, 1234)) {
Serial.println("Connected to server!");
m_client.println(m_name);
sendStatus();
} else {
Serial.println("Could not connect to server!");
}
}
if(m_client.connected()) {
while(m_client.available()) {
char c(m_client.read());
Serial.println(c);
switch(c) {
case '1': on(); break;
case '0': off(); break;
case 't': toggle(); break;
case 's': sendStatus(); break;
case 'r': m_client.println("rebooting"); ESP.restart(); break;
default: Serial.print("Unknown command: "); Serial.println(c);
}
}
}
}
void on() {
Serial.println("on()");
digitalWrite(m_pin, HIGH);
sendStatus();
}
void off() {
Serial.println("off()");
digitalWrite(m_pin, LOW);
sendStatus();
}
void toggle() {
Serial.println("toggle()");
if(status()) {
off();
} else {
on();
}
}
bool status() {
return digitalRead(m_pin) == HIGH;
}
void sendStatus() {
Serial.println("sendStatus()");
m_client.println(status() ? "on" : "off");
}
private:
WiFiClient m_client;
const char *m_name;
const int m_pin;
};
ESP8266WebServer server(80);
ControlClient relais0Client("vorzimmer_decke", D1);
ControlClient relais1Client("wohnzimmer_decke", D2);
bool lastState0, lastState1;
void setup() { void setup() {
Serial.begin(115200); WiFi.begin("McDonalds Free WiFi 2.4GHz", "Passwort_123");
Serial.println();
WiFi.begin(ssid, password); relais0.begin();
relais1.begin();
relais0Client.begin(); controlClient0.begin();
relais1Client.begin(); controlClient1.begin();
pinMode(D5, INPUT_PULLUP); watcher0.begin();
pinMode(D6, INPUT_PULLUP); watcher1.begin();
lastState0 = digitalRead(D5) == HIGH; webserver.addRelais0(relais0);
lastState1 = digitalRead(D6) == HIGH; webserver.addRelais1(relais1);
server.on("/", HTTP_GET, []() { webserver.begin();
server.sendHeader("Connection", "close");
server.send(200, "text/html", indexContent);
});
server.on("/update", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/html", updateContent);
});
server.on("/on0", HTTP_GET, []() {
relais0Client.on();
server.sendHeader("Connection", "close");
server.send(200, "text/plain", success);
});
server.on("/off0", HTTP_GET, []() {
relais0Client.off();
server.sendHeader("Connection", "close");
server.send(200, "text/plain", success);
});
server.on("/on1", HTTP_GET, []() {
relais1Client.on();
server.sendHeader("Connection", "close");
server.send(200, "text/plain", success);
});
server.on("/off1", HTTP_GET, []() {
relais1Client.off();
server.sendHeader("Connection", "close");
server.send(200, "text/plain", success);
});
server.on("/toggle0", HTTP_GET, []() {
relais0Client.toggle();
server.sendHeader("Connection", "close");
server.send(200, "text/plain", success);
});
server.on("/toggle1", HTTP_GET, []() {
relais1Client.toggle();
server.sendHeader("Connection", "close");
server.send(200, "text/plain", success);
});
server.on("/status0", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", relais0Client.status() ? "on" : "off");
});
server.on("/status1", HTTP_GET, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", relais1Client.status() ? "on" : "off");
});
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
Serial.setDebugOutput(true);
Serial.printf("Update: %s\n", upload.filename.c_str());
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if (!Update.begin(maxSketchSpace)) { //start with max available size
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
Update.printError(Serial);
}
Serial.setDebugOutput(false);
}
yield();
});
server.begin();
} }
void loop() { void loop() {
if(WiFi.status() == WL_CONNECTED) { if(WiFi.status() == WL_CONNECTED) {
relais0Client.handleClient(); controlClient0.handleClient();
relais1Client.handleClient(); controlClient1.handleClient();
server.handleClient(); webserver.handleClient();
} else {
Serial.println("No wifi");
delay(500);
} }
if(digitalRead(D5) != (lastState0 ? HIGH : LOW)) { watcher0.handle();
lastState0 = !lastState0; watcher1.handle();
relais0Client.toggle();
}
if(digitalRead(D6) != (lastState1 ? HIGH : LOW)) {
lastState1 = !lastState1;
relais1Client.toggle();
}
delay(1); delay(1);
} }

34
multi_lamp/relais.cpp Normal file
View File

@@ -0,0 +1,34 @@
#include "relais.h"
#include <Arduino.h>
Relais::Relais(const int pin) :
m_pin(pin)
{
}
void Relais::begin()
{
pinMode(m_pin, OUTPUT);
on();
}
void Relais::on()
{
digitalWrite(m_pin, HIGH);
}
void Relais::off()
{
digitalWrite(m_pin, LOW);
}
void Relais::toggle()
{
digitalWrite(m_pin, status() ? LOW : HIGH);
}
bool Relais::status() const
{
return digitalRead(m_pin) == HIGH;
}

17
multi_lamp/relais.h Normal file
View File

@@ -0,0 +1,17 @@
#pragma once
class Relais
{
public:
explicit Relais(const int pin);
void begin();
void on();
void off();
void toggle();
bool status() const;
private:
const int m_pin;
};

View File

@@ -0,0 +1,38 @@
#include "switchwatcher.h"
#include <Arduino.h>
#include "relais.h"
SwitchWatcher::SwitchWatcher(const int pin, Relais &relais) :
m_pin(pin),
m_relais(relais)
{
}
void SwitchWatcher::begin()
{
pinMode(m_pin, INPUT_PULLUP);
m_lastState = status();
m_countdown = 0;
}
void SwitchWatcher::handle()
{
if(status() != m_lastState)
{
if(++m_countdown >= 10)
{
m_relais.toggle();
m_lastState = !m_lastState;
m_countdown = 0;
}
}
else
m_countdown = 0;
}
bool SwitchWatcher::status() const
{
return digitalRead(m_pin) == HIGH;
}

View File

@@ -0,0 +1,21 @@
#pragma once
class Relais;
class SwitchWatcher
{
public:
explicit SwitchWatcher(const int pin, Relais &relais);
void begin();
void handle();
bool status() const;
private:
const int m_pin;
Relais &m_relais;
bool m_lastState;
int m_countdown;
};

View File

@@ -0,0 +1,87 @@
#include "updatewebserver.h"
const char* UpdateWebserver::m_content =
"<!doctype html>"
"<html lang=\"de-AT\">"
"<head>"
"<meta charset=\"utf-8\" />"
"<meta http-equiv=\"x-ua-compatible\" content=\"ie=edge\" />"
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />"
"<title>Update</title>"
"<link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css\" integrity=\"sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm\" crossorigin=\"anonymous\" />"
"<style>.hidden { display: none; }</style>"
"</head>"
"<body>"
"<!--[if lte IE 9]>"
"<p class=\"browserupgrade\">You are using an <strong>outdated</strong> browser. Please <a href=\"https://browsehappy.com/\">upgrade your browser</a> to improve your experience and security.</p>"
"<![endif]-->"
"<div class=\"container\">"
"<h1>Update</h1>"
"<form method=\"POST\" action=\"/update\" enctype=\"multipart/form-data\">"
"<input type=\"file\" name=\"update\" />"
"<button type=\"submit\">Install</button>"
"</form>"
"</div>"
"<script src=\"https://code.jquery.com/jquery-3.3.1.min.js\" integrity=\"sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT\" crossorigin=\"anonymous\"></script>"
"<script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js\" integrity=\"sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl\" crossorigin=\"anonymous\"></script>"
"</body>"
"</html>";
UpdateWebserver::UpdateWebserver(IPAddress addr, int port) :
ESP8266WebServer(addr, port)
{
init();
}
UpdateWebserver::UpdateWebserver(int port) :
ESP8266WebServer(port)
{
init();
}
UpdateWebserver::~UpdateWebserver()
{
}
void UpdateWebserver::init()
{
on("/update", HTTP_GET, [this]() {
sendHeader("Connection", "close");
send(200, "text/html", m_content);
});
on("/update", HTTP_POST, [this]() {
sendHeader("Connection", "close");
send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
}, [this]() {
HTTPUpload& upload = this->upload();
if (upload.status == UPLOAD_FILE_START) {
//Serial.setDebugOutput(true);
//Serial.printf("Update: %s\n", upload.filename.c_str());
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if (!Update.begin(maxSketchSpace)) { //start with max available size
//Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
//Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
//Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
//Update.printError(Serial);
}
//Serial.setDebugOutput(false);
}
yield();
});
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <ESP8266WebServer.h>
class UpdateWebserver : public ESP8266WebServer
{
static const char* m_content;
public:
explicit UpdateWebserver(IPAddress addr, int port = 80);
explicit UpdateWebserver(int port = 80);
virtual ~UpdateWebserver();
private:
void init();
};