Merge pull request #75 from technyon/add_retry_mechanic
Add retry mechanic
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
#define mqtt_topic_lock_action "/lock/action"
|
#define mqtt_topic_lock_action "/lock/action"
|
||||||
#define mqtt_topic_lock_rssi "/lock/rssi"
|
#define mqtt_topic_lock_rssi "/lock/rssi"
|
||||||
#define mqtt_topic_lock_address "/lock/address"
|
#define mqtt_topic_lock_address "/lock/address"
|
||||||
|
#define mqtt_topic_lock_retry "/lock/retry"
|
||||||
|
|
||||||
#define mqtt_topic_config_button_enabled "/configuration/buttonEnabled"
|
#define mqtt_topic_config_button_enabled "/configuration/buttonEnabled"
|
||||||
#define mqtt_topic_config_led_enabled "/configuration/ledEnabled"
|
#define mqtt_topic_config_led_enabled "/configuration/ledEnabled"
|
||||||
|
|||||||
@@ -388,6 +388,11 @@ void NetworkLock::publishRssi(const int& rssi)
|
|||||||
publishInt(mqtt_topic_lock_rssi, rssi);
|
publishInt(mqtt_topic_lock_rssi, rssi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkLock::publishRetry(const std::string& message)
|
||||||
|
{
|
||||||
|
publishString(mqtt_topic_lock_retry, message.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkLock::publishBleAddress(const std::string &address)
|
void NetworkLock::publishBleAddress(const std::string &address)
|
||||||
{
|
{
|
||||||
publishString(mqtt_topic_lock_address, address.c_str());
|
publishString(mqtt_topic_lock_address, address.c_str());
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public:
|
|||||||
void publishConfig(const NukiLock::Config& config);
|
void publishConfig(const NukiLock::Config& config);
|
||||||
void publishAdvancedConfig(const NukiLock::AdvancedConfig& config);
|
void publishAdvancedConfig(const NukiLock::AdvancedConfig& config);
|
||||||
void publishRssi(const int& rssi);
|
void publishRssi(const int& rssi);
|
||||||
|
void publishRetry(const std::string& message);
|
||||||
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);
|
||||||
|
|||||||
@@ -382,6 +382,11 @@ void NetworkOpener::publishRssi(const int &rssi)
|
|||||||
publishInt(mqtt_topic_lock_rssi, rssi);
|
publishInt(mqtt_topic_lock_rssi, rssi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkOpener::publishRetry(const std::string& message)
|
||||||
|
{
|
||||||
|
publishString(mqtt_topic_lock_retry, message.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkOpener::publishBleAddress(const std::string &address)
|
void NetworkOpener::publishBleAddress(const std::string &address)
|
||||||
{
|
{
|
||||||
publishString(mqtt_topic_lock_address, address.c_str());
|
publishString(mqtt_topic_lock_address, address.c_str());
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public:
|
|||||||
void publishConfig(const NukiOpener::Config& config);
|
void publishConfig(const NukiOpener::Config& config);
|
||||||
void publishAdvancedConfig(const NukiOpener::AdvancedConfig& config);
|
void publishAdvancedConfig(const NukiOpener::AdvancedConfig& config);
|
||||||
void publishRssi(const int& rssi);
|
void publishRssi(const int& rssi);
|
||||||
|
void publishRetry(const std::string& message);
|
||||||
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);
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ void NukiOpenerWrapper::initialize()
|
|||||||
_publishAuthData = _preferences->getBool(preference_publish_authdata);
|
_publishAuthData = _preferences->getBool(preference_publish_authdata);
|
||||||
_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);
|
||||||
|
_retryDelay = _preferences->getInt(preference_command_retry_delay);
|
||||||
|
|
||||||
if(_intervalLockstate == 0)
|
if(_intervalLockstate == 0)
|
||||||
{
|
{
|
||||||
@@ -142,22 +144,53 @@ void NukiOpenerWrapper::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_nextLockAction != (NukiOpener::LockAction)0xff)
|
if(_nextLockAction != (NukiOpener::LockAction)0xff && ts > _nextRetryTs)
|
||||||
{
|
{
|
||||||
NukiOpener::CmdResult cmdResult = _nukiOpener.lockAction(_nextLockAction, 0, 0);
|
Nuki::CmdResult cmdResult = _nukiOpener.lockAction(_nextLockAction, 0, 0);
|
||||||
|
|
||||||
char resultStr[15] = {0};
|
char resultStr[15] = {0};
|
||||||
NukiOpener::cmdResultToString(cmdResult, resultStr);
|
NukiOpener::cmdResultToString(cmdResult, resultStr);
|
||||||
|
|
||||||
_network->publishCommandResult(resultStr);
|
_network->publishCommandResult(resultStr);
|
||||||
|
|
||||||
Log->print(F("Opener lock action result: "));
|
Log->print(F("Lock action result: "));
|
||||||
Log->println(resultStr);
|
Log->println(resultStr);
|
||||||
|
|
||||||
_nextLockAction = (NukiOpener::LockAction)0xff;
|
if(cmdResult == Nuki::CmdResult::Success)
|
||||||
if(_intervalLockstate > 10)
|
|
||||||
{
|
{
|
||||||
_nextLockStateUpdateTs = ts + 10 * 1000;
|
_retryCount = 0;
|
||||||
|
_nextLockAction = (NukiOpener::LockAction) 0xff;
|
||||||
|
_network->publishRetry("--");
|
||||||
|
if (_intervalLockstate > 10)
|
||||||
|
{
|
||||||
|
_nextLockStateUpdateTs = ts + 10 * 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(_retryCount < _nrOfRetries)
|
||||||
|
{
|
||||||
|
Log->print(F("Opener: Last command failed, retrying after "));
|
||||||
|
Log->print(_retryDelay);
|
||||||
|
Log->print(F(" milliseconds. Retry "));
|
||||||
|
Log->print(_retryCount + 1);
|
||||||
|
Log->print(" of ");
|
||||||
|
Log->println(_nrOfRetries);
|
||||||
|
|
||||||
|
_network->publishRetry(std::to_string(_retryCount + 1));
|
||||||
|
|
||||||
|
_nextRetryTs = millis() + _retryDelay;
|
||||||
|
|
||||||
|
++_retryCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log->println(F("Opener: Maximum number of retries exceeded, aborting."));
|
||||||
|
_network->publishRetry("failed");
|
||||||
|
_retryCount = 0;
|
||||||
|
_nextRetryTs = 0;
|
||||||
|
_nextLockAction = (NukiOpener::LockAction) 0xff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ private:
|
|||||||
int _restartBeaconTimeout = 0; // seconds
|
int _restartBeaconTimeout = 0; // seconds
|
||||||
bool _publishAuthData = false;
|
bool _publishAuthData = false;
|
||||||
bool _clearAuthData = false;
|
bool _clearAuthData = false;
|
||||||
|
int _nrOfRetries = 0;
|
||||||
|
int _retryDelay = 0;
|
||||||
|
int _retryCount = 0;
|
||||||
|
unsigned long _nextRetryTs = 0;
|
||||||
|
|
||||||
NukiOpener::OpenerState _lastKeyTurnerState;
|
NukiOpener::OpenerState _lastKeyTurnerState;
|
||||||
NukiOpener::OpenerState _keyTurnerState;
|
NukiOpener::OpenerState _keyTurnerState;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ NukiWrapper::~NukiWrapper()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NukiWrapper::initialize()
|
void NukiWrapper::initialize(const bool& firstStart)
|
||||||
{
|
{
|
||||||
|
|
||||||
_nukiLock.initialize();
|
_nukiLock.initialize();
|
||||||
@@ -48,6 +48,19 @@ void NukiWrapper::initialize()
|
|||||||
_maxKeypadCodeCount = _preferences->getUInt(preference_max_keypad_code_count);
|
_maxKeypadCodeCount = _preferences->getUInt(preference_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);
|
||||||
|
_retryDelay = _preferences->getInt(preference_command_retry_delay);
|
||||||
|
|
||||||
|
if(firstStart)
|
||||||
|
{
|
||||||
|
_preferences->putInt(preference_command_nr_of_retries, 3);
|
||||||
|
_preferences->putInt(preference_command_retry_delay, 1000);
|
||||||
|
}
|
||||||
|
if(_retryDelay <= 100)
|
||||||
|
{
|
||||||
|
_retryDelay = 100;
|
||||||
|
_preferences->putInt(preference_command_retry_delay, _retryDelay);
|
||||||
|
}
|
||||||
|
|
||||||
if(_intervalLockstate == 0)
|
if(_intervalLockstate == 0)
|
||||||
{
|
{
|
||||||
@@ -163,7 +176,7 @@ void NukiWrapper::update()
|
|||||||
updateKeypad();
|
updateKeypad();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_nextLockAction != (NukiLock::LockAction)0xff)
|
if(_nextLockAction != (NukiLock::LockAction)0xff && ts > _nextRetryTs)
|
||||||
{
|
{
|
||||||
Nuki::CmdResult cmdResult = _nukiLock.lockAction(_nextLockAction, 0, 0);
|
Nuki::CmdResult cmdResult = _nukiLock.lockAction(_nextLockAction, 0, 0);
|
||||||
|
|
||||||
@@ -175,10 +188,41 @@ void NukiWrapper::update()
|
|||||||
Log->print(F("Lock action result: "));
|
Log->print(F("Lock action result: "));
|
||||||
Log->println(resultStr);
|
Log->println(resultStr);
|
||||||
|
|
||||||
_nextLockAction = (NukiLock::LockAction)0xff;
|
if(cmdResult == Nuki::CmdResult::Success)
|
||||||
if(_intervalLockstate > 10)
|
|
||||||
{
|
{
|
||||||
_nextLockStateUpdateTs = ts + 10 * 1000;
|
_retryCount = 0;
|
||||||
|
_nextLockAction = (NukiLock::LockAction) 0xff;
|
||||||
|
_network->publishRetry("--");
|
||||||
|
if (_intervalLockstate > 10)
|
||||||
|
{
|
||||||
|
_nextLockStateUpdateTs = ts + 10 * 1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(_retryCount < _nrOfRetries)
|
||||||
|
{
|
||||||
|
Log->print(F("Lock: Last command failed, retrying after "));
|
||||||
|
Log->print(_retryDelay);
|
||||||
|
Log->print(F(" milliseconds. Retry "));
|
||||||
|
Log->print(_retryCount + 1);
|
||||||
|
Log->print(" of ");
|
||||||
|
Log->println(_nrOfRetries);
|
||||||
|
|
||||||
|
_network->publishRetry(std::to_string(_retryCount + 1));
|
||||||
|
|
||||||
|
_nextRetryTs = millis() + _retryDelay;
|
||||||
|
|
||||||
|
++_retryCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log->println(F("Lock: Maximum number of retries exceeded, aborting."));
|
||||||
|
_network->publishRetry("failed");
|
||||||
|
_retryCount = 0;
|
||||||
|
_nextRetryTs = 0;
|
||||||
|
_nextLockAction = (NukiLock::LockAction) 0xff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ public:
|
|||||||
NukiWrapper(const std::string& deviceName, uint32_t id, BleScanner::Scanner* scanner, NetworkLock* network, Preferences* preferences);
|
NukiWrapper(const std::string& deviceName, uint32_t id, BleScanner::Scanner* scanner, NetworkLock* network, Preferences* preferences);
|
||||||
virtual ~NukiWrapper();
|
virtual ~NukiWrapper();
|
||||||
|
|
||||||
void initialize();
|
void initialize(const bool& firstStart);
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
void lock();
|
void lock();
|
||||||
@@ -84,6 +84,10 @@ private:
|
|||||||
bool _keypadEnabled = false;
|
bool _keypadEnabled = false;
|
||||||
bool _configRead = false;
|
bool _configRead = false;
|
||||||
uint _maxKeypadCodeCount = 0;
|
uint _maxKeypadCodeCount = 0;
|
||||||
|
int _nrOfRetries = 0;
|
||||||
|
int _retryDelay = 0;
|
||||||
|
int _retryCount = 0;
|
||||||
|
unsigned long _nextRetryTs = 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;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define preference_started_befores "run"
|
#define preference_started_before "run"
|
||||||
#define preference_deviceId "deviceId"
|
#define preference_deviceId "deviceId"
|
||||||
#define preference_mqtt_broker "mqttbroker"
|
#define preference_mqtt_broker "mqttbroker"
|
||||||
#define preference_mqtt_broker_port "mqttport"
|
#define preference_mqtt_broker_port "mqttport"
|
||||||
@@ -27,6 +27,8 @@
|
|||||||
#define preference_query_interval_keypad "kpInterval"
|
#define preference_query_interval_keypad "kpInterval"
|
||||||
#define preference_keypad_control_enabled "kpEnabled"
|
#define preference_keypad_control_enabled "kpEnabled"
|
||||||
#define preference_register_as_app "regAsApp" // true = register as hub; false = register as app
|
#define preference_register_as_app "regAsApp" // true = register as hub; false = register as app
|
||||||
|
#define preference_command_nr_of_retries "nrRetry"
|
||||||
|
#define preference_command_retry_delay "rtryDelay"
|
||||||
#define preference_cred_user "crdusr"
|
#define preference_cred_user "crdusr"
|
||||||
#define preference_cred_password "crdpass"
|
#define preference_cred_password "crdpass"
|
||||||
#define preference_publish_authdata "pubauth"
|
#define preference_publish_authdata "pubauth"
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define nuki_hub_version "6.10"
|
#define nuki_hub_version "6.11"
|
||||||
@@ -307,6 +307,16 @@ bool WebCfgServer::processArgs(String& message)
|
|||||||
_preferences->putBool(preference_keypad_control_enabled, (value == "1"));
|
_preferences->putBool(preference_keypad_control_enabled, (value == "1"));
|
||||||
configChanged = true;
|
configChanged = true;
|
||||||
}
|
}
|
||||||
|
else if(key == "NRTRY")
|
||||||
|
{
|
||||||
|
_preferences->putInt(preference_command_nr_of_retries, value.toInt());
|
||||||
|
configChanged = true;
|
||||||
|
}
|
||||||
|
else if(key == "TRYDLY")
|
||||||
|
{
|
||||||
|
_preferences->putInt(preference_command_retry_delay, value.toInt());
|
||||||
|
configChanged = true;
|
||||||
|
}
|
||||||
else if(key == "PRDTMO")
|
else if(key == "PRDTMO")
|
||||||
{
|
{
|
||||||
_preferences->putInt(preference_presence_detection_timeout, value.toInt());
|
_preferences->putInt(preference_presence_detection_timeout, value.toInt());
|
||||||
@@ -637,6 +647,8 @@ void WebCfgServer::buildNukiConfigHtml(String &response)
|
|||||||
printInputField(response, "KPINT", "Query interval keypad (seconds)", _preferences->getInt(preference_query_interval_keypad), 10);
|
printInputField(response, "KPINT", "Query interval keypad (seconds)", _preferences->getInt(preference_query_interval_keypad), 10);
|
||||||
printCheckBox(response, "KPENA", "Enabled keypad control via MQTT", _preferences->getBool(preference_keypad_control_enabled));
|
printCheckBox(response, "KPENA", "Enabled keypad control via MQTT", _preferences->getBool(preference_keypad_control_enabled));
|
||||||
}
|
}
|
||||||
|
printInputField(response, "NRTRY", "Number of retries if command failed", _preferences->getInt(preference_command_nr_of_retries), 10);
|
||||||
|
printInputField(response, "TRYDLY", "Delay between retries (milliseconds)", _preferences->getInt(preference_command_retry_delay), 10);
|
||||||
printCheckBox(response, "PUBAUTH", "Publish auth data (May reduce battery life)", _preferences->getBool(preference_publish_authdata));
|
printCheckBox(response, "PUBAUTH", "Publish auth data (May reduce battery life)", _preferences->getBool(preference_publish_authdata));
|
||||||
printCheckBox(response, "GPLCK", "Enable control via GPIO", _preferences->getBool(preference_gpio_locking_enabled));
|
printCheckBox(response, "GPLCK", "Enable control via GPIO", _preferences->getBool(preference_gpio_locking_enabled));
|
||||||
printInputField(response, "PRDTMO", "Presence detection timeout (seconds; -1 to disable)", _preferences->getInt(preference_presence_detection_timeout), 10);
|
printInputField(response, "PRDTMO", "Presence detection timeout (seconds; -1 to disable)", _preferences->getInt(preference_presence_detection_timeout), 10);
|
||||||
|
|||||||
14
main.cpp
14
main.cpp
@@ -140,14 +140,16 @@ void initEthServer(const NetworkDeviceType device)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initPreferences()
|
bool initPreferences()
|
||||||
{
|
{
|
||||||
preferences = new Preferences();
|
preferences = new Preferences();
|
||||||
preferences->begin("nukihub", false);
|
preferences->begin("nukihub", false);
|
||||||
|
|
||||||
if(!preferences->getBool(preference_started_befores))
|
bool firstStart = !preferences->getBool(preference_started_before);
|
||||||
|
|
||||||
|
if(firstStart)
|
||||||
{
|
{
|
||||||
preferences->putBool(preference_started_befores, true);
|
preferences->putBool(preference_started_before, true);
|
||||||
preferences->putBool(preference_lock_enabled, true);
|
preferences->putBool(preference_lock_enabled, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +157,8 @@ void initPreferences()
|
|||||||
{
|
{
|
||||||
preferences->putInt(preference_restart_timer, -1);
|
preferences->putInt(preference_restart_timer, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return firstStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup()
|
void setup()
|
||||||
@@ -163,7 +167,7 @@ void setup()
|
|||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
Log = &Serial;
|
Log = &Serial;
|
||||||
|
|
||||||
initPreferences();
|
bool firstStart = initPreferences();
|
||||||
|
|
||||||
if(preferences->getInt(preference_restart_timer) > 0)
|
if(preferences->getInt(preference_restart_timer) > 0)
|
||||||
{
|
{
|
||||||
@@ -196,7 +200,7 @@ void setup()
|
|||||||
if(lockEnabled)
|
if(lockEnabled)
|
||||||
{
|
{
|
||||||
nuki = new NukiWrapper("NukiHub", deviceId, bleScanner, networkLock, preferences);
|
nuki = new NukiWrapper("NukiHub", deviceId, bleScanner, networkLock, preferences);
|
||||||
nuki->initialize();
|
nuki->initialize(firstStart);
|
||||||
|
|
||||||
if(preferences->getBool(preference_gpio_locking_enabled))
|
if(preferences->getBool(preference_gpio_locking_enabled))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user