From 0fb0c6f74ddcfc6900dd6568c18e98f7a14684d3 Mon Sep 17 00:00:00 2001 From: Nic Limper Date: Thu, 27 Mar 2025 01:03:04 +0100 Subject: [PATCH] more robust extended sleep time and 'no updates between' handling --- ESP32_AP-Flasher/data/www/index.html.gz | Bin 6554 -> 6568 bytes ESP32_AP-Flasher/data/www/main.js.gz | Bin 16166 -> 16258 bytes ESP32_AP-Flasher/include/tag_db.h | 1 + ESP32_AP-Flasher/platformio.ini | 121 +++++++++++------------- ESP32_AP-Flasher/src/contentmanager.cpp | 12 ++- ESP32_AP-Flasher/src/makeimage.cpp | 14 +++ ESP32_AP-Flasher/src/newproto.cpp | 12 +-- ESP32_AP-Flasher/src/tag_db.cpp | 16 ++-- ESP32_AP-Flasher/src/web.cpp | 3 + ESP32_AP-Flasher/wwwroot/index.html | 43 +++++---- ESP32_AP-Flasher/wwwroot/main.js | 22 ++++- 11 files changed, 139 insertions(+), 105 deletions(-) diff --git a/ESP32_AP-Flasher/data/www/index.html.gz b/ESP32_AP-Flasher/data/www/index.html.gz index a369830b09ebf5ec784923053a306f25bb18cd42..8ae02dee1a4ff5eb1d67dd7f78455b555371ea41 100644 GIT binary patch literal 6568 zcmV;Z8CT{XiwFn+00002|7mVyWq2-VbZu+^5xg-c&3lHJnGoIJ!Au^U~e zDijJ;g~H|V4=0zsn_sT_ZMG$$3srtiX2gw9W}~iMj!bsnk5C1WPy64Lnx@1NKLW+>M-P?%Q}}n^GN@S z`Ya&l+`A{;(TGV&t_1hO!u+GC5@oT0ITe*bo{?O9_Q(WC(@2DX$LyP^qMlaFCaU zQaq#Ods$S%SxR}Wjzz{;T18Juy5sltu}_El&c5*Fr}BI<4a=uz=jY|O*WHtUZnn$qdc6$) z+Sa5+XNis+?>C_2ipUweG+>G-{f$1>Tt1XFpWcgFv)ZWE)nj$0dM6|1!Ia2FKdCMuAstGh#rrBt0KQaEtD$pQ zP%;3^5ZEIU)LBcjBDFLt!blU;j)t@n(qIB(s5BKgc81XLsIW(+6Dp@eK?A4M!A}Xl zpGzpDlQf+hIsrjT=DJ^w1ohJt(qacvBOrAbia86i1aT02R=e2DcL6rjI8z2>hk=+& zW{D}vao2ucYeAvqbV;N{6@qRMH5!jf4wt~mV&4-UJ1BM3=R4tjIhlhxj(MhM2P_P^ zr+ZgFeK~3{!qTM9#bg2mN*%Opchcj&&%!jd%rlOy+S9?+Ig~#22zQQ3LFCC0SV0Sr zs+a|$zJeJES0r*q>sFEc6Wb?^UH|cbJg^|-;5;hSq^emn%hjb+Tnn7eEk0c+ldKIn{v3-<0# zfMq+Z(WkOaS+$xmYuauqBZ+URPR|&yWfMB*o+IY=i~fWSkIht~ImW$PGkA!~#9}QA z10uYU%SZR%nOJzrU1(j`a|Tl}fBoHe-^bPyK%M+fQA{}2HV&W@B6)_cF-G$$?zR|l zEp#$eR^Y%W#l=26Dm7EMOmxB}^l`OXU4;>zgRj17x}U=j410?Oh#9_MlLI# zD0X~URQohOh%B+90(eZls zmI<3C+PNlEfN87Ki-G_uxC^3Hl%V|uH{8lZUMh-E-^WU`ZK!i-qJUzaFoeL%WqNEt zpr=vYQ5S+Qjb~N-Wyx#kOF!holbKme(iiwL2}IoylJ)r41=M?Fr{ZM8H*q;dJlgOYpOh<^abe7VE*nJ;@HQS)X370OEG*` z;9r9eqfLn4a1-lShMTywrysrsFUm%YrWDMa6^(scV#b#C^utDGo=h^bTuKpyFV-cg z@=1n$2+OE6e4FRdl#TA0ljUB2>vZww%ZM?<#*B^(6Zn)Rtx7KF=qr#_od-4|l#F?X zf%rAcMN)hYPXr&o7DFD)|03VPsgW7zP_R7ERndF+OEl=`sFSu~h1pjMG8B)t1;+N; zHn;+2idLBFc}bGGO#QrAggHC}Y$jsynU^dVwow0mEk107WjKjnv%Dn57y~&3+|$=$ z$hU#F;>W&a*@;Wd!`I@)1n04;=(lBMF{P;>y0EIRblBjcU@97>q7(hTI;AriVfHYN zYD_AulxcmO3xJq~&rq5p>OD}I!lH|x$jw3+>$)C5TgCOCm1Euj5HKm+2xFAZP$LFv z=xl;X``!&;DJ!}b25p#95uOWX%;849f^-@=`_U+}SrjlCRpPNZnL!*)Cya1O=9FWC z4;7DuQx$QNP!J!2eXy~m&Ywm+7`coFftUw;G7S&1++$>wWY}VdA z?m9QOjmvZ1j)LE}XCG%DefTr3)oSx@_MhInt>Z3W>(0C9y5y(sG5%a1-(R>t{Jzup zCGcAx|K&btfB4Y*#k>4CnEdqfqJQzr{Do&p z;p*o%pDqXYz5easbU3^D`Rd9a{`N4r0rZ#iqa!VWB^5OCSZVW6LK5cL4jV?3*yuH~ z1}*{U;GCRL*Clf{lmbF9KpD{Sn8%UNTH6-6ikea8Bq16X#FZjDIBg@*HMr?;Wkn#I&F6@zym_b3d(cD?RD9;E$J zHaDT)OiEsKqfjV%pv&+GO2S8))i@V%I1JSPF~Sc#oD!OaE`v8gPXi7|H`GB_hF(pr z1R@D7Fjk8)7%9#qqKEK7Og#RH zY4-`{5ZLfQp+g#kh7nu>AaQc1Oa>5^%*aJk<#&ki+(k7dsil@~6y5FM*hsD?W;3LV z!)d+PZgDw+#A{1-k$nQvjD~7y9oN3~(l@SrFTaKXW3?HCIV`AwLfxHeh5DmlzFRTc z zqlI3naGwCdXa@4dKC%62df)I>T@q^s6F7|h>~|mZ#3(kdO;+Xs_4f(>Rf@gTBJ!8Y z^jG*3lCvxP9pfL4e;D)e$HPCLe*N~Fzf>xIh%XiP$noJ{0|+v9-ymeZZ&-vD6e6kd>+=5xdX{z5Q>$slZ^W zRHn@J2|8;KBMd6_YGX$vgbe^#Y;#%n!r2x6*L55;TgXU+E9aFlepbAa4~lBKXW%xT=1RdVpbI1EFDO&h2{?O2%f>b}B5QHTVqn-8peX?6`RvTN@HW{rvdW}ZCVNt3SDXt(yK!%1Pg`nQ4me%TnjD{0#y4Ij5s1E6x1(d?! z5}WSic6l9o6aJ72+1+ke>+o~|Oug<$fxy5BBJ1z-aiDgAP!Pu!;Mjf%jwa%0DjeI@ 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 a`z`RIb9249y7OFL)c?O`;$N}CUjP6Yt)kHY literal 6554 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 M3!#Y;-`QUP08ziLc>n+a diff --git a/ESP32_AP-Flasher/data/www/main.js.gz b/ESP32_AP-Flasher/data/www/main.js.gz index ee8fa5123c8f2fe67a25fed65ed4e305a669588d..289da7c1fad4a3cea0a8598440ffe9bb54fc2622 100644 GIT binary patch delta 15957 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 BsuBPI diff --git a/ESP32_AP-Flasher/include/tag_db.h b/ESP32_AP-Flasher/include/tag_db.h index 21ffa38f..7465429d 100644 --- a/ESP32_AP-Flasher/include/tag_db.h +++ b/ESP32_AP-Flasher/include/tag_db.h @@ -75,6 +75,7 @@ struct Config { uint8_t discovery; String repo; String env; + uint8_t showtimestamp; }; struct Color { diff --git a/ESP32_AP-Flasher/platformio.ini b/ESP32_AP-Flasher/platformio.ini index 36494404..cc32e130 100644 --- a/ESP32_AP-Flasher/platformio.ini +++ b/ESP32_AP-Flasher/platformio.ini @@ -6,9 +6,8 @@ platform = platformio/espressif32@^6.10.0 ;platform = https://github.com/pioarduino/platform-espressif32/releases/download/stable/platform-espressif32.zip framework = arduino lib_deps = - ESP32Async/AsyncTCP - ESP32Async/ESPAsyncWebServer - + ESP32Async/AsyncTCP + ESP32Async/ESPAsyncWebServer bblanchon/ArduinoJson bodmer/TFT_eSPI https://github.com/Bodmer/TJpg_Decoder.git @@ -30,7 +29,9 @@ build_flags = -D DISABLE_ALL_LIBRARY_WARNINGS -D ILI9341_DRIVER -D SMOOTH_FONT - -D ARDUINOJSON_ENABLE_COMMENTS=1 + -D LOAD_FONT2 + -D LOAD_GLCD + -D ARDUINOJSON_ENABLE_COMMENTS=1 ; ---------------------------------------------------------------------------------------- ; !!! this configuration expects the 16MB Flash / 8MB Ram version of the ESP32-S3-DevkitC1 ; ---------------------------------------------------------------------------------------- @@ -101,11 +102,11 @@ board = esp32-s3-devkitc-1 board_build.partitions = large_spiffs_16MB.csv build_unflags = -std=gnu++11 - -D ARDUINO_USB_MODE=1 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y - -D ILI9341_DRIVER + -D ARDUINO_USB_MODE=1 + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -D ILI9341_DRIVER lib_deps = - ${env.lib_deps} + ${env.lib_deps} build_flags = -std=gnu++17 ${env.build_flags} @@ -144,7 +145,6 @@ build_flags = -D TFT_RST=1 -D TFT_RGB_ORDER=TFT_BGR -D USE_HSPI_PORT - -D LOAD_FONT2 -D MD5_ENABLED=1 -D SERIAL_FLASHER_INTERFACE_UART=1 -D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50 @@ -169,8 +169,8 @@ monitor_dtr = 0 monitor_rts = 0 build_unflags = -std=gnu++11 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y - ;-D ILI9341_DRIVER + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + ;-D ILI9341_DRIVER lib_deps = ${env.lib_deps} lib_extra_dirs = lib2/Arduino_GFX-1.3.7 build_flags = @@ -207,7 +207,6 @@ build_flags = -D TFT_HEIGHT=480 -D TFT_HW_TYPE=226 -D USE_HSPI_PORT - -D LOAD_FONT2 -D MD5_ENABLED=1 -D SERIAL_FLASHER_INTERFACE_UART=1 -D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=200 @@ -233,11 +232,11 @@ monitor_dtr = 0 monitor_rts = 0 build_unflags = -std=gnu++11 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y lib_deps = ${env.lib_deps} lib_extra_dirs = lib2/Arduino_GFX-1.3.7 - lib2/gt911-touch -build_flags = + lib2/gt911-touch +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_TFT @@ -250,7 +249,7 @@ build_flags = -D BOARD_HAS_PSRAM -D CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y -D HAS_BLE_WRITER - -D FLASHER_AP_SS=-1 + -D FLASHER_AP_SS=-1 -D FLASHER_AP_CLK=-1 -D FLASHER_AP_MOSI=-1 -D FLASHER_AP_MISO=-1 @@ -272,7 +271,6 @@ build_flags = -D TFT_HEIGHT=480 -D TFT_HW_TYPE=226 -D USE_HSPI_PORT - -D LOAD_FONT2 -D MD5_ENABLED=1 -D SERIAL_FLASHER_INTERFACE_UART=1 -D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=200 @@ -295,15 +293,15 @@ board = esp32-s3-devkitc-1 board_build.partitions = large_spiffs_16MB.csv build_unflags = -std=gnu++11 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y lib_deps = - ${env.lib_deps} -build_flags = + ${env.lib_deps} +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_BLE_WRITER -D CORE_DEBUG_LEVEL=0 - -D ARDUINO_USB_CDC_ON_BOOT + -D ARDUINO_USB_CDC_ON_BOOT -D CONFIG_ESP32S3_SPIRAM_SUPPORT=1 -D CONFIG_SPIRAM_USE_MALLOC=1 -D POWER_NO_SOFT_POWER @@ -344,15 +342,15 @@ board = esp32-s3-devkitc-1 board_build.partitions = large_spiffs_16MB.csv build_unflags = -std=gnu++11 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y lib_deps = - ${env.lib_deps} -build_flags = + ${env.lib_deps} +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_BLE_WRITER -D CORE_DEBUG_LEVEL=0 - -D ARDUINO_USB_CDC_ON_BOOT + -D ARDUINO_USB_CDC_ON_BOOT -D CONFIG_ESP32S3_SPIRAM_SUPPORT=1 -D CONFIG_SPIRAM_USE_MALLOC=1 -D POWER_NO_SOFT_POWER @@ -393,15 +391,15 @@ board = esp32-s3-devkitc-1 board_build.partitions = large_spiffs_16MB.csv build_unflags = -std=gnu++11 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y lib_deps = - ${env.lib_deps} -build_flags = + ${env.lib_deps} +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_BLE_WRITER -D CORE_DEBUG_LEVEL=0 - -D ARDUINO_USB_CDC_ON_BOOT + -D ARDUINO_USB_CDC_ON_BOOT -D CONFIG_ESP32S3_SPIRAM_SUPPORT=1 -D CONFIG_SPIRAM_USE_MALLOC=1 -D POWER_NO_SOFT_POWER @@ -445,16 +443,16 @@ board = esp32-s3-devkitc-1 board_build.partitions = large_spiffs_16MB.csv build_unflags = -std=gnu++11 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -D ILI9341_DRIVER lib_deps = - ${env.lib_deps} -build_flags = + ${env.lib_deps} +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_TFT -D CORE_DEBUG_LEVEL=1 - -D ARDUINO_USB_CDC_ON_BOOT=1 + -D ARDUINO_USB_CDC_ON_BOOT=1 -D CONFIG_ESP32S3_SPIRAM_SUPPORT=1 -D CONFIG_SPIRAM_USE_MALLOC=1 -D POWER_NO_SOFT_POWER @@ -489,16 +487,13 @@ build_flags = -D TFT_RST=1 -D TFT_RGB_ORDER=TFT_BGR -D USE_HSPI_PORT - -D LOAD_FONT2 - -D LOAD_FONT4 - -D LOAD_GLCD -D MD5_ENABLED=1 -D SERIAL_FLASHER_INTERFACE_UART=1 -D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=200 -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=200 -D C6_OTA_FLASHING - -D HAS_SUBGHZ -build_src_filter = + -D HAS_SUBGHZ +build_src_filter = +<*>--- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -514,16 +509,16 @@ board = esp32-s3-devkitc-1 board_build.partitions = large_spiffs_16MB.csv build_unflags = -std=gnu++11 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -D ILI9341_DRIVER lib_deps = - ${env.lib_deps} -build_flags = + ${env.lib_deps} +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_TFT -D CORE_DEBUG_LEVEL=1 - -D ARDUINO_USB_CDC_ON_BOOT=1 + -D ARDUINO_USB_CDC_ON_BOOT=1 -D CONFIG_ESP32S3_SPIRAM_SUPPORT=1 -D CONFIG_SPIRAM_USE_MALLOC=1 -D POWER_NO_SOFT_POWER @@ -558,16 +553,13 @@ build_flags = -D TFT_RST=1 -D TFT_RGB_ORDER=TFT_BGR -D USE_HSPI_PORT - -D LOAD_FONT2 - -D LOAD_FONT4 - -D LOAD_GLCD -D MD5_ENABLED=1 -D SERIAL_FLASHER_INTERFACE_UART=1 -D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=200 -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=200 -D C6_OTA_FLASHING - -D HAS_SUBGHZ -build_src_filter = + -D HAS_SUBGHZ +build_src_filter = +<*>--- board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -583,11 +575,11 @@ board = esp32-s3-devkitc-1 board_build.partitions = large_spiffs_16MB.csv build_unflags = -std=gnu++11 - -D ARDUINO_USB_MODE=1 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -D ARDUINO_USB_MODE=1 + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y lib_deps = - ${env.lib_deps} -build_flags = + ${env.lib_deps} +build_flags = -std=gnu++17 ${env.build_flags} -D CORE_DEBUG_LEVEL=0 @@ -633,8 +625,8 @@ build_unflags = -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -std=gnu++11 lib_deps = - ${env.lib_deps} -build_flags = + ${env.lib_deps} +build_flags = -std=gnu++17 ${env.build_flags} -D OPENEPAPERLINK_POE_AP_PCB @@ -676,17 +668,17 @@ monitor_dtr = 0 monitor_rts = 0 build_unflags = -std=gnu++11 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -D ILI9341_DRIVER lib_deps = - ${env.lib_deps} -build_flags = + ${env.lib_deps} +build_flags = -std=gnu++17 ${env.build_flags} -D HAS_TFT -D HAS_EXT_FLASHER -D CORE_DEBUG_LEVEL=1 - -D ARDUINO_USB_CDC_ON_BOOT=1 + -D ARDUINO_USB_CDC_ON_BOOT=1 -D CONFIG_ESP32S3_SPIRAM_SUPPORT=1 -D CONFIG_SPIRAM_USE_MALLOC=1 -D POWER_NO_SOFT_POWER @@ -741,16 +733,13 @@ build_flags = -D TFT_RST=1 -D TFT_RGB_ORDER=TFT_BGR -D USE_HSPI_PORT - -D LOAD_FONT2 - -D LOAD_FONT4 - -D LOAD_GLCD -D MD5_ENABLED=1 -D SERIAL_FLASHER_INTERFACE_UART=1 -D SERIAL_FLASHER_BOOT_HOLD_TIME_MS=200 -D SERIAL_FLASHER_RESET_HOLD_TIME_MS=200 -D C6_OTA_FLASHING - -D HAS_SUBGHZ -build_src_filter = + -D HAS_SUBGHZ +build_src_filter = +<*> board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi @@ -767,11 +756,11 @@ board = esp32-s3-devkitc-1 board_build.partitions = large_spiffs_16MB.csv build_unflags = -std=gnu++11 - -D ARDUINO_USB_MODE=1 - -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y - -D ILI9341_DRIVER + -D ARDUINO_USB_MODE=1 + -D CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y + -D ILI9341_DRIVER lib_deps = - ${env.lib_deps} + ${env.lib_deps} build_flags = -std=gnu++17 ${env.build_flags} diff --git a/ESP32_AP-Flasher/src/contentmanager.cpp b/ESP32_AP-Flasher/src/contentmanager.cpp index 284e9f91..19ef5da6 100644 --- a/ESP32_AP-Flasher/src/contentmanager.cpp +++ b/ESP32_AP-Flasher/src/contentmanager.cpp @@ -54,17 +54,22 @@ void contentRunner() { time_t now; time(&now); + uint8_t wifimac[8]; + WiFi.macAddress(wifimac); + memset(&wifimac[6], 0, 2); for (tagRecord *taginfo : tagDB) { + + const bool isAp = memcmp(taginfo->mac, wifimac, 8) == 0; if (taginfo->RSSI && (now >= taginfo->nextupdate || needRedraw(taginfo->contentMode, taginfo->wakeupReason)) && - config.runStatus == RUNSTATUS_RUN && - Storage.freeSpace() > 31000 && !util::isSleeping(config.sleepTime1, config.sleepTime2)) { + config.runStatus == RUNSTATUS_RUN && (taginfo->expectedNextCheckin < now + 300 || isAp) && + Storage.freeSpace() > 31000 && !util::isSleeping(config.sleepTime1, config.sleepTime2)) { drawNew(taginfo->mac, taginfo); taginfo->wakeupReason = 0; } - if (taginfo->expectedNextCheckin > now - 10 && taginfo->expectedNextCheckin < now + 30 && taginfo->pendingIdle == 0 && taginfo->pendingCount == 0) { + if (taginfo->expectedNextCheckin > now - 10 && taginfo->expectedNextCheckin < now + 30 && taginfo->pendingIdle == 0 && taginfo->pendingCount == 0 && !isAp) { int32_t minutesUntilNextUpdate = (taginfo->nextupdate - now) / 60; if (minutesUntilNextUpdate > config.maxsleep) { minutesUntilNextUpdate = config.maxsleep; @@ -82,6 +87,7 @@ void contentRunner() { } if (minutesUntilNextUpdate > 1 && (wsClientCount() == 0 || config.stopsleep == 0)) { taginfo->pendingIdle = minutesUntilNextUpdate * 60; + taginfo->expectedNextCheckin = now + taginfo->pendingIdle; if (taginfo->isExternal == false) { prepareIdleReq(taginfo->mac, minutesUntilNextUpdate); } diff --git a/ESP32_AP-Flasher/src/makeimage.cpp b/ESP32_AP-Flasher/src/makeimage.cpp index 982e61ed..dd8d0f0a 100644 --- a/ESP32_AP-Flasher/src/makeimage.cpp +++ b/ESP32_AP-Flasher/src/makeimage.cpp @@ -365,9 +365,23 @@ uint8_t *g5Compress(uint16_t width, uint16_t height, uint8_t *buffer, uint16_t b } #endif +void doTimestamp(TFT_eSprite *spr) { + time_t now = time(nullptr); + struct tm *timeinfo = localtime(&now); + char buffer[20]; + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M", timeinfo); + + // spr->drawRect(spr->width() - 16 * 6 - 4, spr->height() - 10 - 2, 16 * 6 + 3, 11, TFT_BLACK); + spr->drawRect(spr->width() - 16 * 6 - 3, spr->height() - 10 - 1, 16 * 6 + 1, 9, TFT_WHITE); + spr->setTextColor(TFT_BLACK, TFT_WHITE); + spr->setCursor(spr->width() - 16 * 6 - 2, spr->height() - 10, 1); + spr->print(buffer); +} + void spr2buffer(TFT_eSprite &spr, String &fileout, imgParam &imageParams) { long t = millis(); + if (config.showtimestamp) doTimestamp(&spr); #ifdef HAS_TFT extern uint8_t YellowSense; if (fileout == "direct") { diff --git a/ESP32_AP-Flasher/src/newproto.cpp b/ESP32_AP-Flasher/src/newproto.cpp index 14fe25c7..37c5a45c 100644 --- a/ESP32_AP-Flasher/src/newproto.cpp +++ b/ESP32_AP-Flasher/src/newproto.cpp @@ -507,9 +507,9 @@ void processXferTimeout(struct espXferComplete* xfc, bool local) { if (taginfo != nullptr) { taginfo->pendingIdle = 60; clearPending(taginfo); - while (dequeueItem(xfc->src)) { - }; } + while (dequeueItem(xfc->src)) { + }; checkQueue(xfc->src); @@ -560,15 +560,14 @@ void processDataReq(struct espAvailDataReq* eadr, bool local, IPAddress remoteIP taginfo->apIp = IPAddress(0, 0, 0, 0); } - if (taginfo->pendingIdle == 0) { - taginfo->expectedNextCheckin = now + 60; + if (taginfo->pendingIdle == 0 || countQueueItem(eadr->src) > 0) { + if (taginfo->expectedNextCheckin < now + 60) taginfo->expectedNextCheckin = now + 60; } else if (taginfo->pendingIdle == 9999) { taginfo->expectedNextCheckin = 3216153600; - taginfo->pendingIdle = 0; } else { taginfo->expectedNextCheckin = now + taginfo->pendingIdle; - taginfo->pendingIdle = 0; } + taginfo->pendingIdle = 0; taginfo->lastseen = now; if (eadr->adr.lastPacketRSSI != 0) { @@ -607,6 +606,7 @@ void processDataReq(struct espAvailDataReq* eadr, bool local, IPAddress remoteIP if (local) { sprintf(buffer, "src[7], eadr->src[6], eadr->src[5], eadr->src[4], eadr->src[3], eadr->src[2], eadr->src[1], eadr->src[0]); Serial.print(buffer); + checkQueue(eadr->src); // experiemental 3/26/25: redundant check } if (local) { diff --git a/ESP32_AP-Flasher/src/tag_db.cpp b/ESP32_AP-Flasher/src/tag_db.cpp index 4feba865..a0abebe0 100644 --- a/ESP32_AP-Flasher/src/tag_db.cpp +++ b/ESP32_AP-Flasher/src/tag_db.cpp @@ -211,7 +211,7 @@ bool loadDB(const String& filename) { taginfo->nextupdate = (uint32_t)tag["nextupdate"]; taginfo->expectedNextCheckin = (uint32_t)tag["nextcheckin"]; if (taginfo->expectedNextCheckin < now) { - taginfo->expectedNextCheckin = now + 1800; + taginfo->expectedNextCheckin = now + 60; } taginfo->pendingCount = 0; taginfo->alias = tag["alias"].as(); @@ -280,11 +280,11 @@ uint32_t getTagCount(uint32_t& timeoutcount, uint32_t& lowbattcount) { if (!taginfo->isExternal) tagcount++; const int32_t timeout = now - taginfo->lastseen; if (taginfo->expectedNextCheckin < 3600) { - // not initialised, timeout if not seen last 10 minutes - if (timeout > 600) timeoutcount++; - } else if (now - taginfo->expectedNextCheckin > 600) { - // expected checkin is behind, timeout if not seen last 10 minutes - if (timeout > 600) timeoutcount++; + // not initialised, timeout if not seen last 5 minutes + if (timeout > config.maxsleep * 60 + 300) timeoutcount++; + } else if (now - static_cast(taginfo->expectedNextCheckin) > 600) { + // expected checkin is behind, timeout if not seen last 5 minutes + if (timeout > config.maxsleep * 60 + 300) timeoutcount++; } if (taginfo->batteryMv < 2400 && taginfo->batteryMv != 0 && taginfo->batteryMv != 1337) lowbattcount++; } @@ -335,8 +335,9 @@ void initAPconfig() { config.sleepTime2 = APconfig["sleeptime2"].is() ? APconfig["sleeptime2"] : 0; config.ble = APconfig["ble"].is() ? APconfig["ble"] : 0; config.discovery = APconfig["discovery"].is() ? APconfig["discovery"] : 0; + config.showtimestamp = APconfig["showtimestamp"].is() ? APconfig["showtimestamp"] : 0; #ifdef BLE_ONLY - config.ble = true; + config.ble = true; #endif // default wifi power 8.5 dbM // see https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiGeneric.h#L111 @@ -373,6 +374,7 @@ void saveAPconfig() { APconfig["repo"] = config.repo; APconfig["env"] = config.env; APconfig["discovery"] = config.discovery; + APconfig["showtimestamp"] = config.showtimestamp; serializeJsonPretty(APconfig, configFile); configFile.close(); xSemaphoreGive(fsMutex); diff --git a/ESP32_AP-Flasher/src/web.cpp b/ESP32_AP-Flasher/src/web.cpp index 19d29577..440c4d90 100644 --- a/ESP32_AP-Flasher/src/web.cpp +++ b/ESP32_AP-Flasher/src/web.cpp @@ -634,6 +634,9 @@ void init_web() { if (request->hasParam("discovery", true)) { config.discovery = static_cast(request->getParam("discovery", true)->value().toInt()); } + if (request->hasParam("showtimestamp", true)) { + config.showtimestamp = static_cast(request->getParam("showtimestamp", true)->value().toInt()); + } if (request->hasParam("repo", true)) { config.repo = request->getParam("repo", true)->value(); } diff --git a/ESP32_AP-Flasher/wwwroot/index.html b/ESP32_AP-Flasher/wwwroot/index.html index 6360e21b..8f5438b3 100644 --- a/ESP32_AP-Flasher/wwwroot/index.html +++ b/ESP32_AP-Flasher/wwwroot/index.html @@ -290,24 +290,24 @@ options:

-

- - -

+

+ + +

+

+ + +

diff --git a/ESP32_AP-Flasher/wwwroot/main.js b/ESP32_AP-Flasher/wwwroot/main.js index a7c24ba4..9d2d942d 100644 --- a/ESP32_AP-Flasher/wwwroot/main.js +++ b/ESP32_AP-Flasher/wwwroot/main.js @@ -375,7 +375,7 @@ function processTags(tagArray) { if (element.nextcheckin > 1672531200) { div.dataset.nextcheckin = element.nextcheckin; } else { - div.dataset.nextcheckin = element.lastseen + 1800; + div.dataset.nextcheckin = element.lastseen + 60; } div.style.opacity = '1'; @@ -461,7 +461,7 @@ function updatecards() { if (item.dataset.lastseen && item.dataset.lastseen > (Date.now() / 1000) - servertimediff - 30 * 24 * 3600 * 60) { 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 - 600 > item.dataset.nextcheckin) { + if ((Date.now() / 1000) - servertimediff - apConfig.maxsleep * 60 - 300 > item.dataset.nextcheckin) { $('#tag' + tagmac + ' .warningicon').style.display = 'inline-block'; $('#tag' + tagmac).classList.remove("tagpending") $('#tag' + tagmac).style.background = '#e0e0a0'; @@ -793,6 +793,7 @@ document.addEventListener("loadTab", function (event) { $("#apcnight1").value = data.sleeptime1; $("#apcnight2").value = data.sleeptime2; $("#apcdiscovery").value = data.discovery; + $("#apcshowtimestamp").value = data.showtimestamp; } }) $('#apcfgmsg').innerHTML = ''; @@ -830,7 +831,8 @@ $('#apcfgsave').onclick = function () { formData.append('timezone', $('#apctimezone').value); formData.append('sleeptime1', $('#apcnight1').value); formData.append('sleeptime2', $('#apcnight2').value); - formData.append('discovery', $('#apcdiscovery').value) + formData.append('discovery', $('#apcdiscovery').value); + formData.append('showtimestamp', $('#apcshowtimestamp').value); fetch("save_apcfg", { method: "POST", body: formData @@ -1788,14 +1790,24 @@ function populateAPInfo(apip) { }) .then(data => { if (data.env) { + let gModuleType = ""; + if (data.hasC6 == 1) { + gModuleType = "esp32-C6"; + } + if (data.hasH2 == 1) { + gModuleType = "esp32-H2"; + } + if (data.hasTslr == 1) { + gModuleType = "TSLR"; + } let version = ''; version += `env: ${data.env}
`; version += `build date: ${formatEpoch(data.buildtime)}
`; version += `esp32 version: ${data.buildversion}
`; version += `psram size: ${data.psramsize}
`; version += `flash size: ${data.flashsize}
`; - if (data.hasC6) { - version += `ESP-C6/H2 version: 0x${parseInt(data.C6version).toString(16).toUpperCase()}
`; + if (gModuleType) { + version += `${gModuleType} version: 0x${parseInt(data.ap_version).toString(16).toUpperCase()}
`; } $('#ap' + apid + ' .apswversion').innerHTML = version; }