mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-21 03:04:25 +01:00
update update screen to new design; ability to choose repo source for OTA
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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<tagRecord*> tagDB;
|
||||
extern std::unordered_map<int, HwType> hwtype;
|
||||
extern std::unordered_map<std::string, varStruct> 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);
|
||||
|
||||
@@ -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<JsonArray>();
|
||||
for (JsonObject obj : jsonArray) {
|
||||
String filename = "/" + obj["filename"].as<String>();
|
||||
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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#include "storage.h"
|
||||
#include "util.h"
|
||||
|
||||
#define STR_IMPL(x) #x
|
||||
#define STR(x) STR_IMPL(x)
|
||||
|
||||
std::vector<tagRecord*> tagDB;
|
||||
std::unordered_map<std::string, varStruct> varDB;
|
||||
std::unordered_map<int, HwType> 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);
|
||||
|
||||
@@ -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<uint8_t>(request->getParam("channel", true)->value().toInt());
|
||||
if (request->hasParam("led", true)) {
|
||||
config.led = static_cast<int16_t>(request->getParam("led", true)->value().toInt());
|
||||
updateBrightnessFromConfig();
|
||||
}
|
||||
if (request->hasParam("language", true)) {
|
||||
config.language = static_cast<uint8_t>(request->getParam("language", true)->value().toInt());
|
||||
updateLanguageFromConfig();
|
||||
}
|
||||
if (request->hasParam("maxsleep", true)) {
|
||||
config.maxsleep = static_cast<uint8_t>(request->getParam("maxsleep", true)->value().toInt());
|
||||
}
|
||||
if (request->hasParam("stopsleep", true)) {
|
||||
config.stopsleep = static_cast<uint8_t>(request->getParam("stopsleep", true)->value().toInt());
|
||||
}
|
||||
if (request->hasParam("preview", true)) {
|
||||
config.preview = static_cast<uint8_t>(request->getParam("preview", true)->value().toInt());
|
||||
}
|
||||
if (request->hasParam("sleeptime1", true)) {
|
||||
config.sleepTime1 = static_cast<uint8_t>(request->getParam("sleeptime1", true)->value().toInt());
|
||||
config.sleepTime2 = static_cast<uint8_t>(request->getParam("sleeptime2", true)->value().toInt());
|
||||
}
|
||||
if (request->hasParam("wifipower", true)) {
|
||||
config.wifiPower = static_cast<uint8_t>(request->getParam("wifipower", true)->value().toInt());
|
||||
WiFi.setTxPower(static_cast<wifi_power_t>(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<uint8_t>(request->getParam("channel", true)->value().toInt());
|
||||
}
|
||||
if (request->hasParam("led", true)) {
|
||||
config.led = static_cast<int16_t>(request->getParam("led", true)->value().toInt());
|
||||
updateBrightnessFromConfig();
|
||||
}
|
||||
if (request->hasParam("language", true)) {
|
||||
config.language = static_cast<uint8_t>(request->getParam("language", true)->value().toInt());
|
||||
updateLanguageFromConfig();
|
||||
}
|
||||
if (request->hasParam("maxsleep", true)) {
|
||||
config.maxsleep = static_cast<uint8_t>(request->getParam("maxsleep", true)->value().toInt());
|
||||
}
|
||||
if (request->hasParam("stopsleep", true)) {
|
||||
config.stopsleep = static_cast<uint8_t>(request->getParam("stopsleep", true)->value().toInt());
|
||||
}
|
||||
if (request->hasParam("preview", true)) {
|
||||
config.preview = static_cast<uint8_t>(request->getParam("preview", true)->value().toInt());
|
||||
}
|
||||
if (request->hasParam("sleeptime1", true)) {
|
||||
config.sleepTime1 = static_cast<uint8_t>(request->getParam("sleeptime1", true)->value().toInt());
|
||||
config.sleepTime2 = static_cast<uint8_t>(request->getParam("sleeptime2", true)->value().toInt());
|
||||
}
|
||||
if (request->hasParam("wifipower", true)) {
|
||||
config.wifiPower = static_cast<uint8_t>(request->getParam("wifipower", true)->value().toInt());
|
||||
WiFi.setTxPower(static_cast<wifi_power_t>(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");
|
||||
});
|
||||
|
||||
|
||||
@@ -39,376 +39,409 @@
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<form>
|
||||
<div class="container">
|
||||
<div class="container">
|
||||
|
||||
<div class="window">
|
||||
<div class="window">
|
||||
|
||||
<div id="hometab" class="tabcontent">
|
||||
<table>
|
||||
<tr onclick="setFilterAndShow('')">
|
||||
<td class="material-symbols-outlined" style="color:#239f26" id="dashboardStatusIcon">
|
||||
check_circle
|
||||
</td>
|
||||
<td id="dashboardStatus" style="color:#239f26" colspan="2">
|
||||
initialising...
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('')">
|
||||
<td class="material-symbols-outlined" style="color:#77239e">
|
||||
<div id="hometab" class="tabcontent">
|
||||
<table>
|
||||
<tr onclick="setFilterAndShow('')">
|
||||
<td class="material-symbols-outlined" style="color:#239f26" id="dashboardStatusIcon">
|
||||
check_circle
|
||||
</td>
|
||||
<td id="dashboardStatus" style="color:#239f26" colspan="2">
|
||||
initialising...
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('')">
|
||||
<td class="material-symbols-outlined" style="color:#77239e">
|
||||
sell
|
||||
</td>
|
||||
<td>
|
||||
tags
|
||||
</td>
|
||||
<td id="dashboardTagCount" style="color:#77239e">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('pending')">
|
||||
<td class="material-symbols-outlined" style="color:#235f9e">
|
||||
hourglass_empty
|
||||
</td>
|
||||
<td>
|
||||
pending data
|
||||
</td>
|
||||
<td id="dashboardPending" style="color:#235f9e">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('lowbatt')">
|
||||
<td class="material-symbols-outlined" style="color:#9e9223">
|
||||
battery_low
|
||||
</td>
|
||||
<td>
|
||||
low battery
|
||||
</td>
|
||||
<td id="dashboardLowBatt" style="color:#9e9223">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('inactive')">
|
||||
<td class="material-symbols-outlined" style="color:#9e2323">
|
||||
signal_disconnected
|
||||
</td>
|
||||
<td>
|
||||
timeout
|
||||
</td>
|
||||
<td id="dashboardTimeout" style="color:#9e2323">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr onclick="$(`[data-target='aptab']`).click()">
|
||||
<td class="material-symbols-outlined" style="color:#239f26">
|
||||
cell_tower
|
||||
</td>
|
||||
<td>
|
||||
access points
|
||||
</td>
|
||||
<td id="dashboardApCount" style="color:#239f26">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
-->
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="tagtab" class="tabcontent">
|
||||
<div class="tagheader">
|
||||
<h3>Currently active tags</h3>
|
||||
<div id="activefilter"></div><button class="material-symbols-outlined"
|
||||
id="toggleFilters">filter_alt</button>
|
||||
</div>
|
||||
<div id="filterOptions">
|
||||
<div>
|
||||
<div>group by</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="" id="rnone" checked><label
|
||||
for="rnone">None</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="model" id="rtagtype"><label for="rtagtype">Tag
|
||||
model</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="contentmode" id="rcontent"><label
|
||||
for="rcontent">Content</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="data-channel" id="rchannel"><label
|
||||
for="rchannel">Channel</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>sort by</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="alias" id="ralias" checked><label
|
||||
for="ralias">Alias</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="mac" id="rmac"><label for="rmac">Mac</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="data-lastseen" id="rlastseen"><label
|
||||
for="rlastseen">Last seen</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="data-nextupdate" id="rnext"><label
|
||||
for="rnext">Next update</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>filter</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="local" id="rlocal"><label
|
||||
for="rlocal">local</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="remote" id="rremote"><label
|
||||
for="rremote">remote</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="inactive" id="rinactive"><label
|
||||
for="rinactive">timed out</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="pending" id="rpending"><label
|
||||
for="rpending">pending</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="lowbatt" id="rlowbatt"><label
|
||||
for="rlowbatt">low battery</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="taglist" class="taglist">
|
||||
<div class="tagcard" id="tagtemplate">
|
||||
<div class="currimg"><canvas class="tagimg"></div>
|
||||
<div class="mac"></div>
|
||||
<div class="alias"></div>
|
||||
<div class="model"></div>
|
||||
<div class="received"></div>
|
||||
<div class="contentmode"></div>
|
||||
<div class="lastseen"></div>
|
||||
<div class="nextcheckin"></div>
|
||||
<div class="nextupdate"></div>
|
||||
<div class="corner">
|
||||
<div class="pendingicon" title="A new message is waiting for the tag to pick up">
|
||||
↻</div>
|
||||
<div class="warningicon" title="This tag has not been seen for a long time">⚠
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="logtab" class="tabcontent">
|
||||
<div class="tabheader">
|
||||
<div><img id="clearlog" src="data:image/gif;base64,R0lGODlhEAAQAPMAANXV1e3t7d/f39HR0dvb2/Hx8dTU1OLi4urq6mZmZpmZmf///wAAAAAAAAAAAAAAACH5BAEAAAwALAAAAAAQABAAAARBkMlJq71Yrp3ZXkr4WWCYnOZSgQVyEMYwJCq1nHhe20qgCAoA7QLyAYU7njE4JPV+zOSkCEUSFbmTVPPpbjvgTAQAOw==
|
||||
"></div>
|
||||
<div><input type="checkbox" id="showdebug" value="1"><label for="showdebug">Show all websocket
|
||||
traffic</label></div>
|
||||
</div>
|
||||
<ul id="messages" class="messages">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="aptab" class="tabcontent">
|
||||
<h3>Active access points</h3>
|
||||
|
||||
<div id="aplist">
|
||||
<div id="apcard" class="apcard">
|
||||
<p class="apip">194.109.6.66</p>
|
||||
<p class="apalias">AP kitchen</p>
|
||||
<div>
|
||||
<span class="material-symbols-outlined">
|
||||
sell
|
||||
</td>
|
||||
<td>
|
||||
tags
|
||||
</td>
|
||||
<td id="dashboardTagCount" style="color:#77239e">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('pending')">
|
||||
<td class="material-symbols-outlined" style="color:#235f9e">
|
||||
hourglass_empty
|
||||
</td>
|
||||
<td>
|
||||
pending data
|
||||
</td>
|
||||
<td id="dashboardPending" style="color:#235f9e">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('lowbatt')">
|
||||
<td class="material-symbols-outlined" style="color:#9e9223">
|
||||
battery_low
|
||||
</td>
|
||||
<td>
|
||||
low battery
|
||||
</td>
|
||||
<td id="dashboardLowBatt" style="color:#9e9223">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<tr onclick="setFilterAndShow('inactive')">
|
||||
<td class="material-symbols-outlined" style="color:#9e2323">
|
||||
signal_disconnected
|
||||
</td>
|
||||
<td>
|
||||
timeout
|
||||
</td>
|
||||
<td id="dashboardTimeout" style="color:#9e2323">
|
||||
0
|
||||
</td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr onclick="$(`[data-target='aptab']`).click()">
|
||||
<td class="material-symbols-outlined" style="color:#239f26">
|
||||
</span>
|
||||
<span class="aptagcount">13</span>
|
||||
<span class="material-symbols-outlined space">
|
||||
cell_tower
|
||||
</td>
|
||||
<td>
|
||||
access points
|
||||
</td>
|
||||
<td id="dashboardApCount" style="color:#239f26">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
-->
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="tagtab" class="tabcontent">
|
||||
<div class="tagheader">
|
||||
<h3>Currently active tags</h3>
|
||||
<div id="activefilter"></div><button class="material-symbols-outlined"
|
||||
id="toggleFilters">filter_alt</button>
|
||||
</div>
|
||||
<div id="filterOptions">
|
||||
<div>
|
||||
<div>group by</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="" id="rnone" checked><label
|
||||
for="rnone">None</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="model" id="rtagtype"><label for="rtagtype">Tag
|
||||
model</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="contentmode" id="rcontent"><label
|
||||
for="rcontent">Content</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="group" value="data-channel" id="rchannel"><label
|
||||
for="rchannel">Channel</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>sort by</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="alias" id="ralias" checked><label
|
||||
for="ralias">Alias</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="mac" id="rmac"><label for="rmac">Mac</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="data-lastseen" id="rlastseen"><label
|
||||
for="rlastseen">Last seen</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" name="sort" value="data-nextupdate" id="rnext"><label
|
||||
for="rnext">Next update</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>filter</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="local" id="rlocal"><label
|
||||
for="rlocal">local</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="remote" id="rremote"><label
|
||||
for="rremote">remote</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="inactive" id="rinactive"><label
|
||||
for="rinactive">timed out</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="pending" id="rpending"><label
|
||||
for="rpending">pending</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" name="filter" value="lowbatt" id="rlowbatt"><label
|
||||
for="rlowbatt">low battery</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="taglist" class="taglist">
|
||||
<div class="tagcard" id="tagtemplate">
|
||||
<div class="currimg"><canvas class="tagimg"></div>
|
||||
<div class="mac"></div>
|
||||
<div class="alias"></div>
|
||||
<div class="model"></div>
|
||||
<div class="received"></div>
|
||||
<div class="contentmode"></div>
|
||||
<div class="lastseen"></div>
|
||||
<div class="nextcheckin"></div>
|
||||
<div class="nextupdate"></div>
|
||||
<div class="corner">
|
||||
<div class="pendingicon" title="A new message is waiting for the tag to pick up">
|
||||
↻</div>
|
||||
<div class="warningicon" title="This tag has not been seen for a long time">⚠
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<span class="apchannel">25</span>
|
||||
</div>
|
||||
<p class="apswversion">
|
||||
fetching software version...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="logtab" class="tabcontent">
|
||||
<div class="tabheader">
|
||||
<div><img id="clearlog" src="data:image/gif;base64,R0lGODlhEAAQAPMAANXV1e3t7d/f39HR0dvb2/Hx8dTU1OLi4urq6mZmZpmZmf///wAAAAAAAAAAAAAAACH5BAEAAAwALAAAAAAQABAAAARBkMlJq71Yrp3ZXkr4WWCYnOZSgQVyEMYwJCq1nHhe20qgCAoA7QLyAYU7njE4JPV+zOSkCEUSFbmTVPPpbjvgTAQAOw==
|
||||
"></div>
|
||||
<div><input type="checkbox" id="showdebug" value="1"><label for="showdebug">Show all websocket
|
||||
traffic</label></div>
|
||||
</div>
|
||||
<ul id="messages" class="messages">
|
||||
</ul>
|
||||
</div>
|
||||
<div id="templatetab" class="tabcontent">
|
||||
Work in progress...
|
||||
</div>
|
||||
|
||||
<div id="aptab" class="tabcontent">
|
||||
<h3>Active access points</h3>
|
||||
<div id="configtab" class="tabcontent">
|
||||
<h3>Access Point config</h3>
|
||||
<p>
|
||||
<label for="apcfgalias">Alias</label>
|
||||
<input id="apcfgalias" type="text">
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfgchid">IEEE 802.15.4 channel</label>
|
||||
<select id="apcfgchid">
|
||||
<option value="0" selected>auto</option>
|
||||
<option value="11">11</option>
|
||||
<option value="15">15</option>
|
||||
<option value="20">20</option>
|
||||
<option value="25">25</option>
|
||||
<option value="26">26</option>
|
||||
<option value="27">27</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfgledbrightness">LED brightness</label>
|
||||
<select id="apcfgledbrightness">
|
||||
<option value="-1">off</option>
|
||||
<option value="20">10%</option>
|
||||
<option value="64">25%</option>
|
||||
<option value="128" selected>50%</option>
|
||||
<option value="192">75%</option>
|
||||
<option value="255">100%</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfglanguage">Content language</label>
|
||||
<select id="apcfglanguage">
|
||||
<option value="0" selected>EN English</option>
|
||||
<option value="1">NL Nederlands</option>
|
||||
<option value="2">DE Deutsch</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Depending on the content, a tag can sleep for
|
||||
longer periods when no updates are expected
|
||||
(like a date display). This setting specifies
|
||||
the maximum sleep time.">
|
||||
<label for="apclatency">Maximum sleep</label>
|
||||
<select id="apclatency">
|
||||
<option value="0" selected>shortest (40 sec)</option>
|
||||
<option value="5">5 minutes</option>
|
||||
<option value="10">10 minute</option>
|
||||
<option value="30">30 minutes</option>
|
||||
<option value="60">1 hour</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="If connected to the website, don't sleep extra.
|
||||
Latency will be around 40 seconds.">
|
||||
<label for="apcpreventsleep">Shorten latency during config</label>
|
||||
<select id="apcpreventsleep">
|
||||
<option value="0">no</option>
|
||||
<option value="1" selected>yes</option>
|
||||
</select>
|
||||
</p>
|
||||
<p
|
||||
title="Stops updates at night, and put the tags to sleep. During the configured night time, this overrides the maximum sleep time.">
|
||||
<label for="apcnight1">No updates between</label>
|
||||
<select id="apcnight1"></select>
|
||||
<span style="align-self:center;">and</span>
|
||||
<select id="apcnight2"></select>
|
||||
</p>
|
||||
<p title="Turn off preview images on the webpage if you want to manage many tags,
|
||||
to save file system space">
|
||||
<label for="apcpreview">Preview images</label>
|
||||
<select id="apcpreview">
|
||||
<option value="1" selected>yes</option>
|
||||
<option value="0">no</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Wifi transmit power">
|
||||
<label for="apcwifipower">Wifi power</label>
|
||||
<select id="apcwifipower">
|
||||
<option value="78">19.5 dBm</option>
|
||||
<option value="76">19.0 dBm</option>
|
||||
<option value="74">18.5 dBm</option>
|
||||
<option value="68">17.0 dBm</option>
|
||||
<option value="60">15.0 dBm</option>
|
||||
<option value="52">13.0 dBm</option>
|
||||
<option value="44">11.0 dBm</option>
|
||||
<option value="34" selected>8.5 dBm</option>
|
||||
<option value="28">7.0 dBm</option>
|
||||
<option value="20">5.0 dBm</option>
|
||||
<option value="8">2.0 dBm</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Your local time zone">
|
||||
<label for="apctimezone">Local time zone</label>
|
||||
<select id="apctimezone">
|
||||
<optgroup label="Europe">
|
||||
<option value="CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" selected>Central European
|
||||
Time</option>
|
||||
<option value="EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00">Athens, Greece</option>
|
||||
<option value="GMT+0IST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">Dublin, Ireland</option>
|
||||
<option value="EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00">Helsinki, Finland</option>
|
||||
<option value="WET-0WEST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">Lisbon, Portugal</option>
|
||||
<option value="GMT+0BST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">London, Great Britain
|
||||
</option>
|
||||
<option value="EET-2EEST,M3.5.0/3,M10.5.0/4">Kyiv, Ukraine</option>
|
||||
</optgroup>
|
||||
<optgroup label="USA / Canada">
|
||||
<option value="HAW10">Hawaii Time</option>
|
||||
<option value="AKST9AKDT">Alaska Time</option>
|
||||
<option value="PST8PDT">Pacific Time</option>
|
||||
<option value="MST7MDT">Mountain Time</option>
|
||||
<option value="MST7">Arizona, no DST</option>
|
||||
<option value="CST6CDT">Central Time</option>
|
||||
<option value="EST5EDT">Eastern Time</option>
|
||||
</optgroup>
|
||||
<optgroup label="Australia / New Zealand">
|
||||
<option value="EST-10EDT-11,M10.5.0/02:00:00,M3.5.0/03:00:00">Melbourne, Sydney</option>
|
||||
<option value="WST-8">Perth</option>
|
||||
<option value="EST-10">Brisbane</option>
|
||||
<option value="CST-9:30CDT-10:30,M10.5.0/02:00:00,M3.5.0/03:00:00">Adelaide</option>
|
||||
<option value="CST-9:30">Darwin</option>
|
||||
<option value="EST-10EDT-11,M10.1.0/02:00:00,M3.5.0/03:00:00">Hobart</option>
|
||||
<option value="NZST-12NZDT-13,M9.4.0/02:00:00,M4.1.0/03:00:00">New Zealand</option>
|
||||
</optgroup>
|
||||
<optgroup label="Asia">
|
||||
<option value="JST-9">Tokyo</option>
|
||||
<option value="WIB-7">Jakarta</option>
|
||||
<option value="GMT+2">Jerusalem</option>
|
||||
<option value="SGT-8">Singapore</option>
|
||||
<option value="ULAT-8ULAST,M3.5.0/2,M9.5.0/2">Ulaanbaatar, Mongolia</option>
|
||||
</optgroup>
|
||||
<optgroup label="Central and South America">
|
||||
<option value="BRST+3BRDT+2,M10.3.0,M2.3.0">Brazil, Sao Paulo</option>
|
||||
<option value="UTC+3">Argentina</option>
|
||||
<option value="CST+6">Central America</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<input type="button" value="Save" id="apcfgsave"><span id="apcfgmsg"></span>
|
||||
</p>
|
||||
<h3>Manage</h3>
|
||||
<p>
|
||||
<button type="button" id="rebootbutton">Reboot AP</button> Saves the tagDB and instantly reboots the Access
|
||||
Point
|
||||
</p>
|
||||
<p>
|
||||
<a href="/backup_db" id="downloadDBbutton">Download tagDB</a>
|
||||
</p>
|
||||
<p>
|
||||
<button type="button" id="updatebutton" class="tablinks" data-target="updatetab" title="Update">Update</button> Manage firmware of the ESP32
|
||||
</p>
|
||||
<p>
|
||||
<a href="/setup" target="setup" class="wifibutton">WiFi config</a> Opens a new window with WiFi
|
||||
config options
|
||||
</p>
|
||||
<p>
|
||||
<br>
|
||||
<a href="https://github.com/jjwbruijn/OpenEPaperLink" target="_new">Github
|
||||
OpenEPaperLink</a><br>
|
||||
<a href="https://github.com/jjwbruijn/OpenEPaperLink/wiki" target="_new">OpenEPaperLink
|
||||
Wiki</a><br>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div id="aplist">
|
||||
<div id="apcard" class="apcard">
|
||||
<p class="apip">194.109.6.66</p>
|
||||
<p class="apalias">AP kitchen</p>
|
||||
<div>
|
||||
<span class="material-symbols-outlined">
|
||||
sell
|
||||
<div id="updatetab" class="tabcontent">
|
||||
<h3>Firmware Updates</h3>
|
||||
<div>
|
||||
<div class="updateCol1">
|
||||
<div id="easyupdate"></div>
|
||||
<h4>Repository</h4>
|
||||
<div>
|
||||
<label for="repo">Repo</label><input type="text" id="repo" value="">
|
||||
<button id="selectRepo">Change</button><br>
|
||||
<p id="repoWarning" style="display:none" class="warning">
|
||||
To change to this repository, select and confirm the build environment.
|
||||
</p>
|
||||
<label for="environment">Environment</label><input type="text" id="environment" readonly value="">
|
||||
<button id="confirmSelectRepo">Confirm</button><button id="cancelSelectRepo">Cancel</button>
|
||||
</div>
|
||||
<h4>Releases</h4>
|
||||
<div id="releasetable"></div>
|
||||
<h4>Other actions</h4>
|
||||
<div>
|
||||
<p>
|
||||
<div id="rollbackOption" style="display:none"><button type="button" id="rollbackBtn">Rollback to previous
|
||||
firmware</button></div>
|
||||
</p>
|
||||
<p>
|
||||
<span id="c6Option">
|
||||
<div id="updateC6Option"><button type="button" id="updateC6Btn">Update ESP32-C6</button> <input type="checkbox"
|
||||
value="1" checked id="c6download"> download latest version</div>
|
||||
</span>
|
||||
<span class="aptagcount">13</span>
|
||||
<span class="material-symbols-outlined space">
|
||||
cell_tower
|
||||
</span>
|
||||
<span class="apchannel">25</span>
|
||||
</div>
|
||||
<p class="apswversion">
|
||||
fetching software version...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="console" id="updateconsole"></div>
|
||||
</div>
|
||||
|
||||
<div id="templatetab" class="tabcontent">
|
||||
Work in progress...
|
||||
</div>
|
||||
|
||||
<div id="configtab" class="tabcontent">
|
||||
<h3>Access Point config</h3>
|
||||
<p>
|
||||
<label for="apcfgalias">Alias</label>
|
||||
<input id="apcfgalias" type="text">
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfgchid">Channel</label>
|
||||
<select id="apcfgchid">
|
||||
<option value="0" selected>auto</option>
|
||||
<option value="11">11</option>
|
||||
<option value="15">15</option>
|
||||
<option value="20">20</option>
|
||||
<option value="25">25</option>
|
||||
<option value="26">26</option>
|
||||
<option value="27">27</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfgledbrightness">LED brightness</label>
|
||||
<select id="apcfgledbrightness">
|
||||
<option value="-1">off</option>
|
||||
<option value="20">10%</option>
|
||||
<option value="64">25%</option>
|
||||
<option value="128" selected>50%</option>
|
||||
<option value="192">75%</option>
|
||||
<option value="255">100%</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="apcfglanguage">Content language</label>
|
||||
<select id="apcfglanguage">
|
||||
<option value="0" selected>EN English</option>
|
||||
<option value="1">NL Nederlands</option>
|
||||
<option value="2">DE Deutsch</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Depending on the content, a tag can sleep for
|
||||
longer periods when no updates are expected
|
||||
(like a date display). This setting specifies
|
||||
the maximum sleep time.">
|
||||
<label for="apclatency">Maximum sleep</label>
|
||||
<select id="apclatency">
|
||||
<option value="0" selected>shortest (40 sec)</option>
|
||||
<option value="5">5 minutes</option>
|
||||
<option value="10">10 minute</option>
|
||||
<option value="30">30 minutes</option>
|
||||
<option value="60">1 hour</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="If connected to the website, don't sleep extra.
|
||||
Latency will be around 40 seconds.">
|
||||
<label for="apcpreventsleep">Shorten latency during config</label>
|
||||
<select id="apcpreventsleep">
|
||||
<option value="0">no</option>
|
||||
<option value="1" selected>yes</option>
|
||||
</select>
|
||||
</p>
|
||||
<p
|
||||
title="Stops updates at night, and put the tags to sleep. During the configured night time, this overrides the maximum sleep time.">
|
||||
<label for="apcnight1">No updates between</label>
|
||||
<select id="apcnight1"></select>
|
||||
<span style="align-self:center;">and</span>
|
||||
<select id="apcnight2"></select>
|
||||
</p>
|
||||
<p title="Turn off preview images on the webpage if you want to manage many tags,
|
||||
to save file system space">
|
||||
<label for="apcpreview">Preview images</label>
|
||||
<select id="apcpreview">
|
||||
<option value="1" selected>yes</option>
|
||||
<option value="0">no</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Wifi transmit power">
|
||||
<label for="apcwifipower">Wifi power</label>
|
||||
<select id="apcwifipower">
|
||||
<option value="78">19.5 dBm</option>
|
||||
<option value="76">19.0 dBm</option>
|
||||
<option value="74">18.5 dBm</option>
|
||||
<option value="68">17.0 dBm</option>
|
||||
<option value="60">15.0 dBm</option>
|
||||
<option value="52">13.0 dBm</option>
|
||||
<option value="44">11.0 dBm</option>
|
||||
<option value="34" selected>8.5 dBm</option>
|
||||
<option value="28">7.0 dBm</option>
|
||||
<option value="20">5.0 dBm</option>
|
||||
<option value="8">2.0 dBm</option>
|
||||
</select>
|
||||
</p>
|
||||
<p title="Your local time zone">
|
||||
<label for="apctimezone">Local time zone</label>
|
||||
<select id="apctimezone">
|
||||
<optgroup label="Europe">
|
||||
<option value="CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00" selected>Central European
|
||||
Time</option>
|
||||
<option value="EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00">Athens, Greece</option>
|
||||
<option value="GMT+0IST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">Dublin, Ireland</option>
|
||||
<option value="EET-2EEST-3,M3.5.0/03:00:00,M10.5.0/04:00:00">Helsinki, Finland</option>
|
||||
<option value="WET-0WEST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">Lisbon, Portugal</option>
|
||||
<option value="GMT+0BST-1,M3.5.0/01:00:00,M10.5.0/02:00:00">London, Great Britain
|
||||
</option>
|
||||
<option value="EET-2EEST,M3.5.0/3,M10.5.0/4">Kyiv, Ukraine</option>
|
||||
</optgroup>
|
||||
<optgroup label="USA / Canada">
|
||||
<option value="HAW10">Hawaii Time</option>
|
||||
<option value="AKST9AKDT">Alaska Time</option>
|
||||
<option value="PST8PDT">Pacific Time</option>
|
||||
<option value="MST7MDT">Mountain Time</option>
|
||||
<option value="MST7">Arizona, no DST</option>
|
||||
<option value="CST6CDT">Central Time</option>
|
||||
<option value="EST5EDT">Eastern Time</option>
|
||||
</optgroup>
|
||||
<optgroup label="Australia / New Zealand">
|
||||
<option value="EST-10EDT-11,M10.5.0/02:00:00,M3.5.0/03:00:00">Melbourne, Sydney</option>
|
||||
<option value="WST-8">Perth</option>
|
||||
<option value="EST-10">Brisbane</option>
|
||||
<option value="CST-9:30CDT-10:30,M10.5.0/02:00:00,M3.5.0/03:00:00">Adelaide</option>
|
||||
<option value="CST-9:30">Darwin</option>
|
||||
<option value="EST-10EDT-11,M10.1.0/02:00:00,M3.5.0/03:00:00">Hobart</option>
|
||||
<option value="NZST-12NZDT-13,M9.4.0/02:00:00,M4.1.0/03:00:00">New Zealand</option>
|
||||
</optgroup>
|
||||
<optgroup label="Asia">
|
||||
<option value="JST-9">Tokyo</option>
|
||||
<option value="WIB-7">Jakarta</option>
|
||||
<option value="GMT+2">Jerusalem</option>
|
||||
<option value="SGT-8">Singapore</option>
|
||||
<option value="ULAT-8ULAST,M3.5.0/2,M9.5.0/2">Ulaanbaatar, Mongolia</option>
|
||||
</optgroup>
|
||||
<optgroup label="Central and South America">
|
||||
<option value="BRST+3BRDT+2,M10.3.0,M2.3.0">Brazil, Sao Paulo</option>
|
||||
<option value="UTC+3">Argentina</option>
|
||||
<option value="CST+6">Central America</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<input type="button" value="Save" id="apcfgsave"><span id="apcfgmsg"></span>
|
||||
</p>
|
||||
<h3>Manage</h3>
|
||||
<p>
|
||||
<button id="rebootbutton">Reboot AP</button> Saves the tagDB and instantly reboots the Access
|
||||
Point
|
||||
</p>
|
||||
<p>
|
||||
<a href="/backup_db" id="downloadDBbutton">Download tagDB</a>
|
||||
</p>
|
||||
<p>
|
||||
<button id="updatebutton">Update</button> Manage firmware of the ESP32
|
||||
</p>
|
||||
<p>
|
||||
<a href="/setup" target="setup" class="wifibutton">WiFi config</a> Opens a new window with WiFi
|
||||
config options
|
||||
</p>
|
||||
<p>
|
||||
<br>
|
||||
<a href="https://github.com/jjwbruijn/OpenEPaperLink" target="_new">Github
|
||||
OpenEPaperLink</a><br>
|
||||
<a href="https://github.com/jjwbruijn/OpenEPaperLink/wiki" target="_new">OpenEPaperLink
|
||||
Wiki</a><br>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<footer class="logbox">
|
||||
<p>
|
||||
@@ -464,27 +497,6 @@
|
||||
</p>
|
||||
</dialog>
|
||||
|
||||
<div id="apupdatebox">
|
||||
<div class="closebtn">✖</div>
|
||||
<h3>Update dashboard</h3>
|
||||
<div id="easyupdate"></div>
|
||||
<div id="advanceddiv">
|
||||
<!--<div>
|
||||
repo: <input type="text" name="repo"> <button id="switchRepo">Switch</button><br>
|
||||
environment: <span id="environment">environment</span>
|
||||
</div>-->
|
||||
<div id="releasetable"></div>
|
||||
<div>
|
||||
<div id="rollbackOption" style="display:none"><button id="rollbackBtn">Rollback to previous
|
||||
firmware</button></div>
|
||||
<span id="c6Option">
|
||||
<div id="updateC6Option"><button id="updateC6Btn">Update ESP32-C6</button> <input type="checkbox"
|
||||
value="1" checked id="c6download"> download latest version</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul id="context-menu"
|
||||
style="display: none; position: absolute; background: white; border: 1px solid gray; padding: 0; list-style: none;">
|
||||
</ul>
|
||||
|
||||
@@ -65,7 +65,7 @@ footer {
|
||||
.logo {
|
||||
margin: 0 auto;
|
||||
height: 50px;
|
||||
text-indent: 50px;
|
||||
text-indent: 12px;
|
||||
overflow: hidden;
|
||||
font-size: 2.5em;
|
||||
color: white;
|
||||
@@ -202,7 +202,8 @@ label {
|
||||
}
|
||||
|
||||
#aptab,
|
||||
#configtab {
|
||||
#configtab,
|
||||
#updatetab {
|
||||
padding: 10px;
|
||||
|
||||
& p {
|
||||
@@ -210,6 +211,35 @@ label {
|
||||
}
|
||||
}
|
||||
|
||||
#updatetab {
|
||||
&>div {
|
||||
display: flex;
|
||||
gap: 2em;
|
||||
flex-flow: wrap;
|
||||
}
|
||||
& label {
|
||||
width: 100px;
|
||||
display: inline-block;
|
||||
vertical-align: baseline;
|
||||
padding: 7px 0px;
|
||||
}
|
||||
& input[type="text"] {
|
||||
width: 200px;
|
||||
}
|
||||
& button {
|
||||
margin: 0px 5px;
|
||||
}
|
||||
& input:read-only {
|
||||
background-color: #ccc;
|
||||
}
|
||||
& .warning {
|
||||
padding: 5px;
|
||||
color: #f02000;
|
||||
background-color: #ffffc0;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
#aplist {
|
||||
display: flex;
|
||||
gap: 1em;
|
||||
@@ -719,7 +749,10 @@ ul.messages li.new {
|
||||
/* updatescreens */
|
||||
|
||||
#easyupdate {
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
background-color: white;
|
||||
width: 400px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#easyupdate button {
|
||||
@@ -733,13 +766,10 @@ ul.messages li.new {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#advanceddiv {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#advanceddiv div:nth-child(2) {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
h4 {
|
||||
font-size: 1.25em;
|
||||
margin: 10px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#releasetable {
|
||||
@@ -764,7 +794,7 @@ ul.messages li.new {
|
||||
}
|
||||
|
||||
#releasetable td:nth-child(2) {
|
||||
word-wrap: nowrap;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#releasetable button {
|
||||
@@ -780,17 +810,21 @@ ul.messages li.new {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.updateCol1 {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.console {
|
||||
width: 100%;
|
||||
width: 450px;
|
||||
background-color: black;
|
||||
font-family: 'lucida console', 'ui-monospace';
|
||||
color: white;
|
||||
padding: 5px 10px;
|
||||
margin: 20px 0px;
|
||||
padding-bottom: 25px;
|
||||
height: 400px;
|
||||
height: calc(100vh - 200px);
|
||||
overflow-y: scroll;
|
||||
white-space: break-spaces;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.console div {
|
||||
|
||||
@@ -83,7 +83,8 @@ function initTabs() {
|
||||
const tabContents = document.querySelectorAll(".tabcontent");
|
||||
|
||||
tabLinks.forEach(tabLink => {
|
||||
tabLink.addEventListener("click", function () {
|
||||
tabLink.addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
const targetId = this.getAttribute("data-target");
|
||||
const loadTabEvent = new CustomEvent('loadTab', { detail: targetId });
|
||||
document.dispatchEvent(loadTabEvent);
|
||||
@@ -575,6 +576,10 @@ document.addEventListener("loadTab", function (event) {
|
||||
})
|
||||
$('#apcfgmsg').innerHTML = '';
|
||||
break;
|
||||
case 'updatetab':
|
||||
$('#updateconsole').innerHTML = '';
|
||||
loadOTA();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -605,12 +610,6 @@ $('#apcfgsave').onclick = function () {
|
||||
.catch(error => showMessage('Error: ' + error));
|
||||
}
|
||||
|
||||
$('#updatebutton').onclick = function (event) {
|
||||
event.preventDefault();
|
||||
$('#apupdatebox').style.display = 'block';
|
||||
loadOTA();
|
||||
}
|
||||
|
||||
async function loadOTA() {
|
||||
otamodule = await import('./ota.js?v=' + Date.now());
|
||||
otamodule.initUpdate();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
const repoUrl = 'https://api.github.com/repos/jjwbruijn/OpenEPaperLink/releases';
|
||||
var repo = apConfig.repo || 'jjwbruijn/OpenEPaperLink';
|
||||
var repoUrl = 'https://api.github.com/repos/' + repo + '/releases';
|
||||
|
||||
const $ = document.querySelector.bind(document);
|
||||
|
||||
@@ -8,17 +9,26 @@ let env = '', currentVer = '', currentBuildtime = 0;
|
||||
let buttonState = false;
|
||||
|
||||
export async function initUpdate() {
|
||||
if (!$("#updateconsole")) {
|
||||
const consoleDiv = document.createElement('div');
|
||||
consoleDiv.classList.add('console');
|
||||
consoleDiv.id = "updateconsole";
|
||||
$('#apupdatebox').appendChild(consoleDiv);
|
||||
}
|
||||
$("#updateconsole").innerHTML = "";
|
||||
|
||||
const response = await fetch("/version.txt");
|
||||
let filesystemversion = await response.text();
|
||||
if (!filesystemversion) filesystemversion = "unknown";
|
||||
$('#repo').value = repo;
|
||||
|
||||
const envBox = $('#environment');
|
||||
if (envBox?.tagName === 'SELECT') {
|
||||
const inputElement = document.createElement('input');
|
||||
inputElement.type = 'text';
|
||||
inputElement.id = 'environment';
|
||||
envBox.parentNode.replaceChild(inputElement, envBox);
|
||||
}
|
||||
$('#environment').value = '';
|
||||
$('#environment').setAttribute('readonly', true);
|
||||
$('#repo').removeAttribute('readonly');
|
||||
$('#confirmSelectRepo').style.display = 'none';
|
||||
$('#cancelSelectRepo').style.display = 'none';
|
||||
$('#selectRepo').style.display = 'inline-block';
|
||||
$('#repoWarning').style.display = 'none';
|
||||
|
||||
fetch("/sysinfo")
|
||||
.then(response => {
|
||||
@@ -42,7 +52,6 @@ export async function initUpdate() {
|
||||
print(`build date: ${formatEpoch(data.buildtime)}`);
|
||||
print(`esp32 version: ${data.buildversion}`);
|
||||
print(`filesystem version: ${filesystemversion}` + matchtest);
|
||||
print(`sha: ${data.sha}`);
|
||||
print(`psram size: ${data.psramsize}`);
|
||||
print(`flash size: ${data.flashsize}`);
|
||||
print("--------------------------", "gray");
|
||||
@@ -51,6 +60,7 @@ export async function initUpdate() {
|
||||
currentBuildtime = data.buildtime;
|
||||
if (data.rollback) $("#rollbackOption").style.display = 'block';
|
||||
if (data.env == 'ESP32_S3_16_8_YELLOW_AP') $("#c6Option").style.display = 'block';
|
||||
$('#environment').value = env;
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
@@ -92,7 +102,6 @@ export async function initUpdate() {
|
||||
}
|
||||
}
|
||||
}
|
||||
easyupdate.innerHTML += "<br><a onclick=\"$('#advanceddiv').style.display='block'\">advanced options</a>"
|
||||
|
||||
const table = document.createElement('table');
|
||||
const tableHeader = document.createElement('tr');
|
||||
@@ -101,9 +110,9 @@ export async function initUpdate() {
|
||||
|
||||
let rowCounter = 0;
|
||||
releaseDetails.forEach(release => {
|
||||
if (rowCounter < 3 && release?.html_url) {
|
||||
if (rowCounter < 4 && release?.html_url) {
|
||||
const tableRow = document.createElement('tr');
|
||||
let tablerow = `<td><a href="${release.html_url}" target="_new">${release.tag_name}</a></td><td>${release.date}</td><td>${release.name}</td><td><button onclick="otamodule.updateESP('${release.bin_url}', true)">ESP32</button></td><td><button onclick="otamodule.updateWebpage('${release.file_url}','${release.tag_name}', true)">Filesystem</button></td>`;
|
||||
let tablerow = `<td><a href="${release.html_url}" target="_new">${release.tag_name}</a></td><td>${release.date}</td><td>${release.name}</td><td><button type="button" onclick="otamodule.updateWebpage('${release.file_url}','${release.tag_name}', true)">Filesystem</button></td><td><button type="button" onclick="otamodule.updateESP('${release.bin_url}', true)">ESP32</button></td>`;
|
||||
if (release.tag_name == currentVer) {
|
||||
tablerow += "<td>current version</td>";
|
||||
} else if (release.date < formatEpoch(currentBuildtime)) {
|
||||
@@ -362,6 +371,90 @@ $('#updateC6Btn').onclick = function () {
|
||||
disableButtons(false);
|
||||
}
|
||||
|
||||
$('#selectRepo').onclick = function (event) {
|
||||
event.preventDefault();
|
||||
$('#updateconsole').innerHTML = '';
|
||||
|
||||
let repoUrl = 'https://api.github.com/repos/' + $('#repo').value + '/releases';
|
||||
fetch(repoUrl)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
const release = data[0];
|
||||
print("Repo found! Latest release: " + release.name + " created " + release.created_at);
|
||||
const assets = release.assets;
|
||||
const filesJsonAsset = assets.find(asset => asset.name === 'filesystem.json');
|
||||
const binariesJsonAsset = assets.find(asset => asset.name === 'binaries.json');
|
||||
if (filesJsonAsset && binariesJsonAsset) {
|
||||
const updateUrl = "http://openepaperlink.eu/getupdate/?url=" + binariesJsonAsset.browser_download_url + "&env=" + $('#repo').value;
|
||||
return fetch(updateUrl);
|
||||
} else {
|
||||
throw new Error("Json file binaries.json and/or filesystem.json not found in the release assets");
|
||||
}
|
||||
};
|
||||
})
|
||||
.then(updateResponse => {
|
||||
if (!updateResponse.ok) {
|
||||
throw new Error("Network response was not OK");
|
||||
}
|
||||
return updateResponse.text();
|
||||
})
|
||||
.then(responseBody => {
|
||||
if (!responseBody.trim().startsWith("[")) {
|
||||
throw new Error("Failed to fetch the release info file");
|
||||
}
|
||||
const updateData = JSON.parse(responseBody).filter(item => !item.name.endsWith('_full.bin'));
|
||||
|
||||
const inputParent = $('#environment').parentNode;
|
||||
const selectElement = document.createElement('select');
|
||||
selectElement.id = 'environment';
|
||||
updateData.forEach(item => {
|
||||
const option = document.createElement('option');
|
||||
option.value = item.name.replace('.bin', '');
|
||||
option.text = item.name.replace('.bin', '');
|
||||
selectElement.appendChild(option);
|
||||
});
|
||||
inputParent.replaceChild(selectElement, $('#environment'));
|
||||
$('#environment').value = env;
|
||||
$('#confirmSelectRepo').style.display = 'inline-block';
|
||||
$('#cancelSelectRepo').style.display = 'inline-block';
|
||||
$('#selectRepo').style.display = 'none';
|
||||
$('#repo').setAttribute('readonly', true);
|
||||
$('#repoWarning').style.display = 'block';
|
||||
})
|
||||
.catch(error => {
|
||||
print('Error fetching releases:' + error, "red");
|
||||
});
|
||||
}
|
||||
|
||||
$('#cancelSelectRepo').onclick = function (event) {
|
||||
event.preventDefault();
|
||||
$('#updateconsole').innerHTML = '';
|
||||
initUpdate();
|
||||
}
|
||||
|
||||
$('#confirmSelectRepo').onclick = function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
repo = $('#repo').value;
|
||||
let formData = new FormData();
|
||||
formData.append("repo", repo);
|
||||
formData.append("env", $('#environment').value);
|
||||
fetch("/save_apcfg", {
|
||||
method: "POST",
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
window.dispatchEvent(loadConfig);
|
||||
print('OK, Saved');
|
||||
})
|
||||
.catch(error => print('Error: ' + error));
|
||||
$('#updateconsole').innerHTML = '';
|
||||
repoUrl = 'https://api.github.com/repos/' + repo + '/releases';
|
||||
initUpdate();
|
||||
}
|
||||
|
||||
export function print(line, color = "white") {
|
||||
const consoleDiv = document.getElementById('updateconsole');
|
||||
if (consoleDiv) {
|
||||
@@ -464,7 +557,7 @@ const writeVersion = async (content, name, path) => {
|
||||
};
|
||||
|
||||
function disableButtons(active) {
|
||||
$("#apupdatebox").querySelectorAll('button').forEach(button => {
|
||||
$("#configtab").querySelectorAll('button').forEach(button => {
|
||||
button.disabled = active;
|
||||
});
|
||||
buttonState = active;
|
||||
|
||||
Reference in New Issue
Block a user