Merge branch 'master' of github.com:technyon/nuki_hub into arduinoJson_for_ha_autodiscovery
This commit is contained in:
@@ -52,6 +52,7 @@ file(GLOB SRCFILES
|
|||||||
networkDevices/W5500Device.cpp
|
networkDevices/W5500Device.cpp
|
||||||
networkDevices/ClientSyncW5500.cpp
|
networkDevices/ClientSyncW5500.cpp
|
||||||
networkDevices/espMqttClientW5500.cpp
|
networkDevices/espMqttClientW5500.cpp
|
||||||
|
QueryCommand.h
|
||||||
NukiWrapper.cpp
|
NukiWrapper.cpp
|
||||||
NukiOpenerWrapper.cpp
|
NukiOpenerWrapper.cpp
|
||||||
MqttTopics.h
|
MqttTopics.h
|
||||||
|
|||||||
2
Config.h
2
Config.h
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define NUKI_HUB_VERSION "8.8"
|
#define NUKI_HUB_VERSION "8.9"
|
||||||
|
|
||||||
#define MQTT_QOS_LEVEL 1
|
#define MQTT_QOS_LEVEL 1
|
||||||
#define MQTT_CLEAN_SESSIONS false
|
#define MQTT_CLEAN_SESSIONS false
|
||||||
@@ -10,6 +10,10 @@
|
|||||||
#define mqtt_topic_battery_keypad_critical "/battery/keypadCritical"
|
#define mqtt_topic_battery_keypad_critical "/battery/keypadCritical"
|
||||||
|
|
||||||
#define mqtt_topic_lock_state "/lock/state"
|
#define mqtt_topic_lock_state "/lock/state"
|
||||||
|
#define mqtt_topic_query_config "/lock/query/config"
|
||||||
|
#define mqtt_topic_query_lockstate "/lock/query/lockstate"
|
||||||
|
#define mqtt_topic_query_keypad "/lock/query/keypad"
|
||||||
|
#define mqtt_topic_query_battery "/lock/query/battery"
|
||||||
#define mqtt_topic_lock_binary_state "/lock/binaryState"
|
#define mqtt_topic_lock_binary_state "/lock/binaryState"
|
||||||
#define mqtt_topic_lock_trigger "/lock/trigger"
|
#define mqtt_topic_lock_trigger "/lock/trigger"
|
||||||
#define mqtt_topic_lock_log "/lock/log"
|
#define mqtt_topic_lock_log "/lock/log"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "RestartReason.h"
|
#include "RestartReason.h"
|
||||||
|
|
||||||
Network* Network::_inst = nullptr;
|
Network* Network::_inst = nullptr;
|
||||||
|
unsigned long Network::_ignoreSubscriptionsTs = 0;
|
||||||
|
|
||||||
RTC_NOINIT_ATTR char WiFi_fallbackDetect[14];
|
RTC_NOINIT_ATTR char WiFi_fallbackDetect[14];
|
||||||
|
|
||||||
@@ -359,6 +360,7 @@ bool Network::reconnect()
|
|||||||
_mqttConnectionState = 1;
|
_mqttConnectionState = 1;
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
|
_ignoreSubscriptionsTs = millis() + 2000;
|
||||||
_device->mqttOnMessage(Network::onMqttDataReceivedCallback);
|
_device->mqttOnMessage(Network::onMqttDataReceivedCallback);
|
||||||
for(const String& topic : _subscribedTopics)
|
for(const String& topic : _subscribedTopics)
|
||||||
{
|
{
|
||||||
@@ -372,7 +374,6 @@ bool Network::reconnect()
|
|||||||
_device->mqttPublish(it.first.c_str(), MQTT_QOS_LEVEL, true, it.second.c_str());
|
_device->mqttPublish(it.first.c_str(), MQTT_QOS_LEVEL, true, it.second.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delay(1000);
|
|
||||||
_mqttConnectionState = 2;
|
_mqttConnectionState = 2;
|
||||||
for(const auto& callback : _reconnectedCallbacks)
|
for(const auto& callback : _reconnectedCallbacks)
|
||||||
{
|
{
|
||||||
@@ -436,6 +437,11 @@ void Network::registerMqttReceiver(MqttReceiver* receiver)
|
|||||||
|
|
||||||
void Network::onMqttDataReceivedCallback(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total)
|
void Network::onMqttDataReceivedCallback(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total)
|
||||||
{
|
{
|
||||||
|
if(millis() < _ignoreSubscriptionsTs)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t value[50] = {0};
|
uint8_t value[50] = {0};
|
||||||
size_t l = min(len, sizeof(value)-1);
|
size_t l = min(len, sizeof(value)-1);
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ private:
|
|||||||
unsigned long _lastConnectedTs = 0;
|
unsigned long _lastConnectedTs = 0;
|
||||||
unsigned long _lastMaintenanceTs = 0;
|
unsigned long _lastMaintenanceTs = 0;
|
||||||
unsigned long _lastRssiTs = 0;
|
unsigned long _lastRssiTs = 0;
|
||||||
|
static unsigned long _ignoreSubscriptionsTs;
|
||||||
long _rssiPublishInterval = 0;
|
long _rssiPublishInterval = 0;
|
||||||
std::function<void()> _keepAliveCallback = nullptr;
|
std::function<void()> _keepAliveCallback = nullptr;
|
||||||
std::vector<std::function<void()>> _reconnectedCallbacks;
|
std::vector<std::function<void()>> _reconnectedCallbacks;
|
||||||
|
|||||||
@@ -57,6 +57,13 @@ void NetworkLock::initialize()
|
|||||||
_network->subscribe(_mqttPath, mqtt_topic_reset);
|
_network->subscribe(_mqttPath, mqtt_topic_reset);
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_reset, "0");
|
_network->initTopic(_mqttPath, mqtt_topic_reset, "0");
|
||||||
|
|
||||||
|
_network->initTopic(_mqttPath, mqtt_topic_query_config, "0");
|
||||||
|
_network->initTopic(_mqttPath, mqtt_topic_query_lockstate, "0");
|
||||||
|
_network->initTopic(_mqttPath, mqtt_topic_query_battery, "0");
|
||||||
|
_network->subscribe(_mqttPath, mqtt_topic_query_config);
|
||||||
|
_network->subscribe(_mqttPath, mqtt_topic_query_lockstate);
|
||||||
|
_network->subscribe(_mqttPath, mqtt_topic_query_battery);
|
||||||
|
|
||||||
if(_preferences->getBool(preference_keypad_control_enabled))
|
if(_preferences->getBool(preference_keypad_control_enabled))
|
||||||
{
|
{
|
||||||
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_action);
|
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_action);
|
||||||
@@ -64,11 +71,13 @@ void NetworkLock::initialize()
|
|||||||
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_name);
|
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_name);
|
||||||
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_code);
|
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_code);
|
||||||
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_enabled);
|
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_enabled);
|
||||||
|
_network->subscribe(_mqttPath, mqtt_topic_query_keypad);
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_action, "--");
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_action, "--");
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_id, "0");
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_id, "0");
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_name, "--");
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_name, "--");
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_code, "000000");
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_code, "000000");
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_enabled, "1");
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_enabled, "1");
|
||||||
|
_network->initTopic(_mqttPath, mqtt_topic_query_keypad, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
_network->addReconnectedCallback([&]()
|
_network->addReconnectedCallback([&]()
|
||||||
@@ -81,16 +90,14 @@ void NetworkLock::onMqttDataReceived(const char* topic, byte* payload, const uns
|
|||||||
{
|
{
|
||||||
char* value = (char*)payload;
|
char* value = (char*)payload;
|
||||||
|
|
||||||
bool processActions = _network->mqttConnectionState() >= 2;
|
if(comparePrefixedPath(topic, mqtt_topic_reset) && strcmp(value, "1") == 0)
|
||||||
|
|
||||||
if(processActions && comparePrefixedPath(topic, mqtt_topic_reset) && strcmp(value, "1") == 0)
|
|
||||||
{
|
{
|
||||||
Log->println(F("Restart requested via MQTT."));
|
Log->println(F("Restart requested via MQTT."));
|
||||||
delay(200);
|
delay(200);
|
||||||
restartEsp(RestartReason::RequestedViaMqtt);
|
restartEsp(RestartReason::RequestedViaMqtt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(processActions && comparePrefixedPath(topic, mqtt_topic_lock_action))
|
if(comparePrefixedPath(topic, mqtt_topic_lock_action))
|
||||||
{
|
{
|
||||||
if(strcmp(value, "") == 0 || strcmp(value, "--") == 0 || strcmp(value, "ack") == 0 || strcmp(value, "unknown_action") == 0) return;
|
if(strcmp(value, "") == 0 || strcmp(value, "--") == 0 || strcmp(value, "ack") == 0 || strcmp(value, "unknown_action") == 0) return;
|
||||||
|
|
||||||
@@ -104,7 +111,7 @@ void NetworkLock::onMqttDataReceived(const char* topic, byte* payload, const uns
|
|||||||
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(comparePrefixedPath(topic, mqtt_topic_keypad_command_action))
|
||||||
{
|
{
|
||||||
if(_keypadCommandReceivedReceivedCallback != nullptr)
|
if(_keypadCommandReceivedReceivedCallback != nullptr)
|
||||||
{
|
{
|
||||||
@@ -143,6 +150,26 @@ void NetworkLock::onMqttDataReceived(const char* topic, byte* payload, const uns
|
|||||||
{
|
{
|
||||||
_keypadCommandEnabled = atoi(value);
|
_keypadCommandEnabled = atoi(value);
|
||||||
}
|
}
|
||||||
|
else if(comparePrefixedPath(topic, mqtt_topic_query_config) && strcmp(value, "1") == 0)
|
||||||
|
{
|
||||||
|
_queryCommands = _queryCommands | QUERY_COMMAND_CONFIG;
|
||||||
|
publishString(mqtt_topic_query_config, "0");
|
||||||
|
}
|
||||||
|
else if(comparePrefixedPath(topic, mqtt_topic_query_lockstate) && strcmp(value, "1") == 0)
|
||||||
|
{
|
||||||
|
_queryCommands = _queryCommands | QUERY_COMMAND_LOCKSTATE;
|
||||||
|
publishString(mqtt_topic_query_lockstate, "0");
|
||||||
|
}
|
||||||
|
else if(comparePrefixedPath(topic, mqtt_topic_query_keypad) && strcmp(value, "1") == 0)
|
||||||
|
{
|
||||||
|
_queryCommands = _queryCommands | QUERY_COMMAND_KEYPAD;
|
||||||
|
publishString(mqtt_topic_query_keypad, "0");
|
||||||
|
}
|
||||||
|
else if(comparePrefixedPath(topic, mqtt_topic_query_battery) && strcmp(value, "1") == 0)
|
||||||
|
{
|
||||||
|
_queryCommands = _queryCommands | QUERY_COMMAND_BATTERY;
|
||||||
|
publishString(mqtt_topic_query_battery, "0");
|
||||||
|
}
|
||||||
|
|
||||||
for(auto configTopic : _configTopics)
|
for(auto configTopic : _configTopics)
|
||||||
{
|
{
|
||||||
@@ -569,3 +596,10 @@ bool NetworkLock::reconnected()
|
|||||||
_reconnected = false;
|
_reconnected = false;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t NetworkLock::queryCommands()
|
||||||
|
{
|
||||||
|
uint8_t qc = _queryCommands;
|
||||||
|
_queryCommands = 0;
|
||||||
|
return qc;
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "NukiConstants.h"
|
#include "NukiConstants.h"
|
||||||
#include "NukiLockConstants.h"
|
#include "NukiLockConstants.h"
|
||||||
#include "Network.h"
|
#include "Network.h"
|
||||||
|
#include "QueryCommand.h"
|
||||||
|
|
||||||
class NetworkLock : public MqttReceiver
|
class NetworkLock : public MqttReceiver
|
||||||
{
|
{
|
||||||
@@ -41,6 +42,7 @@ 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;
|
||||||
|
|
||||||
bool reconnected();
|
bool reconnected();
|
||||||
|
uint8_t queryCommands();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool comparePrefixedPath(const char* fullPath, const char* subPath);
|
bool comparePrefixedPath(const char* fullPath, const char* subPath);
|
||||||
@@ -74,6 +76,7 @@ private:
|
|||||||
String _keypadCommandCode = "";
|
String _keypadCommandCode = "";
|
||||||
uint _keypadCommandId = 0;
|
uint _keypadCommandId = 0;
|
||||||
int _keypadCommandEnabled = 1;
|
int _keypadCommandEnabled = 1;
|
||||||
|
uint8_t _queryCommands = 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;
|
||||||
|
|||||||
@@ -43,6 +43,13 @@ void NetworkOpener::initialize()
|
|||||||
_network->subscribe(_mqttPath, topic);
|
_network->subscribe(_mqttPath, topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_network->initTopic(_mqttPath, mqtt_topic_query_config, "0");
|
||||||
|
_network->initTopic(_mqttPath, mqtt_topic_query_lockstate, "0");
|
||||||
|
_network->initTopic(_mqttPath, mqtt_topic_query_battery, "0");
|
||||||
|
_network->subscribe(_mqttPath, mqtt_topic_query_config);
|
||||||
|
_network->subscribe(_mqttPath, mqtt_topic_query_lockstate);
|
||||||
|
_network->subscribe(_mqttPath, mqtt_topic_query_battery);
|
||||||
|
|
||||||
if(_preferences->getBool(preference_keypad_control_enabled))
|
if(_preferences->getBool(preference_keypad_control_enabled))
|
||||||
{
|
{
|
||||||
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_action);
|
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_action);
|
||||||
@@ -50,11 +57,13 @@ void NetworkOpener::initialize()
|
|||||||
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_name);
|
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_name);
|
||||||
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_code);
|
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_code);
|
||||||
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_enabled);
|
_network->subscribe(_mqttPath, mqtt_topic_keypad_command_enabled);
|
||||||
|
_network->subscribe(_mqttPath, mqtt_topic_query_keypad);
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_action, "--");
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_action, "--");
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_id, "0");
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_id, "0");
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_name, "--");
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_name, "--");
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_code, "000000");
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_code, "000000");
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_enabled, "1");
|
_network->initTopic(_mqttPath, mqtt_topic_keypad_command_enabled, "1");
|
||||||
|
_network->initTopic(_mqttPath, mqtt_topic_query_keypad, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
_network->addReconnectedCallback([&]()
|
_network->addReconnectedCallback([&]()
|
||||||
@@ -79,9 +88,7 @@ void NetworkOpener::onMqttDataReceived(const char* topic, byte* payload, const u
|
|||||||
{
|
{
|
||||||
char* value = (char*)payload;
|
char* value = (char*)payload;
|
||||||
|
|
||||||
bool processActions = _network->mqttConnectionState() >= 2;
|
if(comparePrefixedPath(topic, mqtt_topic_lock_action))
|
||||||
|
|
||||||
if(processActions && comparePrefixedPath(topic, mqtt_topic_lock_action))
|
|
||||||
{
|
{
|
||||||
if(strcmp((char*)payload, "") == 0 || strcmp(value, "--") == 0 || strcmp(value, "ack") == 0 || strcmp(value, "unknown_action") == 0) return;
|
if(strcmp((char*)payload, "") == 0 || strcmp(value, "--") == 0 || strcmp(value, "ack") == 0 || strcmp(value, "unknown_action") == 0) return;
|
||||||
|
|
||||||
@@ -95,7 +102,7 @@ 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(comparePrefixedPath(topic, mqtt_topic_keypad_command_action))
|
||||||
{
|
{
|
||||||
if(_keypadCommandReceivedReceivedCallback != nullptr)
|
if(_keypadCommandReceivedReceivedCallback != nullptr)
|
||||||
{
|
{
|
||||||
@@ -134,6 +141,26 @@ void NetworkOpener::onMqttDataReceived(const char* topic, byte* payload, const u
|
|||||||
{
|
{
|
||||||
_keypadCommandEnabled = atoi(value);
|
_keypadCommandEnabled = atoi(value);
|
||||||
}
|
}
|
||||||
|
else if(comparePrefixedPath(topic, mqtt_topic_query_config) && strcmp(value, "1") == 0)
|
||||||
|
{
|
||||||
|
_queryCommands = _queryCommands | QUERY_COMMAND_CONFIG;
|
||||||
|
publishString(mqtt_topic_query_config, "0");
|
||||||
|
}
|
||||||
|
else if(comparePrefixedPath(topic, mqtt_topic_query_lockstate) && strcmp(value, "1") == 0)
|
||||||
|
{
|
||||||
|
_queryCommands = _queryCommands | QUERY_COMMAND_LOCKSTATE;
|
||||||
|
publishString(mqtt_topic_query_lockstate, "0");
|
||||||
|
}
|
||||||
|
else if(comparePrefixedPath(topic, mqtt_topic_query_keypad) && strcmp(value, "1") == 0)
|
||||||
|
{
|
||||||
|
_queryCommands = _queryCommands | QUERY_COMMAND_KEYPAD;
|
||||||
|
publishString(mqtt_topic_query_keypad, "0");
|
||||||
|
}
|
||||||
|
else if(comparePrefixedPath(topic, mqtt_topic_query_battery) && strcmp(value, "1") == 0)
|
||||||
|
{
|
||||||
|
_queryCommands = _queryCommands | QUERY_COMMAND_BATTERY;
|
||||||
|
publishString(mqtt_topic_query_battery, "0");
|
||||||
|
}
|
||||||
|
|
||||||
for(auto configTopic : _configTopics)
|
for(auto configTopic : _configTopics)
|
||||||
{
|
{
|
||||||
@@ -612,3 +639,10 @@ bool NetworkOpener::reconnected()
|
|||||||
_reconnected = false;
|
_reconnected = false;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t NetworkOpener::queryCommands()
|
||||||
|
{
|
||||||
|
uint8_t qc = _queryCommands;
|
||||||
|
_queryCommands = 0;
|
||||||
|
return qc;
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ 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;
|
||||||
|
|
||||||
bool reconnected();
|
bool reconnected();
|
||||||
|
uint8_t queryCommands();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool comparePrefixedPath(const char* fullPath, const char* subPath);
|
bool comparePrefixedPath(const char* fullPath, const char* subPath);
|
||||||
@@ -79,6 +80,7 @@ private:
|
|||||||
uint _keypadCommandId = 0;
|
uint _keypadCommandId = 0;
|
||||||
int _keypadCommandEnabled = 1;
|
int _keypadCommandEnabled = 1;
|
||||||
unsigned long _resetLockStateTs = 0;
|
unsigned long _resetLockStateTs = 0;
|
||||||
|
uint8_t _queryCommands = 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;
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ void NukiOpenerWrapper::update()
|
|||||||
|
|
||||||
unsigned long ts = millis();
|
unsigned long ts = millis();
|
||||||
unsigned long lastReceivedBeaconTs = _nukiOpener.getLastReceivedBeaconTs();
|
unsigned long lastReceivedBeaconTs = _nukiOpener.getLastReceivedBeaconTs();
|
||||||
|
uint8_t queryCommands = _network->queryCommands();
|
||||||
|
|
||||||
if(_restartBeaconTimeout > 0 &&
|
if(_restartBeaconTimeout > 0 &&
|
||||||
ts > 60000 &&
|
ts > 60000 &&
|
||||||
lastReceivedBeaconTs > 0 &&
|
lastReceivedBeaconTs > 0 &&
|
||||||
@@ -147,18 +149,18 @@ void NukiOpenerWrapper::update()
|
|||||||
|
|
||||||
_nukiOpener.updateConnectionState();
|
_nukiOpener.updateConnectionState();
|
||||||
|
|
||||||
if(_statusUpdated || _nextLockStateUpdateTs == 0 || ts >= _nextLockStateUpdateTs)
|
if(_statusUpdated || _nextLockStateUpdateTs == 0 || ts >= _nextLockStateUpdateTs || (queryCommands & QUERY_COMMAND_LOCKSTATE) > 0)
|
||||||
{
|
{
|
||||||
_nextLockStateUpdateTs = ts + _intervalLockstate * 1000;
|
_nextLockStateUpdateTs = ts + _intervalLockstate * 1000;
|
||||||
updateKeyTurnerState();
|
updateKeyTurnerState();
|
||||||
_statusUpdated = false;
|
_statusUpdated = false;
|
||||||
}
|
}
|
||||||
if(_nextBatteryReportTs == 0 || ts > _nextBatteryReportTs)
|
if(_nextBatteryReportTs == 0 || ts > _nextBatteryReportTs || (queryCommands & QUERY_COMMAND_BATTERY) > 0)
|
||||||
{
|
{
|
||||||
_nextBatteryReportTs = ts + _intervalBattery * 1000;
|
_nextBatteryReportTs = ts + _intervalBattery * 1000;
|
||||||
updateBatteryState();
|
updateBatteryState();
|
||||||
}
|
}
|
||||||
if(_nextConfigUpdateTs == 0 || ts > _nextConfigUpdateTs)
|
if(_nextConfigUpdateTs == 0 || ts > _nextConfigUpdateTs || (queryCommands & QUERY_COMMAND_CONFIG) > 0)
|
||||||
{
|
{
|
||||||
_nextConfigUpdateTs = ts + _intervalConfig * 1000;
|
_nextConfigUpdateTs = ts + _intervalConfig * 1000;
|
||||||
updateConfig();
|
updateConfig();
|
||||||
@@ -183,7 +185,7 @@ void NukiOpenerWrapper::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_hasKeypad && _keypadEnabled && (_nextKeypadUpdateTs == 0 || ts > _nextKeypadUpdateTs))
|
if(_hasKeypad && _keypadEnabled && (_nextKeypadUpdateTs == 0 || ts > _nextKeypadUpdateTs || (queryCommands & QUERY_COMMAND_KEYPAD) > 0))
|
||||||
{
|
{
|
||||||
_nextKeypadUpdateTs = ts + _intervalKeypad * 1000;
|
_nextKeypadUpdateTs = ts + _intervalKeypad * 1000;
|
||||||
updateKeypad();
|
updateKeypad();
|
||||||
@@ -267,6 +269,7 @@ void NukiOpenerWrapper::unpair()
|
|||||||
|
|
||||||
void NukiOpenerWrapper::updateKeyTurnerState()
|
void NukiOpenerWrapper::updateKeyTurnerState()
|
||||||
{
|
{
|
||||||
|
Log->print(F("Querying opener state: "));
|
||||||
Nuki::CmdResult result =_nukiOpener.requestOpenerState(&_keyTurnerState);
|
Nuki::CmdResult result =_nukiOpener.requestOpenerState(&_keyTurnerState);
|
||||||
if(result != Nuki::CmdResult::Success)
|
if(result != Nuki::CmdResult::Success)
|
||||||
{
|
{
|
||||||
@@ -294,13 +297,12 @@ void NukiOpenerWrapper::updateKeyTurnerState()
|
|||||||
|
|
||||||
if(_keyTurnerState.nukiState == NukiOpener::State::ContinuousMode)
|
if(_keyTurnerState.nukiState == NukiOpener::State::ContinuousMode)
|
||||||
{
|
{
|
||||||
Log->println(F("Nuki opener state: Continuous Mode"));
|
Log->println(F("Continuous Mode"));
|
||||||
}
|
}
|
||||||
else if(_keyTurnerState.lockState != _lastKeyTurnerState.lockState)
|
else
|
||||||
{
|
{
|
||||||
char lockStateStr[20];
|
char lockStateStr[20];
|
||||||
lockstateToString(_keyTurnerState.lockState, lockStateStr);
|
lockstateToString(_keyTurnerState.lockState, lockStateStr);
|
||||||
Log->print(F("Nuki opener state: "));
|
|
||||||
Log->println(lockStateStr);
|
Log->println(lockStateStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,7 +317,9 @@ void NukiOpenerWrapper::updateKeyTurnerState()
|
|||||||
|
|
||||||
void NukiOpenerWrapper::updateBatteryState()
|
void NukiOpenerWrapper::updateBatteryState()
|
||||||
{
|
{
|
||||||
|
Log->print("Querying opener battery state: ");
|
||||||
Nuki::CmdResult result = _nukiOpener.requestBatteryReport(&_batteryReport);
|
Nuki::CmdResult result = _nukiOpener.requestBatteryReport(&_batteryReport);
|
||||||
|
printCommandResult(result);
|
||||||
if(result == Nuki::CmdResult::Success)
|
if(result == Nuki::CmdResult::Success)
|
||||||
{
|
{
|
||||||
_network->publishBatteryReport(_batteryReport);
|
_network->publishBatteryReport(_batteryReport);
|
||||||
@@ -369,8 +373,10 @@ void NukiOpenerWrapper::updateAuthData()
|
|||||||
|
|
||||||
void NukiOpenerWrapper::updateKeypad()
|
void NukiOpenerWrapper::updateKeypad()
|
||||||
{
|
{
|
||||||
|
Log->print(F("Querying opener keypad: "));
|
||||||
Nuki::CmdResult result = _nukiOpener.retrieveKeypadEntries(0, 0xffff);
|
Nuki::CmdResult result = _nukiOpener.retrieveKeypadEntries(0, 0xffff);
|
||||||
if(result == 1)
|
printCommandResult(result);
|
||||||
|
if(result == Nuki::CmdResult::Success)
|
||||||
{
|
{
|
||||||
std::list<NukiLock::KeypadEntry> entries;
|
std::list<NukiLock::KeypadEntry> entries;
|
||||||
_nukiOpener.getKeypadEntries(&entries);
|
_nukiOpener.getKeypadEntries(&entries);
|
||||||
@@ -381,7 +387,7 @@ void NukiOpenerWrapper::updateKeypad()
|
|||||||
if(keypadCount > _maxKeypadCodeCount)
|
if(keypadCount > _maxKeypadCodeCount)
|
||||||
{
|
{
|
||||||
_maxKeypadCodeCount = keypadCount;
|
_maxKeypadCodeCount = keypadCount;
|
||||||
_preferences->putUInt(preference_opener_max_keypad_code_count, _maxKeypadCodeCount);
|
_preferences->putUInt(preference_lock_max_keypad_code_count, _maxKeypadCodeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
_network->publishKeypad(entries, _maxKeypadCodeCount);
|
_network->publishKeypad(entries, _maxKeypadCodeCount);
|
||||||
@@ -393,6 +399,7 @@ void NukiOpenerWrapper::updateKeypad()
|
|||||||
_keypadCodeIds.push_back(entry.codeId);
|
_keypadCodeIds.push_back(entry.codeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
postponeBleWatchdog();
|
postponeBleWatchdog();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -653,3 +660,10 @@ void NukiOpenerWrapper::disableHASS()
|
|||||||
Log->println(F("Unable to disable HASS. Invalid config received."));
|
Log->println(F("Unable to disable HASS. Invalid config received."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NukiOpenerWrapper::printCommandResult(Nuki::CmdResult result)
|
||||||
|
{
|
||||||
|
char resultStr[15];
|
||||||
|
NukiOpener::cmdResultToString(result, resultStr);
|
||||||
|
Log->println(resultStr);
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ private:
|
|||||||
|
|
||||||
void setupHASS();
|
void setupHASS();
|
||||||
|
|
||||||
|
void printCommandResult(Nuki::CmdResult result);
|
||||||
|
|
||||||
NukiOpener::LockAction lockActionToEnum(const char* str); // char array at least 14 characters
|
NukiOpener::LockAction lockActionToEnum(const char* str); // char array at least 14 characters
|
||||||
|
|
||||||
std::string _deviceName;
|
std::string _deviceName;
|
||||||
|
|||||||
@@ -133,6 +133,8 @@ void NukiWrapper::update()
|
|||||||
|
|
||||||
unsigned long ts = millis();
|
unsigned long ts = millis();
|
||||||
unsigned long lastReceivedBeaconTs = _nukiLock.getLastReceivedBeaconTs();
|
unsigned long lastReceivedBeaconTs = _nukiLock.getLastReceivedBeaconTs();
|
||||||
|
uint8_t queryCommands = _network->queryCommands();
|
||||||
|
|
||||||
if(_restartBeaconTimeout > 0 &&
|
if(_restartBeaconTimeout > 0 &&
|
||||||
ts > 60000 &&
|
ts > 60000 &&
|
||||||
lastReceivedBeaconTs > 0 &&
|
lastReceivedBeaconTs > 0 &&
|
||||||
@@ -148,18 +150,18 @@ void NukiWrapper::update()
|
|||||||
|
|
||||||
_nukiLock.updateConnectionState();
|
_nukiLock.updateConnectionState();
|
||||||
|
|
||||||
if(_statusUpdated || _nextLockStateUpdateTs == 0 || ts >= _nextLockStateUpdateTs)
|
if(_statusUpdated || _nextLockStateUpdateTs == 0 || ts >= _nextLockStateUpdateTs || (queryCommands & QUERY_COMMAND_LOCKSTATE) > 0)
|
||||||
{
|
{
|
||||||
_statusUpdated = false;
|
_statusUpdated = false;
|
||||||
_nextLockStateUpdateTs = ts + _intervalLockstate * 1000;
|
_nextLockStateUpdateTs = ts + _intervalLockstate * 1000;
|
||||||
updateKeyTurnerState();
|
updateKeyTurnerState();
|
||||||
}
|
}
|
||||||
if(_nextBatteryReportTs == 0 || ts > _nextBatteryReportTs)
|
if(_nextBatteryReportTs == 0 || ts > _nextBatteryReportTs || (queryCommands & QUERY_COMMAND_BATTERY) > 0)
|
||||||
{
|
{
|
||||||
_nextBatteryReportTs = ts + _intervalBattery * 1000;
|
_nextBatteryReportTs = ts + _intervalBattery * 1000;
|
||||||
updateBatteryState();
|
updateBatteryState();
|
||||||
}
|
}
|
||||||
if(_nextConfigUpdateTs == 0 || ts > _nextConfigUpdateTs)
|
if(_nextConfigUpdateTs == 0 || ts > _nextConfigUpdateTs || (queryCommands & QUERY_COMMAND_CONFIG) > 0)
|
||||||
{
|
{
|
||||||
_nextConfigUpdateTs = ts + _intervalConfig * 1000;
|
_nextConfigUpdateTs = ts + _intervalConfig * 1000;
|
||||||
updateConfig();
|
updateConfig();
|
||||||
@@ -184,7 +186,7 @@ void NukiWrapper::update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_hasKeypad && _keypadEnabled && (_nextKeypadUpdateTs == 0 || ts > _nextKeypadUpdateTs))
|
if(_hasKeypad && _keypadEnabled && (_nextKeypadUpdateTs == 0 || ts > _nextKeypadUpdateTs || (queryCommands & QUERY_COMMAND_KEYPAD) > 0))
|
||||||
{
|
{
|
||||||
_nextKeypadUpdateTs = ts + _intervalKeypad * 1000;
|
_nextKeypadUpdateTs = ts + _intervalKeypad * 1000;
|
||||||
updateKeypad();
|
updateKeypad();
|
||||||
@@ -283,6 +285,7 @@ void NukiWrapper::unpair()
|
|||||||
|
|
||||||
void NukiWrapper::updateKeyTurnerState()
|
void NukiWrapper::updateKeyTurnerState()
|
||||||
{
|
{
|
||||||
|
Log->print(F("Querying lock state: "));
|
||||||
Nuki::CmdResult result =_nukiLock.requestKeyTurnerState(&_keyTurnerState);
|
Nuki::CmdResult result =_nukiLock.requestKeyTurnerState(&_keyTurnerState);
|
||||||
if(result != Nuki::CmdResult::Success)
|
if(result != Nuki::CmdResult::Success)
|
||||||
{
|
{
|
||||||
@@ -298,13 +301,9 @@ void NukiWrapper::updateKeyTurnerState()
|
|||||||
|
|
||||||
_network->publishKeyTurnerState(_keyTurnerState, _lastKeyTurnerState);
|
_network->publishKeyTurnerState(_keyTurnerState, _lastKeyTurnerState);
|
||||||
|
|
||||||
if(_keyTurnerState.lockState != _lastKeyTurnerState.lockState)
|
char lockStateStr[20];
|
||||||
{
|
lockstateToString(_keyTurnerState.lockState, lockStateStr);
|
||||||
char lockStateStr[20];
|
Log->println(lockStateStr);
|
||||||
lockstateToString(_keyTurnerState.lockState, lockStateStr);
|
|
||||||
Log->print(F("Nuki lock state update: "));
|
|
||||||
Log->println(lockStateStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(_publishAuthData)
|
if(_publishAuthData)
|
||||||
{
|
{
|
||||||
@@ -316,7 +315,9 @@ void NukiWrapper::updateKeyTurnerState()
|
|||||||
|
|
||||||
void NukiWrapper::updateBatteryState()
|
void NukiWrapper::updateBatteryState()
|
||||||
{
|
{
|
||||||
|
Log->print("Querying lock battery state: ");
|
||||||
Nuki::CmdResult result = _nukiLock.requestBatteryReport(&_batteryReport);
|
Nuki::CmdResult result = _nukiLock.requestBatteryReport(&_batteryReport);
|
||||||
|
printCommandResult(result);
|
||||||
if(result == Nuki::CmdResult::Success)
|
if(result == Nuki::CmdResult::Success)
|
||||||
{
|
{
|
||||||
_network->publishBatteryReport(_batteryReport);
|
_network->publishBatteryReport(_batteryReport);
|
||||||
@@ -370,8 +371,10 @@ void NukiWrapper::updateAuthData()
|
|||||||
|
|
||||||
void NukiWrapper::updateKeypad()
|
void NukiWrapper::updateKeypad()
|
||||||
{
|
{
|
||||||
|
Log->print(F("Querying lock keypad: "));
|
||||||
Nuki::CmdResult result = _nukiLock.retrieveKeypadEntries(0, 0xffff);
|
Nuki::CmdResult result = _nukiLock.retrieveKeypadEntries(0, 0xffff);
|
||||||
if(result == 1)
|
printCommandResult(result);
|
||||||
|
if(result == Nuki::CmdResult::Success)
|
||||||
{
|
{
|
||||||
std::list<NukiLock::KeypadEntry> entries;
|
std::list<NukiLock::KeypadEntry> entries;
|
||||||
_nukiLock.getKeypadEntries(&entries);
|
_nukiLock.getKeypadEntries(&entries);
|
||||||
@@ -394,6 +397,7 @@ void NukiWrapper::updateKeypad()
|
|||||||
_keypadCodeIds.push_back(entry.codeId);
|
_keypadCodeIds.push_back(entry.codeId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
postponeBleWatchdog();
|
postponeBleWatchdog();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,3 +689,10 @@ const BLEAddress NukiWrapper::getBleAddress() const
|
|||||||
{
|
{
|
||||||
return _nukiLock.getBleAddress();
|
return _nukiLock.getBleAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NukiWrapper::printCommandResult(Nuki::CmdResult result)
|
||||||
|
{
|
||||||
|
char resultStr[15];
|
||||||
|
NukiLock::cmdResultToString(result, resultStr);
|
||||||
|
Log->println(resultStr);
|
||||||
|
}
|
||||||
|
|||||||
@@ -52,6 +52,8 @@ private:
|
|||||||
void setupHASS();
|
void setupHASS();
|
||||||
bool hasDoorSensor();
|
bool hasDoorSensor();
|
||||||
|
|
||||||
|
void printCommandResult(Nuki::CmdResult result);
|
||||||
|
|
||||||
NukiLock::LockAction lockActionToEnum(const char* str); // char array at least 14 characters
|
NukiLock::LockAction lockActionToEnum(const char* str); // char array at least 14 characters
|
||||||
|
|
||||||
std::string _deviceName;
|
std::string _deviceName;
|
||||||
|
|||||||
6
QueryCommand.h
Normal file
6
QueryCommand.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define QUERY_COMMAND_LOCKSTATE 1
|
||||||
|
#define QUERY_COMMAND_CONFIG 2
|
||||||
|
#define QUERY_COMMAND_KEYPAD 4
|
||||||
|
#define QUERY_COMMAND_BATTERY 8
|
||||||
@@ -59,6 +59,9 @@ This project is free to use for everyone. However if you feel like donating, you
|
|||||||
- lock/authorizationName: If enabled in the web interface, this node returns the authorization name of the last lock action
|
- lock/authorizationName: If enabled in the web interface, this node returns the authorization name of the last lock action
|
||||||
- lock/commandResult: Result of the last action as reported by NUKI library: success, failed, timeOut, working, notPaired, error, undefined
|
- lock/commandResult: Result of the last action as reported by NUKI library: success, failed, timeOut, working, notPaired, error, undefined
|
||||||
- lock/doorSensorState: State of the door sensor: unavailable, deactivated, doorClosed, doorOpened, doorStateUnknown, calibrating
|
- lock/doorSensorState: State of the door sensor: unavailable, deactivated, doorClosed, doorOpened, doorStateUnknown, calibrating
|
||||||
|
- query/lockstate: Set to 1 to trigger query lockstage. Auto-resets to 0.
|
||||||
|
- query/config: Set to 1 to trigger query config. Auto-resets to 0.
|
||||||
|
- query/keypad: Set to 1 to trigger query keypad. Auto-resets to 0.
|
||||||
<br><br>
|
<br><br>
|
||||||
- battery/level: Battery level in percent
|
- battery/level: Battery level in percent
|
||||||
- battery/critical: 1 if battery level is critical, otherwise 0
|
- battery/critical: 1 if battery level is critical, otherwise 0
|
||||||
@@ -84,6 +87,9 @@ This project is free to use for everyone. However if you feel like donating, you
|
|||||||
- lock/authorizationName: If enabled in the web interface, this node returns the authorization name of the last lock action
|
- lock/authorizationName: If enabled in the web interface, this node returns the authorization name of the last lock action
|
||||||
- lock/commandResult: Result of the last action as reported by NUKI library: success, failed, timeOut, working, notPaired, error, undefined
|
- lock/commandResult: Result of the last action as reported by NUKI library: success, failed, timeOut, working, notPaired, error, undefined
|
||||||
- lock/doorSensorState: State of the door sensor: unavailable, deactivated, doorClosed, doorOpened, doorStateUnknown, calibrating
|
- lock/doorSensorState: State of the door sensor: unavailable, deactivated, doorClosed, doorOpened, doorStateUnknown, calibrating
|
||||||
|
- query/lockstate: Set to 1 to trigger query lockstage. Auto-resets to 0.
|
||||||
|
- query/config: Set to 1 to trigger query config. Auto-resets to 0.
|
||||||
|
- query/keypad: Set to 1 to trigger query keypad. Auto-resets to 0.
|
||||||
<br><br>
|
<br><br>
|
||||||
- battery/voltage: Reports the current battery voltage in Volts.
|
- battery/voltage: Reports the current battery voltage in Volts.
|
||||||
- battery/critical: 1 if battery level is critical, otherwise 0
|
- battery/critical: 1 if battery level is critical, otherwise 0
|
||||||
|
|||||||
@@ -780,7 +780,7 @@ void WebCfgServer::buildInfoHtml(String &response)
|
|||||||
|
|
||||||
response.concat("Restart reason FW: ");
|
response.concat("Restart reason FW: ");
|
||||||
response.concat(getRestartReason());
|
response.concat(getRestartReason());
|
||||||
response.concat("\n");
|
response.concat( "\n");
|
||||||
|
|
||||||
response.concat("Restart reason ESP: ");
|
response.concat("Restart reason ESP: ");
|
||||||
response.concat(getEspRestartReason());
|
response.concat(getEspRestartReason());
|
||||||
|
|||||||
1
main.cpp
1
main.cpp
@@ -170,6 +170,7 @@ void setup()
|
|||||||
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path);
|
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path);
|
||||||
network = new Network(preferences, mqttLockPath);
|
network = new Network(preferences, mqttLockPath);
|
||||||
network->initialize();
|
network->initialize();
|
||||||
|
|
||||||
networkLock = new NetworkLock(network, preferences);
|
networkLock = new NetworkLock(network, preferences);
|
||||||
networkLock->initialize();
|
networkLock->initialize();
|
||||||
|
|
||||||
|
|||||||
@@ -143,11 +143,11 @@ void W5500Device::resetDevice()
|
|||||||
Log->println(F("Resetting network hardware."));
|
Log->println(F("Resetting network hardware."));
|
||||||
pinMode(_resetPin, OUTPUT);
|
pinMode(_resetPin, OUTPUT);
|
||||||
digitalWrite(_resetPin, HIGH);
|
digitalWrite(_resetPin, HIGH);
|
||||||
delay(250);
|
delay(50);
|
||||||
digitalWrite(_resetPin, LOW);
|
digitalWrite(_resetPin, LOW);
|
||||||
delay(50);
|
delay(50);
|
||||||
digitalWrite(_resetPin, HIGH);
|
digitalWrite(_resetPin, HIGH);
|
||||||
delay(1500);
|
delay(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user