diff --git a/src/NukiOpenerWrapper.cpp b/src/NukiOpenerWrapper.cpp index a32f8dd..3222a44 100644 --- a/src/NukiOpenerWrapper.cpp +++ b/src/NukiOpenerWrapper.cpp @@ -123,6 +123,8 @@ void NukiOpenerWrapper::readSettings() _disableNonJSON = _preferences->getBool(preference_disable_non_json, false); _checkKeypadCodes = _preferences->getBool(preference_keypad_check_code_enabled, false); _pairedAsApp = _preferences->getBool(preference_register_opener_as_app, false); + _forceKeypad = _preferences->getBool(preference_opener_force_keypad, false); + _forceId = _preferences->getBool(preference_opener_force_id, false); _preferences->getBytes(preference_conf_opener_basic_acl, &_basicOpenerConfigAclPrefs, sizeof(_basicOpenerConfigAclPrefs)); _preferences->getBytes(preference_conf_opener_advanced_acl, &_advancedOpenerConfigAclPrefs, sizeof(_advancedOpenerConfigAclPrefs)); @@ -428,7 +430,10 @@ void NukiOpenerWrapper::unpair() nukiBlePref.clear(); nukiBlePref.end(); _deviceId->assignNewId(); - _preferences->remove(preference_nuki_id_opener); + if(!_forceId) + { + _preferences->remove(preference_nuki_id_opener); + } _paired = false; } @@ -563,7 +568,7 @@ void NukiOpenerWrapper::updateConfig() if(_nukiConfigValid) { - if(_preferences->getUInt(preference_nuki_id_opener, 0) == 0 || _retryConfigCount == 10) + if(!_forceId && (_preferences->getUInt(preference_nuki_id_opener, 0) == 0 || _retryConfigCount == 10)) { char uidString[20]; itoa(_nukiConfig.nukiId, uidString, 16); @@ -4001,7 +4006,7 @@ const bool NukiOpenerWrapper::isPaired() const const bool NukiOpenerWrapper::hasKeypad() const { - return _hasKeypad; + return _forceKeypad || _hasKeypad; } const BLEAddress NukiOpenerWrapper::getBleAddress() const diff --git a/src/NukiOpenerWrapper.h b/src/NukiOpenerWrapper.h index 0af838a..a57fc3d 100644 --- a/src/NukiOpenerWrapper.h +++ b/src/NukiOpenerWrapper.h @@ -132,7 +132,9 @@ private: bool _statusUpdated = false; int _newSignal = 0; bool _hasKeypad = false; + bool _forceKeypad = false; bool _keypadEnabled = false; + bool _forceId = false; uint _maxKeypadCodeCount = 0; uint _maxTimeControlEntryCount = 0; uint _maxAuthEntryCount = 0; diff --git a/src/NukiWrapper.cpp b/src/NukiWrapper.cpp index 7c772e3..cb7a578 100644 --- a/src/NukiWrapper.cpp +++ b/src/NukiWrapper.cpp @@ -124,6 +124,9 @@ void NukiWrapper::readSettings() _disableNonJSON = _preferences->getBool(preference_disable_non_json, false); _checkKeypadCodes = _preferences->getBool(preference_keypad_check_code_enabled, false); _pairedAsApp = _preferences->getBool(preference_register_as_app, false); + _forceDoorsensor = _preferences->getBool(preference_lock_force_doorsensor, false); + _forceKeypad = _preferences->getBool(preference_lock_force_keypad, false); + _forceId = _preferences->getBool(preference_lock_force_id, false); _preferences->getBytes(preference_conf_lock_basic_acl, &_basicLockConfigaclPrefs, sizeof(_basicLockConfigaclPrefs)); _preferences->getBytes(preference_conf_lock_advanced_acl, &_advancedLockConfigaclPrefs, sizeof(_advancedLockConfigaclPrefs)); @@ -434,7 +437,10 @@ void NukiWrapper::unpair() nukiBlePref.clear(); nukiBlePref.end(); _deviceId->assignNewId(); - _preferences->remove(preference_nuki_id_lock); + if (!_forceId) + { + _preferences->remove(preference_nuki_id_lock); + } _paired = false; } @@ -557,7 +563,7 @@ void NukiWrapper::updateConfig() if(_nukiConfigValid) { - if(_preferences->getUInt(preference_nuki_id_lock, 0) == 0 || _retryConfigCount == 10) + if(!_forceId && (_preferences->getUInt(preference_nuki_id_lock, 0) == 0 || _retryConfigCount == 10)) { char uidString[20]; itoa(_nukiConfig.nukiId, uidString, 16); @@ -4031,7 +4037,7 @@ const bool NukiWrapper::isPaired() const const bool NukiWrapper::hasKeypad() const { - return _hasKeypad; + return _forceKeypad || _hasKeypad; } void NukiWrapper::notify(Nuki::EventType eventType) @@ -4127,7 +4133,8 @@ void NukiWrapper::readAdvancedConfig() bool NukiWrapper::hasDoorSensor() const { - return _keyTurnerState.doorSensorState == Nuki::DoorSensorState::DoorClosed || + return _forceDoorsensor || + _keyTurnerState.doorSensorState == Nuki::DoorSensorState::DoorClosed || _keyTurnerState.doorSensorState == Nuki::DoorSensorState::DoorOpened || _keyTurnerState.doorSensorState == Nuki::DoorSensorState::Calibrating; } diff --git a/src/NukiWrapper.h b/src/NukiWrapper.h index 1336f92..116c4a7 100644 --- a/src/NukiWrapper.h +++ b/src/NukiWrapper.h @@ -132,7 +132,10 @@ private: bool _statusUpdated = false; int _newSignal = 0; bool _hasKeypad = false; + bool _forceDoorsensor = false; + bool _forceKeypad = false; bool _keypadEnabled = false; + bool _forceId = false; uint _maxKeypadCodeCount = 0; uint _maxTimeControlEntryCount = 0; uint _maxAuthEntryCount = 0; diff --git a/src/PreferencesKeys.h b/src/PreferencesKeys.h index beedf5a..149e70a 100644 --- a/src/PreferencesKeys.h +++ b/src/PreferencesKeys.h @@ -113,6 +113,11 @@ #define preference_official_hybrid_retry (char*)"hybridRtry" #define preference_keypad_check_code_enabled (char*)"kpChkEna" #define preference_retain_gpio (char*)"retGpio" +#define preference_lock_force_id (char*)"lckForceId" +#define preference_lock_force_doorsensor (char*)"lckForceDrsns" +#define preference_lock_force_keypad (char*)"lckForceKp" +#define preference_opener_force_id (char*)"opForceId" +#define preference_opener_force_keypad (char*)"opForceKp" //NOT USER CHANGABLE #define preference_updater_version (char*)"updVer" @@ -380,8 +385,8 @@ private: preference_network_custom_pwr, preference_network_custom_mdio, preference_ntw_reconfigure, preference_lock_max_auth_entry_count, preference_opener_max_auth_entry_count, preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_auth_max_entries, preference_wifi_ssid, preference_wifi_pass, preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_mqtt_hass_enabled, preference_hass_device_discovery, preference_retain_gpio, - preference_debug_connect, preference_debug_communication, preference_debug_readable_data, preference_debug_hex_data, preference_debug_command, preference_connect_mode - + preference_debug_connect, preference_debug_communication, preference_debug_readable_data, preference_debug_hex_data, preference_debug_command, preference_connect_mode, + preference_lock_force_id, preference_lock_force_doorsensor, preference_lock_force_keypad, preference_opener_force_id, preference_opener_force_keypad }; std::vector _redact = { @@ -398,7 +403,8 @@ private: preference_official_hybrid_actions, preference_official_hybrid_retry, preference_conf_info_enabled, preference_disable_non_json, preference_update_from_mqtt, preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_webserial_enabled, preference_hass_device_discovery, preference_ntw_reconfigure, preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_find_best_rssi, - preference_debug_connect, preference_debug_communication, preference_debug_readable_data, preference_debug_hex_data, preference_debug_command, preference_connect_mode + preference_debug_connect, preference_debug_communication, preference_debug_readable_data, preference_debug_hex_data, preference_debug_command, preference_connect_mode, + preference_lock_force_id, preference_lock_force_doorsensor, preference_lock_force_keypad, preference_opener_force_id, preference_opener_force_keypad }; std::vector _bytePrefs = { diff --git a/src/WebCfgServer.cpp b/src/WebCfgServer.cpp index c56b227..e978173 100644 --- a/src/WebCfgServer.cpp +++ b/src/WebCfgServer.cpp @@ -112,7 +112,7 @@ void WebCfgServer::initialize() } return sendFavicon(request); }); - + if(_network->isApOpen()) { #ifndef CONFIG_IDF_TARGET_ESP32H2 @@ -365,7 +365,7 @@ void WebCfgServer::initialize() #else return request->redirect("/"); #endif - } + } else { if(!_network->isApOpen()) @@ -406,11 +406,11 @@ void WebCfgServer::initialize() { String message = ""; bool restart = processArgs(request, message); - if(request->hasParam("mqttssl")) + if(request->hasParam("mqttssl")) { return buildConfirmHtml(request, message, 3, true, "/get?page=mqttconfig"); } - else + else { return buildConfirmHtml(request, message, 3, true); } @@ -441,7 +441,7 @@ void WebCfgServer::initialize() String message = ""; bool restart = processImport(request, message); return buildConfirmHtml(request, message, 3, true); - } + } else #else if (1 == 1) @@ -461,7 +461,7 @@ void WebCfgServer::initialize() return buildWifiConnectHtml(request); } #endif - } + } }); PsychicUploadHandler *updateHandler = new PsychicUploadHandler(); @@ -2255,6 +2255,51 @@ bool WebCfgServer::processArgs(PsychicRequest *request, String& message) configChanged = true; } } + else if(key == "LCKFORCEID") + { + if(_preferences->getBool(preference_lock_force_id, false) != (value == "1")) + { + _preferences->putBool(preference_lock_force_id, (value == "1")); + Log->print(F("Setting changed: ")); + Log->println(key); + } + } + else if(key == "LCKFORCEKP") + { + if(_preferences->getBool(preference_lock_force_keypad, false) != (value == "1")) + { + _preferences->putBool(preference_lock_force_keypad, (value == "1")); + Log->print(F("Setting changed: ")); + Log->println(key); + } + } + else if(key == "LCKFORCEDS") + { + if(_preferences->getBool(preference_lock_force_doorsensor, false) != (value == "1")) + { + _preferences->putBool(preference_lock_force_doorsensor, (value == "1")); + Log->print(F("Setting changed: ")); + Log->println(key); + } + } + else if(key == "OPFORCEID") + { + if(_preferences->getBool(preference_opener_force_id, false) != (value == "1")) + { + _preferences->putBool(preference_opener_force_id, (value == "1")); + Log->print(F("Setting changed: ")); + Log->println(key); + } + } + else if(key == "OPFORCEKP") + { + if(_preferences->getBool(preference_opener_force_keypad, false) != (value == "1")) + { + _preferences->putBool(preference_opener_force_keypad, (value == "1")); + Log->print(F("Setting changed: ")); + Log->println(key); + } + } else if(key == "ACLLVLCHANGED") { aclLvlChanged = true; @@ -3649,7 +3694,7 @@ esp_err_t WebCfgServer::buildMqttConfigHtml(PsychicRequest *request) } response.print("Set MQTT SSL CA Certificate"); response.print("Set MQTT SSL Client Certificate"); - response.print("Set MQTT SSL Client Key"); + response.print("Set MQTT SSL Client Key"); printInputField(&response, "NETTIMEOUT", "MQTT Timeout until restart (seconds; -1 to disable)", _preferences->getInt(preference_network_timeout), 5, ""); printCheckBox(&response, "MQTTLOG", "Enable MQTT logging", _preferences->getBool(preference_mqtt_log_enabled), ""); printCheckBox(&response, "UPDATEMQTT", "Allow updating using MQTT", _preferences->getBool(preference_update_from_mqtt), ""); @@ -3742,6 +3787,28 @@ esp_err_t WebCfgServer::buildAdvancedConfigHtml(PsychicRequest *request) printInputField(&response, "OTAUPD", "Custom URL to update Nuki Hub updater", "", 255, ""); printInputField(&response, "OTAMAIN", "Custom URL to update Nuki Hub", "", 255, ""); + std::vector> optionsForce; + optionsForce.push_back(std::make_pair("0", "Do not force")); + optionsForce.push_back(std::make_pair("1", "Force unavailable")); + optionsForce.push_back(std::make_pair("2", "Force available")); + + if(_nuki != nullptr) + { + char uidString[20]; + itoa(_preferences->getUInt(preference_nuki_id_lock, 0), uidString, 16); + printCheckBox(&response, "LCKFORCEID", ((String)"Force Lock ID to current ID (" + uidString + ")").c_str(), _preferences->getBool(preference_lock_force_id, false), ""); + printCheckBox(&response, "LCKFORCEKP", "Force Lock Keypad connected", _preferences->getBool(preference_lock_force_keypad, false), ""); + printCheckBox(&response, "LCKFORCEDS", "Force Lock Doorsensor connected", _preferences->getBool(preference_lock_force_doorsensor, false), ""); + } + + if(_nukiOpener != nullptr) + { + char uidString[20]; + itoa(_preferences->getUInt(preference_nuki_id_opener, 0), uidString, 16); + printCheckBox(&response, "OPFORCEID", ((String)"Force Opener ID to current ID (" + uidString + ")").c_str(), _preferences->getBool(preference_opener_force_id, false), ""); + printCheckBox(&response, "OPFORCEKP", "Force Opener Keypad", _preferences->getBool(preference_opener_force_keypad, false), ""); + } + printCheckBox(&response, "DBGCONN", "Enable Nuki connect debug logging", _preferences->getBool(preference_debug_connect, false), ""); printCheckBox(&response, "DBGCOMMU", "Enable Nuki communication debug logging", _preferences->getBool(preference_debug_communication, false), ""); printCheckBox(&response, "DBGREAD", "Enable Nuki readable data debug logging", _preferences->getBool(preference_debug_readable_data, false), "");