Check keypad codes
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#define NUKI_HUB_VERSION "9.02"
|
#define NUKI_HUB_VERSION "9.02"
|
||||||
#define NUKI_HUB_BUILD "unknownbuildnr"
|
#define NUKI_HUB_BUILD "unknownbuildnr"
|
||||||
#define NUKI_HUB_DATE "2024-10-13"
|
#define NUKI_HUB_DATE "2024-10-15"
|
||||||
|
|
||||||
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
|
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
|
||||||
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"
|
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ void NukiOpenerWrapper::readSettings()
|
|||||||
_retryDelay = _preferences->getInt(preference_command_retry_delay);
|
_retryDelay = _preferences->getInt(preference_command_retry_delay);
|
||||||
_rssiPublishInterval = _preferences->getInt(preference_rssi_publish_interval) * 1000;
|
_rssiPublishInterval = _preferences->getInt(preference_rssi_publish_interval) * 1000;
|
||||||
_disableNonJSON = _preferences->getBool(preference_disable_non_json, false);
|
_disableNonJSON = _preferences->getBool(preference_disable_non_json, false);
|
||||||
|
_checkKeypadCodes = _preferences->getBool(preference_keypad_check_code_enabled, false);
|
||||||
_preferences->getBytes(preference_conf_opener_basic_acl, &_basicOpenerConfigAclPrefs, sizeof(_basicOpenerConfigAclPrefs));
|
_preferences->getBytes(preference_conf_opener_basic_acl, &_basicOpenerConfigAclPrefs, sizeof(_basicOpenerConfigAclPrefs));
|
||||||
_preferences->getBytes(preference_conf_opener_advanced_acl, &_advancedOpenerConfigAclPrefs, sizeof(_advancedOpenerConfigAclPrefs));
|
_preferences->getBytes(preference_conf_opener_advanced_acl, &_advancedOpenerConfigAclPrefs, sizeof(_advancedOpenerConfigAclPrefs));
|
||||||
|
|
||||||
@@ -254,6 +255,11 @@ void NukiOpenerWrapper::update()
|
|||||||
updateKeypad(false);
|
updateKeypad(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_checkKeypadCodes && _invalidCount > 0 && ts - 120000 < _lastCodeCheck)
|
||||||
|
{
|
||||||
|
_invalidCount--;
|
||||||
|
}
|
||||||
|
|
||||||
if(_nextLockAction != (NukiOpener::LockAction)0xff)
|
if(_nextLockAction != (NukiOpener::LockAction)0xff)
|
||||||
{
|
{
|
||||||
int retryCount = 0;
|
int retryCount = 0;
|
||||||
@@ -714,10 +720,13 @@ void NukiOpenerWrapper::updateKeypad(bool retrieved)
|
|||||||
_network->publishKeypad(entries, _maxKeypadCodeCount);
|
_network->publishKeypad(entries, _maxKeypadCodeCount);
|
||||||
|
|
||||||
_keypadCodeIds.clear();
|
_keypadCodeIds.clear();
|
||||||
|
_keypadCodes.clear();
|
||||||
_keypadCodeIds.reserve(entries.size());
|
_keypadCodeIds.reserve(entries.size());
|
||||||
|
_keypadCodes.reserve(entries.size());
|
||||||
for(const auto& entry : entries)
|
for(const auto& entry : entries)
|
||||||
{
|
{
|
||||||
_keypadCodeIds.push_back(entry.codeId);
|
_keypadCodeIds.push_back(entry.codeId);
|
||||||
|
_keypadCodes.push_back(entry.code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1797,6 +1806,53 @@ void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value)
|
|||||||
idExists = std::find(_keypadCodeIds.begin(), _keypadCodeIds.end(), codeId) != _keypadCodeIds.end();
|
idExists = std::find(_keypadCodeIds.begin(), _keypadCodeIds.end(), codeId) != _keypadCodeIds.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(strcmp(action, "check") == 0) {
|
||||||
|
if(!_preferences->getBool(preference_keypad_check_code_enabled, false))
|
||||||
|
{
|
||||||
|
_network->publishKeypadJsonCommandResult("checkingKeypadCodesDisabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pow(_invalidCount, 5) + _lastCodeCheck > (esp_timer_get_time() / 1000))
|
||||||
|
{
|
||||||
|
_network->publishKeypadJsonCommandResult("checkingCodesBlockedTooManyInvalid");
|
||||||
|
_lastCodeCheck = (esp_timer_get_time() / 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastCodeCheck = (esp_timer_get_time() / 1000);
|
||||||
|
|
||||||
|
if(idExists)
|
||||||
|
{
|
||||||
|
auto it1 = std::find(_keypadCodeIds.begin(), _keypadCodeIds.end(), codeId);
|
||||||
|
int index = it1 - _keypadCodeIds.begin();
|
||||||
|
Log->print(F("Check keypad code: "));
|
||||||
|
|
||||||
|
if(code == _keypadCodes[index])
|
||||||
|
{
|
||||||
|
_invalidCount = 0;
|
||||||
|
_network->publishKeypadJsonCommandResult("codeValid");
|
||||||
|
Log->println("Valid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_invalidCount++;
|
||||||
|
_network->publishKeypadJsonCommandResult("codeInvalid");
|
||||||
|
Log->println("Invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_invalidCount++;
|
||||||
|
_network->publishKeypadJsonCommandResult("noExistingCodeIdSet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
Nuki::CmdResult result = (Nuki::CmdResult)-1;
|
Nuki::CmdResult result = (Nuki::CmdResult)-1;
|
||||||
int retryCount = 0;
|
int retryCount = 0;
|
||||||
|
|
||||||
@@ -2165,6 +2221,7 @@ void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value)
|
|||||||
_network->publishKeypadJsonCommandResult(resultStr);
|
_network->publishKeypadJsonCommandResult(resultStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_network->publishKeypadJsonCommandResult("noActionSet");
|
_network->publishKeypadJsonCommandResult("noActionSet");
|
||||||
|
|||||||
@@ -106,12 +106,16 @@ private:
|
|||||||
bool _publishAuthData = false;
|
bool _publishAuthData = false;
|
||||||
bool _clearAuthData = false;
|
bool _clearAuthData = false;
|
||||||
bool _disableNonJSON = false;
|
bool _disableNonJSON = false;
|
||||||
|
bool _checkKeypadCodes = false;
|
||||||
int _nrOfRetries = 0;
|
int _nrOfRetries = 0;
|
||||||
int _retryDelay = 0;
|
int _retryDelay = 0;
|
||||||
int _retryConfigCount = 0;
|
int _retryConfigCount = 0;
|
||||||
int _retryLockstateCount = 0;
|
int _retryLockstateCount = 0;
|
||||||
int64_t _nextRetryTs = 0;
|
int64_t _nextRetryTs = 0;
|
||||||
|
int64_t _invalidCount = 0;
|
||||||
|
int64_t _lastCodeCheck = 0;
|
||||||
std::vector<uint16_t> _keypadCodeIds;
|
std::vector<uint16_t> _keypadCodeIds;
|
||||||
|
std::vector<uint32_t> _keypadCodes;
|
||||||
std::vector<uint8_t> _timeControlIds;
|
std::vector<uint8_t> _timeControlIds;
|
||||||
std::vector<uint32_t> _authIds;
|
std::vector<uint32_t> _authIds;
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ void NukiWrapper::readSettings()
|
|||||||
_retryDelay = _preferences->getInt(preference_command_retry_delay);
|
_retryDelay = _preferences->getInt(preference_command_retry_delay);
|
||||||
_rssiPublishInterval = _preferences->getInt(preference_rssi_publish_interval) * 1000;
|
_rssiPublishInterval = _preferences->getInt(preference_rssi_publish_interval) * 1000;
|
||||||
_disableNonJSON = _preferences->getBool(preference_disable_non_json, false);
|
_disableNonJSON = _preferences->getBool(preference_disable_non_json, false);
|
||||||
|
_checkKeypadCodes = _preferences->getBool(preference_keypad_check_code_enabled, false);
|
||||||
_preferences->getBytes(preference_conf_lock_basic_acl, &_basicLockConfigaclPrefs, sizeof(_basicLockConfigaclPrefs));
|
_preferences->getBytes(preference_conf_lock_basic_acl, &_basicLockConfigaclPrefs, sizeof(_basicLockConfigaclPrefs));
|
||||||
_preferences->getBytes(preference_conf_lock_advanced_acl, &_advancedLockConfigaclPrefs, sizeof(_advancedLockConfigaclPrefs));
|
_preferences->getBytes(preference_conf_lock_advanced_acl, &_advancedLockConfigaclPrefs, sizeof(_advancedLockConfigaclPrefs));
|
||||||
|
|
||||||
@@ -369,6 +369,10 @@ void NukiWrapper::update()
|
|||||||
_nextKeypadUpdateTs = ts + _intervalKeypad * 1000;
|
_nextKeypadUpdateTs = ts + _intervalKeypad * 1000;
|
||||||
updateKeypad(false);
|
updateKeypad(false);
|
||||||
}
|
}
|
||||||
|
if(_checkKeypadCodes && _invalidCount > 0 && ts - 120000 < _lastCodeCheck)
|
||||||
|
{
|
||||||
|
_invalidCount--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(_clearAuthData)
|
if(_clearAuthData)
|
||||||
{
|
{
|
||||||
@@ -773,10 +777,13 @@ void NukiWrapper::updateKeypad(bool retrieved)
|
|||||||
_network->publishKeypad(entries, _maxKeypadCodeCount);
|
_network->publishKeypad(entries, _maxKeypadCodeCount);
|
||||||
|
|
||||||
_keypadCodeIds.clear();
|
_keypadCodeIds.clear();
|
||||||
|
_keypadCodes.clear();
|
||||||
_keypadCodeIds.reserve(entries.size());
|
_keypadCodeIds.reserve(entries.size());
|
||||||
|
_keypadCodes.reserve(entries.size());
|
||||||
for(const auto& entry : entries)
|
for(const auto& entry : entries)
|
||||||
{
|
{
|
||||||
_keypadCodeIds.push_back(entry.codeId);
|
_keypadCodeIds.push_back(entry.codeId);
|
||||||
|
_keypadCodes.push_back(entry.code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1919,6 +1926,53 @@ void NukiWrapper::onKeypadJsonCommandReceived(const char *value)
|
|||||||
idExists = std::find(_keypadCodeIds.begin(), _keypadCodeIds.end(), codeId) != _keypadCodeIds.end();
|
idExists = std::find(_keypadCodeIds.begin(), _keypadCodeIds.end(), codeId) != _keypadCodeIds.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(strcmp(action, "check") == 0) {
|
||||||
|
if(!_preferences->getBool(preference_keypad_check_code_enabled, false))
|
||||||
|
{
|
||||||
|
_network->publishKeypadJsonCommandResult("checkingKeypadCodesDisabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pow(_invalidCount, 5) + _lastCodeCheck > (esp_timer_get_time() / 1000))
|
||||||
|
{
|
||||||
|
_network->publishKeypadJsonCommandResult("checkingCodesBlockedTooManyInvalid");
|
||||||
|
_lastCodeCheck = (esp_timer_get_time() / 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastCodeCheck = (esp_timer_get_time() / 1000);
|
||||||
|
|
||||||
|
if(idExists)
|
||||||
|
{
|
||||||
|
auto it1 = std::find(_keypadCodeIds.begin(), _keypadCodeIds.end(), codeId);
|
||||||
|
int index = it1 - _keypadCodeIds.begin();
|
||||||
|
Log->print(F("Check keypad code: "));
|
||||||
|
|
||||||
|
if(code == _keypadCodes[index])
|
||||||
|
{
|
||||||
|
_invalidCount = 0;
|
||||||
|
_network->publishKeypadJsonCommandResult("codeValid");
|
||||||
|
Log->println("Valid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_invalidCount++;
|
||||||
|
_network->publishKeypadJsonCommandResult("codeInvalid");
|
||||||
|
Log->println("Invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_invalidCount++;
|
||||||
|
_network->publishKeypadJsonCommandResult("noExistingCodeIdSet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
Nuki::CmdResult result = (Nuki::CmdResult)-1;
|
Nuki::CmdResult result = (Nuki::CmdResult)-1;
|
||||||
int retryCount = 0;
|
int retryCount = 0;
|
||||||
|
|
||||||
@@ -2287,6 +2341,7 @@ void NukiWrapper::onKeypadJsonCommandReceived(const char *value)
|
|||||||
_network->publishKeypadJsonCommandResult(resultStr);
|
_network->publishKeypadJsonCommandResult(resultStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_network->publishKeypadJsonCommandResult("noActionSet");
|
_network->publishKeypadJsonCommandResult("noActionSet");
|
||||||
|
|||||||
@@ -107,7 +107,11 @@ private:
|
|||||||
int _restartBeaconTimeout = 0; // seconds
|
int _restartBeaconTimeout = 0; // seconds
|
||||||
bool _publishAuthData = false;
|
bool _publishAuthData = false;
|
||||||
bool _clearAuthData = false;
|
bool _clearAuthData = false;
|
||||||
|
bool _checkKeypadCodes = false;
|
||||||
|
int64_t _invalidCount = 0;
|
||||||
|
int64_t _lastCodeCheck = 0;
|
||||||
std::vector<uint16_t> _keypadCodeIds;
|
std::vector<uint16_t> _keypadCodeIds;
|
||||||
|
std::vector<uint32_t> _keypadCodes;
|
||||||
std::vector<uint8_t> _timeControlIds;
|
std::vector<uint8_t> _timeControlIds;
|
||||||
std::vector<uint32_t> _authIds;
|
std::vector<uint32_t> _authIds;
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,7 @@
|
|||||||
#define preference_recon_netw_on_mqtt_discon (char*)"recNtwMqttDis"
|
#define preference_recon_netw_on_mqtt_discon (char*)"recNtwMqttDis"
|
||||||
#define preference_official_hybrid_actions (char*)"hybridAct"
|
#define preference_official_hybrid_actions (char*)"hybridAct"
|
||||||
#define preference_official_hybrid_retry (char*)"hybridRtry"
|
#define preference_official_hybrid_retry (char*)"hybridRtry"
|
||||||
|
#define preference_keypad_check_code_enabled (char*)"kpChkEna"
|
||||||
|
|
||||||
//NOT USER CHANGABLE
|
//NOT USER CHANGABLE
|
||||||
#define preference_updater_version (char*)"updVer"
|
#define preference_updater_version (char*)"updVer"
|
||||||
@@ -284,7 +285,7 @@ private:
|
|||||||
preference_network_custom_mdc, preference_network_custom_clk, preference_network_custom_phy, preference_network_custom_addr, preference_network_custom_irq,
|
preference_network_custom_mdc, preference_network_custom_clk, preference_network_custom_phy, preference_network_custom_addr, 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_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_ntw_reconfigure, preference_lock_max_auth_entry_count, preference_opener_max_auth_entry_count,
|
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_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_auth_max_entries, preference_keypad_check_code_enabled
|
||||||
};
|
};
|
||||||
std::vector<char*> _redact =
|
std::vector<char*> _redact =
|
||||||
{
|
{
|
||||||
@@ -300,7 +301,7 @@ private:
|
|||||||
preference_publish_authdata, preference_publish_debug_info, preference_network_wifi_fallback_disabled, preference_official_hybrid_enabled,
|
preference_publish_authdata, preference_publish_debug_info, preference_network_wifi_fallback_disabled, preference_official_hybrid_enabled,
|
||||||
preference_official_hybrid_actions, preference_official_hybrid_retry, preference_conf_info_enabled, preference_disable_non_json, preference_update_from_mqtt,
|
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_recon_netw_on_mqtt_discon, preference_webserial_enabled,
|
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_recon_netw_on_mqtt_discon, preference_webserial_enabled,
|
||||||
preference_ntw_reconfigure
|
preference_ntw_reconfigure, preference_keypad_check_code_enabled
|
||||||
};
|
};
|
||||||
std::vector<char*> _bytePrefs =
|
std::vector<char*> _bytePrefs =
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1561,6 +1561,16 @@ bool WebCfgServer::processArgs(AsyncWebServerRequest *request, String& message)
|
|||||||
//configChanged = true;
|
//configChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(key == "KPCHECK")
|
||||||
|
{
|
||||||
|
if(_preferences->getBool(preference_keypad_check_code_enabled, false) != (value == "1"))
|
||||||
|
{
|
||||||
|
_preferences->putBool(preference_keypad_check_code_enabled, (value == "1"));
|
||||||
|
Log->print(F("Setting changed: "));
|
||||||
|
Log->println(key);
|
||||||
|
//configChanged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(key == "KPENA")
|
else if(key == "KPENA")
|
||||||
{
|
{
|
||||||
if(_preferences->getBool(preference_keypad_control_enabled, false) != (value == "1"))
|
if(_preferences->getBool(preference_keypad_control_enabled, false) != (value == "1"))
|
||||||
@@ -2639,15 +2649,15 @@ void WebCfgServer::buildCredHtml(AsyncWebServerRequest *request)
|
|||||||
{
|
{
|
||||||
_response = "";
|
_response = "";
|
||||||
buildHtmlHeader();
|
buildHtmlHeader();
|
||||||
_response.concat("<form class=\"adapt\" method=\"post\" action=\"savecfg\">");
|
_response.concat("<form id=\"credfrm\" class=\"adapt\" onsubmit=\"return testcreds();\" method=\"post\" action=\"savecfg\">");
|
||||||
_response.concat("<h3>Credentials</h3>");
|
_response.concat("<h3>Credentials</h3>");
|
||||||
_response.concat("<table>");
|
_response.concat("<table>");
|
||||||
printInputField("CREDUSER", "User (# to clear)", _preferences->getString(preference_cred_user).c_str(), 30, "", false, true);
|
printInputField("CREDUSER", "User (# to clear)", _preferences->getString(preference_cred_user).c_str(), 30, "id=\"inputuser\"", false, true);
|
||||||
printInputField("CREDPASS", "Password", "*", 30, "", true, true);
|
printInputField("CREDPASS", "Password", "*", 30, "id=\"inputpass\"", true, true);
|
||||||
printInputField("CREDPASSRE", "Retype password", "*", 30, "", true);
|
printInputField("CREDPASSRE", "Retype password", "*", 30, "", true);
|
||||||
_response.concat("</table>");
|
_response.concat("</table>");
|
||||||
_response.concat("<br><input type=\"submit\" name=\"submit\" value=\"Save\">");
|
_response.concat("<br><input type=\"submit\" name=\"submit\" value=\"Save\">");
|
||||||
_response.concat("</form>");
|
_response.concat("</form><script>function testcreds() { var input_user = document.getElementById(\"inputuser\").value; var input_pass = document.getElementById(\"inputpass\").value; var pattern = /^[ -~]*$/; if(!pattern.test(input_user) || !pattern.test(input_pass)) { alert('Only non unicode characters are allowed in username and password'); return false;} else { return true; } }</script>");
|
||||||
if(_nuki != nullptr)
|
if(_nuki != nullptr)
|
||||||
{
|
{
|
||||||
_response.concat("<br><br><form class=\"adapt\" method=\"post\" action=\"savecfg\">");
|
_response.concat("<br><br><form class=\"adapt\" method=\"post\" action=\"savecfg\">");
|
||||||
@@ -2919,6 +2929,7 @@ void WebCfgServer::buildAccLvlHtml(AsyncWebServerRequest *request)
|
|||||||
printCheckBox("KPPUB", "Publish keypad entries information", _preferences->getBool(preference_keypad_info_enabled), "");
|
printCheckBox("KPPUB", "Publish keypad entries information", _preferences->getBool(preference_keypad_info_enabled), "");
|
||||||
printCheckBox("KPPER", "Publish a topic per keypad entry and create HA sensor", _preferences->getBool(preference_keypad_topic_per_entry), "");
|
printCheckBox("KPPER", "Publish a topic per keypad entry and create HA sensor", _preferences->getBool(preference_keypad_topic_per_entry), "");
|
||||||
printCheckBox("KPCODE", "Also publish keypad codes (<span class=\"warning\">Disadvised for security reasons</span>)", _preferences->getBool(preference_keypad_publish_code, false), "");
|
printCheckBox("KPCODE", "Also publish keypad codes (<span class=\"warning\">Disadvised for security reasons</span>)", _preferences->getBool(preference_keypad_publish_code, false), "");
|
||||||
|
printCheckBox("KPCHECK", "Allow checking if keypad codes are valid (<span class=\"warning\">Disadvised for security reasons</span>)", _preferences->getBool(preference_keypad_check_code_enabled, false), "");
|
||||||
printCheckBox("KPENA", "Add, modify and delete keypad codes", _preferences->getBool(preference_keypad_control_enabled), "");
|
printCheckBox("KPENA", "Add, modify and delete keypad codes", _preferences->getBool(preference_keypad_control_enabled), "");
|
||||||
}
|
}
|
||||||
printCheckBox("TCPUB", "Publish time control entries information", _preferences->getBool(preference_timecontrol_info_enabled), "");
|
printCheckBox("TCPUB", "Publish time control entries information", _preferences->getBool(preference_timecontrol_info_enabled), "");
|
||||||
@@ -3386,6 +3397,8 @@ void WebCfgServer::buildInfoHtml(AsyncWebServerRequest *request)
|
|||||||
_response.concat(_preferences->getBool(preference_keypad_topic_per_entry, false) ? "Yes" : "No");
|
_response.concat(_preferences->getBool(preference_keypad_topic_per_entry, false) ? "Yes" : "No");
|
||||||
_response.concat("\nPublish Keypad codes: ");
|
_response.concat("\nPublish Keypad codes: ");
|
||||||
_response.concat(_preferences->getBool(preference_keypad_publish_code, false) ? "Yes" : "No");
|
_response.concat(_preferences->getBool(preference_keypad_publish_code, false) ? "Yes" : "No");
|
||||||
|
_response.concat("\nAllow checking Keypad codes: ");
|
||||||
|
_response.concat(_preferences->getBool(preference_keypad_check_code_enabled, false) ? "Yes" : "No");
|
||||||
_response.concat("\nMax keypad entries to retrieve: ");
|
_response.concat("\nMax keypad entries to retrieve: ");
|
||||||
_response.concat(_preferences->getInt(preference_keypad_max_entries, MAX_KEYPAD));
|
_response.concat(_preferences->getInt(preference_keypad_max_entries, MAX_KEYPAD));
|
||||||
_response.concat("\nPublish timecontrol info: ");
|
_response.concat("\nPublish timecontrol info: ");
|
||||||
|
|||||||
Reference in New Issue
Block a user