From fa856dc656df3cad33f8b79fde7d2b4159a91892 Mon Sep 17 00:00:00 2001 From: technyon Date: Wed, 10 Aug 2022 22:12:23 +0200 Subject: [PATCH] publish keypad code info --- MqttTopics.h | 4 +++- NetworkLock.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- NetworkLock.h | 4 ++++ NetworkOpener.cpp | 2 +- NukiWrapper.cpp | 26 ++++++++++++++++++++++++++ NukiWrapper.h | 4 ++++ PreferencesKeys.h | 1 + 7 files changed, 79 insertions(+), 3 deletions(-) diff --git a/MqttTopics.h b/MqttTopics.h index 04c089a..04ba9a5 100644 --- a/MqttTopics.h +++ b/MqttTopics.h @@ -15,7 +15,7 @@ #define mqtt_topic_lock_auth_name "/lock/authorizationName" #define mqtt_topic_lock_completionStatus "/lock/completionStatus" #define mqtt_topic_lock_action_command_result "/lock/commandResult" -#define mqtt_topic_door_sensor_state "/lock/doorSensorState" +#define mqtt_topic_lock_door_sensor_state "/lock/doorSensorState" #define mqtt_topic_lock_action "/lock/action" #define mqtt_topic_config_button_enabled "/configuration/buttonEnabled" @@ -26,6 +26,8 @@ #define mqtt_topic_config_single_lock "/configuration/singleLock" #define mqtt_topic_config_sound_level "/configuration/soundLevel" +#define mqtt_topic_keypad "/keypad" + #define mqtt_topic_presence "/presence/devices" #define mqtt_topic_reset "/maintenance/reset" diff --git a/NetworkLock.cpp b/NetworkLock.cpp index 24acd4a..c8e09b7 100644 --- a/NetworkLock.cpp +++ b/NetworkLock.cpp @@ -144,7 +144,7 @@ void NetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurne { memset(&str, 0, sizeof(str)); NukiLock::doorSensorStateToString(keyTurnerState.doorSensorState, str); - publishString(mqtt_topic_door_sensor_state, str); + publishString(mqtt_topic_lock_door_sensor_state, str); } if(_firstTunerStatePublish || keyTurnerState.criticalBatteryState != lastKeyTurnerState.criticalBatteryState) @@ -216,6 +216,38 @@ void NetworkLock::publishAdvancedConfig(const NukiLock::AdvancedConfig &config) publishBool(mqtt_topic_config_auto_lock, config.autoLockEnabled == 1); } +void NetworkLock::publishKeypad(const std::list& entries, uint maxKeypadCodeCount) +{ + uint index = 0; + for(const auto& entry : entries) + { + String basePath = mqtt_topic_keypad; + basePath.concat("/code_"); + basePath.concat(std::to_string(index).c_str()); + + char codeName[sizeof(entry.name) + 1]; + memset(codeName, 0, sizeof(codeName)); + memcpy(codeName, entry.name, sizeof(entry.name)); + + publishInt(concat(basePath, "/id").c_str(), entry.codeId); + publishBool(concat(basePath, "/enabled").c_str(), entry.enabled); + publishString(concat(basePath, "/name").c_str(), codeName); + publishInt(concat(basePath, "/createdYear").c_str(), entry.dateCreatedYear); + publishInt(concat(basePath, "/createdMonth").c_str(), entry.dateCreatedMonth); + publishInt(concat(basePath, "/createdDay").c_str(), entry.dateCreatedDay); + publishInt(concat(basePath, "/createdHour").c_str(), entry.dateCreatedHour); + publishInt(concat(basePath, "/createdMin").c_str(), entry.dateCreatedMin); + publishInt(concat(basePath, "/createdSec").c_str(), entry.dateCreatedSec); + publishInt(concat(basePath, "/lockCount").c_str(), entry.lockCount); + + ++index; + } + while(index < maxKeypadCodeCount) + { + ++index; + } +} + void NetworkLock::setLockActionReceivedCallback(bool (*lockActionReceivedCallback)(const char *)) { _lockActionReceivedCallback = lockActionReceivedCallback; @@ -298,3 +330,10 @@ void NetworkLock::publishULong(const char *topic, const unsigned long value) return _network->publishULong(_mqttPath, topic, value); } +String NetworkLock::concat(String a, String b) +{ + String c = a; + c.concat(b); + return c; +} + diff --git a/NetworkLock.h b/NetworkLock.h index 45b3234..1b22706 100644 --- a/NetworkLock.h +++ b/NetworkLock.h @@ -6,6 +6,7 @@ #include "networkDevices/W5500Device.h" #include #include +#include #include "NukiConstants.h" #include "NukiLockConstants.h" #include "Network.h" @@ -26,6 +27,7 @@ public: void publishBatteryReport(const NukiLock::BatteryReport& batteryReport); void publishConfig(const NukiLock::Config& config); void publishAdvancedConfig(const NukiLock::AdvancedConfig& config); + void publishKeypad(const std::list& entries, uint maxKeypadCodeCount); void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState); void removeHASSConfig(char* uidString); @@ -43,6 +45,8 @@ private: bool publishString(const char* topic, const char* value); bool comparePrefixedPath(const char* fullPath, const char* subPath); + String concat(String a, String b); + void buildMqttPath(const char* path, char* outPath); Network* _network; diff --git a/NetworkOpener.cpp b/NetworkOpener.cpp index 3b2dab9..09de990 100644 --- a/NetworkOpener.cpp +++ b/NetworkOpener.cpp @@ -113,7 +113,7 @@ void NetworkOpener::publishKeyTurnerState(const NukiOpener::OpenerState& keyTurn { memset(&str, 0, sizeof(str)); NukiLock::doorSensorStateToString(keyTurnerState.doorSensorState, str); - publishString(mqtt_topic_door_sensor_state, str); + publishString(mqtt_topic_lock_door_sensor_state, str); } if(_firstTunerStatePublish || keyTurnerState.criticalBatteryState != lastKeyTurnerState.criticalBatteryState) diff --git a/NukiWrapper.cpp b/NukiWrapper.cpp index 6e6b378..219a026 100644 --- a/NukiWrapper.cpp +++ b/NukiWrapper.cpp @@ -41,6 +41,7 @@ void NukiWrapper::initialize() _intervalLockstate = _preferences->getInt(preference_query_interval_lockstate); _intervalBattery = _preferences->getInt(preference_query_interval_battery); _publishAuthData = _preferences->getBool(preference_publish_authdata); + _maxKeypadCodeCount = _preferences->getUInt(preference_max_keypad_code_count); if(_intervalLockstate == 0) { @@ -105,6 +106,11 @@ void NukiWrapper::update() _nextConfigUpdateTs = ts + _intervalConfig * 1000; updateConfig(); } + if(_hasKeypad && _nextKeypadUpdateTs == 0 || ts > _nextKeypadUpdateTs) + { + _nextKeypadUpdateTs = ts + 60 * 60 * 1000; + updateKeypad(); + } if(_nextLockAction != (NukiLock::LockAction)0xff) { @@ -189,6 +195,7 @@ void NukiWrapper::updateConfig() { readConfig(); readAdvancedConfig(); + _hasKeypad = _nukiConfig.hasKeypad > 0; _network->publishConfig(_nukiConfig); _network->publishAdvancedConfig(_nukiAdvancedConfig); } @@ -231,6 +238,25 @@ void NukiWrapper::updateAuthData() } } +void NukiWrapper::updateKeypad() +{ + Nuki::CmdResult result = _nukiLock.retrieveKeypadEntries(0, 0xffff); + if(result == 1) + { + std::list entries; + _nukiLock.getKeypadEntries(&entries); + + uint keypadCount = entries.size(); + if(keypadCount > _maxKeypadCodeCount) + { + _maxKeypadCodeCount = keypadCount; + _preferences->putUInt(preference_max_keypad_code_count, _maxKeypadCodeCount); + } + + _network->publishKeypad(entries, _maxKeypadCodeCount); + } +} + NukiLock::LockAction NukiWrapper::lockActionToEnum(const char *str) { if(strcmp(str, "unlock") == 0) return NukiLock::LockAction::Unlock; diff --git a/NukiWrapper.h b/NukiWrapper.h index 6e809df..785d24d 100644 --- a/NukiWrapper.h +++ b/NukiWrapper.h @@ -38,6 +38,7 @@ private: void updateBatteryState(); void updateConfig(); void updateAuthData(); + void updateKeypad(); void readConfig(); void readAdvancedConfig(); @@ -72,9 +73,12 @@ private: bool _paired = false; bool _statusUpdated = false; + bool _hasKeypad = false; + uint _maxKeypadCodeCount = 0; unsigned long _nextLockStateUpdateTs = 0; unsigned long _nextBatteryReportTs = 0; unsigned long _nextConfigUpdateTs = 0; + unsigned long _nextKeypadUpdateTs = 0; unsigned long _nextPairTs = 0; NukiLock::LockAction _nextLockAction = (NukiLock::LockAction)0xff; }; diff --git a/PreferencesKeys.h b/PreferencesKeys.h index c220810..3b72102 100644 --- a/PreferencesKeys.h +++ b/PreferencesKeys.h @@ -10,6 +10,7 @@ #define preference_mqtt_lock_path "mqttpath" #define preference_opener_enabled "openerena" #define preference_mqtt_opener_path "mqttoppath" +#define preference_max_keypad_code_count "maxkpad" #define preference_mqtt_ca "mqttca" #define preference_mqtt_crt "mqttcrt" #define preference_mqtt_key "mqttkey"