From aa484575b8a507ba09b7ab7b6e3c3b35ea53c113 Mon Sep 17 00:00:00 2001 From: Nic Limper Date: Thu, 28 Sep 2023 11:40:29 +0200 Subject: [PATCH] update update screen to new design; ability to choose repo source for OTA --- ESP32_AP-Flasher/data/www/index.html.gz | Bin 4604 -> 4748 bytes ESP32_AP-Flasher/data/www/main.css.gz | Bin 3191 -> 3298 bytes ESP32_AP-Flasher/data/www/main.js.gz | Bin 10774 -> 10775 bytes ESP32_AP-Flasher/data/www/ota.js.gz | Bin 4203 -> 4853 bytes ESP32_AP-Flasher/include/tag_db.h | 3 +- ESP32_AP-Flasher/src/espflasher.cpp | 6 +- ESP32_AP-Flasher/src/flasher.cpp | 4 - ESP32_AP-Flasher/src/tag_db.cpp | 7 + ESP32_AP-Flasher/src/web.cpp | 82 +-- ESP32_AP-Flasher/wwwroot/index.html | 758 ++++++++++++------------ ESP32_AP-Flasher/wwwroot/main.css | 62 +- ESP32_AP-Flasher/wwwroot/main.js | 13 +- ESP32_AP-Flasher/wwwroot/ota.js | 119 +++- 13 files changed, 600 insertions(+), 454 deletions(-) diff --git a/ESP32_AP-Flasher/data/www/index.html.gz b/ESP32_AP-Flasher/data/www/index.html.gz index be72d2d9a6444ed3e08a8a9d1fcf85c20f807743..ae4cc3cc3ced410c299bd55b700a1b62b963e05c 100644 GIT binary patch literal 4748 zcmV;75_9bziwFn+00002|7mVyWq2-VbZu+^PkWs?i7=W)QCKBkWBPRNxGacB5LKgPNE~F|&Yg&S zi|Vrf8FFWs3lg2j(WH9pWLN?`C+E%+C5w>p$m+YGUNk%R$P;x*RlQUY4QNEMUllI) z$$7Ja=J*?($MdWq7KE!eJcfpbgX)U)y-q|UpLB0R5}?5?4hctBGOw*qff~7u@L8u&!)hAfo=g_cMPz8P$=}%UgvMsDvIz}plUT~vIxMJsx%Bx zJmHQ3ScQ<96JQZq>Z;IESDBI8K^~59HNt!fX6VeAG`}&7jvVuI=MszAm|^ZYUHK{F z_ql{3JhkbJ@KiWmL45zmk-(u%!B#tva)H!C#1@1nq;hmY@y`>F%tIewb26GXpg!ho zAxMsLI>OHr8th?0bE+MZD58N@uYTGn@pFiRrP~y**mMeXoUU{M4+81O?T8Quh-WG!Ib#r@6BdofB&pgmjGR~2Iq8rhCN`` zK&)fN#=+EyN5R*nBGU+Doq%^UN}EuhjN>R`!49=`C(H*|@xZ_-bn19r50*oy8;_t} zj`A<^%^IiN++X!R3mSNAk$lmgq~Pfc&j#BpE{O-}$nhtsVMH9U!1by72+o&8uc;5x z^#X4=V~dwBUi_Lm9su(EiGd5N!77x38%21PLw@eGEFxwpr2=_jJR#8qv;CA~ghM_Ma+<2xYz~1F7d%m?COmck9Sj?vq$pbjoXj!Zq!-(=<<#cqb zdla(rTow6jF~(8!Tos*=lUA#3@g^VI6mcD()($uwJ;)DP?RFC@Kpe>ef=0EUo$FFo{FA zuZFq6XsXxZEZCm4yZxAR=-@ArHc=$~FRa?_Tx_L+4)uMaEIWx}Iwoi+9F%O0l59hW z-&rk zR`R{CA9k{}mVM;;6^uvUZF)lOnHWJJn#00KV4e%?PeXNk^5@5>HpkE$yM`V4ls7%q za*f@eKvoSXIGIQg5*P;3*KMlE0IuK($;Y3?S^&vn9C|V-Grj^Ewlbzaet>_G?(`gE z(+;t;Aj*8k>{}v>ap;LOK67z0W%Tn_?dq@U=eyNfzzrvJma5deY~v^StbczNM@cAW zcuHTlag_ncu**ZRBK|Da!X(yLoF#AD7)!sKho8lj$qZ7H(r??1%6zwC`O=ePW4r+C zA!Njn6(s5R&3i{vS8f-k!Ijzca&me|cQ7DyqI0QX7Y9#RSXgxPng+8t$=&tYxbPkQ zRTQuTfD@O1(RsUI?3H^5nB`@+!bpFn%zzex87H}uFK+J$=RX=_HJk8ea})(+f#wjX z<0(N@parIKt5B{=D4MB|7DWt&kWGNUwJ`7fqIYC4=WN00bQYcE`O0rfVIHi~9?gKB z#6N@a4;ZZapenV}DC!vb3>cA9U+(9f93LN_Ww`SyC}Gu`vw&m+vt$-9Ud;kjAP*L+ zkST2dM#x{ds~5LZeatbXld~}vXY`# z+m8+JY22#6{dVk)?wU7ObU)@_59gofpF{X(Qm@w+z5IXuw+9zJz}8#zu5`=qy$kvC z@#68?fB*HU`H6?^&;NYn`}g<#Pr=RS;q>=EmV@h0i}(Gn&EV~fv>IQh{T}Nb{eHFV zeY!gez6|!?-~RFH&zs?6e{eT^J)V#LxV;U>U!JBTK!3A1Ki3*qF-D`0jUG;FNI**O zk#RgtU0gFC2W0?Vnf@c}`)EPNfOl+R)*P4x!+F|YRuu~5= z!X*LiEqbKV%LF;V{A^V_r?d`MAXof}r9!cIf=rv{cBCf+lqtQWV3P=38$kvpw{skRmq*GSAZ@j{d&VCT z4N%D0l!L(~gg4`~&V~wXI6Epsx|6k?(a8j|W-MrRGTo6l8E;?=JOQcKW~-oTHkp*sVzcp|MPP^fQjLXR&DODH5eLP1n0O?8$rCE+N9MTU70?!uY~v8UNe5J>uR z@-56x177;{5mt41Y($Vp1^DLWuQjA%S97cmD-&_)gc7~WE!i-2IEJaF0k;9T-6)It zP@+cinD0C6;@t$LhdMHSkz*pmNE(p}@>uX9GD8FF5661xywXZV3kosk7{;7Kz~UjT zH3r7KbqGUFp1|l7MisY$!UJRm33)M>Mv^S2yT&z-XzSp1gW~ncvVi5fvUjM^KqNIJ z5er2&J0cWFe+|7hux7no?M^6&{-vKVr4@aUk}ISyni{4ABSE85S1#xZ0Zvi<~# zrGUV3B}U$0ra;r_-sXrGo22UWeTG)bcuOem9{ekUsTznmjUc;P*hzR^%msiN0M$!9 z?-tVPvW4%XW0`Q(4v=>-FOu=-P{B4z!9qCFJT8a#Q1Wn84zKc_2jyT7S~4pu2fHu% zZI**=?_0J}Qbq{7x+O)F0bfZ80cmS9WC_#z1WOQ7JN3#hp+D6jyJ%s{4j&w+B8h5Eb->6XF&le{(&0)p!TE zna6JI&(AIkY#;tLu)(h7P_gHrhK0e|CuP?GyAD#i@BzlG2t zp2{I~EBFPcvUt$iGbyX8gj74F0p8%ZC4H)(yGJey64xhUJu&3% zrhPZ;p*rfrBIn`l2L85pFQd)3c!4QJrL42}+i-N!`|WZhcP6lS#O1o(4oAngvePY= zVZB?f*Y$98bS-;b%Y80TM)_{Q9;Yz>aYd#gm%~wEul{g!*q6kT`CD$b4o3$A*=v9y zTHsqaEHh-iSVZcy90u+KL=v9~mb1dyMY`H-0P$+Gxn`lO6A*Mr{4u!Q0D{Hg(hJD4 zc)kGvaPzl>N3$}Ds7hmksUXHUAZ7GjJvnVR`ci-fJd}{3=Yc1J0Jk)9aAKG*Xi$=U zOPS4`jJ#!I%%eiAA3jU8tq-3iUYO!1wf!90eN84sYmNK&*^r<+ru%!T6sJ34k4siO z`0p;NFpJ*fM-UX3a-IT}n*mzs$#mERJTVHz%CBJ2ZRoaX5O_zW8_vN>J7Vp9YK8do%edkHk>twjKIoMUToh_G_H0nO{n=2(Jk}knwxutw!whwbMWP(Oa z*2}=_mIG3|Tn{=ps#|&nZF?SdtYzjt0H&p|7BVx7)Stlt_*m69eX z?{zsvS}1KcrcX_kZLa3RJ~ACKby^1VNo|T!fp{u<#bkxb{V2=kb2Zh*G4(w}f+xyZ zFo%JvS-C^FSwR*wgqzt*fx7H&z#4|M1w7zx^%+)&wib1hrA7-J2QKk*(5hvnetPXl zSec0rcBG7Pf8E5m{;CSkHyPOt=#r~Saqtzp?95WBg`N4n^y9jCd-K3|cdS9C`$Z&| zAoHRMd*uEei-lcHX69a|zLmP3+@R;UO;=O*&@j457Bf>*kfJ4}f2i2ju0VVKYX2}> zA~qMCSQ72+WxJK81lVwytc6Y&C68+3UPQ@}{)+JHB?fjy#m>@Gt9VQ>pV$&6P2Ccu z0@<^=Bba{ZOdw1E3(GDcOD*Utg^5pAtp5^>MR;b*k&T;J3K~pUE(kIbcIujdp(d|w zs{0oDZXyPHR;@us+7{erf{de}rS4}o8jVA%WDLB%?hjFzEb(iY|5DGN3SqgKU8M(B z;lcK@gJkr!Am3SUZ*SsRu=0A2^08@|V6xkmUdPEtvbJ{$F~oF9MAD(%UZ+l_vRcRO z6R9oBN2RQ%RUVL(vpGv{cUY=TD~!A+>Fc}%Ch;OOB9AamQ6v0zmarH?0;{2u_$FK0 z(+DT8Ezb1K+K=j2A1~xLK37zhbVw%2+F3yZd1T7T+PT7t0*e^)V;I7#yU|W&6wp>q zHWY*`IOd>_}(%8ymSAxevocXb0^bRr>( zyyfq1Z~@Dt)0O}3hVuvs&2goCOb)Mibpa8H;sSn>BXm(j#V4|q-J}Y#N?j#ybe>+* z`TtOIsj4k)J*6%no9a47l*#QFC&yXZ?U&1qv&?wo`XIeC5$vFZp?hMK5%c`Pckn6uRqH93qlW;i=BW+RYkDGi^?o>DH aKLJuVe*;AQVG#KTVg45g8-DXBMgRbM)h*8e literal 4604 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 diff --git a/ESP32_AP-Flasher/data/www/main.css.gz b/ESP32_AP-Flasher/data/www/main.css.gz index 9f1639be04f3139e32aa4e3bc1426ec3c5726fab..098183c137e6802a627f38ec04d6db4ea27b464d 100644 GIT binary patch literal 3298 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 delta 9027 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 diff --git a/ESP32_AP-Flasher/data/www/ota.js.gz b/ESP32_AP-Flasher/data/www/ota.js.gz index 39e25f469a73cad9b43c4df157d5e2b7e815c94c..ed81cfbf1ec2554ecff9207d8e02dfc44e551a83 100644 GIT binary patch literal 4853 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 bNaPc#m9TX``CZTM;sdp$5;RWP?(yM literal 4203 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 B98~}S diff --git a/ESP32_AP-Flasher/include/tag_db.h b/ESP32_AP-Flasher/include/tag_db.h index c7653cab..7534b741 100644 --- a/ESP32_AP-Flasher/include/tag_db.h +++ b/ESP32_AP-Flasher/include/tag_db.h @@ -71,6 +71,8 @@ struct Config { char timeZone[52]; uint8_t sleepTime1; uint8_t sleepTime2; + String repo; + String env; }; struct HwType { @@ -90,7 +92,6 @@ extern Config config; extern std::vector tagDB; extern std::unordered_map hwtype; extern std::unordered_map varDB; -extern DynamicJsonDocument APconfig; extern String tagDBtoJson(const uint8_t mac[8] = nullptr, uint8_t startPos = 0); extern bool deleteRecord(const uint8_t mac[8]); extern void fillNode(JsonObject& tag, const tagRecord* taginfo); diff --git a/ESP32_AP-Flasher/src/espflasher.cpp b/ESP32_AP-Flasher/src/espflasher.cpp index db19d9d0..15fe7f72 100644 --- a/ESP32_AP-Flasher/src/espflasher.cpp +++ b/ESP32_AP-Flasher/src/espflasher.cpp @@ -7,6 +7,7 @@ #include "esp32_port.h" #include "esp_littlefs.h" #include "storage.h" +#include "tag_db.h" #include "web.h" esp_loader_error_t connect_to_target(uint32_t higher_transmission_rate) { @@ -163,8 +164,7 @@ bool downloadAndWriteBinary(String &filename, const char *url) { } bool doC6flash(uint8_t doDownload) { - const char *githubUrl = "https://raw.githubusercontent.com/jjwbruijn/OpenEPaperLink/master/binaries/ESP32-C6/firmware.json"; - + const String githubUrl = "https://raw.githubusercontent.com/" + config.repo + "/master/binaries/ESP32-C6/firmware.json"; HTTPClient http; Serial.println(githubUrl); http.begin(githubUrl); @@ -181,7 +181,7 @@ bool doC6flash(uint8_t doDownload) { JsonArray jsonArray = jsonDoc.as(); for (JsonObject obj : jsonArray) { String filename = "/" + obj["filename"].as(); - String binaryUrl = "https://raw.githubusercontent.com/jjwbruijn/OpenEPaperLink/master/binaries/ESP32-C6" + String(filename); + String binaryUrl = "https://raw.githubusercontent.com/" + config.repo + "/master/binaries/ESP32-C6" + String(filename); for (int retry = 0; retry < 10; retry++) { if (downloadAndWriteBinary(filename, binaryUrl.c_str())) { break; diff --git a/ESP32_AP-Flasher/src/flasher.cpp b/ESP32_AP-Flasher/src/flasher.cpp index 1c99dd96..6c88c5d4 100644 --- a/ESP32_AP-Flasher/src/flasher.cpp +++ b/ESP32_AP-Flasher/src/flasher.cpp @@ -176,7 +176,6 @@ bool flasher::getInfoBlockType() { bool flasher::findTagByMD5() { DynamicJsonDocument doc(3000); - DynamicJsonDocument APconfig(600); fs::File readfile = contentFS->open("/tag_md5_db.json", "r"); DeserializationError err = deserializeJson(doc, readfile); if (!err) { @@ -206,7 +205,6 @@ bool flasher::findTagByMD5() { bool flasher::findTagByType(uint8_t type) { DynamicJsonDocument doc(3000); - DynamicJsonDocument APconfig(600); fs::File readfile = contentFS->open("/tag_md5_db.json", "r"); DeserializationError err = deserializeJson(doc, readfile); if (!err) { @@ -446,7 +444,6 @@ bool flasher::writeFlashFromPackOffset(fs::File *file, uint16_t length) { bool flasher::writeFlashFromPack(String filename, uint8_t type) { StaticJsonDocument<512> doc; - DynamicJsonDocument APconfig(512); fs::File readfile = contentFS->open(filename, "r"); DeserializationError err = deserializeJson(doc, readfile); if (!err) { @@ -505,7 +502,6 @@ bool flasher::writeBlock(uint16_t offset, uint8_t *data, uint16_t len, bool info uint16_t getAPUpdateVersion(uint8_t type) { StaticJsonDocument<512> doc; - DynamicJsonDocument APconfig(512); fs::File readfile = contentFS->open("/AP_FW_Pack.bin", "r"); DeserializationError err = deserializeJson(doc, readfile); if (!err) { diff --git a/ESP32_AP-Flasher/src/tag_db.cpp b/ESP32_AP-Flasher/src/tag_db.cpp index 2ce32340..a510c099 100644 --- a/ESP32_AP-Flasher/src/tag_db.cpp +++ b/ESP32_AP-Flasher/src/tag_db.cpp @@ -11,6 +11,9 @@ #include "storage.h" #include "util.h" +#define STR_IMPL(x) #x +#define STR(x) STR_IMPL(x) + std::vector tagDB; std::unordered_map varDB; std::unordered_map hwdata = { @@ -309,6 +312,8 @@ void initAPconfig() { // default wifi power 8.5 dbM // see https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiGeneric.h#L111 config.wifiPower = APconfig["wifipower"] | 34; + config.repo = APconfig["repo"] | "jjwbruijn/OpenEPaperLink"; + config.env = APconfig["env"] | STR(BUILD_ENV_NAME); if (APconfig["timezone"]) { strlcpy(config.timeZone, APconfig["timezone"], sizeof(config.timeZone)); } else { @@ -331,6 +336,8 @@ void saveAPconfig() { APconfig["timezone"] = config.timeZone; APconfig["sleeptime1"] = config.sleepTime1; APconfig["sleeptime2"] = config.sleepTime2; + APconfig["repo"] = config.repo; + APconfig["env"] = config.env; serializeJsonPretty(APconfig, configFile); configFile.close(); xSemaphoreGive(fsMutex); diff --git a/ESP32_AP-Flasher/src/web.cpp b/ESP32_AP-Flasher/src/web.cpp index f4d6504a..98bd878c 100644 --- a/ESP32_AP-Flasher/src/web.cpp +++ b/ESP32_AP-Flasher/src/web.cpp @@ -26,8 +26,6 @@ extern uint8_t data_to_send[]; -// const char *http_username = "admin"; -// const char *http_password = "admin"; AsyncWebServer server(80); AsyncWebSocket ws("/ws"); WifiManager wm; @@ -189,7 +187,6 @@ void init_web() { wm.connectToWifi(); - // server.addHandler(new SPIFFSEditor(*contentFS, http_username, http_password)); server.addHandler(new SPIFFSEditor(*contentFS)); server.addHandler(&ws); @@ -424,48 +421,55 @@ void init_web() { }); server.on("/save_apcfg", HTTP_POST, [](AsyncWebServerRequest *request) { - if (request->hasParam("alias", true) && request->hasParam("channel", true)) { + if (request->hasParam("alias", true)) { String aliasValue = request->getParam("alias", true)->value(); size_t aliasLength = aliasValue.length(); if (aliasLength > 31) aliasLength = 31; aliasValue.toCharArray(config.alias, aliasLength + 1); config.alias[aliasLength] = '\0'; - - config.channel = static_cast(request->getParam("channel", true)->value().toInt()); - if (request->hasParam("led", true)) { - config.led = static_cast(request->getParam("led", true)->value().toInt()); - updateBrightnessFromConfig(); - } - if (request->hasParam("language", true)) { - config.language = static_cast(request->getParam("language", true)->value().toInt()); - updateLanguageFromConfig(); - } - if (request->hasParam("maxsleep", true)) { - config.maxsleep = static_cast(request->getParam("maxsleep", true)->value().toInt()); - } - if (request->hasParam("stopsleep", true)) { - config.stopsleep = static_cast(request->getParam("stopsleep", true)->value().toInt()); - } - if (request->hasParam("preview", true)) { - config.preview = static_cast(request->getParam("preview", true)->value().toInt()); - } - if (request->hasParam("sleeptime1", true)) { - config.sleepTime1 = static_cast(request->getParam("sleeptime1", true)->value().toInt()); - config.sleepTime2 = static_cast(request->getParam("sleeptime2", true)->value().toInt()); - } - if (request->hasParam("wifipower", true)) { - config.wifiPower = static_cast(request->getParam("wifipower", true)->value().toInt()); - WiFi.setTxPower(static_cast(config.wifiPower)); - } - if (request->hasParam("timezone", true)) { - strncpy(config.timeZone, request->getParam("timezone", true)->value().c_str(), sizeof(config.timeZone) - 1); - config.timeZone[sizeof(config.timeZone) - 1] = '\0'; - setenv("TZ", config.timeZone, 1); - tzset(); - } - saveAPconfig(); - setAPchannel(); } + if (request->hasParam("channel", true)) { + config.channel = static_cast(request->getParam("channel", true)->value().toInt()); + } + if (request->hasParam("led", true)) { + config.led = static_cast(request->getParam("led", true)->value().toInt()); + updateBrightnessFromConfig(); + } + if (request->hasParam("language", true)) { + config.language = static_cast(request->getParam("language", true)->value().toInt()); + updateLanguageFromConfig(); + } + if (request->hasParam("maxsleep", true)) { + config.maxsleep = static_cast(request->getParam("maxsleep", true)->value().toInt()); + } + if (request->hasParam("stopsleep", true)) { + config.stopsleep = static_cast(request->getParam("stopsleep", true)->value().toInt()); + } + if (request->hasParam("preview", true)) { + config.preview = static_cast(request->getParam("preview", true)->value().toInt()); + } + if (request->hasParam("sleeptime1", true)) { + config.sleepTime1 = static_cast(request->getParam("sleeptime1", true)->value().toInt()); + config.sleepTime2 = static_cast(request->getParam("sleeptime2", true)->value().toInt()); + } + if (request->hasParam("wifipower", true)) { + config.wifiPower = static_cast(request->getParam("wifipower", true)->value().toInt()); + WiFi.setTxPower(static_cast(config.wifiPower)); + } + if (request->hasParam("timezone", true)) { + strncpy(config.timeZone, request->getParam("timezone", true)->value().c_str(), sizeof(config.timeZone) - 1); + config.timeZone[sizeof(config.timeZone) - 1] = '\0'; + setenv("TZ", config.timeZone, 1); + tzset(); + } + if (request->hasParam("repo", true)) { + config.repo = request->getParam("repo", true)->value(); + } + if (request->hasParam("env", true)) { + config.env = request->getParam("env", true)->value(); + } + saveAPconfig(); + setAPchannel(); request->send(200, "text/plain", "Ok, saved"); }); diff --git a/ESP32_AP-Flasher/wwwroot/index.html b/ESP32_AP-Flasher/wwwroot/index.html index 9bd39e77..7116c90a 100644 --- a/ESP32_AP-Flasher/wwwroot/index.html +++ b/ESP32_AP-Flasher/wwwroot/index.html @@ -39,376 +39,409 @@ -
-
+
-
+
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
- check_circle - - initialising... -
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ check_circle + + initialising... +
+ sell + + tags + + 0 +
+ hourglass_empty + + pending data + + 0 +
+ battery_low + + low battery + + 0 +
+ signal_disconnected + + timeout + + 0 +
+
+ +
+
+

Currently active tags

+
+
+
+
+
group by
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
sort by
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
filter
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ↻
+
⚠ +
+
+
+
+
+ +
+
+
+
+
+
    +
+
+ +
+

Active access points

+ +
+
+

194.109.6.66

+

AP kitchen

+
+ sell -
- tags - - 0 -
- hourglass_empty - - pending data - - 0 -
- battery_low - - low battery - - 0 -
- signal_disconnected - - timeout - - 0 -
-
- -
-
-

Currently active tags

-
-
-
-
-
group by
-
- -
-
- -
-
- -
-
- -
-
-
-
sort by
-
- -
-
- -
-
- -
-
- -
-
-
-
filter
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ↻
-
⚠ -
-
+ + 25
+

+ fetching software version... +

+
-
-
-
-
-
-
    -
-
+
+ Work in progress... +
-
-

Active access points

+
+

Access Point config

+

+ + +

+

+ + +

+

+ + +

+

+ + +

+

+ + +

+

+ + +

+

+ + + and + +

+

+ + +

+

+ + +

+

+ + +

+

+ +

+

Manage

+

+ Saves the tagDB and instantly reboots the Access + Point +

+

+ Download tagDB +

+

+ Manage firmware of the ESP32 +

+

+ WiFi config Opens a new window with WiFi + config options +

+

+
+ Github + OpenEPaperLink
+ OpenEPaperLink + Wiki
+

+
-
-
-

194.109.6.66

-

AP kitchen

-
- - sell +
+

Firmware Updates

+
+
+
+

Repository

+
+ +
+ + + +
+

Releases

+
+

Other actions

+
+

+

+

+

+ +

download latest version
- 13 - - cell_tower - - 25 -
-

- fetching software version...

+
- -
- Work in progress... -
- -
-

Access Point config

-

- - -

-

- - -

-

- - -

-

- - -

-

- - -

-

- - -

-

- - - and - -

-

- - -

-

- - -

-

- - -

-

- -

-

Manage

-

- Saves the tagDB and instantly reboots the Access - Point -

-

- Download tagDB -

-

- Manage firmware of the ESP32 -

-

- WiFi config Opens a new window with WiFi - config options -

-

-
- Github - OpenEPaperLink
- OpenEPaperLink - Wiki
-

-
-
-
- + + +