diff --git a/NukiWrapper.cpp b/NukiWrapper.cpp
index 91b7913..d484f5e 100644
--- a/NukiWrapper.cpp
+++ b/NukiWrapper.cpp
@@ -739,8 +739,12 @@ void NukiWrapper::setupHASS()
String baseTopic = _preferences->getString(preference_mqtt_lock_path);
char uidString[20];
itoa(_nukiConfig.nukiId, uidString, 16);
+
+ bool HASSkeypad = _hasKeypad;
+
+ if(_preferences->getBool(preference_lock_force_keypad)) HASSkeypad = true;
- _network->publishHASSConfig("SmartLock", baseTopic.c_str(),(char*)_nukiConfig.name, uidString, hasDoorSensor(), _hasKeypad, _publishAuthData, "lock", "unlock", "unlatch");
+ _network->publishHASSConfig("SmartLock", baseTopic.c_str(),(char*)_nukiConfig.name, uidString, hasDoorSensor(), HASSkeypad, _publishAuthData, "lock", "unlock", "unlatch");
_hassSetupCompleted = true;
Log->println("HASS setup for lock completed.");
@@ -748,6 +752,8 @@ void NukiWrapper::setupHASS()
bool NukiWrapper::hasDoorSensor() const
{
+ if(_preferences->getBool(preference_lock_force_doorsensor)) return true;
+
return _keyTurnerState.doorSensorState == Nuki::DoorSensorState::DoorClosed ||
_keyTurnerState.doorSensorState == Nuki::DoorSensorState::DoorOpened ||
_keyTurnerState.doorSensorState == Nuki::DoorSensorState::Calibrating;
diff --git a/PreferencesKeys.h b/PreferencesKeys.h
index 1fa1487..3b7030b 100644
--- a/PreferencesKeys.h
+++ b/PreferencesKeys.h
@@ -21,6 +21,9 @@
#define preference_check_updates "checkupdates"
#define preference_lock_max_keypad_code_count "maxkpad"
#define preference_opener_max_keypad_code_count "opmaxkpad"
+#define preference_lock_force_keypad "forcekpad"
+#define preference_opener_force_keypad "opforcekpad"
+#define preference_lock_force_doorsensor "forcedrsnsr"
#define preference_mqtt_ca "mqttca"
#define preference_mqtt_crt "mqttcrt"
#define preference_mqtt_key "mqttkey"
@@ -72,8 +75,8 @@ private:
{
preference_started_before, preference_config_version, preference_device_id_lock, preference_device_id_opener, preference_nuki_id_lock, preference_nuki_id_opener, preference_mqtt_broker, preference_mqtt_broker_port, preference_mqtt_user, preference_mqtt_password, preference_mqtt_log_enabled, preference_check_updates,
preference_lock_enabled, preference_mqtt_lock_path, preference_opener_enabled, preference_opener_continuous_mode, preference_mqtt_opener_path,
- preference_lock_max_keypad_code_count, preference_opener_max_keypad_code_count, preference_mqtt_ca,
- preference_mqtt_crt, preference_mqtt_key, preference_mqtt_hass_discovery, preference_mqtt_hass_cu_url,
+ preference_lock_max_keypad_code_count, preference_opener_max_keypad_code_count, preference_lock_force_keypad, preference_opener_force_keypad,
+ preference_lock_force_doorsensor, preference_mqtt_ca, preference_mqtt_crt, preference_mqtt_key, preference_mqtt_hass_discovery, preference_mqtt_hass_cu_url,
preference_ip_dhcp_enabled, preference_ip_address, preference_ip_subnet, preference_ip_gateway, preference_ip_dns_server,
preference_network_hardware, preference_network_wifi_fallback_disabled, preference_rssi_publish_interval,
preference_hostname, preference_network_timeout, preference_restart_on_disconnect,
@@ -95,7 +98,7 @@ private:
{
preference_started_before, preference_mqtt_log_enabled, preference_check_updates, preference_lock_enabled, preference_opener_enabled, preference_opener_continuous_mode,
preference_restart_on_disconnect, preference_keypad_control_enabled, preference_admin_enabled, preference_keypad_info_enabled,
- preference_register_as_app, preference_ip_dhcp_enabled,
+ preference_lock_force_keypad, preference_opener_force_keypad, preference_lock_force_doorsensor, preference_register_as_app, preference_ip_dhcp_enabled,
preference_publish_authdata, preference_has_mac_saved, preference_publish_debug_info, preference_network_wifi_fallback_disabled
};
diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp
index ea43d99..4754561 100644
--- a/WebCfgServer.cpp
+++ b/WebCfgServer.cpp
@@ -635,7 +635,7 @@ bool WebCfgServer::processArgs(String& message)
_preferences->putString(preference_cred_password, "");
configChanged = true;
}
-
+
if(aclLvlChanged)
{
_preferences->putBytes(preference_acl, (byte*)(&aclPrefs), sizeof(aclPrefs));
@@ -939,7 +939,7 @@ void WebCfgServer::buildAccLvlHtml(String &response)
response.concat("
Nuki General Access Control
");
response.concat("| Setting | Enabled |
");
printCheckBox(response, "ACLCNF", "Change Nuki configuration", _preferences->getBool(preference_admin_enabled));
- if((_nuki != nullptr && _nuki->hasKeypad()) || (_nukiOpener != nullptr && _nukiOpener->hasKeypad()))
+ if((_nuki != nullptr && (_preferences->getString(preference_lock_force_keypad) || _nuki->hasKeypad())) || (_nukiOpener != nullptr && (_preferences->getString(preference_opener_force_keypad) || _nukiOpener->hasKeypad())))
{
printCheckBox(response, "KPPUB", "Publish keypad codes information", _preferences->getBool(preference_keypad_info_enabled));
printCheckBox(response, "KPENA", "Add, modify and delete keypad codes", _preferences->getBool(preference_keypad_control_enabled));
@@ -993,11 +993,14 @@ void WebCfgServer::buildNukiConfigHtml(String &response)
if(_preferences->getBool(preference_lock_enabled))
{
printInputField(response, "MQTTPATH", "MQTT Nuki Smartlock Path", _preferences->getString(preference_mqtt_lock_path).c_str(), 180);
+ printCheckBox(response, "LCKFORCEKPAD", "Force Lock Keypad availability", _preferences->getBool(preference_lock_force_keypad));
+ printCheckBox(response, "LCKFORCEDRSNSR", "Force Lock Door Sensor availability", _preferences->getBool(preference_lock_force_doorsensor));
}
printCheckBox(response, "OPENA", "Nuki Opener enabled", _preferences->getBool(preference_opener_enabled));
if(_preferences->getBool(preference_opener_enabled))
{
printInputField(response, "MQTTOPPATH", "MQTT Nuki Opener Path", _preferences->getString(preference_mqtt_opener_path).c_str(), 180);
+ printCheckBox(response, "OPFORCEKPAD", "Force Opener Keypad availability", _preferences->getBool(preference_opener_force_keypad));
}
response.concat("
");
@@ -1007,7 +1010,7 @@ void WebCfgServer::buildNukiConfigHtml(String &response)
printInputField(response, "LSTINT", "Query interval lock state (seconds)", _preferences->getInt(preference_query_interval_lockstate), 10);
printInputField(response, "CFGINT", "Query interval configuration (seconds)", _preferences->getInt(preference_query_interval_configuration), 10);
printInputField(response, "BATINT", "Query interval battery (seconds)", _preferences->getInt(preference_query_interval_battery), 10);
- if((_nuki != nullptr && _nuki->hasKeypad()) || (_nukiOpener != nullptr && _nukiOpener->hasKeypad()))
+ if((_nuki != nullptr && (_preferences->getString(preference_lock_force_keypad) || _nuki->hasKeypad())) || (_nukiOpener != nullptr && (_preferences->getString(preference_opener_force_keypad) || _nukiOpener->hasKeypad())))
{
printInputField(response, "KPINT", "Query interval keypad (seconds)", _preferences->getInt(preference_query_interval_keypad), 10);
}
@@ -1089,6 +1092,9 @@ void WebCfgServer::buildInfoHtml(String &response)
response.concat("MQTT connected: ");
response.concat(_network->mqttConnectionState() > 0 ? "Yes\n" : "No\n");
+ uint32_t aclPrefs[17];
+ _preferences->getBytes(preference_acl, &aclPrefs, sizeof(aclPrefs));
+
if(_nuki != nullptr)
{
response.concat("Lock firmware version: ");
@@ -1103,7 +1109,26 @@ void WebCfgServer::buildInfoHtml(String &response)
response.concat(_nuki->hasDoorSensor() ? "Yes\n" : "No\n");
response.concat("Lock has keypad: ");
response.concat(_nuki->hasKeypad() ? "Yes\n" : "No\n");
+ response.concat("Lock ACL (Lock): ");
+ response.concat((int)aclPrefs[0] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Lock ACL (Unlock): ");
+ response.concat((int)aclPrefs[1] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Lock ACL (Unlatch): ");
+ response.concat((int)aclPrefs[2] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Lock ACL (Lock N Go): ");
+ response.concat((int)aclPrefs[3] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Lock ACL (Lock N Go Unlatch): ");
+ response.concat((int)aclPrefs[4] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Lock ACL (Full Lock): ");
+ response.concat((int)aclPrefs[5] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Lock ACL (Fob Action 1): ");
+ response.concat((int)aclPrefs[6] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Lock ACL (Fob Action 2): ");
+ response.concat((int)aclPrefs[7] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Lock ACL (Fob Action 3): ");
+ response.concat((int)aclPrefs[8] ? "Allowed\n" : "Disallowed\n");
}
+
if(_nukiOpener != nullptr)
{
response.concat("Opener firmware version: ");
@@ -1115,6 +1140,22 @@ void WebCfgServer::buildInfoHtml(String &response)
response.concat(_nukiOpener->isPaired() ? _nukiOpener->isPinSet() ? "Yes\n" : "No\n" : "-\n");
response.concat("Opener has keypad: ");
response.concat(_nukiOpener->hasKeypad() ? "Yes\n" : "No\n");
+ response.concat("Opener ACL (Activate Ring-to-Open): ");
+ response.concat((int)aclPrefs[9] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Opener ACL (Deactivate Ring-to-Open): ");
+ response.concat((int)aclPrefs[10] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Opener ACL (Electric Strike Actuation): ");
+ response.concat((int)aclPrefs[11] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Opener ACL (Activate Continuous Mode): ");
+ response.concat((int)aclPrefs[12] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Opener ACL (Deactivate Continuous Mode): ");
+ response.concat((int)aclPrefs[13] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Opener ACL (Fob Action 1): ");
+ response.concat((int)aclPrefs[14] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Opener ACL (Fob Action 2): ");
+ response.concat((int)aclPrefs[15] ? "Allowed\n" : "Disallowed\n");
+ response.concat("Opener ACL (Fob Action 3): ");
+ response.concat((int)aclPrefs[16] ? "Allowed\n" : "Disallowed\n");
}
response.concat("Network device: ");