From 9b316cd216294b38ea1a677f668b15f3c62b1183 Mon Sep 17 00:00:00 2001 From: iranl Date: Tue, 4 Nov 2025 21:26:51 +0100 Subject: [PATCH] Make BLE timeouts configurable --- README.md | 2 ++ src/NukiOpenerWrapper.cpp | 2 ++ src/NukiWrapper.cpp | 2 ++ src/PreferencesKeys.h | 11 ++++++++--- src/WebCfgServer.cpp | 26 ++++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ae4e861..76a551f 100644 --- a/README.md +++ b/README.md @@ -410,6 +410,8 @@ Note that the following options can break Nuki Hub and cause bootloops that will - Char buffer size (min 4096, max 65536): Set the character buffer size, needs to be enlarged to support large amounts of auth/keypad/timecontrol/authorization entries. Default 4096. - Task size Network (min 12288, max 65536): Set the Network task stack size, needs to be enlarged to support large amounts of auth/keypad/timecontrol/authorization entries. Default 12288. - Task size Nuki (min 8192, max 65536): Set the Nuki task stack size. Default 8192. +- BLE General timeout in ms (min 3000, max 65536): General timeout for communication with Nuki devices, default 3000ms. Mainly used when retrieving Nuki keypad authorizations +- BLE Command timeout in ms (min 3000, max 65536): Command timeout for communication with Nuki devices, default 3000ms. - Max auth log entries (min 1, max 100): The maximum amount of log entries that will be requested from the lock/opener, default 5. - Max keypad entries (min 1, max 200): The maximum amount of keypad codes that will be requested from the lock/opener, default 10. - Max timecontrol entries (min 1, max 100): The maximum amount of timecontrol entries that will be requested from the lock/opener, default 10. diff --git a/src/NukiOpenerWrapper.cpp b/src/NukiOpenerWrapper.cpp index c969dca..b8c4ea4 100644 --- a/src/NukiOpenerWrapper.cpp +++ b/src/NukiOpenerWrapper.cpp @@ -69,6 +69,8 @@ void NukiOpenerWrapper::initialize() _nukiOpener.setEventHandler(this); _nukiOpener.setConnectTimeout(2); _nukiOpener.setDisconnectTimeout(2000); + _nukiOpener.setGeneralTimeout(_preferences->getInt(preference_ble_general_timeout, 3000)); + _nukiOpener.setCommandTimeout(_preferences->getInt(preference_ble_command_timeout, 3000)); _hassEnabled = _preferences->getBool(preference_mqtt_hass_enabled, false); readSettings(); diff --git a/src/NukiWrapper.cpp b/src/NukiWrapper.cpp index 0598a70..654bef2 100644 --- a/src/NukiWrapper.cpp +++ b/src/NukiWrapper.cpp @@ -75,6 +75,8 @@ void NukiWrapper::initialize() _nukiLock.setEventHandler(this); _nukiLock.setConnectTimeout(2); _nukiLock.setDisconnectTimeout(2000); + _nukiLock.setGeneralTimeout(_preferences->getInt(preference_ble_general_timeout, 3000)); + _nukiLock.setCommandTimeout(_preferences->getInt(preference_ble_command_timeout, 3000)); _hassEnabled = _preferences->getBool(preference_mqtt_hass_enabled, false); readSettings(); diff --git a/src/PreferencesKeys.h b/src/PreferencesKeys.h index 151dff4..c89de71 100644 --- a/src/PreferencesKeys.h +++ b/src/PreferencesKeys.h @@ -159,6 +159,8 @@ #define preference_mqtt_crt (char*)"mqttcrt" #define preference_mqtt_key (char*)"mqttkey" #define preference_save_log_num (char*)"svLgNm" +#define preference_ble_general_timeout (char*)"bleGenTmOt" +#define preference_ble_command_timeout (char*)"bleCmdTmOt" //NOT USER CHANGABLE #define preference_mfa_reconfigure (char*)"mfaRECONF" @@ -264,7 +266,9 @@ inline void initPreferences(Preferences* preferences) preferences->putInt(preference_mqtt_broker_port, 1883); preferences->putInt(preference_buffer_size, CHAR_BUFFER_SIZE); preferences->putInt(preference_task_size_network, NETWORK_TASK_SIZE); - preferences->putInt(preference_task_size_nuki, NUKI_TASK_SIZE); + preferences->putInt(preference_task_size_nuki, NUKI_TASK_SIZE); + preferences->putInt(preference_ble_general_timeout, 3000); + preferences->putInt(preference_ble_command_timeout, 3000); preferences->putInt(preference_authlog_max_entries, MAX_AUTHLOG); preferences->putInt(preference_keypad_max_entries, MAX_KEYPAD); preferences->putInt(preference_timecontrol_max_entries, MAX_TIMECONTROL); @@ -557,7 +561,7 @@ private: preference_cred_session_lifetime, preference_cred_session_lifetime_remember, preference_cred_session_lifetime_duo, preference_cred_session_lifetime_duo_remember, preference_cred_duo_approval, preference_cred_bypass_boot_btn_enabled, preference_cred_bypass_gpio_high, preference_cred_bypass_gpio_low, preference_publish_config, preference_config_from_mqtt, preference_totp_secret, preference_cred_session_lifetime_totp, preference_cred_session_lifetime_totp_remember, preference_bypass_secret, - preference_admin_secret + preference_admin_secret, preference_ble_general_timeout, preference_ble_command_timeout }; std::vector _redact = { @@ -597,7 +601,8 @@ private: preference_network_custom_irq, preference_network_custom_rst, preference_network_custom_cs, preference_network_custom_sck, preference_network_custom_miso, preference_network_custom_mosi, preference_network_custom_pwr, preference_network_custom_mdio, preference_http_auth_type, preference_cred_session_lifetime, preference_cred_session_lifetime_remember, preference_cred_session_lifetime_duo, preference_cred_session_lifetime_duo_remember, - preference_cred_bypass_gpio_high, preference_cred_bypass_gpio_low, preference_cred_session_lifetime_totp, preference_cred_session_lifetime_totp_remember + preference_cred_bypass_gpio_high, preference_cred_bypass_gpio_low, preference_cred_session_lifetime_totp, preference_cred_session_lifetime_totp_remember, + preference_ble_general_timeout, preference_ble_command_timeout }; std::vector _uintPrefs = { diff --git a/src/WebCfgServer.cpp b/src/WebCfgServer.cpp index 56d4d9e..7727526 100644 --- a/src/WebCfgServer.cpp +++ b/src/WebCfgServer.cpp @@ -3813,6 +3813,30 @@ bool WebCfgServer::processArgs(PsychicRequest *request, PsychicResponse* resp, S } } } + else if(key == "BLEGENTIMEOUT") + { + if(value.toInt() > 2999 && value.toInt() < 65537) + { + if(_preferences->getInt(preference_ble_general_timeout, 3000) != value.toInt()) + { + _preferences->putInt(preference_ble_general_timeout, value.toInt()); + Log->print("Setting changed: "); + Log->println(key); + } + } + } + else if(key == "BLECMDTIMEOUT") + { + if(value.toInt() > 2999 && value.toInt() < 65537) + { + if(_preferences->getInt(preference_ble_command_timeout, 3000) != value.toInt()) + { + _preferences->putInt(preference_ble_command_timeout, value.toInt()); + Log->print("Setting changed: "); + Log->println(key); + } + } + } else if(key == "ALMAX") { if(value.toInt() > 0 && value.toInt() < 101) @@ -5732,6 +5756,8 @@ esp_err_t WebCfgServer::buildAdvancedConfigHtml(PsychicRequest *request, Psychic printInputField(&response, "TSKNTWK", "Task size Network (min 12288, max 65536)", _preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), 6, ""); response.print("Advised minimum network task size based on current settings"); printInputField(&response, "TSKNUKI", "Task size Nuki (min 8192, max 65536)", _preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), 6, ""); + printInputField(&response, "BLEGENTIMEOUT", "BLE General timeout in ms (min 3000, max 65536)", _preferences->getInt(preference_ble_general_timeout, 3000), 6, ""); + printInputField(&response, "BLECMDTIMEOUT", "BLE Command timeout in ms (min 3000, max 65536)", _preferences->getInt(preference_ble_command_timeout, 3000), 6, ""); printInputField(&response, "ALMAX", "Max auth log entries (min 1, max 100)", _preferences->getInt(preference_authlog_max_entries, MAX_AUTHLOG), 3, "id=\"inputmaxauthlog\""); printInputField(&response, "KPMAX", "Max keypad entries (min 1, max 200)", _preferences->getInt(preference_keypad_max_entries, MAX_KEYPAD), 3, "id=\"inputmaxkeypad\""); printInputField(&response, "TCMAX", "Max timecontrol entries (min 1, max 100)", _preferences->getInt(preference_timecontrol_max_entries, MAX_TIMECONTROL), 3, "id=\"inputmaxtimecontrol\"");