Import/Export config over MQTT

This commit is contained in:
iranl
2025-01-31 20:21:26 +01:00
parent 57456f42f9
commit 24bbe22e87
25 changed files with 1792 additions and 1206 deletions

View File

@@ -12,14 +12,16 @@
NukiOpenerWrapper* nukiOpenerInst;
Preferences* nukiOpenerPreferences = nullptr;
NukiOpenerWrapper::NukiOpenerWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NukiNetworkOpener* network, Gpio* gpio, Preferences* preferences)
NukiOpenerWrapper::NukiOpenerWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NukiNetworkOpener* network, Gpio* gpio, Preferences* preferences, char* buffer, size_t bufferSize)
: _deviceName(deviceName),
_deviceId(deviceId),
_nukiOpener(deviceName, _deviceId->get()),
_bleScanner(scanner),
_network(network),
_gpio(gpio),
_preferences(preferences)
_preferences(preferences),
_buffer(buffer),
_bufferSize(bufferSize)
{
Log->print("Device id opener: ");
Log->println(_deviceId->get());
@@ -81,7 +83,7 @@ void NukiOpenerWrapper::readSettings()
#else
if(pwrLvl >= 20)
{
powerLevel = ESP_PWR_LVL_P20;
powerLevel = ESP_PWR_LVL_P20;
}
else if(pwrLvl >= 18)
{
@@ -197,11 +199,11 @@ void NukiOpenerWrapper::readSettings()
_preferences->putInt(preference_restart_ble_beacon_lost, _restartBeaconTimeout);
}
Log->print(("Opener state interval: "));
Log->print("Opener state interval: ");
Log->print(_intervalLockstate);
Log->print((" | Battery interval: "));
Log->print(" | Battery interval: ");
Log->print(_intervalBattery);
Log->print((" | Publish auth data: "));
Log->print(" | Publish auth data: ");
Log->println(_publishAuthData ? "yes" : "no");
if(!_publishAuthData)
@@ -218,7 +220,7 @@ void NukiOpenerWrapper::update()
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
if(!_paired)
{
Log->println(("Nuki opener start pairing"));
Log->println("Nuki opener start pairing");
_network->publishBleAddress("");
Nuki::AuthorizationIdType idType = _preferences->getBool(preference_register_opener_as_app) ?
@@ -227,7 +229,7 @@ void NukiOpenerWrapper::update()
if(_nukiOpener.pairNuki(idType) == NukiOpener::PairingResult::Success)
{
Log->println(("Nuki opener paired"));
Log->println("Nuki opener paired");
_paired = true;
_network->publishBleAddress(_nukiOpener.getBleAddress().toString());
}
@@ -270,14 +272,14 @@ void NukiOpenerWrapper::update()
_network->publishCommandResult(resultStr);
Log->print(("Opener action result: "));
Log->print("Opener action result: ");
Log->println(resultStr);
if(cmdResult != Nuki::CmdResult::Success)
{
Log->print(("Opener: Last command failed, retrying after "));
Log->print("Opener: Last command failed, retrying after ");
Log->print(_retryDelay);
Log->print((" milliseconds. Retry "));
Log->print(" milliseconds. Retry ");
Log->print(retryCount + 1);
Log->print(" of ");
Log->println(_nrOfRetries);
@@ -297,7 +299,7 @@ void NukiOpenerWrapper::update()
_network->publishRetry("--");
retryCount = 0;
_statusUpdated = true;
Log->println(("Opener: updating status after action"));
Log->println("Opener: updating status after action");
_statusUpdatedTs = ts;
if(_intervalLockstate > 10)
{
@@ -306,7 +308,7 @@ void NukiOpenerWrapper::update()
}
else
{
Log->println(("Opener: Maximum number of retries exceeded, aborting."));
Log->println("Opener: Maximum number of retries exceeded, aborting.");
_network->publishRetry("failed");
retryCount = 0;
_nextLockAction = (NukiOpener::LockAction) 0xff;
@@ -432,11 +434,6 @@ void NukiOpenerWrapper::deactivateCM()
_nextLockAction = NukiOpener::LockAction::DeactivateCM;
}
bool NukiOpenerWrapper::isPinSet()
{
return _nukiOpener.getSecurityPincode() != 0;
}
bool NukiOpenerWrapper::isPinValid()
{
return _preferences->getInt(preference_opener_pin_status, 4) == 1;
@@ -475,7 +472,7 @@ bool NukiOpenerWrapper::updateKeyTurnerState()
while(result != Nuki::CmdResult::Success && retryCount < _nrOfRetries + 1)
{
Log->print(("Result (attempt "));
Log->print("Result (attempt ");
Log->print(retryCount + 1);
Log->print("): ");
result =_nukiOpener.requestOpenerState(&_keyTurnerState);
@@ -494,7 +491,7 @@ bool NukiOpenerWrapper::updateKeyTurnerState()
postponeBleWatchdog();
if(_retryLockstateCount < _nrOfRetries + 1)
{
Log->print(("Query opener state retrying in "));
Log->print("Query opener state retrying in ");
Log->print(_retryDelay);
Log->println("ms");
_nextLockStateUpdateTs = espMillis() + _retryDelay;
@@ -517,7 +514,7 @@ bool NukiOpenerWrapper::updateKeyTurnerState()
_lastKeyTurnerState.lockState == NukiOpener::LockState::Locked &&
_lastKeyTurnerState.nukiState == _keyTurnerState.nukiState)
{
Log->println(("Nuki opener: Ring detected (Locked)"));
Log->println("Nuki opener: Ring detected (Locked)");
_network->publishRing(true);
}
else
@@ -527,17 +524,17 @@ bool NukiOpenerWrapper::updateKeyTurnerState()
_keyTurnerState.lockState == NukiOpener::LockState::Open &&
_keyTurnerState.trigger == NukiOpener::Trigger::Manual)
{
Log->println(("Nuki opener: Ring detected (Open)"));
Log->println("Nuki opener: Ring detected (Open)");
_network->publishRing(false);
}
if(_publishAuthData)
{
Log->println(("Publishing auth data"));
Log->println("Publishing auth data");
updateAuthData(false);
Log->println(("Done publishing auth data"));
Log->println("Done publishing auth data");
}
if(_keyTurnerState.lockState == NukiOpener::LockState::Undefined)
{
if (_nextLockStateUpdateTs > espMillis() + 60000)
@@ -552,12 +549,12 @@ bool NukiOpenerWrapper::updateKeyTurnerState()
if((_keyTurnerState.lockState == NukiOpener::LockState::Open || _keyTurnerState.lockState == NukiOpener::LockState::Opening) && espMillis() < _statusUpdatedTs + 10000)
{
updateStatus = true;
Log->println(("Opener: Keep updating status on intermediate lock state"));
Log->println("Opener: Keep updating status on intermediate lock state");
}
if(_keyTurnerState.nukiState == NukiOpener::State::ContinuousMode)
{
Log->println(("Continuous Mode"));
Log->println("Continuous Mode");
}
char lockStateStr[20];
@@ -566,7 +563,7 @@ bool NukiOpenerWrapper::updateKeyTurnerState()
}
postponeBleWatchdog();
Log->println(("Done querying opener state"));
Log->println("Done querying opener state");
return updateStatus;
}
@@ -577,7 +574,7 @@ void NukiOpenerWrapper::updateBatteryState()
while(retryCount < _nrOfRetries + 1)
{
Log->print(("Querying opener battery state: "));
Log->print("Querying opener battery state: ");
result = _nukiOpener.requestBatteryReport(&_batteryReport);
delay(250);
if(result != Nuki::CmdResult::Success)
@@ -596,7 +593,7 @@ void NukiOpenerWrapper::updateBatteryState()
_network->publishBatteryReport(_batteryReport);
}
postponeBleWatchdog();
Log->println(("Done querying opener battery state"));
Log->println("Done querying opener battery state");
}
void NukiOpenerWrapper::updateConfig()
@@ -611,7 +608,7 @@ void NukiOpenerWrapper::updateConfig()
{
char uidString[20];
itoa(_nukiConfig.nukiId, uidString, 16);
Log->print(("Saving Opener Nuki ID to preferences ("));
Log->print("Saving Opener Nuki ID to preferences (");
Log->print(_nukiConfig.nukiId);
Log->print(" / ");
Log->print(uidString);
@@ -640,61 +637,49 @@ void NukiOpenerWrapper::updateConfig()
const int pinStatus = _preferences->getInt(preference_opener_pin_status, 4);
if(isPinSet())
Nuki::CmdResult result = (Nuki::CmdResult)-1;
int retryCount = 0;
while(retryCount < _nrOfRetries + 1)
{
Nuki::CmdResult result = (Nuki::CmdResult)-1;
int retryCount = 0;
Log->println(("Nuki opener PIN is set"));
while(retryCount < _nrOfRetries + 1)
{
result = _nukiOpener.verifySecurityPin();
if(result != Nuki::CmdResult::Success)
{
++retryCount;
}
else
{
break;
}
}
result = _nukiOpener.verifySecurityPin();
if(result != Nuki::CmdResult::Success)
{
Log->println(("Nuki opener PIN is invalid"));
if(pinStatus != 2)
{
_preferences->putInt(preference_opener_pin_status, 2);
}
++retryCount;
}
else
{
Log->println(("Nuki opener PIN is valid"));
if(pinStatus != 1)
{
_preferences->putInt(preference_opener_pin_status, 1);
}
break;
}
}
if(result != Nuki::CmdResult::Success)
{
Log->println("Nuki opener PIN is invalid or not set");
if(pinStatus != 2)
{
_preferences->putInt(preference_opener_pin_status, 2);
}
}
else
{
Log->println(("Nuki opener PIN is not set"));
if(pinStatus != 0)
Log->println("Nuki opener PIN is valid");
if(pinStatus != 1)
{
_preferences->putInt(preference_opener_pin_status, 0);
_preferences->putInt(preference_opener_pin_status, 1);
}
}
}
else
{
Log->println(("Invalid/Unexpected opener config received, ID does not matched saved ID"));
Log->println("Invalid/Unexpected opener config received, ID does not matched saved ID");
expectedConfig = false;
}
}
else
{
Log->println(("Invalid/Unexpected opener config received, Config is not valid"));
Log->println("Invalid/Unexpected opener config received, Config is not valid");
expectedConfig = false;
}
@@ -711,7 +696,7 @@ void NukiOpenerWrapper::updateConfig()
}
else
{
Log->println(("Invalid/Unexpected opener advanced config received, Advanced config is not valid"));
Log->println("Invalid/Unexpected opener advanced config received, Advanced config is not valid");
expectedConfig = false;
}
}
@@ -719,12 +704,12 @@ void NukiOpenerWrapper::updateConfig()
if(expectedConfig && _nukiConfigValid && _nukiAdvancedConfigValid)
{
_retryConfigCount = 0;
Log->println(("Done retrieving opener config and advanced config"));
Log->println("Done retrieving opener config and advanced config");
}
else
{
++_retryConfigCount;
Log->println(("Invalid/Unexpected opener config and/or advanced config received, retrying in 10 seconds"));
Log->println("Invalid/Unexpected opener config and/or advanced config received, retrying in 10 seconds");
int64_t ts = espMillis();
_nextConfigUpdateTs = ts + 10000;
}
@@ -734,7 +719,7 @@ void NukiOpenerWrapper::updateAuthData(bool retrieved)
{
if(!isPinValid())
{
Log->println(("No valid PIN set"));
Log->println("No valid PIN set");
return;
}
@@ -820,7 +805,7 @@ void NukiOpenerWrapper::updateKeypad(bool retrieved)
if(!isPinValid())
{
Log->println(("No valid Nuki Opener PIN set"));
Log->println("No valid Nuki Opener PIN set");
return;
}
@@ -900,7 +885,7 @@ void NukiOpenerWrapper::updateTimeControl(bool retrieved)
if(!isPinValid())
{
Log->println(("No valid Nuki Opener PIN set"));
Log->println("No valid Nuki Opener PIN set");
return;
}
@@ -972,7 +957,7 @@ void NukiOpenerWrapper::updateAuth(bool retrieved)
{
if(!isPinValid())
{
Log->println(("No valid Nuki Lock PIN set"));
Log->println("No valid Nuki Lock PIN set");
return;
}
@@ -1558,23 +1543,21 @@ Nuki::BatteryType NukiOpenerWrapper::batteryTypeToEnum(const char* str)
void NukiOpenerWrapper::onConfigUpdateReceived(const char *value)
{
JsonDocument jsonResult;
char _resbuf[2048];
if(!_nukiConfigValid)
{
jsonResult["general"] = "configNotReady";
serializeJson(jsonResult, _resbuf, sizeof(_resbuf));
_network->publishConfigCommandResult(_resbuf);
serializeJson(jsonResult, _buffer, _bufferSize);
_network->publishConfigCommandResult(_buffer);
return;
}
if(!isPinValid())
{
jsonResult["general"] = "noValidPinSet";
serializeJson(jsonResult, _resbuf, sizeof(_resbuf));
_network->publishConfigCommandResult(_resbuf);
serializeJson(jsonResult, _buffer, _bufferSize);
_network->publishConfigCommandResult(_buffer);
return;
}
@@ -1584,8 +1567,8 @@ void NukiOpenerWrapper::onConfigUpdateReceived(const char *value)
if(jsonError)
{
jsonResult["general"] = "invalidJson";
serializeJson(jsonResult, _resbuf, sizeof(_resbuf));
_network->publishConfigCommandResult(_resbuf);
serializeJson(jsonResult, _buffer, _bufferSize);
_network->publishConfigCommandResult(_buffer);
return;
}
@@ -2437,8 +2420,8 @@ void NukiOpenerWrapper::onConfigUpdateReceived(const char *value)
_nextConfigUpdateTs = espMillis() + 300;
serializeJson(jsonResult, _resbuf, sizeof(_resbuf));
_network->publishConfigCommandResult(_resbuf);
serializeJson(jsonResult, _buffer, _bufferSize);
_network->publishConfigCommandResult(_buffer);
return;
}
@@ -4198,7 +4181,7 @@ void NukiOpenerWrapper::updateTime()
{
if(!isPinValid())
{
Log->println(("No valid PIN set"));
Log->println("No valid PIN set");
return;
}
@@ -4209,7 +4192,7 @@ void NukiOpenerWrapper::updateTime()
if (int(tm.tm_year + 1900) < int(2025))
{
Log->println(("NTP Time not valid, not updating Nuki device"));
Log->println("NTP Time not valid, not updating Nuki device");
return;
}