mirror of
https://github.com/OpenEPaperLink/OpenEPaperLink.git
synced 2026-03-28 15:08:11 +01:00
added advanced tag options
- added advanced tag options: image rotation / always use default lut / force refresh / cancel pending - fixed rx/tx swap in documentation
This commit is contained in:
@@ -29,10 +29,30 @@
|
||||
<button id="paintbutton"><i>A</i>🖌</button>
|
||||
</p>
|
||||
<div id="customoptions"></div>
|
||||
<p>
|
||||
<input type="button" value="Save" id="cfgsave">
|
||||
<span id="cfgdelete"><img src="data:image/gif;base64,R0lGODlhEAAQAPMAANXV1e3t7d/f39HR0dvb2/Hx8dTU1OLi4urq6mZmZpmZmf///wAAAAAAAAAAAAAAACH5BAEAAAwALAAAAAAQABAAAARBkMlJq71Yrp3ZXkr4WWCYnOZSgQVyEMYwJCq1nHhe20qgCAoA7QLyAYU7njE4JPV+zOSkCEUSFbmTVPPpbjvgTAQAOw==
|
||||
"></span>
|
||||
<div id="advancedoptions" style="height: 0px;">
|
||||
<p>Advanced options</p>
|
||||
<p>
|
||||
<label for="cfgrotate">Rotate image</label>
|
||||
<select id="cfgrotate">
|
||||
<option value="0">0 degrees</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="cfglut">LUT</label>
|
||||
<select id="cfglut">
|
||||
<option value="0">auto</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<button id="cfgrefresh">force refresh</button>
|
||||
<button id="cfgclrpending">clear pending</button>
|
||||
<button id="cfgdelete"><img src="data:image/gif;base64,R0lGODlhEAAQAPMAANXV1e3t7d/f39HR0dvb2/Hx8dTU1OLi4urq6mZmZpmZmf///wAAAAAAAAAAAAAAACH5BAEAAAwALAAAAAAQABAAAARBkMlJq71Yrp3ZXkr4WWCYnOZSgQVyEMYwJCq1nHhe20qgCAoA7QLyAYU7njE4JPV+zOSkCEUSFbmTVPPpbjvgTAQAOw==
|
||||
"></button>
|
||||
</p>
|
||||
</div>
|
||||
<p id="savebar">
|
||||
<span><input type="button" value="Save" id="cfgsave"></span>
|
||||
<span id="cfgmore" title="advanced options">🞃</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -159,8 +179,8 @@ Latency will be around 40 seconds.">
|
||||
<div class="nextcheckin"></div>
|
||||
<div class="nextupdate"></div>
|
||||
<div class="corner">
|
||||
<div class="pendingicon">↻</div>
|
||||
<div class="warningicon">⚠</div>
|
||||
<div class="pendingicon" title="A new message is waiting for the tag to pick up">↻</div>
|
||||
<div class="warningicon" title="This tag has nog been seen for a long time">⚠</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -142,6 +142,33 @@ select {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
#advancedoptions {
|
||||
overflow: hidden;
|
||||
transition: height 0.3s ease;
|
||||
}
|
||||
|
||||
#advancedoptions p:first-child {
|
||||
font-weight: 700;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
#savebar {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#savebar:first-child {
|
||||
flex-grow: 2;
|
||||
}
|
||||
|
||||
#cfgmore {
|
||||
padding: 2px 5px;
|
||||
font-weight: 700;
|
||||
font-size: 1.2em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#apconfigbox {
|
||||
background-color: #e6f0d3;
|
||||
}
|
||||
@@ -179,10 +206,8 @@ select {
|
||||
}
|
||||
|
||||
#cfgdelete {
|
||||
position: absolute;
|
||||
bottom: 15px;
|
||||
right: 15px;
|
||||
cursor:pointer;
|
||||
cursor: pointer;
|
||||
padding: 2px 10px;
|
||||
}
|
||||
|
||||
.closebtn {
|
||||
|
||||
@@ -11,8 +11,9 @@ const WAKEUP_REASON_WDT_RESET = 0xFE;
|
||||
const models = ["1.54\" 152x152px", "2.9\" 296x128px", "4.2\" 400x300px"];
|
||||
models[240] = "Segmented tag"
|
||||
models[17] = "2.9\" 296x128px (UC8151)"
|
||||
const displaySizeLookup = { 0: [152, 152], 1: [128, 296], 2: [400, 300] };
|
||||
displaySizeLookup[17] = [128, 296];
|
||||
const displaySizeLookup = { 0: [152, 152, 4], 1: [128, 296, 2], 2: [400, 300, 2] }; // w, h, rotate
|
||||
displaySizeLookup[17] = [128, 296, 2];
|
||||
displaySizeLookup[240] = [0, 0, 0];
|
||||
const colorTable = { 0: [255, 255, 255], 1: [0, 0, 0], 2: [255, 0, 0], 3: [150, 150, 150] };
|
||||
|
||||
const apstate = [
|
||||
@@ -272,6 +273,7 @@ $('#clearlog').onclick = function () {
|
||||
document.querySelectorAll('.closebtn').forEach(button => {
|
||||
button.addEventListener('click', (event) => {
|
||||
event.target.parentNode.style.display = 'none';
|
||||
$('#advancedoptions').style.height = '0px';
|
||||
});
|
||||
});
|
||||
|
||||
@@ -295,19 +297,29 @@ $('#taglist').addEventListener("click", (event) => {
|
||||
.then(data => {
|
||||
var tagdata = data.tags[0];
|
||||
$('#cfgalias').value = tagdata.alias;
|
||||
$('#cfgmore').style.display = "none";
|
||||
if (populateSelectTag(tagdata.hwType, tagdata.capabilities)) {
|
||||
$('#cfgcontent').parentNode.style.display = "flex";
|
||||
$('#cfgcontent').value = tagdata.contentMode;
|
||||
$('#cfgcontent').dataset.json = tagdata.modecfgjson;
|
||||
contentselected();
|
||||
if (tagdata.contentMode != 12) $('#cfgmore').style.display = 'block';
|
||||
} else {
|
||||
$('#customoptions').innerHTML = "";
|
||||
$('#cfgcontent').parentNode.style.display = "none";
|
||||
}
|
||||
$('#cfgrotate').value = tagdata.rotate;
|
||||
$('#cfglut').value = tagdata.lut;
|
||||
$('#cfgmore').innerHTML = '🞃';
|
||||
$('#configbox').style.display = 'block';
|
||||
})
|
||||
})
|
||||
|
||||
$('#cfgmore').onclick = function () {
|
||||
$('#cfgmore').innerHTML = $('#advancedoptions').style.height == '0px' ? '🞁' : '🞃';
|
||||
$('#advancedoptions').style.height = $('#advancedoptions').style.height == '0px' ? $('#advancedoptions').scrollHeight + 'px' : '0px';
|
||||
};
|
||||
|
||||
$('#cfgsave').onclick = function () {
|
||||
let contentMode = $('#cfgcontent').value;
|
||||
let contentDef = getContentDefById(contentMode);
|
||||
@@ -332,6 +344,9 @@ $('#cfgsave').onclick = function () {
|
||||
formData.append("modecfgjson", String());
|
||||
}
|
||||
|
||||
formData.append("rotate", $('#cfgrotate').value);
|
||||
formData.append("lut", $('#cfglut').value);
|
||||
|
||||
fetch("/save_cfg", {
|
||||
method: "POST",
|
||||
body: formData
|
||||
@@ -340,26 +355,41 @@ $('#cfgsave').onclick = function () {
|
||||
.then(data => showMessage(data))
|
||||
.catch(error => showMessage('Error: ' + error));
|
||||
|
||||
$('#advancedoptions').style.height = '0px';
|
||||
$('#configbox').style.display = 'none';
|
||||
}
|
||||
|
||||
$('#cfgdelete').onclick = function () {
|
||||
function sendCmd(mac, cmd) {
|
||||
let formData = new FormData();
|
||||
formData.append("mac", $('#cfgmac').dataset.mac);
|
||||
fetch("/delete_cfg", {
|
||||
formData.append("mac", mac);
|
||||
formData.append("cmd", cmd);
|
||||
fetch("/tag_cmd", {
|
||||
method: "POST",
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
var div = $('#tag' + $('#cfgmac').dataset.mac);
|
||||
div.remove();
|
||||
if (cmd == "del") div.remove();
|
||||
showMessage(data);
|
||||
})
|
||||
.catch(error => showMessage('Error: ' + error));
|
||||
$('#advancedoptions').style.height = '0px';
|
||||
$('#configbox').style.display = 'none';
|
||||
}
|
||||
|
||||
$('#cfgdelete').onclick = function () {
|
||||
sendCmd($('#cfgmac').dataset.mac, "del");
|
||||
}
|
||||
|
||||
$('#cfgclrpending').onclick = function () {
|
||||
sendCmd($('#cfgmac').dataset.mac, "clear");
|
||||
}
|
||||
|
||||
$('#cfgrefresh').onclick = function () {
|
||||
sendCmd($('#cfgmac').dataset.mac, "refresh");
|
||||
}
|
||||
|
||||
$('#rebootbutton').onclick = function () {
|
||||
showMessage("rebooting AP....", true);
|
||||
fetch("/reboot", {
|
||||
@@ -459,7 +489,6 @@ function contentselected() {
|
||||
obj = JSON.parse($('#cfgcontent').dataset.json);
|
||||
}
|
||||
$('#paintbutton').style.display = 'none';
|
||||
|
||||
if (contentMode) {
|
||||
let contentDef = getContentDefById(contentMode);
|
||||
if (contentDef) {
|
||||
@@ -514,17 +543,46 @@ function populateSelectTag(hwtype, capabilities) {
|
||||
var selectTag = $("#cfgcontent");
|
||||
selectTag.innerHTML = "";
|
||||
var optionsAdded = false;
|
||||
var option;
|
||||
cardconfig.forEach(item => {
|
||||
var capcheck = item.capabilities ?? 0;
|
||||
var hwtypeArray = item.hwtype;
|
||||
if (hwtypeArray.includes(hwtype) && (capabilities & capcheck || capcheck == 0)) {
|
||||
var option = document.createElement("option");
|
||||
option = document.createElement("option");
|
||||
option.value = item.id;
|
||||
option.text = item.name;
|
||||
selectTag.appendChild(option);
|
||||
optionsAdded = true;
|
||||
}
|
||||
});
|
||||
|
||||
var rotateTag = $("#cfgrotate");
|
||||
rotateTag.innerHTML = "";
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
if (i == 0 || displaySizeLookup[hwtype][2] == 4 || (i == 2 && displaySizeLookup[hwtype][2] == 2)) {
|
||||
option = document.createElement("option");
|
||||
option.value = i;
|
||||
option.text = (i * 90) + " degrees";
|
||||
rotateTag.appendChild(option);
|
||||
}
|
||||
}
|
||||
|
||||
var lutTag = $("#cfglut");
|
||||
lutTag.innerHTML = "";
|
||||
|
||||
option = document.createElement("option");
|
||||
option.value = "0";
|
||||
option.text = "auto";
|
||||
lutTag.appendChild(option);
|
||||
|
||||
if (hwtype != 240) {
|
||||
option = document.createElement("option");
|
||||
option.value = "1";
|
||||
option.text = "Always full refresh";
|
||||
lutTag.appendChild(option);
|
||||
}
|
||||
|
||||
return optionsAdded;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ struct imgParam {
|
||||
bool dither;
|
||||
bool grayLut = false;
|
||||
uint8_t bpp = 8;
|
||||
uint8_t rotate = 0;
|
||||
|
||||
char segments[12];
|
||||
uint16_t symbols;
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
class tagRecord {
|
||||
public:
|
||||
tagRecord() : mac{0}, alias(""), lastseen(0), nextupdate(0), contentMode(0), pending(false), md5{0}, md5pending{0}, expectedNextCheckin(0), modeConfigJson(""), LQI(0), RSSI(0), temperature(0), batteryMv(0), hwType(0), wakeupReason(0), capabilities(0), lastfullupdate(0), isExternal(false), pendingIdle(0), hasCustomLUT(false),
|
||||
filename(""), data(nullptr), len(0) {}
|
||||
tagRecord() : mac{0}, alias(""), lastseen(0), nextupdate(0), contentMode(0), pending(false), md5{0}, md5pending{0}, expectedNextCheckin(0), modeConfigJson(""), LQI(0), RSSI(0), temperature(0), batteryMv(0), hwType(0), wakeupReason(0), capabilities(0), lastfullupdate(0), isExternal(false), pendingIdle(0), hasCustomLUT(false), rotate(0), lut(0),
|
||||
dataType(0), filename(""), data(nullptr), len(0) {}
|
||||
|
||||
uint8_t mac[8];
|
||||
String alias;
|
||||
@@ -41,6 +41,10 @@ class tagRecord {
|
||||
bool isExternal;
|
||||
uint16_t pendingIdle;
|
||||
bool hasCustomLUT;
|
||||
uint8_t rotate;
|
||||
uint8_t lut;
|
||||
|
||||
uint8_t dataType;
|
||||
String filename;
|
||||
uint8_t* data;
|
||||
uint32_t len;
|
||||
|
||||
@@ -128,10 +128,11 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
|
||||
imageParams.hasRed = false;
|
||||
imageParams.dataType = DATATYPE_IMG_RAW_1BPP;
|
||||
imageParams.dither = false;
|
||||
if (taginfo->hasCustomLUT) imageParams.grayLut = true;
|
||||
if (taginfo->hasCustomLUT && taginfo->lut != 1) imageParams.grayLut = true;
|
||||
|
||||
imageParams.invert = false;
|
||||
imageParams.symbols = 0;
|
||||
imageParams.rotate = taginfo->rotate;
|
||||
|
||||
switch (taginfo->contentMode) {
|
||||
case Image:
|
||||
@@ -1002,7 +1003,7 @@ void prepareLUTreq(uint8_t *dst, String input) {
|
||||
void getTemplate(JsonDocument &json, const char *filePath, uint8_t id, uint8_t hwtype) {
|
||||
File jsonFile = LittleFS.open(filePath, "r");
|
||||
if (!jsonFile) {
|
||||
Serial.println("Failed to open JSON file");
|
||||
Serial.println("Failed to open content template file " + String(filePath));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,11 +80,12 @@ void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) {
|
||||
|
||||
fs::File f_out = LittleFS.open(fileout, "w");
|
||||
|
||||
bool dither = true, rotated = false;
|
||||
bool dither = true;
|
||||
uint8_t rotate = imageParams.rotate;
|
||||
long bufw = spr.width(), bufh = spr.height();
|
||||
|
||||
if (bufw > bufh && bufw!=400 && bufh!=300) {
|
||||
rotated = true;
|
||||
rotate = (rotate + 3) % 4;
|
||||
bufw = spr.height();
|
||||
bufh = spr.width();
|
||||
}
|
||||
@@ -115,10 +116,19 @@ void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) {
|
||||
for (uint16_t y = 0; y < bufh; y++) {
|
||||
memset(error_buffernew, 0, bufw * sizeof(Error));
|
||||
for (uint16_t x = 0; x < bufw; x++) {
|
||||
if (rotated) {
|
||||
color = Color(spr.readPixel(bufh - 1 - y, x));
|
||||
} else {
|
||||
color = Color(spr.readPixel(x, y));
|
||||
switch (rotate) {
|
||||
case 0:
|
||||
color = Color(spr.readPixel(x, y));
|
||||
break;
|
||||
case 1:
|
||||
color = Color(spr.readPixel(y, bufw - 1 - x));
|
||||
break;
|
||||
case 2:
|
||||
color = Color(spr.readPixel(bufw - 1 - x, bufh - 1 - y));
|
||||
break;
|
||||
case 3:
|
||||
color = Color(spr.readPixel(bufh - 1 - y, x));
|
||||
break;
|
||||
}
|
||||
|
||||
int best_color_index = 0;
|
||||
|
||||
@@ -98,6 +98,7 @@ void prepareDataAvail(uint8_t* data, uint16_t len, uint8_t dataType, uint8_t* ds
|
||||
taginfo->len = len;
|
||||
taginfo->expectedNextCheckin = 0;
|
||||
taginfo->filename = String();
|
||||
taginfo->dataType = dataType;
|
||||
memset(taginfo->md5pending, 0, 16 * sizeof(uint8_t));
|
||||
|
||||
struct pendingData pending = {0};
|
||||
@@ -168,11 +169,11 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
|
||||
time_t now;
|
||||
time(&now);
|
||||
time_t last_midnight = now - now % (24 * 60 * 60) + 3 * 3600; // somewhere in the middle of the night
|
||||
if (taginfo->lastfullupdate < last_midnight || taginfo->hwType == SOLUM_29_UC8151) {
|
||||
if (taginfo->lastfullupdate < last_midnight || taginfo->hwType == SOLUM_29_UC8151 || taginfo->lut == 1) {
|
||||
lut = EPD_LUT_DEFAULT; // full update once a day
|
||||
taginfo->lastfullupdate = now;
|
||||
}
|
||||
if (taginfo->hasCustomLUT && taginfo->capabilities & CAPABILITY_SUPPORTS_CUSTOM_LUTS) {
|
||||
if (taginfo->hasCustomLUT && taginfo->capabilities & CAPABILITY_SUPPORTS_CUSTOM_LUTS && taginfo->lut != 1) {
|
||||
Serial.println("using custom LUT");
|
||||
lut = EPD_LUT_OTA;
|
||||
}
|
||||
@@ -190,16 +191,18 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
|
||||
time_t now;
|
||||
time(&now);
|
||||
taginfo->expectedNextCheckin = now + nextCheckin * 60 + 60;
|
||||
clearPending(taginfo);
|
||||
taginfo->filename = *filename;
|
||||
taginfo->len = filesize;
|
||||
clearPending(taginfo);
|
||||
taginfo->dataType = dataType;
|
||||
taginfo->pending = true;
|
||||
memcpy(taginfo->md5pending, md5bytes, sizeof(md5bytes));
|
||||
} else {
|
||||
wsLog("firmware upload pending");
|
||||
clearPending(taginfo);
|
||||
taginfo->filename = *filename;
|
||||
taginfo->len = filesize;
|
||||
clearPending(taginfo);
|
||||
taginfo->dataType = dataType;
|
||||
taginfo->pending = true;
|
||||
}
|
||||
|
||||
@@ -272,9 +275,10 @@ void prepareExternalDataAvail(struct pendingData* pending, IPAddress remoteIP) {
|
||||
}
|
||||
|
||||
file.close();
|
||||
clearPending(taginfo);
|
||||
taginfo->filename = filename;
|
||||
taginfo->len = filesize;
|
||||
clearPending(taginfo);
|
||||
taginfo->dataType = pending->availdatainfo.dataType;
|
||||
taginfo->pending = true;
|
||||
memcpy(taginfo->md5pending, md5bytes, sizeof(md5bytes));
|
||||
break;
|
||||
@@ -296,6 +300,7 @@ void prepareExternalDataAvail(struct pendingData* pending, IPAddress remoteIP) {
|
||||
taginfo->data = new uint8_t[len];
|
||||
WiFiClient* stream = http.getStreamPtr();
|
||||
stream->readBytes(taginfo->data, len);
|
||||
taginfo->dataType = pending->availdatainfo.dataType;
|
||||
taginfo->pending = true;
|
||||
taginfo->len = len;
|
||||
}
|
||||
@@ -334,7 +339,7 @@ void processBlockRequest(struct espBlockRequest* br) {
|
||||
// not cached. open file, cache the data
|
||||
fs::File file = LittleFS.open(taginfo->filename);
|
||||
if (!file) {
|
||||
Serial.print("Dunno how this happened... File pending but deleted in the meantime?\n");
|
||||
Serial.print("No current file. Canceling request\n");
|
||||
prepareCancelPending(br->src);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -690,7 +690,7 @@ void APTask(void* parameter) {
|
||||
Serial.println("I wasn't able to connect to a ZBS (AP) tag.\n");
|
||||
Serial.printf("This could be the first time this AP is booted and the AP-tag may be unflashed. We'll try to flash it!\n");
|
||||
Serial.printf("If this tag was previously flashed succesfully but this message still shows up, there's probably something wrong with the serial connections.\n");
|
||||
Serial.printf("The build of this firmware expects an AP tag with RXD/TXD on ESP32 pins %d and %d, does this match with your wiring?\n", FLASHER_AP_RXD, FLASHER_AP_TXD);
|
||||
Serial.printf("The build of this firmware expects an AP tag with TXD/RXD on ESP32 pins %d and %d, does this match with your wiring?\n", FLASHER_AP_RXD, FLASHER_AP_TXD);
|
||||
Serial.println("Performing firmware flash in about 30 seconds!\n");
|
||||
flashCountDown(30);
|
||||
if (doAPFlash()) {
|
||||
@@ -729,8 +729,8 @@ void APTask(void* parameter) {
|
||||
Serial.println("Seems like you're running into some issues with the wiring, or (very small chance) the tag itself");
|
||||
Serial.println("This ESP32-build expects the following pins connected to the ZBS243:");
|
||||
Serial.println("--- ZBS243 based tag ESP32 ---");
|
||||
Serial.printf(" RXD ---------------- %02d\n", FLASHER_AP_RXD);
|
||||
Serial.printf(" TXD ---------------- %02d\n", FLASHER_AP_TXD);
|
||||
Serial.printf(" TXD ---------------- %02d\n", FLASHER_AP_RXD);
|
||||
Serial.printf(" RXD ---------------- %02d\n", FLASHER_AP_TXD);
|
||||
Serial.printf(" CS/SS ---------------- %02d\n", FLASHER_AP_SS);
|
||||
Serial.printf(" MOSI ---------------- %02d\n", FLASHER_AP_MOSI);
|
||||
Serial.printf(" MISO ---------------- %02d\n", FLASHER_AP_MISO);
|
||||
|
||||
@@ -117,6 +117,8 @@ void fillNode(JsonObject &tag, tagRecord* &taginfo) {
|
||||
tag["capabilities"] = taginfo->capabilities;
|
||||
tag["modecfgjson"] = taginfo->modeConfigJson;
|
||||
tag["isexternal"] = taginfo->isExternal;
|
||||
tag["rotate"] = taginfo->rotate;
|
||||
tag["lut"] = taginfo->lut;
|
||||
}
|
||||
|
||||
void saveDB(String filename) {
|
||||
@@ -210,6 +212,8 @@ void loadDB(String filename) {
|
||||
taginfo->capabilities = tag["capabilities"];
|
||||
taginfo->modeConfigJson = tag["modecfgjson"].as<String>();
|
||||
taginfo->isExternal = tag["isexternal"].as<bool>();
|
||||
taginfo->rotate = tag["rotate"] | 0;
|
||||
taginfo->lut = tag["lut"] | 0;
|
||||
}
|
||||
} else {
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
@@ -251,6 +255,7 @@ uint8_t getTagCount() {
|
||||
}
|
||||
|
||||
void clearPending(tagRecord* taginfo) {
|
||||
taginfo->filename = String();
|
||||
if (taginfo->data != nullptr) {
|
||||
free(taginfo->data);
|
||||
taginfo->data = nullptr;
|
||||
|
||||
@@ -319,6 +319,12 @@ void init_web() {
|
||||
taginfo->modeConfigJson = request->getParam("modecfgjson", true)->value();
|
||||
taginfo->contentMode = atoi(request->getParam("contentmode", true)->value().c_str());
|
||||
taginfo->nextupdate = 0;
|
||||
if (request->hasParam("rotate", true)) {
|
||||
taginfo->rotate = atoi(request->getParam("rotate", true)->value().c_str());
|
||||
}
|
||||
if (request->hasParam("lut", true)) {
|
||||
taginfo->lut = atoi(request->getParam("lut", true)->value().c_str());
|
||||
}
|
||||
// memset(taginfo->md5, 0, 16 * sizeof(uint8_t));
|
||||
// memset(taginfo->md5pending, 0, 16 * sizeof(uint8_t));
|
||||
wsSendTaginfo(mac, SYNC_USERCFG);
|
||||
@@ -332,20 +338,33 @@ void init_web() {
|
||||
request->send(200, "text/plain", "Ok, saved");
|
||||
});
|
||||
|
||||
server.on("/delete_cfg", HTTP_POST, [](AsyncWebServerRequest *request) {
|
||||
if (request->hasParam("mac", true)) {
|
||||
String dst = request->getParam("mac", true)->value();
|
||||
server.on("/tag_cmd", HTTP_POST, [](AsyncWebServerRequest *request) {
|
||||
if (request->hasParam("mac", true) && request->hasParam("cmd", true)) {
|
||||
uint8_t mac[8];
|
||||
if (hex2mac(dst, mac)) {
|
||||
wsSendTaginfo(mac, SYNC_DELETE);
|
||||
if (deleteRecord(mac)) {
|
||||
request->send(200, "text/plain", "Ok, deleted");
|
||||
if (hex2mac(request->getParam("mac", true)->value(), mac)) {
|
||||
tagRecord *taginfo = nullptr;
|
||||
taginfo = tagRecord::findByMAC(mac);
|
||||
if (taginfo != nullptr) {
|
||||
const char *cmdValue = request->getParam("cmd", true)->value().c_str();
|
||||
if (strcmp(cmdValue, "del") == 0) {
|
||||
wsSendTaginfo(mac, SYNC_DELETE);
|
||||
deleteRecord(mac);
|
||||
}
|
||||
if (strcmp(cmdValue, "clear") == 0) {
|
||||
clearPending(taginfo);
|
||||
memcpy(taginfo->md5pending, taginfo->md5, sizeof(taginfo->md5pending));
|
||||
wsSendTaginfo(mac, SYNC_TAGSTATUS);
|
||||
}
|
||||
if (strcmp(cmdValue, "refresh") == 0) {
|
||||
updateContent(mac);
|
||||
}
|
||||
request->send(200, "text/plain", "Ok, done");
|
||||
} else {
|
||||
request->send(200, "text/plain", "Error while saving: mac not found");
|
||||
request->send(200, "text/plain", "Error: mac not found");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
request->send(500, "text/plain", "no mac");
|
||||
request->send(500, "text/plain", "param error");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user