Update WebServerData class; move EthernetClient inside WebServer class; modify WebServer init, getWebServerData, and SendToBrowser methods; update DebugLog init method; modify HTMLGenerator methods to use DebugLog; update platformio

This commit is contained in:
Ondrej-Trochta
2024-05-01 16:29:23 +02:00
parent c32905663b
commit 481aaf9ad3
16 changed files with 249 additions and 109 deletions
+7
View File
@@ -15,7 +15,10 @@ void GSMMobileData::readAllData(String id)
EEPROMUtils eepromUtils = EEPROMUtils();
MobileNumber = eepromUtils.readString(1, 20);
Sms = eepromUtils.readString(21, 100);
#ifdef DEBUG
DebugLog::log("Load from EEPROM. Mobile Number: " + MobileNumber + " SMS: " + Sms);
#endif
}
void GSMMobileData::updateMobileNumber(const String &newMobileNumber)
@@ -30,7 +33,9 @@ void GSMMobileData::updateMobileNumber(const String &newMobileNumber)
EEPROMUtils eepromUtils = EEPROMUtils();
MobileNumber = newMobileNumber;
eepromUtils.writeString(1, newMobileNumber, 20);
#ifdef DEBUG
DebugLog::log("Update Mobile Number: " + newMobileNumber);
#endif
}
}
@@ -45,6 +50,8 @@ void GSMMobileData::updateSMS(const String &newSMS)
EEPROMUtils eepromUtils = EEPROMUtils();
Sms = newSMS;
eepromUtils.writeString(21, newSMS, 100);
#ifdef DEBUG
DebugLog::log("Update sms: " + newSMS);
#endif
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
#include "PinTypeIn.h"
bool PinTypeIn::IsPinHigh()
const bool PinTypeIn::IsPinHigh()
{
return digitalRead(_pin) == HIGH ? true : false;
}
+1 -1
View File
@@ -24,7 +24,7 @@ public:
/// @brief Get Actual Pin Value if is SET = True, if is NOT SET = False
/// @return
bool IsPinHigh();
const bool IsPinHigh();
};
+3 -3
View File
@@ -6,16 +6,16 @@
void PinTypeOut::setOutputSignalToHigh()
{
digitalWrite(_pinNumber, HIGH);
lastState = true;
}
void PinTypeOut::setOutputSignalToLow()
{
digitalWrite(_pinNumber, LOW);
lastState = false;
}
bool PinTypeOut::IsPinOn()
{
return lastState;
return digitalRead(_pinNumber) == HIGH;
}
+3 -3
View File
@@ -8,7 +8,7 @@ class PinTypeOut : public DeviceBase
{
private:
uint8_t _pinNumber;
bool lastState;
unsigned long _debounceTime;
unsigned long lastStateChangeTime;
@@ -17,13 +17,13 @@ public:
const char *description;
PinTypeOut(String id, uint8_t pinNumber, unsigned long debounceTime, const char *description)
: DeviceBase(id), _pinNumber(pinNumber), lastState(false), _debounceTime(debounceTime), lastStateChangeTime(0), description(description)
: DeviceBase(id), _pinNumber(pinNumber), _debounceTime(debounceTime), lastStateChangeTime(0), description(description)
{
pinMode(pinNumber, OUTPUT);
}
PinTypeOut(String id, uint8_t pinNumber, const char *description)
: DeviceBase(id), _pinNumber(pinNumber), lastState(false), _debounceTime(0), lastStateChangeTime(0), description(description)
: DeviceBase(id), _pinNumber(pinNumber),_debounceTime(0), lastStateChangeTime(0), description(description)
{
pinMode(pinNumber, OUTPUT);
}
+1 -1
View File
@@ -1,4 +1,4 @@
#include "WebServerData.h"
#include <WebServerData.h>
#include <Ethernet.h>
#include <Arduino.h>
+3 -3
View File
@@ -7,16 +7,16 @@
class WebServerData
{
public:
EthernetClient Client;
String Request;
bool IsEmpty;
WebServerData(EthernetClient client) : Client(client), IsEmpty(true){};
WebServerData(EthernetClient client, String request) : Client(client), Request(request), IsEmpty(false){};
WebServerData() : IsEmpty(true){};
WebServerData(String request) : Request(request), IsEmpty(false){};
String getValue(const String &data, const String &key, char endchar);
String getValue(const String &data, const String &key);
String removeAllCharactersAfterEmptySpace(String &data);
String getVariableName(const String &data, const String &key);
};
#endif // WebServerData_H
+20 -12
View File
@@ -6,12 +6,17 @@
void GSMMobileDevice::end()
{
_gsmSerial.end();
#ifdef DEBUG
DebugLog::log("GSM End ..");
#endif
}
void GSMMobileDevice::executeAtCommand(const String &atCommand)
{
#ifdef DEBUG
DebugLog::log(atCommand);
#endif
_gsmSerial.print(atCommand + "\r");
delay(500);
}
@@ -23,18 +28,19 @@ String GSMMobileDevice::readStringSerialPort()
void GSMMobileDevice::sendSMSToGSM(GSMMobileData gsmData)
{
#ifdef DEBUG
DebugLog::log("SMS Start SEND SMS Id:" + gsmData.Id + " M:" + gsmData.MobileNumber + " with message " + gsmData.Sms);
#endif
/*executeAtCommand("AT+CMGF=1");
executeAtCommand("AT + CMGS =\"" + gsmData.MobileNumber + "\"");
executeAtCommand("ID:" + gsmData.Id + " Msg:" + gsmData.Sms);
/*executeAtCommand("AT+CMGF=1");
executeAtCommand("AT + CMGS =\"" + gsmData.MobileNumber + "\"");
executeAtCommand("ID:" + gsmData.Id + " Msg:" + gsmData.Sms);
delay(1000);
// Send a Ctrl+Z / ASCII SUB
_gsmSerial.print((char)26);
delay(500);
// Close the connection
_gsmSerial.print((char)27);*/
delay(1000);
// Send a Ctrl+Z / ASCII SUB
_gsmSerial.print((char)26);
delay(500);
// Close the connection
_gsmSerial.print((char)27);*/
delay(500);
}
@@ -52,13 +58,15 @@ bool GSMMobileDevice::checkSMSError()
return false;
}
GSMMobileDevice::GSMMobileDevice(uint8_t pinRx, uint8_t pinTx, long baudRate): _gsmSerial(pinRx, pinTx)
GSMMobileDevice::GSMMobileDevice(uint8_t pinRx, uint8_t pinTx, long baudRate) : _gsmSerial(pinRx, pinTx)
{
_baudRate = baudRate;
// init software serial
_gsmSerial.begin(baudRate);
#ifdef DEBUG
DebugLog::log("GSM Init ..");
//delay(5000); // initialization GSM module (give it some time to boot up)
#endif
// delay(5000); // initialization GSM module (give it some time to boot up)
}
void GSMMobileDevice::sendSMS(GSMMobileData gsmData)
+88 -18
View File
@@ -1,10 +1,10 @@
#include <Arduino.h>
#include <Ethernet.h>
#include "WebServerData.h"
#include "WebServer.h"
#include "WebServerData.h"
#include "DebugLog.h"
// Constructor
// Constructor
WebServer::WebServer() : _server(80) {}
WebServer::WebServer(byte mac[6], IPAddress ip, uint16_t port) : _ip(ip), _server(port)
@@ -15,46 +15,83 @@ WebServer::WebServer(byte mac[6], IPAddress ip, uint16_t port) : _ip(ip), _serve
// Initialize the Ethernet and start the server
void WebServer::init()
{
DebugLog::log("Starting WebServer mac: " + String(_mac[0]) + String(_mac[1]) + ", IP: " + _ip);
Ethernet.begin(_mac, _ip);
#ifdef DEBUG
DebugLog::log("Ethernet IP: " + Ethernet.localIP());
#endif
_server.begin();
#ifdef DEBUG
DebugLog::log("Server Start");
#endif
}
// Move the declaration of EthernetClient inside the WebServer class
EthernetClient client;
// Handle client requests
WebServerData WebServer::getWebServerData()
{
// Check if a client has connected
client = _server.available();
if (client)
{
if (client.connected())
{
//DebugLog::log("Client connected");
if (client.available())
#ifdef DEBUG
DebugLog::log("Client connected");
#endif
unsigned long startTime = millis();
while (client.available() == 0)
{
String request = client.readStringUntil('\r');
// client.flush(); // Clear the incoming buffer after reading the GET request
// If you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (request.startsWith("GET"))
if (millis() - startTime >= 10000)
{
DebugLog::log("GET WEB SERVER DATA: " + request);
WebServerData webServerData = WebServerData(client, request);
return webServerData;
break;
}
delay(10);
}
client.println(F("HTTP/1.1 200 OK")); // Respond together with the Web page in the HTML
client.println(F("Content-Type: text/html"));
client.println(F("Connection: close"));
client.println();
String request = client.readStringUntil('\r');
if (request.startsWith("GET / HTTP/1.1"))
{
#ifdef DEBUG
DebugLog::log("EMPTY DATA: " + request);
#endif
return WebServerData();
}
// client.flush(); // Clear the incoming buffer after reading the GET request
// If you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (request.startsWith("GET /"))
{
#ifdef DEBUG
DebugLog::log("GET WEB SERVER DATA: " + request);
#endif
WebServerData webServerData = WebServerData(request);
return webServerData;
}
}
// Give the web browser time to receive the data
}
return WebServerData(client); // Return a default-constructed WebServerData object if no client is available
return WebServerData();
// Give the web browser time to receive the data
}
// Return a default-constructed WebServerData object if no client is available
void WebServer::endServer()
{
if (_server.available())
@@ -64,3 +101,36 @@ void WebServer::endServer()
client.stop();
}
}
void WebServer::SendToBrowser(const String &dataString)
{
const byte chunkSize = 50;
// Send data in chunks
unsigned int stringIndex = 0;
unsigned long startTime = millis();
while (stringIndex < dataString.length())
{
if (client.availableForWrite() > 0)
{
int chunkLength = min(chunkSize, dataString.length() - stringIndex);
const String chunk = dataString.substring(stringIndex, stringIndex + chunkLength);
// Send the chunk (consider error handling)
#ifdef DEBUG
DebugLog::log("StBC: " + chunk);
#endif
client.print(chunk);
stringIndex += chunkLength;
delay(5); // Optional delay between chunks
}
else if (millis() - startTime >= 10000)
{
return; // Timeout
}
delay(5); // Optional delay between chunks
}
client.println("");
}
+3 -2
View File
@@ -1,9 +1,9 @@
#ifndef WebServer_H
#define WebServer_H
#include <WebServerData.h>
#include <Arduino.h>
#include <Ethernet.h>
#include "WebServerData.h"
class WebServer
{
@@ -12,7 +12,7 @@ private:
IPAddress _ip;
EthernetServer _server;
public:
public:
EthernetClient client;
WebServer();
@@ -20,6 +20,7 @@ public:
WebServerData getWebServerData();
void init();
void endServer();
void SendToBrowser(const String &dataString);
};
#endif // WebServer_H
+20 -1
View File
@@ -1,12 +1,31 @@
#include <Arduino.h>
#include "DebugLog.h"
void DebugLog::log(const String &log)
{
Serial.println(log);
WriteToSerial(log);
}
void DebugLog::init(const long &bound)
{
Serial.begin(bound);
Serial.println("Serial Port Initialized");
}
void DebugLog::WriteToSerial(const String &dataString)
{
const byte chunkSize = 60;
unsigned int stringIndex = 0;
while (stringIndex < dataString.length())
{
int chunkLength = min(chunkSize, dataString.length() - stringIndex);
String chunk = dataString.substring(stringIndex, stringIndex + chunkLength);
Serial.print(chunk);
stringIndex += chunkLength;
delay(4); // Optional delay between chunks
}
Serial.println("");
}
+5
View File
@@ -3,11 +3,16 @@
#include <Arduino.h>
class DebugLog
{
private:
static void WriteToSerial(const String &dataString);
public:
static void init(const long &bound);
static void log(const String &log);
};
#endif
+13 -14
View File
@@ -1,22 +1,21 @@
#include <Arduino.h>
#include "HTMLGenerator.h"
#include "DebugLog.h"
const String HTMLGenerator::GetElement(const String &tag, String &content, const String &attributes)
const String HTMLGenerator::GetElement(const String &tag, const String &content)
{
if (attributes != "")
{
content += "<" + tag + " " + attributes + ">" + content + "</" + tag + ">";
}
else
{
content+= "<" + tag + ">" + content + "</" + tag + ">";
}
return content;
return "<" + tag + ">" + content + "</" + tag + ">";
}
const String HTMLGenerator::DisplayPinStatus(const String &status, const String &link, bool isOn)
const String HTMLGenerator::DisplayOuputPinStatus(const String &pinName, const bool &isOn, const String &description)
{
String element = isOn ? "H4" : "p";
String content = status + (link != "" ? " <a href=\"" + link + "\">" + (isOn ? "OFF" : "ON") + "</a>" : "");
return GetElement(element, content,"");
const String pinvariable = pinName + (isOn ? "=OFF" : "=ON");
String content = pinName + " is " + (isOn ? "ON" : "OFF") + " | <a href=\"" + pinvariable + "\">" + pinvariable + "</a> ";
return GetElement("p", content);
}
const String HTMLGenerator::DisplayInputPinStatus(const String &pinName, const bool &isOn, const String &description)
{
const String content = pinName + " is " + (isOn ? "ON" : "OFF");
return GetElement("H4", content);
}
+3 -2
View File
@@ -6,8 +6,9 @@
class HTMLGenerator
{
public:
static const String GetElement(const String &tag, String &content, const String &attributes = "");
static const String DisplayPinStatus(const String &status, const String &link, bool isOn);
static const String GetElement(const String &tag,const String &content );
static const String DisplayOuputPinStatus( const String &pinName,const bool &isOn, const String &description);
static const String DisplayInputPinStatus( const String &pinName,const bool &isOn,const String &description);
};
#endif // HTMLGENERATOR_H
+1 -1
View File
@@ -15,5 +15,5 @@ framework = arduino
lib_deps =
arduino-libraries/Ethernet@^2.0.2
featherfly/SoftwareSerial@^1.0
monitor_speed = 9600
monitor_speed = 115200
+77 -47
View File
@@ -10,6 +10,8 @@
#include "DebugLog.h"
#include "HTMLGenerator.h"
#define DEBUG
// PIN INPUT Initialization as OUTPUT
static const int COUNT_OUTPUTS_PIN_OUT = 2;
static PinTypeOut PinIn8 = PinTypeOut("PIN8", 8, "Electric Alarm");
@@ -23,69 +25,100 @@ static PinTypeIn PinIn3 = PinTypeIn("PIN3", 3, 100, "Input Contact Box");
static const PinTypeIn INPUTS_PINS_ARRAY[COUNT_INPUTS_PIN_IN] = {PinIn2, PinIn3};
// // GSM Serial Port
static const uint8_t GSM_PIN_RX = 10;
static const uint8_t GSM_PIN_TX = 11;
static const long GSM_BAUD_RATE = 115200;
/*static const uint8_t GSM_PIN_RX = 5;
static const uint8_t GSM_PIN_TX = 6;
static const long GSM_BAUD_RATE = 115200;*/
// WebServer Data
static byte WebServerMac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
static IPAddress WebServerIP = IPAddress(192, 168, 1, 177);
static IPAddress WebServerIP = IPAddress(192, 168, 1, 99);
static const byte WebServerPort = 80;
byte gateway[] = {192, 168, 1, 1}; // Replace with your gateway IP
byte subnetMask[] = {255, 255, 255, 0}; // Replace if needed
// // Devices
GSMMobileDevice gsmDevice = GSMMobileDevice(GSM_PIN_RX, GSM_PIN_TX, GSM_BAUD_RATE);
// // Pin Input
GSMMobileData gsmData = GSMMobileData("GSM");
WebServer webServer;
// GSMMobileDevice gsmDevice = GSMMobileDevice(GSM_PIN_RX, GSM_PIN_TX, GSM_BAUD_RATE);
// // Pin Input
// GSMMobileData gsmData = GSMMobileData("GSM");
WebServer _webServer;
void SeparateDataFromRequest(WebServerData &request)
{
int indexofHttp = request.Request.indexOf(" HTTP");
if (indexofHttp == -1)
{
#ifdef DEBUG
DebugLog::log("ERROR: HTTP not found in GET Header!");
#endif
return;
}
#ifdef DEBUG
DebugLog::log("SeparateDataFromRequest: " + request.Request);
#endif
if (request.Request.indexOf("GET /id=GSM") != -1)
{
#ifdef DEBUG
DebugLog::log("it is GSM");
#endif
// int start = request.indexOf("/?id=") + 2;
String data = request.Request.substring(5);
#ifdef DEBUG
DebugLog::log("Update Data from GET: " + data);
#endif
String value = request.getValue(data, "mobileNumber=");
gsmData.updateMobileNumber(value);
// gsmData.updateMobileNumber(value);
value = request.getValue(data, "sms=");
gsmData.updateSMS(value);
// gsmData.updateSMS(value);
}
int indexPin = request.Request.indexOf("/PIN");
if (indexPin != -1)
{
String pinName = request.Request.substring(indexPin + 1, indexofHttp);
#ifdef DEBUG
DebugLog::log("GET as PIN [" + pinName + "]");
#endif
// foreach OUPUTS_PINS_ARRAY
for (int i = 0; i < COUNT_OUTPUTS_PIN_OUT; i++)
{
String actualPinName = request.getVariableName(pinName, "=");
PinTypeOut pinValue = OUPUTS_PINS_ARRAY[i];
#ifdef DEBUG
DebugLog::log("Compare Pin [" + actualPinName + "] with [" + pinValue.Id + "]");
#endif
if (pinValue.Id == actualPinName)
{
#ifdef DEBUG
DebugLog::log("Update GET as PIN : " + actualPinName);
#endif
if (request.Request.indexOf("=ON") != -1)
{
#ifdef DEBUG
DebugLog::log("Set " + actualPinName + "=ON");
#endif
pinValue.setOutputSignalToHigh();
}
if (request.Request.indexOf("=OFF") != -1)
{
#ifdef DEBUG
DebugLog::log("Set " + actualPinName + "=OFF");
#endif
pinValue.setOutputSignalToLow();
}
}
@@ -93,68 +126,65 @@ void SeparateDataFromRequest(WebServerData &request)
}
}
void WebServerEvent(WebServerData &data)
{
// Your function implementation here
SeparateDataFromRequest(data);
}
void setup()
{
#ifdef DEBUG
DebugLog::init(115200);
DebugLog::log("Called: Setup");
webServer = WebServer(WebServerMac, WebServerIP, WebServerPort);
// // serial monitori init and set baud rate
#endif
webServer.init();
_webServer = WebServer(WebServerMac, WebServerIP, WebServerPort);
delay(1000);
_webServer.init();
delay(1000);
#ifdef DEBUG
DebugLog::log("Web Server Initilized");
#endif
}
void GenerateHtml(WebServerData &data)
void GenerateHtml()
{
EthernetClient client = data.Client;
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
client.println("<html><head><style>");
client.println(" body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0;}");
client.println(".content {text-align: center;}");
_webServer.SendToBrowser("<html><head><style>");
_webServer.SendToBrowser(" body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0;}");
_webServer.SendToBrowser(".content {text-align: center;}");
_webServer.SendToBrowser("</style>");
_webServer.SendToBrowser("</head><body><div class=\"content\">");
_webServer.SendToBrowser("<H2> Trochta.net:</H2>");
for (int i = 0; i < COUNT_OUTPUTS_PIN_OUT; i++)
{
PinTypeOut pinValue = OUPUTS_PINS_ARRAY[i];
HTMLGenerator::DisplayPinStatus(pinValue.Id + "|" + pinValue.description, pinValue.Id, pinValue.IsPinOn());
String line = HTMLGenerator::DisplayOuputPinStatus(pinValue.Id, pinValue.IsPinOn(), pinValue.description);
_webServer.SendToBrowser(line);
}
for (int i = 0; i < COUNT_INPUTS_PIN_IN; i++)
for (int i = 0; i < COUNT_INPUTS_PIN_IN; i++)
{
PinTypeIn pinValue = INPUTS_PINS_ARRAY[i];
HTMLGenerator::DisplayPinStatus(pinValue.Id + "|" + pinValue.description,"", pinValue.IsPinHigh());
String line = HTMLGenerator::DisplayInputPinStatus(pinValue.Id, pinValue.IsPinHigh(), pinValue.description);
_webServer.SendToBrowser(line);
}
client.println("</style>");
client.println("</head><body><div class=\"content\">");
client.println("<H2> Trochta.net:</H2>");
client.println("</div></body></html>");
client.stop();
_webServer.SendToBrowser("</div></body></html>");
}
void loop()
{
// DebugLog::log("Called: Loop");
WebServerData data = webServer.getWebServerData();
WebServerData data = _webServer.getWebServerData();
if (!data.IsEmpty)
{
WebServerEvent(data);
SeparateDataFromRequest(data);
}
if (data.Client.available())
#ifdef DEBUG
DebugLog::log("client avaible [" + String (_webServer.client.available()) + "]");
#endif
if (_webServer.client.available())
{
GenerateHtml(data);
data.Client.stop();
GenerateHtml();
_webServer.endServer();
}
}