apconfig improvements

This commit is contained in:
Nic Limper
2023-05-25 09:22:48 +02:00
parent 92c8d6178d
commit f73ce60468
13 changed files with 149 additions and 75 deletions

View File

@@ -38,7 +38,7 @@
<div id="apconfigbox">
<div class="closebtn">&#10006;</div>
<h3 id="cfgmac">Access Point config</h3>
<h3>Access Point config</h3>
<p>
<label for="apcfgalias">Alias</label>
<input id="apcfgalias" type="text">
@@ -56,7 +56,7 @@
</select>
</p>
<p>
<label for="apcfgledbrightness">LED Brightness</label>
<label for="apcfgledbrightness">LED brightness</label>
<select id="apcfgledbrightness">
<option value="-1">off</option>
<option value="64">25%</option>
@@ -66,27 +66,37 @@
</select>
</p>
<p>
<label for="apcfglanguage">Content Language</label>
<label for="apcfglanguage">Content language</label>
<select id="apcfglanguage">
<option value="0">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">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">yes</option>
</select>
</p>
<p>
<input type="button" value="Save" id="apcfgsave">
</p>
<!--
<p><pre>
work in progress
- upload tagDB
- update webinterface from github
- update APtag FW from github
- update all tag FW from github
- update esp32 fw
</pre>
</p>
-->
<p>
Active access points:<br>
<table id="aptable">
@@ -102,12 +112,35 @@
<p>
<span id="rebootbutton">reboot AP</span>
<a href="/backup_db" id="downloadDBbutton">download tagDB</a>
<!--<span id="updatebutton">update</span>-->
</p>
<p>
<a href="https://github.com/jjwbruijn/OpenEPaperLink" target="_new">Github OpenEPaperLink</a>
</p>
</div>
<div id="apupdatebox">
<div class="closebtn">&#10006;</div>
<h3>Firmware updates</h3>
<p>
test
</p>
<p>
<input type="button" value="Save" id="apfwsave">
</p>
<!--
<p><pre>
work in progress
- upload tagDB
- update webinterface from github
- update APtag FW from github
- update all tag FW from github
- update esp32 fw
</pre>
</p>
-->
</div>
<form>
<div class="container">

View File

@@ -29,8 +29,10 @@ header {
}
label {
width:100px;
width: 120px;
display: inline-block;
vertical-align: top;
padding: 3px 0px;
}
.logo {
@@ -62,7 +64,7 @@ label {
gap: 20px;
}
#rebootbutton, #downloadDBbutton, #apconfigbutton, .filebutton {
#rebootbutton, #updatebutton, #downloadDBbutton, #apconfigbutton, .filebutton {
padding: 2px 5px;
background-color: #cccccc;
text-decoration: none;
@@ -85,7 +87,7 @@ button {
}
input {
border: solid 1px #666666;
border: solid 1px #cccccc;
padding: 4px;
border-radius: 0px;
}
@@ -102,11 +104,12 @@ button:hover {
}
select {
padding: 4px;
padding: 3px 4px;
border-radius: 0px;
border: solid 1px #cccccc;
}
#configbox, #apconfigbox {
#configbox, #apconfigbox, #apupdatebox {
display: none;
position: fixed;
top: 80px;
@@ -118,22 +121,17 @@ select {
box-shadow: 7px 10px 52px -19px rgba(0, 0, 0, 0.63);
}
#configbox p, #apconfigbox p {
#configbox p, #apconfigbox p, #apupdatebox p {
padding: 5px;
}
#configbox h3, #apconfigbox h3 {
#configbox h3, #apconfigbox h3, #apupdatebox h3 {
font-size: 1.5em;
font-weight: bold;
}
#configbox input, #apconfigbox input {
border: solid 1px #666666;
/*padding: 4px;*/
}
#configbox label, #apconfigbox label {
text-transform: capitalize;
border: solid 1px #cccccc;
}
#configbox input[type=number] {
@@ -169,6 +167,10 @@ select {
text-align: right;
}
#apupdatebox {
background-color: #f0e0d0;
}
#cfgdelete {
position: absolute;
bottom: 15px;

View File

@@ -346,23 +346,27 @@ $('#apconfigbutton').onclick = function () {
for (var i = rowCount - 1; i > 0; i--) {
table.deleteRow(i);
}
$('#apconfigbox').style.display = 'block'
fetch("/get_ap_list")
.then(response => response.json())
.then(data => {
$('#apcfgalias').value = data.alias;
$('#apcfgchid').value = data.channel;
$("#apcfgledbrightness").value = data.ledbrightness;
$("#apcfgledbrightness").value = data.led;
$("#apcfglanguage").value = data.language;
$("#apclatency").value = data.maxsleep;
$("#apcpreventsleep").value = data.stopsleep;
})
$('#apconfigbox').style.display = 'block'
}
$('#apcfgsave').onclick = function () {
let formData = new FormData();
formData.append("alias", $('#apcfgalias').value);
formData.append("channel", $('#apcfgchid').value);
formData.append('ledbrightness', $('#apcfgledbrightness').value);
formData.append('led', $('#apcfgledbrightness').value);
formData.append('language', $('#apcfglanguage').value);
formData.append('maxsleep', $('#apclatency').value);
formData.append('stopsleep', $('#apcpreventsleep').value);
fetch("/save_apcfg", {
method: "POST",
body: formData
@@ -374,6 +378,12 @@ $('#apcfgsave').onclick = function () {
$('#apconfigbox').style.display = 'none';
}
$('#updatebutton').onclick = function () {
$('#apconfigbox').style.display = 'none';
$('#apupdatebox').style.display = 'block';
//https://api.github.com/repos/jjwbruijn/OpenEPaperLink/commits
}
$('#paintbutton').onclick = function () {
if (paintShow) {
paintShow = false;

View File

@@ -6,13 +6,6 @@
#define FLASHER_ALTRADIO_PORT 2
#endif
// how long the we should keep the transfer metadata
#define PENDING_TIMEOUT 24 * 3600
// this determines how long images will be cached;
#define PENDING_DATA_TIMEOUT 60
// maximum time (in minutes) that a tag is put to sleep if no update is expected.
#define MIN_RESPONSE_TIME 10
// Which port we should use for the AP process
// (useful for testing, can only be FLASHER_AP_PORT for any other board than the OpenEPaperLinkPCB board)
#define AP_PROCESS_PORT FLASHER_AP_PORT

View File

@@ -44,6 +44,16 @@ class tagRecord {
static tagRecord* findByMAC(uint8_t mac[8]);
};
struct Config {
uint8_t channel;
char alias[32];
int16_t led;
uint8_t language;
uint8_t maxsleep;
uint8_t stopsleep;
};
extern Config config;
extern std::vector<tagRecord*> tagDB;
extern DynamicJsonDocument APconfig;
String tagDBtoJson(uint8_t mac[8] = nullptr, uint8_t startPos = 0);

View File

@@ -29,6 +29,9 @@ board_build.f_cpu = 240000000L
;upload_port = COM30
;monitor_port = COM30
build_flags =
-D BUILD_ENV_NAME=$PIOENV
-D BUILD_TIME=$UNIX_TIME
[env:OpenEPaperLink_Mini_AP]
platform = https://github.com/platformio/platform-espressif32.git
@@ -137,7 +140,7 @@ board = esp32dev
board_build.partitions = default.csv
build_flags =
-DCORE_DEBUG_LEVEL=0
-D CORE_DEBUG_LEVEL=0
-D SIMPLE_AP
-D FLASHER_AP_SS=5

View File

@@ -56,8 +56,8 @@ void contentRunner() {
if (taginfo->expectedNextCheckin > now - 10 && taginfo->expectedNextCheckin < now + 30 && taginfo->pendingIdle == 0 && taginfo->pending == false) {
uint16_t minutesUntilNextUpdate = 0;
minutesUntilNextUpdate = (taginfo->nextupdate - now) / 60;
if (minutesUntilNextUpdate > MIN_RESPONSE_TIME) minutesUntilNextUpdate = MIN_RESPONSE_TIME;
if (minutesUntilNextUpdate > 1 && wsClientCount() == 0) {
if (minutesUntilNextUpdate > config.maxsleep) minutesUntilNextUpdate = config.maxsleep;
if (minutesUntilNextUpdate > 1 && (wsClientCount() == 0 || config.stopsleep == 0)) {
taginfo->pendingIdle = minutesUntilNextUpdate;
if (taginfo->isExternal == false) prepareIdleReq(taginfo->mac, minutesUntilNextUpdate);
}
@@ -301,7 +301,11 @@ void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams) {
if (taginfo->hwType == SOLUM_29_SSD1619 || taginfo->hwType == SOLUM_29_UC8151) {
initSprite(spr, 296, 128);
drawString(spr, languageDays[getCurrentLanguage()][timeinfo.tm_wday], 296 / 2, 10, "fonts/calibrib62", TC_DATUM, PAL_RED);
if (getCurrentLanguage() == 0 && timeinfo.tm_wday == 3) {
drawString(spr, languageDays[getCurrentLanguage()][timeinfo.tm_wday], 296 / 2, 10, "fonts/calibrib50", TC_DATUM, PAL_RED);
} else {
drawString(spr, languageDays[getCurrentLanguage()][timeinfo.tm_wday], 296 / 2, 10, "fonts/calibrib62", TC_DATUM, PAL_RED);
}
drawString(spr, String(timeinfo.tm_mday) + " " + languageMonth[getCurrentLanguage()][timeinfo.tm_mon], 296 / 2, 73, "fonts/calibrib50", TC_DATUM);
} else if (taginfo->hwType == SOLUM_154_SSD1619) {

View File

@@ -8,7 +8,7 @@
int currentLanguage = defaultLanguage;
void updateLanguageFromConfig() {
int tempLang = APconfig["language"].as<int>();
int tempLang = config.language;
if (tempLang < 0 || tempLang >= sizeof(languageList)) {
Serial.println("Language not supported");
return;

View File

@@ -172,8 +172,8 @@ void setBrightness(int brightness) {
}
void updateBrightnessFromConfig() {
if (APconfig["ledbrightness"].as<int>() != 0) {
int newbrightness = APconfig["ledbrightness"].as<int>();
if (config.led != 0) {
int newbrightness = config.led;
if (newbrightness < 0) newbrightness = 0;
if (newbrightness != maxledbrightness) {
setBrightness(newbrightness);

View File

@@ -64,13 +64,13 @@ void prepareCancelPending(uint8_t dst[8]) {
}
void prepareIdleReq(uint8_t* dst, uint16_t nextCheckin) {
if (nextCheckin > MIN_RESPONSE_TIME) nextCheckin = MIN_RESPONSE_TIME;
if (nextCheckin > config.maxsleep) nextCheckin = config.maxsleep;
if (nextCheckin > 0) {
struct pendingData pending = {0};
memcpy(pending.targetMac, dst, 8);
pending.availdatainfo.dataType = DATATYPE_NOUPDATE;
pending.availdatainfo.nextCheckIn = nextCheckin;
pending.attemptsLeft = 10 + MIN_RESPONSE_TIME;
pending.attemptsLeft = 10 + config.maxsleep;
char buffer[64];
sprintf(buffer, ">SDA %02X%02X%02X%02X%02X%02X%02X%02X NOP\n", dst[7], dst[6], dst[5], dst[4], dst[3], dst[2], dst[1], dst[0]);
@@ -127,8 +127,8 @@ void prepareNFCReq(uint8_t* dst, const char* url) {
}
bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t nextCheckin) {
if (nextCheckin > MIN_RESPONSE_TIME) nextCheckin = MIN_RESPONSE_TIME;
if (wsClientCount()) nextCheckin=0;
if (nextCheckin > config.maxsleep) nextCheckin = config.maxsleep;
if (wsClientCount() && config.stopsleep == 1) nextCheckin=0;
tagRecord* taginfo = nullptr;
taginfo = tagRecord::findByMAC(dst);
@@ -507,13 +507,13 @@ void refreshAllPending() {
};
void setAPchannel() {
if (APconfig["channel"].as<int>() == 0) {
if (config.channel == 0) {
// trigger channel autoselect
UDPcomm udpsync;
udpsync.getAPList();
} else {
if (curChannel.channel != APconfig["channel"].as<int>()) {
curChannel.channel = APconfig["channel"].as<int>();
if (curChannel.channel != config.channel) {
curChannel.channel = config.channel;
sendChannelPower(&curChannel);
}
}

View File

@@ -9,7 +9,8 @@
#include "language.h"
std::vector<tagRecord*> tagDB;
DynamicJsonDocument APconfig(150);
Config config;
tagRecord* tagRecord::findByMAC(uint8_t mac[8]) {
for (int16_t c = 0; c < tagDB.size(); c++) {
@@ -245,27 +246,32 @@ void clearPending(tagRecord* taginfo) {
void initAPconfig() {
LittleFS.begin(true);
DynamicJsonDocument APconfig(150);
File configFile = LittleFS.open("/current/apconfig.json", "r");
if (!configFile) {
// default values'
Serial.println("APconfig not found");
APconfig["channel"] = 0;
APconfig["alias"] = String();
APconfig["ledbrightness"] = 255;
APconfig["language"] = getDefaultLanguage();
return;
}
DeserializationError error = deserializeJson(APconfig, configFile);
if (error) {
configFile.close();
Serial.println("apconfig.json file corrupted, or not enough space in apconfig to hold it");
return;
Serial.println("failed to read apconfig.json. Using default config");
}
configFile.close();
config.channel = APconfig["channel"] | 25;
strlcpy(config.alias, APconfig["alias"], sizeof(config.alias));
config.led = APconfig["led"] | 255;
config.language = APconfig["language"] | getDefaultLanguage();
config.maxsleep = APconfig["maxsleep"] | 10;
config.stopsleep = APconfig["stopsleep"] | 1;
}
void saveAPconfig() {
fs::File configFile = LittleFS.open("/current/apconfig.json", "w");
DynamicJsonDocument APconfig(150);
APconfig["channel"] = config.channel;
APconfig["alias"] = config.alias;
APconfig["led"] = config.led;
APconfig["language"] = config.language;
APconfig["maxsleep"] = config.maxsleep;
APconfig["stopsleep"] = config.stopsleep;
serializeJson(APconfig, configFile);
configFile.close();
}

View File

@@ -67,7 +67,7 @@ void UDPcomm::processPacket(AsyncUDPPacket packet) {
APlist APitem;
APitem.src = WiFi.localIP();
strcpy(APitem.alias, APconfig["alias"]);
strcpy(APitem.alias, config.alias);
APitem.channelId = curChannel.channel;
APitem.tagCount = getTagCount();
APitem.version = apInfo.version;
@@ -116,7 +116,7 @@ void autoselect(void* pvParameters) {
if (curChannel.channel == 0) {
curChannel.channel = 11;
}
APconfig["channel"] = curChannel.channel;
config.channel = curChannel.channel;
do {
vTaskDelay(1000 / portTICK_PERIOD_MS);
} while (!apInfo.isOnline);
@@ -131,13 +131,13 @@ void autoselect(void* pvParameters) {
void UDPcomm::getAPList() {
APlist APitem;
APitem.src = WiFi.localIP();
strcpy(APitem.alias, APconfig["alias"]);
strcpy(APitem.alias, config.alias);
APitem.channelId = curChannel.channel;
APitem.tagCount = getTagCount();
APitem.version = apInfo.version;
wsSendAPitem(&APitem);
if (APconfig["channel"].as<int>() == 0) {
if (config.alias == 0) {
xTaskCreate(autoselect, "autoselect", 5000, NULL, configMAX_PRIORITIES - 10, NULL);
}

View File

@@ -21,8 +21,8 @@
extern uint8_t data_to_send[];
const char *http_username = "admin";
const char *http_password = "admin";
//const char *http_username = "admin";
//const char *http_password = "admin";
AsyncWebServer server(80);
AsyncWebSocket ws("/ws");
@@ -224,7 +224,8 @@ void init_web() {
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
server.addHandler(new SPIFFSEditor(LittleFS, http_username, http_password));
//server.addHandler(new SPIFFSEditor(LittleFS, http_username, http_password));
server.addHandler(new SPIFFSEditor(LittleFS));
ws.onEvent(onEvent);
server.addHandler(&ws);
@@ -341,16 +342,28 @@ void init_web() {
server.on("/save_apcfg", HTTP_POST, [](AsyncWebServerRequest *request) {
if (request->hasParam("alias", true) && request->hasParam("channel", true)) {
APconfig["alias"] = request->getParam("alias", true)->value();
APconfig["channel"] = request->getParam("channel", true)->value();
if (request->hasParam("ledbrightness", true)) {
APconfig["ledbrightness"] = request->getParam("ledbrightness", true)->value();
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)) {
APconfig["language"] = request->getParam("language", true)->value();
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());
}
saveAPconfig();
setAPchannel();
}