diff --git a/MqttTopics.h b/MqttTopics.h index 66c315f..2b09c82 100644 --- a/MqttTopics.h +++ b/MqttTopics.h @@ -20,6 +20,7 @@ #define mqtt_topic_lock_door_sensor_state "/lock/doorSensorState" #define mqtt_topic_lock_action "/lock/action" #define mqtt_topic_lock_rssi "/lock/rssi" +#define mqtt_topic_lock_address "/lock/address" #define mqtt_topic_config_button_enabled "/configuration/buttonEnabled" #define mqtt_topic_config_led_enabled "/configuration/ledEnabled" diff --git a/NetworkLock.cpp b/NetworkLock.cpp index 3c08524..e683e77 100644 --- a/NetworkLock.cpp +++ b/NetworkLock.cpp @@ -388,6 +388,11 @@ void NetworkLock::publishRssi(const int& rssi) publishInt(mqtt_topic_lock_rssi, rssi); } +void NetworkLock::publishBleAddress(const std::string &address) +{ + publishString(mqtt_topic_lock_address, address.c_str()); +} + void NetworkLock::publishKeypad(const std::list& entries, uint maxKeypadCodeCount) { uint index = 0; diff --git a/NetworkLock.h b/NetworkLock.h index c268a36..b313b30 100644 --- a/NetworkLock.h +++ b/NetworkLock.h @@ -28,6 +28,7 @@ public: void publishConfig(const NukiLock::Config& config); void publishAdvancedConfig(const NukiLock::AdvancedConfig& config); void publishRssi(const int& rssi); + void publishBleAddress(const std::string& address); void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState); void removeHASSConfig(char* uidString); void publishKeypad(const std::list& entries, uint maxKeypadCodeCount); diff --git a/NetworkOpener.cpp b/NetworkOpener.cpp index 28d0d3b..6b3dc84 100644 --- a/NetworkOpener.cpp +++ b/NetworkOpener.cpp @@ -97,15 +97,23 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn { char str[50]; - if((_firstTunerStatePublish || keyTurnerState.lockState != lastKeyTurnerState.lockState) && keyTurnerState.lockState != NukiOpener::LockState::Undefined) + if((_firstTunerStatePublish || keyTurnerState.lockState != lastKeyTurnerState.lockState || keyTurnerState.nukiState != lastKeyTurnerState.nukiState) && keyTurnerState.lockState != NukiOpener::LockState::Undefined) { memset(&str, 0, sizeof(str)); - lockstateToString(keyTurnerState.lockState, str); - publishString(mqtt_topic_lock_state, str); + + if(keyTurnerState.nukiState == NukiOpener::State::ContinuousMode) + { + publishString(mqtt_topic_lock_state, "ContinuousMode"); + } + else + { + lockstateToString(keyTurnerState.lockState, str); + publishString(mqtt_topic_lock_state, str); + } if(_haEnabled) { - publishBinaryState(keyTurnerState.lockState); + publishBinaryState(keyTurnerState); } } @@ -145,20 +153,27 @@ void NetworkOpener::publishRing() _resetLockStateTs = millis() + 2000; } -void NetworkOpener::publishBinaryState(NukiOpener::LockState lockState) +void NetworkOpener::publishBinaryState(NukiOpener::OpenerState lockState) { - switch(lockState) + if(lockState.nukiState == NukiOpener::State::ContinuousMode) { - case NukiOpener::LockState::Locked: - publishString(mqtt_topic_lock_binary_state, "locked"); - break; - case NukiOpener::LockState::RTOactive: - case NukiOpener::LockState::Open: - case NukiOpener::LockState::Opening: - publishString(mqtt_topic_lock_binary_state, "unlocked"); - break; - default: - break; + publishString(mqtt_topic_lock_binary_state, "unlocked"); + } + else + { + switch (lockState.lockState) + { + case NukiOpener::LockState::Locked: + publishString(mqtt_topic_lock_binary_state, "locked"); + break; + case NukiOpener::LockState::RTOactive: + case NukiOpener::LockState::Open: + case NukiOpener::LockState::Opening: + publishString(mqtt_topic_lock_binary_state, "unlocked"); + break; + default: + break; + } } } @@ -367,6 +382,11 @@ void NetworkOpener::publishRssi(const int &rssi) publishInt(mqtt_topic_lock_rssi, rssi); } +void NetworkOpener::publishBleAddress(const std::string &address) +{ + publishString(mqtt_topic_lock_address, address.c_str()); +} + void NetworkOpener::publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState) { _network->publishHASSConfig(deviceType, baseTopic, name, uidString, lockAction, unlockAction, openAction, lockedState, unlockedState); @@ -449,4 +469,3 @@ bool NetworkOpener::comparePrefixedPath(const char *fullPath, const char *subPat buildMqttPath(subPath, prefixedPath); return strcmp(fullPath, prefixedPath) == 0; } - diff --git a/NetworkOpener.h b/NetworkOpener.h index 063709f..eb52a22 100644 --- a/NetworkOpener.h +++ b/NetworkOpener.h @@ -21,7 +21,7 @@ public: void publishKeyTurnerState(const NukiOpener::OpenerState& keyTurnerState, const NukiOpener::OpenerState& lastKeyTurnerState); void publishRing(); - void publishBinaryState(NukiOpener::LockState lockState); + void publishBinaryState(NukiOpener::OpenerState lockState); void publishAuthorizationInfo(const std::list& logEntries); void clearAuthorizationInfo(); void publishCommandResult(const char* resultStr); @@ -29,6 +29,7 @@ public: void publishConfig(const NukiOpener::Config& config); void publishAdvancedConfig(const NukiOpener::AdvancedConfig& config); void publishRssi(const int& rssi); + void publishBleAddress(const std::string& address); void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState); void removeHASSConfig(char* uidString); diff --git a/NukiOpenerWrapper.cpp b/NukiOpenerWrapper.cpp index d85b252..aa4025d 100644 --- a/NukiOpenerWrapper.cpp +++ b/NukiOpenerWrapper.cpp @@ -75,14 +75,17 @@ void NukiOpenerWrapper::update() if (!_paired) { Log->println(F("Nuki opener start pairing")); + _network->publishBleAddress(""); Nuki::AuthorizationIdType idType = _preferences->getBool(preference_register_as_app) ? Nuki::AuthorizationIdType::App : Nuki::AuthorizationIdType::Bridge; - if (_nukiOpener.pairNuki(idType) == NukiOpener::PairingResult::Success) { + if (_nukiOpener.pairNuki(idType) == NukiOpener::PairingResult::Success) + { Log->println(F("Nuki opener paired")); _paired = true; + _network->publishBleAddress(_nukiOpener.getBleAddress().toString()); } else { @@ -91,7 +94,12 @@ void NukiOpenerWrapper::update() } } - if(_restartBeaconTimeout > 0 && (millis() - _nukiOpener.getLastReceivedBeaconTs() > _restartBeaconTimeout * 1000)) + unsigned long ts = millis(); + unsigned long lastReceivedBeaconTs = _nukiOpener.getLastReceivedBeaconTs(); + if(_restartBeaconTimeout > 0 && + ts > 60000 && + lastReceivedBeaconTs > 0 && + (ts - lastReceivedBeaconTs > _restartBeaconTimeout * 1000)) { Log->print("No BLE beacon received from the opener for "); Log->print((millis() - _nukiOpener.getLastReceivedBeaconTs()) / 1000); @@ -102,8 +110,6 @@ void NukiOpenerWrapper::update() _nukiOpener.updateConnectionState(); - unsigned long ts = millis(); - if(_statusUpdated || _nextLockStateUpdateTs == 0 || ts >= _nextLockStateUpdateTs) { _nextLockStateUpdateTs = ts + _intervalLockstate * 1000; @@ -179,7 +185,10 @@ void NukiOpenerWrapper::updateKeyTurnerState() { _nukiOpener.requestOpenerState(&_keyTurnerState); - if(_statusUpdated && _keyTurnerState.lockState == NukiOpener::LockState::Locked && _lastKeyTurnerState.lockState == NukiOpener::LockState::Locked) + if(_statusUpdated && + _keyTurnerState.lockState == NukiOpener::LockState::Locked && + _lastKeyTurnerState.lockState == NukiOpener::LockState::Locked && + _lastKeyTurnerState.nukiState == _keyTurnerState.nukiState) { Log->println(F("Nuki opener: Ring detected")); _network->publishRing(); @@ -188,7 +197,11 @@ void NukiOpenerWrapper::updateKeyTurnerState() { _network->publishKeyTurnerState(_keyTurnerState, _lastKeyTurnerState); - if(_keyTurnerState.lockState != _lastKeyTurnerState.lockState) + if(_keyTurnerState.nukiState == NukiOpener::State::ContinuousMode) + { + Log->println(F("Nuki opener state: Continuous Mode")); + } + else if(_keyTurnerState.lockState != _lastKeyTurnerState.lockState) { char lockStateStr[20]; lockstateToString(_keyTurnerState.lockState, lockStateStr); @@ -305,6 +318,11 @@ const bool NukiOpenerWrapper::isPaired() return _paired; } +const BLEAddress NukiOpenerWrapper::getBleAddress() const +{ + return _nukiOpener.getBleAddress(); +} + BleScanner::Scanner *NukiOpenerWrapper::bleScanner() { return _bleScanner; diff --git a/NukiOpenerWrapper.h b/NukiOpenerWrapper.h index fa00602..434f0b1 100644 --- a/NukiOpenerWrapper.h +++ b/NukiOpenerWrapper.h @@ -23,6 +23,7 @@ public: const NukiOpener::OpenerState& keyTurnerState(); const bool isPaired(); + const BLEAddress getBleAddress() const; BleScanner::Scanner* bleScanner(); diff --git a/NukiWrapper.cpp b/NukiWrapper.cpp index 4dc4adf..46921a5 100644 --- a/NukiWrapper.cpp +++ b/NukiWrapper.cpp @@ -87,21 +87,20 @@ void NukiWrapper::initialize() void NukiWrapper::update() { - Nuki::AuthorizationIdType idType = _preferences->getBool(preference_register_as_app) ? - Nuki::AuthorizationIdType::App : - Nuki::AuthorizationIdType::Bridge; - if (!_paired) { Log->println(F("Nuki start pairing")); + _network->publishBleAddress(""); Nuki::AuthorizationIdType idType = _preferences->getBool(preference_register_as_app) ? Nuki::AuthorizationIdType::App : Nuki::AuthorizationIdType::Bridge; - if (_nukiLock.pairNuki(idType) == Nuki::PairingResult::Success) { + if (_nukiLock.pairNuki(idType) == Nuki::PairingResult::Success) + { Log->println(F("Nuki paired")); _paired = true; + _network->publishBleAddress(_nukiLock.getBleAddress().toString()); } else { @@ -110,7 +109,12 @@ void NukiWrapper::update() } } - if(_restartBeaconTimeout > 0 && (millis() - _nukiLock.getLastReceivedBeaconTs() > _restartBeaconTimeout * 1000)) + unsigned long ts = millis(); + unsigned long lastReceivedBeaconTs = _nukiLock.getLastReceivedBeaconTs(); + if(_restartBeaconTimeout > 0 && + ts > 60000 && + lastReceivedBeaconTs > 0 && + (ts - lastReceivedBeaconTs > _restartBeaconTimeout * 1000)) { Log->print("No BLE beacon received from the lock for "); Log->print((millis() - _nukiLock.getLastReceivedBeaconTs()) / 1000); @@ -121,8 +125,6 @@ void NukiWrapper::update() _nukiLock.updateConnectionState(); - unsigned long ts = millis(); - if(_statusUpdated || _nextLockStateUpdateTs == 0 || ts >= _nextLockStateUpdateTs) { _statusUpdated = false; @@ -576,3 +578,8 @@ void NukiWrapper::disableHASS() Log->println(F("Unable to disable HASS. Invalid config received.")); } } + +const BLEAddress NukiWrapper::getBleAddress() const +{ + return _nukiLock.getBleAddress(); +} diff --git a/NukiWrapper.h b/NukiWrapper.h index 3f681d5..9e7c669 100644 --- a/NukiWrapper.h +++ b/NukiWrapper.h @@ -27,6 +27,7 @@ public: const NukiLock::KeyTurnerState& keyTurnerState(); const bool isPaired(); const bool hasKeypad(); + const BLEAddress getBleAddress() const; void notify(Nuki::EventType eventType) override; diff --git a/Version.h b/Version.h index e679cb7..32dcaef 100644 --- a/Version.h +++ b/Version.h @@ -1,3 +1,3 @@ #pragma once -#define nuki_hub_version "6.8" \ No newline at end of file +#define nuki_hub_version "6.9" \ No newline at end of file diff --git a/WebCfgServer.cpp b/WebCfgServer.cpp index 144d48c..a87bfaa 100644 --- a/WebCfgServer.cpp +++ b/WebCfgServer.cpp @@ -450,14 +450,14 @@ void WebCfgServer::buildHtml(String& response) { char lockstateArr[20]; NukiLock::lockstateToString(_nuki->keyTurnerState().lockState, lockstateArr); - printParameter(response, "NUKI Lock paired", _nuki->isPaired() ? "Yes" : "No"); + printParameter(response, "NUKI Lock paired", _nuki->isPaired() ? ("Yes (BLE Address " + _nuki->getBleAddress().toString() + ")").c_str() : "No"); printParameter(response, "NUKI Lock state", lockstateArr); } if(_nukiOpener != nullptr) { char lockstateArr[20]; NukiOpener::lockstateToString(_nukiOpener->keyTurnerState().lockState, lockstateArr); - printParameter(response, "NUKI Opener paired", _nukiOpener->isPaired() ? "Yes" : "No"); + printParameter(response, "NUKI Opener paired", _nuki->isPaired() ? ("Yes (BLE Address " + _nukiOpener->getBleAddress().toString() + ")").c_str() : "No"); printParameter(response, "NUKI Opener state", lockstateArr); } printParameter(response, "Firmware", version.c_str()); diff --git a/lib/NimBLE-Arduino/CHANGELOG.md b/lib/NimBLE-Arduino/CHANGELOG.md index 7e12ae5..43fbc62 100644 --- a/lib/NimBLE-Arduino/CHANGELOG.md +++ b/lib/NimBLE-Arduino/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to this project will be documented in this file. ### Fixed - Compile warning removed for esp32c3 - NimBLEDevice::getPower incorrect value when power level is -3db. - - Failure pairing when already in progress. + - Failed pairing when already in progress. ### Changed - Revert previous change that forced writing with response when subscribing in favor of allowing the application to decide. diff --git a/lib/NimBLE-Arduino/docs/Doxyfile b/lib/NimBLE-Arduino/docs/Doxyfile index d9c4303..54129a1 100644 --- a/lib/NimBLE-Arduino/docs/Doxyfile +++ b/lib/NimBLE-Arduino/docs/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = NimBLE-Arduino # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.4.1 +PROJECT_NUMBER = 1.4.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -58,7 +58,7 @@ PROJECT_LOGO = # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = doxydocs +OUTPUT_DIRECTORY = docs # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and @@ -836,7 +836,7 @@ WARN_NO_PARAMDOC = NO # Possible values are: NO, YES and FAIL_ON_WARNINGS. # The default value is: NO. -WARN_AS_ERROR = YES +WARN_AS_ERROR = FAIL_ON_WARNINGS # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which diff --git a/lib/nuki_ble b/lib/nuki_ble index be1fa97..75791e7 160000 --- a/lib/nuki_ble +++ b/lib/nuki_ble @@ -1 +1 @@ -Subproject commit be1fa972a61a5c86673c1cebe37ba4c5e2cdea9f +Subproject commit 75791e72e313dbc92f02bd66246874c313b79bca diff --git a/webflash/nuki_hub.bin b/webflash/nuki_hub.bin index 0769032..232e0aa 100644 Binary files a/webflash/nuki_hub.bin and b/webflash/nuki_hub.bin differ