Skip to content

Instantly share code, notes, and snippets.

@abderrahman-laid
Last active April 26, 2023 12:07
Show Gist options
  • Save abderrahman-laid/691fe1883d8dc185190c1928ff5c9eb2 to your computer and use it in GitHub Desktop.
Save abderrahman-laid/691fe1883d8dc185190c1928ff5c9eb2 to your computer and use it in GitHub Desktop.
Esp32 Water Monitoring System Code
#include <splash.h> // Used To Display The Adafruit Logo In The Beginning
#include <Adafruit_GFX.h> // Used For For Drawing Lines, Rectangles, Circles, Text, And Images, As Well As Functions For Changing The Color And Size Of Drawn Shapes.
#include <Adafruit_SSD1306.h> // Used For Controlling The Display And Drawing Graphics On It.
#include <WiFi.h> // Used For Connecting To A Wi-Fi Network And For Communicating With Other Devices Over The Network. It Allows The Board To Act As A Client Or Server On A Wi-Fi Network
#include <WebServer.h> // Used To Receive Http Requests From Clients, Such As Web Browsers Or Mobile Apps, And To Send Responses Back To Those Clients.
#include <WebSocketsServer.h> // Used To Establish A Two-way Communication Channel With A Client, Such As A Web Browser Or Mobile App, Over A Single Tcp Connection.
#define OLED_RESET 4 // Pin For OLED Reseting (For Updating Its Content)
Adafruit_SSD1306 display(OLED_RESET); // Used To Updates The Display With The Latest Content (Reseting The Display In This Case).
#define TRIGGER_PIN 26 // Pin For The Ultra Sonic's Sensor Trigger
#define ECHO_PIN 27 // Pin For The Ultra Sonic's Sensor Echo
#define TH 50 // Write Here The Maximum Height Of The Water Inside The Water Tank In cm (Total Capacity In cm) Note:The Maximum sensor distance is rated at 400-500cm)
#define IGH 20 // Witre Here The Ignored Height Above The Water Tank In cm (Distance Between The Sensor And The 100% Of Water Level)
#define TC 1600 // Write Here The Total Capacity Of The Water Tank In Liters
const char* ssid = "abdouwissal"; // Write your SSID here
const char* password = "abdouhiba123.."; // Write your PASSWORD here
WebServer server(80); // Used To Creates A Web Server Object That Listens For Incoming Http Requests On The Specified Port (80 In This Case).
WebSocketsServer webSocket = WebSocketsServer(81); // Used To Creates A Websocket Server Object That Listens For Incoming Websocket Connections On The Specified Port (81 In This Case).
#define RELAY 32 // Pin For The Relay
boolean RELAYonoff=false; // Boolean Value For The Relay State
String JSONtxt; // Used To Declare A String Value To JSONtxt
#include "webpage.h" // Use For The Webpage
#include "functions.h" // Used For Decaring Some Functions
long duration, distance; // Used To Declare Duration And Distance
int WH,P,C; // Used To Declare WH,P,C
//=================================================================================================================================================================================================================================================================================================
void setup() { // Used To Put Code Here To Be Ran Once
Serial.begin(9600); // Used To Initializes The Serial Communication With A Baud Rate Of 9600 Bits Per Second.
pinMode(RELAY, OUTPUT); // Used To Specifie That The Pin Will Be Used As An Output Pin.
pinMode(TRIGGER_PIN, OUTPUT); // Used To Specifie That The Pin Will Be Used As An Output Pin.
pinMode(ECHO_PIN, INPUT); // Used To Specifie That The Pin Will Be Used As An Input Pin.
//=================================================================================================================================================================================================================================================================================================
WiFi.begin(ssid, password); // Used To Connects The Board To The Specified Wi-fi Network Using The Provided Ssid (Network Name) And Password.
while(WiFi.status() != WL_CONNECTED) // Used To Returns The Current Status Of The Wi-fi Connection, Such As "Connected", "Disconnected", Or "Connecting".
{
Serial.print("."); delay(500); // Used For Showing Text In The Serial Monitor
}
WiFi.mode(WIFI_STA); // Used To Set The WIFI To A WiFi Station mode.
Serial.print(" Local IP: "); // Used For Showing Text In The Serial Monitor
Serial.println(WiFi.localIP()); // Used To Returns The Local Ip Address Of The Board On The Wi-fi Network.
//=================================================================================================================================================================================================================================================================================================
server.on("/", handleRoot); // Used To Sets Up A Handler Function For A Specific Url Path On The Web Server. When A Client Makes An Http Request To That Path, The Handler Function Is Called And Can Generate A Response To Send Back To The Client.
server.begin(); // Used To Starts The Websocket Server And Begins Listening For Incoming Connections.
webSocket.begin(); // Used To Initializes The WebSocket Server
webSocket.onEvent(webSocketEvent); // Used To Registers An Event Handler Function For Websocket Events On The Websocket Server,The Websocket.Onevent() Function Can Be Called Multiple Times In An Arduino Sketch To Register Multiple Event Handlers For Different Websocket Events.
//=================================================================================================================================================================================================================================================================================================
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Used To Initialize With The I2C Address 0X3C (For The 128X32 OLED Display)
display.display(); // Used To Clear The Display.
delay(1000); // Used To Set A 1 Second Delay.
display.clearDisplay(); // Used To Clear The Display (Clear The Buffer).
}
//=================================================================================================================================================================================================================================================================================================
// The sensor is triggered by a HIGH pulse of 10 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
void loop() { // Used To Put Code Here To Be Ran Repeatedly
digitalWrite(TRIGGER_PIN, LOW); // Used To sets the digital output pin TRIGGER_PIN to a low voltage level, which corresponds to a logical value of 0.
delayMicroseconds(5); // Used To Set A 5 Micro-Second Delay
digitalWrite(TRIGGER_PIN, HIGH); // Used To sets the digital output pin TRIGGER_PIN to a high voltage level, which corresponds to a logical value of 1.
delayMicroseconds(10); // Used To Set A 10 Micro-Second Delay
digitalWrite(TRIGGER_PIN, LOW); // Used To sets the digital output pin TRIGGER_PIN to a low voltage level, which corresponds to a logical value of 0.
// Read the signal from the sensor: a HIGH pulse whose
// duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
duration = pulseIn(ECHO_PIN, HIGH); // Used To Measures The Duration Of A Pulse On A Digital Input Pin Echo_Pin.
distance = (duration/2) / 29.1; // Used To convert the time into a distance
WH=(TH+IGH)-distance; // WH Is The Water Height In cm
P=(WH*100)/TH; // P Is The Water Percentage
C=(P*TC)/100; // C Is The Real Time Capacity Of The Water Tank
//=================================================================================================================================================================================================================================================================================================
if (P > 100 || P<0) { // Used To Set An If Condition In Case The Water Rises More That 100%
Serial.print("The Water Is Leaking\n"); // Used For Showing Text In The Serial Monitor
}
else { // Used For The Resting Condition
Serial.print("Capacity: " + String(C) + " Liters\n"); // Used For Showing Text In The Serial Monitor
Serial.print("Percentage: " + String(P) + " %\n"); // Used For Showing Text In The Serial Monitor
}
//=================================================================================================================================================================================================================================================================================================
if (P > 100 || P<0) { // Used To Set An If Condition In Case The Water Rises More That 100%
display.clearDisplay(); // Used To Clear The Display
display.setTextSize(1); // Used To Set The Text's Size
display.setTextColor(WHITE); // Used To Set The Font's Color
display.setCursor(0,0); // Used To Sets The Cursor Position For Text On The Display.
display.print("---------------------\n"); // Used For Showing Text On The Display
display.print(" W A R N I N G ! \n"); // Used For Showing Text On The Display
display.print(" Water Level > 100 % \n"); // Used For Showing Text On The Display
display.print("---------------------\n"); // Used For Showing Text On The Display
}
else { // Used For The Resting Condition
display.clearDisplay(); // Used To Clear The Display
display.setTextSize(2); // Used To Set The Text's Size
display.setTextColor(WHITE); // Used To Set The Font's Color
display.setCursor(0,0); // Used To Sets The Cursor Position For Text On The Display.
display.println("" + String(C) + "Liters");// Used For Showing Text On The Display
display.print("Or " + String(P) + " %"); // Used For Showing Text On The Display
}
display.display(); // Used To Clear The Display
//=================================================================================================================================================================================================================================================================================================
webSocket.loop(); // Used to repeatedly processe incoming WebSocket messages and events on the WebSocket server.
server.handleClient(); // Used To processe incoming client requests on the HTTP server.
//=================================================================================================================================================================================================================================================================================================
static unsigned long l = 0; // Used To Track time intervals and retain their values across multiple iterations of the loop.
unsigned long t = millis(); // Used to track the starting time of an operation and calculate elapsed time using the millis() function.
if((t-l) > 1000) // Used To Set An If Condition In Case The (t-l) > 1000
{
if(RELAYonoff == false) digitalWrite(RELAY, LOW); // Used to turn the Relay Off if the condition is off
else digitalWrite(RELAY, HIGH); // Used to turn the Relay On if the condition is on
String RELAYstatus = "OFF"; // Status of the Relay
if(RELAYonoff == true) RELAYstatus = "ON"; // sed to turn the Relay On if the condition is on
//=================================================================================================================================================================================================================================================================================================
String capacityvalString = String(C); // Used to give a value to a string
String percentagevalString = String(P); // Used to give a value to a string
//=================================================================================================================================================================================================================================================================================================
JSONtxt = "{\"capacity\":\""+ capacityvalString +"\","; // Used For generating a JSON-formatted string with a single key-value pair,
JSONtxt += "\"percentage\":\""+ percentagevalString +"\","; // where the value is the contents of a variable.This is a common way to transmit data between different
JSONtxt += "\"RELAYonoff\":\""+ RELAYstatus +"\"}"; // systems or components using a lightweight and widely supported data format.
webSocket.broadcastTXT(JSONtxt); // sends the JSON-formatted string as a text message to all connected clients.
} // This allows the clients to receive and process the message in a way
} // that is appropriate for their specific use case.
Full Project Here:
https://github.com/abderrahman-laid/ESP32-Water-Monitoring-System
void handleRoot() //handle function: send webpage to client
{
server.send(200,"text/html", webpageCont); // Used To Sends An Http Response Back To The Client With The Specified Status Code, Content Type, And Content.
}
//=========================================================================================================================================================================
//function process event: new data received from client (its a callback function that is called by the WebSocketsServer library when a WebSocket event occurs.)
//"num" is an identifier for the WebSocket client that triggered the event
//"type" is the type of the event (e.g. WStype_TEXT for a text message)
//"payload" is a pointer to the message data
//"welength" is the length of the message data in bytes.
//=========================================================================================================================================================================
void webSocketEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t welength)
{
String payloadString = (const char *)payload; // Used To converts a byte array (i.e., payload) into a String object (i.e., payloadString).
//=========================================================================================================================================================================
if(type == WStype_TEXT) // Used To checks whether the WebSocket event type is a text message (WStype_TEXT). If it is, then the code within the curly braces is executed.
{
byte separator=payloadString.indexOf('='); // Used To finds the index of the equals sign (=) in the payloadString. The equals sign is used as a separator between the key and value in the key-value pairs.
String var = payloadString.substring(0,separator); // Used To extracts the substring of the payloadString from the beginning of the string to the index of the separator. This substring represents the key in the key-value pair.
String val = payloadString.substring(separator+1); // Used To extracts the substring of the payloadString from the index of the separator plus one to the end of the string. This substring represents the value in the key-value pair.
//=========================================================================================================================================================================
if(var == "RELAYonoff") // Used To check whether the key extracted from the payload is equal to the string. If it is, then the code within the curly braces is executed.
{
RELAYonoff = false; // Used To set the relay off variable to false by default. This variable is used to track whether the relay is turned on or off.
if(val == "ON") RELAYonoff = true; // Used To check whether the value extracted from the payload is equal to the string "ON". If it is, then the relay variable is set to true, indicating that the relay should be turned on.
}
}
}
//webpage.h
//=====================
//HTML,CSS,JSP code for webpage
//=====================
const char webpageCont[] PROGMEM =
R"=====(
<!DOCTYPE HTML>
<html>
<title>ESP32 Water Monitoring System</title>
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
<!---------------------------CSS-------------------------->
<style>
body {
background-color: #e8e8e8;
}
.newtons-cradle {
--uib-size: 70px;
--uib-speed: 1.2s;
--uib-color: #5C8EEE;
position: fixed;
bottom: 40%;
right: 48.5%;
display: flex;
align-items: center;
justify-content: center;
width: var(--uib-size);
height: var(--uib-size);
}
.newtons-cradle__dot {
position: relative;
display: flex;
align-items: center;
height: 100%;
width: 25%;
transform-origin: center top;
}
.newtons-cradle__dot::after {
content: '';
display: block;
width: 100%;
height: 25%;
border-radius: 50%;
background-color: var(--uib-color);
}
.newtons-cradle__dot:first-child {
animation: swing var(--uib-speed) linear infinite;
}
.newtons-cradle__dot:last-child {
animation: swing2 var(--uib-speed) linear infinite;
}
@keyframes swing {
0% {
transform: rotate(0deg);
animation-timing-function: ease-out;
}
25% {
transform: rotate(70deg);
animation-timing-function: ease-in;
}
50% {
transform: rotate(0deg);
animation-timing-function: linear;
}
}
@keyframes swing2 {
0% {
transform: rotate(0deg);
animation-timing-function: linear;
}
50% {
transform: rotate(0deg);
animation-timing-function: ease-out;
}
75% {
transform: rotate(-70deg);
animation-timing-function: ease-in;
}
}
tank {
width: 300px;
height: 550px;
background: linear-gradient(90deg, #E6E6FA 0%, #e0e0e0 50%, #D3D3D3 100%) center no-repeat;
box-shadow: 15px 15px 30px #bebebe,
-15px -15px 30px #ffffff;
border-radius: 10px 10px 20px 20px;
position: fixed;
bottom: 4%;
right: 40%;
}
tank #water {
width: 300px;
height:0%;
transition: height 0.5s ease-out;
background: linear-gradient(90deg, rgba(92, 142, 238, 0.51) 0%, #5C8EEE 100%);
border-radius: 10px 10px 20px 20px;
border-radius: 10px 10px 20px 20px;
position: absolute;
bottom: 0%;
right: 0%;
}
#box_switch {
width: 300px;
height: 300px;
background: linear-gradient(90deg, #E6E6FA 0%, #e0e0e0 50%, #D3D3D3 100%) center no-repeat;
box-shadow: 15px 15px 30px #bebebe,
-15px -15px 30px #ffffff;
border: 2px solid #5C8EEE;
border-radius: 30px ;
position: fixed;
bottom: 35%;
right: 8%;
}
button_doc {
color: #090909;
padding: 0.7em 1.7em;
font-family: inherit;
font-weight: 500;
font-size: 18px;
border-radius: 0.8em;
letter-spacing: 0.05em;
background: #e8e8e8;
border: 1px solid #e8e8e8;
transition: all .3s;
box-shadow: 6px 6px 12px #c5c5c5,
-6px -6px 12px #ffffff;
position: fixed;
bottom: 3%;
right: 2%;
}
button_doc:hover {
border: 1px solid #5C8EEE;
}
button_doc:active {
box-shadow: 4px 4px 12px #c5c5c5,
-4px -4px 12px #ffffff;}
#documentation_text {
color: black;
text-decoration: none;
font-family: Arial, sans-serif;
color:#5C8EEE;
text-shadow: 1px 2px 6px #969696;
}
button_code {
color: #090909;
padding: 0.7em 1.7em;
font-family: inherit;
font-weight: 500;
font-size: 18px;
letter-spacing: 0.05em;
border-radius: 0.8em;
background: #e8e8e8;
border: 1px solid #e8e8e8;
transition: all .3s;
box-shadow: 6px 6px 12px #c5c5c5,
-6px -6px 12px #ffffff;
position: fixed;
bottom: 2.8%;
right: 19%;
}
button_code:hover {
border: 1px solid #5C8EEE;}
button_code:active {
box-shadow: 4px 4px 12px #c5c5c5,
-4px -4px 12px #ffffff;}
#code_text {
color: black;
text-decoration: none;
font-family: Arial, sans-serif;
color:#5C8EEE;
text-shadow: 1px 2px 6px #969696;
}
svg {
position: fixed;
bottom: 5%;
right: 3.1%;
}
.switch {
font-size: 30px;
position: fixed;
bottom: 50%;
right: 15%;
display: inline-block;
width: 3.5em;
height: 2em;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(90deg, #E6E6FA 0%, #e0e0e0 50%, #D3D3D3 100%) center no-repeat;
box-shadow: 5px 10px 30px #bebebe,
-5px -10px 30px #ffffff;
transition: .4s;
border: 1px solid #5C8EEE;
border-radius: 10px;
}
.slider:before {
position: absolute;
content: "";
height: 1.4em;
width: 0.1em;
border-radius: 0px;
left: 0.3em;
bottom: 0.3em;
background-color: white;
transition: .4s;
}
input:checked + .slider {
background: linear-gradient(90deg, rgba(92, 142, 238, 0.51) 0%, #5C8EEE 100%);
}
input:checked + .slider:before {
transform: translateX(2.8em) ;
background-color: var(green);
}
#switch_text{
font-family: 'Verdana';
font-family: 'Roboto';
color: #205FDA;
text-shadow: 5px 3px 6px rgba(0, 0, 0, 0.3);
font-weight: 500;
font-size: 20px;
margin: 0;
text-align: center;
position: absolute;
top: 30%;
left: 81%;
transform: translate(-50%, -50%);
}
#copyright {
font-size: 12px;
position:fixed;
bottom:-2%;
left:0.1%;
}
#capacity {
font-family: 'Segoe UI';
font-family: 'Roboto';
color: #205FDA;
-webkit-text-stroke-width: 1.5px;
-webkit-text-stroke-color: #E0E0E0;
font-weight: 700;
font-size: 32px;
margin: 0;
text-align: center;
position: absolute;
top: 50%;
left: 49%;
transform: translate(-50%, -50%);
}
#percentage {
font-family: 'Segoe UI';
font-family: 'Roboto';
color: #205FDA;
-webkit-text-stroke-width: 1.5px;
-webkit-text-stroke-color: #E0E0E0;
font-weight: 700;
font-size: 27px;
margin: 0;
text-align: center;
position: absolute;
top: 56%;
left: 49%;
transform: translate(-50%, -50%);
}
body {
background-color: #e8e8e8;
}
.newtons-cradle {
--uib-size: 70px;
--uib-speed: 1.2s;
--uib-color: #5C8EEE;
position: fixed;
bottom: 40%;
right: 48.5%;
display: flex;
align-items: center;
justify-content: center;
width: var(--uib-size);
height: var(--uib-size);
}
.newtons-cradle__dot {
position: relative;
display: flex;
align-items: center;
height: 100%;
width: 25%;
transform-origin: center top;
}
.newtons-cradle__dot::after {
content: '';
display: block;
width: 100%;
height: 25%;
border-radius: 50%;
background-color: var(--uib-color);
}
.newtons-cradle__dot:first-child {
animation: swing var(--uib-speed) linear infinite;
}
.newtons-cradle__dot:last-child {
animation: swing2 var(--uib-speed) linear infinite;
}
@keyframes swing {
0% {
transform: rotate(0deg);
animation-timing-function: ease-out;
}
25% {
transform: rotate(70deg);
animation-timing-function: ease-in;
}
50% {
transform: rotate(0deg);
animation-timing-function: linear;
}
}
@keyframes swing2 {
0% {
transform: rotate(0deg);
animation-timing-function: linear;
}
50% {
transform: rotate(0deg);
animation-timing-function: ease-out;
}
75% {
transform: rotate(-70deg);
animation-timing-function: ease-in;
}
}
tank {
width: 300px;
height: 550px;
background: linear-gradient(90deg, #E6E6FA 0%, #e0e0e0 50%, #D3D3D3 100%) center no-repeat;
box-shadow: 15px 15px 30px #bebebe,
-15px -15px 30px #ffffff;
border-radius: 10px 10px 20px 20px;
position: fixed;
bottom: 4%;
right: 40%;
}
tank #water {
width: 300px;
height:0%;
transition: height 0.5s ease-out;
background: linear-gradient(90deg, rgba(92, 142, 238, 0.51) 0%, #5C8EEE 100%);
border-radius: 10px 10px 20px 20px;
border-radius: 10px 10px 20px 20px;
position: absolute;
bottom: 0%;
right: 0%;
}
#box_switch {
width: 300px;
height: 300px;
background: linear-gradient(90deg, #E6E6FA 0%, #e0e0e0 50%, #D3D3D3 100%) center no-repeat;
box-shadow: 15px 15px 30px #bebebe,
-15px -15px 30px #ffffff;
border: 2px solid #5C8EEE;
border-radius: 30px ;
position: fixed;
bottom: 35%;
right: 8%;
}
button_doc {
color: #090909;
padding: 0.7em 1.7em;
font-family: inherit;
font-weight: 500;
font-size: 18px;
border-radius: 0.8em;
letter-spacing: 0.05em;
background: #e8e8e8;
border: 1px solid #e8e8e8;
transition: all .3s;
box-shadow: 6px 6px 12px #c5c5c5,
-6px -6px 12px #ffffff;
position: fixed;
bottom: 3%;
right: 2%;
}
button_doc:hover {
border: 1px solid #5C8EEE;
}
button_doc:active {
box-shadow: 4px 4px 12px #c5c5c5,
-4px -4px 12px #ffffff;}
#documentation_text {
color: black;
text-decoration: none;
font-family: Arial, sans-serif;
color:#5C8EEE;
text-shadow: 1px 2px 6px #969696;
}
button_code {
color: #090909;
padding: 0.7em 1.7em;
font-family: inherit;
font-weight: 500;
font-size: 18px;
letter-spacing: 0.05em;
border-radius: 0.8em;
background: #e8e8e8;
border: 1px solid #e8e8e8;
transition: all .3s;
box-shadow: 6px 6px 12px #c5c5c5,
-6px -6px 12px #ffffff;
position: fixed;
bottom: 2.8%;
right: 19%;
}
button_code:hover {
border: 1px solid #5C8EEE;}
button_code:active {
box-shadow: 4px 4px 12px #c5c5c5,
-4px -4px 12px #ffffff;}
#code_text {
color: black;
text-decoration: none;
font-family: Arial, sans-serif;
color:#5C8EEE;
text-shadow: 1px 2px 6px #969696;
}
svg {
position: fixed;
bottom: 5%;
right: 3.1%;
}
.switch {
font-size: 30px;
position: fixed;
bottom: 50%;
right: 15%;
display: inline-block;
width: 3.5em;
height: 2em;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(90deg, #E6E6FA 0%, #e0e0e0 50%, #D3D3D3 100%) center no-repeat;
box-shadow: 5px 10px 30px #bebebe,
-5px -10px 30px #ffffff;
transition: .4s;
border: 1px solid #5C8EEE;
border-radius: 10px;
}
.slider:before {
position: absolute;
content: "";
height: 1.4em;
width: 0.1em;
border-radius: 0px;
left: 0.3em;
bottom: 0.3em;
background-color: white;
transition: .4s;
}
input:checked + .slider {
background: linear-gradient(90deg, rgba(92, 142, 238, 0.51) 0%, #5C8EEE 100%);
}
input:checked + .slider:before {
transform: translateX(2.8em) ;
background-color: var(green);
}
#switch_text{
font-family: 'Verdana';
font-style: sans-serif;
color: #205FDA;
text-shadow: 5px 3px 6px rgba(0, 0, 0, 0.3);
font-weight: 500;
font-size: 20px;
margin: 0;
text-align: center;
position: absolute;
top: 30%;
left: 81%;
transform: translate(-50%, -50%);
}
#copyright {
font-size: 12px;
position:fixed;
bottom:-2%;
left:0.1%;
}
#capacity {
font-family: 'Segoe UI';
color: #0C5BF3;
-webkit-text-stroke-width: 1.5px;
-webkit-text-stroke-color: #E0E0E0;
font-weight: 700;
font-size: 32px;
margin: 0;
text-align: center;
position: absolute;
top: 50%;
left: 49%;
transform: translate(-50%, -50%);
}
#percentage {
font-family: 'Segoe UI';
color: #0C5BF3;
-webkit-text-stroke-width: 1.5px;
-webkit-text-stroke-color: #E0E0E0;
font-weight: 700;
font-size: 27px;
margin: 0;
text-align: center;
position: absolute;
top: 56%;
left: 49%;
transform: translate(-50%, -50%);
}
#title_of_page{
font-family: 'Segoe UI';
color: #0C5BF3;
}
</style>
<!--------------------------HTML-------------------------->
<body>
<h1 id="title_of_page">ESP32 Water Monitoring System</h1>
<p id="copyright">&#169 2023 Blida . All Rights Reserved</p>
<tank>
<div id="water"></div>
</tank>
<div id="box_switch"></div>
<p id="switch_text">initializing ...</p>
<p id="capacity"></p>
<p id="percentage"></p>
<button_doc><a id=documentation_text href="https://github.com/abderrahman-laid/ESP32-Water-Monitoring-System" target="_blank">Documentation&nbsp;&nbsp;&nbsp;&nbsp;</a></button_doc>
<button_code><a id=code_text href="https://gist.github.com/abderrahman-laid/691fe1883d8dc185190c1928ff5c9eb2" target="_blank">&lt;/&gt; Code</a></button_code>
<label class="switch">
<input type="checkbox" id="RELAYbtn" onclick="relayONOFF()">
<span class="slider"></span>
</label>
<div class="newtons-cradle" id="loading_animation">
<div class="newtons-cradle__dot"></div>
<div class="newtons-cradle__dot"></div>
<div class="newtons-cradle__dot"></div>
<div class="newtons-cradle__dot"></div>
</div>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path fill="#5C8EEE" d="M12 0a12 12 0 0 0-3.8 23.4c.6.1.8-.3.8-.6v-2.2c-3.3.7-4-1.4-4-1.4-.6-1.4-1.4-1.8-1.4-1.8-1-.7.1-.7.1-.7 1.2 0 1.9 1.2 1.9 1.2 1 1.8 2.8 1.3 3.4 1 .2-.8.5-1.3.8-1.6-2.7-.3-5.5-1.3-5.5-6 0-1.2.5-2.3 1.3-3.1-.1-.4-.6-1.6.1-3.2 0 0 1-.3 3.3 1.2a11.5 11.5 0 0 1 6 0C17.3 4.7 18.3 5 18.3 5c.7 1.6.2 2.9.1 3.2.8.8 1.3 1.9 1.3 3.2 0 4.6-2.9 5.6-5.5 5.9.4.4.8 1.1.8 2.2v3.3c0 .3.2.7.8.6A12 12 0 0 0 12 0z"/></svg>
</body>
<!----------------------JavaScript------------------------>
<script>
InitWebSocket()
function InitWebSocket()
{
websock = new WebSocket('ws://'+window.location.hostname+':81/');
websock.onmessage=function(evt)
{
JSONobj = JSON.parse(evt.data);
document.getElementById('loading_animation').innerHTML ="";
document.getElementById('switch_text').innerHTML ="Use This Switch To Turn The Motor ON or OFF ";
var P=JSONobj.percentage;
if (P > 100 || P< 0) {
document.getElementById('percentage').style.color = "red";
document.getElementById('capacity').style.color = "red";
document.getElementById('capacity').innerHTML = "WARNING !";
document.getElementById('percentage').innerHTML = "Water > 100%";
var height = parseInt(JSONobj.percentage);
document.getElementById("water").style.height = "100%";
document.getElementById("water").style.border = "5px solid red";
}
else {
document.getElementById('percentage').style.color = "#0C5BF3";
document.getElementById('capacity').style.color = "#0C5BF3";
document.getElementById("water").style.border = "0px solid red";
document.getElementById('capacity').innerHTML = JSONobj.capacity +" Liters";
document.getElementById('percentage').innerHTML = JSONobj.percentage +" %";
var height = parseInt(JSONobj.percentage);
document.getElementById("water").style.height = height+"%";
}
document.getElementById('RELAYbtn').checked = (JSONobj.RELAYonoff == 'OFF');
}
}
//----------------------------------------------------
function relayONOFF() {
let RELAYbtn = 'RELAYonoff=ON';
if (document.getElementById('RELAYbtn').checked) {
RELAYbtn = 'RELAYonoff=OFF';
}
websock.send(RELAYbtn);
}
</script>
</html>
)=====";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment