Skip to content

Commit

Permalink
Add Auth Log Processing
Browse files Browse the repository at this point in the history
  • Loading branch information
AzonInc committed Oct 24, 2024
1 parent 7cdecc5 commit a3f6543
Show file tree
Hide file tree
Showing 2 changed files with 204 additions and 1 deletion.
199 changes: 198 additions & 1 deletion components/nuki_lock/nuki_lock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ void NukiLockComponent::update_status()
this->door_sensor_state_text_sensor_->publish_state(this->nuki_doorsensor_to_string(this->retrievedKeyTurnerState_.doorSensorState));
#endif

this->auth_data_update_ = true;

if (
this->retrievedKeyTurnerState_.lockState == NukiLock::LockState::Locking
|| this->retrievedKeyTurnerState_.lockState == NukiLock::LockState::Unlocking
Expand Down Expand Up @@ -226,6 +228,191 @@ void NukiLockComponent::update_advanced_config() {
}
}

void NukiLockComponent::update_auth_data()
{
this->auth_data_update_ = false;

Nuki::CmdResult confReqResult = (Nuki::CmdResult)-1;
int retryCount = 0;
while(retryCount < 3)
{
ESP_LOGD(TAG, "Retrieve Auth Logs",);
confReqResult = this->nukiLock_.retrieveLogEntries(0, 3, 1, false);

if(confReqResult != Nuki::CmdResult::Success)
{
++retryCount;
}
else
{
break;
}
}

std::list<NukiLock::LogEntry> log;
this->nukiLock_.getLogEntries(&log);

if(log.size() > 3)
{
log.resize(3);
}

log.sort([](const NukiLock::LogEntry& a, const NukiLock::LogEntry& b)
{
return a.index < b.index;
});

if(log.size() > 0)
{
this->processLogEntries(log);
}
}

void NukiLockComponent::processLogEntries(const std::list<NukiLock::LogEntry>& logEntries)
{
char str[50];
char authName[33];
uint32_t authIndex = 0;

for(const auto& log : logEntries)
{
memset(authName, 0, sizeof(authName));
authName[0] = '\0';

if((log.loggingType == NukiLock::LoggingType::LockAction || log.loggingType == NukiLock::LoggingType::KeypadAction))
{
int sizeName = sizeof(log.name);
memcpy(authName, log.name, sizeName);
if(authName[sizeName - 1] != '\0')
{
authName[sizeName] = '\0';
}

if(log.index > authIndex)
{
authIndex = log.index;
this->auth_id_ = log.authId;

memset(_authName, 0, sizeof(_authName));
memcpy(_authName, authName, sizeof(authName));

if(authName[sizeName - 1] != '\0' && _authEntries.count(this->auth_id_) > 0)
{
memset(_authName, 0, sizeof(_authName));
memcpy(_authName, _authEntries[this->auth_id_].c_str(), sizeof(_authEntries[this->auth_id_].c_str()));
}
}
}

ESP_LOGD(TAG, "index: %i", log.index);
ESP_LOGD(TAG, "authorizationIdAuth ID: %i", log.authId);
if(entry["authorizationName"].as<String>().length() == 0 && _authEntries.count(log.authId) > 0)
{
ESP_LOGD(TAG, "authorizationName: %s", _authEntries[log.authId]);
}
else
{
ESP_LOGD(TAG, "authorizationName: %s", authName);
}

ESP_LOGD(TAG, "timeYear: %i", log.timeStampYear);
ESP_LOGD(TAG, "timeMonth: %i", log.timeStampMonth);
ESP_LOGD(TAG, "timeDay: %i", log.timeStampDay);
ESP_LOGD(TAG, "timeHour: %i", log.timeStampHour);
ESP_LOGD(TAG, "timeMinute: %i", log.timeStampMinute);
ESP_LOGD(TAG, "timeSecond: %i", log.timeStampSecond);

memset(str, 0, sizeof(str));
NukiLock::loggingTypeToString(log.loggingType, str);
ESP_LOGD(TAG, "type: %i", str);


/*
switch(log.loggingType)
{
case NukiLock::LoggingType::LockAction:
memset(str, 0, sizeof(str));
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
entry["action"] = str;
memset(str, 0, sizeof(str));
NukiLock::triggerToString((NukiLock::Trigger)log.data[1], str);
entry["trigger"] = str;
memset(str, 0, sizeof(str));
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[3], str);
entry["completionStatus"] = str;
break;
case NukiLock::LoggingType::KeypadAction:
memset(str, 0, sizeof(str));
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
entry["action"] = str;
switch(log.data[1])
{
case 0:
entry["trigger"] = "arrowkey";
break;
case 1:
entry["trigger"] = "code";
break;
case 2:
entry["trigger"] = "fingerprint";
break;
default:
entry["trigger"] = "Unknown";
break;
}
memset(str, 0, sizeof(str));
if(log.data[2] == 9)
{
entry["completionStatus"] = "notAuthorized";
}
else if (log.data[2] == 224)
{
entry["completionStatus"] = "invalidCode";
}
else
{
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[2], str);
entry["completionStatus"] = str;
}
entry["codeId"] = 256U*log.data[4]+log.data[3];
break;
case NukiLock::LoggingType::DoorSensor:
switch(log.data[0])
{
case 0:
entry["action"] = "DoorOpened";
break;
case 1:
entry["action"] = "DoorClosed";
break;
case 2:
entry["action"] = "SensorJammed";
break;
default:
entry["action"] = "Unknown";
break;
}
break;
}
if(log.index > _lastRollingLog)
{
_lastRollingLog = log.index;
serializeJson(entry, _buffer, _bufferSize);
publishString(mqtt_topic_lock_log_rolling, _buffer, true);
publishInt(mqtt_topic_lock_log_rolling_last, log.index, true);
}*/
}
}

bool NukiLockComponent::executeLockAction(NukiLock::LockAction lockAction) {
// Publish the assumed transitional lock state
switch (lockAction) {
Expand Down Expand Up @@ -296,6 +483,9 @@ void NukiLockComponent::setup() {

if (this->nukiLock_.isPairedWithLock()) {
this->status_update_ = true;
this->config_update_ = true;
this->advanced_config_update_ = true;
this->auth_data_update_ = true;
ESP_LOGI(TAG, "%s Nuki paired", this->deviceName_);
#ifdef USE_BINARY_SENSOR
this->is_paired_binary_sensor_->publish_initial_state(true);
Expand Down Expand Up @@ -346,7 +536,7 @@ void NukiLockComponent::update() {
#endif

// Execute (all) actions first, then status updates, then config updates.
// Only one command (action, status, or config) is executed per update() call.
// Only one command (action, status, config, or auth data) is executed per update() call.
if (this->actionAttempts_ > 0) {
this->actionAttempts_--;

Expand Down Expand Up @@ -395,6 +585,12 @@ void NukiLockComponent::update() {
ESP_LOGD(TAG, "Update present, getting advanced config...");
this->update_advanced_config();

command_cooldown_millis = COOLDOWN_COMMANDS_MILLIS;
lastCommandExecutedTime_ = millis();
} else if (this->auth_data_update_) {
ESP_LOGD(TAG, "Update present, getting auth data...");
this->update_auth_data();

command_cooldown_millis = COOLDOWN_COMMANDS_MILLIS;
lastCommandExecutedTime_ = millis();
}
Expand Down Expand Up @@ -627,6 +823,7 @@ void NukiLockComponent::notify(Nuki::EventType eventType) {
this->status_update_ = true;
this->config_update_ = true;
this->advanced_config_update_ = true;
this->auth_data_update_ = true;
ESP_LOGI(TAG, "event notified %d", eventType);
}

Expand Down
6 changes: 6 additions & 0 deletions components/nuki_lock/nuki_lock.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ class NukiLockComponent : public lock::Lock, public PollingComponent, public api
void update_status();
void update_config();
void update_advanced_config();

void update_auth_data();
void processLogEntries(const std::list<NukiLock::LogEntry>& logEntries);

bool executeLockAction(NukiLock::LockAction lockAction);

BleScanner::Scanner scanner_;
Expand All @@ -158,6 +162,7 @@ class NukiLockComponent : public lock::Lock, public PollingComponent, public api
bool status_update_;
bool config_update_;
bool advanced_config_update_;
bool auth_data_update_;
bool open_latch_;
bool lock_n_go_;

Expand All @@ -181,6 +186,7 @@ class NukiLockComponent : public lock::Lock, public PollingComponent, public api

std::vector<uint16_t> keypadCodeIds_;
bool keypad_paired_;
uint32_t auth_id_ = 0;
};

// Actions
Expand Down

0 comments on commit a3f6543

Please sign in to comment.