HTML.ino
// ****************************************************************
// Sketch Gaszähler Webinterface Modular(Tab)
// created: Jens Fleischer, 2018-04-08
// last mod: Jens Fleischer, 2023-02-12
// For more information visit: https://fipsok.de
// ****************************************************************
// Hardware: ESP32
// Software: ESP32 Arduino Core 2.0.6
/******************************************************************
Copyright (c) 2018 Jens Fleischer. All rights reserved.
This file is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
*******************************************************************/
// #include <WebServer.h> muss im Haupttab aufgerufen werden.
// Die Funktionalität des ESP32 Webservers ist erforderlich.
// Die Funktion "webpage();" muss im Setup eingebunden werden.
/**************************************************************************************/
void webpage() {
server.on("/", handleRoot);
server.on("/favicon.ico", handleIcon);
server.on("/status", handleStatus);
server.on("/ledh", []() {
ledh = !ledh;
handleStatus();
});
server.on("/ledz", []() {
ledz = !ledz;
handleStatus();
});
}
void handleStatus() {
if (server.arg(0).length() > 0 && server.arg(0).length() <= 7) {
value = server.arg(0).toInt();
save(); // Benutzer Eingabe in der Datei speichern
Serial.printf("Zählerstand vom Client: %ld\n", value);
}
char buf[42];
snprintf(buf, sizeof(buf), "[\"%05ld,%02ld9 m³\",\"%d\",\"%d\",\"%s\"]", value / 100, value % 100, ledh, ledz, errorTime().c_str());
server.send(200, "application/json", buf); // Zählerstand und Led Status an Html Seite senden
}
String errorTime() { // ermittelt die vergangene Zeit seit dem letztem Verbindungsfehler zu Thingspeak
if (lastError > 0) {
String Time = "";
uint8_t mm = (millis() / 1000 - lastError) / 60 % 60;
uint16_t hh = ((millis() / 1000 - lastError) / 60) / 60;
if (hh > 240) lastError = 0; // nach 10 Tagen ohne Fehler, wird die Fehleranzeige zurückgesetzt
if (hh < 10)Time += "0";
Time += (String)hh + ":";
if (mm < 10)Time += "0";
Time += (String)mm;
return Time;
}
return "0";
}
void handleRoot() { // Html Webseite, der Zählerstand wird aller 5 Sekunden mittels fetch.api aktuallisiert
String temp = "<!DOCTYPE HTML><html lang='de'><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1'><title>Gaszähler</title><script>";
temp += "addEventListener('load',()=>{let h=document.querySelector('#ledh'),z=document.querySelector('#ledz');let i=document.querySelector('input'),n=document.querySelector('#note');";
temp += "document.querySelector('#grey').addEventListener('click',()=>t());z.addEventListener('click',()=>s('ledz'));h.addEventListener('click',()=>s('ledh'));i.addEventListener('blur',";
temp += "()=>{!i.checkValidity()?(n.innerHTML=i.validationMessage,n.classList.add('note')):s('status',i.value)});function t(){let x=document.getElementById('no');getComputedStyle(x).";
temp += "display==='none'?x.style.display='flex':x.style.display='none';n.innerHTML='';n.classList.remove('note');i.value=''}async function s(p='status',v){if(Number.isInteger(parseInt";
temp += "(v)))t();let r=await fetch(p,{method:'POST',body:v});let j=await r.json();document.querySelector('span').innerHTML=j[0];j[1]=='0'?(h.innerHTML='LED Off',h.classList.add('off')):";
temp += "(h.innerHTML='LED On',h.classList.remove('off'));j[2]=='0'?(z.innerHTML='LED Off',z.classList.add('off')):(z.innerHTML='LED On',z.classList.remove('off'));if(j[3]!='0') document.";
temp += "querySelector('#err').innerHTML='Sendefehler vor '+j[3]+' hh:mm'}s(),setInterval(s,5000)});</script><style>body{background-color:tan;font-size:1.1em}body,#grey,#no,#black{display";
temp += ":flex;flex-flow:column;align-items:center}#grey,#no{background-color:#c5c3c3;width:280px;height:150px;border:.3em solid #aeaeab;border-radius:.5em;box-shadow:5px 10px 5px #4e4d4d}";
temp += "#grey{cursor:pointer}#black{background-color:black;width:14em;border-radius:.2em}#red{border:.28em solid red;position:relative;width:3.8em;height:1.5em;left:1.5em}span{color:white";
temp += ";position:relative;left:.1em;letter-spacing:.2em;font-size:1.6em;font-weight:bold;top:4.55em;pointer-events:none;z-index:1}#no{display:none}.note{background-color:#fecdee;padding:";
temp += ".3em;border-radius:.5em;position:relative;top:-5.5em}input,#err{height:30px;margin-top:1em}.button{background-color:#75a27e;height:40px;width:120px;font-size:16px;box-shadow:5px ";
temp += "5px 5px #4e4d4d}.off{background-color:#cf848c}</style></head><body><span></span><div id='grey'><h1>Zählerstand</h1><div id='black'><div id='red'></div></div></div><div id='no'>";
temp += "<input placeholder=' Zählerstand eingeben' pattern='[0-9]{1,7}' title='Nur 1 bis 7 Ziffern sind erlaubt' required><div id='err'>Zähler - Led - Heartbeat </div><div><button id='";
temp += "ledz' class='button'></button><button id='ledh' class='button'></button></div></div><div id='note'></div></body></html>";
server.send(200, "text/html", temp);
}
void handleIcon() {
const char favicon[] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x08, 0x03, 0x00, 0x00, 0x00, 0x44, 0xA4, 0x8A,
0xC6, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61,
0x05, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x4D, 0x00, 0x00, 0x7A, 0x26, 0x00, 0x00, 0x80,
0x84, 0x00, 0x00, 0xFA, 0x00, 0x00, 0x00, 0x80, 0xE8, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xEA,
0x60, 0x00, 0x00, 0x3A, 0x98, 0x00, 0x00, 0x17, 0x70, 0x9C, 0xBA, 0x51, 0x3C, 0x00, 0x00, 0x01,
0x50, 0x50, 0x4C, 0x54, 0x45, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3,
0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB3, 0xB5, 0xAF, 0xAF, 0xBC, 0x9F, 0x9F, 0xC0, 0x93, 0x93,
0xC5, 0x87, 0x87, 0xC7, 0x83, 0x83, 0xC6, 0x86, 0x86, 0xC2, 0x8F, 0x8F, 0xBC, 0x9E, 0x9E, 0xB4,
0xB2, 0xB2, 0xC9, 0x7F, 0x7F, 0xDE, 0x4F, 0x4F, 0xEE, 0x27, 0x27, 0xFD, 0x04, 0x04, 0xFF, 0x00,
0x00, 0xFD, 0x05, 0x05, 0xF3, 0x1D, 0x1D, 0xE2, 0x45, 0x45, 0xCF, 0x72, 0x72, 0xBA, 0xA1, 0xA1,
0xB6, 0xAB, 0xAB, 0xD5, 0x62, 0x62, 0xF5, 0x18, 0x18, 0xFE, 0x02, 0x02, 0xE9, 0x33, 0x33, 0xCC,
0x77, 0x77, 0xB5, 0xAE, 0xAE, 0xC7, 0x84, 0x84, 0xF6, 0x15, 0x15, 0xCB, 0x7C, 0x7C, 0xD1, 0x6D,
0x6D, 0xCD, 0x77, 0x77, 0xFE, 0x03, 0x03, 0xEF, 0x24, 0x24, 0xE1, 0x46, 0x46, 0xDB, 0x55, 0x55,
0xD9, 0x5A, 0x5A, 0xDD, 0x4F, 0x4F, 0xE9, 0x34, 0x34, 0xF9, 0x0D, 0x0D, 0xC3, 0x8C, 0x8C, 0xFB,
0x08, 0x08, 0xD8, 0x5B, 0x5B, 0xBA, 0xA4, 0xA4, 0xB4, 0xAF, 0xAF, 0xCA, 0x7E, 0x7E, 0xE5, 0x3C,
0x3C, 0xFE, 0x04, 0x04, 0xB4, 0xB1, 0xB1, 0xF2, 0x1F, 0x1F, 0xF2, 0x20, 0x20, 0xBD, 0x9A, 0x9A,
0xBF, 0x96, 0x96, 0xCC, 0x78, 0x78, 0xBA, 0xA3, 0xA3, 0xCC, 0x79, 0x79, 0xF5, 0x17, 0x17, 0xC9,
0x80, 0x80, 0xE6, 0x3B, 0x3B, 0xFB, 0x09, 0x09, 0xF0, 0x22, 0x22, 0xC2, 0x90, 0x90, 0xCB, 0x79,
0x79, 0xC5, 0x88, 0x88, 0xBE, 0x9A, 0x9A, 0xD0, 0x6F, 0x6F, 0xD3, 0x67, 0x67, 0xD0, 0x70, 0x70,
0xC6, 0x85, 0x85, 0xC2, 0x8E, 0x8E, 0xDC, 0x53, 0x53, 0xB6, 0xAD, 0xAD, 0xFC, 0x07, 0x07, 0xDC,
0x54, 0x54, 0xDD, 0x51, 0x51, 0xE8, 0x35, 0x35, 0xCA, 0x7D, 0x7D, 0xD0, 0x6E, 0x6E, 0xF6, 0x16,
0x16, 0xF7, 0x14, 0x14, 0xBE, 0x98, 0x98, 0xFC, 0x08, 0x08, 0xDA, 0x56, 0x56, 0xDC, 0x52, 0x52,
0xDA, 0x58, 0x58, 0xD5, 0x63, 0x63, 0xD1, 0x6B, 0x6B, 0xD7, 0x5D, 0x5D, 0xB3, 0xB2, 0xB2, 0xF8,
0x12, 0x12, 0xF9, 0x0E, 0x0E, 0xF5, 0x16, 0x16, 0xDF, 0x4C, 0x4C, 0xBF, 0x98, 0x98, 0xB5, 0xAD,
0xAD, 0xCE, 0x74, 0x74, 0xFA, 0x0D, 0x0D, 0xEE, 0x28, 0x28, 0xE1, 0x48, 0x48, 0xCF, 0x71, 0x71,
0xBD, 0x9B, 0x9B, 0xBD, 0x9C, 0x9C, 0xC2, 0x91, 0x91, 0xC7, 0x85, 0x85, 0xC0, 0x96, 0x96, 0xB9,
0xA4, 0xA4, 0xFF, 0xFF, 0xFF, 0xD7, 0xC3, 0x74, 0x75, 0x00, 0x00, 0x00, 0x05, 0x74, 0x52, 0x4E,
0x53, 0xF0, 0xFC, 0xE2, 0xF2, 0xEE, 0x8D, 0xB1, 0xB7, 0x7D, 0x00, 0x00, 0x00, 0x01, 0x62, 0x4B,
0x47, 0x44, 0x6F, 0x55, 0x08, 0x61, 0x81, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00,
0x00, 0x03, 0x3A, 0x00, 0x00, 0x03, 0x3A, 0x01, 0x59, 0x83, 0x48, 0xD2, 0x00, 0x00, 0x00, 0x07,
0x74, 0x49, 0x4D, 0x45, 0x07, 0xE7, 0x02, 0x0B, 0x07, 0x0A, 0x0B, 0x02, 0x26, 0x72, 0x7C, 0x00,
0x00, 0x01, 0x29, 0x49, 0x44, 0x41, 0x54, 0x38, 0xCB, 0x63, 0x60, 0x60, 0xC5, 0x0B, 0x18, 0x19,
0x48, 0x54, 0xC0, 0xC6, 0xCE, 0xC1, 0xC9, 0xC5, 0xCD, 0xC3, 0xCB, 0x87, 0x4D, 0x01, 0x1F, 0xBF,
0x80, 0xA0, 0x90, 0x30, 0x04, 0x88, 0x88, 0x8A, 0x89, 0x4B, 0xA0, 0x2A, 0x90, 0x94, 0x92, 0x16,
0x46, 0x05, 0x32, 0xB2, 0x72, 0xF2, 0x08, 0x05, 0x0A, 0x8A, 0xC2, 0x58, 0x80, 0x12, 0x5C, 0x81,
0xB2, 0x8C, 0x30, 0x5E, 0x05, 0x2A, 0x70, 0x79, 0x55, 0x35, 0x75, 0x0D, 0x4D, 0x2D, 0x6D, 0x1D,
0x54, 0x05, 0xBA, 0x30, 0xB7, 0xE9, 0xE9, 0x1B, 0x40, 0x6C, 0x34, 0x34, 0x32, 0x36, 0x41, 0x28,
0x30, 0x35, 0x83, 0xCA, 0x9B, 0x5B, 0x20, 0xF9, 0xD8, 0x52, 0x16, 0xAE, 0xC0, 0x0A, 0x2A, 0x2F,
0x6D, 0x8D, 0x1A, 0x48, 0x36, 0xB6, 0x76, 0x10, 0x05, 0xF6, 0x50, 0x05, 0x76, 0x38, 0x42, 0x52,
0xDE, 0x01, 0x22, 0xEF, 0x88, 0x2B, 0xA8, 0x9D, 0xA0, 0x06, 0x68, 0xE2, 0x52, 0xC0, 0x0F, 0x55,
0xE0, 0x0C, 0x16, 0x71, 0x91, 0x43, 0x02, 0xAE, 0x60, 0x05, 0x6E, 0x50, 0x05, 0x2E, 0x60, 0x05,
0xB2, 0xC8, 0x01, 0xE5, 0x0E, 0x56, 0xE0, 0x01, 0xE5, 0x79, 0xE2, 0x52, 0x00, 0xB3, 0x42, 0x0E,
0x97, 0x02, 0x2F, 0x28, 0xCF, 0x1B, 0x97, 0x02, 0x1F, 0x5F, 0x08, 0xCF, 0x0C, 0xAC, 0xC0, 0xCD,
0x0F, 0x08, 0xFC, 0x51, 0x14, 0xB0, 0x06, 0x40, 0xB9, 0x81, 0x70, 0xCF, 0xF9, 0xA0, 0x2A, 0x08,
0x82, 0x72, 0x83, 0x25, 0x70, 0x28, 0x90, 0x0F, 0x81, 0x45, 0x56, 0x28, 0x76, 0x05, 0xAC, 0x4A,
0x30, 0x47, 0x85, 0x85, 0xB3, 0x63, 0x55, 0xC0, 0x1A, 0x81, 0x48, 0x88, 0x66, 0x62, 0x91, 0x51,
0xD1, 0x31, 0xE8, 0x0A, 0x62, 0x05, 0xB0, 0xA6, 0x38, 0x84, 0x02, 0x56, 0x56, 0xFE, 0x38, 0x02,
0x0A, 0x58, 0x0D, 0xBC, 0xE3, 0xD1, 0xA5, 0x13, 0x12, 0x93, 0x50, 0x32, 0x4E, 0x72, 0x8A, 0xBA,
0x19, 0x2C, 0xF1, 0xA6, 0xA6, 0xA5, 0x67, 0x64, 0x62, 0xCB, 0x7A, 0x3E, 0x59, 0xD9, 0x39, 0x5C,
0xBA, 0xB9, 0x79, 0xA4, 0x64, 0x5E, 0x26, 0x66, 0xBC, 0x80, 0x05, 0x00, 0x60, 0x24, 0x46, 0xAE,
0xA3, 0x6F, 0x16, 0xCA, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65,
0x3A, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x32, 0x33, 0x2D, 0x30, 0x32, 0x2D,
0x31, 0x31, 0x54, 0x30, 0x37, 0x3A, 0x31, 0x30, 0x3A, 0x31, 0x31, 0x2B, 0x30, 0x30, 0x3A, 0x30,
0x30, 0xBE, 0xBE, 0x45, 0x23, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74,
0x65, 0x3A, 0x6D, 0x6F, 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x32, 0x33, 0x2D, 0x30, 0x32,
0x2D, 0x31, 0x31, 0x54, 0x30, 0x37, 0x3A, 0x31, 0x30, 0x3A, 0x31, 0x31, 0x2B, 0x30, 0x30, 0x3A,
0x30, 0x30, 0xCF, 0xE3, 0xFD, 0x9F, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6F,
0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E, 0x6B, 0x73, 0x63,
0x61, 0x70, 0x65, 0x2E, 0x6F, 0x72, 0x67, 0x9B, 0xEE, 0x3C, 0x1A, 0x00, 0x00, 0x00, 0x57, 0x7A,
0x54, 0x58, 0x74, 0x52, 0x61, 0x77, 0x20, 0x70, 0x72, 0x6F, 0x66, 0x69, 0x6C, 0x65, 0x20, 0x74,
0x79, 0x70, 0x65, 0x20, 0x69, 0x70, 0x74, 0x63, 0x00, 0x00, 0x78, 0x9C, 0xE3, 0xF2, 0x0C, 0x08,
0x71, 0x56, 0x28, 0x28, 0xCA, 0x4F, 0xCB, 0xCC, 0x49, 0xE5, 0x52, 0x00, 0x03, 0x23, 0x0B, 0x2E,
0x63, 0x0B, 0x13, 0x23, 0x13, 0x4B, 0x93, 0x14, 0x03, 0x13, 0x20, 0x44, 0x80, 0x34, 0xC3, 0x64,
0x03, 0x23, 0xB3, 0x54, 0x20, 0xCB, 0xD8, 0xD4, 0xC8, 0xC4, 0xCC, 0xC4, 0x1C, 0xC4, 0x07, 0xCB,
0x80, 0x48, 0xA0, 0x4A, 0x2E, 0x00, 0xEA, 0x17, 0x11, 0x74, 0xF2, 0x42, 0x35, 0x95, 0x00, 0x00,
0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
};
server.send(200, "image/x-icon", favicon); // Icon an den Browser senden
}
Der Compiler ist glücklich, ob auch Daten gezählt werden, habe ich nicht geprüft. Die HTML-Seite wird angezeigt und läßt sich ausklappen: