From 8410eb0a533cef7d31e187af5ecceb4154ff6e57 Mon Sep 17 00:00:00 2001 From: Nic Limper Date: Thu, 9 Feb 2023 19:40:55 +0100 Subject: [PATCH] timing improvements and bugfixes --- esp32_fw/data/fonts/tw20.vlw | Bin 0 -> 8864 bytes esp32_fw/data/fonts/twbold20.vlw | Bin 0 -> 10484 bytes esp32_fw/data/fonts/weathericons50.vlw | Bin 0 -> 82975 bytes esp32_fw/data/fonts/weathericons78.vlw | Bin 118301 -> 104727 bytes esp32_fw/data/www/edit.html | 1 + esp32_fw/data/www/main.js | 3 +- esp32_fw/include/newproto.h | 1 + esp32_fw/include/pendingdata.h | 2 +- esp32_fw/include/serial.h | 3 +- esp32_fw/include/settings.h | 23 +++++---- esp32_fw/include/tag_db.h | 15 +----- esp32_fw/src/contentmanager.cpp | 31 ++++++++---- esp32_fw/src/main.cpp | 8 +++- esp32_fw/src/makeimage.cpp | 8 ++-- esp32_fw/src/newproto.cpp | 64 ++++++++++++++++++++++--- esp32_fw/src/serial.cpp | 27 +++++++---- esp32_fw/src/tag_db.cpp | 2 +- esp32_fw/src/web.cpp | 5 +- 18 files changed, 132 insertions(+), 61 deletions(-) create mode 100644 esp32_fw/data/fonts/tw20.vlw create mode 100644 esp32_fw/data/fonts/twbold20.vlw create mode 100644 esp32_fw/data/fonts/weathericons50.vlw diff --git a/esp32_fw/data/fonts/tw20.vlw b/esp32_fw/data/fonts/tw20.vlw new file mode 100644 index 0000000000000000000000000000000000000000..884fc49429b763574076e8b4b5f9b8304bb0a868 GIT binary patch literal 8864 zcmbtV2YX~S3|u-K^*DY&==JEmL+B7{=p7O|IpBcM|2oW!BwP0Ld)W|wu`Fq%k!0^~ zR;$%VtJUg4>?^RjF2+6^`%2f(besM&u(__nKF9ZYI4{8t>}t2k$()Q`1N&0!bFurp zYd!WNKXbk7;G_S1>%E44bpX zeC#WFxdl3N&cbFr_7vDj*NHKPJFr`!Gd5<(dAGsOJ|idhay$IAiS>Qn;TY=$MqaKv zvFGycTEOmhEZ#5oa?b#ROY2_9xq9~vu;}yt0Ty@mzykIlFwPwJNj>r&g3ixSyivv; zhW{9Lye-ejdjvY~IWTer_9*nZyvKlXc77gsZ~4w1hkXM3a%_J8_}vK3C!jNypLuTT zv7UrNd-U#`3)oYRv5(-4dQUqx>hqZe?AZm*=N7Q%9pf8uj(jgKxXoSygR1o+BxCt* z{R}TTHkx6}G3M~Ca=n+`9^K0;jalj9%;oI@o2&PQ=LIJ@VtolEbLKw3>ag7B*N(++WX8S$#&;ND-+JEY z-M?Gl{2my4;~VjFMxFdzd)Tz&KB>oDpIX3v05&)Kj|zz&*XUy2ou-SX$ zQI9@<@z~J}zb;_=j`3dj8O`;6Tgdwz7-x@n$a#OHyncp1f$@J%vR zBgT2S{>JX}1VH?Q&9`I@d*UqO_+tnm*mJlA?XSbBtJvjI68XMre6 zYq^`#+vXvnnnDMypb|sGS+Icy6gZNME=g+#IhH2koLd;0zDq=oFHRJj>S`{9Q$6A!i-SJnsI{(y#-a~HANMiGIb}Mk&bX#V8PuT z8Jd@1I9gRDJhzLQLhQ>{${4E=$TLOs);drSl-!A2rNt&Ga@sYf)eV|M!!H_jAD$&n ziyleq%sAH3!J!$;0J6;KEOtcHAh;A5Rg3>Y%by`-E#xs=) zY27I+F50dL0RPf$9ooti&Lh&Xkk@}0qH<%3!aOw=+M!#lm+QIYDC)R7bmVDPI~z5_ zqS#Q~#VATe!D1;MZ&^o?#(i|Dw$!m{>Pg*(M$qcygP&x-%jsbd2z1#LQpl22UW$|3 z{g{P_01i+Qrstuw0+Jy_W1^}aNe9*TfJvgIqfIbNNu`rurMGo@oK-kTGL_93jVrRM zC;=0fvXu&kb^ffFUPs{*VGuj&wcb{YJ4L%z1E94YG*rx6ycvxvNv9=|AuT2wkvWZn z`iv%bZyt&>GNgN{1MmMh*>c}1(j?zXD5ntFImMYfT zMYC>5Q{!lecPb3X!8L87!J*z6-miJYA`Kr&;%qGbSVg|#X%u0`IhHv(aY|j^ZX#>$ zNMlDzozFw3cIX1%5P2RwU3purG+IcI#kchDtHN99nXw zK&Tz>)T0oKb8s3n>j5xatU8-CZOTLKNDWORdyh?QZRDErpV;2t*xcRQ*xKIMJhiv8 TyLWnbXLWpgAHJ>alhySfcX7yB literal 0 HcmV?d00001 diff --git a/esp32_fw/data/fonts/twbold20.vlw b/esp32_fw/data/fonts/twbold20.vlw new file mode 100644 index 0000000000000000000000000000000000000000..5ed00c42ef3b01e4f3231ad4e18f59dac131a679 GIT binary patch literal 10484 zcmb_eXO|o`5L|Lj4|tD{M~)`vj7%=2O*?{R$?=w}RUj~l{(e|}8x!gjwK!-kI2V?uZBcT@P6DUKR&8+Y?WED=vM#-`%R^v54cIodbtCA6MMDihCk*zH9V??eSz7muuqt!?$71r@}@p z`e0VvVfo;5&bT8b=jZO+(>wexv6LLigMsYzG`_@{?uK+R&wLJem!#dR;O@p2sicJzFBhP z=de4IdrP^ges3#>`|_QI$?;CCI4`tf!uEJK4EQ*k&*$8GGr9MbgBIib96pHHr7`{e zp{K`(VT^y)IrmW*t8n-ohF-qU`W<}|arEZd|BVs0$ERW7{eu=@tCr8ghjyO;)gTmcrkEZ% z1Q~}a*_ElgpEy*#UNvCT-3szyvHtyyI3Oij~(`U~t=+s?wZyMkP zv8lz<4Ge~8$0!}lzeKLMWJDh4@{P5@4O1@92s{u zF<5KdStE!0eC2YsMRe?XmVuor7#g0XzX?ua?^sr6O2D2=?PGs5!|u&zU$GgM+>BDMsh)MQ}NEnJ8_MniUDA2JbxzQxJIyi!m2|8d4IT2XR$8vuc4t!`W6;={>>nOfY3p6u`BC0Kx-f=4(FK)UWOd%6?K4 zp&Y$D{1uLbbOcM`f-^xgtE;1gX4z&?Y?=^sT02xa&)Bm~IP?d(Ma`WD8eCU){&hr} u!QV+&?Vj8@vVX91ba&^-@q@kngA@CEJBN=S+gn_@domJ7cMr8V!~X%Fltvr? literal 0 HcmV?d00001 diff --git a/esp32_fw/data/fonts/weathericons50.vlw b/esp32_fw/data/fonts/weathericons50.vlw new file mode 100644 index 0000000000000000000000000000000000000000..4019f1313036d659e9d7ffe41f5ea97be6d0f244 GIT binary patch literal 82975 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 delta 2393 zcmbtWOKcle6zzkwcI=5gw&PzMe-hitBu(OJ{&AXiT0@DT0jrJLN)?q+RiOxpx_}T; zRLNB&mehI|@B7`) zxz`py9QbO-)w6HkzTo#gTdZ#ivm(ZlMEZ!Gn6kDoH84ufSOz+O*2kDg{W)ip=+Pgq ziA;iRka{9T#<#Ci^Ws@DS>%7Cxq1qBCWJA|hK04w3Z$MqLlt+5ng^ny9bj>;&Euci z7v`z<#7%m9iqxx1T$=$bles!=FE!^B(*GTo^X(6qBCk5gwYSLF2~qo-HRou6)XN^x znqd=Eznm9U9}7|SaF5*mDm8QAEkn6uC@g%DYqP>Q&kCYuuqYYIC{{zjoZJN*21@-9 zFb2#}BNC(^7hLpDBuVX!FfX|%^E147+%K#t=7Kv(7#t?E>Jnua%Te`$PZ$f#B{D0J zTB@I#sUb3FV_eGs;CC93;981n3CvPt{*)#CR8ll%*dSSdhh@;RWKD(T3H53m!59L@ za1rc#9F^B+sd5L8F1o3lNRqx$p!RNxTDo*7{){7C$3}%!U@6jjQ)K;86sn&s*&mRW z$ZYsYz1uI0bJ)^*7g>{&UmFFkd8zrRI(AB~OaNu5$N1(k=aQ^*iKI^!OKBJ$ zMV5SI{h7qY39<^{^UerWiU`+zX;&H}iy>1y3_i#q)1CvSMg4tnTK7b`mWK=qUKo+c zwNb7O?tMZ9LXB~4;Mq^fbg3g_cNE<9AREC>WDHYUDxHXMEsAN3^x}x99Ap8i`TMq~ zSsVq4XdxAiPlDJN;9A%bWxc3)F=ES=qMMf_k3n0oo-!*wSqs1boRw+s!@e#~bT;Yn zfD>l9;B^iZWko4uMFX%nK$p*W>E60ZjV)NWk#)itgtY@?dfkp3f(-WAvLBX7IR?4+ zS-v0#P~dhim0y}5Bccf7B8=7JNU&qMXbv+Sq4su{#;_FX2(|fft_7cOuE*s?{dR-E z6NkGIc=|H6j_M-wHp3p8f(z&vxmgEifC0#d9M=j!$$U6rGk*-2ge=*%&b4(r*R^B; zDw(GeP^S6#9vb&flkuP*t>P6BFd&RI=A-KVG1R7CR1UEoYTWLjH`Y9zPA5qopm&jq zCnxO)%8obAH(`CXm#>dtIf>vRo(pUe0(x6Va8YeOZz~MNht4&QIohBXxjmNe))>md zJ}Ea33F`_w)QL`QURH(d6OpbW1wjr+QTZZ|Tp`h&$l9F*wZk=ZF-gPfT7vYm3mu_# z6kRvBw`Sgqi`EL8;Gw?Gx_L9ozg(7d7V0FvI?PqLw;I7~AoeOM4g8q}=~guujyJ2l zWZex>=D{*A$p&l_Sm+Dc{{oQ7{$H@WF$g?mQ?xuFb4y%eJW%(wG zei0E;@Pz=zSHF&sK0J<`#;AVdq%;msE%s7oej1I*0|SG5vau6JEy=QwCK*&e9_5)! zR6a1rHT0j`3bkK23Lg}zKEyLj3i~w8DQ!CibsT{Z_(8>tTY_ff5h7sGMgStq47{n z{vdD?t$&UZ*crAHC)D@Y3^nJ_sCHGSJE66sfGXF~?ol|E>nEs8XQ;f3Xp$@{e8=Pt P1Jl4cU|9V18JqkMGW$LC diff --git a/esp32_fw/data/www/edit.html b/esp32_fw/data/www/edit.html index f5b566f5..4adac442 100644 --- a/esp32_fw/data/www/edit.html +++ b/esp32_fw/data/www/edit.html @@ -595,6 +595,7 @@ case "jpg": case "gif": case "bmp": + case "pending": return true; } } diff --git a/esp32_fw/data/www/main.js b/esp32_fw/data/www/main.js index 5d0276da..27d3529f 100644 --- a/esp32_fw/data/www/main.js +++ b/esp32_fw/data/www/main.js @@ -139,8 +139,9 @@ function updatecards() { if (item.dataset.lastseen && item.dataset.lastseen > 1672531200) { let idletime = (Date.now() / 1000) + servertimediff - item.dataset.lastseen; $('#tag' + tagmac + ' .lastseen').innerHTML = "last seen"+displayTime(Math.floor(idletime))+" ago"; - if ((Date.now() / 1000) + servertimediff > item.dataset.nextcheckin) { + if ((Date.now() / 1000) + servertimediff - 60 > item.dataset.nextcheckin) { $('#tag' + tagmac + ' .warningicon').style.display='inline-block'; + $('#tag' + tagmac).classList.remove("tagpending") $('#tag' + tagmac).style.background = '#ffffcc'; } if (idletime > 24*3600) { diff --git a/esp32_fw/include/newproto.h b/esp32_fw/include/newproto.h index 54ffe327..c41b3972 100644 --- a/esp32_fw/include/newproto.h +++ b/esp32_fw/include/newproto.h @@ -4,6 +4,7 @@ extern void addCRC(void* p, uint8_t len); extern bool checkCRC(void* p, uint8_t len); extern void processBlockRequest(struct espBlockRequest* br); +extern void prepareIdleReq(uint8_t* dst, uint16_t nextCheckin); extern bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t nextCheckin); extern void processJoinNetwork(struct espJoinNetwork* xjn); extern void processXferComplete(struct espXferComplete* xfc); diff --git a/esp32_fw/include/pendingdata.h b/esp32_fw/include/pendingdata.h index 1bbc1e9f..88b09054 100644 --- a/esp32_fw/include/pendingdata.h +++ b/esp32_fw/include/pendingdata.h @@ -11,7 +11,7 @@ class pendingdata { //uint8_t dst[8]; uint64_t ver; String md5; - uint16_t timeout; + uint32_t timeout; uint8_t datatimeout; uint8_t* data = nullptr; uint32_t len; diff --git a/esp32_fw/include/serial.h b/esp32_fw/include/serial.h index d9476e6c..76ed03a1 100644 --- a/esp32_fw/include/serial.h +++ b/esp32_fw/include/serial.h @@ -4,4 +4,5 @@ void zbsTx(uint8_t* packetdata, uint8_t len); void zbsRxTask(void* parameter); void sendCancelPending(struct pendingData* pending); -void sendDataAvail(struct pendingData* pending); \ No newline at end of file +void sendDataAvail(struct pendingData* pending); +void Ping(); \ No newline at end of file diff --git a/esp32_fw/include/settings.h b/esp32_fw/include/settings.h index bfe32c49..d1ab28cd 100644 --- a/esp32_fw/include/settings.h +++ b/esp32_fw/include/settings.h @@ -1,19 +1,16 @@ #include -#define CHECK_IN_DELAY 900000 -#define RETRY_DELAY 1000 -#define FAILED_TILL_BLANK 2 -#define FAILED_TILL_REASSOCIATE 1 - // how long the we should keep the transfer metadata -#define PENDING_TIMEOUT 600 +#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 // flasher options #define CUSTOM_MAC_HDR 0x0000 -/* +/* Lolin32 lite connections to AP tag #define RXD1 16 #define TXD1 17 @@ -24,10 +21,13 @@ #define ZBS_Reset 2 #define ZBS_POWER1 13 #define ZBS_POWER2 15 -*/ -#define RXD1 13 -#define TXD1 12 +#define ONBOARD_LED 22 +//*/ + +//* +#define RXD1 13 +#define TXD1 12 #define ZBS_SS 21 #define ZBS_CLK 18 @@ -37,5 +37,8 @@ #define ZBS_POWER1 15 #define ZBS_POWER2 2 +#define ONBOARD_LED 22 +//*/ + #define MAX_WRITE_ATTEMPTS 5 diff --git a/esp32_fw/include/tag_db.h b/esp32_fw/include/tag_db.h index 703423f3..4e8f147b 100644 --- a/esp32_fw/include/tag_db.h +++ b/esp32_fw/include/tag_db.h @@ -6,17 +6,6 @@ #pragma pack(push, 1) #pragma once -enum contentModes { - Image, - Today, - CountDays, - CountHours, - Weather, - Firmware, - Memo, - ImageUrl, -}; - #define SOLUM_154_033 0 #define SOLUM_29_033 1 #define SOLUM_42_033 2 @@ -29,13 +18,13 @@ enum contentModes { class tagRecord { public: uint16_t nextCheckinpending; - tagRecord() : mac{0}, alias(""), lastseen(0), nextupdate(0), contentMode(Image), 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}, CheckinInMinPending(0), expectedNextCheckin(0), modeConfigJson(""), LQI(0), RSSI(0), temperature(0), batteryMv(0), hwType(0), wakeupReason(0), capabilities(0) {} uint8_t mac[6]; String alias; uint32_t lastseen; uint32_t nextupdate; - contentModes contentMode; + uint8_t contentMode; bool pending; uint8_t md5[16]; uint8_t md5pending[16]; diff --git a/esp32_fw/src/contentmanager.cpp b/esp32_fw/src/contentmanager.cpp index a4c08405..2d0b1d30 100644 --- a/esp32_fw/src/contentmanager.cpp +++ b/esp32_fw/src/contentmanager.cpp @@ -12,6 +12,18 @@ #include "makeimage.h" #include "web.h" +enum contentModes { + Image, + Today, + CountDays, + CountHours, + Weather, + Firmware, + Memo, + ImageUrl, +}; + + void contentRunner() { time_t now; time(&now); @@ -76,8 +88,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) { case Today: drawDate(filename, taginfo); - // updateTagImage(filename, mac, (midnight - now) / 60 - 10); - updateTagImage(filename, mac, 600); + updateTagImage(filename, mac, (midnight - now) / 60 - 10); taginfo->nextupdate = midnight; break; @@ -85,7 +96,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) { if (buttonPressed) cfgobj["counter"] = 0; drawNumber(filename, (int32_t)cfgobj["counter"], (int32_t)cfgobj["thresholdred"], taginfo); - updateTagImage(filename, mac, (buttonPressed?0:600)); + updateTagImage(filename, mac, (buttonPressed?0:15)); cfgobj["counter"] = (int32_t)cfgobj["counter"] + 1; taginfo->nextupdate = midnight; break; @@ -94,9 +105,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) { if (buttonPressed) cfgobj["counter"] = 0; drawNumber(filename, (int32_t)cfgobj["counter"], (int32_t)cfgobj["thresholdred"], taginfo); - // updateTagImage(&filename, mac, (3600 - now % 3600) / 60); - // taginfo->nextupdate = now + 3600 - (now % 3600); - updateTagImage(filename, mac, (buttonPressed?0:600)); + updateTagImage(filename, mac, (buttonPressed?0:5)); cfgobj["counter"] = (int32_t)cfgobj["counter"] + 1; taginfo->nextupdate = now + 3600; break; @@ -109,7 +118,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) { // https://github.com/erikflowers/weather-icons drawWeather(filename, cfgobj["location"], taginfo); - updateTagImage(filename, mac, 600); + updateTagImage(filename, mac, 15); taginfo->nextupdate = now + 3600; break; @@ -134,7 +143,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) { drawIdentify(filename, taginfo); updateTagImage(filename, mac, 0); - taginfo->nextupdate = now + 24*3600; + taginfo->nextupdate = now + 12*3600; break; case ImageUrl: @@ -142,8 +151,10 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) { if (getImgURL(filename, cfgobj["url"], (time_t)cfgobj["#fetched"])) { updateTagImage(filename, mac, cfgobj["interval"].as()); cfgobj["#fetched"] = now; + taginfo->nextupdate = now + 60 * (cfgobj["interval"].as() < 5 ? 5 : cfgobj["interval"].as()); + } else { + taginfo->nextupdate = now + 300; } - taginfo->nextupdate = now + 60 * (cfgobj["interval"].as() < 5 ? 5 : cfgobj["interval"].as()) ; break; } @@ -449,7 +460,7 @@ bool getImgURL(String &filename, String URL, time_t fetched) { } } http.end(); - return (httpCode == 200); + return (httpCode == 200 || httpCode == 304); } char *formatHttpDate(time_t t) { diff --git a/esp32_fw/src/main.cpp b/esp32_fw/src/main.cpp index 391c9ae5..9dc18d5d 100644 --- a/esp32_fw/src/main.cpp +++ b/esp32_fw/src/main.cpp @@ -8,6 +8,7 @@ #include "makeimage.h" #include "pendingdata.h" #include "serial.h" +#include "settings.h" #include "soc/rtc_wdt.h" #include "tag_db.h" #include "web.h" @@ -21,7 +22,9 @@ void timeTask(void* parameter) { Serial.println("Waiting for valid time from NTP-server"); } else { if (now % 10 == 0) wsSendSysteminfo(); - if (now % 300 == 0) saveDB("/current/tagDB.json"); + if (now % 60 == 3) Ping(); + if (now % 300 == 6) saveDB("/current/tagDB.json"); + contentRunner(); } vTaskDelay(1000 / portTICK_PERIOD_MS); @@ -32,6 +35,9 @@ void setup() { Serial.begin(115200); Serial.print(">\n"); + pinMode(ONBOARD_LED, OUTPUT); + digitalWrite(ONBOARD_LED, HIGH); + configTzTime("CET-1CEST,M3.5.0,M10.5.0/3", "0.nl.pool.ntp.org", "europe.pool.ntp.org", "time.nist.gov"); // https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv diff --git a/esp32_fw/src/makeimage.cpp b/esp32_fw/src/makeimage.cpp index 4bcd7955..54e8660d 100644 --- a/esp32_fw/src/makeimage.cpp +++ b/esp32_fw/src/makeimage.cpp @@ -29,7 +29,7 @@ void jpg2grays(String filein, String fileout) { } spr.setColorDepth(8); spr.fillSprite(TFT_WHITE); - TJpgDec.drawFsJpg(0, 0, filein); + TJpgDec.drawFsJpg(0, 0, filein, LittleFS); spr2grays(spr, w, h, fileout); spr.deleteSprite(); @@ -236,8 +236,7 @@ void spr2grays(TFT_eSprite &spr, long w, long h, String &fileout) { f_out.write(0); } f_out.close(); - Serial.println(millis() - t); - Serial.println("finished writing BMP"); + Serial.println("finished writing BMP " + String(millis() - t) + "ms"); } void bmp2grays(String filein, String fileout) { @@ -429,6 +428,5 @@ void bmp2grays(String filein, String fileout) { } f_in.close(); f_out.close(); - Serial.println(millis() - t); - Serial.println("finished writing BMP2"); + Serial.println("finished converting BMP " + String(millis() - t) + "ms"); } \ No newline at end of file diff --git a/esp32_fw/src/newproto.cpp b/esp32_fw/src/newproto.cpp index a69acb13..bbd2f148 100644 --- a/esp32_fw/src/newproto.cpp +++ b/esp32_fw/src/newproto.cpp @@ -49,14 +49,34 @@ void prepareCancelPending(uint64_t ver) { sendCancelPending(&pending); } -bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t nextCheckin) { +void prepareIdleReq(uint8_t* dst, uint16_t nextCheckin) { + if (nextCheckin > MIN_RESPONSE_TIME) { + // to prevent very long sleeps of the tag + nextCheckin = MIN_RESPONSE_TIME; + } + struct pendingData pending = {0}; + memcpy(pending.targetMac, dst, 8); + pending.availdatainfo.dataType = DATATYPE_NOUPDATE; + pending.availdatainfo.nextCheckIn = nextCheckin; + pending.attemptsLeft = 10; - if (nextCheckin > 1440) { + char buffer[64]; + uint8_t src[8]; + *((uint64_t*)src) = swap64(*((uint64_t*)dst)); + sprintf(buffer, "idle request %02X%02X%02X%02X%02X%02X %d minutes\n\0", src[2], src[3], src[4], src[5], src[6], src[7], nextCheckin); + Serial.print(buffer); + + sendDataAvail(&pending); +} + +bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t nextCheckin) { + if (nextCheckin > MIN_RESPONSE_TIME) { //to prevent very long sleeps of the tag - nextCheckin = 0; + nextCheckin = MIN_RESPONSE_TIME; } *filename = "/" + *filename; + LittleFS.begin(); if (!LittleFS.exists(*filename)) return false; fs::File file = LittleFS.open(*filename); @@ -137,7 +157,6 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t pendinginfo->data = nullptr; pendinginfo->timeout = PENDING_TIMEOUT; //pendinginfo->data = getDataForFile(&file); - pendinginfo->timeout = 1800; // ***fixme... a tag can sleep for a long time when ttl is used. pendingfiles.push_back(pendinginfo); if (dataType != DATATYPE_UPDATE) { @@ -157,7 +176,7 @@ bool prepareDataAvail(String* filename, uint8_t dataType, uint8_t* dst, uint16_t wsLog("new image pending: " + String(dst_path)); if (taginfo != nullptr) { taginfo->pending = true; - taginfo->CheckinInMinPending = nextCheckin + 1; + taginfo->CheckinInMinPending = nextCheckin; memcpy(taginfo->md5pending, md5bytes, sizeof(md5bytes)); } } @@ -244,14 +263,31 @@ void processXferComplete(struct espXferComplete* xfc) { tagRecord* taginfo = nullptr; taginfo = tagRecord::findByMAC(mac); 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 (minutesUntilNextUpdate > MIN_RESPONSE_TIME) minutesUntilNextUpdate = MIN_RESPONSE_TIME; + + taginfo->expectedNextCheckin = now + 60 * minutesUntilNextUpdate + 60; + if (minutesUntilNextUpdate > 0) prepareIdleReq (xfc->src, minutesUntilNextUpdate); + taginfo->CheckinInMinPending = minutesUntilNextUpdate; + } else { + taginfo->expectedNextCheckin = now + 60; + taginfo->CheckinInMinPending = 0; + } + taginfo->pending = false; - taginfo->expectedNextCheckin = now + 60 * taginfo->CheckinInMinPending + 30; memcpy(taginfo->md5, taginfo->md5pending, sizeof(taginfo->md5pending)); } wsSendTaginfo(mac); } void processDataReq(struct espAvailDataReq* eadr) { + + digitalWrite(ONBOARD_LED, LOW); + char buffer[64]; uint8_t src[8]; *((uint64_t*)src) = swap64(*((uint64_t*)eadr->src)); @@ -270,7 +306,19 @@ void processDataReq(struct espAvailDataReq* eadr) { time_t now; time(&now); taginfo->lastseen = now; - taginfo->expectedNextCheckin = now + 300; + + 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 (minutesUntilNextUpdate > MIN_RESPONSE_TIME) minutesUntilNextUpdate = MIN_RESPONSE_TIME; + taginfo->expectedNextCheckin = now + 60 * minutesUntilNextUpdate + 60; + if (minutesUntilNextUpdate > 0) prepareIdleReq(eadr->src, minutesUntilNextUpdate); + taginfo->CheckinInMinPending = minutesUntilNextUpdate; + } else { + taginfo->expectedNextCheckin = now + 60 * taginfo->CheckinInMinPending + 60; + } + if (eadr->adr.lastPacketRSSI != 0) { taginfo->LQI = eadr->adr.lastPacketLQI; taginfo->hwType = eadr->adr.hwType; @@ -287,4 +335,6 @@ void processDataReq(struct espAvailDataReq* eadr) { sprintf(buffer, "", 4) == 0) && waitingForVersion) { - waitingForVersion = false; + waitingForVersion = 0; pktindex = 0; RXState = ZBS_RX_WAIT_VER; charindex = 0; @@ -182,7 +187,8 @@ void SerialRXLoop() { if (charindex == 4) { charindex = 0; version = (uint16_t)strtoul(cmdbuffer, NULL, 16); - uint16_t fsversion; // BREAK here! break; + /* + uint16_t fsversion; lookupFirmwareFile(fsversion); if ((fsversion) && (version != fsversion)) { Serial.printf("ZBS/Zigbee FW version: %04X, version on SPIFFS: %04X\n", version, fsversion); @@ -194,6 +200,7 @@ void SerialRXLoop() { } else { Serial.printf("ZBS/Zigbee FW version: %04X\n", version); } + */ RXState = ZBS_RX_WAIT_HEADER; } break; @@ -208,6 +215,7 @@ void zbsRxTask(void* parameter) { simplePowerOn(); Serial1.print("VER?"); + waitingForVersion = esp_timer_get_time(); while (1) { SerialRXLoop(); @@ -216,13 +224,12 @@ void zbsRxTask(void* parameter) { } vTaskDelay(1 / portTICK_PERIOD_MS); if (waitingForVersion) { - if (millis() > 30000) { - waitingForVersion = false; - performDeviceFlash(); - // Serial.printf("We've been waiting for communication from the tag, but got nothing. This is expected if this tag hasn't been flashed yet. We'll try to flash it.\n"); - // doAPUpdate(); + if (esp_timer_get_time() - waitingForVersion > 10000*1000ULL) { + waitingForVersion = esp_timer_get_time(); //performDeviceFlash(); - // SDAtest(); + Serial.println("I wasn't able to connect to a ZBS tag, trying to reboot the tag."); + Serial.println("If this problem persists, please check wiring and definitions in the settings.h file, and presence of the right firmware"); + simplePowerOn(); } } } diff --git a/esp32_fw/src/tag_db.cpp b/esp32_fw/src/tag_db.cpp index 65c4f1aa..e6b6224f 100644 --- a/esp32_fw/src/tag_db.cpp +++ b/esp32_fw/src/tag_db.cpp @@ -149,7 +149,7 @@ void loadDB(String filename) { } taginfo->pending = false; taginfo->alias = tag["alias"].as(); - taginfo->contentMode = static_cast(tag["contentMode"]); + taginfo->contentMode = tag["contentMode"]; taginfo->LQI = tag["LQI"]; taginfo->RSSI = tag["RSSI"]; taginfo->temperature = tag["temperature"]; diff --git a/esp32_fw/src/web.cpp b/esp32_fw/src/web.cpp index fc01ad0f..e18d6f74 100644 --- a/esp32_fw/src/web.cpp +++ b/esp32_fw/src/web.cpp @@ -282,8 +282,11 @@ void init_web() { if (taginfo != nullptr) { taginfo->alias = request->getParam("alias", true)->value(); taginfo->modeConfigJson = request->getParam("modecfgjson", true)->value(); - taginfo->contentMode = (contentModes)atoi(request->getParam("contentmode", true)->value().c_str()); + 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); saveDB("/current/tagDB.json"); request->send(200, "text/plain", "Ok, saved");