@@ -33,11 +33,16 @@ static bool verNewer(const char *rel, const char *cur) {
3333}
3434// Ask GitHub for the latest RELEASE: its tag (= firmware version) and the firmware.bin
3535// asset URL. updAvail = the released version differs from this build. Runs on core-0.
36- static void updateCheck () {
37- if (WiFi .status () != WL_CONNECTED || !timeSynced || otaActive ) return ; // cert validation needs a real clock
36+ // Returns true if GitHub answered with a valid release (so the caller can back off to the slow
37+ // 6h cadence); false on any network/TLS/parse failure (caller retries soon). updChkState feeds
38+ // the Settings row: 1=checking, 2=up-to-date, -1=check failed.
39+ static bool updateCheck () {
40+ if (WiFi .status () != WL_CONNECTED || !timeSynced || otaActive ) return false; // cert validation needs a real clock
41+ updChkState = 1 ; // checking…
42+ bool got = false;
3843 WiFiClientSecure net ; otaTrust (net );
3944 HTTPClient http ; http .setConnectTimeout (5000 ); http .setTimeout (6000 );
40- if (!http .begin (net , "https://api.github.com/repos/holoduke/JKBMS/releases/latest" )) return ;
45+ if (!http .begin (net , "https://api.github.com/repos/holoduke/JKBMS/releases/latest" )) { updChkState = -1 ; return false; }
4146 http .addHeader ("User-Agent" , "jkbms-device" );
4247 if (http .GET () == 200 ) {
4348 JsonDocument filter ; // keep only the fields we need (the release JSON is big)
@@ -55,10 +60,13 @@ static void updateCheck() {
5560 strncpy (updUrl , url , sizeof (updUrl ) - 1 ); updUrl [sizeof (updUrl ) - 1 ] = 0 ;
5661 const char * cur = instTag [0 ] ? instTag : FW_VERSION ;
5762 updAvail = verNewer (updTag , cur ); // only flag a genuinely NEWER release (not a downgrade)
63+ got = true;
5864 }
5965 }
6066 }
6167 http .end ();
68+ updChkState = got ? (updAvail ? 0 : 2 ) : -1 ; // available→0 (icon speaks) / up-to-date→2 / failed→-1
69+ return got ;
6270}
6371// One download+flash attempt of updUrl. Returns true only on a fully written, finalised image.
6472// Streams the GitHub asset (→ signed CDN redirect) straight into the inactive app slot.
@@ -132,9 +140,15 @@ static void netTask(void *) {
132140 lastPoll = now ;
133141 bmsRead (); // history sampling + energy integration run on core 1 (see bmsPoll_cb) to avoid a cross-core race on those buffers
134142 }
135- if ((!lastUpd && now > 30000 ) || (lastUpd && now - lastUpd > 21600000UL )) { // GitHub release check ~30s after boot, then every 6h
136- lastUpd = now ; updateCheck ();
137- if (updAvail && autoUpdate ) updGo = true; // auto-update enabled → flash it
143+ // GitHub release check: ~15s after boot, then every 6h — but if a check FAILS, retry in
144+ // ~60s instead of waiting 6h (a single transient failure used to hide an update until the
145+ // next 6h window). A manual "check now" (Settings row / web) forces it immediately.
146+ bool due = (!lastUpd && now > 15000 ) || (lastUpd && now - lastUpd > 21600000UL ) || updCheckNow ;
147+ if (due ) {
148+ updCheckNow = false;
149+ bool ok = updateCheck ();
150+ lastUpd = ok ? now : (now - 21600000UL + 60000UL ); // ok → 6h; failed → retry in ~60s
151+ if (updAvail && autoUpdate ) updGo = true; // auto-update enabled → flash it
138152 }
139153 if (updGo ) { updGo = false; selfUpdate (); } // manual "Update now" (web) or auto trigger
140154 vTaskDelay (pdMS_TO_TICKS (20 ));
0 commit comments