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

@@ -11,7 +11,7 @@
NukiWrapper* nukiInst = nullptr;
NukiWrapper::NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NukiNetworkLock* network, NukiOfficial* nukiOfficial, Gpio* gpio, Preferences* preferences)
NukiWrapper::NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NukiNetworkLock* network, NukiOfficial* nukiOfficial, Gpio* gpio, Preferences* preferences, char* buffer, size_t bufferSize)
: _deviceName(deviceName),
_deviceId(deviceId),
_bleScanner(scanner),
@@ -19,7 +19,9 @@ NukiWrapper::NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId,
_network(network),
_nukiOfficial(nukiOfficial),
_gpio(gpio),
_preferences(preferences)
_preferences(preferences),
_buffer(buffer),
_bufferSize(bufferSize)
{
Log->print("Device id lock: ");
@@ -233,8 +235,8 @@ void NukiWrapper::update(bool reboot)
wdt_hal_write_protect_enable(&rtc_wdt_ctx);
if(!_paired)
{
Log->println(("Nuki lock start pairing"));
_preferences->getBool(preference_register_as_app) ? Log->println(("Pairing as app")) : Log->println(("Pairing as bridge"));
Log->println("Nuki lock start pairing");
_preferences->getBool(preference_register_as_app) ? Log->println("Pairing as app") : Log->println("Pairing as bridge");
_network->publishBleAddress("");
Nuki::AuthorizationIdType idType = _preferences->getBool(preference_register_as_app) ?
@@ -243,7 +245,7 @@ void NukiWrapper::update(bool reboot)
if(_nukiLock.pairNuki(idType) == Nuki::PairingResult::Success)
{
Log->println(("Nuki paired"));
Log->println("Nuki paired");
_paired = true;
_network->publishBleAddress(_nukiLock.getBleAddress().toString());
}
@@ -295,9 +297,9 @@ void NukiWrapper::update(bool reboot)
if(cmdResult != Nuki::CmdResult::Success)
{
Log->print(("Lock: Last command failed, retrying after "));
Log->print("Lock: 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);
@@ -320,7 +322,7 @@ void NukiWrapper::update(bool reboot)
{
_statusUpdated = true;
}
Log->println(("Lock: updating status after action"));
Log->println("Lock: updating status after action");
_statusUpdatedTs = ts;
if(_intervalLockstate > 10)
{
@@ -329,7 +331,7 @@ void NukiWrapper::update(bool reboot)
}
else
{
Log->println(("Lock: Maximum number of retries exceeded, aborting."));
Log->println("Lock: Maximum number of retries exceeded, aborting.");
_network->publishRetry("failed");
retryCount = 0;
_nextLockAction = (NukiLock::LockAction) 0xff;
@@ -450,18 +452,6 @@ void NukiWrapper::lockngounlatch()
_nextLockAction = NukiLock::LockAction::LockNgoUnlatch;
}
bool NukiWrapper::isPinSet()
{
if (_isUltra)
{
return _nukiLock.getUltraPincode() != 0;
}
else
{
return _nukiLock.getSecurityPincode() != 0;
}
}
bool NukiWrapper::isPinValid()
{
return _preferences->getInt(preference_lock_pin_status, 4) == 1;
@@ -508,11 +498,11 @@ bool NukiWrapper::updateKeyTurnerState()
Nuki::CmdResult result = (Nuki::CmdResult)-1;
int retryCount = 0;
Log->println(("Querying lock state"));
Log->println("Querying lock state");
while(result != Nuki::CmdResult::Success && retryCount < _nrOfRetries + 1)
{
Log->print(("Result (attempt "));
Log->print("Result (attempt ");
Log->print(retryCount + 1);
Log->print(("): "));
result =_nukiLock.requestKeyTurnerState(&_keyTurnerState);
@@ -531,7 +521,7 @@ bool NukiWrapper::updateKeyTurnerState()
postponeBleWatchdog();
if(_retryLockstateCount < _nrOfRetries + 1)
{
Log->print(("Query lock state retrying in "));
Log->print("Query lock state retrying in ");
Log->print(_retryDelay);
Log->println("ms");
_nextLockStateUpdateTs = espMillis() + _retryDelay;
@@ -557,9 +547,9 @@ bool NukiWrapper::updateKeyTurnerState()
{
if(_publishAuthData && (lockState == NukiLock::LockState::Locked || lockState == NukiLock::LockState::Unlocked))
{
Log->println(("Publishing auth data"));
Log->println("Publishing auth data");
updateAuthData(false);
Log->println(("Done publishing auth data"));
Log->println("Done publishing auth data");
}
updateGpioOutputs();
@@ -567,7 +557,7 @@ bool NukiWrapper::updateKeyTurnerState()
else if(!_nukiOfficial->getOffConnected() && espMillis() < _statusUpdatedTs + 10000)
{
updateStatus = true;
Log->println(("Lock: Keep updating status on intermediate lock state"));
Log->println("Lock: Keep updating status on intermediate lock state");
}
else if(lockState == NukiLock::LockState::Undefined)
{
@@ -583,7 +573,7 @@ bool NukiWrapper::updateKeyTurnerState()
Log->println(lockStateStr);
postponeBleWatchdog();
Log->println(("Done querying lock state"));
Log->println("Done querying lock state");
return updateStatus;
}
@@ -617,7 +607,7 @@ void NukiWrapper::updateBatteryState()
_network->publishBatteryReport(_batteryReport);
}
postponeBleWatchdog();
Log->println(("Done querying lock battery state"));
Log->println("Done querying lock battery state");
}
void NukiWrapper::updateConfig()
@@ -632,7 +622,7 @@ void NukiWrapper::updateConfig()
{
char uidString[20];
itoa(_nukiConfig.nukiId, uidString, 16);
Log->print(("Saving Lock Nuki ID to preferences ("));
Log->print("Saving Lock Nuki ID to preferences (");
Log->print(_nukiConfig.nukiId);
Log->print(" / ");
Log->print(uidString);
@@ -660,60 +650,48 @@ void NukiWrapper::updateConfig()
const int pinStatus = _preferences->getInt(preference_lock_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 Lock PIN is set"));
while(retryCount < _nrOfRetries + 1)
{
result = _nukiLock.verifySecurityPin();
if(result != Nuki::CmdResult::Success)
{
++retryCount;
}
else
{
break;
}
}
result = _nukiLock.verifySecurityPin();
if(result != Nuki::CmdResult::Success)
{
Log->println(("Nuki Lock PIN is invalid"));
if(pinStatus != 2)
{
_preferences->putInt(preference_lock_pin_status, 2);
}
++retryCount;
}
else
{
Log->println(("Nuki Lock PIN is valid"));
if(pinStatus != 1)
{
_preferences->putInt(preference_lock_pin_status, 1);
}
break;
}
}
if(result != Nuki::CmdResult::Success)
{
Log->println("Nuki Lock PIN is invalid or not set");
if(pinStatus != 2)
{
_preferences->putInt(preference_lock_pin_status, 2);
}
}
else
{
Log->println(("Nuki Lock PIN is not set"));
if(pinStatus != 0)
Log->println("Nuki Lock PIN is valid");
if(pinStatus != 1)
{
_preferences->putInt(preference_lock_pin_status, 0);
_preferences->putInt(preference_lock_pin_status, 1);
}
}
}
else
{
Log->println(("Invalid/Unexpected lock config received, ID does not matched saved ID"));
Log->println("Invalid/Unexpected lock config received, ID does not matched saved ID");
expectedConfig = false;
}
}
else
{
Log->println(("Invalid/Unexpected lock config received, Config is not valid"));
Log->println("Invalid/Unexpected lock config received, Config is not valid");
expectedConfig = false;
}
@@ -730,7 +708,7 @@ void NukiWrapper::updateConfig()
}
else
{
Log->println(("Invalid/Unexpected lock advanced config received, Advanced config is not valid"));
Log->println("Invalid/Unexpected lock advanced config received, Advanced config is not valid");
expectedConfig = false;
}
}
@@ -738,12 +716,12 @@ void NukiWrapper::updateConfig()
if(expectedConfig && _nukiConfigValid && _nukiAdvancedConfigValid)
{
_retryConfigCount = 0;
Log->println(("Done retrieving lock config and advanced config"));
Log->println("Done retrieving lock config and advanced config");
}
else
{
++_retryConfigCount;
Log->println(("Invalid/Unexpected lock config and/or advanced config received, retrying in 10 seconds"));
Log->println("Invalid/Unexpected lock config and/or advanced config received, retrying in 10 seconds");
int64_t ts = espMillis();
_nextConfigUpdateTs = ts + 10000;
}
@@ -753,7 +731,7 @@ void NukiWrapper::updateAuthData(bool retrieved)
{
if(!isPinValid())
{
Log->println(("No valid Nuki Lock PIN set"));
Log->println("No valid Nuki Lock PIN set");
return;
}
@@ -837,7 +815,7 @@ void NukiWrapper::updateKeypad(bool retrieved)
if(!isPinValid())
{
Log->println(("No valid Nuki Lock PIN set"));
Log->println("No valid Nuki Lock PIN set");
return;
}
@@ -916,7 +894,7 @@ void NukiWrapper::updateTimeControl(bool retrieved)
if(!isPinValid())
{
Log->println(("No valid Nuki Lock PIN set"));
Log->println("No valid Nuki Lock PIN set");
return;
}
@@ -987,7 +965,7 @@ void NukiWrapper::updateAuth(bool retrieved)
{
if(!isPinValid())
{
Log->println(("No valid Nuki Lock PIN set"));
Log->println("No valid Nuki Lock PIN set");
return;
}
@@ -1495,21 +1473,20 @@ void NukiWrapper::onOfficialUpdateReceived(const char *topic, const char *value)
void NukiWrapper::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;
}
@@ -1519,15 +1496,11 @@ void NukiWrapper::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;
}
Log->println(value);
serializeJson(json, _resbuf, sizeof(_resbuf));
Log->println(_resbuf);
Nuki::CmdResult cmdResult;
const char *basicKeys[16] = {"name", "latitude", "longitude", "autoUnlatch", "pairingEnabled", "buttonEnabled", "ledEnabled", "ledBrightness", "timeZoneOffset", "dstMode", "fobAction1", "fobAction2", "fobAction3", "singleLock", "advertisingMode", "timeZone"};
const char *advancedKeys[25] = {"unlockedPositionOffsetDegrees", "lockedPositionOffsetDegrees", "singleLockedPositionOffsetDegrees", "unlockedToLockedTransitionOffsetDegrees", "lockNgoTimeout", "singleButtonPressAction", "doubleButtonPressAction", "detachedCylinder", "batteryType", "automaticBatteryTypeDetection", "unlatchDuration", "autoLockTimeOut", "autoUnLockDisabled", "nightModeEnabled", "nightModeStartTime", "nightModeEndTime", "nightModeAutoLockEnabled", "nightModeAutoUnlockDisabled", "nightModeImmediateLockOnStart", "autoLockEnabled", "immediateAutoLockEnabled", "autoUpdateEnabled", "rebootNuki", "motorSpeed", "enableSlowSpeedDuringNightMode"};
@@ -2500,8 +2473,8 @@ void NukiWrapper::onConfigUpdateReceived(const char *value)
_nextConfigUpdateTs = espMillis() + 300;
serializeJson(jsonResult, _resbuf, sizeof(_resbuf));
_network->publishConfigCommandResult(_resbuf);
serializeJson(jsonResult, _buffer, _bufferSize);
_network->publishConfigCommandResult(_buffer);
return;
}
@@ -4325,7 +4298,7 @@ void NukiWrapper::updateTime()
{
if(!isPinValid())
{
Log->println(("No valid PIN set"));
Log->println("No valid PIN set");
return;
}
@@ -4336,7 +4309,7 @@ void NukiWrapper::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;
}