From 003b88828fb2552073d357dad288852c84a59225 Mon Sep 17 00:00:00 2001 From: iranl Date: Thu, 16 May 2024 22:37:04 +0200 Subject: [PATCH 1/3] Make the code optional when updating keypad using JSON --- README.md | 4 ++-- src/NukiOpenerWrapper.cpp | 14 ++++++++++++-- src/NukiOpenerWrapper.h | 1 + src/NukiWrapper.cpp | 14 ++++++++++++-- src/NukiWrapper.h | 1 + 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index edd44e0..0320786 100644 --- a/README.md +++ b/README.md @@ -446,7 +446,7 @@ To change Nuki Lock/Opener keypad settings set the `keypad/actionJson` topic to |------------------|----------|----------|----------|------------------------------------------------------------------------------------------------------------------|----------------------------------------| | action | Required | Required | Required | The action to execute | "delete", "add", "update" | | codeId | Required | Not used | Required | The code ID of the existing code to delete or update | Integer | -| code | Not used | Required | Required | The code to create or update | 6-digit Integer without zero's, can't start with "12"| +| code | Not used | Required | Optional | The code to create or update | 6-digit Integer without zero's, can't start with "12"| | enabled | Not used | Not used | Optional | Enable or disable the code, always enabled on add, disabled if not set on update | 1 = enabled, 0 = disabled | | name | Not used | Required | Required | The name of the code to create or update | String, max 20 chars | | timeLimited | Not used | Optional | Optional | If this authorization is restricted to access only at certain times, disabled if not set (requires enabled = 1) | 1 = enabled, 0 = disabled | @@ -459,7 +459,7 @@ To change Nuki Lock/Opener keypad settings set the `keypad/actionJson` topic to Examples: - Delete: `{ "action": "delete", "codeId": "1234" }` - Add: `{ "action": "add", "code": "589472", "name": "Test", "timeLimited": "1", "allowedFrom": "2024-04-12 10:00:00", "allowedUntil": "2034-04-12 10:00:00", "allowedWeekdays": [ "wed", "thu", "fri" ], "allowedFromTime": "08:00", "allowedUntilTime": "16:00" }` -- Update: `{ "action": "update", "codeId": "1234", "code": "589472", "enabled": "1", "name": "Test", "timeLimited": "1", "allowedFrom": "2024-04-12 10:00:00", "allowedUntil": "2034-04-12 10:00:00", "allowedWeekdays": [ "mon", "tue", "sat", "sun" ], "allowedFromTime": "08:00", "allowedUntilTime": "16:00" }` +- Update: `{ "action": "update", "codeId": "1234", "enabled": "1", "name": "Test", "timeLimited": "1", "allowedFrom": "2024-04-12 10:00:00", "allowedUntil": "2034-04-12 10:00:00", "allowedWeekdays": [ "mon", "tue", "sat", "sun" ], "allowedFromTime": "08:00", "allowedUntilTime": "16:00" }` ### Result of attempted keypad code changes diff --git a/src/NukiOpenerWrapper.cpp b/src/NukiOpenerWrapper.cpp index daee4b4..bfff6e8 100644 --- a/src/NukiOpenerWrapper.cpp +++ b/src/NukiOpenerWrapper.cpp @@ -525,9 +525,12 @@ void NukiOpenerWrapper::updateKeypad() _keypadCodeIds.clear(); _keypadCodeIds.reserve(entries.size()); + _keypadCodes.clear(); + _keypadCodes.reserve(entries.size()); for(const auto& entry : entries) { _keypadCodeIds.push_back(entry.codeId); + _keypadCodes.push_back(entry.code); } } @@ -1504,7 +1507,7 @@ void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value) return; } } - else + else if (strcmp(action, "update") != 0) { _network->publishKeypadJsonCommandResult("noCodeSet"); return; @@ -1685,7 +1688,14 @@ void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value) entry.codeId = codeId; size_t nameLen = strlen(name); memcpy(&entry.name, name, nameLen > 20 ? 20 : nameLen); - entry.code = code; + + if(code) entry.code = code; + else + { + auto it = std::find(_keypadCodeIds.begin(), _keypadCodeIds.end(), codeId); + entry.code = _keypadCodes[(it - _keypadCodeIds.begin())]; + } + entry.enabled = enabled == 0 ? 0 : 1; entry.timeLimited = timeLimited == 1 ? 1 : 0; diff --git a/src/NukiOpenerWrapper.h b/src/NukiOpenerWrapper.h index 6414396..fb4fd95 100644 --- a/src/NukiOpenerWrapper.h +++ b/src/NukiOpenerWrapper.h @@ -105,6 +105,7 @@ private: int _retryLockstateCount = 0; unsigned long _nextRetryTs = 0; std::vector _keypadCodeIds; + std::vector _keypadCodes; std::vector _timeControlIds; NukiOpener::OpenerState _lastKeyTurnerState; diff --git a/src/NukiWrapper.cpp b/src/NukiWrapper.cpp index 1b28b3e..6412a11 100644 --- a/src/NukiWrapper.cpp +++ b/src/NukiWrapper.cpp @@ -506,9 +506,12 @@ void NukiWrapper::updateKeypad() _keypadCodeIds.clear(); _keypadCodeIds.reserve(entries.size()); + _keypadCodes.clear(); + _keypadCodes.reserve(entries.size()); for(const auto& entry : entries) { _keypadCodeIds.push_back(entry.codeId); + _keypadCodes.push_back(entry.code); } } @@ -1490,7 +1493,7 @@ void NukiWrapper::onKeypadJsonCommandReceived(const char *value) return; } } - else + else if (strcmp(action, "update") != 0) { _network->publishKeypadJsonCommandResult("noCodeSet"); return; @@ -1671,7 +1674,14 @@ void NukiWrapper::onKeypadJsonCommandReceived(const char *value) entry.codeId = codeId; size_t nameLen = strlen(name); memcpy(&entry.name, name, nameLen > 20 ? 20 : nameLen); - entry.code = code; + + if(code) entry.code = code; + else + { + auto it = std::find(_keypadCodeIds.begin(), _keypadCodeIds.end(), codeId); + entry.code = _keypadCodes[(it - _keypadCodeIds.begin())]; + } + entry.enabled = enabled == 0 ? 0 : 1; entry.timeLimited = timeLimited == 1 ? 1 : 0; diff --git a/src/NukiWrapper.h b/src/NukiWrapper.h index f5d0291..9a4663e 100644 --- a/src/NukiWrapper.h +++ b/src/NukiWrapper.h @@ -94,6 +94,7 @@ private: bool _publishAuthData = false; bool _clearAuthData = false; std::vector _keypadCodeIds; + std::vector _keypadCodes; std::vector _timeControlIds; NukiLock::KeyTurnerState _lastKeyTurnerState; From 5d5d8b15be70c3411b300b45162e98d39223fa6b Mon Sep 17 00:00:00 2001 From: iranl Date: Sun, 19 May 2024 21:40:41 +0200 Subject: [PATCH 2/3] Update README.md --- README.md | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 0e441b0..10b6667 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ It exposes the lock state (and much more) through MQTT and allows executing comm ***Nuki Hub does not integrate with the Nuki mobile app, it can't register itself as a bridge in the official Nuki mobile app.*** -Feel free to join us on Discord: https://discord.gg/feB9FnMY +Feel free to join us on Discord: https://discord.gg/24HxpGBJ ## Supported devices @@ -156,16 +156,16 @@ In a browser navigate to the IP address assigned to the ESP32. #### Nuki General Access Control - Publish keypad codes information (Only available when a Keypad is detected): Enable to publish information about keypad codes through MQTT, see the "[Keypad control](#keypad-control-optional)" section of this README - Add, modify and delete keypad codes (Only available when a Keypad is detected): Enable to allow configuration of keypad codes through MQTT, see the "[Keypad control](#keypad-control-optional)" section of this README -- Publish time control information: Enable to publish information about time control entries through MQTT, see the "Time control" section of this README -- Add, modify and delete time control entries: Enable to allow configuration of time control entries through MQTT, see the "Time control" section of this README -- Publish auth data: Enable to publish authorization data to the MQTT topic lock/log. Requires the Nuki security code / PIN to be set, see "Nuki Lock PIN / Nuki Opener PIN" below. +- Publish time control information: Enable to publish information about time control entries through MQTT, see the "[Time Control](#time-control)" section of this README +- Add, modify and delete time control entries: Enable to allow configuration of time control entries through MQTT, see the "[Time Control](#time-control)" section of this README +- Publish auth data: Enable to publish authorization data to the MQTT topic lock/log. Requires the Nuki security code / PIN to be set, see "[Nuki Lock PIN / Nuki Opener PIN](#nuki-lock-pin--nuki-opener-pin)" below. #### Nuki Lock/Opener Access Control - Enable or disable executing each available lock action for the Nuki Lock and Nuki Opener through MQTT. Note: GPIO control is not restricted through this setting. #### Nuki Lock/Opener Config Control - Enable or disable changing each available configuration setting for the Nuki Lock and Nuki Opener through MQTT. -- NOTE: Changing configuration settings requires the Nuki security code / PIN to be set, see "Nuki Lock PIN / Nuki Opener PIN" below. +- NOTE: Changing configuration settings requires the Nuki security code / PIN to be set, see "[Nuki Lock PIN / Nuki Opener PIN](#nuki-lock-pin--nuki-opener-pin)" below. ### Credentials @@ -184,7 +184,7 @@ In a browser navigate to the IP address assigned to the ESP32. ### GPIO Configuration -- Gpio [2-33]: See the "GPIO lock control" section of this README. +- Gpio [2-33]: See the "[GPIO lock control](#gpio-lock-control-optional)" section of this README. ## Exposed MQTT Topics @@ -268,7 +268,7 @@ In a browser navigate to the IP address assigned to the ESP32. ### Time Control -- See the "Time control" section of this README. +- See the "[Time Control](#time-control)" section of this README. ### Info @@ -415,8 +415,25 @@ To enable SSL encryption, supply the necessary information in the MQTT Configura The following configurations are supported:
CA, CERT and KEY are empty -> No encryption
CA is filled but CERT and KEY are empty -> Encrypted MQTT
-CA, CERT and KEY are filled -> Encrypted MQTT with client vaildation +CA, CERT and KEY are filled -> Encrypted MQTT with client vaildation
+
+Example certificate creation for your MQTT server: +```console +# make a ca key +openssl genpkey -algorithm RSA -out ca.key +# make a CA cert +openssl req -new -x509 -days 3650 -key ca.key -out ca.crt -subj "/C=US/ST=YourState/L=YourCity/O=YourOrganization/OU=YourUnit/CN=YourCAName" + +# make a server key +openssl genpkey -algorithm RSA -out server.key + +# Make a sign request, MAKE SURE THE CN MATCHES YOUR MQTT SERVERNAME +openssl req -new -key server.key -out server.csr -subj "/C=US/ST=YourState/L=YourCity/O=YourOrganization/OU=YourUnit/CN=homeserver.local" + +# sign it + openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 +``` ## Home Assistant Discovery (optional) This software supports [MQTT Discovery](https://www.home-assistant.io/docs/mqtt/discovery/) for integrating Nuki Hub with Home Assistant.
From 6fc21ae43b48924905247805c0e367042ae0d92f Mon Sep 17 00:00:00 2001 From: iranl Date: Sun, 19 May 2024 19:34:37 +0200 Subject: [PATCH 3/3] Fix AuthName --- README.md | 4 +-- platformio.ini | 55 +++++++++++++++++++++++++------------ src/NetworkLock.cpp | 36 ++++++++++++++---------- src/NetworkOpener.cpp | 33 +++++++++++++--------- src/NukiOpenerWrapper.cpp | 58 +++++++++++++++++++++++---------------- src/NukiOpenerWrapper.h | 1 + src/NukiWrapper.cpp | 58 +++++++++++++++++++++++---------------- src/NukiWrapper.h | 1 + src/WebCfgServer.cpp | 8 +++--- 9 files changed, 155 insertions(+), 99 deletions(-) diff --git a/README.md b/README.md index 0e441b0..c0aa979 100644 --- a/README.md +++ b/README.md @@ -390,7 +390,7 @@ Example usage for changing multiple settings at once:
The result of the last configuration change action will be published to the `configuration/commandResult` MQTT topic as JSON data.

The JSON data will include a node called "general" and a node for every setting that Nuki Hub detected in the action.
-Possible values for the "general" node are "noPinSet", "invalidJson", "invalidConfig", "success" and "noChange".
+Possible values for the "general" node are "noValidPinSet", "invalidJson", "invalidConfig", "success" and "noChange".
Possible values for the node per setting are "unchanged", "noValueSet", "invalidValue", "valueTooLong", "accessDenied", "success", "failed", "timeOut", "working", "notPaired", "error" and "undefined"

Example: @@ -465,7 +465,7 @@ Examples: ### Result of attempted keypad code changes The result of the last configuration change action will be published to the `configuration/commandResultJson` MQTT topic.
-Possible values are "noPinSet", "keypadControlDisabled", "keypadNotAvailable", "keypadDisabled", "invalidConfig", "invalidJson", "noActionSet", "invalidAction", "noExistingCodeIdSet", "noNameSet", "noValidCodeSet", "noCodeSet", "invalidAllowedFrom", "invalidAllowedUntil", "invalidAllowedFromTime", "invalidAllowedUntilTime", "success", "failed", "timeOut", "working", "notPaired", "error" and "undefined".
+Possible values are "noValidPinSet", "keypadControlDisabled", "keypadNotAvailable", "keypadDisabled", "invalidConfig", "invalidJson", "noActionSet", "invalidAction", "noExistingCodeIdSet", "noNameSet", "noValidCodeSet", "noCodeSet", "invalidAllowedFrom", "invalidAllowedUntil", "invalidAllowedFromTime", "invalidAllowedUntilTime", "success", "failed", "timeOut", "working", "notPaired", "error" and "undefined".
## Keypad control (alternative, optional) diff --git a/platformio.ini b/platformio.ini index dd721bf..2fc6733 100644 --- a/platformio.ini +++ b/platformio.ini @@ -24,14 +24,6 @@ build_flags = -DESP_PLATFORM -DESP32 -DARDUINO_ARCH_ESP32 - -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE - -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 -; -DDEBUG_SENSE_NUKI -; -DDEBUG_NUKI_COMMAND -; -DDEBUG_NUKI_CONNECT -; -DDEBUG_NUKI_COMMUNICATION -; -DDEBUG_NUKI_HEX_DATA -; -DDEBUG_NUKI_READABLE_DATA lib_deps = monitor_speed = 115200 @@ -41,9 +33,17 @@ monitor_filters = [env:esp32dev] board = esp32dev +build_flags = + ${env.build_flags} + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 [env:esp32-c3] board = esp32-c3-devkitc-02 +build_flags = + ${env.build_flags} + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 [env:esp32solo1] platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32-2023.10.03.zip @@ -51,51 +51,70 @@ board = esp32-solo1 build_flags = ${env.build_flags} -DFRAMEWORK_ARDUINO_SOLO1 + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 [env:esp32-s3] board = esp32-s3-devkitc-1 - -[env:esp32dev_dbg] -extends = env:esp32dev build_flags = ${env.build_flags} + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_NONE + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=0 + +[env:esp32dev_dbg] +board = esp32dev +build_flags = + ${env.build_flags} + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=4 + -DDEBUG_NUKIHUB -DDEBUG_SENSE_NUKI -DDEBUG_NUKI_COMMAND -DDEBUG_NUKI_CONNECT -DDEBUG_NUKI_COMMUNICATION - -DDEBUG_NUKI_HEX_DATA + ;-DDEBUG_NUKI_HEX_DATA -DDEBUG_NUKI_READABLE_DATA [env:esp32-s3_dbg] -extends = env:esp32-s3 +board = esp32-s3-devkitc-1 build_flags = ${env.build_flags} + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=4 + -DDEBUG_NUKIHUB -DDEBUG_SENSE_NUKI -DDEBUG_NUKI_COMMAND -DDEBUG_NUKI_CONNECT -DDEBUG_NUKI_COMMUNICATION - -DDEBUG_NUKI_HEX_DATA + ;-DDEBUG_NUKI_HEX_DATA -DDEBUG_NUKI_READABLE_DATA [env:esp32-c3_dbg] -extends = env:esp32-c3 +board = esp32-c3-devkitc-02 build_flags = ${env.build_flags} + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=4 + -DDEBUG_NUKIHUB -DDEBUG_SENSE_NUKI -DDEBUG_NUKI_COMMAND -DDEBUG_NUKI_CONNECT -DDEBUG_NUKI_COMMUNICATION - -DDEBUG_NUKI_HEX_DATA + ;-DDEBUG_NUKI_HEX_DATA -DDEBUG_NUKI_READABLE_DATA [env:esp32solo1_dbg] -extends = env:esp32solo1 +platform = https://github.com/tasmota/platform-espressif32/releases/download/2023.10.03/platform-espressif32-2023.10.03.zip +board = esp32-solo1 build_flags = ${env.build_flags} -DFRAMEWORK_ARDUINO_SOLO1 + -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG + -DCONFIG_NIMBLE_CPP_LOG_LEVEL=4 + -DDEBUG_NUKIHUB -DDEBUG_SENSE_NUKI -DDEBUG_NUKI_COMMAND -DDEBUG_NUKI_CONNECT -DDEBUG_NUKI_COMMUNICATION - -DDEBUG_NUKI_HEX_DATA + ;-DDEBUG_NUKI_HEX_DATA -DDEBUG_NUKI_READABLE_DATA \ No newline at end of file diff --git a/src/NetworkLock.cpp b/src/NetworkLock.cpp index 95e7397..f685e7e 100644 --- a/src/NetworkLock.cpp +++ b/src/NetworkLock.cpp @@ -199,7 +199,7 @@ void NetworkLock::onMqttDataReceived(const char* topic, byte* payload, const uns if(comparePrefixedPath(topic, mqtt_topic_config_action)) { if(strcmp(value, "") == 0 || strcmp(value, "--") == 0) return; - + if(_configUpdateReceivedCallback != NULL) { _configUpdateReceivedCallback(value); @@ -265,7 +265,7 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne } json["trigger"] = str; - + char curTime[20]; sprintf(curTime, "%04d-%02d-%02d %02d:%02d:%02d", keyTurnerState.currentTimeYear, keyTurnerState.currentTimeMonth, keyTurnerState.currentTimeDay, keyTurnerState.currentTimeHour, keyTurnerState.currentTimeMinute, keyTurnerState.currentTimeSecond); json["currentTime"] = curTime; @@ -375,11 +375,8 @@ void NetworkLock::publishState(NukiLock::LockState lockState) void NetworkLock::publishAuthorizationInfo(const std::list& logEntries) { char str[50]; - - _authId = 0; - memset(_authName, 0, sizeof(_authName)); - _authName[0] = '\0'; - _authFound = false; + char authName[33]; + bool authFound = false; JsonDocument json; @@ -391,20 +388,31 @@ void NetworkLock::publishAuthorizationInfo(const std::list& break; } --i; - if((log.loggingType == NukiLock::LoggingType::LockAction || log.loggingType == NukiLock::LoggingType::KeypadAction) && ! _authFound) + + memset(authName, 0, sizeof(authName)); + authName[0] = '\0'; + + if((log.loggingType == NukiLock::LoggingType::LockAction || log.loggingType == NukiLock::LoggingType::KeypadAction)) { - _authFound = true; - _authId = log.authId; int sizeName = sizeof(log.name); - memcpy(_authName, log.name, sizeName); - if(_authName[sizeName - 1] != '\0') _authName[sizeName] = '\0'; + memcpy(authName, log.name, sizeName); + if(authName[sizeName - 1] != '\0') authName[sizeName] = '\0'; + + if(!authFound) + { + authFound = true; + _authFound = true; + _authId = log.authId; + memset(_authName, 0, sizeof(_authName)); + memcpy(_authName, authName, sizeof(authName)); + } } auto entry = json.add(); entry["index"] = log.index; entry["authorizationId"] = log.authId; - entry["authorizationName"] = _authName; + entry["authorizationName"] = authName; entry["timeYear"] = log.timeStampYear; entry["timeMonth"] = log.timeStampMonth; entry["timeDay"] = log.timeStampDay; @@ -470,7 +478,7 @@ void NetworkLock::publishAuthorizationInfo(const std::list& serializeJson(json, _buffer, _bufferSize); publishString(mqtt_topic_lock_log, _buffer); - if(_authFound) + if(authFound) { publishUInt(mqtt_topic_lock_auth_id, _authId); publishString(mqtt_topic_lock_auth_name, _authName); diff --git a/src/NetworkOpener.cpp b/src/NetworkOpener.cpp index 1c9277e..574d646 100644 --- a/src/NetworkOpener.cpp +++ b/src/NetworkOpener.cpp @@ -266,7 +266,7 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn } json["trigger"] = str; - + json["ringToOpenTimer"] = keyTurnerState.ringToOpenTimer; char curTime[20]; sprintf(curTime, "%04d-%02d-%02d %02d:%02d:%02d", keyTurnerState.currentTimeYear, keyTurnerState.currentTimeMonth, keyTurnerState.currentTimeDay, keyTurnerState.currentTimeHour, keyTurnerState.currentTimeMinute, keyTurnerState.currentTimeSecond); @@ -373,11 +373,8 @@ void NetworkOpener::publishState(NukiOpener::OpenerState lockState) void NetworkOpener::publishAuthorizationInfo(const std::list& logEntries) { char str[50]; - - _authId = 0; - memset(_authName, 0, sizeof(_authName)); - _authName[0] = '\0'; - _authFound = false; + char authName[33]; + bool authFound = false; JsonDocument json; @@ -390,13 +387,23 @@ void NetworkOpener::publishAuthorizationInfo(const std::list(); @@ -494,7 +501,7 @@ void NetworkOpener::publishAuthorizationInfo(const std::listgetInt(preference_opener_pin_status, 4) == 1; +} + void NukiOpenerWrapper::setPin(const uint16_t pin) { _nukiOpener.saveSecurityPincode(pin); @@ -373,15 +378,18 @@ void NukiOpenerWrapper::updateKeyTurnerState() if(_publishAuthData) { + Log->println(F("Publishing auth data")); updateAuthData(); + Log->println(F("Done publishing auth data")); } postponeBleWatchdog(); + Log->println(F("Done querying lock state")); } void NukiOpenerWrapper::updateBatteryState() { - Log->print("Querying opener battery state: "); + Log->print(F("Querying opener battery state: ")); Nuki::CmdResult result = _nukiOpener.requestBatteryReport(&_batteryReport); printCommandResult(result); if(result == Nuki::CmdResult::Success) @@ -389,6 +397,7 @@ void NukiOpenerWrapper::updateBatteryState() _network->publishBatteryReport(_batteryReport); } postponeBleWatchdog(); + Log->println(F("Done querying lock battery state")); } void NukiOpenerWrapper::updateConfig() @@ -470,27 +479,28 @@ void NukiOpenerWrapper::updateConfig() void NukiOpenerWrapper::updateAuthData() { - if(!isPinSet()) return; + if(!isPinValid()) + { + Log->println(F("No valid PIN set")); + return; + } - Nuki::CmdResult result = _nukiOpener.retrieveLogEntries(0, 0, 0, true); + Nuki::CmdResult result = _nukiOpener.retrieveLogEntries(0, 5, 1, false); + Log->print(F("Retrieve log entries: ")); + Log->println(result); if(result != Nuki::CmdResult::Success) { return; } + delay(100); - uint16_t count = _nukiOpener.getLogEntryCount(); - - result = _nukiOpener.retrieveLogEntries(0, count < 5 ? count : 5, 1, false); - if(result != Nuki::CmdResult::Success) - { - return; - } - delay(1000); - std::list log; _nukiOpener.getLogEntries(&log); + Log->print(F("Log size: ")); + Log->println(log.size()); + if(log.size() > 0) { _network->publishAuthorizationInfo(log); @@ -780,9 +790,9 @@ void NukiOpenerWrapper::onConfigUpdateReceived(const char *value) return; } - if(!isPinSet()) + if(!isPinValid()) { - jsonResult["general"] = "noPinSet"; + jsonResult["general"] = "noValidPinSet"; serializeJson(jsonResult, _resbuf, sizeof(_resbuf)); _network->publishConfigCommandResult(_resbuf); return; @@ -1412,9 +1422,9 @@ void NukiOpenerWrapper::onKeypadCommandReceived(const char *command, const uint void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value) { - if(!isPinSet()) + if(!isPinValid()) { - _network->publishKeypadJsonCommandResult("noPinSet"); + _network->publishKeypadJsonCommandResult("noValidPinSet"); return; } @@ -1478,7 +1488,7 @@ void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value) if(idExists) { result = _nukiOpener.deleteKeypadEntry(codeId); - Log->print("Delete keypad code: "); + Log->print(F("Delete keypad code: ")); Log->println((int)result); } else @@ -1664,7 +1674,7 @@ void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value) } result = _nukiOpener.addKeypadEntry(entry); - Log->print("Add keypad code: "); + Log->print(F("Add keypad code: ")); Log->println((int)result); } else if (strcmp(action, "update") == 0) @@ -1725,7 +1735,7 @@ void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value) } result = _nukiOpener.updateKeypadEntry(entry); - Log->print("Update keypad code: "); + Log->print(F("Update keypad code: ")); Log->println((int)result); } } @@ -1760,9 +1770,9 @@ void NukiOpenerWrapper::onTimeControlCommandReceived(const char *value) return; } - if(!isPinSet()) + if(!isPinValid()) { - _network->publishTimeControlCommandResult("noPinSet"); + _network->publishTimeControlCommandResult("noValidPinSet"); return; } @@ -1815,7 +1825,7 @@ void NukiOpenerWrapper::onTimeControlCommandReceived(const char *value) if(idExists) { result = _nukiOpener.removeTimeControlEntry(entryId); - Log->print("Delete time control "); + Log->print(F("Delete time control ")); Log->println((int)result); } else @@ -1880,7 +1890,7 @@ void NukiOpenerWrapper::onTimeControlCommandReceived(const char *value) entry.lockAction = timeControlLockAction; result = _nukiOpener.addTimeControlEntry(entry); - Log->print("Add time control: "); + Log->print(F("Add time control: ")); Log->println((int)result); } else if (strcmp(action, "update") == 0) @@ -1906,7 +1916,7 @@ void NukiOpenerWrapper::onTimeControlCommandReceived(const char *value) entry.lockAction = timeControlLockAction; result = _nukiOpener.updateTimeControlEntry(entry); - Log->print("Update time control: "); + Log->print(F("Update time control: ")); Log->println((int)result); } } diff --git a/src/NukiOpenerWrapper.h b/src/NukiOpenerWrapper.h index 6414396..1f3f22e 100644 --- a/src/NukiOpenerWrapper.h +++ b/src/NukiOpenerWrapper.h @@ -25,6 +25,7 @@ public: void deactivateCM(); bool isPinSet(); + bool isPinValid(); void setPin(const uint16_t pin); void unpair(); diff --git a/src/NukiWrapper.cpp b/src/NukiWrapper.cpp index 119cb15..a278f3f 100644 --- a/src/NukiWrapper.cpp +++ b/src/NukiWrapper.cpp @@ -309,6 +309,11 @@ bool NukiWrapper::isPinSet() return _nukiLock.getSecurityPincode() != 0; } +bool NukiWrapper::isPinValid() +{ + return _preferences->getInt(preference_lock_pin_status, 4) == 1; +} + void NukiWrapper::setPin(const uint16_t pin) { _nukiLock.saveSecurityPincode(pin); @@ -347,7 +352,9 @@ void NukiWrapper::updateKeyTurnerState() if(_publishAuthData) { + Log->println(F("Publishing auth data")); updateAuthData(); + Log->println(F("Done publishing auth data")); } _network->publishKeyTurnerState(_keyTurnerState, _lastKeyTurnerState); @@ -358,11 +365,12 @@ void NukiWrapper::updateKeyTurnerState() Log->println(lockStateStr); postponeBleWatchdog(); + Log->println(F("Done querying lock state")); } void NukiWrapper::updateBatteryState() { - Log->print("Querying lock battery state: "); + Log->print(F("Querying lock battery state: ")); Nuki::CmdResult result = _nukiLock.requestBatteryReport(&_batteryReport); printCommandResult(result); if(result == Nuki::CmdResult::Success) @@ -370,6 +378,7 @@ void NukiWrapper::updateBatteryState() _network->publishBatteryReport(_batteryReport); } postponeBleWatchdog(); + Log->println(F("Done querying lock battery state")); } void NukiWrapper::updateConfig() @@ -451,27 +460,28 @@ void NukiWrapper::updateConfig() void NukiWrapper::updateAuthData() { - if(!isPinSet()) return; + if(!isPinValid()) + { + Log->println(F("No valid PIN set")); + return; + } - Nuki::CmdResult result = _nukiLock.retrieveLogEntries(0, 0, 0, true); + Nuki::CmdResult result = _nukiLock.retrieveLogEntries(0, 5, 1, false); + Log->print(F("Retrieve log entries: ")); + Log->println(result); if(result != Nuki::CmdResult::Success) { return; } + delay(100); - uint16_t count = _nukiLock.getLogEntryCount(); - - result = _nukiLock.retrieveLogEntries(0, count < 5 ? count : 5, 1, false); - if(result != Nuki::CmdResult::Success) - { - return; - } - delay(1000); - std::list log; _nukiLock.getLogEntries(&log); + Log->print(F("Log size: ")); + Log->println(log.size()); + if(log.size() > 0) { _network->publishAuthorizationInfo(log); @@ -716,9 +726,9 @@ void NukiWrapper::onConfigUpdateReceived(const char *value) return; } - if(!isPinSet()) + if(!isPinValid()) { - jsonResult["general"] = "noPinSet"; + jsonResult["general"] = "noValidPinSet"; serializeJson(jsonResult, _resbuf, sizeof(_resbuf)); _network->publishConfigCommandResult(_resbuf); return; @@ -1398,9 +1408,9 @@ void NukiWrapper::onKeypadCommandReceived(const char *command, const uint &id, c void NukiWrapper::onKeypadJsonCommandReceived(const char *value) { - if(!isPinSet()) + if(!isPinValid()) { - _network->publishKeypadJsonCommandResult("noPinSet"); + _network->publishKeypadJsonCommandResult("noValidPinSet"); return; } @@ -1464,7 +1474,7 @@ void NukiWrapper::onKeypadJsonCommandReceived(const char *value) if(idExists) { result = _nukiLock.deleteKeypadEntry(codeId); - Log->print("Delete keypad code: "); + Log->print(F("Delete keypad code: ")); Log->println((int)result); } else @@ -1650,7 +1660,7 @@ void NukiWrapper::onKeypadJsonCommandReceived(const char *value) } result = _nukiLock.addKeypadEntry(entry); - Log->print("Add keypad code: "); + Log->print(F("Add keypad code: ")); Log->println((int)result); } else if (strcmp(action, "update") == 0) @@ -1711,7 +1721,7 @@ void NukiWrapper::onKeypadJsonCommandReceived(const char *value) } result = _nukiLock.updateKeypadEntry(entry); - Log->print("Update keypad code: "); + Log->print(F("Update keypad code: ")); Log->println((int)result); } } @@ -1746,9 +1756,9 @@ void NukiWrapper::onTimeControlCommandReceived(const char *value) return; } - if(!isPinSet()) + if(!isPinValid()) { - _network->publishTimeControlCommandResult("noPinSet"); + _network->publishTimeControlCommandResult("noValidPinSet"); return; } @@ -1801,7 +1811,7 @@ void NukiWrapper::onTimeControlCommandReceived(const char *value) if(idExists) { result = _nukiLock.removeTimeControlEntry(entryId); - Log->print("Delete time control "); + Log->print(F("Delete time control: ")); Log->println((int)result); } else @@ -1866,7 +1876,7 @@ void NukiWrapper::onTimeControlCommandReceived(const char *value) entry.lockAction = timeControlLockAction; result = _nukiLock.addTimeControlEntry(entry); - Log->print("Add time control: "); + Log->print(F("Add time control: ")); Log->println((int)result); } else if (strcmp(action, "update") == 0) @@ -1892,7 +1902,7 @@ void NukiWrapper::onTimeControlCommandReceived(const char *value) entry.lockAction = timeControlLockAction; result = _nukiLock.updateTimeControlEntry(entry); - Log->print("Update time control: "); + Log->print(F("Update time control: ")); Log->println((int)result); } } diff --git a/src/NukiWrapper.h b/src/NukiWrapper.h index f5d0291..0173bbd 100644 --- a/src/NukiWrapper.h +++ b/src/NukiWrapper.h @@ -25,6 +25,7 @@ public: void lockngounlatch(); bool isPinSet(); + bool isPinValid(); void setPin(const uint16_t pin); void unpair(); diff --git a/src/WebCfgServer.cpp b/src/WebCfgServer.cpp index 8d9ad38..af77e67 100644 --- a/src/WebCfgServer.cpp +++ b/src/WebCfgServer.cpp @@ -1545,8 +1545,8 @@ void WebCfgServer::buildInfoHtml(String &response) response.concat(_nuki->hardwareVersion().c_str()); response.concat("\nLock paired: "); response.concat(_nuki->isPaired() ? "Yes\n" : "No\n"); - response.concat("Lock PIN set: "); - response.concat(_nuki->isPaired() ? _nuki->isPinSet() ? "Yes\n" : "No\n" : "-\n"); + response.concat("Lock valid PIN set: "); + response.concat(_nuki->isPaired() ? _nuki->isPinValid() ? "Yes\n" : "No\n" : "-\n"); response.concat("Lock has door sensor: "); response.concat(_nuki->hasDoorSensor() ? "Yes\n" : "No\n"); response.concat("Lock has keypad: "); @@ -1659,8 +1659,8 @@ void WebCfgServer::buildInfoHtml(String &response) response.concat("\nOpener hardware version: "); response.concat(_nukiOpener->hardwareVersion().c_str()); response.concat("\nOpener paired: "); response.concat(_nukiOpener->isPaired() ? "Yes\n" : "No\n"); - response.concat("Opener PIN set: "); - response.concat(_nukiOpener->isPaired() ? _nukiOpener->isPinSet() ? "Yes\n" : "No\n" : "-\n"); + response.concat("Opener valid PIN set: "); + response.concat(_nukiOpener->isPaired() ? _nukiOpener->isPinValid() ? "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): ");