Extend keypad
This commit is contained in:
@@ -32,6 +32,7 @@ NukiOpenerWrapper::NukiOpenerWrapper(const std::string& deviceName, NukiDeviceId
|
||||
network->setLockActionReceivedCallback(nukiOpenerInst->onLockActionReceivedCallback);
|
||||
network->setConfigUpdateReceivedCallback(nukiOpenerInst->onConfigUpdateReceivedCallback);
|
||||
network->setKeypadCommandReceivedCallback(nukiOpenerInst->onKeypadCommandReceivedCallback);
|
||||
network->setKeypadJsonCommandReceivedCallback(nukiOpenerInst->onKeypadJsonCommandReceivedCallback);
|
||||
|
||||
_gpio->addCallback(NukiOpenerWrapper::gpioActionCallback);
|
||||
}
|
||||
@@ -87,13 +88,6 @@ void NukiOpenerWrapper::initialize()
|
||||
_intervalKeypad = 60 * 30;
|
||||
_preferences->putInt(preference_query_interval_keypad, _intervalKeypad);
|
||||
}
|
||||
/*
|
||||
if(_intervalKeypad == 0)
|
||||
{
|
||||
_intervalKeypad = 60 * 30;
|
||||
_preferences->putInt(preference_query_interval_keypad, _intervalKeypad);
|
||||
}
|
||||
*/
|
||||
if(_restartBeaconTimeout < 10)
|
||||
{
|
||||
_restartBeaconTimeout = -1;
|
||||
@@ -407,7 +401,7 @@ void NukiOpenerWrapper::updateConfig()
|
||||
|
||||
if(_preferences->getUInt(preference_nuki_id_opener, 0) == _nukiConfig.nukiId)
|
||||
{
|
||||
_hasKeypad = _nukiConfig.hasKeypad > 0 || _nukiConfig.hasKeypadV2;
|
||||
_hasKeypad = _nukiConfig.hasKeypad > 0 || _nukiConfig.hasKeypadV2 > 0;
|
||||
_firmwareVersion = std::to_string(_nukiConfig.firmwareVersion[0]) + "." + std::to_string(_nukiConfig.firmwareVersion[1]) + "." + std::to_string(_nukiConfig.firmwareVersion[2]);
|
||||
_hardwareVersion = std::to_string(_nukiConfig.hardwareRevision[0]) + "." + std::to_string(_nukiConfig.hardwareRevision[1]);
|
||||
_network->publishConfig(_nukiConfig);
|
||||
@@ -473,7 +467,7 @@ void NukiOpenerWrapper::updateAuthData()
|
||||
|
||||
void NukiOpenerWrapper::updateKeypad()
|
||||
{
|
||||
if(_preferences->getBool(preference_keypad_info_enabled)) return;
|
||||
if(!_preferences->getBool(preference_keypad_info_enabled)) return;
|
||||
|
||||
Log->print(F("Querying opener keypad: "));
|
||||
Nuki::CmdResult result = _nukiOpener.retrieveKeypadEntries(0, 0xffff);
|
||||
@@ -557,6 +551,11 @@ void NukiOpenerWrapper::onKeypadCommandReceivedCallback(const char *command, con
|
||||
nukiOpenerInst->onKeypadCommandReceived(command, id, name, code, enabled);
|
||||
}
|
||||
|
||||
void NukiOpenerWrapper::onKeypadJsonCommandReceivedCallback(const char *value)
|
||||
{
|
||||
nukiOpenerInst->onKeypadJsonCommandReceived(value);
|
||||
}
|
||||
|
||||
void NukiOpenerWrapper::gpioActionCallback(const GpioAction &action, const int& pin)
|
||||
{
|
||||
switch(action)
|
||||
@@ -726,6 +725,350 @@ void NukiOpenerWrapper::onKeypadCommandReceived(const char *command, const uint
|
||||
}
|
||||
}
|
||||
|
||||
void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value)
|
||||
{
|
||||
if(_nukiOpener.getSecurityPincode() == 0)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("noPinSet");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!_preferences->getBool(preference_keypad_control_enabled))
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("keypadControlDisabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!_hasKeypad)
|
||||
{
|
||||
if(_configRead && _nukiConfigValid)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("keypadNotAvailable");
|
||||
return;
|
||||
}
|
||||
|
||||
updateConfig();
|
||||
|
||||
while (!_nukiConfigValid && _retryConfigCount < 11)
|
||||
{
|
||||
updateConfig();
|
||||
}
|
||||
|
||||
if(_configRead && _nukiConfigValid)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("keypadNotAvailable");
|
||||
return;
|
||||
}
|
||||
|
||||
_network->publishKeypadJsonCommandResult("invalidConfig");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!_keypadEnabled)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("keypadDisabled");
|
||||
return;
|
||||
}
|
||||
|
||||
DynamicJsonDocument json(2048);
|
||||
DeserializationError jsonError = deserializeJson(json, value);
|
||||
|
||||
if(jsonError)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("invalidJson");
|
||||
return;
|
||||
}
|
||||
|
||||
Nuki::CmdResult result = (Nuki::CmdResult)-1;
|
||||
|
||||
const char *action = json["action"].as<const char*>();
|
||||
uint16_t codeId = json["codeId"].as<unsigned int>();
|
||||
uint32_t code = json["code"].as<unsigned int>();
|
||||
String codeStr = json["code"].as<String>();
|
||||
const char *name = json["name"].as<const char*>();
|
||||
uint8_t enabled = json["enabled"].as<unsigned int>();
|
||||
uint8_t timeLimited = json["timeLimited"].as<unsigned int>();
|
||||
const char *allowedFrom = json["allowedFrom"].as<const char*>();
|
||||
const char *allowedUntil = json["allowedUntil"].as<const char*>();
|
||||
String allowedWeekdays = json["allowedWeekdays"].as<String>();
|
||||
const char *allowedFromTime = json["allowedFromTime"].as<const char*>();
|
||||
const char *allowedUntilTime = json["allowedUntilTime"].as<const char*>();
|
||||
|
||||
if(action)
|
||||
{
|
||||
bool idExists = false;
|
||||
|
||||
if(codeId)
|
||||
{
|
||||
idExists = std::find(_keypadCodeIds.begin(), _keypadCodeIds.end(), codeId) != _keypadCodeIds.end();
|
||||
}
|
||||
|
||||
if(strcmp(action, "delete") == 0) {
|
||||
if(idExists)
|
||||
{
|
||||
result = _nukiOpener.deleteKeypadEntry(codeId);
|
||||
Log->print("Delete keypad code: ");
|
||||
Log->println((int)result);
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("noExistingCodeIdSet");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(strcmp(action, "add") == 0 || strcmp(action, "update") == 0)
|
||||
{
|
||||
if(!name)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("noNameSet");
|
||||
return;
|
||||
}
|
||||
|
||||
if(code)
|
||||
{
|
||||
bool codeValid = code > 100000 && code < 1000000 && (codeStr.indexOf('0') == -1);
|
||||
|
||||
if (!codeValid)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("noValidCodeSet");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("noCodeSet");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int allowedFromAr[6];
|
||||
unsigned int allowedUntilAr[6];
|
||||
unsigned int allowedFromTimeAr[2];
|
||||
unsigned int allowedUntilTimeAr[2];
|
||||
uint8_t allowedWeekdaysInt = 0;
|
||||
|
||||
if(timeLimited == 1 && enabled != 0)
|
||||
{
|
||||
if(allowedFrom)
|
||||
{
|
||||
if(strlen(allowedFrom) == 19)
|
||||
{
|
||||
String allowedFromStr = allowedFrom;
|
||||
allowedFromAr[0] = (uint16_t)allowedFromStr.substring(0, 4).toInt();
|
||||
allowedFromAr[1] = (uint8_t)allowedFromStr.substring(5, 7).toInt();
|
||||
allowedFromAr[2] = (uint8_t)allowedFromStr.substring(8, 10).toInt();
|
||||
allowedFromAr[3] = (uint8_t)allowedFromStr.substring(11, 13).toInt();
|
||||
allowedFromAr[4] = (uint8_t)allowedFromStr.substring(14, 16).toInt();
|
||||
allowedFromAr[5] = (uint8_t)allowedFromStr.substring(17, 19).toInt();
|
||||
|
||||
if(allowedFromAr[0] < 2000 || allowedFromAr[0] > 3000 || allowedFromAr[1] < 1 || allowedFromAr[1] > 12 || allowedFromAr[2] < 1 || allowedFromAr[2] > 31 || allowedFromAr[3] < 0 || allowedFromAr[3] > 23 || allowedFromAr[4] < 0 || allowedFromAr[4] > 59 || allowedFromAr[5] < 0 || allowedFromAr[5] > 59)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("invalidAllowedFrom");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("invalidAllowedFrom");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(allowedUntil)
|
||||
{
|
||||
if(strlen(allowedUntil) == 19)
|
||||
{
|
||||
String allowedUntilStr = allowedUntil;
|
||||
allowedUntilAr[0] = (uint16_t)allowedUntilStr.substring(0, 4).toInt();
|
||||
allowedUntilAr[1] = (uint8_t)allowedUntilStr.substring(5, 7).toInt();
|
||||
allowedUntilAr[2] = (uint8_t)allowedUntilStr.substring(8, 10).toInt();
|
||||
allowedUntilAr[3] = (uint8_t)allowedUntilStr.substring(11, 13).toInt();
|
||||
allowedUntilAr[4] = (uint8_t)allowedUntilStr.substring(14, 16).toInt();
|
||||
allowedUntilAr[5] = (uint8_t)allowedUntilStr.substring(17, 19).toInt();
|
||||
|
||||
if(allowedUntilAr[0] < 2000 || allowedUntilAr[0] > 3000 || allowedUntilAr[1] < 1 || allowedUntilAr[1] > 12 || allowedUntilAr[2] < 1 || allowedUntilAr[2] > 31 || allowedUntilAr[3] < 0 || allowedUntilAr[3] > 23 || allowedUntilAr[4] < 0 || allowedUntilAr[4] > 59 || allowedUntilAr[5] < 0 || allowedUntilAr[5] > 59)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("invalidAllowedUntil");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("invalidAllowedUntil");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(allowedFromTime)
|
||||
{
|
||||
if(strlen(allowedFromTime) == 5)
|
||||
{
|
||||
String allowedFromTimeStr = allowedFromTime;
|
||||
allowedFromTimeAr[0] = (uint8_t)allowedFromTimeStr.substring(0, 2).toInt();
|
||||
allowedFromTimeAr[1] = (uint8_t)allowedFromTimeStr.substring(3, 5).toInt();
|
||||
|
||||
if(allowedFromTimeAr[0] < 0 || allowedFromTimeAr[0] > 23 || allowedFromTimeAr[1] < 0 || allowedFromTimeAr[1] > 59)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("invalidAllowedFromTime");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("invalidAllowedFromTime");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(allowedUntilTime)
|
||||
{
|
||||
if(strlen(allowedUntilTime) == 5)
|
||||
{
|
||||
String allowedUntilTimeStr = allowedUntilTime;
|
||||
allowedUntilTimeAr[0] = (uint8_t)allowedUntilTimeStr.substring(0, 2).toInt();
|
||||
allowedUntilTimeAr[1] = (uint8_t)allowedUntilTimeStr.substring(3, 5).toInt();
|
||||
|
||||
if(allowedUntilTimeAr[0] < 0 || allowedUntilTimeAr[0] > 23 || allowedUntilTimeAr[1] < 0 || allowedUntilTimeAr[1] > 59)
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("invalidAllowedUntilTime");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("invalidAllowedUntilTime");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(allowedWeekdays.indexOf("mon") >= 0) allowedWeekdaysInt += 64;
|
||||
if(allowedWeekdays.indexOf("tue") >= 0) allowedWeekdaysInt += 32;
|
||||
if(allowedWeekdays.indexOf("wed") >= 0) allowedWeekdaysInt += 16;
|
||||
if(allowedWeekdays.indexOf("thu") >= 0) allowedWeekdaysInt += 8;
|
||||
if(allowedWeekdays.indexOf("fri") >= 0) allowedWeekdaysInt += 4;
|
||||
if(allowedWeekdays.indexOf("sat") >= 0) allowedWeekdaysInt += 2;
|
||||
if(allowedWeekdays.indexOf("sun") >= 0) allowedWeekdaysInt += 1;
|
||||
}
|
||||
|
||||
if(strcmp(action, "add") == 0)
|
||||
{
|
||||
NukiOpener::NewKeypadEntry entry;
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
size_t nameLen = strlen(name);
|
||||
memcpy(&entry.name, name, nameLen > 20 ? 20 : nameLen);
|
||||
entry.code = code;
|
||||
entry.timeLimited = timeLimited == 1 ? 1 : 0;
|
||||
|
||||
if(allowedFrom)
|
||||
{
|
||||
entry.allowedFromYear = allowedFromAr[0];
|
||||
entry.allowedFromMonth = allowedFromAr[1];
|
||||
entry.allowedFromDay = allowedFromAr[2];
|
||||
entry.allowedFromHour = allowedFromAr[3];
|
||||
entry.allowedFromMin = allowedFromAr[4];
|
||||
entry.allowedFromSec = allowedFromAr[5];
|
||||
}
|
||||
|
||||
if(allowedUntil)
|
||||
{
|
||||
entry.allowedUntilYear = allowedUntilAr[0];
|
||||
entry.allowedUntilMonth = allowedUntilAr[1];
|
||||
entry.allowedUntilDay = allowedUntilAr[2];
|
||||
entry.allowedUntilHour = allowedUntilAr[3];
|
||||
entry.allowedUntilMin = allowedUntilAr[4];
|
||||
entry.allowedUntilSec = allowedUntilAr[5];
|
||||
}
|
||||
|
||||
entry.allowedWeekdays = allowedWeekdaysInt;
|
||||
|
||||
if(allowedFromTime)
|
||||
{
|
||||
entry.allowedFromTimeHour = allowedFromTimeAr[0];
|
||||
entry.allowedFromTimeMin = allowedFromTimeAr[1];
|
||||
}
|
||||
|
||||
if(allowedUntilTime)
|
||||
{
|
||||
entry.allowedUntilTimeHour = allowedUntilTimeAr[0];
|
||||
entry.allowedUntilTimeMin = allowedUntilTimeAr[1];
|
||||
}
|
||||
|
||||
result = _nukiOpener.addKeypadEntry(entry);
|
||||
Log->print("Add keypad code: ");
|
||||
Log->println((int)result);
|
||||
}
|
||||
else if (strcmp(action, "update") == 0)
|
||||
{
|
||||
NukiOpener::UpdatedKeypadEntry entry;
|
||||
memset(&entry, 0, sizeof(entry));
|
||||
entry.codeId = codeId;
|
||||
size_t nameLen = strlen(name);
|
||||
memcpy(&entry.name, name, nameLen > 20 ? 20 : nameLen);
|
||||
entry.code = code;
|
||||
entry.enabled = enabled == 0 ? 0 : 1;
|
||||
entry.timeLimited = timeLimited == 1 ? 1 : 0;
|
||||
|
||||
if(allowedFrom)
|
||||
{
|
||||
entry.allowedFromYear = allowedFromAr[0];
|
||||
entry.allowedFromMonth = allowedFromAr[1];
|
||||
entry.allowedFromDay = allowedFromAr[2];
|
||||
entry.allowedFromHour = allowedFromAr[3];
|
||||
entry.allowedFromMin = allowedFromAr[4];
|
||||
entry.allowedFromSec = allowedFromAr[5];
|
||||
}
|
||||
|
||||
if(allowedUntil)
|
||||
{
|
||||
entry.allowedUntilYear = allowedUntilAr[0];
|
||||
entry.allowedUntilMonth = allowedUntilAr[1];
|
||||
entry.allowedUntilDay = allowedUntilAr[2];
|
||||
entry.allowedUntilHour = allowedUntilAr[3];
|
||||
entry.allowedUntilMin = allowedUntilAr[4];
|
||||
entry.allowedUntilSec = allowedUntilAr[5];
|
||||
}
|
||||
|
||||
entry.allowedWeekdays = allowedWeekdaysInt;
|
||||
|
||||
if(allowedFromTime)
|
||||
{
|
||||
entry.allowedFromTimeHour = allowedFromTimeAr[0];
|
||||
entry.allowedFromTimeMin = allowedFromTimeAr[1];
|
||||
}
|
||||
|
||||
if(allowedUntilTime)
|
||||
{
|
||||
entry.allowedUntilTimeHour = allowedUntilTimeAr[0];
|
||||
entry.allowedUntilTimeMin = allowedUntilTimeAr[1];
|
||||
}
|
||||
|
||||
result = _nukiOpener.updateKeypadEntry(entry);
|
||||
Log->print("Update keypad code: ");
|
||||
Log->println((int)result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("invalidAction");
|
||||
return;
|
||||
}
|
||||
|
||||
updateKeypad();
|
||||
|
||||
if((int)result != -1)
|
||||
{
|
||||
char resultStr[15];
|
||||
memset(&resultStr, 0, sizeof(resultStr));
|
||||
NukiOpener::cmdResultToString(result, resultStr);
|
||||
_network->publishKeypadJsonCommandResult(resultStr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_network->publishKeypadJsonCommandResult("noActionSet");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const NukiOpener::OpenerState &NukiOpenerWrapper::keyTurnerState()
|
||||
{
|
||||
return _keyTurnerState;
|
||||
|
||||
Reference in New Issue
Block a user