diff --git a/MqttTopics.h b/MqttTopics.h index 04ba9a5..8917aa4 100644 --- a/MqttTopics.h +++ b/MqttTopics.h @@ -27,6 +27,10 @@ #define mqtt_topic_config_sound_level "/configuration/soundLevel" #define mqtt_topic_keypad "/keypad" +#define mqtt_topic_keypad_command_action "/keypad/command/action" +#define mqtt_topic_keypad_command_id "/keypad/command/id" +#define mqtt_topic_keypad_command_name "/keypad/command/name" +#define mqtt_topic_keypad_command_code "/keypad/command/code" #define mqtt_topic_presence "/presence/devices" diff --git a/NetworkLock.cpp b/NetworkLock.cpp index 0277618..606af6c 100644 --- a/NetworkLock.cpp +++ b/NetworkLock.cpp @@ -53,6 +53,15 @@ void NetworkLock::initialize() _network->subscribe(_mqttPath, mqtt_topic_reset); _network->initTopic(_mqttPath, mqtt_topic_reset, "0"); + + _network->subscribe(_mqttPath, mqtt_topic_keypad_command_action); + _network->subscribe(_mqttPath, mqtt_topic_keypad_command_id); + _network->subscribe(_mqttPath, mqtt_topic_keypad_command_name); + _network->subscribe(_mqttPath, mqtt_topic_keypad_command_code); + _network->initTopic(_mqttPath, mqtt_topic_keypad_command_action, "--"); + _network->initTopic(_mqttPath, mqtt_topic_keypad_command_id, "0"); + _network->initTopic(_mqttPath, mqtt_topic_keypad_command_name, "--"); + _network->initTopic(_mqttPath, mqtt_topic_keypad_command_code, "000000"); } void NetworkLock::update() @@ -98,6 +107,30 @@ void NetworkLock::onMqttDataReceived(char *&topic, byte *&payload, unsigned int publishString(mqtt_topic_lock_action, success ? "ack" : "unknown_action"); } + if(comparePrefixedPath(topic, mqtt_topic_keypad_command_action)) + { + if(_keypadCommandReceivedReceivedCallback != nullptr) + { + _keypadCommandReceivedReceivedCallback(value, _keypadCommandId, _keypadCommandName, _keypadCommandCode); + publishString(mqtt_topic_keypad_command_action, "--"); + publishInt(mqtt_topic_keypad_command_id, 0); + publishString(mqtt_topic_keypad_command_name, "--"); + publishString(mqtt_topic_keypad_command_code, "000000"); + } + } + else if(comparePrefixedPath(topic, mqtt_topic_keypad_command_id)) + { + _keypadCommandId = atoi(value); + } + else if(comparePrefixedPath(topic, mqtt_topic_keypad_command_name)) + { + _keypadCommandName = value; + } + else if(comparePrefixedPath(topic, mqtt_topic_keypad_command_code)) + { + _keypadCommandCode = value; + } + for(auto configTopic : _configTopics) { if(comparePrefixedPath(topic, configTopic)) @@ -251,6 +284,11 @@ void NetworkLock::setConfigUpdateReceivedCallback(void (*configUpdateReceivedCal _configUpdateReceivedCallback = configUpdateReceivedCallback; } +void NetworkLock::setKeypadCommandReceivedCallback(void (*keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code)) +{ + _keypadCommandReceivedReceivedCallback = keypadCommandReceivedReceivedCallback; +} + void NetworkLock::buildMqttPath(const char* path, char* outPath) { int offset = 0; @@ -349,4 +387,3 @@ String NetworkLock::concat(String a, String b) c.concat(b); return c; } - diff --git a/NetworkLock.h b/NetworkLock.h index 2c87bfb..629e302 100644 --- a/NetworkLock.h +++ b/NetworkLock.h @@ -27,12 +27,13 @@ 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); + void publishKeypad(const std::list& entries, uint maxKeypadCodeCount); void setLockActionReceivedCallback(bool (*lockActionReceivedCallback)(const char* value)); void setConfigUpdateReceivedCallback(void (*configUpdateReceivedCallback)(const char* path, const char* value)); + void setKeypadCommandReceivedCallback(void (*keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code)); void onMqttDataReceived(char*& topic, byte*& payload, unsigned int& length) override; @@ -60,6 +61,11 @@ private: unsigned long _lastMaintenanceTs = 0; bool _haEnabled= false; + String _keypadCommandName = ""; + String _keypadCommandCode = ""; + uint _keypadCommandId = 0; + bool (*_lockActionReceivedCallback)(const char* value) = nullptr; void (*_configUpdateReceivedCallback)(const char* path, const char* value) = nullptr; + void (*_keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code) = nullptr; }; diff --git a/NukiWrapper.cpp b/NukiWrapper.cpp index 219a026..392be65 100644 --- a/NukiWrapper.cpp +++ b/NukiWrapper.cpp @@ -23,6 +23,7 @@ NukiWrapper::NukiWrapper(const std::string& deviceName, uint32_t id, BleScanner: network->setLockActionReceivedCallback(nukiInst->onLockActionReceivedCallback); network->setConfigUpdateReceivedCallback(nukiInst->onConfigUpdateReceivedCallback); + network->setKeypadCommandReceivedCallback(nukiInst->onKeypadCommandReceivedCallback); } @@ -106,7 +107,7 @@ void NukiWrapper::update() _nextConfigUpdateTs = ts + _intervalConfig * 1000; updateConfig(); } - if(_hasKeypad && _nextKeypadUpdateTs == 0 || ts > _nextKeypadUpdateTs) + if(_hasKeypad && (_nextKeypadUpdateTs == 0 || ts > _nextKeypadUpdateTs)) { _nextKeypadUpdateTs = ts + 60 * 60 * 1000; updateKeypad(); @@ -284,6 +285,13 @@ void NukiWrapper::onConfigUpdateReceivedCallback(const char *topic, const char * } +void NukiWrapper::onKeypadCommandReceivedCallback(const char *command, const uint &id, const String &name, + const String &code) +{ + nukiInst->onKeypadCommandReceived(command, id, name, code); +} + + void NukiWrapper::onConfigUpdateReceived(const char *topic, const char *value) { if(strcmp(topic, mqtt_topic_config_button_enabled) == 0) @@ -337,6 +345,27 @@ void NukiWrapper::onConfigUpdateReceived(const char *topic, const char *value) } } +void NukiWrapper::onKeypadCommandReceived(const char *command, const uint &id, const String &name, const String &code) +{ + if(strcmp(command, "add") == 0) + { + NukiLock::NewKeypadEntry entry; + memset(&entry, 0, sizeof(entry)); + size_t nameLen = name.length(); + memcpy(&entry.name, name.c_str(), nameLen > 20 ? 20 : nameLen); + entry.code = code.toInt(); + const auto r = _nukiLock.addKeypadEntry(entry); + Serial.print("Add keypad code: "); Serial.println((int)r); + updateKeypad(); + } + else if(strcmp(command, "delete") == 0) + { + const auto r = _nukiLock.deleteKeypadEntry(id); + Serial.print("Delete keypad code: "); Serial.println((int)r); + updateKeypad(); + } +} + const NukiLock::KeyTurnerState &NukiWrapper::keyTurnerState() { return _keyTurnerState; diff --git a/NukiWrapper.h b/NukiWrapper.h index 785d24d..358fccc 100644 --- a/NukiWrapper.h +++ b/NukiWrapper.h @@ -32,7 +32,9 @@ public: private: static bool onLockActionReceivedCallback(const char* value); static void onConfigUpdateReceivedCallback(const char* topic, const char* value); + static void onKeypadCommandReceivedCallback(const char* command, const uint& id, const String& name, const String& code); void onConfigUpdateReceived(const char* topic, const char* value); + void onKeypadCommandReceived(const char* command, const uint& id, const String& name, const String& code); void updateKeyTurnerState(); void updateBatteryState();