Browse Source

/setup geht noch nicht

pull/283/head
lumapu 2 years ago
parent
commit
03b9af216d
  1. 7
      tools/esp8266/ahoywifi.h
  2. 6
      tools/esp8266/app.cpp
  3. 1
      tools/esp8266/app.h
  4. 2
      tools/esp8266/defines.h
  5. 194
      tools/esp8266/favicon.h
  6. 5
      tools/esp8266/html/convert.py
  7. 100
      tools/esp8266/html/h/favicon_ico_gz.h
  8. 1
      tools/esp8266/html/h/index_html.h
  9. 3
      tools/esp8266/html/h/setup_html.h
  10. 1
      tools/esp8266/html/h/style_css.h
  11. 1
      tools/esp8266/html/h/visualization_html.h
  12. 50
      tools/esp8266/html/setup.html
  13. 4
      tools/esp8266/platformio.ini
  14. 108
      tools/esp8266/tmplProc.h
  15. 524
      tools/esp8266/web.cpp
  16. 59
      tools/esp8266/web.h

7
tools/esp8266/ahoywifi.h

@ -7,13 +7,6 @@
#define __AHOYWIFI_H__
#include "dbg.h"
#ifdef ESP8266
#include <ESP8266WebServer.h>
#include <ESP8266WiFi.h>
#elif defined(ESP32)
#include <WebServer.h>
#include <WiFi.h>
#endif
// NTP
#include <WiFiUdp.h>

6
tools/esp8266/app.cpp

@ -23,6 +23,7 @@ app::app() {
loadDefaultConfig();
mSys = new HmSystemType();
mShouldReboot = false;
}
@ -64,6 +65,11 @@ void app::loop(void) {
}
}
if(mShouldReboot) {
DPRINTLN(DBG_INFO, F("Rebooting..."));
ESP.restart();
}
mSys->Radio.loop();

1
tools/esp8266/app.h

@ -142,6 +142,7 @@ class app {
}
HmSystemType *mSys;
bool mShouldReboot;
private:
void resetSystem(void);

2
tools/esp8266/defines.h

@ -13,7 +13,7 @@
//-------------------------------------
#define VERSION_MAJOR 0
#define VERSION_MINOR 5
#define VERSION_PATCH 15
#define VERSION_PATCH 16
//-------------------------------------

194
tools/esp8266/favicon.h

@ -1,194 +0,0 @@
//-----------------------------------------------------------------------------
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
//-----------------------------------------------------------------------------
// a) https://www.favicon-generator.org/
// b) exiftool -all:all= -r
// c) hexlify.py:
// import sys
// f = open (sys.argv[1], 'rb').read()
// for n, c in enumerate(f):
// if n % 16 == 0: print (' "', end = '')
// print (f"\\x{c:02x}", end = '')
// if n % 16 == 15: print ('" \\')
// if n % 16 != 15: print ('"')
#define FAVICON_PANEL_16 \
"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" \
"\x00\x00\x00\x10\x00\x00\x00\x10\x08\x03\x00\x00\x00\x28\x2d\x0f" \
"\x53\x00\x00\x00\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61" \
"\x05\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x26\x00\x00\x80" \
"\x84\x00\x00\xfa\x00\x00\x00\x80\xe8\x00\x00\x75\x30\x00\x00\xea" \
"\x60\x00\x00\x3a\x98\x00\x00\x17\x70\x9c\xba\x51\x3c\x00\x00\x01" \
"\x9b\x50\x4c\x54\x45\xfc\xfe\xff\xff\xff\xff\xcb\xcd\xcf\x22\x25" \
"\x30\x12\x16\x21\x11\x15\x21\x11\x15\x23\x12\x16\x25\x10\x13\x1f" \
"\x8f\x91\x93\x9b\x9d\xa1\x14\x17\x22\x14\x18\x25\x14\x17\x23\x13" \
"\x17\x22\x14\x17\x24\x17\x19\x27\x22\x24\x2e\xc1\xc2\xc3\xf8\xfa" \
"\xfb\x61\x63\x6b\x11\x13\x1f\x15\x19\x24\x17\x19\x24\x18\x1a\x24" \
"\x18\x1b\x26\x16\x19\x26\x42\x44\x4b\xe7\xe8\xe9\xfd\xff\xff\xfe" \
"\xff\xff\xe0\xe2\xe4\x33\x36\x3f\x16\x19\x24\x16\x17\x22\x16\x18" \
"\x22\x17\x18\x23\x11\x12\x1e\x71\x73\x76\xfb\xfc\xfd\xb5\xb7\xba" \
"\x1a\x1c\x27\x15\x17\x22\x15\x17\x21\x14\x15\x20\x14\x16\x23\x17" \
"\x1a\x26\x1b\x1c\x25\xaa\xac\xad\x7c\x7f\x85\x11\x13\x1d\x16\x18" \
"\x24\x17\x19\x25\x18\x1a\x25\x30\x32\x38\xd7\xd9\xd9\xef\xf1\xf2" \
"\x47\x49\x51\x12\x13\x1e\x17\x19\x22\x16\x17\x23\x10\x11\x1c\x59" \
"\x5a\x5f\xf4\xf6\xf7\xcc\xce\xd0\x24\x25\x2e\x16\x18\x23\x19\x1a" \
"\x24\x16\x17\x21\x15\x16\x21\x17\x17\x21\x15\x17\x20\x92\x93\x95" \
"\x99\x9a\x9e\x16\x16\x20\x17\x19\x23\x1a\x1b\x25\x23\x25\x2c\xc4" \
"\xc6\xc7\xf8\xfa\xfa\x61\x62\x68\x15\x16\x20\x11\x12\x1d\x44\x45" \
"\x49\xea\xec\xec\xdf\xe1\xe2\x33\x35\x3b\x15\x16\x1f\x13\x14\x1d" \
"\x78\x7a\x7c\xfc\xfd\xfe\xb2\xb4\xb7\x1a\x1c\x26\x18\x1b\x25\x1a" \
"\x1b\x22\x19\x1b\x22\xae\xaf\xb0\x86\x88\x8b\x14\x16\x1e\x19\x1b" \
"\x25\x17\x19\x21\x17\x19\x20\x12\x13\x1a\x2c\x2d\x32\xcc\xce\xcf" \
"\xfb\xfe\xff\xd8\xdb\xdb\x72\x74\x76\x25\x26\x2c\x19\x1c\x24\x13" \
"\x16\x1d\x11\x13\x18\x4c\x4d\x4f\xc1\xc3\xc3\xe2\xe4\xe6\xf6\xf8" \
"\xf8\xb6\xb9\xb9\x4f\x51\x55\x1b\x1c\x23\x19\x1b\x23\x15\x17\x1f" \
"\x70\x71\x72\xbb\xbb\xbc\xc3\xc4\xc5\xde\xe0\xe1\xf6\xf8\xf9\xfd" \
"\xfe\xff\xe3\xe5\xe6\x7e\x81\x82\x21\x22\x27\x1d\x1f\x26\x94\x95" \
"\x95\xbd\xbd\xbe\xbd\xbe\xbe\xc8\xca\xcb\xe5\xe7\xe9\xfa\xfc\xfd" \
"\x52\x5f\xd3\xea\x00\x00\x00\x01\x62\x4b\x47\x44\x01\xff\x02\x2d" \
"\xde\x00\x00\x00\xd2\x49\x44\x41\x54\x18\xd3\x63\x60\x00\x02\x46" \
"\x26\x66\x16\x16\x56\x36\x76\x0e\x4e\x46\x06\x30\x60\xe4\xe2\xe6" \
"\xe1\xe5\xe3\x17\x10\x14\x82\x0a\x08\x8b\x88\x8a\x89\x4b\x48\x4a" \
"\x49\xcb\xc8\x82\xf9\x72\xf2\x0a\xdc\x8a\x4a\xca\x2a\xaa\x6a\xea" \
"\x50\x1d\x1a\x9a\x5a\xda\x3a\xba\x7a\xfa\x06\x50\x1d\xb2\x86\x46" \
"\x5a\xbc\xc6\x26\xa6\x66\xe6\x72\x10\xbe\x85\xa5\x95\xb5\x89\xa9" \
"\x8d\xad\x9d\x3d\xc4\x08\x46\x07\x47\x27\x67\x17\x57\x37\x77\x0f" \
"\x39\xa8\x11\x9e\x4a\xa6\x36\x5e\xde\x3e\xbe\x7e\x50\x23\xfc\x03" \
"\x02\x55\x8c\x9d\x55\x82\x82\x43\xa0\x96\x86\x86\x85\x4b\x48\xb8" \
"\x84\x47\x44\x46\x41\x75\x44\xc7\x78\xc7\xba\x87\xc7\xc5\x27\x40" \
"\x75\xc8\x25\x26\x25\x7b\xa7\xa4\xa6\xa5\x67\x64\x42\x5d\x91\x95" \
"\x9d\x93\x92\x9b\x97\x5f\x50\x58\x24\x0c\x55\x52\x5c\x52\x5a\x56" \
"\x5e\x51\x59\x55\x5d\x53\x0b\x11\xa9\x93\xab\x6f\x68\x6c\x6a\x6e" \
"\x69\x6d\x6b\xef\x60\x00\x00\x01\x53\x2a\x2a\x63\x34\xcd\xf7\x00" \
"\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"
#define FAVICON_PANEL_32 \
"\x89\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52" \
"\x00\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a" \
"\xf4\x00\x00\x00\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61" \
"\x05\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x26\x00\x00\x80" \
"\x84\x00\x00\xfa\x00\x00\x00\x80\xe8\x00\x00\x75\x30\x00\x00\xea" \
"\x60\x00\x00\x3a\x98\x00\x00\x17\x70\x9c\xba\x51\x3c\x00\x00\x00" \
"\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00" \
"\x00\x07\x4a\x49\x44\x41\x54\x58\xc3\x9d\x97\xd9\x72\x5d\xc5\x15" \
"\x86\xbf\xee\xde\xd3\xd9\x67\xd0\x99\x74\x34\x3b\x48\x32\x48\xe0" \
"\x21\x60\xe1\x32\xd8\x15\x5e\x80\xdc\xf2\x00\xe4\x41\x12\x9e\x21" \
"\x37\xc9\x43\xa4\x20\x95\xe2\x9a\x82\x0c\x10\x70\x62\x06\x0f\xc2" \
"\x24\x15\xe2\x59\x96\xce\xbc\xe7\xb1\x73\x21\x93\x32\x20\x4b\xa7" \
"\xe8\xaa\x7d\xb3\x2f\x7a\x7d\xf5\xff\xfd\xaf\x5e\x2d\xf2\x52\x6b" \
"\x66\x58\x4a\xc0\x67\xff\xf8\x27\x6f\xbd\xf5\x36\xa3\xf1\x04\xad" \
"\x0b\x84\x94\x68\xad\xc9\xf3\x1c\xc7\x76\x08\xa3\x04\xdb\xb6\xc8" \
"\xf3\x12\x0d\xb8\x15\x9b\x28\x8c\x90\x52\xb0\xfe\xdc\x02\xbf\xff" \
"\xdd\x6f\xb9\x72\xf9\x32\xc5\x53\x15\xe5\x2c\xc5\xbf\x5b\xdf\x7e" \
"\x7b\x87\x34\x4b\x68\x36\xeb\x38\x8e\x4d\xb3\x59\xc7\xb6\x0d\x3a" \
"\x9d\x16\xb6\x63\x52\x71\x6c\xea\xb5\x2a\x52\x0a\x6a\xd5\x0a\x96" \
"\x65\x02\x1a\xc7\x36\xd9\xde\xda\x64\x6b\x6b\x9b\xf2\x07\x7b\x1a" \
"\xb3\x16\xcf\x8a\x82\x4f\x3f\xbd\x4a\x18\x86\x34\x1a\x73\x68\x24" \
"\x52\x1a\x08\xa1\xa8\x54\x1c\xa2\x30\xa4\xd9\xac\xd3\x9d\xef\xa0" \
"\xb5\x66\x65\x65\x91\x30\x8c\x50\x52\xd3\x6a\xd5\xd9\xda\x7a\x81" \
"\x56\xbb\xcd\x0f\xf5\x9e\x09\x40\x0a\x78\xb4\xf7\x98\x8f\x3f\xfe" \
"\x8c\xa2\x28\x99\x4c\xa6\x94\x25\xe4\x59\x49\x14\x47\xc4\x51\x4c" \
"\x92\x24\x54\x9c\x0a\xfd\xfe\x88\x3c\xcb\x89\xc2\x88\x2c\xcb\xd1" \
"\x5a\x23\x74\xce\xf6\xf6\x36\x4a\xf0\x3d\xf9\x67\x06\x10\xc0\xd7" \
"\xb7\xbf\xa1\x3f\x18\xb1\xb0\x30\x8f\xef\xfb\x98\xa6\x49\x96\x6b" \
"\xda\x9d\x39\x6c\x4b\x31\x1c\x8e\xa9\xd5\xaa\x8c\xc7\x1e\xae\xeb" \
"\x50\x71\xab\x0c\xfa\x63\x4c\x43\xb2\x79\xfa\x39\x2e\xbd\xf6\x1a" \
"\x47\x1d\xb6\x99\x2d\xb8\x7a\xf5\x73\xee\xde\x79\x80\x6d\x9b\x64" \
"\x79\x86\x6d\xdb\x64\x59\x86\x28\x73\x22\xa1\xa1\x2c\xb1\x2d\x03" \
"\xd3\x54\x2c\x2e\xf6\x70\x6c\x87\xb2\x28\xa8\xd5\x1c\xce\x9f\x3b" \
"\xc3\xda\xda\x29\x4a\xfd\x13\x00\x84\x00\xcf\x0f\xb8\x7e\xfd\x3a" \
"\xbd\x85\x0e\x8e\x6d\x31\x99\x7a\x58\x96\xc5\x70\x38\x22\x8a\x63" \
"\xd2\x24\xc5\xb2\x4c\x1e\xde\x7f\x44\x9c\xa4\xa4\x71\x42\x91\xe7" \
"\x14\x65\x49\x96\xda\xac\xad\xad\xe2\x58\xe6\x8f\xe4\x9f\x09\x40" \
"\x02\xb7\xbf\xf9\x86\x4f\x3e\xb9\x4a\x92\xc4\x68\x5d\xd2\x68\xd4" \
"\x71\x9c\x0a\x4a\x49\x1c\xdb\xe2\xe0\x60\xc0\xe2\x52\x0f\x7f\xea" \
"\xe3\xe4\x19\xae\x5b\xe5\xe0\x60\x88\x10\x8a\x4e\xbb\xc5\xeb\x97" \
"\x2f\x3f\x73\xff\x99\x2c\xd8\xdd\xbd\xcd\x70\x34\x46\x6b\xcd\x74" \
"\xea\x63\x99\x16\x79\x9e\x63\x5b\x06\x9e\x80\x2c\xcb\x99\x4e\x7d" \
"\x92\xa4\xa0\xd9\x6a\xb1\xd0\xeb\x90\x65\x39\x96\x65\xb0\xb3\xf3" \
"\x73\xce\xbc\x74\xe6\x47\xf1\x9b\x19\x20\x2b\x0a\xbe\xf8\xe2\x3a" \
"\x95\x4a\x85\xb9\x46\x95\xfe\x60\x48\xb7\xdb\x65\x32\x1a\xa1\x94" \
"\x62\x3a\x0d\x90\x52\x12\x85\x11\x7e\x90\x50\x14\x05\xfd\xbd\x3d" \
"\xb2\x3c\xa3\xde\x70\x59\x5b\x5b\x65\xae\x39\xc7\xb3\xda\xdd\xb1" \
"\x00\x52\xc0\x83\x47\x7b\x7c\xf8\xd1\xdf\x18\x8f\x27\x44\xbe\x07" \
"\x42\xe1\xfb\x11\x85\x96\x74\xda\x6d\xb4\x50\xb8\xae\x4d\x51\x94" \
"\x98\x56\x82\xeb\x3a\x0c\xfb\x03\x84\x90\x28\x25\x39\x7f\xfe\x3c" \
"\x12\x28\x7e\x8a\x02\x02\xd8\xdd\xfd\x9a\xbd\xbd\x7d\x96\x16\x7b" \
"\x84\xbe\x87\x46\x3e\xe9\x03\x9a\xfb\xf7\xf6\x88\x93\x84\x38\x76" \
"\x28\x72\xa8\x56\x5d\xe6\xe7\x3b\x14\x79\x86\xd6\x70\xee\xdc\xf3" \
"\x5c\xba\x74\x89\xe3\x7a\xfd\x89\x16\x5c\xbb\xf6\x25\xfd\x7e\x9f" \
"\xb9\x46\x0d\x29\x25\xed\x76\x0b\x06\x23\x9a\xed\x16\x9e\x17\x81" \
"\x00\x43\x29\x02\xcf\x47\x08\xf8\xd7\xed\x7f\x13\xc7\x09\x8d\xb9" \
"\x3a\xa7\x37\x37\x58\x5e\x59\x39\x32\x7e\x27\x02\x08\x01\x5e\x10" \
"\x70\xfd\xc6\x4d\x2a\x8e\x4d\x96\x66\x24\x49\x42\x9e\x17\x44\x51" \
"\x8c\x32\x14\x68\x58\x5d\x5d\x24\x4f\x13\xa4\x94\xd4\xea\xd5\x43" \
"\xf9\xa5\xa4\x2c\x33\x36\xd6\x9f\xc3\x32\x8c\x23\xe3\x77\x22\x80" \
"\x7c\x22\xff\xd5\xcf\xae\xd2\xeb\x75\x48\xd3\x0c\xcb\xb2\x48\x93" \
"\x84\x2c\xcb\x49\xa2\x98\x30\x88\x88\xa3\x94\xb2\x48\x31\x0c\x03" \
"\x77\xbe\x45\xde\xa8\xe3\xe4\x05\xa7\xd6\x7a\x5c\xbe\x72\xe5\x24" \
"\x81\x8f\xb7\xe0\xe6\xcd\x5b\x3c\x7c\xf0\x08\x29\x0c\x0a\xad\xe9" \
"\x74\x5a\x20\x24\xcb\x2b\x8b\xa4\x69\x8a\x65\xd9\x28\x43\x31\x1a" \
"\x44\x80\xe4\xe1\x83\x3d\x82\x20\xa2\x5a\xaf\xb2\xbd\xf5\x02\xdb" \
"\x2f\xbe\xf8\xcc\xf8\x9d\x08\x90\xe5\x05\x37\x6f\xdc\xa2\xd1\x68" \
"\x50\x6f\xcc\xb1\xbf\xdf\x27\x08\x62\xa2\x30\xc4\x77\x2c\xb4\x2e" \
"\x69\xb7\x9b\x74\xe6\xbb\xa4\x69\x4a\xaf\xd7\x65\xd0\x1f\x20\xa4" \
"\x40\x88\x92\x53\xa7\x56\xa9\xd7\x6a\xc7\xfa\xff\x4c\x00\x29\xe0" \
"\xde\xc3\x87\x7c\xf0\xc1\x5f\x08\xc2\x14\x43\x05\x74\x3b\x73\x18" \
"\x96\xc3\x74\x3c\x01\x34\xa3\xe1\x98\xd1\x70\x42\x7f\x30\xa1\x2c" \
"\x72\xb2\x34\xc3\xa9\xb8\x28\x43\xd1\xee\x34\xb8\x70\xe1\x02\xe2" \
"\x44\x03\x9e\x01\x70\x18\xbf\x5d\x06\xc3\x21\x8e\x63\x33\x19\x4f" \
"\xb0\x2c\x93\x42\x2b\x1a\xcd\x26\xad\xa6\x4b\x51\xe4\xd4\x1b\x75" \
"\x1e\xef\x1d\x00\x30\x1a\x4d\xf0\xbd\x90\x8a\x6b\xb1\xbe\x73\x96" \
"\x57\x2f\x5e\x64\x96\x51\xeb\x48\x00\x0d\x7c\x7e\xed\x4b\x26\x93" \
"\x29\xbd\x5e\x97\x40\x81\x53\xa9\xf0\xf8\xf1\x90\xf1\x68\xcc\xb0" \
"\xbf\x8f\x69\x2a\x5c\xd7\xa5\x5a\xab\xd2\xed\xb6\xf1\xfd\x10\xdf" \
"\x0f\x50\x0a\xd6\x7f\x76\x8a\x85\x85\xc5\x13\xe5\x87\x23\x46\xb2" \
"\xc3\xdb\xcf\xe7\xda\xb5\x6b\x64\x69\x42\x7f\xbf\x4f\x92\xa4\xb8" \
"\xd5\x0a\xcd\x66\x8d\x85\xc5\x0e\x08\x41\xa9\x05\x77\xff\x7b\x9f" \
"\xc9\xd8\xc3\x0f\x42\x84\x28\x69\xb6\x1b\x74\xba\x2d\x5e\xd8\xda" \
"\xc2\x54\xb3\x4d\x7b\xf2\xa8\x1f\xbb\xbb\xbb\xdc\xb8\x79\x8b\xc5" \
"\xa5\x1e\xae\xeb\xa0\x81\x7b\x77\x1f\xe2\xf9\x01\xe8\x82\x7a\xdd" \
"\xa5\x3b\xdf\xc2\xb4\x14\x52\x68\xa6\xe3\x31\x7b\x8f\x1e\x13\xf8" \
"\x01\xed\x76\x8b\x2b\x33\xc4\xef\x58\x0b\xbe\xfa\xea\x16\x77\xee" \
"\x3c\xc2\x75\x1d\x2c\xd3\xa0\xd9\x6e\xe2\xfb\x11\x59\x96\xb1\xbf" \
"\xb7\x4f\x9e\x17\x28\x29\x31\x2d\x83\xd5\xce\x12\x42\x1c\xaa\xa1" \
"\x94\xe2\xf4\xe6\x3a\xa7\x9f\x7f\xfe\xc4\xf8\x3d\x13\x20\xcd\x0b" \
"\xae\xdf\xb8\x49\xad\xd1\xc0\x50\x8a\xe9\x64\x42\x56\x68\xa4\x54" \
"\x74\x3b\x4d\x3c\xcf\x27\x89\x13\xc2\x20\x24\x0c\x02\x04\x1a\xcb" \
"\xb6\x69\x34\x1b\x54\xaa\x15\x4e\x6f\x6e\x50\x75\xdd\x99\xfc\xff" \
"\x11\x80\x14\x70\xe7\xfe\x3d\x3e\xfa\xf0\xcf\x58\xa6\xa2\x56\xab" \
"\x61\x59\x26\x69\x9a\x32\x9d\x78\xa0\x0b\x40\xb3\xb4\xbc\x80\xe7" \
"\x79\x24\x69\x4c\xe0\x07\x8c\xfa\x63\x84\x61\xd0\x68\xb8\x9c\x39" \
"\x7b\x96\xa2\xd4\x08\x31\x4b\x08\x7f\x00\x20\x80\x7b\xf7\xef\x93" \
"\xc4\x01\xa1\x37\xc1\x9f\x4e\x59\x5a\x5e\xc2\xb2\x4c\x2c\xcb\x24" \
"\x8e\x22\xbc\xa9\x47\x59\x14\x08\x43\x31\xbf\xd0\xc5\x75\x1d\xee" \
"\xfc\xe7\x2e\x52\xc1\xea\xca\x12\x4b\xcb\x2b\x0c\x87\x23\xea\xf5" \
"\xfa\x93\x77\xc1\xf1\x4b\xfd\xfa\x37\xef\xbc\xf3\x34\x41\xbd\x56" \
"\x67\x71\xb9\xc7\x78\x32\xe2\xe0\xf1\x3e\x81\x17\xe0\x79\x3e\xdd" \
"\x6e\x07\xc3\x30\x10\x42\x20\xa4\xc4\x9b\x7a\x68\x01\xba\x28\x91" \
"\x4a\xd2\x6c\xd6\x79\xe9\xa5\x2d\x76\x76\x76\xc8\x8b\x02\x21\x04" \
"\xa6\x69\xa0\x94\x3a\x56\x8d\xef\x03\x00\xae\x5b\xe1\xdc\xd9\xb3" \
"\xbc\xfc\xca\xcb\x38\xae\xcd\x64\x32\x66\xd0\x1f\x10\xf8\x3e\x41" \
"\x10\xd2\x5b\xe8\x61\x3b\x0e\x49\x92\x52\x16\x05\xde\xd4\x23\x4d" \
"\x12\x2c\x5b\xf1\xfa\x6b\x97\xd8\xd8\xd8\x20\x4b\x53\xf2\x3c\x07" \
"\x0e\x21\xbe\x03\x9f\x09\xe0\x50\x09\xc1\x42\xaf\xc7\xc5\x8b\x17" \
"\x59\xdf\x5c\x47\x8b\x92\xc9\x74\xc2\x68\x30\x22\x89\x53\xa2\x30" \
"\xa6\x56\xab\xd2\x9d\xef\x12\xf8\x11\x5a\xc3\xf2\x52\x8f\x5f\xbe" \
"\xf9\x26\x8d\x46\x9d\xa2\x28\xc8\xb2\x9c\x2c\xcf\x0f\x7d\x36\x0c" \
"\x0c\xc3\x3c\x12\xe2\x68\x00\x0e\xbb\xa1\x65\x59\x9c\xde\xdc\xe4" \
"\xc2\x2b\xaf\xd0\x6c\xcd\x31\x1a\x8f\x89\xe3\x98\xe9\x68\x8c\x2e" \
"\x0b\xb4\x06\xa9\x14\xcd\x56\x93\xed\xad\x4d\xde\x78\xe3\x17\x48" \
"\xa9\x00\x8d\x2e\x4b\x8a\x22\x27\xcf\x0f\x5f\x47\x87\x10\x06\x52" \
"\x7e\x1f\xe2\xd8\xeb\xf8\xbb\x41\x72\x75\x75\x95\x5f\xbd\xfd\x36" \
"\xaf\xee\xec\xf0\xa7\xf7\xdf\xe7\xdd\x3f\xfc\x91\x83\xfd\x7d\xa6" \
"\xe3\x11\x85\x96\xd8\x8e\xc9\xd2\xe2\x02\x8e\xe3\xa0\xff\x3f\x7d" \
"\x6a\x8a\x3c\x27\x0c\x43\x84\x10\x68\x0d\x5a\x6b\xaa\xd5\x2a\xea" \
"\xa9\x2e\x39\xd3\x58\xae\x35\x98\x86\xc9\xab\x3b\x3b\xac\x9d\x3a" \
"\xc5\xc6\xfa\x3a\xef\xbe\xf7\x1e\x7f\xff\xeb\xa7\xe4\x71\x46\x99" \
"\xe7\xac\xaf\xaf\xa3\x94\xa2\x2c\xf5\x93\x2b\x59\x22\xe5\xe1\xa7" \
"\x35\x94\x65\x49\x59\x16\x68\x5d\xf2\x74\x03\xfe\x1f\xc2\x60\x72" \
"\xe2\x6a\x9b\x4e\x8f\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60" \
"\x82"

5
tools/esp8266/html/convert.py

@ -1,5 +1,4 @@
import re
import sys
import os
def convert2Header(inFile):
@ -21,18 +20,22 @@ def convert2Header(inFile):
if fileType == "html":
data = re.sub(r"\>\s+\<", '><', data) # whitespaces between xml tags
data = re.sub(r"(\;|\}|\>|\{)\s+", r'\1', data) # whitespaces inner javascript
length = len(data) # get unescaped length
data = re.sub(r"\"", '\\\"', data) # escape quotation marks
else:
data = re.sub(r"(\;|\}|\:|\{)\s+", r'\1', data) # whitespaces inner css
length = len(data) # get unescaped length
f = open(outName, "w")
f.write("#ifndef __{}_{}_H__\n".format(define, define2))
f.write("#define __{}_{}_H__\n".format(define, define2))
f.write("const char {}[] PROGMEM = \"{}\";\n".format(inFileVarName, data))
f.write("const uint32_t {}_len = {};\n".format(inFileVarName, length))
f.write("#endif /*__{}_{}_H__*/\n".format(define, define2))
f.close()
convert2Header("index.html")
convert2Header("setup.html")
convert2Header("visualization.html")
convert2Header("update.html")
convert2Header("style.css")

100
tools/esp8266/html/h/favicon_ico_gz.h

@ -0,0 +1,100 @@
#ifndef __FAVICON_ICO_GZ_H__
#define __FAVICON_ICO_GZ_H__
#define favicon_ico_gz_len 1533
const uint8_t favicon_ico_gz[] PROGMEM = {0x1f, 0x8b, 0x08, 0x08, 0xf2, 0xc5, 0xd5, 0x62, 0x04, 0x00, 0x66, 0x61, 0x76, 0x69, 0x63, 0x6f,
0x6e, 0x2e, 0x69, 0x63, 0x6f, 0x00, 0xed, 0x5c, 0x49, 0x68, 0x13, 0x51, 0x18, 0xfe, 0x62, 0xa3,
0x51, 0x28, 0xd6, 0x83, 0x82, 0xa0, 0x98, 0xb8, 0x1c, 0xbc, 0x59, 0x11, 0x5c, 0x50, 0xac, 0x88,
0x8a, 0xb8, 0xdd, 0x3c, 0x89, 0xd0, 0x93, 0x7a, 0x53, 0x51, 0x9b, 0x80, 0x4b, 0x46, 0xad, 0xfb,
0xd2, 0xb4, 0x2e, 0xb8, 0xa3, 0xc6, 0xba, 0xe1, 0x02, 0xae, 0xad, 0x0a, 0x26, 0x3d, 0xe8, 0xc5,
0x83, 0x57, 0x31, 0x2d, 0xc1, 0x8b, 0xb7, 0x92, 0x63, 0x0e, 0xa1, 0xcf, 0xff, 0xcf, 0xbc, 0xc9,
0x32, 0xa4, 0x66, 0xcf, 0x4b, 0xf3, 0xfa, 0xc3, 0xc7, 0x97, 0xcc, 0xcc, 0xcb, 0xf7, 0xbe, 0x6f,
0x26, 0x6f, 0x26, 0xf3, 0x92, 0x00, 0x0e, 0x34, 0x61, 0xda, 0x34, 0x66, 0x0f, 0xf6, 0x38, 0x81,
0xa5, 0x00, 0x3c, 0x1e, 0xf3, 0xf9, 0x53, 0x5a, 0x7e, 0x8f, 0x96, 0xad, 0x59, 0x63, 0x3e, 0x5f,
0xb8, 0x16, 0xd8, 0x30, 0x03, 0x58, 0x48, 0xdb, 0xd0, 0x2a, 0x5a, 0x62, 0x2e, 0x1f, 0xad, 0x06,
0xc3, 0x5d, 0xc6, 0x60, 0x38, 0x20, 0x08, 0x5e, 0xf1, 0x08, 0x77, 0x09, 0x42, 0xf4, 0xe2, 0xd7,
0x67, 0x2f, 0x56, 0xf5, 0x7b, 0x21, 0x18, 0xfc, 0xb8, 0x63, 0x0b, 0x7e, 0x11, 0x84, 0x77, 0x0b,
0xee, 0x2e, 0x9a, 0x03, 0x6f, 0xab, 0x1b, 0x82, 0x31, 0x38, 0x10, 0x38, 0xce, 0xaf, 0x51, 0x72,
0x7b, 0xd2, 0xe6, 0xf6, 0xbf, 0xbf, 0xf6, 0xcc, 0x2e, 0xbd, 0x7d, 0xf2, 0x35, 0x76, 0x88, 0x20,
0xf6, 0x96, 0xde, 0x3e, 0xe0, 0xa5, 0x76, 0xad, 0xd4, 0xfe, 0x64, 0xc9, 0xed, 0xa9, 0xff, 0xd4,
0xd6, 0x4f, 0x68, 0x2f, 0xb9, 0x3d, 0xf5, 0x9f, 0x70, 0xb8, 0xaf, 0x03, 0x4b, 0x4b, 0x6e, 0x4f,
0xfd, 0xe7, 0x7d, 0x4b, 0x6d, 0x4f, 0x96, 0xd3, 0xde, 0x7a, 0x8d, 0x72, 0xda, 0x73, 0x7d, 0xdb,
0x8f, 0x29, 0x45, 0xb5, 0x7f, 0x84, 0x4e, 0xfb, 0x71, 0xda, 0xb1, 0x19, 0x9d, 0x05, 0xb5, 0xef,
0xc5, 0xa5, 0xd1, 0x8e, 0x75, 0xef, 0x56, 0x9c, 0xfa, 0x6f, 0xfb, 0x87, 0x58, 0x86, 0x3c, 0x75,
0x70, 0x13, 0x96, 0xe5, 0x6a, 0x1f, 0x19, 0xe8, 0x6a, 0x47, 0x81, 0xd5, 0xea, 0x41, 0x7b, 0x56,
0xfb, 0x50, 0xe0, 0x72, 0xae, 0xed, 0xbe, 0x1a, 0x98, 0xcc, 0xc8, 0xf9, 0x1a, 0x73, 0x70, 0x9a,
0xda, 0x8f, 0xda, 0xf6, 0xb9, 0x81, 0x49, 0xfd, 0x3e, 0xbc, 0xa5, 0xfd, 0xd7, 0xcf, 0xf9, 0x8f,
0xf6, 0x1a, 0xff, 0xeb, 0xe7, 0x04, 0x42, 0x13, 0xc3, 0x20, 0x84, 0x00, 0x57, 0x14, 0x68, 0x89,
0x01, 0xee, 0x38, 0xb0, 0xfa, 0x08, 0x70, 0x64, 0xb5, 0x39, 0xce, 0x78, 0x08, 0x6b, 0x0a, 0x1f,
0x67, 0x2c, 0x0c, 0xf3, 0x72, 0xf1, 0x18, 0xab, 0xe4, 0x3e, 0x4f, 0x23, 0x88, 0x37, 0xbc, 0xae,
0xcf, 0x07, 0xaf, 0xf9, 0x1e, 0x48, 0x83, 0x97, 0xf1, 0xba, 0x43, 0x5b, 0xf0, 0x86, 0x8f, 0x87,
0x4c, 0xd0, 0xfe, 0x5d, 0xc5, 0xeb, 0x28, 0x97, 0x61, 0x33, 0xdf, 0x34, 0x78, 0x39, 0x8f, 0x55,
0xaa, 0xf4, 0x23, 0x03, 0x81, 0x53, 0x56, 0x1f, 0x54, 0xe8, 0xb3, 0xe6, 0x50, 0x28, 0x70, 0xde,
0xea, 0x83, 0x0a, 0xfd, 0x64, 0x1f, 0xc2, 0x81, 0x93, 0xbc, 0x0d, 0xf1, 0x01, 0x15, 0xfa, 0x49,
0x0c, 0x74, 0x9d, 0xe3, 0xed, 0x94, 0xe9, 0x13, 0x78, 0x1f, 0x24, 0xf5, 0x7b, 0xb1, 0x54, 0x89,
0x3e, 0xef, 0x7f, 0x59, 0x7c, 0xce, 0x53, 0xa5, 0x2f, 0x7a, 0xe0, 0x92, 0x7d, 0x38, 0xad, 0x44,
0x9f, 0xf6, 0x3f, 0x9f, 0xb3, 0x65, 0x1f, 0x3a, 0x95, 0xe8, 0x9b, 0xbe, 0x8f, 0x59, 0x7d, 0x50,
0xa4, 0x9f, 0xea, 0x03, 0xe9, 0xaf, 0x57, 0xa4, 0x9f, 0xea, 0x83, 0x42, 0x7d, 0xbe, 0x7e, 0xd9,
0xcf, 0xeb, 0x3e, 0xf9, 0xd0, 0xae, 0x44, 0x9f, 0xf7, 0xbf, 0x2c, 0x3a, 0x87, 0x9f, 0x56, 0xa9,
0x6f, 0xf5, 0x41, 0xa5, 0xbe, 0xbc, 0x0e, 0x3d, 0xa3, 0x52, 0xdf, 0xea, 0x83, 0x4a, 0x7d, 0xae,
0x0f, 0x87, 0x30, 0x5f, 0xa5, 0x3e, 0x57, 0x0d, 0xf4, 0x8d, 0x7c, 0xfa, 0xa4, 0x67, 0x54, 0x49,
0xff, 0x86, 0x10, 0x74, 0x29, 0x9b, 0xbf, 0x1c, 0xa4, 0xd9, 0x5d, 0x51, 0xfd, 0x20, 0x6e, 0x16,
0xa8, 0x9d, 0xd5, 0x87, 0x8a, 0xe8, 0x17, 0xaf, 0x9d, 0xea, 0x03, 0xe9, 0xf6, 0x94, 0xa9, 0x7f,
0xab, 0x44, 0xed, 0xac, 0x3e, 0x94, 0xa4, 0xff, 0x1c, 0xcd, 0x65, 0x6a, 0xa7, 0xfa, 0x60, 0x6c,
0x47, 0x73, 0xb1, 0xfa, 0xd5, 0xa8, 0x42, 0xf4, 0x23, 0xe1, 0xc0, 0x15, 0x54, 0xa9, 0x16, 0xbb,
0x71, 0xe5, 0x7f, 0xfa, 0x91, 0x50, 0xf7, 0x6d, 0x21, 0x8c, 0x09, 0xa8, 0x5e, 0x39, 0x48, 0xf3,
0x6a, 0x86, 0x7e, 0x59, 0xda, 0xfd, 0x07, 0x31, 0x97, 0x81, 0xe2, 0x2a, 0xdd, 0x87, 0xb4, 0xfe,
0x9d, 0x62, 0xb5, 0xe9, 0xde, 0xcb, 0x1c, 0x3a, 0xef, 0x0c, 0xf5, 0x77, 0xe0, 0xcf, 0x17, 0x1f,
0xe6, 0xa1, 0xb8, 0xe2, 0x3e, 0x5c, 0x23, 0x94, 0xa4, 0xfd, 0xd1, 0x07, 0x0f, 0x5d, 0x03, 0x45,
0xad, 0x73, 0x3f, 0x3f, 0xe6, 0x65, 0x28, 0xae, 0x92, 0x7d, 0x70, 0x4e, 0x9e, 0xe6, 0xe9, 0x24,
0xac, 0x23, 0x2c, 0x20, 0x4c, 0x27, 0x34, 0x13, 0x78, 0xf9, 0x24, 0xc2, 0x44, 0x7e, 0x7c, 0x96,
0xb0, 0x91, 0xb0, 0x90, 0x30, 0xd3, 0x5c, 0xe7, 0x6c, 0x26, 0x4c, 0x25, 0xb4, 0x30, 0x02, 0x84,
0x9f, 0x84, 0x58, 0x1a, 0xee, 0xb8, 0xc7, 0xd9, 0x96, 0xf0, 0x38, 0xfd, 0x23, 0x1e, 0xa7, 0x10,
0x1e, 0x97, 0x10, 0x51, 0x0b, 0x2d, 0x23, 0xfe, 0x98, 0x3b, 0xd1, 0x16, 0x6f, 0x8b, 0xbb, 0x13,
0x0b, 0xe5, 0x3d, 0x0a, 0xa3, 0xf8, 0xfb, 0x14, 0xb9, 0x3e, 0xbb, 0x45, 0xac, 0xed, 0xe5, 0x67,
0x38, 0x2f, 0x8f, 0xa1, 0x79, 0xd1, 0x8b, 0x5d, 0xb6, 0xeb, 0x89, 0x61, 0xce, 0x35, 0x0f, 0x86,
0x6d, 0xf7, 0xc1, 0x76, 0xf1, 0x58, 0x9b, 0x17, 0x9b, 0xe1, 0xb5, 0x8d, 0x09, 0x91, 0xf4, 0xfb,
0x21, 0x8d, 0x02, 0xee, 0x93, 0x68, 0xe7, 0x3f, 0x6f, 0x06, 0x1a, 0xf8, 0xe7, 0x1a, 0x0a, 0x75,
0x9d, 0xd0, 0xcd, 0xff, 0xe0, 0x40, 0xf7, 0xa5, 0xbc, 0x19, 0x34, 0xb2, 0x7f, 0xf3, 0xda, 0xe0,
0xa2, 0x3d, 0x03, 0x9d, 0xfc, 0xe7, 0xca, 0x80, 0xef, 0x5b, 0xea, 0xe4, 0xdf, 0xcc, 0xa0, 0xeb,
0x82, 0x3d, 0x03, 0x9d, 0xfc, 0xe7, 0xca, 0x20, 0x12, 0xee, 0xee, 0xd4, 0xc9, 0x3f, 0x21, 0x35,
0x77, 0x91, 0xce, 0x20, 0xb0, 0x5b, 0x27, 0xff, 0xe9, 0xb9, 0x93, 0x74, 0xe9, 0xe6, 0xdf, 0xca,
0x40, 0x67, 0xff, 0xd6, 0xdc, 0x91, 0xd6, 0xfe, 0x93, 0xe8, 0xf6, 0xdb, 0xfc, 0xb7, 0xe7, 0xf5,
0xde, 0x48, 0xfe, 0x6d, 0xe3, 0xbf, 0x35, 0x7f, 0xa5, 0xb3, 0xff, 0x82, 0x32, 0x68, 0x70, 0xff,
0x32, 0x83, 0x33, 0xba, 0xf9, 0x17, 0x0f, 0x30, 0x2b, 0xeb, 0x79, 0x10, 0x97, 0xb5, 0xf2, 0x4f,
0xe3, 0x3f, 0xc1, 0x6f, 0xcb, 0xe0, 0xac, 0x56, 0xfe, 0xe5, 0xdc, 0xad, 0x3d, 0x03, 0xcd, 0xfc,
0x67, 0x65, 0xc0, 0xf3, 0x0a, 0xf4, 0xbc, 0x5b, 0x33, 0xff, 0x3c, 0x97, 0x74, 0xd4, 0x9e, 0x81,
0x56, 0xfe, 0x73, 0x67, 0xd0, 0xa3, 0x95, 0x7f, 0x13, 0x87, 0x6d, 0x19, 0xcc, 0xd6, 0xcc, 0x3f,
0x1f, 0xf3, 0x47, 0x32, 0xb7, 0xd5, 0xce, 0xbf, 0x3c, 0x0e, 0x34, 0xf7, 0x9f, 0xcc, 0x40, 0x73,
0xff, 0x3c, 0x26, 0x6e, 0xb3, 0xda, 0xc8, 0xef, 0x57, 0x5d, 0xd1, 0xca, 0xbf, 0x6d, 0xfc, 0x17,
0x34, 0x15, 0xd9, 0xe7, 0xc5, 0x55, 0x5d, 0xfd, 0x17, 0x98, 0x41, 0x43, 0xfb, 0xb7, 0x32, 0xa0,
0xef, 0xd8, 0x5d, 0xd3, 0xd5, 0x7f, 0x66, 0x06, 0xba, 0xfa, 0xcf, 0xcc, 0x40, 0x57, 0xff, 0x56,
0x06, 0xe4, 0xf9, 0xba, 0xae, 0xfe, 0x33, 0x33, 0xd0, 0xd5, 0x7f, 0x66, 0x06, 0xba, 0xfa, 0xcf,
0x18, 0x0f, 0x4e, 0xeb, 0xea, 0xdf, 0xaa, 0x71, 0xff, 0xe3, 0xfe, 0x1b, 0xc4, 0xff, 0x4e, 0x94,
0x59, 0x1d, 0x5b, 0xb1, 0x33, 0xaf, 0xf7, 0x7a, 0xf4, 0x1f, 0xc4, 0x13, 0xf1, 0x9c, 0x7e, 0x4e,
0x5a, 0x66, 0x19, 0x06, 0x26, 0x50, 0x06, 0xf7, 0xc7, 0x94, 0xff, 0x0a, 0x79, 0x2f, 0x2a, 0x83,
0xfa, 0xf1, 0xff, 0x54, 0x7c, 0x85, 0x13, 0x15, 0x2e, 0xce, 0x80, 0x7e, 0x83, 0xf2, 0xa0, 0xce,
0xfd, 0x57, 0xc5, 0xbb, 0x55, 0xdb, 0xb7, 0xa3, 0x89, 0x33, 0xa8, 0x53, 0xff, 0xcf, 0xaa, 0xe9,
0x3d, 0x33, 0x03, 0xf2, 0xfb, 0xb0, 0xce, 0xfc, 0xd7, 0xc4, 0xbb, 0x3d, 0x83, 0x3a, 0xf1, 0x5f,
0x53, 0xef, 0x59, 0xef, 0x85, 0xad, 0x08, 0x2a, 0xf6, 0xff, 0x5c, 0x85, 0x77, 0x7b, 0x06, 0x8a,
0xfc, 0x2b, 0xf5, 0x6e, 0xcf, 0xa0, 0xa6, 0xfe, 0x83, 0x58, 0x54, 0xc9, 0xf3, 0x7b, 0xb9, 0xc5,
0x19, 0xd0, 0xff, 0x9c, 0x2c, 0xaa, 0x95, 0xff, 0xb1, 0x50, 0xe3, 0xfe, 0xc7, 0xfd, 0xb7, 0x56,
0xc8, 0xff, 0x50, 0xb8, 0xeb, 0x3e, 0xc6, 0x58, 0xd1, 0x7f, 0xfd, 0xdc, 0x6f, 0xad, 0x8c, 0xff,
0x17, 0x3f, 0x7e, 0xdc, 0x9c, 0x88, 0x31, 0x56, 0xdb, 0xe9, 0x2f, 0x8c, 0xc8, 0x5f, 0x6f, 0x99,
0xfe, 0xc7, 0xa4, 0xf7, 0x62, 0x32, 0x68, 0x54, 0xef, 0xb6, 0x0c, 0x1e, 0x17, 0xe9, 0xff, 0x65,
0x23, 0x78, 0x2f, 0x24, 0x03, 0x95, 0xde, 0x69, 0x1e, 0xf8, 0x14, 0x03, 0x35, 0x28, 0xce, 0x60,
0x91, 0x1b, 0x4f, 0x6c, 0xfe, 0xd5, 0x79, 0xf7, 0xe1, 0x44, 0x6a, 0xce, 0xab, 0x03, 0xe7, 0x51,
0x83, 0xca, 0x91, 0x41, 0xe6, 0x77, 0xfc, 0xdf, 0xfd, 0xfe, 0xd0, 0xe3, 0x42, 0x0d, 0xea, 0x93,
0x17, 0xc7, 0xed, 0xf3, 0xbe, 0x74, 0x1c, 0x9c, 0x43, 0x0d, 0x6a, 0xc9, 0x12, 0x4c, 0x24, 0xdf,
0xaf, 0x6c, 0xfe, 0xdf, 0xab, 0xf4, 0xae, 0x28, 0x83, 0xd7, 0x84, 0xba, 0xf1, 0x6e, 0x81, 0xb7,
0x41, 0x0d, 0xca, 0xca, 0x00, 0xcb, 0x11, 0x75, 0xd1, 0xd7, 0x14, 0x0d, 0xc9, 0x21, 0xc9, 0x51,
0xc9, 0xfb, 0x24, 0x2f, 0x97, 0x3c, 0x5b, 0xf2, 0x54, 0xc9, 0x2e, 0xc9, 0x4d, 0x7d, 0x26, 0x3b,
0xe2, 0x26, 0xc3, 0x62, 0x9f, 0xe4, 0xe5, 0x92, 0x57, 0x49, 0x5e, 0x2d, 0xb9, 0x4d, 0xf2, 0x4a,
0xc3, 0xe4, 0x15, 0x21, 0xb9, 0x7d, 0x54, 0x72, 0xbb, 0xe4, 0x56, 0xc9, 0x33, 0x25, 0x37, 0x4b,
0x76, 0x49, 0x6e, 0x92, 0xec, 0xb0, 0xf4, 0xec, 0x1c, 0x93, 0x1c, 0x97, 0x9c, 0x90, 0x3c, 0x22,
0x59, 0x58, 0x7c, 0x46, 0xf2, 0x77, 0xc9, 0x7f, 0x25, 0x8b, 0x82, 0xd8, 0x41, 0x7f, 0x3b, 0x91,
0xec, 0x8f, 0x10, 0x21, 0x66, 0xfe, 0x67, 0x06, 0xe6, 0x16, 0x21, 0x62, 0xcc, 0x6e, 0x21, 0xe2,
0xcc, 0x6d, 0x42, 0x24, 0x98, 0xfd, 0x42, 0x8c, 0x30, 0x0b, 0x2a, 0xf6, 0xcf, 0x7c, 0x87, 0x72,
0x61, 0x4e, 0xe4, 0x67, 0x3f, 0xf3, 0x08, 0x7d, 0x28, 0x4f, 0x16, 0x1c, 0x26, 0x1b, 0x4d, 0xb4,
0x90, 0x56, 0x85, 0x5c, 0xb4, 0x11, 0x6d, 0x1a, 0x6d, 0x21, 0x55, 0x52, 0x8e, 0x31, 0xf8, 0x31,
0x2f, 0xe3, 0x75, 0xff, 0x00, 0xd3, 0x39, 0x74, 0x2c, 0x6e, 0x57, 0x00, 0x00};
#endif /*__FAVICON_ICO_GZ_H__*/

1
tools/esp8266/html/h/index_html.h

@ -1,4 +1,5 @@
#ifndef __INDEX_HTML_H__
#define __INDEX_HTML_H__
const char index_html[] PROGMEM = "<!doctype html><html><head><title>Index - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><script type=\"text/javascript\">getAjax('/uptime', 'uptime');getAjax('/cmdstat', 'cmds');window.setInterval(\"getAjax('/uptime', 'uptime')\", {JS_TS});window.setInterval(\"getAjax('/cmdstat', 'cmds')\", {JS_TS});function getAjax(url, resid) {var http = null;http = new XMLHttpRequest();if(http != null) {http.open(\"GET\", url, true);http.onreadystatechange = print;http.send(null);}function print() {if(http.readyState == 4) {document.getElementById(resid).innerHTML = http.responseText;}}}function getInverterInfo(data){var http = null;http = new XMLHttpRequest();if(http != null) {http.open(\"POST\", \"/api\");http.setRequestHeader(\"Accept\", \"application/json\");http.setRequestHeader(\"Content-Type\", \"application/json\");http.send(data);}}</script></head><body><h1>AHOY - {DEVICE}</h1><div id=\"content\" class=\"content\"><p><a href=\"/visualization\">Visualization</a><br/><br/><a href=\"/setup\">Setup</a><br/></p><p><span class=\"des\">Uptime: </span><span id=\"uptime\"></span></p><p><span class=\"des\">Statistics: </span><pre id=\"cmds\"></pre></p><p>Every {TS}seconds the values are updated</p><div id=\"note\">This project was started from <a href=\"https://www.mikrocontroller.net/topic/525778\" target=\"_blank\">this discussion. (Mikrocontroller.net)</a><br/>New updates can be found on Github: <a href=\"https://github.com/grindylow/ahoy\" target=\"_blank\">https://github.com/grindylow/ahoy</a><br/><br/>Please report issues using the feature provided by <a href=\"https://github.com/grindylow/ahoy/issues\">Github</a><br/><br/>Discuss with us on <a href=\"https://discord.gg/WzhxEY62mB\">Discord</a><br/><p class=\"lic\"><a href=\"https://creativecommons.org/licenses/by-nc-sa/3.0/de\">Creative Commons - https://creativecommons.org/licenses/by-nc-sa/3.0/de/</a><br/>Check the licenses which are published on <a href=\"https://github.com/grindylow/ahoy\">https://github.com/grindylow/ahoy</a>as well</p></div></div><div id=\"footer\"><p class=\"left\">&copy 2022</p><p class=\"left\"><a href=\"/update\">Update Firmware</a></p><p class=\"right\">AHOY :: {VERSION}</p><p class=\"right\"><a href=\"/reboot\">Reboot</a></p><p class=\"right\">Git SHA: {BUILD}</p></div></body></html>";
const uint32_t index_html_len = 2317;
#endif /*__INDEX_HTML_H__*/

3
tools/esp8266/html/h/setup_html.h

File diff suppressed because one or more lines are too long

1
tools/esp8266/html/h/style_css.h

@ -1,4 +1,5 @@
#ifndef __STYLE_CSS_H__
#define __STYLE_CSS_H__
const char style_css[] PROGMEM = "h1 {margin:0;padding:20pt;font-size:22pt;color:#fff;background-color:#006ec0;display:block;text-transform:uppercase;}html, body {font-family:Arial;margin:0;padding:0;}p {text-align:justify;font-size:13pt;}p.lic, p.lic a {font-size:8pt;color:#999;}.des {margin-top:20px;font-size:13pt;color:#006ec0;}.s_active, .s_collapsible:hover {background-color:#006ec0;}.s_content {display:none;overflow:hidden;}.s_collapsible {background-color:#044e86;color:white;cursor:pointer;padding:18px;width:100%;border:none;text-align:left;outline:none;font-size:15px;margin-bottom:4px;}.subdes {font-size:12pt;color:#006ec0;margin-left:7px;}.subsubdes {font-size:12pt;color:#006ec0;margin:0 0 7px 12px;}.hide {display:none;}a:link, a:visited {text-decoration:none;font-size:13pt;color:#006ec0;}a:hover, a:focus {color:#f00;}a.erase {background-color:#006ec0;color:#fff;padding:7px;display:inline-block;margin-top:30px;}#content {padding:15px 15px 60px 15px;}#footer {position:fixed;bottom:0px;height:45px;background-color:#006ec0;width:100%;border-top:5px solid #fff;}#footer p, #footer a {color:#fff;padding:0 7px 0 7px;font-size:10pt !important;}div.content {background-color:#fff;padding-bottom:65px;overflow:auto;}input, select {padding:7px;font-size:13pt;}input.text, select {width:70%;box-sizing:border-box;margin-bottom:10px;border:1px solid #ccc;}input.sh {max-width:150px !important;margin-right:10px;}input.btn {background-color:#006ec0;color:#fff;border:0px;float:right;margin:10px 0 30px;text-transform:uppercase;}input.cb {margin-bottom:20px;}label {width:20%;display:inline-block;font-size:12pt;padding-right:10px;margin:10px 0px 0px 15px;vertical-align:top;}fieldset {margin-bottom:15px;}.left {float:left;}.right {float:right;}div.ch-iv {width:100%;background-color:#32b004;display:inline-block;margin-bottom:15px;padding-bottom:20px;overflow:auto;}div.ch {width:220px;min-height:350px;background-color:#006ec0;display:inline-block;margin:0 10px 15px 10px;overflow:auto;padding-bottom:20px;}div.ch .value, div.ch .info, div.ch .head, div.ch-iv .value, div.ch-iv .info, div.ch-iv .head {color:#fff;display:block;width:100%;text-align:center;}.subgrp {float:left;width:220px;}div.ch .unit, div.ch-iv .unit {font-size:19px;margin-left:10px;}div.ch .value, div.ch-iv .value {margin-top:20px;font-size:24px;}div.ch .info, div.ch-iv .info {margin-top:3px;font-size:10px;}div.ch .head {background-color:#003c80;padding:10px 0 10px 0;}div.ch-iv .head {background-color:#1c6800;padding:10px 0 10px 0;}div.iv {max-width:960px;margin-bottom:40px;}div.ts {font-size:13px;background-color:#ddd;border-top:7px solid #999;padding:7px;}div.modpwr, div.modname {width:70%;display:inline-block;}#note {margin:50px 10px 10px 10px;padding-top:10px;width:100%;border-top:1px solid #bbb;}@media(max-width:500px) {div.ch .unit, div.ch-iv .unit {font-size:18px;}div.ch {width:170px;min-height:100px }.subgrp {width:180px;}}";
const uint32_t style_css_len = 2899;
#endif /*__STYLE_CSS_H__*/

1
tools/esp8266/html/h/visualization_html.h

@ -1,4 +1,5 @@
#ifndef __VISUALIZATION_HTML_H__
#define __VISUALIZATION_HTML_H__
const char visualization_html[] PROGMEM = "<!doctype html><html><head><title>Index - {DEVICE}</title><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\"/><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><script type=\"text/javascript\">getAjax('/livedata', 'livedata');window.setInterval(\"getAjax('/livedata', 'livedata')\", {JS_TS});function getAjax(url, resid) {var http = null;http = new XMLHttpRequest();if(http != null) {http.open(\"GET\", url, true);http.onreadystatechange = print;http.send(null);}function print() {if(http.readyState == 4) {document.getElementById(resid).innerHTML = http.responseText;}}}</script><style type=\"text/css\"></style></head><body><h1>AHOY - {DEVICE}</h1><div id=\"content\" class=\"content\"><div id=\"livedata\"></div><p>Every {TS}seconds the values are updated</p></div><div id=\"footer\"><p class=\"left\">&copy 2022</p><p class=\"left\"><a href=\"/\">Home</a></p><p class=\"right\">AHOY :: {VERSION}</p></div></body></html>";
const uint32_t visualization_html_len = 922;
#endif /*__VISUALIZATION_HTML_H__*/

50
tools/esp8266/html/setup.html

@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
<title>Setup - {DEVICE}</title>
<title>Setup - {#DEVICE}</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript">
@ -54,11 +54,11 @@
<div id="content">
<a class="erase" href="/erase">ERASE SETTINGS (not WiFi)</a>
<form method="post" action="{IP}/save">
<form method="post" action="{#IP}/save">
<fieldset>
<legend class="des">Device Host Name</legend>
<label for="device">Device Name</label>
<input type="text" class="text" name="device" value="{DEVICE}"/>
<input type="text" class="text" name="device" value="{#DEVICE}"/>
</fieldset>
<button type="button" class="s_collapsible">WiFi</button>
@ -67,9 +67,9 @@
<legend class="des">WiFi</legend>
<p>Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.</p>
<label for="ssid">SSID</label>
<input type="text" class="text" name="ssid" value="{SSID}"/>
<input type="text" class="text" name="ssid" value="{#SSID}"/>
<label for="pwd">Password</label>
<input type="password" class="text" name="pwd" value="{PWD}"/>
<input type="password" class="text" name="pwd" value="{#PWD}"/>
</fieldset>
</div>
@ -77,12 +77,12 @@
<div class="s_content">
<fieldset>
<legend class="des">Inverter</legend>
{INVERTERS}<br/>
{#INVERTERS}<br/>
<p class="subdes">General</p>
<label for="invInterval">Interval [s]</label>
<input type="text" class="text" name="invInterval" value="{INV_INTVL}"/>
<input type="text" class="text" name="invInterval" value="{#INV_INTVL}"/>
<label for="invRetry">Max retries per Payload</label>
<input type="text" class="text" name="invRetry" value="{INV_RETRIES}"/>
<input type="text" class="text" name="invRetry" value="{#INV_RETRIES}"/>
</fieldset>
</div>
@ -91,9 +91,9 @@
<fieldset>
<legend class="des">NTP Server</legend>
<label for="ntpAddr">NTP Server / IP</label>
<input type="text" class="text" name="ntpAddr" value="{NTP_ADDR}"/>
<input type="text" class="text" name="ntpAddr" value="{#NTP_ADDR}"/>
<label for="ntpPort">NTP Port</label>
<input type="text" class="text" name="ntpPort" value="{NTP_PORT}"/>
<input type="text" class="text" name="ntpPort" value="{#NTP_PORT}"/>
</fieldset>
</div>
@ -102,15 +102,15 @@
<fieldset>
<legend class="des">MQTT</legend>
<label for="mqttAddr">Broker / Server IP</label>
<input type="text" class="text" name="mqttAddr" value="{MQTT_ADDR}"/>
<input type="text" class="text" name="mqttAddr" value="{#MQTT_ADDR}"/>
<label for="mqttPort">Port</label>
<input type="text" class="text" name="mqttPort" value="{MQTT_PORT}"/>
<input type="text" class="text" name="mqttPort" value="{#MQTT_PORT}"/>
<label for="mqttUser">Username (optional)</label>
<input type="text" class="text" name="mqttUser" value="{MQTT_USER}"/>
<input type="text" class="text" name="mqttUser" value="{#MQTT_USER}"/>
<label for="mqttPwd">Password (optional)</label>
<input type="text" class="text" name="mqttPwd" value="{MQTT_PWD}"/>
<input type="text" class="text" name="mqttPwd" value="{#MQTT_PWD}"/>
<label for="mqttTopic">Topic</label>
<input type="text" class="text" name="mqttTopic" value="{MQTT_TOPIC}"/>
<input type="text" class="text" name="mqttTopic" value="{#MQTT_TOPIC}"/>
</fieldset>
</div>
@ -119,19 +119,19 @@
<fieldset>
<legend class="des">System Config</legend>
<p class="des">Pinout (Wemos)</p>
{PINOUT}
{#PINOUT}
<p class="des">Radio (NRF24L01+)</p>
<label for="rf24Power">Amplifier Power Level</label>
<select name="rf24Power">{RF24}</select>
<select name="rf24Power">{#RF24}</select>
<p class="des">Serial Console</p>
<label for="serEn">print inverter data</label>
<input type="checkbox" class="cb" name="serEn" {SER_VAL_CB}/><br/>
<input type="checkbox" class="cb" name="serEn" {#SER_VAL_CB}/><br/>
<label for="serDbg">print RF24 debug</label>
<input type="checkbox" class="cb" name="serDbg" {SER_DBG_CB}/><br/>
<input type="checkbox" class="cb" name="serDbg" {#SER_DBG_CB}/><br/>
<label for="serIntvl">Interval [s]</label>
<input type="text" class="text" name="serIntvl" value="{SER_INTVL}"/>
<input type="text" class="text" name="serIntvl" value="{#SER_INTVL}"/>
</fieldset>
</div>
@ -143,11 +143,11 @@
</div>
<div id="footer">
<p class="left"><a href="{IP}/">Home</a></p>
<p class="left"><a href="{IP}/update">Update Firmware</a></p>
<p class="right">AHOY - {VERSION}</p>
<p class="right"><a href="{IP}/factory">Factory Reset</a></p>
<p class="right"><a href="{IP}/reboot">Reboot</a></p>
<p class="left"><a href="{#IP}/">Home</a></p>
<p class="left"><a href="{#IP}/update">Update Firmware</a></p>
<p class="right">AHOY - {#VERSION}</p>
<p class="right"><a href="{#IP}/factory">Factory Reset</a></p>
<p class="right"><a href="{#IP}/reboot">Reboot</a></p>
</div>
<script type="text/javascript">

4
tools/esp8266/platformio.ini

@ -34,10 +34,10 @@ lib_deps =
paulstoffregen/Time@^1.6.1
knolleary/PubSubClient@^2.8
bblanchon/ArduinoJson@^6.19.4
me-no-dev/ESP Async WebServer@^1.2.3
me-no-dev/ESPAsyncTCP@^1.2.2
;esp8266/DNSServer@1.1.0
;esp8266/EEPROM@^1.0
;esp8266/ESP8266HTTPUpdateServer@^1.0
;esp8266/ESP8266WebServer@^1.0
;esp8266/ESP8266WiFi@^1.0
;esp8266/SPI@1.0
;esp8266/Ticker@^1.0

108
tools/esp8266/tmplProc.h

@ -0,0 +1,108 @@
//-----------------------------------------------------------------------------
// 2022 Ahoy, https://www.mikrocontroller.net/topic/525778
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
//-----------------------------------------------------------------------------
#ifndef __TMPL_PROC__
#define __TMPL_PROC__
// HTML template processor, searches keywords and calls callback
// inspired by: https://github.com/plapointe6/EspHtmlTemplateProcessor
#include "dbg.h"
#include <string.h>
#include <functional>
#include "ESPAsyncWebServer.h"
#define MAX_BUFFER_SIZE 256
#define MAX_KEY_LEN 20
enum { ST_NONE = 0, ST_BUF, ST_PROC, ST_START, ST_KEY };
typedef std::function<String(char* key)> TmplCb;
class tmplProc {
public:
tmplProc(AsyncWebServerRequest *request, uint32_t bufStartSize = 1000) {
// Note: don't choose the bufStartSize to small. A too small start
// size will result in fractioned memory and maybe in a zero
// increase -> fail (Arduino - cbuf.cpp)
mRequest = request;
mResponse = request->beginResponseStream("text/html", bufStartSize);
}
~tmplProc() {}
void process(const char* tmpl, const uint32_t tmplLen, TmplCb cb) {
char* buf = new char[MAX_BUFFER_SIZE];
char* p = buf;
uint32_t len = 0, pos = 0, i = 0;
uint8_t state = ST_BUF;
bool complete = false;
while (i < tmplLen) {
switch (state) {
default:
DPRINTLN(DBG_DEBUG, F("unknown state"));
break;
case ST_BUF:
if(0 != i) {
buf[pos] = '\0';
mResponse->print(p);
}
pos = 0;
len = ((tmplLen - i) > MAX_BUFFER_SIZE) ? MAX_BUFFER_SIZE : (tmplLen - i);
if((len + i) == tmplLen)
complete = true;
memcpy_P(buf, &tmpl[i], len);
if(len < MAX_BUFFER_SIZE)
buf[len] = '\0';
p = buf;
state = ST_PROC;
break;
case ST_PROC:
if(((pos + MAX_KEY_LEN) >= len) && !complete)
state = ST_BUF;
else if(buf[pos] == '{')
state = ST_START;
break;
case ST_START:
if(buf[pos] == '#') {
if(pos != 0)
buf[pos-1] = '\0';
mResponse->print(p);
p = &buf[pos+1];
state = ST_KEY;
}
else
state = ST_PROC;
break;
case ST_KEY:
if(buf[pos] == '}') {
buf[pos] = '\0';
mResponse->print((cb)(p));
p = &buf[pos+1];
state = ST_PROC;
}
break;
}
if(ST_BUF != state) {
pos++;
i++;
}
}
mResponse->print(p);
delete[] buf;
mRequest->send(mResponse);
}
private:
AsyncWebServerRequest *mRequest;
AsyncResponseStream *mResponse;
};
#endif /*__TMPL_PROC__*/

524
tools/esp8266/web.cpp

@ -12,9 +12,10 @@
#include "html/h/index_html.h"
#include "html/h/style_css.h"
#include "favicon.h"
#include "html/h/favicon_ico_gz.h"
#include "html/h/setup_html.h"
#include "html/h/visualization_html.h"
#include "html/h/update_html.h"
//-----------------------------------------------------------------------------
web::web(app *main, sysConfig_t *sysCfg, config_t *config, char version[]) {
@ -22,14 +23,7 @@ web::web(app *main, sysConfig_t *sysCfg, config_t *config, char version[]) {
mSysCfg = sysCfg;
mConfig = config;
mVersion = version;
#ifdef ESP8266
mWeb = new ESP8266WebServer(80);
mUpdater = new ESP8266HTTPUpdateServer();
#elif defined(ESP32)
mWeb = new WebServer(80);
mUpdater = new HTTPUpdateServer();
#endif
mUpdater->setup(mWeb);
mWeb = new AsyncWebServer(80);
}
@ -38,34 +32,39 @@ void web::setup(void) {
DPRINTLN(DBG_VERBOSE, F("app::setup-begin"));
mWeb->begin();
DPRINTLN(DBG_VERBOSE, F("app::setup-on"));
mWeb->on("/", std::bind(&web::showIndex, this));
mWeb->on("/style.css", std::bind(&web::showCss, this));
mWeb->on("/favicon.ico", std::bind(&web::showFavicon, this));
mWeb->onNotFound ( std::bind(&web::showNotFound, this));
mWeb->on("/uptime", std::bind(&web::showUptime, this));
mWeb->on("/reboot", std::bind(&web::showReboot, this));
mWeb->on("/erase", std::bind(&web::showErase, this));
mWeb->on("/factory", std::bind(&web::showFactoryRst, this));
mWeb->on("/", HTTP_ANY, std::bind(&web::showIndex, this, std::placeholders::_1));
mWeb->on("/style.css", HTTP_ANY, std::bind(&web::showCss, this, std::placeholders::_1));
mWeb->on("/favicon.ico", HTTP_ANY, std::bind(&web::showFavicon, this, std::placeholders::_1));
mWeb->onNotFound ( std::bind(&web::showNotFound, this, std::placeholders::_1));
mWeb->on("/uptime", HTTP_ANY, std::bind(&web::showUptime, this, std::placeholders::_1));
mWeb->on("/reboot", HTTP_ANY, std::bind(&web::showReboot, this, std::placeholders::_1));
mWeb->on("/erase", HTTP_ANY, std::bind(&web::showErase, this, std::placeholders::_1));
mWeb->on("/factory", HTTP_ANY, std::bind(&web::showFactoryRst, this, std::placeholders::_1));
mWeb->on("/setup", HTTP_ANY, std::bind(&web::showSetup, this, std::placeholders::_1));
mWeb->on("/save", HTTP_ANY, std::bind(&web::showSave, this, std::placeholders::_1));
mWeb->on("/setup", std::bind(&web::showSetup, this));
mWeb->on("/save", std::bind(&web::showSave, this));
mWeb->on("/cmdstat", HTTP_ANY, std::bind(&web::showStatistics, this, std::placeholders::_1));
mWeb->on("/visualization", HTTP_ANY, std::bind(&web::showVisualization, this, std::placeholders::_1));
mWeb->on("/livedata", HTTP_ANY, std::bind(&web::showLiveData, this, std::placeholders::_1));
mWeb->on("/json", HTTP_ANY, std::bind(&web::showJson, this, std::placeholders::_1));
mWeb->on("/api", HTTP_POST, std::bind(&web::showWebApi, this, std::placeholders::_1));
mWeb->on("/cmdstat", std::bind(&web::showStatistics, this));
mWeb->on("/visualization", std::bind(&web::showVisualization, this));
mWeb->on("/livedata", std::bind(&web::showLiveData, this));
mWeb->on("/json", std::bind(&web::showJson, this));
mWeb->on("/api", HTTP_POST, std::bind(&web::showWebApi, this));
mWeb->on("/update", HTTP_GET, std::bind(&web::showUpdateForm, this, std::placeholders::_1));
mWeb->on("/update", HTTP_POST, std::bind(&web::showUpdate, this, std::placeholders::_1),
std::bind(&web::showUpdate2, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6));
}
//-----------------------------------------------------------------------------
void web::loop(void) {
mWeb->handleClient();
}
//-----------------------------------------------------------------------------
void web::showIndex(void) {
void web::showIndex(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("showIndex"));
String html = FPSTR(index_html);
html.replace(F("{DEVICE}"), mSysCfg->deviceName);
@ -73,35 +72,46 @@ void web::showIndex(void) {
html.replace(F("{TS}"), String(mConfig->sendInterval) + " ");
html.replace(F("{JS_TS}"), String(mConfig->sendInterval * 1000));
html.replace(F("{BUILD}"), String(AUTO_GIT_HASH));
mWeb->send(200, "text/html", html);
request->send(200, "text/html", html);
}
//-----------------------------------------------------------------------------
void web::showCss(void) {
mWeb->send(200, "text/css", FPSTR(style_css));
void web::showCss(AsyncWebServerRequest *request) {
request->send(200, "text/css", FPSTR(style_css));
}
//-----------------------------------------------------------------------------
void web::showFavicon(void) {
void web::showFavicon(AsyncWebServerRequest *request) {
static const char favicon_type[] PROGMEM = "image/x-icon";
static const char favicon_content[] PROGMEM = FAVICON_PANEL_16;
mWeb->send_P(200, favicon_type, favicon_content, sizeof(favicon_content));
AsyncWebServerResponse *response = request->beginResponse_P(200, favicon_type, favicon_ico_gz, favicon_ico_gz_len);
response->addHeader(F("Content-Encoding"), "gzip");
request->send(response);
}
//-----------------------------------------------------------------------------
void web::showNotFound(void) {
DPRINTLN(DBG_VERBOSE, F("showNotFound - ") + mWeb->uri());
String msg = F("File Not Found\n\nURI: ");
msg += mWeb->uri();
mWeb->send(404, F("text/plain"), msg);
void web::showNotFound(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("showNotFound - ") + request->url());
String msg = F("File Not Found\n\nURL: ");
msg += request->url();
msg += F("\nMethod: ");
msg += ( request->method() == HTTP_GET ) ? "GET" : "POST";
msg += F("\nArguments: ");
msg += request->args();
msg += "\n";
for(uint8_t i = 0; i < request->args(); i++ ) {
msg += " " + request->argName(i) + ": " + request->arg(i) + "\n";
}
request->send(404, F("text/plain"), msg);
}
//-----------------------------------------------------------------------------
void web::showUptime(void) {
void web::showUptime(AsyncWebServerRequest *request) {
char time[21] = {0};
uint32_t uptime = mMain->getUptime();
@ -112,33 +122,33 @@ void web::showUptime(void) {
snprintf(time, 20, "%d Days, %02d:%02d:%02d", upTimeDy, upTimeHr, upTimeMn, upTimeSc);
mWeb->send(200, "text/plain", String(time) + "; now: " + mMain->getDateTimeStr(mMain->getTimestamp()));
request->send(200, "text/plain", String(time) + "; now: " + mMain->getDateTimeStr(mMain->getTimestamp()));
}
//-----------------------------------------------------------------------------
void web::showReboot(void) {
mWeb->send(200, F("text/html"), F("<!doctype html><html><head><title>Rebooting ...</title><meta http-equiv=\"refresh\" content=\"10; URL=/\"></head><body>rebooting ... auto reload after 10s</body></html>"));
void web::showReboot(AsyncWebServerRequest *request) {
request->send(200, F("text/html"), F("<!doctype html><html><head><title>Rebooting ...</title><meta http-equiv=\"refresh\" content=\"10; URL=/\"></head><body>rebooting ... auto reload after 10s</body></html>"));
delay(1000);
ESP.restart();
}
//-----------------------------------------------------------------------------
void web::showErase() {
void web::showErase(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("showErase"));
mMain->eraseSettings();
showReboot();
showReboot(request);
}
//-----------------------------------------------------------------------------
void web::showFactoryRst(void) {
void web::showFactoryRst(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("showFactoryRst"));
String content = "";
int refresh = 3;
if(mWeb->args() > 0) {
if(mWeb->arg("reset").toInt() == 1) {
if(request->args() > 0) {
if(request->arg("reset").toInt() == 1) {
mMain->eraseSettings(true);
content = F("factory reset: success\n\nrebooting ... ");
refresh = 10;
@ -153,7 +163,7 @@ void web::showFactoryRst(void) {
"<p><a href=\"/factory?reset=1\">RESET</a><br/><br/><a href=\"/factory?reset=0\">CANCEL</a><br/></p>");
refresh = 120;
}
mWeb->send(200, F("text/html"), F("<!doctype html><html><head><title>Factory Reset</title><meta http-equiv=\"refresh\" content=\"") + String(refresh) + F("; URL=/\"></head><body>") + content + F("</body></html>"));
request->send(200, F("text/html"), F("<!doctype html><html><head><title>Factory Reset</title><meta http-equiv=\"refresh\" content=\"") + String(refresh) + F("; URL=/\"></head><body>") + content + F("</body></html>"));
if(refresh == 10) {
delay(1000);
ESP.restart();
@ -162,159 +172,42 @@ void web::showFactoryRst(void) {
//-----------------------------------------------------------------------------
void web::showSetup(void) {
DPRINTLN(DBG_VERBOSE, F("showSetup"));
String html = FPSTR(setup_html);
html.replace(F("{SSID}"), mSysCfg->stationSsid);
// PWD will be left at the default value (for protection)
// -> the PWD will only be changed if it does not match the default "{PWD}"
html.replace(F("{DEVICE}"), String(mSysCfg->deviceName));
html.replace(F("{VERSION}"), String(mVersion));
if(mMain->getWifiApActive())
html.replace("{IP}", String(F("http://192.168.1.1")));
else
html.replace("{IP}", (F("http://") + String(WiFi.localIP().toString())));
String inv = "";
Inverter<> *iv;
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
iv = mMain->mSys->getInverterByPos(i);
inv += F("<p class=\"subdes\">Inverter ") + String(i) + "</p>";
inv += F("<label for=\"inv") + String(i) + F("Addr\">Address*</label>");
inv += F("<input type=\"text\" class=\"text\" name=\"inv") + String(i) + F("Addr\" value=\"");
if(NULL != iv)
inv += String(iv->serial.u64, HEX);
inv += F("\"/ maxlength=\"12\" onkeyup=\"checkSerial()\">");
inv += F("<label for=\"inv") + String(i) + F("Name\">Name*</label>");
inv += F("<input type=\"text\" class=\"text\" name=\"inv") + String(i) + F("Name\" value=\"");
if(NULL != iv)
inv += String(iv->name);
inv += F("\"/ maxlength=\"") + String(MAX_NAME_LENGTH) + "\">";
inv += F("<label for=\"inv") + String(i) + F("ActivePowerLimit\">Active Power Limit</label>");
inv += F("<input type=\"text\" class=\"text\" name=\"inv") + String(i) + F("ActivePowerLimit\" value=\"");
if(NULL != iv)
inv += String(iv->powerLimit[0]);
inv += F("\"/ maxlength=\"") + String(6) + "\">";
void web::showSetup(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("app::showSetup"));
inv += F("<label for=\"inv") + String(i) + F("ActivePowerLimitConType\">Active Power Limit Control Type</label>");
inv += F("<select name=\"inv") + String(i);
// UGLY! But I do not know it a better way
// ToDo: Need Cookies, IndexDB or PWA for that or in general client browser storage
if(NULL != iv){
if(iv->powerLimit[1] == AbsolutNonPersistent)
inv += F("PowerLimitControl\"><option value=\"0\">absolute in Watt non persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
if(iv->powerLimit[1] == RelativNonPersistent)
inv += F("PowerLimitControl\"><option value=\"1\">relativ in percent non persistent</option><option value=\"0\">absolute in Watt non persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
if(iv->powerLimit[1] == AbsolutPersistent)
inv += F("PowerLimitControl\"><option value=\"256\">absolute in Watt persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"0\">absolute in Watt non persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
if(iv->powerLimit[1] == RelativPersistent)
inv += F("PowerLimitControl\"><option value=\"257\">relativ in percent persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"0\">absolute in Watt non persistent</option></select>");
} else
inv += F("PowerLimitControl\"><option value=\"0\">absolute in Watt non persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
// UGLY! But I do not know it a better way --//
inv += F("<label for=\"inv") + String(i) + F("ModPwr0\" name=\"lbl") + String(i);
inv += F("ModPwr\">Max Module Power (Wp)</label><div class=\"modpwr\">");
for(uint8_t j = 0; j < 4; j++) {
inv += F("<input type=\"text\" class=\"text sh\" name=\"inv") + String(i) + F("ModPwr") + String(j) + F("\" value=\"");
if(NULL != iv)
inv += String(iv->chMaxPwr[j]);
inv += F("\"/ maxlength=\"4\">");
}
inv += F("</div><br/><label for=\"inv") + String(i) + F("ModName0\" name=\"lbl") + String(i);
inv += F("ModName\">Module Name</label><div class=\"modname\">");
for(uint8_t j = 0; j < 4; j++) {
inv += F("<input type=\"text\" class=\"text sh\" name=\"inv") + String(i) + F("ModName") + String(j) + F("\" value=\"");
if(NULL != iv)
inv += String(iv->chName[j]);
inv += F("\"/ maxlength=\"") + String(MAX_NAME_LENGTH) + "\">";
}
inv += F("</div>");
}
html.replace(F("{INVERTERS}"), String(inv));
// pinout
String pinout;
for(uint8_t i = 0; i < 3; i++) {
pinout += F("<label for=\"") + String(pinArgNames[i]) + "\">" + String(pinNames[i]) + F("</label>");
pinout += F("<select name=\"") + String(pinArgNames[i]) + "\">";
for(uint8_t j = 0; j <= 16; j++) {
pinout += F("<option value=\"") + String(j) + "\"";
switch(i) {
default: if(j == mConfig->pinCs) pinout += F(" selected"); break;
case 1: if(j == mConfig->pinCe) pinout += F(" selected"); break;
case 2: if(j == mConfig->pinIrq) pinout += F(" selected"); break;
}
pinout += ">" + String(wemosPins[j]) + F("</option>");
}
pinout += F("</select>");
}
html.replace(F("{PINOUT}"), String(pinout));
// nrf24l01+
String rf24;
for(uint8_t i = 0; i <= 3; i++) {
rf24 += F("<option value=\"") + String(i) + "\"";
if(i == mConfig->amplifierPower)
rf24 += F(" selected");
rf24 += ">" + String(rf24AmpPowerNames[i]) + F("</option>");
}
html.replace(F("{RF24}"), String(rf24));
html.replace(F("{INV_INTVL}"), String(mConfig->sendInterval));
html.replace(F("{INV_RETRIES}"), String(mConfig->maxRetransPerPyld));
html.replace(F("{SER_INTVL}"), String(mConfig->serialInterval));
html.replace(F("{SER_VAL_CB}"), (mConfig->serialShowIv) ? "checked" : "");
html.replace(F("{SER_DBG_CB}"), (mConfig->serialDebug) ? "checked" : "");
html.replace(F("{NTP_ADDR}"), String(mConfig->ntpAddr));
html.replace(F("{NTP_PORT}"), String(mConfig->ntpPort));
html.replace(F("{MQTT_ADDR}"), String(mConfig->mqtt.broker));
html.replace(F("{MQTT_PORT}"), String(mConfig->mqtt.port));
html.replace(F("{MQTT_USER}"), String(mConfig->mqtt.user));
html.replace(F("{MQTT_PWD}"), String(mConfig->mqtt.pwd));
html.replace(F("{MQTT_TOPIC}"), String(mConfig->mqtt.topic));
mWeb->send(200, F("text/html"), html);
tmplProc *proc = new tmplProc(request, 11000);
proc->process(setup_html, setup_html_len, std::bind(&web::showSetupCb, this, std::placeholders::_1));
}
//-----------------------------------------------------------------------------
void web::showSave(void) {
void web::showSave(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("showSave"));
if(mWeb->args() > 0) {
if(request->args() > 0) {
char buf[20] = {0};
// general
if(mWeb->arg("ssid") != "")
mWeb->arg("ssid").toCharArray(mSysCfg->stationSsid, SSID_LEN);
if(mWeb->arg("pwd") != "{PWD}")
mWeb->arg("pwd").toCharArray(mSysCfg->stationPwd, PWD_LEN);
if(mWeb->arg("device") != "")
mWeb->arg("device").toCharArray(mSysCfg->deviceName, DEVNAME_LEN);
if(request->arg("ssid") != "")
request->arg("ssid").toCharArray(mSysCfg->stationSsid, SSID_LEN);
if(request->arg("pwd") != "{PWD}")
request->arg("pwd").toCharArray(mSysCfg->stationPwd, PWD_LEN);
if(request->arg("device") != "")
request->arg("device").toCharArray(mSysCfg->deviceName, DEVNAME_LEN);
// inverter
Inverter<> *iv;
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
iv = mMain->mSys->getInverterByPos(i, false);
// address
mWeb->arg("inv" + String(i) + "Addr").toCharArray(buf, 20);
request->arg("inv" + String(i) + "Addr").toCharArray(buf, 20);
if(strlen(buf) == 0)
memset(buf, 0, 20);
iv->serial.u64 = mMain->Serial2u64(buf);
// active power limit
uint16_t actPwrLimit = mWeb->arg("inv" + String(i) + "ActivePowerLimit").toInt();
uint16_t actPwrLimitControl = mWeb->arg("inv" + String(i) + "PowerLimitControl").toInt();
uint16_t actPwrLimit = request->arg("inv" + String(i) + "ActivePowerLimit").toInt();
uint16_t actPwrLimitControl = request->arg("inv" + String(i) + "PowerLimitControl").toInt();
if (actPwrLimit != 0xffff && actPwrLimit > 0){
iv->powerLimit[0] = actPwrLimit;
iv->powerLimit[1] = actPwrLimitControl;
@ -335,24 +228,24 @@ void web::showSave(void) {
}
// name
mWeb->arg("inv" + String(i) + "Name").toCharArray(iv->name, MAX_NAME_LENGTH);
request->arg("inv" + String(i) + "Name").toCharArray(iv->name, MAX_NAME_LENGTH);
// max channel power / name
for(uint8_t j = 0; j < 4; j++) {
iv->chMaxPwr[j] = mWeb->arg("inv" + String(i) + "ModPwr" + String(j)).toInt() & 0xffff;
mWeb->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(iv->chName[j], MAX_NAME_LENGTH);
iv->chMaxPwr[j] = request->arg("inv" + String(i) + "ModPwr" + String(j)).toInt() & 0xffff;
request->arg("inv" + String(i) + "ModName" + String(j)).toCharArray(iv->chName[j], MAX_NAME_LENGTH);
}
iv->initialized = true;
}
if(mWeb->arg("invInterval") != "")
mConfig->sendInterval = mWeb->arg("invInterval").toInt();
if(mWeb->arg("invRetry") != "")
mConfig->maxRetransPerPyld = mWeb->arg("invRetry").toInt();
if(request->arg("invInterval") != "")
mConfig->sendInterval = request->arg("invInterval").toInt();
if(request->arg("invRetry") != "")
mConfig->maxRetransPerPyld = request->arg("invRetry").toInt();
// pinout
uint8_t pin;
for(uint8_t i = 0; i < 3; i ++) {
pin = mWeb->arg(String(pinArgNames[i])).toInt();
pin = request->arg(String(pinArgNames[i])).toInt();
switch(i) {
default: mConfig->pinCs = pin; break;
case 1: mConfig->pinCe = pin; break;
@ -361,86 +254,87 @@ void web::showSave(void) {
}
// nrf24 amplifier power
mConfig->amplifierPower = mWeb->arg("rf24Power").toInt() & 0x03;
mConfig->amplifierPower = request->arg("rf24Power").toInt() & 0x03;
// ntp
if(mWeb->arg("ntpAddr") != "") {
mWeb->arg("ntpAddr").toCharArray(mConfig->ntpAddr, NTP_ADDR_LEN);
mConfig->ntpPort = mWeb->arg("ntpPort").toInt() & 0xffff;
if(request->arg("ntpAddr") != "") {
request->arg("ntpAddr").toCharArray(mConfig->ntpAddr, NTP_ADDR_LEN);
mConfig->ntpPort = request->arg("ntpPort").toInt() & 0xffff;
}
// mqtt
if(mWeb->arg("mqttAddr") != "") {
mWeb->arg("mqttAddr").toCharArray(mConfig->mqtt.broker, MQTT_ADDR_LEN);
mWeb->arg("mqttUser").toCharArray(mConfig->mqtt.user, MQTT_USER_LEN);
mWeb->arg("mqttPwd").toCharArray(mConfig->mqtt.pwd, MQTT_PWD_LEN);
mWeb->arg("mqttTopic").toCharArray(mConfig->mqtt.topic, MQTT_TOPIC_LEN);
mConfig->mqtt.port = mWeb->arg("mqttPort").toInt();
if(request->arg("mqttAddr") != "") {
request->arg("mqttAddr").toCharArray(mConfig->mqtt.broker, MQTT_ADDR_LEN);
request->arg("mqttUser").toCharArray(mConfig->mqtt.user, MQTT_USER_LEN);
request->arg("mqttPwd").toCharArray(mConfig->mqtt.pwd, MQTT_PWD_LEN);
request->arg("mqttTopic").toCharArray(mConfig->mqtt.topic, MQTT_TOPIC_LEN);
mConfig->mqtt.port = request->arg("mqttPort").toInt();
}
// serial console
if(mWeb->arg("serIntvl") != "") {
mConfig->serialInterval = mWeb->arg("serIntvl").toInt() & 0xffff;
if(request->arg("serIntvl") != "") {
mConfig->serialInterval = request->arg("serIntvl").toInt() & 0xffff;
mConfig->serialDebug = (mWeb->arg("serDbg") == "on");
mConfig->serialShowIv = (mWeb->arg("serEn") == "on");
mConfig->serialDebug = (request->arg("serDbg") == "on");
mConfig->serialShowIv = (request->arg("serEn") == "on");
// Needed to log TX buffers to serial console
mMain->mSys->Radio.mSerialDebug = mConfig->serialDebug;
}
mMain->saveValues();
if(mWeb->arg("reboot") == "on")
showReboot();
if(request->arg("reboot") == "on")
showReboot(request);
else
mWeb->send(200, F("text/html"), F("<!doctype html><html><head><title>Setup saved</title><meta http-equiv=\"refresh\" content=\"0; URL=/setup\"></head><body>"
request->send(200, F("text/html"), F("<!doctype html><html><head><title>Setup saved</title><meta http-equiv=\"refresh\" content=\"0; URL=/setup\"></head><body>"
"<p>saved</p></body></html>"));
}
}
//-----------------------------------------------------------------------------
void web::showStatistics(void) {
void web::showStatistics(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("web::showStatistics"));
mWeb->send(200, F("text/plain"), mMain->getStatistics());
request->send(200, F("text/plain"), mMain->getStatistics());
}
//-----------------------------------------------------------------------------
void web::showVisualization(void) {
void web::showVisualization(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("web::showVisualization"));
String html = FPSTR(visualization_html);
html.replace(F("{DEVICE}"), mSysCfg->deviceName);
html.replace(F("{VERSION}"), mVersion);
html.replace(F("{TS}"), String(mConfig->sendInterval) + " ");
html.replace(F("{JS_TS}"), String(mConfig->sendInterval * 1000));
mWeb->send(200, F("text/html"), html);
request->send(200, F("text/html"), html);
}
//-----------------------------------------------------------------------------
void web::showLiveData(void) {
void web::showLiveData(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("web::showLiveData"));
mWeb->send(200, F("text/html"), mMain->getLiveData());
request->send(200, F("text/html"), mMain->getLiveData());
}
//-----------------------------------------------------------------------------
void web::showJson(void) {
void web::showJson(AsyncWebServerRequest *request) {
DPRINTLN(DBG_VERBOSE, F("web::showJson"));
mWeb->send(200, F("application/json"), mMain->getJson());
request->send(200, F("application/json"), mMain->getJson());
}
//-----------------------------------------------------------------------------
void web::showWebApi(void)
void web::showWebApi(AsyncWebServerRequest *request)
{
DPRINTLN(DBG_VERBOSE, F("web::showWebApi"));
DPRINTLN(DBG_DEBUG, mWeb->arg("plain"));
DPRINTLN(DBG_DEBUG, request->arg("plain"));
const size_t capacity = 200; // Use arduinojson.org/assistant to compute the capacity.
DynamicJsonDocument response(capacity);
// Parse JSON object
deserializeJson(response, mWeb->arg("plain"));
deserializeJson(response, request->arg("plain"));
// ToDo: error handling for payload
uint8_t iv_id = response["inverter"];
uint8_t cmd = response["cmd"];
@ -453,7 +347,7 @@ void web::showWebApi(void)
if (cmd == AlarmData){
iv->alarmMesIndex = response["payload"];
}
DPRINTLN(DBG_INFO, F("Will make tx-request 0x15 with subcmd ") + String(cmd) + F(" and payload ") + String(response["payload"]));
//DPRINTLN(DBG_INFO, F("Will make tx-request 0x15 with subcmd ") + String(cmd) + F(" and payload ") + String(response["payload"]));
// process payload from web request corresponding to the cmd
iv->enqueCommand<InfoCommand>(cmd);
}
@ -490,5 +384,201 @@ void web::showWebApi(void)
}
}
}
mWeb->send(200, "text/json", "{success:true}");
request->send(200, "text/json", "{success:true}");
}
//-----------------------------------------------------------------------------
void web::showUpdateForm(AsyncWebServerRequest *request) {
tmplProc *proc = new tmplProc(request, 850);
proc->process(update_html, update_html_len, std::bind(&web::showUpdateFormCb, this, std::placeholders::_1));
}
//-----------------------------------------------------------------------------
void web::showUpdate(AsyncWebServerRequest *request) {
bool reboot = !Update.hasError();
String html = F("<!doctype html><html><head><title>Update</title><meta http-equiv=\"refresh\" content=\"20; URL=/\"></head><body>Update: ");
if(reboot)
html += "success";
else
html += "failed";
html += F("<br/><br/>rebooting ... auto reload after 20s</body></html>");
AsyncWebServerResponse *response = request->beginResponse(200, F("text/html"), html);
response->addHeader("Connection", "close");
request->send(response);
mMain->mShouldReboot = reboot;
}
//-----------------------------------------------------------------------------
void web::showUpdate2(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
if(!index) {
Serial.printf("Update Start: %s\n", filename.c_str());
Update.runAsync(true);
if(!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000)) {
Update.printError(Serial);
}
}
if(!Update.hasError()) {
if(Update.write(data, len) != len){
Update.printError(Serial);
}
}
if(final) {
if(Update.end(true)) {
Serial.printf("Update Success: %uB\n", index+len);
} else {
Update.printError(Serial);
}
}
}
//-----------------------------------------------------------------------------
String web::replaceHtmlGenericKeys(char *key) {
if(0 == strncmp(key, "VERSION", 7)) return mVersion;
else if(0 == strncmp(key, "DEVICE", 6)) return mSysCfg->deviceName;
else if(0 == strncmp(key, "IP", 2)) {
if(mMain->getWifiApActive()) return F("http://192.168.1.1");
else return (F("http://") + String(WiFi.localIP().toString()));
}
return "";
}
//-----------------------------------------------------------------------------
String web::showSetupCb(char* key) {
// PWD will be left at the default value (for protection)
// -> the PWD will only be changed if it does not match the placeholder "{PWD}"
String generic = replaceHtmlGenericKeys(key);
if(generic.length() == 0) {
if(0 == strncmp(key, "SSID", 4)) return mSysCfg->stationSsid;
else if(0 == strncmp(key, "PWD", 3)) return F("{PWD}");
else if(0 == strncmp(key, "INVERTERS", 9)) {
String inv = "";
Inverter<> *iv;
for(uint8_t i = 0; i < MAX_NUM_INVERTERS; i ++) {
iv = mMain->mSys->getInverterByPos(i);
inv += F("<p class=\"subdes\">Inverter ") + String(i) + "</p>";
inv += F("<label for=\"inv") + String(i) + F("Addr\">Address*</label>");
inv += F("<input type=\"text\" class=\"text\" name=\"inv") + String(i) + F("Addr\" value=\"");
if(NULL != iv)
inv += String(iv->serial.u64, HEX);
inv += F("\" maxlength=\"12\">");
inv += F("<label for=\"inv") + String(i) + F("Name\">Name*</label>");
inv += F("<input type=\"text\" class=\"text\" name=\"inv") + String(i) + F("Name\" value=\"");
if(NULL != iv)
inv += String(iv->name);
inv += F("\" maxlength=\"") + String(MAX_NAME_LENGTH) + "\">";
inv += F("<label for=\"inv") + String(i) + F("ActivePowerLimit\">Active Power Limit</label>");
inv += F("<input type=\"text\" class=\"text\" name=\"inv") + String(i) + F("ActivePowerLimit\" value=\"");
if(NULL != iv)
inv += String(iv->powerLimit[0]);
inv += F("\" maxlength=\"") + String(6) + "\">";
inv += F("<label for=\"inv") + String(i) + F("ActivePowerLimitConType\">Active Power Limit Control Type</label>");
inv += F("<select name=\"inv") + String(i);
// UGLY! But I do not know it a better way
// ToDo: Need Cookies, IndexDB or PWA for that or in general client browser storage
if(NULL != iv) {
if(iv->powerLimit[1] == AbsolutNonPersistent)
inv += F("PowerLimitControl\"><option value=\"0\">absolute in Watt non persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
if(iv->powerLimit[1] == RelativNonPersistent)
inv += F("PowerLimitControl\"><option value=\"1\">relativ in percent non persistent</option><option value=\"0\">absolute in Watt non persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
if(iv->powerLimit[1] == AbsolutPersistent)
inv += F("PowerLimitControl\"><option value=\"256\">absolute in Watt persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"0\">absolute in Watt non persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
if(iv->powerLimit[1] == RelativPersistent)
inv += F("PowerLimitControl\"><option value=\"257\">relativ in percent persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"0\">absolute in Watt non persistent</option></select>");
}
else
inv += F("PowerLimitControl\"><option value=\"0\">absolute in Watt non persistent</option><option value=\"1\">relativ in percent non persistent</option><option value=\"256\">absolute in Watt persistent</option><option value=\"257\">relativ in percent persistent</option></select>");
// UGLY! But I do not know it a better way --//
inv += F("<label for=\"inv") + String(i) + F("ModPwr0\" name=\"lbl") + String(i);
inv += F("ModPwr\">Max Module Power (Wp)</label><div class=\"modpwr\">");
for(uint8_t j = 0; j < 4; j++) {
inv += F("<input type=\"text\" class=\"text sh\" name=\"inv") + String(i) + F("ModPwr") + String(j) + F("\" value=\"");
if(NULL != iv)
inv += String(iv->chMaxPwr[j]);
inv += F("\" maxlength=\"4\">");
}
inv += F("</div><br/><label for=\"inv") + String(i) + F("ModName0\" name=\"lbl") + String(i);
inv += F("ModName\">Module Name</label><div class=\"modname\">");
for(uint8_t j = 0; j < 4; j++) {
inv += F("<input type=\"text\" class=\"text sh\" name=\"inv") + String(i) + F("ModName") + String(j) + F("\" value=\"");
if(NULL != iv)
inv += String(iv->chName[j]);
inv += F("\" maxlength=\"") + String(MAX_NAME_LENGTH) + "\">";
}
inv += F("</div>");
}
DPRINTLN(DBG_INFO, inv);
return inv;
}
else if(0 == strncmp(key, "PINOUT", 6)) {
String pinout = "";
for(uint8_t i = 0; i < 3; i++) {
pinout += F("<label for=\"") + String(pinArgNames[i]) + "\">" + String(pinNames[i]) + F("</label>");
pinout += F("<select name=\"") + String(pinArgNames[i]) + "\">";
for(uint8_t j = 0; j <= 16; j++) {
pinout += F("<option value=\"") + String(j) + "\"";
switch(i) {
default: if(j == mConfig->pinCs) pinout += F(" selected"); break;
case 1: if(j == mConfig->pinCe) pinout += F(" selected"); break;
case 2: if(j == mConfig->pinIrq) pinout += F(" selected"); break;
}
pinout += ">" + String(wemosPins[j]) + F("</option>");
}
pinout += F("</select>");
}
return pinout;
}
else if(0 == strncmp(key, "RF24", 4)) {
String rf24 = "";
for(uint8_t i = 0; i <= 3; i++) {
rf24 += F("<option value=\"") + String(i) + "\"";
if(i == mConfig->amplifierPower)
rf24 += F(" selected");
rf24 += ">" + String(rf24AmpPowerNames[i]) + F("</option>");
}
return rf24;
}
else if(0 == strncmp(key, "INV_INTVL", 9)) return String(mConfig->sendInterval);
else if(0 == strncmp(key, "INV_RETRIES", 11)) return String(mConfig->maxRetransPerPyld);
else if(0 == strncmp(key, "SER_INTVL", 9)) return String(mConfig->serialInterval);
else if(0 == strncmp(key, "SER_VAL_CB", 10)) return (mConfig->serialShowIv) ? "checked" : "";
else if(0 == strncmp(key, "SER_DBG_CB", 10)) return (mConfig->serialDebug) ? "checked" : "";
else if(0 == strncmp(key, "NTP_ADDR", 8)) return String(mConfig->ntpAddr);
else if(0 == strncmp(key, "NTP_PORT", 8)) return String(mConfig->ntpPort);
else if(0 == strncmp(key, "MQTT_ADDR", 9)) return String(mConfig->mqtt.broker);
else if(0 == strncmp(key, "MQTT_PORT", 9)) return String(mConfig->mqtt.port);
else if(0 == strncmp(key, "MQTT_USER", 9)) return String(mConfig->mqtt.user);
else if(0 == strncmp(key, "MQTT_PWD", 8)) return String(mConfig->mqtt.pwd);
else if(0 == strncmp(key, "MQTT_TOPIC", 10)) return String(mConfig->mqtt.topic);
//else if(0 == strncmp(key, "MQTT_INTVL", 10)) return String(mMqttInterval);
}
return generic;
}
//-----------------------------------------------------------------------------
String web::showUpdateFormCb(char *key) {
String generic = replaceHtmlGenericKeys(key);
if(generic.length() == 0) {
if(0 == strncmp(key, "CONTENT", 7))
return F("<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>");
else if(0 == strncmp(key, "HEAD", 4))
return "";
}
return generic;
}

59
tools/esp8266/web.h

@ -7,15 +7,10 @@
#define __WEB_H__
#include "dbg.h"
#ifdef ESP8266
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#elif defined(ESP32)
#include <WebServer.h>
#include <HTTPUpdateServer.h>
#endif
#include "ESPAsyncTCP.h"
#include "ESPAsyncWebServer.h"
#include "app.h"
#include "tmplProc.h"
class app;
@ -27,31 +22,33 @@ class web {
void setup(void);
void loop(void);
void showIndex(void);
void showCss(void);
void showFavicon(void);
void showNotFound(void);
void showUptime(void);
void showReboot(void);
void showErase();
void showFactoryRst(void);
void showSetup(void);
void showSave(void);
void showStatistics(void);
void showVisualization(void);
void showLiveData(void);
void showJson(void);
void showWebApi(void);
void showIndex(AsyncWebServerRequest *request);
void showCss(AsyncWebServerRequest *request);
void showFavicon(AsyncWebServerRequest *request);
void showNotFound(AsyncWebServerRequest *request);
void showUptime(AsyncWebServerRequest *request);
void showReboot(AsyncWebServerRequest *request);
void showErase(AsyncWebServerRequest *request);
void showFactoryRst(AsyncWebServerRequest *request);
void showSetup(AsyncWebServerRequest *request);
void showSave(AsyncWebServerRequest *request);
void showStatistics(AsyncWebServerRequest *request);
void showVisualization(AsyncWebServerRequest *request);
void showLiveData(AsyncWebServerRequest *request);
void showJson(AsyncWebServerRequest *request);
void showWebApi(AsyncWebServerRequest *request);
void showUpdateForm(AsyncWebServerRequest *request);
void showUpdate(AsyncWebServerRequest *request);
void showUpdate2(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final);
private:
#ifdef ESP8266
ESP8266WebServer *mWeb;
ESP8266HTTPUpdateServer *mUpdater;
#elif defined(ESP32)
WebServer *mWeb;
HTTPUpdateServer *mUpdater;
#endif
String replaceHtmlGenericKeys(char *key);
String showSetupCb(char* key);
String showUpdateFormCb(char* key);
AsyncWebServer *mWeb;
config_t *mConfig;
sysConfig_t *mSysCfg;

Loading…
Cancel
Save