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): ");