Various fixes

- bugfix not recognizing identical image
https://github.com/jjwbruijn/OpenEPaperLink/issues/255
- Count number of updates
https://github.com/jjwbruijn/OpenEPaperLink/issues/247
- Optionally align interval of RSS/calendar/etc
https://github.com/jjwbruijn/OpenEPaperLink/issues/106
This commit is contained in:
Nic Limper
2024-03-18 16:39:44 +01:00
parent 68d75782ba
commit 59e2a5eeb8
7 changed files with 50 additions and 29 deletions

View File

@@ -71,6 +71,15 @@
"type":1,
"note":"2.9 v032 FW"
},
{
"name": "2.9 White - 4rd",
"mac_offset": 64518,
"mac_format": 1,
"mac_suffix": "3B10",
"MD5": "52B8F6316BC2EB45231B23B2CD563B80",
"type": 1,
"note": "2.9 v031 FW"
},
{
"name":"2.9 White + NFC UC8151",
"mac_offset":64518,

View File

@@ -13,4 +13,5 @@
// flasher options
#define CUSTOM_MAC_HDR 0x0000
#define MAX_XFER_ATTEMPTS 20
#define MAX_WRITE_ATTEMPTS 5

View File

@@ -15,7 +15,7 @@
#define NO_SUBGHZ_CHANNEL 255
class tagRecord {
public:
tagRecord() : mac{0}, version(0), alias(""), lastseen(0), nextupdate(0), contentMode(0), pendingCount(0), md5{0}, expectedNextCheckin(0), modeConfigJson(""), LQI(0), RSSI(0), temperature(0), batteryMv(0), hwType(0), wakeupReason(0), capabilities(0), lastfullupdate(0), isExternal(false), apIp(IPAddress(0, 0, 0, 0)), pendingIdle(0), hasCustomLUT(false), rotate(0), lut(0), tagSoftwareVersion(0), currentChannel(0), dataType(0), filename(""), data(nullptr), len(0), invert(0) {}
tagRecord() : mac{0}, version(0), alias(""), lastseen(0), nextupdate(0), contentMode(0), pendingCount(0), md5{0}, expectedNextCheckin(0), modeConfigJson(""), LQI(0), RSSI(0), temperature(0), batteryMv(0), hwType(0), wakeupReason(0), capabilities(0), lastfullupdate(0), isExternal(false), apIp(IPAddress(0, 0, 0, 0)), pendingIdle(0), hasCustomLUT(false), rotate(0), lut(0), tagSoftwareVersion(0), currentChannel(0), dataType(0), filename(""), data(nullptr), len(0), invert(0), updateCount(0) {}
uint8_t mac[8];
uint8_t version;
@@ -44,6 +44,7 @@ class tagRecord {
uint16_t tagSoftwareVersion;
uint8_t currentChannel;
uint8_t invert;
uint32_t updateCount;
uint8_t dataType;
String filename;

View File

@@ -235,6 +235,17 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
imageParams.lut = EPD_LUT_OTA;
}
int32_t interval = 60 * 60;
interval = cfgobj["interval"].as<int>() * 60;
Serial.println("interval: " + String(interval));
if (interval < 0) {
interval = -interval;
unsigned int secondsUntilNext = (interval - (now % interval)) % interval;
interval = secondsUntilNext;
Serial.println("seconds until next: " + String(interval));
} else if (interval < 180)
interval = 60 * 60;
switch (taginfo->contentMode) {
case 0: // Not configured
case 22: // Static image
@@ -363,13 +374,12 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
{
const int httpcode = getImgURL(filename, cfgobj["url"], (time_t)cfgobj["#fetched"], imageParams, String(hexmac));
const int interval = cfgobj["interval"].as<int>();
if (httpcode == 200) {
taginfo->nextupdate = now + 60 * (interval < 3 ? 15 : interval);
updateTagImage(filename, mac, interval, taginfo, imageParams);
taginfo->nextupdate = now + interval;
updateTagImage(filename, mac, interval / 60, taginfo, imageParams);
cfgobj["#fetched"] = now;
} else if (httpcode == 304) {
taginfo->nextupdate = now + 60 * (interval < 3 ? 15 : interval);
taginfo->nextupdate = now + interval;
} else {
taginfo->nextupdate = now + 300;
}
@@ -380,9 +390,8 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
case 9: // RSSFeed
if (getRssFeed(filename, cfgobj["url"], cfgobj["title"], taginfo, imageParams)) {
const int interval = cfgobj["interval"].as<int>();
taginfo->nextupdate = now + 60 * (interval < 3 ? 60 : interval);
updateTagImage(filename, mac, interval, taginfo, imageParams);
taginfo->nextupdate = now + interval;
updateTagImage(filename, mac, interval / 60, taginfo, imageParams);
} else {
taginfo->nextupdate = now + 300;
}
@@ -402,9 +411,8 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
case 11: // Calendar:
if (getCalFeed(filename, cfgobj, taginfo, imageParams)) {
const int interval = cfgobj["interval"].as<int>();
taginfo->nextupdate = now + 60 * (interval < 3 ? 15 : interval);
updateTagImage(filename, mac, interval, taginfo, imageParams);
taginfo->nextupdate = now + interval;
updateTagImage(filename, mac, interval / 60, taginfo, imageParams);
} else {
taginfo->nextupdate = now + 300;
}
@@ -474,13 +482,12 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
DynamicJsonDocument json(1000);
Serial.println("Get json url + file");
if (util::httpGetJson(configUrl, json, 1000)) {
taginfo->nextupdate = now + interval;
if (getJsonTemplateFileExtractVariables(filename, configFilename, json, taginfo, imageParams)) {
updateTagImage(filename, mac, cfgobj["interval"].as<int>(), taginfo, imageParams);
updateTagImage(filename, mac, interval / 60, taginfo, imageParams);
} else {
wsErr("error opening file " + configFilename);
}
const int interval = cfgobj["interval"].as<int>();
taginfo->nextupdate = now + 60 * (interval < 3 ? 15 : interval);
} else {
taginfo->nextupdate = now + 600;
}
@@ -488,7 +495,7 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
} else {
const bool result = getJsonTemplateFile(filename, configFilename, taginfo, imageParams);
if (result) {
updateTagImage(filename, mac, cfgobj["interval"].as<int>(), taginfo, imageParams);
updateTagImage(filename, mac, interval, taginfo, imageParams);
} else {
wsErr("error opening file " + configFilename);
}
@@ -496,13 +503,12 @@ void drawNew(const uint8_t mac[8], tagRecord *&taginfo) {
}
} else {
const int httpcode = getJsonTemplateUrl(filename, cfgobj["url"], (time_t)cfgobj["#fetched"], String(hexmac), taginfo, imageParams);
const int interval = cfgobj["interval"].as<int>();
if (httpcode == 200) {
taginfo->nextupdate = now + 60 * (interval < 3 ? 15 : interval);
updateTagImage(filename, mac, interval, taginfo, imageParams);
taginfo->nextupdate = now + interval;
updateTagImage(filename, mac, interval / 60, taginfo, imageParams);
cfgobj["#fetched"] = now;
} else if (httpcode == 304) {
taginfo->nextupdate = now + 60 * (interval < 3 ? 15 : interval);
taginfo->nextupdate = now + interval;
} else {
taginfo->nextupdate = now + 600;
}
@@ -558,6 +564,7 @@ bool updateTagImage(String &filename, const uint8_t *dst, uint16_t nextCheckin,
imageParams.dataType = DATATYPE_IMG_RAW_2BPP;
Serial.println("datatype: DATATYPE_IMG_RAW_2BPP");
}
if (nextCheckin > 0x7fff) nextCheckin = 0;
prepareDataAvail(filename, imageParams.dataType, imageParams.lut, dst, nextCheckin);
}
return true;

View File

@@ -207,9 +207,8 @@ bool prepareDataAvail(String& filename, uint8_t dataType, uint8_t dataTypeArgume
}
file.close();
uint16_t attempts = 60 * 24;
if (memcmp(md5bytes, taginfo->md5, 16) == 0) {
if (memcmp(md5bytes, taginfo->md5, 8) == 0) {
wsLog("new image is the same as current image. not updating tag.");
wsSendTaginfo(dst, SYNC_TAGSTATUS);
if (contentFS->exists(filename) && resend == false) {
@@ -251,7 +250,7 @@ bool prepareDataAvail(String& filename, uint8_t dataType, uint8_t dataTypeArgume
pending.availdatainfo.dataSize = filesize;
pending.availdatainfo.dataTypeArgument = dataTypeArgument;
pending.availdatainfo.nextCheckIn = nextCheckin;
pending.attemptsLeft = attempts;
pending.attemptsLeft = MAX_XFER_ATTEMPTS;
checkMirror(taginfo, &pending);
queueDataAvail(&pending, !taginfo->isExternal);
if (taginfo->isExternal == false) {
@@ -453,6 +452,7 @@ void processXferComplete(struct espXferComplete* xfc, bool local) {
}
}
memcpy(md5bytes, &queueItem->pendingdata.availdatainfo.dataVer, sizeof(uint64_t));
memset(md5bytes + sizeof(uint64_t), 0, 16 - sizeof(uint64_t));
dequeueItem(xfc->src);
}
@@ -460,6 +460,7 @@ void processXferComplete(struct espXferComplete* xfc, bool local) {
if (taginfo != nullptr) {
clearPending(taginfo);
memcpy(taginfo->md5, md5bytes, sizeof(md5bytes));
taginfo->updateCount++;
taginfo->pendingCount = countQueueItem(xfc->src);
taginfo->wakeupReason = 0;
if (taginfo->contentMode == 12 && local == false) {
@@ -684,7 +685,7 @@ bool sendAPSegmentedData(const uint8_t* dst, String data, uint16_t icons, bool i
memcpy((void*)&(pending.availdatainfo.dataVer), data.c_str(), 10);
pending.availdatainfo.dataTypeArgument = inverted;
pending.availdatainfo.nextCheckIn = 0;
pending.attemptsLeft = 120;
pending.attemptsLeft = MAX_XFER_ATTEMPTS;
Serial.printf(">AP Segmented Data %02X%02X%02X%02X%02X%02X%02X%02X\n\0", dst[7], dst[6], dst[5], dst[4], dst[3], dst[2], dst[1], dst[0]);
if (local) {
return queueDataAvail(&pending, true);
@@ -703,7 +704,7 @@ bool showAPSegmentedInfo(const uint8_t* dst, bool local) {
pending.availdatainfo.dataVer = 0x00;
pending.availdatainfo.dataTypeArgument = 0;
pending.availdatainfo.nextCheckIn = 0;
pending.attemptsLeft = 120;
pending.attemptsLeft = MAX_XFER_ATTEMPTS;
Serial.printf(">SDA %02X%02X%02X%02X%02X%02X%02X%02X\n\0", dst[7], dst[6], dst[5], dst[4], dst[3], dst[2], dst[1], dst[0]);
if (local) {
return queueDataAvail(&pending, true);
@@ -724,7 +725,7 @@ bool sendTagCommand(const uint8_t* dst, uint8_t cmd, bool local, const uint8_t*
memcpy(&pending.availdatainfo.dataVer, payload, sizeof(uint64_t));
memcpy(&pending.availdatainfo.dataSize, payload + sizeof(uint64_t), sizeof(uint32_t));
}
pending.attemptsLeft = 120;
pending.attemptsLeft = MAX_XFER_ATTEMPTS;
Serial.printf(">Tag CMD %02X%02X%02X%02X%02X%02X%02X%02X\n\0", dst[7], dst[6], dst[5], dst[4], dst[3], dst[2], dst[1], dst[0]);
tagRecord* taginfo = tagRecord::findByMAC(dst);

View File

@@ -119,6 +119,7 @@ void fillNode(JsonObject& tag, const tagRecord* taginfo) {
tag["rotate"] = taginfo->rotate;
tag["lut"] = taginfo->lut;
tag["invert"] = taginfo->invert;
tag["updatecount"] = taginfo->updateCount;
tag["ch"] = taginfo->currentChannel;
tag["ver"] = taginfo->tagSoftwareVersion;
}
@@ -226,6 +227,7 @@ bool loadDB(const String& filename) {
taginfo->rotate = tag["rotate"] | 0;
taginfo->lut = tag["lut"] | 0;
taginfo->invert = tag["invert"] | 0;
taginfo->updateCount = tag["updatecount"] | 0;
taginfo->currentChannel = tag["ch"] | 0;
taginfo->tagSoftwareVersion = tag["ver"] | 0;
}

View File

@@ -212,7 +212,7 @@
{
"key": "interval",
"name": "Interval",
"desc": "How often (in minutes) the feed is being refreshed",
"desc": "How often (in minutes) the feed is being refreshed. Negative value to align the interval (-60 is 'on the whole hour')",
"type": "int"
}
]
@@ -231,7 +231,7 @@
{
"key": "interval",
"name": "Interval",
"desc": "How often (in minutes) the image is being fetched. Minimum is 3 minutes.",
"desc": "How often (in minutes) the image is being fetched. Minimum is 3 minutes. Negative value to align the interval (-60 is 'on the whole hour')",
"type": "int"
}
]
@@ -276,7 +276,7 @@
{
"key": "interval",
"name": "Interval",
"desc": "How often (in minutes) the calendar is being refreshed",
"desc": "How often (in minutes) the calendar is being refreshed. Negative value to align the interval (-60 is 'on the whole hour')",
"type": "int"
}
]
@@ -411,7 +411,7 @@
{
"key": "interval",
"name": "Interval",
"desc": "In case of an url, how often (in minutes) the template is being fetched. Minimum is 3 minutes.",
"desc": "In case of an url, how often (in minutes) the template is being fetched. Minimum is 3 minutes. Negative value to align the interval (-60 is 'on the whole hour')",
"type": "int"
}
]