diff --git a/Dev_Docs/Pending_Features/2026-06-14_1610_esp32_shine_reconnect_antifreeze.md b/Dev_Docs/Pending_Features/2026-06-14_1610_esp32_shine_reconnect_antifreeze.md new file mode 100644 index 0000000..94595b2 --- /dev/null +++ b/Dev_Docs/Pending_Features/2026-06-14_1610_esp32_shine_reconnect_antifreeze.md @@ -0,0 +1,26 @@ +# ESP32 антифриз при неверном SHiNE server + +- Статус: `pending` + +## Что сделано + +- уменьшены таймауты `SHiNE`-запросов и `WS`-подключения; +- повторные попытки подключения переведены на backoff: + - `10s` + - `20s` + - максимум `30s` +- пока открыт экран настроек или редактирования, новые фоновые попытки `SHiNE reconnect` не запускаются. + +## Что проверять + +1. Указать неверный адрес `SHiNE server`. +2. Дождаться статуса `unavailable`. +3. Проверить, что `HOME` не подвисает на секунды. +4. Проверить, что можно открыть `SETTINGS -> Server` и исправить адрес без лагов. +5. После сохранения правильного адреса убедиться, что reconnect снова идёт и устройство подключается. + +## Ожидаемый результат + +- при неверном адресе UI остаётся управляемым; +- вход в настройки и редактирование сервера остаются быстрыми; +- после исправления адреса устройство снова подключается без долгой паузы. diff --git a/ESP32/esp32/ESP32-S3-Touch-AMOLED-2.16/main-device/shine_homeserver_main/shine_homeserver_main.ino b/ESP32/esp32/ESP32-S3-Touch-AMOLED-2.16/main-device/shine_homeserver_main/shine_homeserver_main.ino index 9e38eb4..a542979 100644 --- a/ESP32/esp32/ESP32-S3-Touch-AMOLED-2.16/main-device/shine_homeserver_main/shine_homeserver_main.ino +++ b/ESP32/esp32/ESP32-S3-Touch-AMOLED-2.16/main-device/shine_homeserver_main/shine_homeserver_main.ino @@ -57,8 +57,10 @@ int ge25519_frombytes(ge25519_p3 *h, const unsigned char *s); #define HOME_REFRESH_MS 1000 #define ACCOUNT_CHECK_RETRY_MS 15000 #define SHINE_PING_INTERVAL_MS 60000 -#define SHINE_RECONNECT_MS 10000 -#define SHINE_RPC_TIMEOUT_MS 9000 +#define SHINE_RECONNECT_MIN_MS 10000 +#define SHINE_RECONNECT_MAX_MS 30000 +#define SHINE_RPC_TIMEOUT_MS 2500 +#define SHINE_WS_CONNECT_TIMEOUT_MS 1500 #define TEXT_EDIT_PANEL_X 10 #define TEXT_EDIT_PANEL_Y 112 #define TEXT_EDIT_PANEL_W 460 @@ -322,6 +324,7 @@ static String gShineStoragePwd; static bool gShineAuthenticated = false; static unsigned long gLastShineAttemptMs = 0; static unsigned long gLastShinePingMs = 0; +static unsigned long gShineReconnectDelayMs = SHINE_RECONNECT_MIN_MS; static uint32_t gWsRequestCounter = 1; static int64_t gShineServerTimeOffsetMs = 0; static SimpleWebSocketClient gShineWs; @@ -975,6 +978,25 @@ static void clearShineSessionState(bool clearStoredSession) { } } +static bool shouldPauseShineReconnectForUi() { + switch (gCurrentScreen) { + case SCREEN_SETTINGS_MENU: + case SCREEN_WIFI: + case SCREEN_SERVER: + case SCREEN_ACCOUNT: + case SCREEN_ACCOUNT_HOMESERVER: + case SCREEN_ACCOUNT_SECRET: + case SCREEN_SECRET_SHOW: + case SCREEN_SECRET_GENERATE_INFO: + case SCREEN_SECRET_GENERATE_RUNNING: + case SCREEN_SECRET_GENERATE_CANCEL_CONFIRM: + case SCREEN_TEXT_EDIT: + return true; + default: + return false; + } +} + static void markAccountStateDirty() { gAccountCheckPending = true; gLastAccountCheckMs = 0; @@ -2978,7 +3000,7 @@ static bool ensureWebSocketConnected(SimpleWebSocketClient &ws, const String &ur } ws.client.setInsecure(); - ws.client.setTimeout(5000); + ws.client.setTimeout(SHINE_WS_CONNECT_TIMEOUT_MS); if (!ws.client.connect(ws.host.c_str(), ws.port)) { errorOut = "WS connect failed"; return false; @@ -3347,22 +3369,28 @@ static void manageShineConnection() { if (gLoginValue.isEmpty() || !gSecretConfigured || gHomeserverValue.isEmpty()) { gShineStatusLine = String("SHiNE: ") + serverLabel + " account not configured"; clearShineSessionState(false); + gShineReconnectDelayMs = SHINE_RECONNECT_MIN_MS; return; } if (gAccountPdaStatus != ACCOUNT_PDA_OK) { gShineStatusLine = String("SHiNE: ") + serverLabel + " account not configured"; clearShineSessionState(false); + gShineReconnectDelayMs = SHINE_RECONNECT_MIN_MS; return; } if (WiFi.status() != WL_CONNECTED) { gShineStatusLine = String("SHiNE: ") + serverLabel + " unavailable"; clearShineSessionState(false); + gShineReconnectDelayMs = SHINE_RECONNECT_MIN_MS; return; } unsigned long now = millis(); if (!gShineAuthenticated || !gShineWs.connected || !gShineWs.client.connected()) { - if (now - gLastShineAttemptMs < SHINE_RECONNECT_MS) { + if (shouldPauseShineReconnectForUi()) { + return; + } + if (now - gLastShineAttemptMs < gShineReconnectDelayMs) { return; } gLastShineAttemptMs = now; @@ -3370,9 +3398,11 @@ static void manageShineConnection() { if (ensureShineSessionAuthenticated(error)) { gShineStatusLine = String("SHiNE: ") + serverLabel + " connected"; gLastShinePingMs = now; + gShineReconnectDelayMs = SHINE_RECONNECT_MIN_MS; } else { gShineStatusLine = String("SHiNE: ") + serverLabel + " unavailable"; clearShineSessionState(false); + gShineReconnectDelayMs = min(gShineReconnectDelayMs + SHINE_RECONNECT_MIN_MS, (unsigned long)SHINE_RECONNECT_MAX_MS); } return; } @@ -3383,6 +3413,7 @@ static void manageShineConnection() { uint64_t statusCode = 0; if (jsonInt64Field(pingResp, "status", statusCode) && statusCode == 200) { gLastShinePingMs = now; + gShineReconnectDelayMs = SHINE_RECONNECT_MIN_MS; gShineStatusLine = String("SHiNE: ") + serverLabel + " connected"; return; } @@ -3398,6 +3429,7 @@ static void manageShineConnection() { printRegisterDiagToSerial(); gShineStatusLine = String("SHiNE: ") + serverLabel + " unavailable"; clearShineSessionState(false); + gShineReconnectDelayMs = min(gShineReconnectDelayMs + SHINE_RECONNECT_MIN_MS, (unsigned long)SHINE_RECONNECT_MAX_MS); } } @@ -4012,6 +4044,8 @@ static void applyEditorValue() { saveServerPrefs(); gServerStatusMessage = "Shine server saved"; clearShineSessionState(false); + gShineReconnectDelayMs = SHINE_RECONNECT_MIN_MS; + gLastShineAttemptMs = 0; gShineStatusLine = "SHiNE: reconnect pending"; showScreen(SCREEN_SERVER); return; diff --git a/VERSION.properties b/VERSION.properties index 30a3d30..991fb9e 100644 --- a/VERSION.properties +++ b/VERSION.properties @@ -1,2 +1,2 @@ -client.version=1.2.187 -server.version=1.2.176 +client.version=1.2.188 +server.version=1.2.177