add keypad control for opener
This commit is contained in:
@@ -25,6 +25,7 @@ NukiOpenerWrapper::NukiOpenerWrapper(const std::string& deviceName, uint32_t id,
|
||||
|
||||
network->setLockActionReceivedCallback(nukiOpenerInst->onLockActionReceivedCallback);
|
||||
network->setConfigUpdateReceivedCallback(nukiOpenerInst->onConfigUpdateReceivedCallback);
|
||||
network->setKeypadCommandReceivedCallback(nukiOpenerInst->onKeypadCommandReceivedCallback);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,10 +41,12 @@ void NukiOpenerWrapper::initialize()
|
||||
_nukiOpener.registerBleScanner(_bleScanner);
|
||||
|
||||
_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);
|
||||
_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);
|
||||
_maxKeypadCodeCount = _preferences->getUInt(preference_opener_max_keypad_code_count);
|
||||
_restartBeaconTimeout = _preferences->getInt(preference_restart_ble_beacon_lost);
|
||||
_hassEnabled = _preferences->getString(preference_mqtt_hass_discovery) != "";
|
||||
_nrOfRetries = _preferences->getInt(preference_command_nr_of_retries);
|
||||
@@ -71,6 +74,11 @@ void NukiOpenerWrapper::initialize()
|
||||
_intervalBattery = 60 * 30;
|
||||
_preferences->putInt(preference_query_interval_battery, _intervalBattery);
|
||||
}
|
||||
if(_intervalKeypad == 0)
|
||||
{
|
||||
_intervalKeypad = 60 * 30;
|
||||
_preferences->putInt(preference_query_interval_keypad, _intervalKeypad);
|
||||
}
|
||||
/*
|
||||
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)
|
||||
{
|
||||
Nuki::CmdResult cmdResult = _nukiOpener.lockAction(_nextLockAction, 0, 0);
|
||||
@@ -296,6 +310,8 @@ void NukiOpenerWrapper::updateConfig()
|
||||
{
|
||||
readConfig();
|
||||
readAdvancedConfig();
|
||||
_configRead = true;
|
||||
_hasKeypad = _nukiConfig.hasKeypad > 0;
|
||||
_network->publishConfig(_nukiConfig);
|
||||
_network->publishAdvancedConfig(_nukiAdvancedConfig);
|
||||
}
|
||||
@@ -328,6 +344,35 @@ void NukiOpenerWrapper::updateAuthData()
|
||||
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()
|
||||
{
|
||||
_disableBleWatchdogTs = millis() + 15000;
|
||||
@@ -358,6 +403,10 @@ void NukiOpenerWrapper::onConfigUpdateReceivedCallback(const char *topic, const
|
||||
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)
|
||||
{
|
||||
@@ -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()
|
||||
{
|
||||
return _keyTurnerState;
|
||||
|
||||
Reference in New Issue
Block a user