Auth log
This commit is contained in:
@@ -200,6 +200,7 @@ In a browser navigate to the IP address assigned to the ESP32.
|
|||||||
- lock/trigger: The trigger of the last action: autoLock, automatic, button, manual, system.
|
- lock/trigger: The trigger of the last action: autoLock, automatic, button, manual, system.
|
||||||
- lock/lastLockAction: Reports the last lock action as a string. Possible values are: Unlock, Lock, Unlatch, LockNgo, LockNgoUnlatch, FullLock, FobAction1, FobAction2, FobAction3, Unknown.
|
- lock/lastLockAction: Reports the last lock action as a string. Possible values are: Unlock, Lock, Unlatch, LockNgo, LockNgoUnlatch, FullLock, FobAction1, FobAction2, FobAction3, Unknown.
|
||||||
- lock/log: If "Publish auth data" is enabled in the web interface, this topic will be filled with the log of authorization data.
|
- lock/log: If "Publish auth data" is enabled in the web interface, this topic will be filled with the log of authorization data.
|
||||||
|
- lock/shortLog: If "Publish auth data" is enabled in the web interface, this topic will be filled with the 3 most recent entries in the log of authorization data, updates faster than lock/log.
|
||||||
- lock/completionStatus: Status of the last action as reported by Nuki Lock: success, motorBlocked, canceled, tooRecent, busy, lowMotorVoltage, clutchFailure, motorPowerFailure, incompleteFailure, invalidCode, otherError, unknown.
|
- lock/completionStatus: Status of the last action as reported by Nuki Lock: success, motorBlocked, canceled, tooRecent, busy, lowMotorVoltage, clutchFailure, motorPowerFailure, incompleteFailure, invalidCode, otherError, unknown.
|
||||||
- lock/authorizationId: If enabled in the web interface, this node returns the authorization id of the last lock action.
|
- lock/authorizationId: If enabled in the web interface, this node returns the authorization id of the last lock action.
|
||||||
- lock/authorizationName: If enabled in the web interface, this node returns the authorization name of the last lock action.
|
- lock/authorizationName: If enabled in the web interface, this node returns the authorization name of the last lock action.
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#define mqtt_topic_lock_trigger "/lock/trigger"
|
#define mqtt_topic_lock_trigger "/lock/trigger"
|
||||||
#define mqtt_topic_lock_last_lock_action "/lock/lastLockAction"
|
#define mqtt_topic_lock_last_lock_action "/lock/lastLockAction"
|
||||||
#define mqtt_topic_lock_log "/lock/log"
|
#define mqtt_topic_lock_log "/lock/log"
|
||||||
|
#define mqtt_topic_lock_log_latest "/lock/shortLog"
|
||||||
#define mqtt_topic_lock_auth_id "/lock/authorizationId"
|
#define mqtt_topic_lock_auth_id "/lock/authorizationId"
|
||||||
#define mqtt_topic_lock_auth_name "/lock/authorizationName"
|
#define mqtt_topic_lock_auth_name "/lock/authorizationName"
|
||||||
#define mqtt_topic_lock_completionStatus "/lock/completionStatus"
|
#define mqtt_topic_lock_completionStatus "/lock/completionStatus"
|
||||||
|
|||||||
@@ -429,83 +429,79 @@ void NetworkLock::publishAuthorizationInfo(const std::list<NukiLock::LogEntry>&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!latest)
|
auto entry = json.add<JsonVariant>();
|
||||||
|
|
||||||
|
entry["index"] = log.index;
|
||||||
|
entry["authorizationId"] = log.authId;
|
||||||
|
entry["authorizationName"] = authName;
|
||||||
|
entry["timeYear"] = log.timeStampYear;
|
||||||
|
entry["timeMonth"] = log.timeStampMonth;
|
||||||
|
entry["timeDay"] = log.timeStampDay;
|
||||||
|
entry["timeHour"] = log.timeStampHour;
|
||||||
|
entry["timeMinute"] = log.timeStampMinute;
|
||||||
|
entry["timeSecond"] = log.timeStampSecond;
|
||||||
|
|
||||||
|
memset(str, 0, sizeof(str));
|
||||||
|
loggingTypeToString(log.loggingType, str);
|
||||||
|
entry["type"] = str;
|
||||||
|
|
||||||
|
switch(log.loggingType)
|
||||||
{
|
{
|
||||||
auto entry = json.add<JsonVariant>();
|
case NukiLock::LoggingType::LockAction:
|
||||||
|
memset(str, 0, sizeof(str));
|
||||||
|
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
|
||||||
|
entry["action"] = str;
|
||||||
|
|
||||||
entry["index"] = log.index;
|
memset(str, 0, sizeof(str));
|
||||||
entry["authorizationId"] = log.authId;
|
NukiLock::triggerToString((NukiLock::Trigger)log.data[1], str);
|
||||||
entry["authorizationName"] = authName;
|
entry["trigger"] = str;
|
||||||
entry["timeYear"] = log.timeStampYear;
|
|
||||||
entry["timeMonth"] = log.timeStampMonth;
|
|
||||||
entry["timeDay"] = log.timeStampDay;
|
|
||||||
entry["timeHour"] = log.timeStampHour;
|
|
||||||
entry["timeMinute"] = log.timeStampMinute;
|
|
||||||
entry["timeSecond"] = log.timeStampSecond;
|
|
||||||
|
|
||||||
memset(str, 0, sizeof(str));
|
memset(str, 0, sizeof(str));
|
||||||
loggingTypeToString(log.loggingType, str);
|
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[3], str);
|
||||||
entry["type"] = str;
|
entry["completionStatus"] = str;
|
||||||
|
entry["completionStatusVal"] = log.data[3];
|
||||||
|
break;
|
||||||
|
case NukiLock::LoggingType::KeypadAction:
|
||||||
|
memset(str, 0, sizeof(str));
|
||||||
|
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
|
||||||
|
entry["action"] = str;
|
||||||
|
|
||||||
switch(log.loggingType)
|
memset(str, 0, sizeof(str));
|
||||||
{
|
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[2], str);
|
||||||
case NukiLock::LoggingType::LockAction:
|
entry["completionStatus"] = str;
|
||||||
memset(str, 0, sizeof(str));
|
entry["completionStatusVal"] = log.data[2];
|
||||||
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
|
break;
|
||||||
entry["action"] = str;
|
case NukiLock::LoggingType::DoorSensor:
|
||||||
|
memset(str, 0, sizeof(str));
|
||||||
|
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
|
||||||
|
|
||||||
memset(str, 0, sizeof(str));
|
switch(log.data[0])
|
||||||
NukiLock::triggerToString((NukiLock::Trigger)log.data[1], str);
|
{
|
||||||
entry["trigger"] = str;
|
case 0:
|
||||||
|
entry["action"] = "DoorOpened";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
entry["action"] = "DoorClosed";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
entry["action"] = "SensorJammed";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
entry["action"] = "Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
memset(str, 0, sizeof(str));
|
memset(str, 0, sizeof(str));
|
||||||
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[3], str);
|
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[2], str);
|
||||||
entry["completionStatus"] = str;
|
entry["completionStatus"] = str;
|
||||||
entry["completionStatusVal"] = log.data[3];
|
break;
|
||||||
break;
|
|
||||||
case NukiLock::LoggingType::KeypadAction:
|
|
||||||
memset(str, 0, sizeof(str));
|
|
||||||
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
|
|
||||||
entry["action"] = str;
|
|
||||||
|
|
||||||
memset(str, 0, sizeof(str));
|
|
||||||
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[2], str);
|
|
||||||
entry["completionStatus"] = str;
|
|
||||||
entry["completionStatusVal"] = log.data[2];
|
|
||||||
break;
|
|
||||||
case NukiLock::LoggingType::DoorSensor:
|
|
||||||
memset(str, 0, sizeof(str));
|
|
||||||
NukiLock::lockactionToString((NukiLock::LockAction)log.data[0], str);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(str, 0, sizeof(str));
|
|
||||||
NukiLock::completionStatusToString((NukiLock::CompletionStatus)log.data[2], str);
|
|
||||||
entry["completionStatus"] = str;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!latest)
|
serializeJson(json, _buffer, _bufferSize);
|
||||||
{
|
|
||||||
serializeJson(json, _buffer, _bufferSize);
|
if(latest) publishString(mqtt_topic_lock_log_latest, _buffer);
|
||||||
publishString(mqtt_topic_lock_log, _buffer);
|
else publishString(mqtt_topic_lock_log, _buffer);
|
||||||
}
|
|
||||||
|
|
||||||
if(authFound)
|
if(authFound)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -398,106 +398,102 @@ void NetworkOpener::publishAuthorizationInfo(const std::list<NukiOpener::LogEntr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!latest)
|
auto entry = json.add<JsonVariant>();
|
||||||
|
|
||||||
|
entry["index"] = log.index;
|
||||||
|
entry["authorizationId"] = log.authId;
|
||||||
|
entry["authorizationName"] = _authName;
|
||||||
|
entry["timeYear"] = log.timeStampYear;
|
||||||
|
entry["timeMonth"] = log.timeStampMonth;
|
||||||
|
entry["timeDay"] = log.timeStampDay;
|
||||||
|
entry["timeHour"] = log.timeStampHour;
|
||||||
|
entry["timeMinute"] = log.timeStampMinute;
|
||||||
|
entry["timeSecond"] = log.timeStampSecond;
|
||||||
|
|
||||||
|
memset(str, 0, sizeof(str));
|
||||||
|
loggingTypeToString(log.loggingType, str);
|
||||||
|
entry["type"] = str;
|
||||||
|
|
||||||
|
switch(log.loggingType)
|
||||||
{
|
{
|
||||||
auto entry = json.add<JsonVariant>();
|
case NukiOpener::LoggingType::LockAction:
|
||||||
|
memset(str, 0, sizeof(str));
|
||||||
|
NukiOpener::lockactionToString((NukiOpener::LockAction)log.data[0], str);
|
||||||
|
entry["action"] = str;
|
||||||
|
|
||||||
entry["index"] = log.index;
|
memset(str, 0, sizeof(str));
|
||||||
entry["authorizationId"] = log.authId;
|
NukiOpener::triggerToString((NukiOpener::Trigger)log.data[1], str);
|
||||||
entry["authorizationName"] = _authName;
|
entry["trigger"] = str;
|
||||||
entry["timeYear"] = log.timeStampYear;
|
|
||||||
entry["timeMonth"] = log.timeStampMonth;
|
|
||||||
entry["timeDay"] = log.timeStampDay;
|
|
||||||
entry["timeHour"] = log.timeStampHour;
|
|
||||||
entry["timeMinute"] = log.timeStampMinute;
|
|
||||||
entry["timeSecond"] = log.timeStampSecond;
|
|
||||||
|
|
||||||
memset(str, 0, sizeof(str));
|
memset(str, 0, sizeof(str));
|
||||||
loggingTypeToString(log.loggingType, str);
|
NukiOpener::completionStatusToString((NukiOpener::CompletionStatus)log.data[3], str);
|
||||||
entry["type"] = str;
|
entry["completionStatus"] = str;
|
||||||
|
break;
|
||||||
|
case NukiOpener::LoggingType::KeypadAction:
|
||||||
|
memset(str, 0, sizeof(str));
|
||||||
|
NukiOpener::lockactionToString((NukiOpener::LockAction)log.data[0], str);
|
||||||
|
entry["action"] = str;
|
||||||
|
|
||||||
switch(log.loggingType)
|
memset(str, 0, sizeof(str));
|
||||||
{
|
NukiOpener::completionStatusToString((NukiOpener::CompletionStatus)log.data[2], str);
|
||||||
case NukiOpener::LoggingType::LockAction:
|
entry["completionStatus"] = str;
|
||||||
memset(str, 0, sizeof(str));
|
break;
|
||||||
NukiOpener::lockactionToString((NukiOpener::LockAction)log.data[0], str);
|
case NukiOpener::LoggingType::DoorbellRecognition:
|
||||||
entry["action"] = str;
|
switch(log.data[0] & 3)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
entry["mode"] = "None";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
entry["mode"] = "RTO";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
entry["mode"] = "CM";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
entry["mode"] = "Unknown";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
memset(str, 0, sizeof(str));
|
switch(log.data[1])
|
||||||
NukiOpener::triggerToString((NukiOpener::Trigger)log.data[1], str);
|
{
|
||||||
entry["trigger"] = str;
|
case 0:
|
||||||
|
entry["source"] = "Doorbell";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
entry["source"] = "Timecontrol";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
entry["source"] = "App";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
entry["source"] = "Button";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
entry["source"] = "Fob";
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
entry["source"] = "Bridge";
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
entry["source"] = "Keypad";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
entry["source"] = "Unknown";
|
||||||
|
break; }
|
||||||
|
|
||||||
memset(str, 0, sizeof(str));
|
entry["geofence"] = log.data[2] == 1 ? "active" : "inactive";
|
||||||
NukiOpener::completionStatusToString((NukiOpener::CompletionStatus)log.data[3], str);
|
entry["doorbellSuppression"] = log.data[3] == 1 ? "active" : "inactive";
|
||||||
entry["completionStatus"] = str;
|
entry["completionStatus"] = str;
|
||||||
break;
|
|
||||||
case NukiOpener::LoggingType::KeypadAction:
|
|
||||||
memset(str, 0, sizeof(str));
|
|
||||||
NukiOpener::lockactionToString((NukiOpener::LockAction)log.data[0], str);
|
|
||||||
entry["action"] = str;
|
|
||||||
|
|
||||||
memset(str, 0, sizeof(str));
|
break;
|
||||||
NukiOpener::completionStatusToString((NukiOpener::CompletionStatus)log.data[2], str);
|
|
||||||
entry["completionStatus"] = str;
|
|
||||||
break;
|
|
||||||
case NukiOpener::LoggingType::DoorbellRecognition:
|
|
||||||
switch(log.data[0] & 3)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
entry["mode"] = "None";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
entry["mode"] = "RTO";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
entry["mode"] = "CM";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
entry["mode"] = "Unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(log.data[1])
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
entry["source"] = "Doorbell";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
entry["source"] = "Timecontrol";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
entry["source"] = "App";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
entry["source"] = "Button";
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
entry["source"] = "Fob";
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
entry["source"] = "Bridge";
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
entry["source"] = "Keypad";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
entry["source"] = "Unknown";
|
|
||||||
break; }
|
|
||||||
|
|
||||||
entry["geofence"] = log.data[2] == 1 ? "active" : "inactive";
|
|
||||||
entry["doorbellSuppression"] = log.data[3] == 1 ? "active" : "inactive";
|
|
||||||
entry["completionStatus"] = str;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!latest)
|
serializeJson(json, _buffer, _bufferSize);
|
||||||
{
|
|
||||||
serializeJson(json, _buffer, _bufferSize);
|
if(latest) publishString(mqtt_topic_lock_log_latest, _buffer);
|
||||||
publishString(mqtt_topic_lock_log, _buffer);
|
else publishString(mqtt_topic_lock_log, _buffer);
|
||||||
}
|
|
||||||
|
|
||||||
if(authFound)
|
if(authFound)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -499,22 +499,28 @@ void NukiOpenerWrapper::updateAuthData(bool retrieved)
|
|||||||
|
|
||||||
if(!retrieved)
|
if(!retrieved)
|
||||||
{
|
{
|
||||||
Nuki::CmdResult result = _nukiOpener.retrieveLogEntries(0, 3, 1, false);
|
delay(250);
|
||||||
|
Nuki::CmdResult result = _nukiOpener.retrieveLogEntries(0, _preferences->getInt(preference_authlog_max_entries, MAX_AUTHLOG), 1, false);
|
||||||
Log->print(F("Retrieve log entries: "));
|
Log->print(F("Retrieve log entries: "));
|
||||||
Log->println(result);
|
Log->println(result);
|
||||||
printCommandResult(result);
|
printCommandResult(result);
|
||||||
if(result == Nuki::CmdResult::Success)
|
if(result == Nuki::CmdResult::Success)
|
||||||
{
|
{
|
||||||
Nuki::CmdResult result = _nukiOpener.retrieveLogEntries(0, _preferences->getInt(preference_authlog_max_entries, MAX_AUTHLOG), 1, false);
|
_waitAuthLogUpdateTs = millis() + 5000;
|
||||||
if(result == Nuki::CmdResult::Success)
|
delay(100);
|
||||||
{
|
|
||||||
_waitAuthLogUpdateTs = millis() + 5000;
|
|
||||||
}
|
|
||||||
delay(150);
|
|
||||||
|
|
||||||
std::list<NukiOpener::LogEntry> log;
|
std::list<NukiOpener::LogEntry> log;
|
||||||
_nukiOpener.getLogEntries(&log);
|
_nukiOpener.getLogEntries(&log);
|
||||||
_network->publishAuthorizationInfo(log, true);
|
|
||||||
|
if(log.size() > _preferences->getInt(preference_authlog_max_entries, 3))
|
||||||
|
{
|
||||||
|
log.resize(_preferences->getInt(preference_authlog_max_entries, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(log.size() > 0)
|
||||||
|
{
|
||||||
|
_network->publishAuthorizationInfo(log, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1734,7 +1740,7 @@ void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value)
|
|||||||
_network->publishKeypadJsonCommandResult("noExistingCodeIdSet");
|
_network->publishKeypadJsonCommandResult("noExistingCodeIdSet");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NukiOpener::UpdatedKeypadEntry entry;
|
NukiOpener::UpdatedKeypadEntry entry;
|
||||||
memset(&entry, 0, sizeof(entry));
|
memset(&entry, 0, sizeof(entry));
|
||||||
entry.codeId = codeId;
|
entry.codeId = codeId;
|
||||||
|
|||||||
@@ -480,22 +480,28 @@ void NukiWrapper::updateAuthData(bool retrieved)
|
|||||||
|
|
||||||
if(!retrieved)
|
if(!retrieved)
|
||||||
{
|
{
|
||||||
Nuki::CmdResult result = _nukiLock.retrieveLogEntries(0, 3, 1, false);
|
delay(250);
|
||||||
|
Nuki::CmdResult result = _nukiLock.retrieveLogEntries(0, _preferences->getInt(preference_authlog_max_entries, MAX_AUTHLOG), 1, false);
|
||||||
Log->print(F("Retrieve log entries: "));
|
Log->print(F("Retrieve log entries: "));
|
||||||
Log->println(result);
|
Log->println(result);
|
||||||
printCommandResult(result);
|
printCommandResult(result);
|
||||||
if(result == Nuki::CmdResult::Success)
|
if(result == Nuki::CmdResult::Success)
|
||||||
{
|
{
|
||||||
Nuki::CmdResult result = _nukiLock.retrieveLogEntries(0, _preferences->getInt(preference_authlog_max_entries, MAX_AUTHLOG), 1, false);
|
_waitAuthLogUpdateTs = millis() + 5000;
|
||||||
if(result == Nuki::CmdResult::Success)
|
delay(100);
|
||||||
{
|
|
||||||
_waitAuthLogUpdateTs = millis() + 5000;
|
|
||||||
}
|
|
||||||
delay(150);
|
|
||||||
|
|
||||||
std::list<NukiLock::LogEntry> log;
|
std::list<NukiLock::LogEntry> log;
|
||||||
_nukiLock.getLogEntries(&log);
|
_nukiLock.getLogEntries(&log);
|
||||||
_network->publishAuthorizationInfo(log, true);
|
|
||||||
|
if(log.size() > _preferences->getInt(preference_authlog_max_entries, 3))
|
||||||
|
{
|
||||||
|
log.resize(_preferences->getInt(preference_authlog_max_entries, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(log.size() > 0)
|
||||||
|
{
|
||||||
|
_network->publishAuthorizationInfo(log, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user