Add Authorization entries (#456)
* Add and remove libs and components for Arduino Core 3 * Arduino Core 3 * Add back Solo1 * Change ESP32-S3 to 4MB build * Add Authorization info and control * Use esp_crt_bundle for HTTPS requests * Remove Solo1 support * Improve Nuki device config read functions * Webserial * OTA Improvements * Authorization Entries * Authorization entries * Authorization
This commit is contained in:
@@ -37,6 +37,7 @@ NukiWrapper::NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId,
|
||||
if(_disableNonJSON) network->setKeypadCommandReceivedCallback(nukiInst->onKeypadCommandReceivedCallback);
|
||||
network->setKeypadJsonCommandReceivedCallback(nukiInst->onKeypadJsonCommandReceivedCallback);
|
||||
network->setTimeControlCommandReceivedCallback(nukiInst->onTimeControlCommandReceivedCallback);
|
||||
network->setAuthCommandReceivedCallback(nukiInst->onAuthCommandReceivedCallback);
|
||||
|
||||
_gpio->addCallback(NukiWrapper::gpioActionCallback);
|
||||
}
|
||||
@@ -76,6 +77,7 @@ void NukiWrapper::initialize(const bool& firstStart)
|
||||
_publishAuthData = _preferences->getBool(preference_publish_authdata);
|
||||
_maxKeypadCodeCount = _preferences->getUInt(preference_lock_max_keypad_code_count);
|
||||
_maxTimeControlEntryCount = _preferences->getUInt(preference_lock_max_timecontrol_entry_count);
|
||||
_maxAuthEntryCount = _preferences->getUInt(preference_lock_max_auth_entry_count);
|
||||
_restartBeaconTimeout = _preferences->getInt(preference_restart_ble_beacon_lost);
|
||||
_hassEnabled = _preferences->getString(preference_mqtt_hass_discovery) != "";
|
||||
_nrOfRetries = _preferences->getInt(preference_command_nr_of_retries, 200);
|
||||
@@ -262,7 +264,6 @@ void NukiWrapper::update()
|
||||
cmdResult = _nukiLock.lockAction(_nextLockAction, 0, 0);
|
||||
char resultStr[15] = {0};
|
||||
NukiLock::cmdResultToString(cmdResult, resultStr);
|
||||
|
||||
_network->publishCommandResult(resultStr);
|
||||
|
||||
Log->print(F("Lock action result: "));
|
||||
@@ -344,6 +345,11 @@ void NukiWrapper::update()
|
||||
_waitTimeControlUpdateTs = 0;
|
||||
updateTimeControl(true);
|
||||
}
|
||||
if(_waitAuthUpdateTs != 0 && ts > _waitAuthUpdateTs)
|
||||
{
|
||||
_waitAuthUpdateTs = 0;
|
||||
updateAuth(true);
|
||||
}
|
||||
if(_hassEnabled && _nukiConfigValid && _nukiAdvancedConfigValid && _network->reconnected())
|
||||
{
|
||||
setupHASS();
|
||||
@@ -446,7 +452,6 @@ void NukiWrapper::updateKeyTurnerState()
|
||||
Log->print(_retryCount + 1);
|
||||
Log->print("): ");
|
||||
result =_nukiLock.requestKeyTurnerState(&_keyTurnerState);
|
||||
|
||||
if(result != Nuki::CmdResult::Success) {
|
||||
++_retryCount;
|
||||
}
|
||||
@@ -566,6 +571,7 @@ void NukiWrapper::updateConfig()
|
||||
_hardwareVersion = std::to_string(_nukiConfig.hardwareRevision[0]) + "." + std::to_string(_nukiConfig.hardwareRevision[1]);
|
||||
if(_preferences->getBool(preference_conf_info_enabled, true)) _network->publishConfig(_nukiConfig);
|
||||
if(_preferences->getBool(preference_timecontrol_info_enabled)) updateTimeControl(false);
|
||||
if(_preferences->getBool(preference_auth_info_enabled)) updateAuth(false);
|
||||
|
||||
const int pinStatus = _preferences->getInt(preference_lock_pin_status, 4);
|
||||
|
||||
@@ -577,7 +583,6 @@ void NukiWrapper::updateConfig()
|
||||
while(_retryCount < _nrOfRetries + 1)
|
||||
{
|
||||
result = _nukiLock.verifySecurityPin();
|
||||
|
||||
if(result != Nuki::CmdResult::Success) {
|
||||
++_retryCount;
|
||||
}
|
||||
@@ -665,7 +670,6 @@ void NukiWrapper::updateAuthData(bool retrieved)
|
||||
{
|
||||
Log->print(F("Retrieve log entries: "));
|
||||
result = _nukiLock.retrieveLogEntries(0, _preferences->getInt(preference_authlog_max_entries, MAX_AUTHLOG), 1, false);
|
||||
|
||||
if(result != Nuki::CmdResult::Success) {
|
||||
++_retryCount;
|
||||
}
|
||||
@@ -737,7 +741,6 @@ void NukiWrapper::updateKeypad(bool retrieved)
|
||||
{
|
||||
Log->print(F("Querying lock keypad: "));
|
||||
result = _nukiLock.retrieveKeypadEntries(0, _preferences->getInt(preference_keypad_max_entries, MAX_KEYPAD));
|
||||
|
||||
if(result != Nuki::CmdResult::Success) {
|
||||
++_retryCount;
|
||||
}
|
||||
@@ -802,9 +805,8 @@ void NukiWrapper::updateTimeControl(bool retrieved)
|
||||
|
||||
while(_retryCount < _nrOfRetries + 1)
|
||||
{
|
||||
Log->print(F("Querying lock time control: "));
|
||||
Log->print(F("Querying lock timecontrol: "));
|
||||
result = _nukiLock.retrieveTimeControlEntries();
|
||||
|
||||
if(result != Nuki::CmdResult::Success) {
|
||||
++_retryCount;
|
||||
}
|
||||
@@ -822,7 +824,7 @@ void NukiWrapper::updateTimeControl(bool retrieved)
|
||||
std::list<NukiLock::TimeControlEntry> timeControlEntries;
|
||||
_nukiLock.getTimeControlEntries(&timeControlEntries);
|
||||
|
||||
Log->print(F("Lock time control entries: "));
|
||||
Log->print(F("Lock timecontrol entries: "));
|
||||
Log->println(timeControlEntries.size());
|
||||
|
||||
timeControlEntries.sort([](const NukiLock::TimeControlEntry& a, const NukiLock::TimeControlEntry& b) { return a.entryId < b.entryId; });
|
||||
@@ -852,6 +854,67 @@ void NukiWrapper::updateTimeControl(bool retrieved)
|
||||
postponeBleWatchdog();
|
||||
}
|
||||
|
||||
void NukiWrapper::updateAuth(bool retrieved)
|
||||
{
|
||||
if(!_preferences->getBool(preference_auth_info_enabled)) return;
|
||||
|
||||
if(!retrieved)
|
||||
{
|
||||
Nuki::CmdResult result = (Nuki::CmdResult)-1;
|
||||
_retryCount = 0;
|
||||
|
||||
while(_retryCount < _nrOfRetries)
|
||||
{
|
||||
Log->print(F("Querying lock authorization: "));
|
||||
result = _nukiLock.retrieveAuthorizationEntries(0, _preferences->getInt(preference_auth_max_entries, MAX_AUTH));
|
||||
delay(250);
|
||||
if(result != Nuki::CmdResult::Success) {
|
||||
++_retryCount;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
printCommandResult(result);
|
||||
if(result == Nuki::CmdResult::Success)
|
||||
{
|
||||
_waitAuthUpdateTs = millis() + 5000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::list<NukiLock::AuthorizationEntry> authEntries;
|
||||
_nukiLock.getAuthorizationEntries(&authEntries);
|
||||
|
||||
Log->print(F("Lock authorization entries: "));
|
||||
Log->println(authEntries.size());
|
||||
|
||||
authEntries.sort([](const NukiLock::AuthorizationEntry& a, const NukiLock::AuthorizationEntry& b) { return a.authId < b.authId; });
|
||||
|
||||
if(authEntries.size() > _preferences->getInt(preference_auth_max_entries, MAX_AUTH))
|
||||
{
|
||||
authEntries.resize(_preferences->getInt(preference_auth_max_entries, MAX_AUTH));
|
||||
}
|
||||
|
||||
uint authCount = authEntries.size();
|
||||
if(authCount > _maxAuthEntryCount)
|
||||
{
|
||||
_maxAuthEntryCount = authCount;
|
||||
_preferences->putUInt(preference_lock_max_auth_entry_count, _maxAuthEntryCount);
|
||||
}
|
||||
|
||||
_network->publishAuth(authEntries, _maxAuthEntryCount);
|
||||
|
||||
_authIds.clear();
|
||||
_authIds.reserve(authEntries.size());
|
||||
for(const auto& entry : authEntries)
|
||||
{
|
||||
_authIds.push_back(entry.authId);
|
||||
}
|
||||
}
|
||||
|
||||
postponeBleWatchdog();
|
||||
}
|
||||
|
||||
void NukiWrapper::postponeBleWatchdog()
|
||||
{
|
||||
_disableBleWatchdogTs = (esp_timer_get_time() / 1000) + 15000;
|
||||
@@ -1725,6 +1788,11 @@ void NukiWrapper::onTimeControlCommandReceivedCallback(const char *value)
|
||||
nukiInst->onTimeControlCommandReceived(value);
|
||||
}
|
||||
|
||||
void NukiWrapper::onAuthCommandReceivedCallback(const char *value)
|
||||
{
|
||||
nukiInst->onAuthCommandReceived(value);
|
||||
}
|
||||
|
||||
void NukiWrapper::gpioActionCallback(const GpioAction &action, const int& pin)
|
||||
{
|
||||
switch(action)
|
||||
@@ -2436,7 +2504,7 @@ void NukiWrapper::onTimeControlCommandReceived(const char *value)
|
||||
if(idExists)
|
||||
{
|
||||
result = _nukiLock.removeTimeControlEntry(entryId);
|
||||
Log->print(F("Delete time control: "));
|
||||
Log->print(F("Delete timecontrol: "));
|
||||
Log->println((int)result);
|
||||
}
|
||||
else
|
||||
@@ -2495,7 +2563,7 @@ void NukiWrapper::onTimeControlCommandReceived(const char *value)
|
||||
entry.lockAction = timeControlLockAction;
|
||||
|
||||
result = _nukiLock.addTimeControlEntry(entry);
|
||||
Log->print(F("Add time control: "));
|
||||
Log->print(F("Add timecontrol: "));
|
||||
Log->println((int)result);
|
||||
}
|
||||
else if (strcmp(action, "update") == 0)
|
||||
@@ -2533,13 +2601,13 @@ void NukiWrapper::onTimeControlCommandReceived(const char *value)
|
||||
|
||||
if(!foundExisting)
|
||||
{
|
||||
_network->publishTimeControlCommandResult("failedToRetrieveExistingKeypadEntry");
|
||||
_network->publishTimeControlCommandResult("failedToRetrieveExistingTimeControlEntry");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishTimeControlCommandResult("failedToRetrieveExistingKeypadEntry");
|
||||
_network->publishTimeControlCommandResult("failedToRetrieveExistingTimeControlEntry");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2558,7 +2626,7 @@ void NukiWrapper::onTimeControlCommandReceived(const char *value)
|
||||
entry.lockAction = timeControlLockAction;
|
||||
|
||||
result = _nukiLock.updateTimeControlEntry(entry);
|
||||
Log->print(F("Update time control: "));
|
||||
Log->print(F("Update timecontrol: "));
|
||||
Log->println((int)result);
|
||||
}
|
||||
}
|
||||
@@ -2591,6 +2659,467 @@ void NukiWrapper::onTimeControlCommandReceived(const char *value)
|
||||
}
|
||||
}
|
||||
|
||||
void NukiWrapper::onAuthCommandReceived(const char *value)
|
||||
{
|
||||
if(!_nukiConfigValid)
|
||||
{
|
||||
_network->publishAuthCommandResult("configNotReady");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!isPinValid())
|
||||
{
|
||||
_network->publishAuthCommandResult("noValidPinSet");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!_preferences->getBool(preference_auth_control_enabled))
|
||||
{
|
||||
_network->publishAuthCommandResult("keypadControlDisabled");
|
||||
return;
|
||||
}
|
||||
|
||||
JsonDocument json;
|
||||
DeserializationError jsonError = deserializeJson(json, value);
|
||||
|
||||
if(jsonError)
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidJson");
|
||||
return;
|
||||
}
|
||||
|
||||
char oldName[33];
|
||||
const char *action = json["action"].as<const char*>();
|
||||
uint16_t authId = json["authId"].as<unsigned int>();
|
||||
//uint8_t idType = json["idType"].as<unsigned int>();
|
||||
//unsigned char secretKeyK[32] = {0x00};
|
||||
uint8_t remoteAllowed;
|
||||
uint8_t enabled;
|
||||
uint8_t timeLimited;
|
||||
String name;
|
||||
//String sharedKey;
|
||||
String allowedFrom;
|
||||
String allowedUntil;
|
||||
String allowedWeekdays;
|
||||
String allowedFromTime;
|
||||
String allowedUntilTime;
|
||||
|
||||
if(json.containsKey("remoteAllowed")) remoteAllowed = json["remoteAllowed"].as<unsigned int>();
|
||||
else remoteAllowed = 2;
|
||||
|
||||
if(json.containsKey("enabled")) enabled = json["enabled"].as<unsigned int>();
|
||||
else enabled = 2;
|
||||
|
||||
if(json.containsKey("timeLimited")) timeLimited = json["timeLimited"].as<unsigned int>();
|
||||
else timeLimited = 2;
|
||||
|
||||
if(json.containsKey("name")) name = json["name"].as<String>();
|
||||
//if(json.containsKey("sharedKey")) sharedKey = json["sharedKey"].as<String>();
|
||||
if(json.containsKey("allowedFrom")) allowedFrom = json["allowedFrom"].as<String>();
|
||||
if(json.containsKey("allowedUntil")) allowedUntil = json["allowedUntil"].as<String>();
|
||||
if(json.containsKey("allowedWeekdays")) allowedWeekdays = json["allowedWeekdays"].as<String>();
|
||||
if(json.containsKey("allowedFromTime")) allowedFromTime = json["allowedFromTime"].as<String>();
|
||||
if(json.containsKey("allowedUntilTime")) allowedUntilTime = json["allowedUntilTime"].as<String>();
|
||||
|
||||
if(action)
|
||||
{
|
||||
bool idExists = false;
|
||||
|
||||
if(authId)
|
||||
{
|
||||
idExists = std::find(_authIds.begin(), _authIds.end(), authId) != _authIds.end();
|
||||
}
|
||||
|
||||
Nuki::CmdResult result = (Nuki::CmdResult)-1;
|
||||
_retryCount = 0;
|
||||
|
||||
while(_retryCount < _nrOfRetries)
|
||||
{
|
||||
if(strcmp(action, "delete") == 0) {
|
||||
if(idExists)
|
||||
{
|
||||
result = _nukiLock.deleteAuthorizationEntry(authId);
|
||||
delay(250);
|
||||
Log->print(F("Delete authorization: "));
|
||||
Log->println((int)result);
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishAuthCommandResult("noExistingAuthIdSet");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(strcmp(action, "add") == 0 || strcmp(action, "update") == 0)
|
||||
{
|
||||
if(name.length() < 1)
|
||||
{
|
||||
if (strcmp(action, "update") != 0)
|
||||
{
|
||||
_network->publishAuthCommandResult("noNameSet");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if(sharedKey.length() != 64)
|
||||
{
|
||||
if (strcmp(action, "update") != 0)
|
||||
{
|
||||
_network->publishAuthCommandResult("noSharedKeySet");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i=0; i<sharedKey.length();i+=2) secretKeyK[(i/2)] = std::stoi(sharedKey.substring(i, i+2).c_str(), nullptr, 16);
|
||||
}
|
||||
*/
|
||||
|
||||
unsigned int allowedFromAr[6];
|
||||
unsigned int allowedUntilAr[6];
|
||||
unsigned int allowedFromTimeAr[2];
|
||||
unsigned int allowedUntilTimeAr[2];
|
||||
uint8_t allowedWeekdaysInt = 0;
|
||||
|
||||
if(timeLimited == 1)
|
||||
{
|
||||
if(allowedFrom.length() > 0)
|
||||
{
|
||||
if(allowedFrom.length() == 19)
|
||||
{
|
||||
allowedFromAr[0] = (uint16_t)allowedFrom.substring(0, 4).toInt();
|
||||
allowedFromAr[1] = (uint8_t)allowedFrom.substring(5, 7).toInt();
|
||||
allowedFromAr[2] = (uint8_t)allowedFrom.substring(8, 10).toInt();
|
||||
allowedFromAr[3] = (uint8_t)allowedFrom.substring(11, 13).toInt();
|
||||
allowedFromAr[4] = (uint8_t)allowedFrom.substring(14, 16).toInt();
|
||||
allowedFromAr[5] = (uint8_t)allowedFrom.substring(17, 19).toInt();
|
||||
|
||||
if(allowedFromAr[0] < 2000 || allowedFromAr[0] > 3000 || allowedFromAr[1] < 1 || allowedFromAr[1] > 12 || allowedFromAr[2] < 1 || allowedFromAr[2] > 31 || allowedFromAr[3] < 0 || allowedFromAr[3] > 23 || allowedFromAr[4] < 0 || allowedFromAr[4] > 59 || allowedFromAr[5] < 0 || allowedFromAr[5] > 59)
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidAllowedFrom");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidAllowedFrom");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(allowedUntil.length() > 0)
|
||||
{
|
||||
if(allowedUntil.length() > 0 == 19)
|
||||
{
|
||||
allowedUntilAr[0] = (uint16_t)allowedUntil.substring(0, 4).toInt();
|
||||
allowedUntilAr[1] = (uint8_t)allowedUntil.substring(5, 7).toInt();
|
||||
allowedUntilAr[2] = (uint8_t)allowedUntil.substring(8, 10).toInt();
|
||||
allowedUntilAr[3] = (uint8_t)allowedUntil.substring(11, 13).toInt();
|
||||
allowedUntilAr[4] = (uint8_t)allowedUntil.substring(14, 16).toInt();
|
||||
allowedUntilAr[5] = (uint8_t)allowedUntil.substring(17, 19).toInt();
|
||||
|
||||
if(allowedUntilAr[0] < 2000 || allowedUntilAr[0] > 3000 || allowedUntilAr[1] < 1 || allowedUntilAr[1] > 12 || allowedUntilAr[2] < 1 || allowedUntilAr[2] > 31 || allowedUntilAr[3] < 0 || allowedUntilAr[3] > 23 || allowedUntilAr[4] < 0 || allowedUntilAr[4] > 59 || allowedUntilAr[5] < 0 || allowedUntilAr[5] > 59)
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidAllowedUntil");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidAllowedUntil");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(allowedFromTime.length() > 0)
|
||||
{
|
||||
if(allowedFromTime.length() == 5)
|
||||
{
|
||||
allowedFromTimeAr[0] = (uint8_t)allowedFromTime.substring(0, 2).toInt();
|
||||
allowedFromTimeAr[1] = (uint8_t)allowedFromTime.substring(3, 5).toInt();
|
||||
|
||||
if(allowedFromTimeAr[0] < 0 || allowedFromTimeAr[0] > 23 || allowedFromTimeAr[1] < 0 || allowedFromTimeAr[1] > 59)
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidAllowedFromTime");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidAllowedFromTime");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(allowedUntilTime.length() > 0)
|
||||
{
|
||||
if(allowedUntilTime.length() == 5)
|
||||
{
|
||||
allowedUntilTimeAr[0] = (uint8_t)allowedUntilTime.substring(0, 2).toInt();
|
||||
allowedUntilTimeAr[1] = (uint8_t)allowedUntilTime.substring(3, 5).toInt();
|
||||
|
||||
if(allowedUntilTimeAr[0] < 0 || allowedUntilTimeAr[0] > 23 || allowedUntilTimeAr[1] < 0 || allowedUntilTimeAr[1] > 59)
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidAllowedUntilTime");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidAllowedUntilTime");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(allowedWeekdays.indexOf("mon") >= 0) allowedWeekdaysInt += 64;
|
||||
if(allowedWeekdays.indexOf("tue") >= 0) allowedWeekdaysInt += 32;
|
||||
if(allowedWeekdays.indexOf("wed") >= 0) allowedWeekdaysInt += 16;
|
||||
if(allowedWeekdays.indexOf("thu") >= 0) allowedWeekdaysInt += 8;
|
||||
if(allowedWeekdays.indexOf("fri") >= 0) allowedWeekdaysInt += 4;
|
||||
if(allowedWeekdays.indexOf("sat") >= 0) allowedWeekdaysInt += 2;
|
||||
if(allowedWeekdays.indexOf("sun") >= 0) allowedWeekdaysInt += 1;
|
||||
}
|
||||
|
||||
if(strcmp(action, "add") == 0)
|
||||
{
|
||||
_network->publishAuthCommandResult("addActionNotSupported");
|
||||
return;
|
||||
|
||||
NukiLock::NewAuthorizationEntry entry;
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
size_t nameLen = name.length();
|
||||
memcpy(&entry.name, name.c_str(), nameLen > 32 ? 32 : nameLen);
|
||||
/*
|
||||
memcpy(&entry.sharedKey, secretKeyK, 32);
|
||||
|
||||
if(idType != 1)
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidIdType");
|
||||
return;
|
||||
}
|
||||
|
||||
entry.idType = idType;
|
||||
*/
|
||||
entry.remoteAllowed = remoteAllowed == 1 ? 1 : 0;
|
||||
entry.timeLimited = timeLimited == 1 ? 1 : 0;
|
||||
|
||||
if(allowedFrom.length() > 0)
|
||||
{
|
||||
entry.allowedFromYear = allowedFromAr[0];
|
||||
entry.allowedFromMonth = allowedFromAr[1];
|
||||
entry.allowedFromDay = allowedFromAr[2];
|
||||
entry.allowedFromHour = allowedFromAr[3];
|
||||
entry.allowedFromMinute = allowedFromAr[4];
|
||||
entry.allowedFromSecond = allowedFromAr[5];
|
||||
}
|
||||
|
||||
if(allowedUntil.length() > 0)
|
||||
{
|
||||
entry.allowedUntilYear = allowedUntilAr[0];
|
||||
entry.allowedUntilMonth = allowedUntilAr[1];
|
||||
entry.allowedUntilDay = allowedUntilAr[2];
|
||||
entry.allowedUntilHour = allowedUntilAr[3];
|
||||
entry.allowedUntilMinute = allowedUntilAr[4];
|
||||
entry.allowedUntilSecond = allowedUntilAr[5];
|
||||
}
|
||||
|
||||
entry.allowedWeekdays = allowedWeekdaysInt;
|
||||
|
||||
if(allowedFromTime.length() > 0)
|
||||
{
|
||||
entry.allowedFromTimeHour = allowedFromTimeAr[0];
|
||||
entry.allowedFromTimeMin = allowedFromTimeAr[1];
|
||||
}
|
||||
|
||||
if(allowedUntilTime.length() > 0)
|
||||
{
|
||||
entry.allowedUntilTimeHour = allowedUntilTimeAr[0];
|
||||
entry.allowedUntilTimeMin = allowedUntilTimeAr[1];
|
||||
}
|
||||
|
||||
result = _nukiLock.addAuthorizationEntry(entry);
|
||||
delay(250);
|
||||
Log->print(F("Add authorization: "));
|
||||
Log->println((int)result);
|
||||
}
|
||||
else if (strcmp(action, "update") == 0)
|
||||
{
|
||||
if(!authId)
|
||||
{
|
||||
_network->publishAuthCommandResult("noAuthIdSet");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!idExists)
|
||||
{
|
||||
_network->publishAuthCommandResult("noExistingAuthIdSet");
|
||||
return;
|
||||
}
|
||||
|
||||
Nuki::CmdResult resultAuth = _nukiLock.retrieveAuthorizationEntries(0, _preferences->getInt(preference_auth_max_entries, MAX_AUTH));
|
||||
delay(250);
|
||||
bool foundExisting = false;
|
||||
|
||||
if(resultAuth == Nuki::CmdResult::Success)
|
||||
{
|
||||
std::list<NukiLock::AuthorizationEntry> entries;
|
||||
_nukiLock.getAuthorizationEntries(&entries);
|
||||
|
||||
for(const auto& entry : entries)
|
||||
{
|
||||
if (authId != entry.authId) continue;
|
||||
else foundExisting = true;
|
||||
|
||||
if(name.length() < 1)
|
||||
{
|
||||
memset(oldName, 0, sizeof(oldName));
|
||||
memcpy(oldName, entry.name, sizeof(entry.name));
|
||||
}
|
||||
if(remoteAllowed == 2) remoteAllowed = entry.remoteAllowed;
|
||||
if(enabled == 2) enabled = entry.enabled;
|
||||
if(timeLimited == 2) timeLimited = entry.timeLimited;
|
||||
if(allowedFrom.length() < 1)
|
||||
{
|
||||
allowedFrom = "old";
|
||||
allowedFromAr[0] = entry.allowedFromYear;
|
||||
allowedFromAr[1] = entry.allowedFromMonth;
|
||||
allowedFromAr[2] = entry.allowedFromDay;
|
||||
allowedFromAr[3] = entry.allowedFromHour;
|
||||
allowedFromAr[4] = entry.allowedFromMinute;
|
||||
allowedFromAr[5] = entry.allowedFromSecond;
|
||||
}
|
||||
if(allowedUntil.length() < 1)
|
||||
{
|
||||
allowedUntil = "old";
|
||||
allowedUntilAr[0] = entry.allowedUntilYear;
|
||||
allowedUntilAr[1] = entry.allowedUntilMonth;
|
||||
allowedUntilAr[2] = entry.allowedUntilDay;
|
||||
allowedUntilAr[3] = entry.allowedUntilHour;
|
||||
allowedUntilAr[4] = entry.allowedUntilMinute;
|
||||
allowedUntilAr[5] = entry.allowedUntilSecond;
|
||||
}
|
||||
if(allowedWeekdays.length() < 1) allowedWeekdaysInt = entry.allowedWeekdays;
|
||||
if(allowedFromTime.length() < 1)
|
||||
{
|
||||
allowedFromTime = "old";
|
||||
allowedFromTimeAr[0] = entry.allowedFromTimeHour;
|
||||
allowedFromTimeAr[1] = entry.allowedFromTimeMin;
|
||||
}
|
||||
|
||||
if(allowedUntilTime.length() < 1)
|
||||
{
|
||||
allowedUntilTime = "old";
|
||||
allowedUntilTimeAr[0] = entry.allowedUntilTimeHour;
|
||||
allowedUntilTimeAr[1] = entry.allowedUntilTimeMin;
|
||||
}
|
||||
}
|
||||
|
||||
if(!foundExisting)
|
||||
{
|
||||
_network->publishAuthCommandResult("failedToRetrieveExistingAuthorizationEntry");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishAuthCommandResult("failedToRetrieveExistingAuthorizationEntry");
|
||||
return;
|
||||
}
|
||||
|
||||
NukiLock::UpdatedAuthorizationEntry entry;
|
||||
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
entry.authId = authId;
|
||||
|
||||
if(name.length() < 1)
|
||||
{
|
||||
size_t nameLen = strlen(oldName);
|
||||
memcpy(&entry.name, oldName, nameLen > 20 ? 20 : nameLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t nameLen = name.length();
|
||||
memcpy(&entry.name, name.c_str(), nameLen > 20 ? 20 : nameLen);
|
||||
}
|
||||
entry.remoteAllowed = remoteAllowed;
|
||||
entry.enabled = enabled;
|
||||
entry.timeLimited = timeLimited;
|
||||
|
||||
if(enabled == 1)
|
||||
{
|
||||
if(timeLimited == 1)
|
||||
{
|
||||
if(allowedFrom.length() > 0)
|
||||
{
|
||||
entry.allowedFromYear = allowedFromAr[0];
|
||||
entry.allowedFromMonth = allowedFromAr[1];
|
||||
entry.allowedFromDay = allowedFromAr[2];
|
||||
entry.allowedFromHour = allowedFromAr[3];
|
||||
entry.allowedFromMinute = allowedFromAr[4];
|
||||
entry.allowedFromSecond = allowedFromAr[5];
|
||||
}
|
||||
|
||||
if(allowedUntil.length() > 0)
|
||||
{
|
||||
entry.allowedUntilYear = allowedUntilAr[0];
|
||||
entry.allowedUntilMonth = allowedUntilAr[1];
|
||||
entry.allowedUntilDay = allowedUntilAr[2];
|
||||
entry.allowedUntilHour = allowedUntilAr[3];
|
||||
entry.allowedUntilMinute = allowedUntilAr[4];
|
||||
entry.allowedUntilSecond = allowedUntilAr[5];
|
||||
}
|
||||
|
||||
entry.allowedWeekdays = allowedWeekdaysInt;
|
||||
|
||||
if(allowedFromTime.length() > 0)
|
||||
{
|
||||
entry.allowedFromTimeHour = allowedFromTimeAr[0];
|
||||
entry.allowedFromTimeMin = allowedFromTimeAr[1];
|
||||
}
|
||||
|
||||
if(allowedUntilTime.length() > 0)
|
||||
{
|
||||
entry.allowedUntilTimeHour = allowedUntilTimeAr[0];
|
||||
entry.allowedUntilTimeMin = allowedUntilTimeAr[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result = _nukiLock.updateAuthorizationEntry(entry);
|
||||
delay(250);
|
||||
Log->print(F("Update authorization: "));
|
||||
Log->println((int)result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishAuthCommandResult("invalidAction");
|
||||
return;
|
||||
}
|
||||
|
||||
if(result != Nuki::CmdResult::Success) {
|
||||
++_retryCount;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
updateAuth(false);
|
||||
|
||||
if((int)result != -1)
|
||||
{
|
||||
char resultStr[15];
|
||||
memset(&resultStr, 0, sizeof(resultStr));
|
||||
NukiLock::cmdResultToString(result, resultStr);
|
||||
_network->publishAuthCommandResult(resultStr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishAuthCommandResult("noActionSet");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const NukiLock::KeyTurnerState &NukiWrapper::keyTurnerState()
|
||||
{
|
||||
return _keyTurnerState;
|
||||
|
||||
Reference in New Issue
Block a user