add keypad control for opener
This commit is contained in:
2
Config.h
2
Config.h
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define NUKI_HUB_VERSION "8.5"
|
#define NUKI_HUB_VERSION "8.6"
|
||||||
|
|
||||||
#define MQTT_QOS_LEVEL 1
|
#define MQTT_QOS_LEVEL 1
|
||||||
#define MQTT_CLEAN_SESSIONS false
|
#define MQTT_CLEAN_SESSIONS false
|
||||||
@@ -546,7 +546,6 @@ void NetworkLock::publishKeypadEntry(const String topic, NukiLock::KeypadEntry e
|
|||||||
publishInt(concat(topic, "/lockCount").c_str(), entry.lockCount);
|
publishInt(concat(topic, "/lockCount").c_str(), entry.lockCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NetworkLock::publishULong(const char *topic, const unsigned long value)
|
void NetworkLock::publishULong(const char *topic, const unsigned long value)
|
||||||
{
|
{
|
||||||
return _network->publishULong(_mqttPath, topic, value);
|
return _network->publishULong(_mqttPath, topic, value);
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ public:
|
|||||||
void onMqttDataReceived(const char* topic, byte* payload, const unsigned int length) override;
|
void onMqttDataReceived(const char* topic, byte* payload, const unsigned int length) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool comparePrefixedPath(const char* fullPath, const char* subPath);
|
||||||
|
|
||||||
void publishFloat(const char* topic, const float value, const uint8_t precision = 2);
|
void publishFloat(const char* topic, const float value, const uint8_t precision = 2);
|
||||||
void publishInt(const char* topic, const int value);
|
void publishInt(const char* topic, const int value);
|
||||||
void publishUInt(const char* topic, const unsigned int value);
|
void publishUInt(const char* topic, const unsigned int value);
|
||||||
@@ -50,7 +52,6 @@ private:
|
|||||||
bool publishString(const char* topic, const std::string& value);
|
bool publishString(const char* topic, const std::string& value);
|
||||||
bool publishString(const char* topic, const char* value);
|
bool publishString(const char* topic, const char* value);
|
||||||
void publishKeypadEntry(const String topic, NukiLock::KeypadEntry entry);
|
void publishKeypadEntry(const String topic, NukiLock::KeypadEntry entry);
|
||||||
bool comparePrefixedPath(const char* fullPath, const char* subPath);
|
|
||||||
|
|
||||||
String concat(String a, String b);
|
String concat(String a, String b);
|
||||||
|
|
||||||
|
|||||||
@@ -42,6 +42,20 @@ void NetworkOpener::initialize()
|
|||||||
{
|
{
|
||||||
_network->subscribe(_mqttPath, topic);
|
_network->subscribe(_mqttPath, topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_preferences->getBool(preference_keypad_control_enabled))
|
||||||
|
{
|
||||||
|
_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->subscribe(_mqttPath, mqtt_topic_keypad_command_enabled);
|
||||||
|
_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");
|
||||||
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_enabled, "1");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkOpener::update()
|
void NetworkOpener::update()
|
||||||
@@ -76,6 +90,46 @@ void NetworkOpener::onMqttDataReceived(const char* topic, byte* payload, const u
|
|||||||
publishString(mqtt_topic_lock_action, success ? "ack" : "unknown_action");
|
publishString(mqtt_topic_lock_action, success ? "ack" : "unknown_action");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(processActions && comparePrefixedPath(topic, mqtt_topic_keypad_command_action))
|
||||||
|
{
|
||||||
|
if(_keypadCommandReceivedReceivedCallback != nullptr)
|
||||||
|
{
|
||||||
|
if(strcmp(value, "--") == 0) return;
|
||||||
|
|
||||||
|
_keypadCommandReceivedReceivedCallback(value, _keypadCommandId, _keypadCommandName, _keypadCommandCode, _keypadCommandEnabled);
|
||||||
|
|
||||||
|
_keypadCommandId = 0;
|
||||||
|
_keypadCommandName = "--";
|
||||||
|
_keypadCommandCode = "000000";
|
||||||
|
_keypadCommandEnabled = 1;
|
||||||
|
|
||||||
|
if(strcmp(value, "--") != 0)
|
||||||
|
{
|
||||||
|
publishString(mqtt_topic_keypad_command_action, "--");
|
||||||
|
}
|
||||||
|
publishInt(mqtt_topic_keypad_command_id, _keypadCommandId);
|
||||||
|
publishString(mqtt_topic_keypad_command_name, _keypadCommandName);
|
||||||
|
publishString(mqtt_topic_keypad_command_code, _keypadCommandCode);
|
||||||
|
publishInt(mqtt_topic_keypad_command_enabled, _keypadCommandEnabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else if(comparePrefixedPath(topic, mqtt_topic_keypad_command_enabled))
|
||||||
|
{
|
||||||
|
_keypadCommandEnabled = atoi(value);
|
||||||
|
}
|
||||||
|
|
||||||
for(auto configTopic : _configTopics)
|
for(auto configTopic : _configTopics)
|
||||||
{
|
{
|
||||||
if(comparePrefixedPath(topic, configTopic))
|
if(comparePrefixedPath(topic, configTopic))
|
||||||
@@ -399,6 +453,36 @@ void NetworkOpener::removeHASSConfig(char* uidString)
|
|||||||
_network->removeHASSConfig(uidString);
|
_network->removeHASSConfig(uidString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkOpener::publishKeypad(const std::list<NukiLock::KeypadEntry>& 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());
|
||||||
|
publishKeypadEntry(basePath, entry);
|
||||||
|
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
while(index < maxKeypadCodeCount)
|
||||||
|
{
|
||||||
|
NukiLock::KeypadEntry entry;
|
||||||
|
memset(&entry, 0, sizeof(entry));
|
||||||
|
String basePath = mqtt_topic_keypad;
|
||||||
|
basePath.concat("/code_");
|
||||||
|
basePath.concat(std::to_string(index).c_str());
|
||||||
|
publishKeypadEntry(basePath, entry);
|
||||||
|
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkOpener::publishKeypadCommandResult(const char* result)
|
||||||
|
{
|
||||||
|
publishString(mqtt_topic_keypad_command_result, result);
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkOpener::setLockActionReceivedCallback(bool (*lockActionReceivedCallback)(const char *))
|
void NetworkOpener::setLockActionReceivedCallback(bool (*lockActionReceivedCallback)(const char *))
|
||||||
{
|
{
|
||||||
_lockActionReceivedCallback = lockActionReceivedCallback;
|
_lockActionReceivedCallback = lockActionReceivedCallback;
|
||||||
@@ -409,6 +493,11 @@ void NetworkOpener::setConfigUpdateReceivedCallback(void (*configUpdateReceivedC
|
|||||||
_configUpdateReceivedCallback = configUpdateReceivedCallback;
|
_configUpdateReceivedCallback = configUpdateReceivedCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkOpener::setKeypadCommandReceivedCallback(void (*keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code, const int& enabled))
|
||||||
|
{
|
||||||
|
_keypadCommandReceivedReceivedCallback = keypadCommandReceivedReceivedCallback;
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkOpener::publishFloat(const char *topic, const float value, const uint8_t precision)
|
void NetworkOpener::publishFloat(const char *topic, const float value, const uint8_t precision)
|
||||||
{
|
{
|
||||||
_network->publishFloat(_mqttPath, topic, value, precision);
|
_network->publishFloat(_mqttPath, topic, value, precision);
|
||||||
@@ -450,6 +539,24 @@ void NetworkOpener::publishString(const char* topic, const char* value)
|
|||||||
_network->publishString(_mqttPath, topic, value);
|
_network->publishString(_mqttPath, topic, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkOpener::publishKeypadEntry(const String topic, NukiLock::KeypadEntry entry)
|
||||||
|
{
|
||||||
|
char codeName[sizeof(entry.name) + 1];
|
||||||
|
memset(codeName, 0, sizeof(codeName));
|
||||||
|
memcpy(codeName, entry.name, sizeof(entry.name));
|
||||||
|
|
||||||
|
publishInt(concat(topic, "/id").c_str(), entry.codeId);
|
||||||
|
publishBool(concat(topic, "/enabled").c_str(), entry.enabled);
|
||||||
|
publishString(concat(topic, "/name").c_str(), codeName);
|
||||||
|
publishInt(concat(topic, "/createdYear").c_str(), entry.dateCreatedYear);
|
||||||
|
publishInt(concat(topic, "/createdMonth").c_str(), entry.dateCreatedMonth);
|
||||||
|
publishInt(concat(topic, "/createdDay").c_str(), entry.dateCreatedDay);
|
||||||
|
publishInt(concat(topic, "/createdHour").c_str(), entry.dateCreatedHour);
|
||||||
|
publishInt(concat(topic, "/createdMin").c_str(), entry.dateCreatedMin);
|
||||||
|
publishInt(concat(topic, "/createdSec").c_str(), entry.dateCreatedSec);
|
||||||
|
publishInt(concat(topic, "/lockCount").c_str(), entry.lockCount);
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkOpener::buildMqttPath(const char* path, char* outPath)
|
void NetworkOpener::buildMqttPath(const char* path, char* outPath)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@@ -486,3 +593,10 @@ bool NetworkOpener::comparePrefixedPath(const char *fullPath, const char *subPat
|
|||||||
|
|
||||||
return strcmp(fullPath, prefixedPath) == 0;
|
return strcmp(fullPath, prefixedPath) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String NetworkOpener::concat(String a, String b)
|
||||||
|
{
|
||||||
|
String c = a;
|
||||||
|
c.concat(b);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,9 +32,12 @@ public:
|
|||||||
void publishBleAddress(const std::string& address);
|
void publishBleAddress(const std::string& address);
|
||||||
void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, char* lockAction, char* unlockAction, char* openAction, char* lockedState, char* unlockedState);
|
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 removeHASSConfig(char* uidString);
|
||||||
|
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
|
||||||
|
void publishKeypadCommandResult(const char* result);
|
||||||
|
|
||||||
void setLockActionReceivedCallback(bool (*lockActionReceivedCallback)(const char* value));
|
void setLockActionReceivedCallback(bool (*lockActionReceivedCallback)(const char* value));
|
||||||
void setConfigUpdateReceivedCallback(void (*configUpdateReceivedCallback)(const char* path, 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, const int& enabled));
|
||||||
|
|
||||||
void onMqttDataReceived(const char* topic, byte* payload, const unsigned int length) override;
|
void onMqttDataReceived(const char* topic, byte* payload, const unsigned int length) override;
|
||||||
|
|
||||||
@@ -48,11 +51,14 @@ private:
|
|||||||
void publishString(const char* topic, const String& value);
|
void publishString(const char* topic, const String& value);
|
||||||
void publishString(const char* topic, const std::string& value);
|
void publishString(const char* topic, const std::string& value);
|
||||||
void publishString(const char* topic, const char* value);
|
void publishString(const char* topic, const char* value);
|
||||||
|
void publishKeypadEntry(const String topic, NukiLock::KeypadEntry entry);
|
||||||
|
|
||||||
void buildMqttPath(const char* path, char* outPath);
|
void buildMqttPath(const char* path, char* outPath);
|
||||||
void subscribe(const char* path);
|
void subscribe(const char* path);
|
||||||
void logactionCompletionStatusToString(uint8_t value, char* out);
|
void logactionCompletionStatusToString(uint8_t value, char* out);
|
||||||
|
|
||||||
|
String concat(String a, String b);
|
||||||
|
|
||||||
Preferences* _preferences;
|
Preferences* _preferences;
|
||||||
|
|
||||||
Network* _network = nullptr;
|
Network* _network = nullptr;
|
||||||
@@ -64,8 +70,13 @@ private:
|
|||||||
|
|
||||||
bool _firstTunerStatePublish = true;
|
bool _firstTunerStatePublish = true;
|
||||||
bool _haEnabled= false;
|
bool _haEnabled= false;
|
||||||
|
String _keypadCommandName = "";
|
||||||
|
String _keypadCommandCode = "";
|
||||||
|
uint _keypadCommandId = 0;
|
||||||
|
int _keypadCommandEnabled = 1;
|
||||||
unsigned long _resetLockStateTs = 0;
|
unsigned long _resetLockStateTs = 0;
|
||||||
|
|
||||||
bool (*_lockActionReceivedCallback)(const char* value) = nullptr;
|
bool (*_lockActionReceivedCallback)(const char* value) = nullptr;
|
||||||
void (*_configUpdateReceivedCallback)(const char* path, 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, const int& enabled) = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ NukiOpenerWrapper::NukiOpenerWrapper(const std::string& deviceName, uint32_t id,
|
|||||||
|
|
||||||
network->setLockActionReceivedCallback(nukiOpenerInst->onLockActionReceivedCallback);
|
network->setLockActionReceivedCallback(nukiOpenerInst->onLockActionReceivedCallback);
|
||||||
network->setConfigUpdateReceivedCallback(nukiOpenerInst->onConfigUpdateReceivedCallback);
|
network->setConfigUpdateReceivedCallback(nukiOpenerInst->onConfigUpdateReceivedCallback);
|
||||||
|
network->setKeypadCommandReceivedCallback(nukiOpenerInst->onKeypadCommandReceivedCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -40,10 +41,12 @@ void NukiOpenerWrapper::initialize()
|
|||||||
_nukiOpener.registerBleScanner(_bleScanner);
|
_nukiOpener.registerBleScanner(_bleScanner);
|
||||||
|
|
||||||
_intervalLockstate = _preferences->getInt(preference_query_interval_lockstate);
|
_intervalLockstate = _preferences->getInt(preference_query_interval_lockstate);
|
||||||
_intervalConfig = _preferences->getInt(preference_query_interval_battery);
|
|
||||||
_intervalBattery = _preferences->getInt(preference_query_interval_battery);
|
|
||||||
_intervalConfig = _preferences->getInt(preference_query_interval_configuration);
|
_intervalConfig = _preferences->getInt(preference_query_interval_configuration);
|
||||||
|
_intervalBattery = _preferences->getInt(preference_query_interval_battery);
|
||||||
|
_intervalKeypad = _preferences->getInt(preference_query_interval_keypad);
|
||||||
|
_keypadEnabled = _preferences->getBool(preference_keypad_control_enabled);
|
||||||
_publishAuthData = _preferences->getBool(preference_publish_authdata);
|
_publishAuthData = _preferences->getBool(preference_publish_authdata);
|
||||||
|
_maxKeypadCodeCount = _preferences->getUInt(preference_opener_max_keypad_code_count);
|
||||||
_restartBeaconTimeout = _preferences->getInt(preference_restart_ble_beacon_lost);
|
_restartBeaconTimeout = _preferences->getInt(preference_restart_ble_beacon_lost);
|
||||||
_hassEnabled = _preferences->getString(preference_mqtt_hass_discovery) != "";
|
_hassEnabled = _preferences->getString(preference_mqtt_hass_discovery) != "";
|
||||||
_nrOfRetries = _preferences->getInt(preference_command_nr_of_retries);
|
_nrOfRetries = _preferences->getInt(preference_command_nr_of_retries);
|
||||||
@@ -71,6 +74,11 @@ void NukiOpenerWrapper::initialize()
|
|||||||
_intervalBattery = 60 * 30;
|
_intervalBattery = 60 * 30;
|
||||||
_preferences->putInt(preference_query_interval_battery, _intervalBattery);
|
_preferences->putInt(preference_query_interval_battery, _intervalBattery);
|
||||||
}
|
}
|
||||||
|
if(_intervalKeypad == 0)
|
||||||
|
{
|
||||||
|
_intervalKeypad = 60 * 30;
|
||||||
|
_preferences->putInt(preference_query_interval_keypad, _intervalKeypad);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
if(_intervalKeypad == 0)
|
if(_intervalKeypad == 0)
|
||||||
{
|
{
|
||||||
@@ -172,6 +180,12 @@ void NukiOpenerWrapper::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_hasKeypad && _keypadEnabled && (_nextKeypadUpdateTs == 0 || ts > _nextKeypadUpdateTs))
|
||||||
|
{
|
||||||
|
_nextKeypadUpdateTs = ts + _intervalKeypad * 1000;
|
||||||
|
updateKeypad();
|
||||||
|
}
|
||||||
|
|
||||||
if(_nextLockAction != (NukiOpener::LockAction)0xff && ts > _nextRetryTs)
|
if(_nextLockAction != (NukiOpener::LockAction)0xff && ts > _nextRetryTs)
|
||||||
{
|
{
|
||||||
Nuki::CmdResult cmdResult = _nukiOpener.lockAction(_nextLockAction, 0, 0);
|
Nuki::CmdResult cmdResult = _nukiOpener.lockAction(_nextLockAction, 0, 0);
|
||||||
@@ -296,6 +310,8 @@ void NukiOpenerWrapper::updateConfig()
|
|||||||
{
|
{
|
||||||
readConfig();
|
readConfig();
|
||||||
readAdvancedConfig();
|
readAdvancedConfig();
|
||||||
|
_configRead = true;
|
||||||
|
_hasKeypad = _nukiConfig.hasKeypad > 0;
|
||||||
_network->publishConfig(_nukiConfig);
|
_network->publishConfig(_nukiConfig);
|
||||||
_network->publishAdvancedConfig(_nukiAdvancedConfig);
|
_network->publishAdvancedConfig(_nukiAdvancedConfig);
|
||||||
}
|
}
|
||||||
@@ -328,6 +344,35 @@ void NukiOpenerWrapper::updateAuthData()
|
|||||||
postponeBleWatchdog();
|
postponeBleWatchdog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NukiOpenerWrapper::updateKeypad()
|
||||||
|
{
|
||||||
|
Nuki::CmdResult result = _nukiOpener.retrieveKeypadEntries(0, 0xffff);
|
||||||
|
if(result == 1)
|
||||||
|
{
|
||||||
|
std::list<NukiLock::KeypadEntry> entries;
|
||||||
|
_nukiOpener.getKeypadEntries(&entries);
|
||||||
|
|
||||||
|
entries.sort([](const NukiLock::KeypadEntry& a, const NukiLock::KeypadEntry& b) { return a.codeId < b.codeId; });
|
||||||
|
|
||||||
|
uint keypadCount = entries.size();
|
||||||
|
if(keypadCount > _maxKeypadCodeCount)
|
||||||
|
{
|
||||||
|
_maxKeypadCodeCount = keypadCount;
|
||||||
|
_preferences->putUInt(preference_opener_max_keypad_code_count, _maxKeypadCodeCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
_network->publishKeypad(entries, _maxKeypadCodeCount);
|
||||||
|
|
||||||
|
_keypadCodeIds.clear();
|
||||||
|
_keypadCodeIds.reserve(entries.size());
|
||||||
|
for(const auto& entry : entries)
|
||||||
|
{
|
||||||
|
_keypadCodeIds.push_back(entry.codeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
postponeBleWatchdog();
|
||||||
|
}
|
||||||
|
|
||||||
void NukiOpenerWrapper::postponeBleWatchdog()
|
void NukiOpenerWrapper::postponeBleWatchdog()
|
||||||
{
|
{
|
||||||
_disableBleWatchdogTs = millis() + 15000;
|
_disableBleWatchdogTs = millis() + 15000;
|
||||||
@@ -358,6 +403,10 @@ void NukiOpenerWrapper::onConfigUpdateReceivedCallback(const char *topic, const
|
|||||||
nukiOpenerInst->onConfigUpdateReceived(topic, value);
|
nukiOpenerInst->onConfigUpdateReceived(topic, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NukiOpenerWrapper::onKeypadCommandReceivedCallback(const char *command, const uint &id, const String &name, const String &code, const int& enabled)
|
||||||
|
{
|
||||||
|
nukiOpenerInst->onKeypadCommandReceived(command, id, name, code, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
void NukiOpenerWrapper::onConfigUpdateReceived(const char *topic, const char *value)
|
void NukiOpenerWrapper::onConfigUpdateReceived(const char *topic, const char *value)
|
||||||
{
|
{
|
||||||
@@ -384,6 +433,117 @@ void NukiOpenerWrapper::onConfigUpdateReceived(const char *topic, const char *va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NukiOpenerWrapper::onKeypadCommandReceived(const char *command, const uint &id, const String &name, const String &code, const int& enabled)
|
||||||
|
{
|
||||||
|
if(!_hasKeypad)
|
||||||
|
{
|
||||||
|
if(_configRead)
|
||||||
|
{
|
||||||
|
_network->publishKeypadCommandResult("KeypadNotAvailable");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!_keypadEnabled)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool idExists = std::find(_keypadCodeIds.begin(), _keypadCodeIds.end(), id) != _keypadCodeIds.end();
|
||||||
|
int codeInt = code.toInt();
|
||||||
|
bool codeValid = codeInt > 100000 && codeInt < 1000000 && (code.indexOf('0') == -1);
|
||||||
|
NukiLock::CmdResult result = (NukiLock::CmdResult)-1;
|
||||||
|
|
||||||
|
if(strcmp(command, "add") == 0)
|
||||||
|
{
|
||||||
|
if(name == "" || name == "--")
|
||||||
|
{
|
||||||
|
_network->publishKeypadCommandResult("MissingParameterName");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(codeInt == 0)
|
||||||
|
{
|
||||||
|
_network->publishKeypadCommandResult("MissingParameterCode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!codeValid)
|
||||||
|
{
|
||||||
|
_network->publishKeypadCommandResult("CodeInvalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = codeInt;
|
||||||
|
result = _nukiOpener.addKeypadEntry(entry);
|
||||||
|
Log->print("Add keypad code: "); Log->println((int)result);
|
||||||
|
updateKeypad();
|
||||||
|
}
|
||||||
|
else if(strcmp(command, "delete") == 0)
|
||||||
|
{
|
||||||
|
if(!idExists)
|
||||||
|
{
|
||||||
|
_network->publishKeypadCommandResult("UnknownId");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
result = _nukiOpener.deleteKeypadEntry(id);
|
||||||
|
Log->print("Delete keypad code: "); Log->println((int)result);
|
||||||
|
updateKeypad();
|
||||||
|
}
|
||||||
|
else if(strcmp(command, "update") == 0)
|
||||||
|
{
|
||||||
|
if(name == "" || name == "--")
|
||||||
|
{
|
||||||
|
_network->publishKeypadCommandResult("MissingParameterName");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(codeInt == 0)
|
||||||
|
{
|
||||||
|
_network->publishKeypadCommandResult("MissingParameterCode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!codeValid)
|
||||||
|
{
|
||||||
|
_network->publishKeypadCommandResult("CodeInvalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!idExists)
|
||||||
|
{
|
||||||
|
_network->publishKeypadCommandResult("UnknownId");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NukiLock::UpdatedKeypadEntry entry;
|
||||||
|
memset(&entry, 0, sizeof(entry));
|
||||||
|
entry.codeId = id;
|
||||||
|
size_t nameLen = name.length();
|
||||||
|
memcpy(&entry.name, name.c_str(), nameLen > 20 ? 20 : nameLen);
|
||||||
|
entry.code = codeInt;
|
||||||
|
entry.enabled = enabled == 0 ? 0 : 1;
|
||||||
|
result = _nukiOpener.updateKeypadEntry(entry);
|
||||||
|
Log->print("Update keypad code: "); Log->println((int)result);
|
||||||
|
updateKeypad();
|
||||||
|
}
|
||||||
|
else if(command == "--")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_network->publishKeypadCommandResult("UnknownCommand");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((int)result != -1)
|
||||||
|
{
|
||||||
|
char resultStr[15];
|
||||||
|
memset(&resultStr, 0, sizeof(resultStr));
|
||||||
|
NukiOpener::cmdResultToString(result, resultStr);
|
||||||
|
_network->publishKeypadCommandResult(resultStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const NukiOpener::OpenerState &NukiOpenerWrapper::keyTurnerState()
|
const NukiOpener::OpenerState &NukiOpenerWrapper::keyTurnerState()
|
||||||
{
|
{
|
||||||
return _keyTurnerState;
|
return _keyTurnerState;
|
||||||
|
|||||||
@@ -33,12 +33,15 @@ public:
|
|||||||
private:
|
private:
|
||||||
static bool onLockActionReceivedCallback(const char* value);
|
static bool onLockActionReceivedCallback(const char* value);
|
||||||
static void onConfigUpdateReceivedCallback(const char* topic, 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, const int& enabled);
|
||||||
void onConfigUpdateReceived(const char* topic, const char* value);
|
void onConfigUpdateReceived(const char* topic, const char* value);
|
||||||
|
void onKeypadCommandReceived(const char* command, const uint& id, const String& name, const String& code, const int& enabled);
|
||||||
|
|
||||||
void updateKeyTurnerState();
|
void updateKeyTurnerState();
|
||||||
void updateBatteryState();
|
void updateBatteryState();
|
||||||
void updateConfig();
|
void updateConfig();
|
||||||
void updateAuthData();
|
void updateAuthData();
|
||||||
|
void updateKeypad();
|
||||||
void postponeBleWatchdog();
|
void postponeBleWatchdog();
|
||||||
|
|
||||||
void readConfig();
|
void readConfig();
|
||||||
@@ -56,6 +59,7 @@ private:
|
|||||||
int _intervalLockstate = 0; // seconds
|
int _intervalLockstate = 0; // seconds
|
||||||
int _intervalBattery = 0; // seconds
|
int _intervalBattery = 0; // seconds
|
||||||
int _intervalConfig = 60 * 60; // seconds
|
int _intervalConfig = 60 * 60; // seconds
|
||||||
|
int _intervalKeypad = 0; // seconds
|
||||||
int _restartBeaconTimeout = 0; // seconds
|
int _restartBeaconTimeout = 0; // seconds
|
||||||
bool _publishAuthData = false;
|
bool _publishAuthData = false;
|
||||||
bool _clearAuthData = false;
|
bool _clearAuthData = false;
|
||||||
@@ -63,6 +67,7 @@ private:
|
|||||||
int _retryDelay = 0;
|
int _retryDelay = 0;
|
||||||
int _retryCount = 0;
|
int _retryCount = 0;
|
||||||
unsigned long _nextRetryTs = 0;
|
unsigned long _nextRetryTs = 0;
|
||||||
|
std::vector<uint16_t> _keypadCodeIds;
|
||||||
|
|
||||||
NukiOpener::OpenerState _lastKeyTurnerState;
|
NukiOpener::OpenerState _lastKeyTurnerState;
|
||||||
NukiOpener::OpenerState _keyTurnerState;
|
NukiOpener::OpenerState _keyTurnerState;
|
||||||
@@ -79,10 +84,15 @@ private:
|
|||||||
|
|
||||||
bool _paired = false;
|
bool _paired = false;
|
||||||
bool _statusUpdated = false;
|
bool _statusUpdated = false;
|
||||||
|
bool _hasKeypad = false;
|
||||||
|
bool _keypadEnabled = false;
|
||||||
|
uint _maxKeypadCodeCount = 0;
|
||||||
|
bool _configRead = false;
|
||||||
long _rssiPublishInterval = 0;
|
long _rssiPublishInterval = 0;
|
||||||
unsigned long _nextLockStateUpdateTs = 0;
|
unsigned long _nextLockStateUpdateTs = 0;
|
||||||
unsigned long _nextBatteryReportTs = 0;
|
unsigned long _nextBatteryReportTs = 0;
|
||||||
unsigned long _nextConfigUpdateTs = 0;
|
unsigned long _nextConfigUpdateTs = 0;
|
||||||
|
unsigned long _nextKeypadUpdateTs = 0;
|
||||||
unsigned long _nextPairTs = 0;
|
unsigned long _nextPairTs = 0;
|
||||||
long _nextRssiTs = 0;
|
long _nextRssiTs = 0;
|
||||||
unsigned long _lastRssi = 0;
|
unsigned long _lastRssi = 0;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void NukiWrapper::initialize(const bool& firstStart)
|
|||||||
_intervalKeypad = _preferences->getInt(preference_query_interval_keypad);
|
_intervalKeypad = _preferences->getInt(preference_query_interval_keypad);
|
||||||
_keypadEnabled = _preferences->getBool(preference_keypad_control_enabled);
|
_keypadEnabled = _preferences->getBool(preference_keypad_control_enabled);
|
||||||
_publishAuthData = _preferences->getBool(preference_publish_authdata);
|
_publishAuthData = _preferences->getBool(preference_publish_authdata);
|
||||||
_maxKeypadCodeCount = _preferences->getUInt(preference_max_keypad_code_count);
|
_maxKeypadCodeCount = _preferences->getUInt(preference_lock_max_keypad_code_count);
|
||||||
_restartBeaconTimeout = _preferences->getInt(preference_restart_ble_beacon_lost);
|
_restartBeaconTimeout = _preferences->getInt(preference_restart_ble_beacon_lost);
|
||||||
_hassEnabled = _preferences->getString(preference_mqtt_hass_discovery) != "";
|
_hassEnabled = _preferences->getString(preference_mqtt_hass_discovery) != "";
|
||||||
_nrOfRetries = _preferences->getInt(preference_command_nr_of_retries);
|
_nrOfRetries = _preferences->getInt(preference_command_nr_of_retries);
|
||||||
@@ -357,7 +357,7 @@ void NukiWrapper::updateKeypad()
|
|||||||
if(keypadCount > _maxKeypadCodeCount)
|
if(keypadCount > _maxKeypadCodeCount)
|
||||||
{
|
{
|
||||||
_maxKeypadCodeCount = keypadCount;
|
_maxKeypadCodeCount = keypadCount;
|
||||||
_preferences->putUInt(preference_max_keypad_code_count, _maxKeypadCodeCount);
|
_preferences->putUInt(preference_lock_max_keypad_code_count, _maxKeypadCodeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
_network->publishKeypad(entries, _maxKeypadCodeCount);
|
_network->publishKeypad(entries, _maxKeypadCodeCount);
|
||||||
@@ -403,13 +403,11 @@ void NukiWrapper::onConfigUpdateReceivedCallback(const char *topic, const char *
|
|||||||
nukiInst->onConfigUpdateReceived(topic, value);
|
nukiInst->onConfigUpdateReceived(topic, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NukiWrapper::onKeypadCommandReceivedCallback(const char *command, const uint &id, const String &name, const String &code, const int& enabled)
|
void NukiWrapper::onKeypadCommandReceivedCallback(const char *command, const uint &id, const String &name, const String &code, const int& enabled)
|
||||||
{
|
{
|
||||||
nukiInst->onKeypadCommandReceived(command, id, name, code, enabled);
|
nukiInst->onKeypadCommandReceived(command, id, name, code, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NukiWrapper::onConfigUpdateReceived(const char *topic, const char *value)
|
void NukiWrapper::onConfigUpdateReceived(const char *topic, const char *value)
|
||||||
{
|
{
|
||||||
if(strcmp(topic, mqtt_topic_config_button_enabled) == 0)
|
if(strcmp(topic, mqtt_topic_config_button_enabled) == 0)
|
||||||
|
|||||||
@@ -85,8 +85,8 @@ private:
|
|||||||
bool _statusUpdated = false;
|
bool _statusUpdated = false;
|
||||||
bool _hasKeypad = false;
|
bool _hasKeypad = false;
|
||||||
bool _keypadEnabled = false;
|
bool _keypadEnabled = false;
|
||||||
bool _configRead = false;
|
|
||||||
uint _maxKeypadCodeCount = 0;
|
uint _maxKeypadCodeCount = 0;
|
||||||
|
bool _configRead = false;
|
||||||
int _nrOfRetries = 0;
|
int _nrOfRetries = 0;
|
||||||
int _retryDelay = 0;
|
int _retryDelay = 0;
|
||||||
int _retryCount = 0;
|
int _retryCount = 0;
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
#define preference_mqtt_lock_path "mqttpath"
|
#define preference_mqtt_lock_path "mqttpath"
|
||||||
#define preference_opener_enabled "openerena"
|
#define preference_opener_enabled "openerena"
|
||||||
#define preference_mqtt_opener_path "mqttoppath"
|
#define preference_mqtt_opener_path "mqttoppath"
|
||||||
#define preference_max_keypad_code_count "maxkpad"
|
#define preference_lock_max_keypad_code_count "maxkpad"
|
||||||
|
#define preference_opener_max_keypad_code_count "opmaxkpad"
|
||||||
#define preference_mqtt_ca "mqttca"
|
#define preference_mqtt_ca "mqttca"
|
||||||
#define preference_mqtt_crt "mqttcrt"
|
#define preference_mqtt_crt "mqttcrt"
|
||||||
#define preference_mqtt_key "mqttkey"
|
#define preference_mqtt_key "mqttkey"
|
||||||
@@ -50,7 +51,7 @@ class DebugPreferences
|
|||||||
private:
|
private:
|
||||||
std::vector<char*> _keys =
|
std::vector<char*> _keys =
|
||||||
{
|
{
|
||||||
preference_started_before, preference_deviceId, preference_mqtt_broker, preference_mqtt_broker_port, preference_mqtt_user, preference_mqtt_password, preference_mqtt_log_enabled, preference_lock_enabled, preference_mqtt_lock_path, preference_opener_enabled, preference_mqtt_opener_path, preference_max_keypad_code_count, preference_mqtt_ca, preference_mqtt_crt, preference_mqtt_key, preference_mqtt_hass_discovery, preference_network_hardware, preference_network_hardware_gpio, preference_rssi_publish_interval, preference_hostname, preference_network_timeout, preference_restart_on_disconnect, preference_restart_timer, preference_restart_ble_beacon_lost, preference_query_interval_lockstate, preference_query_interval_configuration, preference_query_interval_battery, preference_query_interval_keypad, preference_keypad_control_enabled, preference_register_as_app, preference_command_nr_of_retries, preference_command_retry_delay, preference_cred_user, preference_cred_password, preference_publish_authdata, preference_gpio_locking_enabled, preference_publish_debug_info, preference_presence_detection_timeout, preference_has_mac_saved, preference_has_mac_byte_0, preference_has_mac_byte_1, preference_has_mac_byte_2,
|
preference_started_before, preference_deviceId, preference_mqtt_broker, preference_mqtt_broker_port, preference_mqtt_user, preference_mqtt_password, preference_mqtt_log_enabled, preference_lock_enabled, preference_mqtt_lock_path, preference_opener_enabled, preference_mqtt_opener_path, preference_lock_max_keypad_code_count, preference_opener_max_keypad_code_count, preference_mqtt_ca, preference_mqtt_crt, preference_mqtt_key, preference_mqtt_hass_discovery, preference_network_hardware, preference_network_hardware_gpio, preference_rssi_publish_interval, preference_hostname, preference_network_timeout, preference_restart_on_disconnect, preference_restart_timer, preference_restart_ble_beacon_lost, preference_query_interval_lockstate, preference_query_interval_configuration, preference_query_interval_battery, preference_query_interval_keypad, preference_keypad_control_enabled, preference_register_as_app, preference_command_nr_of_retries, preference_command_retry_delay, preference_cred_user, preference_cred_password, preference_publish_authdata, preference_gpio_locking_enabled, preference_publish_debug_info, preference_presence_detection_timeout, preference_has_mac_saved, preference_has_mac_byte_0, preference_has_mac_byte_1, preference_has_mac_byte_2,
|
||||||
};
|
};
|
||||||
std::vector<char*> _redact =
|
std::vector<char*> _redact =
|
||||||
{
|
{
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user