Merge pull request #365 from iranl/extend-keyturner

Extend keyturner state and publish Nuki device status updated
This commit is contained in:
Jan-Ole Schümann
2024-05-18 12:32:51 +07:00
committed by GitHub
8 changed files with 54 additions and 6 deletions

View File

@@ -191,9 +191,10 @@ In a browser navigate to the IP address assigned to the ESP32.
### Lock
- lock/action: Allows to execute lock actions. After receiving the action, the value is set to "ack". Possible actions: unlock, lock, unlatch, lockNgo, lockNgoUnlatch, fullLock, fobAction1, fobAction2, fobAction3.
- lock/statusUpdated: 1 when the Nuki Lock/Opener signals the KeyTurner state has been updated, resets to 0 when Nuki Hub has queried the updated state.
- lock/state: Reports the current lock state as a string. Possible values are: uncalibrated, locked, unlocked, unlatched, unlockedLnga, unlatching, bootRun, motorBlocked.
- lock/hastate: Reports the current lock state as a string, specifically for use by Home Assistant. Possible values are: locking, locked, unlocking, unlocked, jammed.
- lock/json: Reports the lock state, last action trigger, last lock action, lock completion status, door sensor state, auth ID and auth name as JSON data.
- lock/json: Reports the lock state, lockngo_state, trigger, current time, time zone offset, night mode state, last action trigger, last lock action, lock completion status, door sensor state, auth ID and auth name as JSON data.
- lock/binaryState: Reports the current lock state as a string, mostly for use by Home Assistant. Possible values are: locked, unlocked.
- 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.
@@ -205,14 +206,14 @@ In a browser navigate to the IP address assigned to the ESP32.
- lock/doorSensorState: State of the door sensor: unavailable, deactivated, doorClosed, doorOpened, doorStateUnknown, calibrating.
- lock/rssi: The signal strenght of the Nuki Lock as measured by the ESP32 and expressed by the RSSI Value in dBm.
- lock/address: The BLE address of the Nuki Lock.
- lock/retry: Reports the current number of retries for the current command. 0 when command is succesfull, "failed" if the number of retries is greater than the maximum configured number of retries.
- lock/retry: Reports the current number of retries for the current command. 0 when command is successful, "failed" if the number of retries is greater than the maximum configured number of retries.
### Opener
- lock/action: Allows to execute lock actions. After receiving the action, the value is set to "ack". Possible actions: activateRTO, deactivateRTO, electricStrikeActuation, activateCM, deactivateCM, fobAction1, fobAction2, fobAction3.
- lock/state: Reports the current lock state as a string. Possible values are: locked, RTOactive, open, opening, uncalibrated.
- lock/hastate: Reports the current lock state as a string, specifically for use by Home Assistant. Possible values are: locking, locked, unlocking, unlocked, jammed.
- lock/json: Reports the lock state, last action trigger, last lock action, lock completion status, door sensor state, auth ID and auth name as JSON data.
- lock/json: Reports the lock state, trigger, ring to open timer, current time, time zone offset, last action trigger, last lock action, lock completion status, door sensor state, auth ID and auth name as JSON data.
- lock/binaryState: Reports the current lock state as a string, mostly for use by Home Assistant. Possible values are: locked, unlocked.
- lock/continuousMode: Enable or disable continuous mode on the opener (0 = disabled; 1 = enabled).
- lock/ring: The string "ring" is published to this topic when a doorbell ring is detected while RTO or continuous mode is active or "ringlocked" when both are inactive.
@@ -227,7 +228,7 @@ In a browser navigate to the IP address assigned to the ESP32.
- lock/doorSensorState: State of the door sensor: unavailable, deactivated, doorClosed, doorOpened, doorStateUnknown, calibrating.
- lock/rssi: The bluetooth signal strength of the Nuki Lock as measured by the ESP32 and expressed by the RSSI Value in dBm.
- lock/address: The BLE address of the Nuki Lock.
- lock/retry: Reports the current number of retries for the current command. 0 when command is succesfull, "failed" if the number of retries is greater than the maximum configured number of retries.
- lock/retry: Reports the current number of retries for the current command. 0 when command is successful, "failed" if the number of retries is greater than the maximum configured number of retries.
### Configuration
- configuration/buttonEnabled: 1 if the Nuki Lock/Opener button is enabled, otherwise 0.

View File

@@ -1,6 +1,7 @@
#pragma once
#define mqtt_topic_lock_action "/lock/action"
#define mqtt_topic_lock_status_updated "/lock/statusUpdated"
#define mqtt_topic_lock_state "/lock/state"
#define mqtt_topic_lock_ha_state "/lock/hastate"
#define mqtt_topic_lock_json "/lock/json"

View File

@@ -242,7 +242,7 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne
lockstateToString(keyTurnerState.lockState, str);
if((_firstTunerStatePublish || keyTurnerState.lockState != lastKeyTurnerState.lockState) && keyTurnerState.lockState != NukiLock::LockState::Undefined)
if(keyTurnerState.lockState != NukiLock::LockState::Undefined)
{
publishString(mqtt_topic_lock_state, str);
@@ -254,6 +254,7 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne
}
json["lock_state"] = str;
json["lockngo_state"] = (keyTurnerState.lockNgoTimer == 0 ? 0 : 1);
memset(&str, 0, sizeof(str));
triggerToString(keyTurnerState.trigger, str);
@@ -264,6 +265,12 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne
}
json["trigger"] = str;
char curTime[20];
sprintf(curTime, "%04d-%02d-%02d %02d:%02d:%02d", keyTurnerState.currentTimeYear, keyTurnerState.currentTimeMonth, keyTurnerState.currentTimeDay, keyTurnerState.currentTimeHour, keyTurnerState.currentTimeMinute, keyTurnerState.currentTimeSecond);
json["currentTime"] = curTime;
json["timeZoneOffset"] = keyTurnerState.timeZoneOffset;
json["nightModeActive"] = keyTurnerState.nightModeActive;
memset(&str, 0, sizeof(str));
lockactionToString(keyTurnerState.lastLockAction, str);
@@ -275,6 +282,10 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne
json["last_lock_action"] = str;
memset(&str, 0, sizeof(str));
triggerToString(keyTurnerState.lastLockActionTrigger, str);
json["last_lock_action_trigger"] = str;
memset(&str, 0, sizeof(str));
NukiLock::completionStatusToString(keyTurnerState.lastLockActionCompletionStatus, str);
@@ -809,6 +820,11 @@ void NetworkLock::publishTimeControlCommandResult(const char* result)
publishString(mqtt_topic_timecontrol_command_result, result);
}
void NetworkLock::publishStatusUpdated(const bool statusUpdated)
{
publishBool(mqtt_topic_lock_status_updated, statusUpdated);
}
void NetworkLock::setLockActionReceivedCallback(LockActionResult (*lockActionReceivedCallback)(const char *))
{
_lockActionReceivedCallback = lockActionReceivedCallback;

View File

@@ -38,6 +38,7 @@ public:
void removeHASSConfig(char* uidString);
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
void publishTimeControl(const std::list<NukiLock::TimeControlEntry>& timeControlEntries);
void publishStatusUpdated(const bool statusUpdated);
void publishConfigCommandResult(const char* result);
void publishKeypadCommandResult(const char* result);
void publishKeypadJsonCommandResult(const char* result);

View File

@@ -266,6 +266,25 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn
}
json["trigger"] = str;
json["ringToOpenTimer"] = keyTurnerState.ringToOpenTimer;
char curTime[20];
sprintf(curTime, "%04d-%02d-%02d %02d:%02d:%02d", keyTurnerState.currentTimeYear, keyTurnerState.currentTimeMonth, keyTurnerState.currentTimeDay, keyTurnerState.currentTimeHour, keyTurnerState.currentTimeMinute, keyTurnerState.currentTimeSecond);
json["currentTime"] = curTime;
json["timeZoneOffset"] = keyTurnerState.timeZoneOffset;
lockactionToString(keyTurnerState.lastLockAction, str);
if(_firstTunerStatePublish || keyTurnerState.lastLockAction != lastKeyTurnerState.lastLockAction)
{
publishString(mqtt_topic_lock_last_lock_action, str);
}
json["last_lock_action"] = str;
memset(&str, 0, sizeof(str));
triggerToString(keyTurnerState.lastLockActionTrigger, str);
json["last_lock_action_trigger"] = str;
memset(&str, 0, sizeof(str));
completionStatusToString(keyTurnerState.lastLockActionCompletionStatus, str);
@@ -867,6 +886,11 @@ void NetworkOpener::publishTimeControlCommandResult(const char* result)
{
publishString(mqtt_topic_timecontrol_command_result, result);
}
void NetworkOpener::publishStatusUpdated(const bool statusUpdated)
{
publishBool(mqtt_topic_lock_status_updated, statusUpdated);
}
void NetworkOpener::setLockActionReceivedCallback(LockActionResult (*lockActionReceivedCallback)(const char *))
{

View File

@@ -35,6 +35,7 @@ public:
void removeHASSConfig(char* uidString);
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
void publishTimeControl(const std::list<NukiOpener::TimeControlEntry>& timeControlEntries);
void publishStatusUpdated(const bool statusUpdated);
void publishConfigCommandResult(const char* result);
void publishKeypadCommandResult(const char* result);
void publishKeypadJsonCommandResult(const char* result);

View File

@@ -154,9 +154,10 @@ void NukiOpenerWrapper::update()
if(_statusUpdated || _nextLockStateUpdateTs == 0 || ts >= _nextLockStateUpdateTs || (queryCommands & QUERY_COMMAND_LOCKSTATE) > 0)
{
_statusUpdated = false;
_nextLockStateUpdateTs = ts + _intervalLockstate * 1000;
updateKeyTurnerState();
_statusUpdated = false;
_network->publishStatusUpdated(_statusUpdated);
}
if(_nextBatteryReportTs == 0 || ts > _nextBatteryReportTs || (queryCommands & QUERY_COMMAND_BATTERY) > 0)
{
@@ -1962,6 +1963,7 @@ void NukiOpenerWrapper::notify(Nuki::EventType eventType)
if(eventType == Nuki::EventType::KeyTurnerStatusUpdated)
{
_statusUpdated = true;
_network->publishStatusUpdated(_statusUpdated);
}
}

View File

@@ -176,6 +176,7 @@ void NukiWrapper::update()
_statusUpdated = false;
_nextLockStateUpdateTs = ts + _intervalLockstate * 1000;
updateKeyTurnerState();
_network->publishStatusUpdated(_statusUpdated);
}
if(_nextBatteryReportTs == 0 || ts > _nextBatteryReportTs || (queryCommands & QUERY_COMMAND_BATTERY) > 0)
{
@@ -1938,6 +1939,7 @@ void NukiWrapper::notify(Nuki::EventType eventType)
if(eventType == Nuki::EventType::KeyTurnerStatusUpdated)
{
_statusUpdated = true;
_network->publishStatusUpdated(_statusUpdated);
}
}