Merge branch 'master' into separate-config

This commit is contained in:
iranl
2024-04-25 16:58:32 +02:00
committed by GitHub
23 changed files with 935 additions and 1676 deletions

View File

@@ -172,6 +172,11 @@ void NukiOpenerWrapper::update()
setupHASS();
}
}
if(_nextTimeControlUpdateTs != 0 && ts > _nextTimeControlUpdateTs)
{
_nextTimeControlUpdateTs = 0;
updateTimeControl(true);
}
if(_hassEnabled && _configRead && _network->reconnected())
{
setupHASS();
@@ -406,7 +411,9 @@ void NukiOpenerWrapper::updateConfig()
_hardwareVersion = std::to_string(_nukiConfig.hardwareRevision[0]) + "." + std::to_string(_nukiConfig.hardwareRevision[1]);
_network->publishConfig(_nukiConfig);
_retryConfigCount = 0;
if(_preferences->getBool(preference_timecontrol_info_enabled)) updateTimeControl(false);
const int pinStatus = _preferences->getInt(preference_opener_pin_status, 4);
if(isPinSet()) {
@@ -501,6 +508,9 @@ void NukiOpenerWrapper::updateKeypad()
{
std::list<NukiLock::KeypadEntry> entries;
_nukiOpener.getKeypadEntries(&entries);
Log->print(F("Opener keypad codes: "));
Log->println(entries.size());
entries.sort([](const NukiLock::KeypadEntry& a, const NukiLock::KeypadEntry& b) { return a.codeId < b.codeId; });
@@ -524,6 +534,43 @@ void NukiOpenerWrapper::updateKeypad()
postponeBleWatchdog();
}
void NukiOpenerWrapper::updateTimeControl(bool retrieved)
{
if(!_preferences->getBool(preference_timecontrol_info_enabled)) return;
if(!retrieved)
{
Log->print(F("Querying opener time control: "));
Nuki::CmdResult result = _nukiOpener.retrieveTimeControlEntries();
printCommandResult(result);
if(result == Nuki::CmdResult::Success)
{
_nextTimeControlUpdateTs = millis() + 5000;
}
}
else
{
std::list<NukiOpener::TimeControlEntry> timeControlEntries;
_nukiOpener.getTimeControlEntries(&timeControlEntries);
Log->print(F("Opener time control entries: "));
Log->println(timeControlEntries.size());
timeControlEntries.sort([](const NukiOpener::TimeControlEntry& a, const NukiOpener::TimeControlEntry& b) { return a.entryId < b.entryId; });
_network->publishTimeControl(timeControlEntries);
_timeControlIds.clear();
_timeControlIds.reserve(timeControlEntries.size());
for(const auto& entry : timeControlEntries)
{
_timeControlIds.push_back(entry.entryId);
}
}
postponeBleWatchdog();
}
void NukiOpenerWrapper::postponeBleWatchdog()
{
_disableBleWatchdogTs = millis() + 15000;
@@ -531,24 +578,31 @@ void NukiOpenerWrapper::postponeBleWatchdog()
NukiOpener::LockAction NukiOpenerWrapper::lockActionToEnum(const char *str)
{
if(strcmp(str, "activateRTO") == 0) return NukiOpener::LockAction::ActivateRTO;
else if(strcmp(str, "deactivateRTO") == 0) return NukiOpener::LockAction::DeactivateRTO;
else if(strcmp(str, "electricStrikeActuation") == 0) return NukiOpener::LockAction::ElectricStrikeActuation;
else if(strcmp(str, "activateCM") == 0) return NukiOpener::LockAction::ActivateCM;
else if(strcmp(str, "deactivateCM") == 0) return NukiOpener::LockAction::DeactivateCM;
else if(strcmp(str, "fobAction2") == 0) return NukiOpener::LockAction::FobAction2;
else if(strcmp(str, "fobAction1") == 0) return NukiOpener::LockAction::FobAction1;
else if(strcmp(str, "fobAction3") == 0) return NukiOpener::LockAction::FobAction3;
if(strcmp(str, "activateRTO") == 0 || strcmp(str, "ActivateRTO") == 0) return NukiOpener::LockAction::ActivateRTO;
else if(strcmp(str, "deactivateRTO") == 0 || strcmp(str, "DeactivateRTO") == 0) return NukiOpener::LockAction::DeactivateRTO;
else if(strcmp(str, "electricStrikeActuation") == 0 || strcmp(str, "ElectricStrikeActuation") == 0) return NukiOpener::LockAction::ElectricStrikeActuation;
else if(strcmp(str, "activateCM") == 0 || strcmp(str, "ActivateCM") == 0) return NukiOpener::LockAction::ActivateCM;
else if(strcmp(str, "deactivateCM") == 0 || strcmp(str, "DeactivateCM") == 0) return NukiOpener::LockAction::DeactivateCM;
else if(strcmp(str, "fobAction2") == 0 || strcmp(str, "FobAction2") == 0) return NukiOpener::LockAction::FobAction2;
else if(strcmp(str, "fobAction1") == 0 || strcmp(str, "FobAction1") == 0) return NukiOpener::LockAction::FobAction1;
else if(strcmp(str, "fobAction3") == 0 || strcmp(str, "FobAction3") == 0) return NukiOpener::LockAction::FobAction3;
return (NukiOpener::LockAction)0xff;
}
LockActionResult NukiOpenerWrapper::onLockActionReceivedCallback(const char *value)
{
NukiOpener::LockAction action = nukiOpenerInst->lockActionToEnum(value);
if((int)action == 0xff)
NukiOpener::LockAction action;
if(strlen(value) > 0)
{
return LockActionResult::UnknownAction;
action = nukiOpenerInst->lockActionToEnum(value);
if((int)action == 0xff)
{
return LockActionResult::UnknownAction;
}
}
else return LockActionResult::UnknownAction;
nukiOpenerPreferences = new Preferences();
nukiOpenerPreferences->begin("nukihub", true);
@@ -1672,6 +1726,181 @@ void NukiOpenerWrapper::onKeypadJsonCommandReceived(const char *value)
}
}
void NukiOpenerWrapper::onTimeControlCommandReceived(const char *value)
{
if(_nukiOpener.getSecurityPincode() == 0)
{
_network->publishTimeControlCommandResult("noPinSet");
return;
}
if(!_preferences->getBool(preference_timecontrol_control_enabled))
{
_network->publishTimeControlCommandResult("timeControlControlDisabled");
return;
}
JsonDocument json;
DeserializationError jsonError = deserializeJson(json, value);
if(jsonError)
{
_network->publishTimeControlCommandResult("invalidJson");
return;
}
Nuki::CmdResult result = (Nuki::CmdResult)-1;
const char *action = json["action"].as<const char*>();
uint8_t entryId = json["entryId"].as<unsigned int>();
uint8_t enabled = json["enabled"].as<unsigned int>();
String weekdays = json["weekdays"].as<String>();
const char *time = json["time"].as<const char*>();
const char *lockAct = json["lockAction"].as<const char*>();
NukiOpener::LockAction timeControlLockAction;
if(strlen(lockAct) > 0)
{
timeControlLockAction = nukiOpenerInst->lockActionToEnum(lockAct);
if((int)timeControlLockAction == 0xff)
{
_network->publishTimeControlCommandResult("invalidLockAction");
return;
}
}
else
{
_network->publishTimeControlCommandResult("invalidLockAction");
return;
}
if(action)
{
bool idExists = false;
if(entryId)
{
idExists = std::find(_timeControlIds.begin(), _timeControlIds.end(), entryId) != _timeControlIds.end();
}
if(strcmp(action, "delete") == 0) {
if(idExists)
{
result = _nukiOpener.removeTimeControlEntry(entryId);
Log->print("Delete time control ");
Log->println((int)result);
}
else
{
_network->publishTimeControlCommandResult("noExistingEntryIdSet");
return;
}
}
else if(strcmp(action, "add") == 0 || strcmp(action, "update") == 0)
{
uint8_t timeHour;
uint8_t timeMin;
uint8_t weekdaysInt = 0;
unsigned int timeAr[2];
if(time)
{
if(strlen(time) == 5)
{
String timeStr = time;
timeAr[0] = (uint8_t)timeStr.substring(0, 2).toInt();
timeAr[1] = (uint8_t)timeStr.substring(3, 5).toInt();
if(timeAr[0] < 0 || timeAr[0] > 23 || timeAr[1] < 0 || timeAr[1] > 59)
{
_network->publishTimeControlCommandResult("invalidTime");
return;
}
}
else
{
_network->publishTimeControlCommandResult("invalidTime");
return;
}
}
else
{
_network->publishTimeControlCommandResult("invalidTime");
return;
}
if(weekdays.indexOf("mon") >= 0) weekdaysInt += 64;
if(weekdays.indexOf("tue") >= 0) weekdaysInt += 32;
if(weekdays.indexOf("wed") >= 0) weekdaysInt += 16;
if(weekdays.indexOf("thu") >= 0) weekdaysInt += 8;
if(weekdays.indexOf("fri") >= 0) weekdaysInt += 4;
if(weekdays.indexOf("sat") >= 0) weekdaysInt += 2;
if(weekdays.indexOf("sun") >= 0) weekdaysInt += 1;
if(strcmp(action, "add") == 0)
{
NukiOpener::NewTimeControlEntry entry;
memset(&entry, 0, sizeof(entry));
entry.weekdays = weekdaysInt;
if(time)
{
entry.timeHour = timeAr[0];
entry.timeMin = timeAr[1];
}
entry.lockAction = timeControlLockAction;
result = _nukiOpener.addTimeControlEntry(entry);
Log->print("Add time control: ");
Log->println((int)result);
}
else if (strcmp(action, "update") == 0)
{
NukiOpener::TimeControlEntry entry;
memset(&entry, 0, sizeof(entry));
entry.entryId = entryId;
entry.enabled = enabled == 0 ? 0 : 1;
entry.weekdays = weekdaysInt;
if(time)
{
entry.timeHour = timeAr[0];
entry.timeMin = timeAr[1];
}
entry.lockAction = timeControlLockAction;
result = _nukiOpener.updateTimeControlEntry(entry);
Log->print("Update time control: ");
Log->println((int)result);
}
}
else
{
_network->publishTimeControlCommandResult("invalidAction");
return;
}
if((int)result != -1)
{
char resultStr[15];
memset(&resultStr, 0, sizeof(resultStr));
NukiOpener::cmdResultToString(result, resultStr);
_network->publishTimeControlCommandResult(resultStr);
}
_nextConfigUpdateTs = millis() + 300;
}
else
{
_network->publishTimeControlCommandResult("noActionSet");
return;
}
}
const NukiOpener::OpenerState &NukiOpenerWrapper::keyTurnerState()
{
return _keyTurnerState;