Merge pull request #14 from nlimper/development

new content and improvements
This commit is contained in:
Nic Limper
2023-02-15 14:59:31 +01:00
committed by GitHub
14 changed files with 285 additions and 58 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -30,6 +30,8 @@
<option value="2">count days</option>
<option value="3">count hours</option>
<option value="4">current weather</option>
<option value="8">weather forecast</option>
<option value="9">rss feed</option>
<option value="6">memo text</option>
<option value="7">image url</option>
<option value="5">firmware update</option>

View File

@@ -1,6 +1,13 @@
const $ = document.querySelector.bind(document);
const contentModes = ["Static image", "Current date", "Counting days", "Counting hours", "Current weather", "Firmware update", "Memo text", "Image url"];
const WAKEUP_REASON_TIMED = 0;
const WAKEUP_REASON_GPIO = 2;
const WAKEUP_REASON_NFC = 3;
const WAKEUP_REASON_FIRSTBOOT = 0xFC;
const WAKEUP_REASON_NETWORK_SCAN = 0xFD;
const WAKEUP_REASON_WDT_RESET = 0xFE;
const contentModes = ["Static image", "Current date", "Counting days", "Counting hours", "Current weather", "Firmware update", "Memo text", "Image url", "Weather forecast","RSS feed"];
const models = ["1.54\" 152x152px", "2.9\" 296x128px", "4.2\" 400x300px"];
const contentModeOptions = [];
contentModeOptions[0] = ["filename","timetolive"];
@@ -11,6 +18,8 @@ contentModeOptions[4] = ["location"];
contentModeOptions[5] = ["filename"];
contentModeOptions[6] = ["text"];
contentModeOptions[7] = ["url","interval"];
contentModeOptions[8] = ["location"];
contentModeOptions[9] = ["title", "url", "interval"];
const imageQueue = [];
let isProcessing = false;
@@ -123,6 +132,28 @@ function processTags(tagArray) {
div.dataset.hash = element.hash;
$('#tag' + tagmac + ' .warningicon').style.display = 'none';
$('#tag' + tagmac).style.background = "inherit";
switch (element.wakeupReason) {
case WAKEUP_REASON_TIMED:
break;
case WAKEUP_REASON_GPIO:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "GPIO wakeup"
break;
case WAKEUP_REASON_NFC:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "NFC wakeup"
break;
case WAKEUP_REASON_FIRSTBOOT:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "<font color=yellow>First boot</font>"
$('#tag' + tagmac).style.background = "purple";
break;
case WAKEUP_REASON_NETWORK_SCAN:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "<font color=yellow>Network scan</font>"
$('#tag' + tagmac).style.background = "green";
break;
case WAKEUP_REASON_WDT_RESET:
$('#tag' + tagmac + ' .nextcheckin').innerHTML = "Watchdog reset!"
$('#tag' + tagmac).style.background = "red";
break;
}
$('#tag' + tagmac + ' .pendingicon').style.display = (element.pending ? 'inline-block' : 'none');
div.classList.add("tagflash");
(function(tagmac) {

View File

@@ -22,10 +22,12 @@ struct blockData {
#define SOLUM_29_033 1
#define SOLUM_42_033 2
#define WAKEUP_REASON_TIMED 0
#define WAKEUP_REASON_BOOTUP 1
#define WAKEUP_REASON_GPIO 2
#define WAKEUP_REASON_NFC 3
#define WAKEUP_REASON_TIMED 0
#define WAKEUP_REASON_GPIO 2
#define WAKEUP_REASON_NFC 3
#define WAKEUP_REASON_FIRSTBOOT 0xFC
#define WAKEUP_REASON_NETWORK_SCAN 0xFD
#define WAKEUP_REASON_WDT_RESET 0xFE
struct AvailDataReq {
uint8_t checksum;
@@ -49,6 +51,11 @@ struct espAvailDataReq {
#define DATATYPE_IMGRAW 2
#define DATATYPE_UPDATE 3
#define EPD_LUT_DEFAULT 0
#define EPD_LUT_NO_REPEATS 1
#define EPD_LUT_FAST_NO_REDS 2
#define EPD_LUT_FAST 3
struct AvailDataInfo {
uint8_t checksum;
uint64_t dataVer; // MD5 of potential traffic

View File

@@ -6,6 +6,15 @@
#include "tag_db.h"
#include <TFT_eSPI.h>
struct contentTypes {
uint16_t id;
String name;
uint16_t tagTypes;
void (*functionname)();
String description;
String optionList;
};
void contentRunner();
void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo);
bool updateTagImage(String &filename, uint8_t *dst, uint16_t nextCheckin);
@@ -14,8 +23,10 @@ void initSprite(TFT_eSprite &spr, int w, int h);
void drawDate(String &filename, tagRecord *&taginfo);
void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord *&taginfo);
void drawWeather(String &filename, String location, tagRecord *&taginfo);
void drawForecast(String &filename, String location, tagRecord *&taginfo);
void drawIdentify(String &filename, tagRecord *&taginfo);
bool getImgURL(String &filename, String URL, time_t fetched);
bool getRSSfeed(String &filename, String URL, String title, tagRecord *&taginfo);
char *formatHttpDate(time_t t);
String urlEncode(const char *msg);
int windSpeedToBeaufort(float windSpeed);

View File

@@ -18,7 +18,7 @@
class tagRecord {
public:
uint16_t nextCheckinpending;
tagRecord() : mac{0}, alias(""), lastseen(0), nextupdate(0), contentMode(0), pending(false), md5{0}, md5pending{0}, CheckinInMinPending(0), expectedNextCheckin(0), modeConfigJson(""), LQI(0), RSSI(0), temperature(0), batteryMv(0), hwType(0), wakeupReason(0), capabilities(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) {}
uint8_t mac[6];
String alias;
@@ -28,7 +28,6 @@ class tagRecord {
bool pending;
uint8_t md5[16];
uint8_t md5pending[16];
uint16_t CheckinInMinPending;
uint32_t expectedNextCheckin;
String modeConfigJson;
uint8_t LQI;
@@ -37,7 +36,8 @@ class tagRecord {
uint16_t batteryMv;
uint8_t hwType;
uint8_t wakeupReason;
uint8_t capabilities;
uint8_t capabilities;
uint32_t lastfullupdate;
static tagRecord* findByMAC(uint8_t mac[6]);
};

View File

@@ -24,5 +24,7 @@ lib_deps =
bblanchon/ArduinoJson
bodmer/TFT_eSPI
https://github.com/Bodmer/TJpg_Decoder.git
https://github.com/garretlab/shoddyxml2
https://github.com/Bodmer/U8g2_for_TFT_eSPI
upload_port = COM12
monitor_port = COM12

View File

@@ -6,8 +6,10 @@
#include "newproto.h"
#include <MD5Builder.h>
#include <locale.h>
#include <rssClass.h>
#include <time.h>
#include "U8g2_for_TFT_eSPI.h"
#include "commstructs.h"
#include "makeimage.h"
#include "web.h"
@@ -21,6 +23,8 @@ enum contentModes {
Firmware,
Memo,
ImageUrl,
Forecast,
RSSFeed,
};
@@ -122,6 +126,13 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
updateTagImage(filename, mac, 15);
break;
case Forecast:
drawForecast(filename, cfgobj["location"], taginfo);
taginfo->nextupdate = now + 3 * 3600;
updateTagImage(filename, mac, 15);
break;
case Firmware:
filename = cfgobj["filename"].as<String>();
@@ -156,6 +167,16 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
taginfo->nextupdate = now + 300;
}
break;
case RSSFeed:
if (getRSSfeed(filename, cfgobj["url"], cfgobj["title"], taginfo)) {
taginfo->nextupdate = now + 60 * (cfgobj["interval"].as<int>() < 5 ? 5 : cfgobj["interval"].as<int>());
updateTagImage(filename, mac, cfgobj["interval"].as<int>());
} else {
taginfo->nextupdate = now + 300;
}
break;
}
taginfo->modeConfigJson = doc.as<String>();
@@ -169,10 +190,10 @@ bool updateTagImage(String &filename, uint8_t *dst, uint16_t nextCheckin) {
void drawString(TFT_eSprite &spr, String content, uint16_t posx, uint16_t posy, String font, byte align,uint16_t color) {
// drawString(spr,"test",100,10,"bahnschrift30",TC_DATUM,TFT_RED);
spr.setTextDatum(align);
spr.loadFont(font, LittleFS);
if (font != "") spr.loadFont(font, LittleFS);
spr.setTextColor(color, TFT_WHITE);
spr.drawString(content, posx, posy);
spr.unloadFont();
if (font != "") spr.unloadFont();
}
void initSprite(TFT_eSprite &spr, int w, int h) {
@@ -316,8 +337,6 @@ void drawWeather(String &filename, String location, tagRecord *&taginfo) {
weatherIcons[2] = "\0uf086";
}
String windIcons[] = {"\uf0b7", "\uf0b8", "\uf0b9", "\uf0ba", "\uf0bb", "\uf0bc", "\uf0bd", "\uf0be", "\uf0bf", "\uf0c0", "\uf0c1", "\uf0c2", "\uf0c3"};
doc.clear();
LittleFS.begin();
@@ -327,33 +346,27 @@ void drawWeather(String &filename, String location, tagRecord *&taginfo) {
initSprite(spr, 296, 128);
drawString(spr, location, 10, 10, "fonts/bahnschrift30");
drawString(spr, location, 5, 5, "fonts/bahnschrift30");
drawString(spr, String(wind), 280, 5, "fonts/bahnschrift30", TR_DATUM, (wind > 4 ? TFT_RED : TFT_BLACK));
char tmpOutput[5];
dtostrf(temperature, 2, 1, tmpOutput);
drawString(spr, String(tmpOutput), 5, 65, "fonts/bahnschrift70", TL_DATUM, (temperature < 0 ? TFT_RED : TFT_BLACK));
spr.loadFont("fonts/weathericons78", LittleFS);
spr.loadFont("fonts/weathericons70", LittleFS);
if (weathercode == 55 || weathercode == 65 || weathercode == 75 || weathercode == 82 || weathercode == 86 || weathercode == 95 || weathercode == 99) {
spr.setTextColor(TFT_RED, TFT_WHITE);
} else {
spr.setTextColor(TFT_BLACK, TFT_WHITE);
}
spr.setCursor(185, 20);
spr.setCursor(185, 32);
spr.printToSprite(weatherIcons[weathercode]);
spr.unloadFont();
spr.loadFont("fonts/weathericons30", LittleFS);
if (wind > 4) {
spr.setTextColor(TFT_RED, TFT_WHITE);
} else {
spr.setTextColor(TFT_BLACK, TFT_WHITE);
}
spr.setCursor(255, 0);
spr.printToSprite(windIcons[wind]);
spr.setTextColor(TFT_BLACK, TFT_WHITE);
spr.setCursor(230, -5);
spr.setCursor(235, -3);
spr.printToSprite(windDirectionIcon(winddirection));
if (weathercode > 10) {
spr.setTextColor(TFT_RED, TFT_WHITE);
@@ -381,21 +394,16 @@ void drawWeather(String &filename, String location, tagRecord *&taginfo) {
} else {
spr.setTextColor(TFT_BLACK, TFT_WHITE);
}
spr.setCursor(35, 25);
spr.setCursor(30, 33);
spr.printToSprite(weatherIcons[weathercode]);
spr.unloadFont();
spr.loadFont("fonts/weathericons30", LittleFS);
if (wind > 4) {
spr.setTextColor(TFT_RED, TFT_WHITE);
} else {
spr.setTextColor(TFT_BLACK, TFT_WHITE);
}
spr.setCursor(115, -5);
spr.printToSprite(windIcons[wind]);
drawString(spr, String(wind), 140, 10, "fonts/bahnschrift30", TR_DATUM, (wind > 4 ? TFT_RED : TFT_BLACK));
spr.loadFont("fonts/weathericons30", LittleFS);
spr.setTextColor(TFT_BLACK, TFT_WHITE);
spr.setCursor(90, -5);
spr.setCursor(100, -2);
spr.printToSprite(windDirectionIcon(winddirection));
if (weathercode > 10) {
spr.setTextColor(TFT_RED, TFT_WHITE);
@@ -413,6 +421,109 @@ void drawWeather(String &filename, String location, tagRecord *&taginfo) {
http.end();
}
void drawForecast(String &filename, String location, tagRecord *&taginfo) {
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite spr = TFT_eSprite(&tft);
wsLog("get weather");
HTTPClient http;
http.begin("https://geocoding-api.open-meteo.com/v1/search?name=" + urlEncode(location.c_str()) + "&count=1");
http.setTimeout(5000); // timeout in ms
int httpCode = http.GET();
if (httpCode == 200) {
DynamicJsonDocument doc(2000);
DeserializationError error = deserializeJson(doc, http.getStream());
http.end();
http.begin("https://api.open-meteo.com/v1/forecast?latitude=" + doc["results"][0]["latitude"].as<String>() + "&longitude=" + doc["results"][0]["longitude"].as<String>() + "&daily=weathercode,temperature_2m_max,temperature_2m_min,precipitation_sum,windspeed_10m_max,winddirection_10m_dominant&windspeed_unit=ms&timeformat=unixtime&timezone=" + doc["results"][0]["timezone"].as<String>());
doc.clear();
http.setTimeout(5000); // timeout in ms
int httpCode = http.GET();
if (httpCode == 200) {
StaticJsonDocument<500> filter;
filter["daily"]["time"][0] = true;
filter["daily"]["weathercode"][0] = true;
filter["daily"]["temperature_2m_max"][0] = true;
filter["daily"]["temperature_2m_min"][0] = true;
filter["daily"]["precipitation_sum"][0] = true;
filter["daily"]["windspeed_10m_max"][0] = true;
filter["daily"]["winddirection_10m_dominant"][0] = true;
//DeserializationError error = deserializeJson(doc, http.getString(), DeserializationOption::Filter(filter));
DeserializationError error = deserializeJson(doc, http.getString());
if (error) {
Serial.println(F("deserializeJson() failed: "));
Serial.println(error.c_str());
}
static const char *weekday_name[] = {"ZO", "MA", "DI", "WO", "DO", "VR", "ZA"};
String weatherIcons[] = {"\uf00d", "\uf00c", "\uf002", "\uf013", "\uf013", "\uf014", "-", "-", "\uf014", "-", "-",
"\uf01a", "-", "\uf01a", "-", "\uf01a", "\uf017", "\uf017", "-", "-", "-",
"\uf019", "-", "\uf019", "-", "\uf019", "\uf015", "\uf015", "-", "-", "-",
"\uf01b", "-", "\uf01b", "-", "\uf01b", "-", "\uf076", "-", "-", "\uf01a",
"\uf01a", "\uf01a", "-", "-", "\uf064", "\uf064", "-", "-", "-", "-",
"-", "-", "-", "-", "\uf01e", "\uf01d", "-", "-", "\uf01e"};
LittleFS.begin();
tft.setTextWrap(false, false);
if (taginfo->hwType == SOLUM_29_033) {
initSprite(spr, 296, 128);
spr.setTextFont(2);
spr.setTextColor(TFT_BLACK, TFT_WHITE);
spr.drawString(location, 5, 0);
for (uint8_t dag = 0; dag < 5; dag++) {
time_t weatherday = doc["daily"]["time"][dag].as<time_t>();
struct tm *datum = localtime(&weatherday);
drawString(spr, String(weekday_name[datum->tm_wday]), dag * 59 + 30, 18, "fonts/twbold20", TC_DATUM, TFT_BLACK);
uint8_t weathercode = doc["daily"]["weathercode"][dag].as<int>();
if (weathercode > 40) weathercode -= 40;
spr.loadFont("fonts/weathericons30", LittleFS);
if (weathercode == 55 || weathercode == 65 || weathercode == 75 || weathercode == 82 || weathercode == 86 || weathercode == 95 || weathercode == 99) {
spr.setTextColor(TFT_RED, TFT_WHITE);
} else {
spr.setTextColor(TFT_BLACK, TFT_WHITE);
}
spr.setTextDatum(TL_DATUM);
spr.setCursor(12 + dag * 59, 58);
spr.printToSprite(weatherIcons[weathercode]);
spr.setTextColor(TFT_BLACK, TFT_WHITE);
spr.setCursor(17 + dag * 59, 27);
spr.printToSprite(windDirectionIcon(doc["daily"]["winddirection_10m_dominant"][dag]));
spr.unloadFont();
int8_t tmin = round(doc["daily"]["temperature_2m_min"][dag].as<double>());
int8_t tmax = round(doc["daily"]["temperature_2m_max"][dag].as<double>());
uint8_t wind = windSpeedToBeaufort(doc["daily"]["windspeed_10m_max"][dag].as<double>());
spr.loadFont("fonts/GillSC20", LittleFS);
drawString(spr, String(tmin) + " ", dag * 59 + 30, 108, "", TR_DATUM, (tmin < 0 ? TFT_RED : TFT_BLACK));
drawString(spr, String(" ") + String(tmax), dag * 59 + 30, 108, "", TL_DATUM, (tmax < 0 ? TFT_RED : TFT_BLACK));
drawString(spr, String(" ") + String(wind), dag * 59 + 30, 43, "", TL_DATUM, (wind > 5 ? TFT_RED : TFT_BLACK));
spr.unloadFont();
if (dag>0) {
for (int i = 20; i < 128; i+=3) {
spr.drawPixel(dag * 59, i, TFT_BLACK);
}
}
}
}
spr2grays(spr, spr.width(), spr.height(), filename);
spr.deleteSprite();
}
}
http.end();
}
void drawIdentify(String &filename, tagRecord *&taginfo) {
TFT_eSPI tft = TFT_eSPI();
@@ -463,6 +574,62 @@ bool getImgURL(String &filename, String URL, time_t fetched) {
return (httpCode == 200 || httpCode == 304);
}
rssClass reader;
bool getRSSfeed(String &filename, String URL, String title, tagRecord *&taginfo) {
// https://github.com/garretlab/shoddyxml2
// http://feeds.feedburner.com/tweakers/nieuws
// https://www.nu.nl/rss/Algemeen
Serial.println("RSS feed");
struct tm timeInfo;
char header[32];
getLocalTime(&timeInfo);
sprintf(header, "%02d-%02d-%04d %02d:%02d", timeInfo.tm_mday, timeInfo.tm_mon + 1, timeInfo.tm_year + 1900, timeInfo.tm_hour, timeInfo.tm_min);
const char *url = URL.c_str();
const char *tag = "title";
const int rssArticleSize = 128;
const int rssNumArticle = 8;
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite spr = TFT_eSprite(&tft);
U8g2_for_TFT_eSPI u8f;
u8f.begin(spr);
if (taginfo->hwType == SOLUM_29_033) {
initSprite(spr, 296, 128);
if (title=="" || title=="null") title="RSS feed";
drawString(spr, title, 5, 3, "fonts/bahnschrift20", TL_DATUM, TFT_RED);
u8f.setFont(u8g2_font_glasstown_nbp_tr); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
u8f.setFontMode(0);
u8f.setFontDirection(0);
u8f.setForegroundColor(TFT_BLACK);
u8f.setBackgroundColor(TFT_WHITE);
u8f.setCursor(220, 20);
u8f.print(header);
// u8g2_font_nine_by_five_nbp_tr
// u8g2_font_7x14_tr
// u8g2_font_crox1h_tr
// u8g2_font_miranda_nbp_tr
u8f.setFont(u8g2_font_glasstown_nbp_tr); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall
int n = reader.getArticles(url, tag, rssArticleSize, rssNumArticle);
for (int i = 0; i < n; i++) {
u8f.setCursor(5, 34+i*13); // start writing at this position
u8f.print(reader.itemData[i]);
}
}
spr2grays(spr, spr.width(), spr.height(), filename);
spr.deleteSprite();
return true;
}
char *formatHttpDate(time_t t) {
static char buf[40];
struct tm *timeinfo;

View File

@@ -152,6 +152,12 @@ void spr2grays(TFT_eSprite &spr, long w, long h, String &fileout) {
f_out.write(0x00);
}
const int dither_matrix[4][4] = {
{1, 9, 3, 11},
{13, 5, 15, 7},
{4, 12, 2, 10},
{0, 8, 14, 6}};
while (numRows--) {
uint32_t pixelValsPackedSoFar = 0, numPixelsPackedSoFar = 0, valSoFar = 0, bytesIn = 0, bytesOut = 0, bitsSoFar = 0;
@@ -170,8 +176,10 @@ void spr2grays(TFT_eSprite &spr, long w, long h, String &fileout) {
uint8_t green = ((color565 >> 5) & 0x3F) * 4;
uint8_t blue = (color565 & 0x1F) * 8;
if (dither)
ditherFudge = (rand() % 255 - 127) / (int)numGrays;
if (dither) {
// ditherFudge = (rand() % 255 - 127) / (int)numGrays; // -64 to 64
ditherFudge = (dither_matrix[numRows % 4][c % 4] - 8) * 24 / (int)numGrays;
}
for (i = 0; i < hdr.numColors; i++) {
int64_t dist = 0;
@@ -253,7 +261,7 @@ void bmp2grays(String filein, String fileout) {
struct BitmapFileHeader hdr;
enum EinkClut clutType;
uint8_t clut[256][3];
bool dither = true;
bool dither = false;
int skipBytes;
srand(0);

View File

@@ -124,7 +124,8 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
md5.getBytes(md5bytes);
}
uint16_t attempts = 60;
uint16_t attempts = 60 * 24;
uint8_t lut = EPD_LUT_DEFAULT;
uint8_t src[8];
*((uint64_t*)src) = swap64(*((uint64_t*)dst));
uint8_t mac[6];
@@ -141,9 +142,13 @@ 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) lut = EPD_LUT_NO_REPEATS; // fast updates during the day
/*
uint16_t minutesUntilNextCheckin = 0;
if (taginfo->expectedNextCheckin > now) minutesUntilNextCheckin = (taginfo->expectedNextCheckin - now) / 60;
attempts += minutesUntilNextCheckin;
*/
} else {
wsErr("Tag not found, this shouldn't happen.");
}
@@ -154,6 +159,7 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
pending.availdatainfo.dataType = dataType;
pending.availdatainfo.dataVer = *((uint64_t*)md5bytes);
pending.availdatainfo.dataSize = file.size();
pending.availdatainfo.dataTypeArgument = EPD_LUT_NO_REPEATS;
pending.availdatainfo.nextCheckIn = nextCheckin;
pending.attemptsLeft = attempts;
sendDataAvail(&pending);
@@ -185,14 +191,15 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t
wsLog("new image pending: " + String(dst_path));
if (taginfo != nullptr) {
time_t now;
time(&now);
taginfo->pending = true;
taginfo->CheckinInMinPending = nextCheckin;
taginfo->expectedNextCheckin = now + nextCheckin * 60 + 60;
memcpy(taginfo->md5pending, md5bytes, sizeof(md5bytes));
}
}
else {
wsLog("firmware upload pending");
}
} else {
wsLog("firmware upload pending");
}
file.close();
wsSendTaginfo(mac);
@@ -275,17 +282,13 @@ void processXferComplete(struct espXferComplete* xfc) {
if (taginfo != nullptr) {
uint16_t minutesUntilNextUpdate = 0;
if (taginfo->nextupdate > now + 60 * taginfo->CheckinInMinPending + 3) {
minutesUntilNextUpdate = (taginfo->nextupdate - now) / 60 - taginfo->CheckinInMinPending;
if (minutesUntilNextUpdate > taginfo->CheckinInMinPending) minutesUntilNextUpdate = taginfo->CheckinInMinPending;
if (taginfo->nextupdate > now + 2) {
minutesUntilNextUpdate = (taginfo->nextupdate - now) / 60;
if (minutesUntilNextUpdate > MIN_RESPONSE_TIME) minutesUntilNextUpdate = MIN_RESPONSE_TIME;
taginfo->expectedNextCheckin = now + 60 * minutesUntilNextUpdate + 60;
if (minutesUntilNextUpdate > 0) prepareIdleReq (xfc->src, minutesUntilNextUpdate);
taginfo->CheckinInMinPending = minutesUntilNextUpdate;
if (minutesUntilNextUpdate > 1) prepareIdleReq (xfc->src, minutesUntilNextUpdate);
} else {
taginfo->expectedNextCheckin = now + 60;
taginfo->CheckinInMinPending = 0;
}
taginfo->pending = false;
@@ -310,7 +313,6 @@ void processXferTimeout(struct espXferComplete* xfc) {
taginfo = tagRecord::findByMAC(mac);
if (taginfo != nullptr) {
taginfo->expectedNextCheckin = now + 60;
taginfo->CheckinInMinPending = 0;
taginfo->pending = false;
memset(taginfo->md5pending, 0, 16 * sizeof(uint8_t));
}
@@ -341,15 +343,13 @@ void processDataReq(struct espAvailDataReq* eadr) {
taginfo->lastseen = now;
uint16_t minutesUntilNextUpdate = 0;
if (taginfo->nextupdate > now + 60 * taginfo->CheckinInMinPending + 3 && taginfo->pending == false) {
minutesUntilNextUpdate = (taginfo->nextupdate - now) / 60 - taginfo->CheckinInMinPending;
if (minutesUntilNextUpdate > taginfo->CheckinInMinPending) minutesUntilNextUpdate = taginfo->CheckinInMinPending;
if (taginfo->nextupdate > now + 2) {
minutesUntilNextUpdate = (taginfo->nextupdate - now) / 60;
if (minutesUntilNextUpdate > MIN_RESPONSE_TIME) minutesUntilNextUpdate = MIN_RESPONSE_TIME;
taginfo->expectedNextCheckin = now + 60 * minutesUntilNextUpdate + 60;
if (minutesUntilNextUpdate > 0) prepareIdleReq(eadr->src, minutesUntilNextUpdate);
taginfo->CheckinInMinPending = minutesUntilNextUpdate;
if (minutesUntilNextUpdate > 1 && taginfo->pending == false) prepareIdleReq(eadr->src, minutesUntilNextUpdate);
} else {
taginfo->expectedNextCheckin = now + 60 * taginfo->CheckinInMinPending + 60;
taginfo->expectedNextCheckin = now + 60;
}
if (eadr->adr.lastPacketRSSI != 0) {

View File

@@ -284,7 +284,6 @@ void init_web() {
taginfo->modeConfigJson = request->getParam("modecfgjson", true)->value();
taginfo->contentMode = atoi(request->getParam("contentmode", true)->value().c_str());
taginfo->nextupdate = 0;
taginfo->CheckinInMinPending = 0;
memset(taginfo->md5, 0, 16 * sizeof(uint8_t));
memset(taginfo->md5pending, 0, 16 * sizeof(uint8_t));
wsSendTaginfo(mac);