Merge remote-tracking branch 'upstream/master' into http-server
This commit is contained in:
@@ -3,6 +3,7 @@ include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
|||||||
project(nukihub)
|
project(nukihub)
|
||||||
|
|
||||||
add_compile_definitions(CONFIG_IDF_TARGET_ESP32)
|
add_compile_definitions(CONFIG_IDF_TARGET_ESP32)
|
||||||
|
add_compile_definitions(NUKI_64BIT_TIME)
|
||||||
|
|
||||||
set(SRCFILES
|
set(SRCFILES
|
||||||
../src/Config.h
|
../src/Config.h
|
||||||
@@ -55,6 +56,8 @@ set(SRCFILES
|
|||||||
../src/util/NetworkUtil.cpp
|
../src/util/NetworkUtil.cpp
|
||||||
../src/enums/NetworkDeviceType.h
|
../src/enums/NetworkDeviceType.h
|
||||||
../src/util/NetworkDeviceInstantiator.cpp
|
../src/util/NetworkDeviceInstantiator.cpp
|
||||||
|
../src/NukiOfficial.cpp
|
||||||
|
../src/NukiPublisher.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB_RECURSE SRCFILESREC
|
file(GLOB_RECURSE SRCFILESREC
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ void NukiNetwork::initialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_discoveryTopic = _preferences->getString(preference_mqtt_hass_discovery, "");
|
_discoveryTopic = _preferences->getString(preference_mqtt_hass_discovery, "");
|
||||||
_offEnabled = _preferences->getBool(preference_official_hybrid, false);
|
_offEnabled = _preferences->getBool(preference_official_hybrid_enabled, false);
|
||||||
readSettings();
|
readSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,28 +14,19 @@ extern bool forceEnableWebServer;
|
|||||||
extern const uint8_t x509_crt_imported_bundle_bin_start[] asm("_binary_x509_crt_bundle_start");
|
extern const uint8_t x509_crt_imported_bundle_bin_start[] asm("_binary_x509_crt_bundle_start");
|
||||||
extern const uint8_t x509_crt_imported_bundle_bin_end[] asm("_binary_x509_crt_bundle_end");
|
extern const uint8_t x509_crt_imported_bundle_bin_end[] asm("_binary_x509_crt_bundle_end");
|
||||||
|
|
||||||
NukiNetworkLock::NukiNetworkLock(NukiNetwork* network, Preferences* preferences, char* buffer, size_t bufferSize)
|
NukiNetworkLock::NukiNetworkLock(NukiNetwork* network, NukiOfficial* nukiOfficial, Preferences* preferences, char* buffer, size_t bufferSize)
|
||||||
: _network(network),
|
: _network(network),
|
||||||
|
_nukiOfficial(nukiOfficial),
|
||||||
_preferences(preferences),
|
_preferences(preferences),
|
||||||
_buffer(buffer),
|
_buffer(buffer),
|
||||||
_bufferSize(bufferSize)
|
_bufferSize(bufferSize)
|
||||||
{
|
{
|
||||||
|
_nukiPublisher = new NukiPublisher(network, _mqttPath);
|
||||||
|
_nukiOfficial->setPublisher(_nukiPublisher);
|
||||||
|
|
||||||
memset(_authName, 0, sizeof(_authName));
|
memset(_authName, 0, sizeof(_authName));
|
||||||
_authName[0] = '\0';
|
_authName[0] = '\0';
|
||||||
|
|
||||||
_offTopics.reserve(10);
|
|
||||||
//_offTopics.push_back(mqtt_topic_official_mode);
|
|
||||||
_offTopics.push_back((char*)mqtt_topic_official_state);
|
|
||||||
_offTopics.push_back((char*)mqtt_topic_official_batteryCritical);
|
|
||||||
_offTopics.push_back((char*)mqtt_topic_official_batteryChargeState);
|
|
||||||
_offTopics.push_back((char*)mqtt_topic_official_batteryCharging);
|
|
||||||
_offTopics.push_back((char*)mqtt_topic_official_keypadBatteryCritical);
|
|
||||||
_offTopics.push_back((char*)mqtt_topic_official_doorsensorState);
|
|
||||||
_offTopics.push_back((char*)mqtt_topic_official_doorsensorBatteryCritical);
|
|
||||||
_offTopics.push_back((char*)mqtt_topic_official_connected);
|
|
||||||
_offTopics.push_back((char*)mqtt_topic_official_commandResponse);
|
|
||||||
_offTopics.push_back((char*)mqtt_topic_official_lockActionEvent);
|
|
||||||
|
|
||||||
_network->registerMqttReceiver(this);
|
_network->registerMqttReceiver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +53,6 @@ void NukiNetworkLock::initialize()
|
|||||||
|
|
||||||
_haEnabled = _preferences->getString(preference_mqtt_hass_discovery, "") != "";
|
_haEnabled = _preferences->getString(preference_mqtt_hass_discovery, "") != "";
|
||||||
_disableNonJSON = _preferences->getBool(preference_disable_non_json, false);
|
_disableNonJSON = _preferences->getBool(preference_disable_non_json, false);
|
||||||
_offEnabled = _preferences->getBool(preference_official_hybrid, false);
|
|
||||||
|
|
||||||
_network->initTopic(_mqttPath, mqtt_topic_lock_action, "--");
|
_network->initTopic(_mqttPath, mqtt_topic_lock_action, "--");
|
||||||
_network->subscribe(_mqttPath, mqtt_topic_lock_action);
|
_network->subscribe(_mqttPath, mqtt_topic_lock_action);
|
||||||
@@ -159,17 +149,13 @@ void NukiNetworkLock::initialize()
|
|||||||
_network->initTopic(_mqttPath, mqtt_topic_auth_action, "--");
|
_network->initTopic(_mqttPath, mqtt_topic_auth_action, "--");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_offEnabled)
|
if(_nukiOfficial->getOffEnabled())
|
||||||
{
|
{
|
||||||
char uidString[20];
|
_nukiOfficial->setUid(_preferences->getUInt(preference_nuki_id_lock, 0));
|
||||||
itoa(_preferences->getUInt(preference_nuki_id_lock, 0), uidString, 16);
|
|
||||||
for(char* c=uidString; *c=toupper(*c); ++c);
|
|
||||||
strcpy(_offMqttPath, "nuki/");
|
|
||||||
strcat(_offMqttPath,uidString);
|
|
||||||
|
|
||||||
for(const auto& offTopic : _offTopics)
|
for(const auto& offTopic : _nukiOfficial->getOffTopics())
|
||||||
{
|
{
|
||||||
_network->subscribe(_offMqttPath, offTopic);
|
_network->subscribe(_nukiOfficial->getMqttPath(), offTopic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,6 +170,14 @@ void NukiNetworkLock::initialize()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NukiNetworkLock::update()
|
||||||
|
{
|
||||||
|
if(_nukiOfficial->hasOffStateToPublish())
|
||||||
|
{
|
||||||
|
publishState(_nukiOfficial->getOffStateToPublish());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NukiNetworkLock::onMqttDataReceived(char* topic, int topic_len, char* data, int data_len)
|
void NukiNetworkLock::onMqttDataReceived(char* topic, int topic_len, char* data, int data_len)
|
||||||
{
|
{
|
||||||
if(_network->mqttRecentlyConnected() && _network->pathEquals(_mqttPath, mqtt_topic_lock_action, topic))
|
if(_network->mqttRecentlyConnected() && _network->pathEquals(_mqttPath, mqtt_topic_lock_action, topic))
|
||||||
@@ -331,11 +325,11 @@ void NukiNetworkLock::onMqttDataReceived(char* topic, int topic_len, char* data,
|
|||||||
if(atoi(data) > 0 && atoi(data) > _lastRollingLog) _lastRollingLog = atoi(data);
|
if(atoi(data) > 0 && atoi(data) > _lastRollingLog) _lastRollingLog = atoi(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_offEnabled)
|
if(_nukiOfficial->getOffEnabled())
|
||||||
{
|
{
|
||||||
for(auto offTopic : _offTopics)
|
for(auto offTopic : _nukiOfficial->getOffTopics())
|
||||||
{
|
{
|
||||||
if(comparePrefixedPath(topic, offTopic, true))
|
if(_nukiOfficial->comparePrefixedPath(topic, offTopic))
|
||||||
{
|
{
|
||||||
if(_officialUpdateReceivedCallback != nullptr)
|
if(_officialUpdateReceivedCallback != nullptr)
|
||||||
{
|
{
|
||||||
@@ -500,7 +494,7 @@ void NukiNetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyT
|
|||||||
JsonDocument json;
|
JsonDocument json;
|
||||||
JsonDocument jsonBattery;
|
JsonDocument jsonBattery;
|
||||||
|
|
||||||
if(!_offConnected)
|
if(!_nukiOfficial->getOffConnected())
|
||||||
{
|
{
|
||||||
lockstateToString(keyTurnerState.lockState, str);
|
lockstateToString(keyTurnerState.lockState, str);
|
||||||
|
|
||||||
@@ -519,7 +513,7 @@ void NukiNetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyT
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lockstateToString((NukiLock::LockState)_offState, str);
|
lockstateToString((NukiLock::LockState)_nukiOfficial->getOffState(), str);
|
||||||
json["lock_state"] = str;
|
json["lock_state"] = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,7 +521,7 @@ void NukiNetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyT
|
|||||||
|
|
||||||
memset(&str, 0, sizeof(str));
|
memset(&str, 0, sizeof(str));
|
||||||
|
|
||||||
if(!_offConnected)
|
if(!_nukiOfficial->getOffConnected())
|
||||||
{
|
{
|
||||||
triggerToString(keyTurnerState.trigger, str);
|
triggerToString(keyTurnerState.trigger, str);
|
||||||
|
|
||||||
@@ -540,7 +534,7 @@ void NukiNetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyT
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
triggerToString((NukiLock::Trigger)_offTrigger, str);
|
triggerToString((NukiLock::Trigger)_nukiOfficial->getOffTrigger(), str);
|
||||||
json["trigger"] = str;
|
json["trigger"] = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,7 +546,7 @@ void NukiNetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyT
|
|||||||
|
|
||||||
memset(&str, 0, sizeof(str));
|
memset(&str, 0, sizeof(str));
|
||||||
|
|
||||||
if(!_offConnected)
|
if(!_nukiOfficial->getOffConnected())
|
||||||
{
|
{
|
||||||
lockactionToString(keyTurnerState.lastLockAction, str);
|
lockactionToString(keyTurnerState.lastLockAction, str);
|
||||||
|
|
||||||
@@ -565,7 +559,7 @@ void NukiNetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyT
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lockactionToString((NukiLock::LockAction)_offLockAction, str);
|
lockactionToString((NukiLock::LockAction)_nukiOfficial->getOffLockAction(), str);
|
||||||
json["last_lock_action"] = str;
|
json["last_lock_action"] = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +578,7 @@ void NukiNetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyT
|
|||||||
json["lock_completion_status"] = str;
|
json["lock_completion_status"] = str;
|
||||||
memset(&str, 0, sizeof(str));
|
memset(&str, 0, sizeof(str));
|
||||||
|
|
||||||
if(!_offConnected)
|
if(!_nukiOfficial->getOffConnected())
|
||||||
{
|
{
|
||||||
NukiLock::doorSensorStateToString(keyTurnerState.doorSensorState, str);
|
NukiLock::doorSensorStateToString(keyTurnerState.doorSensorState, str);
|
||||||
|
|
||||||
@@ -622,11 +616,11 @@ void NukiNetworkLock::publishKeyTurnerState(const NukiLock::KeyTurnerState& keyT
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NukiLock::doorSensorStateToString((NukiLock::DoorSensorState)_offDoorsensorState, str);
|
NukiLock::doorSensorStateToString((NukiLock::DoorSensorState)_nukiOfficial->getOffDoorsensorState(), str);
|
||||||
json["door_sensor_state"] = str;
|
json["door_sensor_state"] = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
json["auth_id"] = _authId;
|
json["auth_id"] = getAuthId();
|
||||||
json["auth_name"] = _authName;
|
json["auth_name"] = _authName;
|
||||||
|
|
||||||
serializeJson(json, _buffer, _bufferSize);
|
serializeJson(json, _buffer, _bufferSize);
|
||||||
@@ -698,13 +692,14 @@ void NukiNetworkLock::publishAuthorizationInfo(const std::list<NukiLock::LogEntr
|
|||||||
{
|
{
|
||||||
authIndex = log.index;
|
authIndex = log.index;
|
||||||
_authId = log.authId;
|
_authId = log.authId;
|
||||||
|
_nukiOfficial->clearAuthId();
|
||||||
memset(_authName, 0, sizeof(_authName));
|
memset(_authName, 0, sizeof(_authName));
|
||||||
memcpy(_authName, authName, sizeof(authName));
|
memcpy(_authName, authName, sizeof(authName));
|
||||||
|
|
||||||
if(authName[sizeName - 1] != '\0' && _authEntries.count(_authId) > 0)
|
if(authName[sizeName - 1] != '\0' && _authEntries.count(getAuthId()) > 0)
|
||||||
{
|
{
|
||||||
memset(_authName, 0, sizeof(_authName));
|
memset(_authName, 0, sizeof(_authName));
|
||||||
memcpy(_authName, _authEntries[_authId].c_str(), sizeof(_authEntries[_authId].c_str()));
|
memcpy(_authName, _authEntries[getAuthId()].c_str(), sizeof(_authEntries[getAuthId()].c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -814,7 +809,7 @@ void NukiNetworkLock::publishAuthorizationInfo(const std::list<NukiLock::LogEntr
|
|||||||
|
|
||||||
if(authIndex > 0)
|
if(authIndex > 0)
|
||||||
{
|
{
|
||||||
publishUInt(mqtt_topic_lock_auth_id, _authId, true);
|
publishUInt(mqtt_topic_lock_auth_id, getAuthId(), true);
|
||||||
publishString(mqtt_topic_lock_auth_name, _authName, true);
|
publishString(mqtt_topic_lock_auth_name, _authName, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1575,13 +1570,12 @@ void NukiNetworkLock::setAuthCommandReceivedCallback(void (*authCommandReceivedR
|
|||||||
_authCommandReceivedReceivedCallback = authCommandReceivedReceivedCallback;
|
_authCommandReceivedReceivedCallback = authCommandReceivedReceivedCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkLock::buildMqttPath(const char* path, char* outPath, bool offPath)
|
void NukiNetworkLock::buildMqttPath(const char* path, char* outPath)
|
||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
char inPath[181] = {0};
|
char inPath[181] = {0};
|
||||||
|
|
||||||
if(offPath) memcpy(inPath, _offMqttPath, sizeof(_offMqttPath));
|
memcpy(inPath, _mqttPath, sizeof(_mqttPath));
|
||||||
else memcpy(inPath, _mqttPath, sizeof(_mqttPath));
|
|
||||||
|
|
||||||
for(const char& c : inPath)
|
for(const char& c : inPath)
|
||||||
{
|
{
|
||||||
@@ -1602,10 +1596,10 @@ void NukiNetworkLock::buildMqttPath(const char* path, char* outPath, bool offPat
|
|||||||
outPath[i+1] = 0x00;
|
outPath[i+1] = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NukiNetworkLock::comparePrefixedPath(const char *fullPath, const char *subPath, bool offPath)
|
bool NukiNetworkLock::comparePrefixedPath(const char *fullPath, const char *subPath)
|
||||||
{
|
{
|
||||||
char prefixedPath[500];
|
char prefixedPath[500];
|
||||||
buildMqttPath(subPath, prefixedPath, offPath);
|
buildMqttPath(subPath, prefixedPath);
|
||||||
return strcmp(fullPath, prefixedPath) == 0;
|
return strcmp(fullPath, prefixedPath) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1651,63 +1645,57 @@ void NukiNetworkLock::publishHASSConfig(char *deviceType, const char *baseTopic,
|
|||||||
|
|
||||||
void NukiNetworkLock::removeHASSConfig(char *uidString)
|
void NukiNetworkLock::removeHASSConfig(char *uidString)
|
||||||
{
|
{
|
||||||
_network->removeHASSConfig(uidString);
|
return _network->removeHASSConfig(uidString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkLock::publishOffAction(const int value)
|
void NukiNetworkLock::publishOffAction(const int value)
|
||||||
{
|
{
|
||||||
_network->publishInt(_offMqttPath, mqtt_topic_official_lock_action, value, false);
|
return _network->publishInt(_nukiOfficial->getMqttPath(), mqtt_topic_official_lock_action, value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkLock::publishFloat(const char *topic, const float value, bool retain, const uint8_t precision)
|
void NukiNetworkLock::publishFloat(const char *topic, const float value, bool retain, const uint8_t precision)
|
||||||
{
|
{
|
||||||
_network->publishFloat(_mqttPath, topic, value, retain, precision);
|
return _nukiPublisher->publishFloat(topic, value, retain, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkLock::publishInt(const char *topic, const int value, bool retain)
|
void NukiNetworkLock::publishInt(const char *topic, const int value, bool retain)
|
||||||
{
|
{
|
||||||
_network->publishInt(_mqttPath, topic, value, retain);
|
return _nukiPublisher->publishInt(topic, value, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkLock::publishUInt(const char *topic, const unsigned int value, bool retain)
|
void NukiNetworkLock::publishUInt(const char *topic, const unsigned int value, bool retain)
|
||||||
{
|
{
|
||||||
_network->publishUInt(_mqttPath, topic, value, retain);
|
return _nukiPublisher->publishUInt(topic, value, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkLock::publishBool(const char *topic, const bool value, bool retain)
|
void NukiNetworkLock::publishBool(const char *topic, const bool value, bool retain)
|
||||||
{
|
{
|
||||||
_network->publishBool(_mqttPath, topic, value, retain);
|
return _nukiPublisher->publishBool(topic, value, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NukiNetworkLock::publishString(const char *topic, const String &value, bool retain)
|
bool NukiNetworkLock::publishString(const char *topic, const String &value, bool retain)
|
||||||
{
|
{
|
||||||
char str[value.length() + 1];
|
return _nukiPublisher->publishString(topic, value, retain);
|
||||||
memset(str, 0, sizeof(str));
|
|
||||||
memcpy(str, value.begin(), value.length());
|
|
||||||
return publishString(topic, str, retain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NukiNetworkLock::publishString(const char *topic, const std::string &value, bool retain)
|
bool NukiNetworkLock::publishString(const char *topic, const std::string &value, bool retain)
|
||||||
{
|
{
|
||||||
char str[value.size() + 1];
|
return _nukiPublisher->publishString(topic, value, retain);
|
||||||
memset(str, 0, sizeof(str));
|
|
||||||
memcpy(str, value.data(), value.length());
|
|
||||||
return publishString(topic, str, retain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NukiNetworkLock::publishString(const char *topic, const char *value, bool retain)
|
bool NukiNetworkLock::publishString(const char *topic, const char *value, bool retain)
|
||||||
{
|
{
|
||||||
return _network->publishString(_mqttPath, topic, value, retain);
|
return _nukiPublisher->publishString(topic, value, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkLock::publishULong(const char *topic, const unsigned long value, bool retain)
|
void NukiNetworkLock::publishULong(const char *topic, const unsigned long value, bool retain)
|
||||||
{
|
{
|
||||||
return _network->publishULong(_mqttPath, topic, value, retain);
|
return _nukiPublisher->publishULong(topic, value, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkLock::publishLongLong(const char *topic, int64_t value, bool retain)
|
void NukiNetworkLock::publishLongLong(const char *topic, int64_t value, bool retain)
|
||||||
{
|
{
|
||||||
return _network->publishLongLong(_mqttPath, topic, value, retain);
|
return _nukiPublisher->publishLongLong(topic, value, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
String NukiNetworkLock::concat(String a, String b)
|
String NukiNetworkLock::concat(String a, String b)
|
||||||
@@ -1802,3 +1790,12 @@ void NukiNetworkLock::fobActionToString(const int fobact, char* str) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint32_t NukiNetworkLock::getAuthId() const
|
||||||
|
{
|
||||||
|
if(_nukiOfficial->hasAuthId())
|
||||||
|
{
|
||||||
|
return _nukiOfficial->getAuthId();
|
||||||
|
}
|
||||||
|
return _authId;
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,14 +12,17 @@
|
|||||||
#include "NukiNetwork.h"
|
#include "NukiNetwork.h"
|
||||||
#include "QueryCommand.h"
|
#include "QueryCommand.h"
|
||||||
#include "LockActionResult.h"
|
#include "LockActionResult.h"
|
||||||
|
#include "NukiOfficial.h"
|
||||||
|
#include "NukiPublisher.h"
|
||||||
|
|
||||||
class NukiNetworkLock : public MqttReceiver
|
class NukiNetworkLock : public MqttReceiver
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit NukiNetworkLock(NukiNetwork* network, Preferences* preferences, char* buffer, size_t bufferSize);
|
explicit NukiNetworkLock(NukiNetwork* network, NukiOfficial* nukiOfficial, Preferences* preferences, char* buffer, size_t bufferSize);
|
||||||
virtual ~NukiNetworkLock();
|
virtual ~NukiNetworkLock();
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
|
void update();
|
||||||
|
|
||||||
void publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurnerState, const NukiLock::KeyTurnerState& lastKeyTurnerState);
|
void publishKeyTurnerState(const NukiLock::KeyTurnerState& keyTurnerState, const NukiLock::KeyTurnerState& lastKeyTurnerState);
|
||||||
void publishState(NukiLock::LockState lockState);
|
void publishState(NukiLock::LockState lockState);
|
||||||
@@ -65,55 +68,38 @@ public:
|
|||||||
bool publishString(const char* topic, const std::string& value, bool retain);
|
bool publishString(const char* topic, const std::string& value, bool retain);
|
||||||
bool publishString(const char* topic, const char* value, bool retain);
|
bool publishString(const char* topic, const char* value, bool retain);
|
||||||
|
|
||||||
|
const uint32_t getAuthId() const;
|
||||||
|
|
||||||
bool reconnected();
|
bool reconnected();
|
||||||
uint8_t queryCommands();
|
uint8_t queryCommands();
|
||||||
//uint8_t _offMode = 0;
|
|
||||||
uint8_t _offState = 0;
|
|
||||||
bool _offCritical = false;
|
|
||||||
uint8_t _offChargeState = 100;
|
|
||||||
bool _offCharging = false;
|
|
||||||
bool _offKeypadCritical = false;
|
|
||||||
uint8_t _offDoorsensorState = 0;
|
|
||||||
bool _offDoorsensorCritical = false;
|
|
||||||
bool _offConnected = false;
|
|
||||||
uint8_t _offCommandResponse = 0;
|
|
||||||
char* _offLockActionEvent;
|
|
||||||
uint8_t _offLockAction = 0;
|
|
||||||
uint8_t _offTrigger = 0;
|
|
||||||
uint32_t _offAuthId = 0;
|
|
||||||
uint32_t _offCodeId = 0;
|
|
||||||
uint8_t _offContext = 0;
|
|
||||||
uint32_t _authId = 0;
|
|
||||||
int64_t _offCommandExecutedTs = 0;
|
|
||||||
NukiLock::LockAction _offCommand = (NukiLock::LockAction)0xff;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool comparePrefixedPath(const char* fullPath, const char* subPath, bool offPath = false);
|
bool comparePrefixedPath(const char* fullPath, const char* subPath);
|
||||||
|
|
||||||
void publishKeypadEntry(const String topic, NukiLock::KeypadEntry entry);
|
void publishKeypadEntry(const String topic, NukiLock::KeypadEntry entry);
|
||||||
void buttonPressActionToString(const NukiLock::ButtonPressAction btnPressAction, char* str);
|
void buttonPressActionToString(const NukiLock::ButtonPressAction btnPressAction, char* str);
|
||||||
void homeKitStatusToString(const int hkstatus, char* str);
|
void homeKitStatusToString(const int hkstatus, char* str);
|
||||||
void fobActionToString(const int fobact, char* str);
|
void fobActionToString(const int fobact, char* str);
|
||||||
|
|
||||||
|
void (*_officialUpdateReceivedCallback)(const char* path, const char* value) = nullptr;
|
||||||
|
|
||||||
String concat(String a, String b);
|
String concat(String a, String b);
|
||||||
|
|
||||||
void buildMqttPath(const char* path, char* outPath, bool offPath = false);
|
void buildMqttPath(const char* path, char* outPath);
|
||||||
|
|
||||||
NukiNetwork* _network;
|
NukiNetwork* _network = nullptr;
|
||||||
Preferences* _preferences;
|
NukiPublisher* _nukiPublisher = nullptr;
|
||||||
|
NukiOfficial* _nukiOfficial = nullptr;
|
||||||
|
Preferences* _preferences = nullptr;
|
||||||
|
|
||||||
std::map<uint32_t, String> _authEntries;
|
std::map<uint32_t, String> _authEntries;
|
||||||
std::vector<char*> _offTopics;
|
|
||||||
char _mqttPath[181] = {0};
|
char _mqttPath[181] = {0};
|
||||||
char _offMqttPath[181] = {0};
|
|
||||||
|
|
||||||
bool _firstTunerStatePublish = true;
|
bool _firstTunerStatePublish = true;
|
||||||
int64_t _lastMaintenanceTs = 0;
|
int64_t _lastMaintenanceTs = 0;
|
||||||
bool _haEnabled = false;
|
bool _haEnabled = false;
|
||||||
bool _reconnected = false;
|
bool _reconnected = false;
|
||||||
bool _disableNonJSON = false;
|
bool _disableNonJSON = false;
|
||||||
bool _offEnabled = false;
|
|
||||||
|
|
||||||
String _keypadCommandName = "";
|
String _keypadCommandName = "";
|
||||||
String _keypadCommandCode = "";
|
String _keypadCommandCode = "";
|
||||||
@@ -121,6 +107,7 @@ private:
|
|||||||
int _keypadCommandEnabled = 1;
|
int _keypadCommandEnabled = 1;
|
||||||
uint8_t _queryCommands = 0;
|
uint8_t _queryCommands = 0;
|
||||||
uint32_t _lastRollingLog = 0;
|
uint32_t _lastRollingLog = 0;
|
||||||
|
uint32_t _authId = 0;
|
||||||
|
|
||||||
char _nukiName[33];
|
char _nukiName[33];
|
||||||
char _authName[33];
|
char _authName[33];
|
||||||
@@ -129,7 +116,6 @@ private:
|
|||||||
size_t _bufferSize;
|
size_t _bufferSize;
|
||||||
|
|
||||||
LockActionResult (*_lockActionReceivedCallback)(const char* value) = nullptr;
|
LockActionResult (*_lockActionReceivedCallback)(const char* value) = nullptr;
|
||||||
void (*_officialUpdateReceivedCallback)(const char* path, const char* value) = nullptr;
|
|
||||||
void (*_configUpdateReceivedCallback)(const char* value) = nullptr;
|
void (*_configUpdateReceivedCallback)(const char* value) = nullptr;
|
||||||
void (*_keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code, const int& enabled) = nullptr;
|
void (*_keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code, const int& enabled) = nullptr;
|
||||||
void (*_keypadJsonCommandReceivedReceivedCallback)(const char* value) = nullptr;
|
void (*_keypadJsonCommandReceivedReceivedCallback)(const char* value) = nullptr;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ NukiNetworkOpener::NukiNetworkOpener(NukiNetwork* network, Preferences* preferen
|
|||||||
_buffer(buffer),
|
_buffer(buffer),
|
||||||
_bufferSize(bufferSize)
|
_bufferSize(bufferSize)
|
||||||
{
|
{
|
||||||
|
_nukiPublisher = new NukiPublisher(network, _mqttPath);
|
||||||
|
|
||||||
memset(_authName, 0, sizeof(_authName));
|
memset(_authName, 0, sizeof(_authName));
|
||||||
_authName[0] = '\0';
|
_authName[0] = '\0';
|
||||||
|
|
||||||
@@ -1380,22 +1382,22 @@ void NukiNetworkOpener::setAuthCommandReceivedCallback(void (*authCommandReceive
|
|||||||
|
|
||||||
void NukiNetworkOpener::publishFloat(const char *topic, const float value, bool retain, const uint8_t precision)
|
void NukiNetworkOpener::publishFloat(const char *topic, const float value, bool retain, const uint8_t precision)
|
||||||
{
|
{
|
||||||
_network->publishFloat(_mqttPath, topic, value, retain, precision);
|
_nukiPublisher->publishFloat(topic, value, retain, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkOpener::publishInt(const char *topic, const int value, bool retain)
|
void NukiNetworkOpener::publishInt(const char *topic, const int value, bool retain)
|
||||||
{
|
{
|
||||||
_network->publishInt(_mqttPath, topic, value, retain);
|
_nukiPublisher->publishInt(topic, value, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkOpener::publishUInt(const char *topic, const unsigned int value, bool retain)
|
void NukiNetworkOpener::publishUInt(const char *topic, const unsigned int value, bool retain)
|
||||||
{
|
{
|
||||||
_network->publishUInt(_mqttPath, topic, value, retain);
|
_nukiPublisher->publishUInt(topic, value, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkOpener::publishBool(const char *topic, const bool value, bool retain)
|
void NukiNetworkOpener::publishBool(const char *topic, const bool value, bool retain)
|
||||||
{
|
{
|
||||||
_network->publishBool(_mqttPath, topic, value, retain);
|
_nukiPublisher->publishBool(topic, value, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkOpener::publishString(const char *topic, const String &value, bool retain)
|
void NukiNetworkOpener::publishString(const char *topic, const String &value, bool retain)
|
||||||
@@ -1416,7 +1418,7 @@ void NukiNetworkOpener::publishString(const char *topic, const std::string &valu
|
|||||||
|
|
||||||
void NukiNetworkOpener::publishString(const char* topic, const char* value, bool retain)
|
void NukiNetworkOpener::publishString(const char* topic, const char* value, bool retain)
|
||||||
{
|
{
|
||||||
_network->publishString(_mqttPath, topic, value, retain);
|
_nukiPublisher->publishString(topic, value, retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiNetworkOpener::publishKeypadEntry(const String topic, NukiLock::KeypadEntry entry)
|
void NukiNetworkOpener::publishKeypadEntry(const String topic, NukiLock::KeypadEntry entry)
|
||||||
|
|||||||
@@ -76,9 +76,10 @@ private:
|
|||||||
|
|
||||||
String concat(String a, String b);
|
String concat(String a, String b);
|
||||||
|
|
||||||
Preferences* _preferences;
|
Preferences* _preferences = nullptr;
|
||||||
|
|
||||||
NukiNetwork* _network = nullptr;
|
NukiNetwork* _network = nullptr;
|
||||||
|
NukiPublisher* _nukiPublisher = nullptr;
|
||||||
|
|
||||||
std::map<uint32_t, String> _authEntries;
|
std::map<uint32_t, String> _authEntries;
|
||||||
char _mqttPath[181] = {0};
|
char _mqttPath[181] = {0};
|
||||||
|
|||||||
325
src/NukiOfficial.cpp
Normal file
325
src/NukiOfficial.cpp
Normal file
@@ -0,0 +1,325 @@
|
|||||||
|
#include <cstring>
|
||||||
|
#include "NukiOfficial.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
#include "PreferencesKeys.h"
|
||||||
|
#include "../lib/nuki_ble/src/NukiLockUtils.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
|
NukiOfficial::NukiOfficial(Preferences *preferences)
|
||||||
|
{
|
||||||
|
offEnabled = preferences->getBool(preference_official_hybrid_enabled, false);
|
||||||
|
_disableNonJSON = preferences->getBool(preference_disable_non_json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NukiOfficial::setUid(const uint32_t& uid)
|
||||||
|
{
|
||||||
|
char uidString[20];
|
||||||
|
itoa(uid, uidString, 16);
|
||||||
|
|
||||||
|
for(char* c=uidString; *c=toupper(*c); ++c);
|
||||||
|
|
||||||
|
strcpy(mqttPath, "nuki/");
|
||||||
|
strcat(mqttPath, uidString);
|
||||||
|
|
||||||
|
offTopics.reserve(10);
|
||||||
|
//_offTopics.push_back(mqtt_topic_official_mode);
|
||||||
|
offTopics.push_back((char*)mqtt_topic_official_state);
|
||||||
|
offTopics.push_back((char*)mqtt_topic_official_batteryCritical);
|
||||||
|
offTopics.push_back((char*)mqtt_topic_official_batteryChargeState);
|
||||||
|
offTopics.push_back((char*)mqtt_topic_official_batteryCharging);
|
||||||
|
offTopics.push_back((char*)mqtt_topic_official_keypadBatteryCritical);
|
||||||
|
offTopics.push_back((char*)mqtt_topic_official_doorsensorState);
|
||||||
|
offTopics.push_back((char*)mqtt_topic_official_doorsensorBatteryCritical);
|
||||||
|
offTopics.push_back((char*)mqtt_topic_official_connected);
|
||||||
|
offTopics.push_back((char*)mqtt_topic_official_commandResponse);
|
||||||
|
offTopics.push_back((char*)mqtt_topic_official_lockActionEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiOfficial::setPublisher(NukiPublisher *publisher)
|
||||||
|
{
|
||||||
|
_publisher = publisher;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *NukiOfficial::getMqttPath() const
|
||||||
|
{
|
||||||
|
return mqttPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiOfficial::buildMqttPath(const char *path, char *outPath)
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
char inPath[181] = {0};
|
||||||
|
|
||||||
|
memcpy(inPath, mqttPath, sizeof(mqttPath));
|
||||||
|
|
||||||
|
for(const char& c : inPath)
|
||||||
|
{
|
||||||
|
if(c == 0x00)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
outPath[offset] = c;
|
||||||
|
++offset;
|
||||||
|
}
|
||||||
|
int i=0;
|
||||||
|
while(outPath[i] != 0x00)
|
||||||
|
{
|
||||||
|
outPath[offset] = path[i];
|
||||||
|
++i;
|
||||||
|
++offset;
|
||||||
|
}
|
||||||
|
outPath[i+1] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NukiOfficial::comparePrefixedPath(const char *fullPath, const char *subPath)
|
||||||
|
{
|
||||||
|
char prefixedPath[500];
|
||||||
|
buildMqttPath(subPath, prefixedPath);
|
||||||
|
return strcmp(fullPath, prefixedPath) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiOfficial::onOfficialUpdateReceived(const char *topic, const char *value)
|
||||||
|
{
|
||||||
|
char str[50];
|
||||||
|
bool publishBatteryJson = false;
|
||||||
|
memset(&str, 0, sizeof(str));
|
||||||
|
|
||||||
|
Log->println("Official Nuki change recieved");
|
||||||
|
Log->print(F("Topic: "));
|
||||||
|
Log->println(topic);
|
||||||
|
Log->print(F("Value: "));
|
||||||
|
Log->println(value);
|
||||||
|
|
||||||
|
if(strcmp(topic, mqtt_topic_official_connected) == 0)
|
||||||
|
{
|
||||||
|
Log->print(F("Connected: "));
|
||||||
|
Log->println((strcmp(value, "true") == 0 ? 1 : 0));
|
||||||
|
offConnected = (strcmp(value, "true") == 0 ? 1 : 0);
|
||||||
|
_publisher->publishBool(mqtt_hybrid_state, offConnected, true);
|
||||||
|
}
|
||||||
|
else if(strcmp(topic, mqtt_topic_official_state) == 0)
|
||||||
|
{
|
||||||
|
offState = atoi(value);
|
||||||
|
_statusUpdated = true;
|
||||||
|
Log->println(F("Lock: Updating status on Hybrid state change"));
|
||||||
|
_publisher->publishBool(mqtt_hybrid_state, offConnected, true);
|
||||||
|
NukiLock::lockstateToString((NukiLock::LockState)offState, str);
|
||||||
|
_publisher->publishString(mqtt_topic_lock_state, str, true);
|
||||||
|
|
||||||
|
Log->print(F("Lockstate: "));
|
||||||
|
Log->println(str);
|
||||||
|
|
||||||
|
_offStateToPublish = (NukiLock::LockState)offState;
|
||||||
|
_hasOffStateToPublish = true;
|
||||||
|
}
|
||||||
|
else if(strcmp(topic, mqtt_topic_official_doorsensorState) == 0)
|
||||||
|
{
|
||||||
|
offDoorsensorState = atoi(value);
|
||||||
|
_statusUpdated = true;
|
||||||
|
Log->println(F("Lock: Updating status on Hybrid door sensor state change"));
|
||||||
|
_publisher->publishBool(mqtt_topic_lock_status_updated, _statusUpdated, true);
|
||||||
|
NukiLock::doorSensorStateToString((NukiLock::DoorSensorState)offDoorsensorState, str);
|
||||||
|
|
||||||
|
Log->print(F("Doorsensor state: "));
|
||||||
|
Log->println(str);
|
||||||
|
|
||||||
|
_publisher->publishString(mqtt_topic_lock_door_sensor_state, str, true);
|
||||||
|
}
|
||||||
|
else if(strcmp(topic, mqtt_topic_official_batteryCritical) == 0)
|
||||||
|
{
|
||||||
|
offCritical = (strcmp(value, "true") == 0 ? 1 : 0);
|
||||||
|
|
||||||
|
Log->print(F("Battery critical: "));
|
||||||
|
Log->println(offCritical);
|
||||||
|
|
||||||
|
if(!_disableNonJSON) _publisher->publishBool(mqtt_topic_battery_critical, offCritical, true);
|
||||||
|
publishBatteryJson = true;
|
||||||
|
}
|
||||||
|
else if(strcmp(topic, mqtt_topic_official_batteryCharging) == 0)
|
||||||
|
{
|
||||||
|
offCharging = (strcmp(value, "true") == 0 ? 1 : 0);
|
||||||
|
|
||||||
|
Log->print(F("Battery charging: "));
|
||||||
|
Log->println(offCharging);
|
||||||
|
|
||||||
|
if(!_disableNonJSON) _publisher->publishBool(mqtt_topic_battery_charging, offCharging, true);
|
||||||
|
publishBatteryJson = true;
|
||||||
|
}
|
||||||
|
else if(strcmp(topic, mqtt_topic_official_batteryChargeState) == 0)
|
||||||
|
{
|
||||||
|
offChargeState = atoi(value);
|
||||||
|
|
||||||
|
Log->print(F("Battery level: "));
|
||||||
|
Log->println(offChargeState);
|
||||||
|
|
||||||
|
if(!_disableNonJSON) _publisher->publishInt(mqtt_topic_battery_level, offChargeState, true);
|
||||||
|
publishBatteryJson = true;
|
||||||
|
}
|
||||||
|
else if(strcmp(topic, mqtt_topic_official_keypadBatteryCritical) == 0)
|
||||||
|
{
|
||||||
|
offKeypadCritical = (strcmp(value, "true") == 0 ? 1 : 0);
|
||||||
|
if(!_disableNonJSON) _publisher->publishBool(mqtt_topic_battery_keypad_critical, offKeypadCritical, true);
|
||||||
|
publishBatteryJson = true;
|
||||||
|
}
|
||||||
|
else if(strcmp(topic, mqtt_topic_official_doorsensorBatteryCritical) == 0)
|
||||||
|
{
|
||||||
|
offDoorsensorCritical = (strcmp(value, "true") == 0 ? 1 : 0);
|
||||||
|
if(!_disableNonJSON) _publisher->publishBool(mqtt_topic_battery_doorsensor_critical, offDoorsensorCritical, true);
|
||||||
|
publishBatteryJson = true;
|
||||||
|
}
|
||||||
|
else if(strcmp(topic, mqtt_topic_official_commandResponse) == 0)
|
||||||
|
{
|
||||||
|
offCommandResponse = atoi(value);
|
||||||
|
if(offCommandResponse == 0)
|
||||||
|
{
|
||||||
|
clearOffCommandExecutedTs();
|
||||||
|
}
|
||||||
|
char resultStr[15] = {0};
|
||||||
|
NukiLock::cmdResultToString((Nuki::CmdResult)offCommandResponse, resultStr);
|
||||||
|
_publisher->publishString(mqtt_topic_lock_action_command_result, resultStr, true);
|
||||||
|
}
|
||||||
|
else if(strcmp(topic, mqtt_topic_official_lockActionEvent) == 0)
|
||||||
|
{
|
||||||
|
clearOffCommandExecutedTs();
|
||||||
|
offLockActionEvent = (char*)value;
|
||||||
|
String LockActionEvent = offLockActionEvent;
|
||||||
|
const int ind1 = LockActionEvent.indexOf(',');
|
||||||
|
const int ind2 = LockActionEvent.indexOf(',', ind1+1);
|
||||||
|
const int ind3 = LockActionEvent.indexOf(',', ind2+1);
|
||||||
|
const int ind4 = LockActionEvent.indexOf(',', ind3+1);
|
||||||
|
const int ind5 = LockActionEvent.indexOf(',', ind4+1);
|
||||||
|
|
||||||
|
offLockAction = atoi(LockActionEvent.substring(0, ind1).c_str());
|
||||||
|
offTrigger = atoi(LockActionEvent.substring(ind1 + 1, ind2 + 1).c_str());
|
||||||
|
offAuthId = atoi(LockActionEvent.substring(ind2 + 1, ind3 + 1).c_str());
|
||||||
|
offCodeId = atoi(LockActionEvent.substring(ind3 + 1, ind4 + 1).c_str());
|
||||||
|
// offContext = atoi(LockActionEvent.substring(ind4 + 1, ind5 + 1).c_str());
|
||||||
|
|
||||||
|
memset(&str, 0, sizeof(str));
|
||||||
|
lockactionToString((NukiLock::LockAction)offLockAction, str);
|
||||||
|
_publisher->publishString(mqtt_topic_lock_last_lock_action, str, true);
|
||||||
|
|
||||||
|
memset(&str, 0, sizeof(str));
|
||||||
|
triggerToString((NukiLock::Trigger)offTrigger, str);
|
||||||
|
_publisher->publishString(mqtt_topic_lock_trigger, str, true);
|
||||||
|
|
||||||
|
if(offAuthId > 0 || offCodeId > 0)
|
||||||
|
{
|
||||||
|
if(offCodeId > 0)
|
||||||
|
{
|
||||||
|
_authId = offCodeId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_authId = offAuthId;
|
||||||
|
}
|
||||||
|
_hasAuthId = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
_network->_authName = RETRIEVE FROM VECTOR AFTER AUTHORIZATION ENTRIES ARE IMPLEMENTED;
|
||||||
|
_offContext = BASE ON CONTEXT OF TRIGGER AND PUBLISH TO MQTT;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(publishBatteryJson)
|
||||||
|
{
|
||||||
|
JsonDocument jsonBattery;
|
||||||
|
char _resbuf[2048];
|
||||||
|
jsonBattery["critical"] = offCritical ? "1" : "0";
|
||||||
|
jsonBattery["charging"] = offCharging ? "1" : "0";
|
||||||
|
jsonBattery["level"] = offChargeState;
|
||||||
|
jsonBattery["keypadCritical"] = offKeypadCritical ? "1" : "0";
|
||||||
|
jsonBattery["doorSensorCritical"] = offDoorsensorCritical ? "1" : "0";
|
||||||
|
serializeJson(jsonBattery, _resbuf, sizeof(_resbuf));
|
||||||
|
_publisher->publishString(mqtt_topic_battery_basic_json, _resbuf, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool NukiOfficial::getStatusUpdated()
|
||||||
|
{
|
||||||
|
bool stu = _statusUpdated;
|
||||||
|
_statusUpdated = false;
|
||||||
|
return stu;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool NukiOfficial::hasOffStateToPublish()
|
||||||
|
{
|
||||||
|
bool hasOff = _hasOffStateToPublish;
|
||||||
|
_hasOffStateToPublish = false;
|
||||||
|
return hasOff;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NukiLock::LockState NukiOfficial::getOffStateToPublish() const
|
||||||
|
{
|
||||||
|
return _offStateToPublish;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t NukiOfficial::getAuthId() const
|
||||||
|
{
|
||||||
|
return _authId;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool NukiOfficial::hasAuthId() const
|
||||||
|
{
|
||||||
|
return _hasAuthId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiOfficial::clearAuthId()
|
||||||
|
{
|
||||||
|
_hasAuthId = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool NukiOfficial::getOffConnected() const
|
||||||
|
{
|
||||||
|
return offConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool NukiOfficial::getOffEnabled() const
|
||||||
|
{
|
||||||
|
return offEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t NukiOfficial::getOffDoorsensorState() const
|
||||||
|
{
|
||||||
|
return offDoorsensorState;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t NukiOfficial::getOffState() const
|
||||||
|
{
|
||||||
|
return offState;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t NukiOfficial::getOffLockAction() const
|
||||||
|
{
|
||||||
|
return offLockAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t NukiOfficial::getOffTrigger() const
|
||||||
|
{
|
||||||
|
return offTrigger;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int64_t NukiOfficial::getOffCommandExecutedTs() const
|
||||||
|
{
|
||||||
|
return offCommandExecutedTs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiOfficial::setOffCommandExecutedTs(const int64_t &value)
|
||||||
|
{
|
||||||
|
offCommandExecutedTs = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiOfficial::clearOffCommandExecutedTs()
|
||||||
|
{
|
||||||
|
offCommandExecutedTs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<char *> NukiOfficial::getOffTopics() const
|
||||||
|
{
|
||||||
|
return offTopics;
|
||||||
|
}
|
||||||
75
src/NukiOfficial.h
Normal file
75
src/NukiOfficial.h
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
#include "../lib/nuki_ble/src/NukiLockConstants.h"
|
||||||
|
#include "NukiPublisher.h"
|
||||||
|
|
||||||
|
class NukiOfficial
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit NukiOfficial(Preferences* preferences);
|
||||||
|
void setPublisher(NukiPublisher* publisher);
|
||||||
|
|
||||||
|
void setUid(const uint32_t& uid);
|
||||||
|
|
||||||
|
const char* getMqttPath() const;
|
||||||
|
const bool getStatusUpdated();
|
||||||
|
|
||||||
|
const bool hasOffStateToPublish();
|
||||||
|
const NukiLock::LockState getOffStateToPublish() const;
|
||||||
|
|
||||||
|
const uint32_t getAuthId() const;
|
||||||
|
const bool hasAuthId() const;
|
||||||
|
void clearAuthId();
|
||||||
|
|
||||||
|
void buildMqttPath(const char* path, char* outPath);
|
||||||
|
bool comparePrefixedPath(const char *fullPath, const char *subPath);
|
||||||
|
|
||||||
|
void onOfficialUpdateReceived(const char* topic, const char* value);
|
||||||
|
|
||||||
|
const bool getOffConnected() const;
|
||||||
|
const bool getOffEnabled() const;
|
||||||
|
const uint8_t getOffDoorsensorState() const;
|
||||||
|
const uint8_t getOffState() const;
|
||||||
|
const uint8_t getOffLockAction() const;
|
||||||
|
const uint8_t getOffTrigger() const;
|
||||||
|
const std::vector<char*> getOffTopics() const;
|
||||||
|
|
||||||
|
const int64_t getOffCommandExecutedTs() const;
|
||||||
|
void setOffCommandExecutedTs(const int64_t& value);
|
||||||
|
void clearOffCommandExecutedTs();
|
||||||
|
|
||||||
|
private:
|
||||||
|
char mqttPath[181] = {0};
|
||||||
|
std::vector<char*> offTopics;
|
||||||
|
|
||||||
|
NukiPublisher* _publisher = nullptr;
|
||||||
|
bool _statusUpdated = false;
|
||||||
|
bool _hasOffStateToPublish = false;
|
||||||
|
NukiLock::LockState _offStateToPublish = (NukiLock::LockState)0;
|
||||||
|
uint32_t _authId = 0;
|
||||||
|
bool _hasAuthId = false;
|
||||||
|
bool _disableNonJSON = false;
|
||||||
|
|
||||||
|
int64_t offCommandExecutedTs = 0;
|
||||||
|
|
||||||
|
//uint8_t _offMode = 0;
|
||||||
|
uint8_t offState = 0;
|
||||||
|
bool offCritical = false;
|
||||||
|
uint8_t offChargeState = 100;
|
||||||
|
bool offCharging = false;
|
||||||
|
bool offKeypadCritical = false;
|
||||||
|
uint8_t offDoorsensorState = 0;
|
||||||
|
bool offDoorsensorCritical = false;
|
||||||
|
bool offConnected = false;
|
||||||
|
uint8_t offCommandResponse = 0;
|
||||||
|
char* offLockActionEvent;
|
||||||
|
uint8_t offLockAction = 0;
|
||||||
|
uint8_t offTrigger = 0;
|
||||||
|
uint32_t offAuthId = 0;
|
||||||
|
uint32_t offCodeId = 0;
|
||||||
|
// uint8_t offContext = 0;
|
||||||
|
bool offEnabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
59
src/NukiPublisher.cpp
Normal file
59
src/NukiPublisher.cpp
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#include "NukiPublisher.h"
|
||||||
|
|
||||||
|
|
||||||
|
NukiPublisher::NukiPublisher(NukiNetwork *network, const char* mqttPath)
|
||||||
|
: _network(network),
|
||||||
|
_mqttPath(mqttPath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiPublisher::publishFloat(const char *topic, const float value, bool retain, const uint8_t precision)
|
||||||
|
{
|
||||||
|
_network->publishFloat(_mqttPath, topic, value, retain, precision);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiPublisher::publishInt(const char *topic, const int value, bool retain)
|
||||||
|
{
|
||||||
|
_network->publishInt(_mqttPath, topic, value, retain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiPublisher::publishUInt(const char *topic, const unsigned int value, bool retain)
|
||||||
|
{
|
||||||
|
_network->publishUInt(_mqttPath, topic, value, retain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiPublisher::publishBool(const char *topic, const bool value, bool retain)
|
||||||
|
{
|
||||||
|
_network->publishBool(_mqttPath, topic, value, retain);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NukiPublisher::publishString(const char *topic, const String &value, bool retain)
|
||||||
|
{
|
||||||
|
char str[value.length() + 1];
|
||||||
|
memset(str, 0, sizeof(str));
|
||||||
|
memcpy(str, value.begin(), value.length());
|
||||||
|
return publishString(topic, str, retain);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NukiPublisher::publishString(const char *topic, const std::string &value, bool retain)
|
||||||
|
{
|
||||||
|
char str[value.size() + 1];
|
||||||
|
memset(str, 0, sizeof(str));
|
||||||
|
memcpy(str, value.data(), value.length());
|
||||||
|
return publishString(topic, str, retain);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NukiPublisher::publishString(const char *topic, const char *value, bool retain)
|
||||||
|
{
|
||||||
|
return _network->publishString(_mqttPath, topic, value, retain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiPublisher::publishULong(const char *topic, const unsigned long value, bool retain)
|
||||||
|
{
|
||||||
|
return _network->publishULong(_mqttPath, topic, value, retain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiPublisher::publishLongLong(const char *topic, int64_t value, bool retain)
|
||||||
|
{
|
||||||
|
return _network->publishLongLong(_mqttPath, topic, value, retain);
|
||||||
|
}
|
||||||
25
src/NukiPublisher.h
Normal file
25
src/NukiPublisher.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include "NukiNetwork.h"
|
||||||
|
|
||||||
|
class NukiPublisher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NukiPublisher(NukiNetwork* _network, const char* mqttPath);
|
||||||
|
|
||||||
|
void publishFloat(const char* topic, const float value, bool retain, const uint8_t precision = 2);
|
||||||
|
void publishInt(const char* topic, const int value, bool retain);
|
||||||
|
void publishUInt(const char* topic, const unsigned int value, bool retain);
|
||||||
|
void publishULong(const char* topic, const unsigned long value, bool retain);
|
||||||
|
void publishLongLong(const char* topic, int64_t value, bool retain);
|
||||||
|
void publishBool(const char* topic, const bool value, bool retain);
|
||||||
|
bool publishString(const char* topic, const String& value, bool retain);
|
||||||
|
bool publishString(const char* topic, const std::string& value, bool retain);
|
||||||
|
bool publishString(const char* topic, const char* value, bool retain);
|
||||||
|
|
||||||
|
private:
|
||||||
|
NukiNetwork* _network;
|
||||||
|
const char* _mqttPath;
|
||||||
|
|
||||||
|
};
|
||||||
@@ -6,16 +6,15 @@
|
|||||||
#include <NukiLockUtils.h>
|
#include <NukiLockUtils.h>
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
NukiWrapper* nukiInst;
|
NukiWrapper* nukiInst = nullptr;
|
||||||
NukiNetworkLock* networkInst;
|
|
||||||
Preferences* nukiLockPreferences = nullptr;
|
|
||||||
|
|
||||||
NukiWrapper::NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NukiNetworkLock* network, Gpio* gpio, Preferences* preferences)
|
NukiWrapper::NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NukiNetworkLock* network, NukiOfficial* nukiOfficial, Gpio* gpio, Preferences* preferences)
|
||||||
: _deviceName(deviceName),
|
: _deviceName(deviceName),
|
||||||
_deviceId(deviceId),
|
_deviceId(deviceId),
|
||||||
_bleScanner(scanner),
|
_bleScanner(scanner),
|
||||||
_nukiLock(deviceName, _deviceId->get()),
|
_nukiLock(deviceName, _deviceId->get()),
|
||||||
_network(network),
|
_network(network),
|
||||||
|
_nukiOfficial(nukiOfficial),
|
||||||
_gpio(gpio),
|
_gpio(gpio),
|
||||||
_preferences(preferences)
|
_preferences(preferences)
|
||||||
{
|
{
|
||||||
@@ -23,7 +22,6 @@ NukiWrapper::NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId,
|
|||||||
Log->println(_deviceId->get());
|
Log->println(_deviceId->get());
|
||||||
|
|
||||||
nukiInst = this;
|
nukiInst = this;
|
||||||
networkInst = _network;
|
|
||||||
|
|
||||||
memset(&_lastKeyTurnerState, sizeof(NukiLock::KeyTurnerState), 0);
|
memset(&_lastKeyTurnerState, sizeof(NukiLock::KeyTurnerState), 0);
|
||||||
memset(&_lastBatteryReport, sizeof(NukiLock::BatteryReport), 0);
|
memset(&_lastBatteryReport, sizeof(NukiLock::BatteryReport), 0);
|
||||||
@@ -64,7 +62,7 @@ void NukiWrapper::initialize(const bool& firstStart)
|
|||||||
_preferences->putBool(preference_find_best_rssi, false);
|
_preferences->putBool(preference_find_best_rssi, false);
|
||||||
_preferences->putBool(preference_check_updates, true);
|
_preferences->putBool(preference_check_updates, true);
|
||||||
_preferences->putBool(preference_opener_continuous_mode, false);
|
_preferences->putBool(preference_opener_continuous_mode, false);
|
||||||
_preferences->putBool(preference_official_hybrid, false);
|
_preferences->putBool(preference_official_hybrid_enabled, false);
|
||||||
_preferences->putBool(preference_official_hybrid_actions, false);
|
_preferences->putBool(preference_official_hybrid_actions, false);
|
||||||
_preferences->putBool(preference_official_hybrid_retry, false);
|
_preferences->putBool(preference_official_hybrid_retry, false);
|
||||||
_preferences->putBool(preference_disable_non_json, false);
|
_preferences->putBool(preference_disable_non_json, false);
|
||||||
@@ -105,7 +103,6 @@ void NukiWrapper::initialize(const bool& firstStart)
|
|||||||
}
|
}
|
||||||
|
|
||||||
_hassEnabled = _preferences->getString(preference_mqtt_hass_discovery) != "";
|
_hassEnabled = _preferences->getString(preference_mqtt_hass_discovery) != "";
|
||||||
_offEnabled = _preferences->getBool(preference_official_hybrid, false);
|
|
||||||
readSettings();
|
readSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,10 +247,10 @@ void NukiWrapper::update()
|
|||||||
|
|
||||||
_nukiLock.updateConnectionState();
|
_nukiLock.updateConnectionState();
|
||||||
|
|
||||||
if(networkInst->_offCommandExecutedTs>0 && ts >= networkInst->_offCommandExecutedTs)
|
if(_nukiOfficial->getOffCommandExecutedTs() > 0 && ts >= _nukiOfficial->getOffCommandExecutedTs())
|
||||||
{
|
{
|
||||||
nukiInst->_nextLockAction = networkInst->_offCommand;
|
nukiInst->_nextLockAction = _offCommand;
|
||||||
networkInst->_offCommandExecutedTs = 0;
|
_nukiOfficial->clearOffCommandExecutedTs();
|
||||||
}
|
}
|
||||||
if(_nextLockAction != (NukiLock::LockAction)0xff)
|
if(_nextLockAction != (NukiLock::LockAction)0xff)
|
||||||
{
|
{
|
||||||
@@ -293,7 +290,7 @@ void NukiWrapper::update()
|
|||||||
_nextLockAction = (NukiLock::LockAction) 0xff;
|
_nextLockAction = (NukiLock::LockAction) 0xff;
|
||||||
_network->publishRetry("--");
|
_network->publishRetry("--");
|
||||||
retryCount = 0;
|
retryCount = 0;
|
||||||
if(!_network->_offConnected) _statusUpdated = true; Log->println(F("Lock: updating status after action"));
|
if(!_nukiOfficial->getOffConnected()) _statusUpdated = true; Log->println(F("Lock: updating status after action"));
|
||||||
_statusUpdatedTs = ts;
|
_statusUpdatedTs = ts;
|
||||||
if(_intervalLockstate > 10) _nextLockStateUpdateTs = ts + 10 * 1000;
|
if(_intervalLockstate > 10) _nextLockStateUpdateTs = ts + 10 * 1000;
|
||||||
}
|
}
|
||||||
@@ -305,7 +302,7 @@ void NukiWrapper::update()
|
|||||||
_nextLockAction = (NukiLock::LockAction) 0xff;
|
_nextLockAction = (NukiLock::LockAction) 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(_statusUpdated || _nextLockStateUpdateTs == 0 || ts >= _nextLockStateUpdateTs || (queryCommands & QUERY_COMMAND_LOCKSTATE) > 0)
|
if(_nukiOfficial->getStatusUpdated() || _statusUpdated || _nextLockStateUpdateTs == 0 || ts >= _nextLockStateUpdateTs || (queryCommands & QUERY_COMMAND_LOCKSTATE) > 0)
|
||||||
{
|
{
|
||||||
Log->println("Updating Lock state based on status, timer or query");
|
Log->println("Updating Lock state based on status, timer or query");
|
||||||
_statusUpdated = false;
|
_statusUpdated = false;
|
||||||
@@ -497,7 +494,7 @@ void NukiWrapper::updateKeyTurnerState()
|
|||||||
|
|
||||||
updateGpioOutputs();
|
updateGpioOutputs();
|
||||||
}
|
}
|
||||||
else if(!_network->_offConnected && (esp_timer_get_time() / 1000) < _statusUpdatedTs + 10000)
|
else if(!_nukiOfficial->getOffConnected() && (esp_timer_get_time() / 1000) < _statusUpdatedTs + 10000)
|
||||||
{
|
{
|
||||||
_statusUpdated = true;
|
_statusUpdated = true;
|
||||||
Log->println(F("Lock: Keep updating status on intermediate lock state"));
|
Log->println(F("Lock: Keep updating status on intermediate lock state"));
|
||||||
@@ -933,6 +930,11 @@ NukiLock::LockAction NukiWrapper::lockActionToEnum(const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LockActionResult NukiWrapper::onLockActionReceivedCallback(const char *value)
|
LockActionResult NukiWrapper::onLockActionReceivedCallback(const char *value)
|
||||||
|
{
|
||||||
|
return nukiInst->onLockActionReceived(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
LockActionResult NukiWrapper::onLockActionReceived(const char *value)
|
||||||
{
|
{
|
||||||
NukiLock::LockAction action;
|
NukiLock::LockAction action;
|
||||||
|
|
||||||
@@ -947,33 +949,28 @@ LockActionResult NukiWrapper::onLockActionReceivedCallback(const char *value)
|
|||||||
}
|
}
|
||||||
else return LockActionResult::UnknownAction;
|
else return LockActionResult::UnknownAction;
|
||||||
|
|
||||||
nukiLockPreferences = new Preferences();
|
|
||||||
nukiLockPreferences->begin("nukihub", true);
|
|
||||||
uint32_t aclPrefs[17];
|
uint32_t aclPrefs[17];
|
||||||
nukiLockPreferences->getBytes(preference_acl, &aclPrefs, sizeof(aclPrefs));
|
_preferences->getBytes(preference_acl, &aclPrefs, sizeof(aclPrefs));
|
||||||
|
|
||||||
if((action == NukiLock::LockAction::Lock && (int)aclPrefs[0] == 1) || (action == NukiLock::LockAction::Unlock && (int)aclPrefs[1] == 1) || (action == NukiLock::LockAction::Unlatch && (int)aclPrefs[2] == 1) || (action == NukiLock::LockAction::LockNgo && (int)aclPrefs[3] == 1) || (action == NukiLock::LockAction::LockNgoUnlatch && (int)aclPrefs[4] == 1) || (action == NukiLock::LockAction::FullLock && (int)aclPrefs[5] == 1) || (action == NukiLock::LockAction::FobAction1 && (int)aclPrefs[6] == 1) || (action == NukiLock::LockAction::FobAction2 && (int)aclPrefs[7] == 1) || (action == NukiLock::LockAction::FobAction3 && (int)aclPrefs[8] == 1))
|
if((action == NukiLock::LockAction::Lock && (int)aclPrefs[0] == 1) || (action == NukiLock::LockAction::Unlock && (int)aclPrefs[1] == 1) || (action == NukiLock::LockAction::Unlatch && (int)aclPrefs[2] == 1) || (action == NukiLock::LockAction::LockNgo && (int)aclPrefs[3] == 1) || (action == NukiLock::LockAction::LockNgoUnlatch && (int)aclPrefs[4] == 1) || (action == NukiLock::LockAction::FullLock && (int)aclPrefs[5] == 1) || (action == NukiLock::LockAction::FobAction1 && (int)aclPrefs[6] == 1) || (action == NukiLock::LockAction::FobAction2 && (int)aclPrefs[7] == 1) || (action == NukiLock::LockAction::FobAction3 && (int)aclPrefs[8] == 1))
|
||||||
{
|
{
|
||||||
if(!networkInst->_offConnected) nukiInst->_nextLockAction = action;
|
if(!_nukiOfficial->getOffConnected()) nukiInst->_nextLockAction = action;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(nukiLockPreferences->getBool(preference_official_hybrid_actions, false))
|
if(_preferences->getBool(preference_official_hybrid_actions, false))
|
||||||
{
|
{
|
||||||
networkInst->_offCommandExecutedTs = (esp_timer_get_time() / 1000) + 2000;
|
_nukiOfficial->setOffCommandExecutedTs((esp_timer_get_time() / 1000) + 2000);
|
||||||
networkInst->_offCommand = action;
|
_offCommand = action;
|
||||||
networkInst->publishOffAction((int)action);
|
_network->publishOffAction((int)action);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nukiInst->_nextLockAction = action;
|
nukiInst->_nextLockAction = action;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nukiLockPreferences->end();
|
|
||||||
return LockActionResult::Success;
|
return LockActionResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
nukiLockPreferences->end();
|
|
||||||
|
|
||||||
return LockActionResult::AccessDenied;
|
return LockActionResult::AccessDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -989,7 +986,7 @@ void NukiWrapper::onConfigUpdateReceivedCallback(const char *value)
|
|||||||
|
|
||||||
bool NukiWrapper::offConnected()
|
bool NukiWrapper::offConnected()
|
||||||
{
|
{
|
||||||
return _network->_offConnected;
|
return _nukiOfficial->getOffConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
Nuki::AdvertisingMode NukiWrapper::advertisingModeToEnum(const char *str)
|
Nuki::AdvertisingMode NukiWrapper::advertisingModeToEnum(const char *str)
|
||||||
@@ -1085,152 +1082,7 @@ Nuki::BatteryType NukiWrapper::batteryTypeToEnum(const char* str)
|
|||||||
|
|
||||||
void NukiWrapper::onOfficialUpdateReceived(const char *topic, const char *value)
|
void NukiWrapper::onOfficialUpdateReceived(const char *topic, const char *value)
|
||||||
{
|
{
|
||||||
char str[50];
|
_nukiOfficial->onOfficialUpdateReceived(topic, value);
|
||||||
bool publishBatteryJson = false;
|
|
||||||
memset(&str, 0, sizeof(str));
|
|
||||||
|
|
||||||
Log->println("Official Nuki change recieved");
|
|
||||||
Log->print(F("Topic: "));
|
|
||||||
Log->println(topic);
|
|
||||||
Log->print(F("Value: "));
|
|
||||||
Log->println(value);
|
|
||||||
|
|
||||||
if(strcmp(topic, mqtt_topic_official_connected) == 0)
|
|
||||||
{
|
|
||||||
Log->print(F("Connected: "));
|
|
||||||
Log->println((strcmp(value, "true") == 0 ? 1 : 0));
|
|
||||||
_network->_offConnected = (strcmp(value, "true") == 0 ? 1 : 0);
|
|
||||||
_network->publishBool(mqtt_hybrid_state, _network->_offConnected, true);
|
|
||||||
|
|
||||||
if(!_network->_offConnected) _nextHybridLockStateUpdateTs = (esp_timer_get_time() / 1000) + _intervalHybridLockstate * 1000;
|
|
||||||
else _nextHybridLockStateUpdateTs = 0;
|
|
||||||
}
|
|
||||||
else if(strcmp(topic, mqtt_topic_official_state) == 0)
|
|
||||||
{
|
|
||||||
_network->_offState = atoi(value);
|
|
||||||
_statusUpdated = true;
|
|
||||||
Log->println(F("Lock: Updating status on Hybrid state change"));
|
|
||||||
_network->publishStatusUpdated(_statusUpdated);
|
|
||||||
NukiLock::lockstateToString((NukiLock::LockState)_network->_offState, str);
|
|
||||||
_network->publishString(mqtt_topic_lock_state, str, true);
|
|
||||||
|
|
||||||
Log->print(F("Lockstate: "));
|
|
||||||
Log->println(str);
|
|
||||||
|
|
||||||
_network->publishState((NukiLock::LockState)_network->_offState);
|
|
||||||
}
|
|
||||||
else if(strcmp(topic, mqtt_topic_official_doorsensorState) == 0)
|
|
||||||
{
|
|
||||||
_network->_offDoorsensorState = atoi(value);
|
|
||||||
_statusUpdated = true;
|
|
||||||
Log->println(F("Lock: Updating status on Hybrid door sensor state change"));
|
|
||||||
_network->publishStatusUpdated(_statusUpdated);
|
|
||||||
NukiLock::doorSensorStateToString((NukiLock::DoorSensorState)_network->_offDoorsensorState, str);
|
|
||||||
|
|
||||||
Log->print(F("Doorsensor state: "));
|
|
||||||
Log->println(str);
|
|
||||||
|
|
||||||
_network->publishString(mqtt_topic_lock_door_sensor_state, str, true);
|
|
||||||
}
|
|
||||||
else if(strcmp(topic, mqtt_topic_official_batteryCritical) == 0)
|
|
||||||
{
|
|
||||||
_network->_offCritical = (strcmp(value, "true") == 0 ? 1 : 0);
|
|
||||||
|
|
||||||
Log->print(F("Battery critical: "));
|
|
||||||
Log->println(_network->_offCritical);
|
|
||||||
|
|
||||||
if(!_disableNonJSON) _network->publishBool(mqtt_topic_battery_critical, _network->_offCritical, true);
|
|
||||||
publishBatteryJson = true;
|
|
||||||
}
|
|
||||||
else if(strcmp(topic, mqtt_topic_official_batteryCharging) == 0)
|
|
||||||
{
|
|
||||||
_network->_offCharging = (strcmp(value, "true") == 0 ? 1 : 0);
|
|
||||||
|
|
||||||
Log->print(F("Battery charging: "));
|
|
||||||
Log->println(_network->_offCharging);
|
|
||||||
|
|
||||||
if(!_disableNonJSON) _network->publishBool(mqtt_topic_battery_charging, _network->_offCharging, true);
|
|
||||||
publishBatteryJson = true;
|
|
||||||
}
|
|
||||||
else if(strcmp(topic, mqtt_topic_official_batteryChargeState) == 0)
|
|
||||||
{
|
|
||||||
_network->_offChargeState = atoi(value);
|
|
||||||
|
|
||||||
Log->print(F("Battery level: "));
|
|
||||||
Log->println(_network->_offChargeState);
|
|
||||||
|
|
||||||
if(!_disableNonJSON) _network->publishInt(mqtt_topic_battery_level, _network->_offChargeState, true);
|
|
||||||
publishBatteryJson = true;
|
|
||||||
}
|
|
||||||
else if(strcmp(topic, mqtt_topic_official_keypadBatteryCritical) == 0)
|
|
||||||
{
|
|
||||||
_network->_offKeypadCritical = (strcmp(value, "true") == 0 ? 1 : 0);
|
|
||||||
if(!_disableNonJSON) _network->publishBool(mqtt_topic_battery_keypad_critical, _network->_offKeypadCritical, true);
|
|
||||||
publishBatteryJson = true;
|
|
||||||
}
|
|
||||||
else if(strcmp(topic, mqtt_topic_official_doorsensorBatteryCritical) == 0)
|
|
||||||
{
|
|
||||||
_network->_offDoorsensorCritical = (strcmp(value, "true") == 0 ? 1 : 0);
|
|
||||||
if(!_disableNonJSON) _network->publishBool(mqtt_topic_battery_doorsensor_critical, _network->_offDoorsensorCritical, true);
|
|
||||||
publishBatteryJson = true;
|
|
||||||
}
|
|
||||||
else if(strcmp(topic, mqtt_topic_official_commandResponse) == 0)
|
|
||||||
{
|
|
||||||
_network->_offCommandResponse = atoi(value);
|
|
||||||
if(_network->_offCommandResponse == 0) networkInst->_offCommandExecutedTs = 0;
|
|
||||||
char resultStr[15] = {0};
|
|
||||||
NukiLock::cmdResultToString((Nuki::CmdResult)_network->_offCommandResponse, resultStr);
|
|
||||||
_network->publishCommandResult(resultStr);
|
|
||||||
}
|
|
||||||
else if(strcmp(topic, mqtt_topic_official_lockActionEvent) == 0)
|
|
||||||
{
|
|
||||||
networkInst->_offCommandExecutedTs = 0;
|
|
||||||
_network->_offLockActionEvent = (char*)value;
|
|
||||||
String LockActionEvent = _network->_offLockActionEvent;
|
|
||||||
const int ind1 = LockActionEvent.indexOf(',');
|
|
||||||
const int ind2 = LockActionEvent.indexOf(',', ind1+1);
|
|
||||||
const int ind3 = LockActionEvent.indexOf(',', ind2+1);
|
|
||||||
const int ind4 = LockActionEvent.indexOf(',', ind3+1);
|
|
||||||
const int ind5 = LockActionEvent.indexOf(',', ind4+1);
|
|
||||||
|
|
||||||
_network->_offLockAction = atoi(LockActionEvent.substring(0, ind1).c_str());
|
|
||||||
_network->_offTrigger = atoi(LockActionEvent.substring(ind1+1, ind2+1).c_str());
|
|
||||||
_network->_offAuthId = atoi(LockActionEvent.substring(ind2+1, ind3+1).c_str());
|
|
||||||
_network->_offCodeId = atoi(LockActionEvent.substring(ind3+1, ind4+1).c_str());
|
|
||||||
_network->_offContext = atoi(LockActionEvent.substring(ind4+1, ind5+1).c_str());
|
|
||||||
|
|
||||||
memset(&str, 0, sizeof(str));
|
|
||||||
lockactionToString((NukiLock::LockAction)_network->_offLockAction, str);
|
|
||||||
_network->publishString(mqtt_topic_lock_last_lock_action, str, true);
|
|
||||||
|
|
||||||
memset(&str, 0, sizeof(str));
|
|
||||||
triggerToString((NukiLock::Trigger)_network->_offTrigger, str);
|
|
||||||
_network->publishString(mqtt_topic_lock_trigger, str, true);
|
|
||||||
|
|
||||||
if(_network->_offAuthId > 0 || _network->_offCodeId > 0)
|
|
||||||
{
|
|
||||||
if(_network->_offCodeId > 0) _network->_authId = _network->_offCodeId;
|
|
||||||
else _network->_authId = _network->_offAuthId;
|
|
||||||
|
|
||||||
/*
|
|
||||||
_network->_authName = RETRIEVE FROM VECTOR AFTER AUTHORIZATION ENTRIES ARE IMPLEMENTED;
|
|
||||||
_network->_offContext = BASE ON CONTEXT OF TRIGGER AND PUBLISH TO MQTT;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(publishBatteryJson)
|
|
||||||
{
|
|
||||||
JsonDocument jsonBattery;
|
|
||||||
char _resbuf[2048];
|
|
||||||
jsonBattery["critical"] = _network->_offCritical ? "1" : "0";
|
|
||||||
jsonBattery["charging"] = _network->_offCharging ? "1" : "0";
|
|
||||||
jsonBattery["level"] = _network->_offChargeState;
|
|
||||||
jsonBattery["keypadCritical"] = _network->_offKeypadCritical ? "1" : "0";
|
|
||||||
jsonBattery["doorSensorCritical"] = _network->_offDoorsensorCritical ? "1" : "0";
|
|
||||||
serializeJson(jsonBattery, _resbuf, sizeof(_resbuf));
|
|
||||||
_network->publishString(mqtt_topic_battery_basic_json, _resbuf, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NukiWrapper::onConfigUpdateReceived(const char *value)
|
void NukiWrapper::onConfigUpdateReceived(const char *value)
|
||||||
@@ -1798,53 +1650,59 @@ void NukiWrapper::onAuthCommandReceivedCallback(const char *value)
|
|||||||
nukiInst->onAuthCommandReceived(value);
|
nukiInst->onAuthCommandReceived(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NukiWrapper::gpioActionCallback(const GpioAction &action, const int& pin)
|
void NukiWrapper::gpioActionCallback(const GpioAction &action, const int& pin)
|
||||||
|
{
|
||||||
|
nukiInst->onGpioActionReceived(action, pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NukiWrapper::onGpioActionReceived(const GpioAction &action, const int &pin)
|
||||||
{
|
{
|
||||||
switch(action)
|
switch(action)
|
||||||
{
|
{
|
||||||
case GpioAction::Lock:
|
case GpioAction::Lock:
|
||||||
if(!networkInst->_offConnected) nukiInst->lock();
|
if(!_nukiOfficial->getOffConnected()) nukiInst->lock();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
networkInst->_offCommandExecutedTs = (esp_timer_get_time() / 1000) + 2000;
|
_nukiOfficial->setOffCommandExecutedTs((esp_timer_get_time() / 1000) + 2000);
|
||||||
networkInst->_offCommand = NukiLock::LockAction::Lock;
|
_offCommand = NukiLock::LockAction::Lock;
|
||||||
networkInst->publishOffAction(2);
|
_network->publishOffAction(2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GpioAction::Unlock:
|
case GpioAction::Unlock:
|
||||||
if(!networkInst->_offConnected) nukiInst->unlock();
|
if(!_nukiOfficial->getOffConnected()) nukiInst->unlock();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
networkInst->_offCommandExecutedTs = (esp_timer_get_time() / 1000) + 2000;
|
_nukiOfficial->setOffCommandExecutedTs((esp_timer_get_time() / 1000) + 2000);
|
||||||
networkInst->_offCommand = NukiLock::LockAction::Unlock;
|
_offCommand = NukiLock::LockAction::Unlock;
|
||||||
networkInst->publishOffAction(1);
|
_network->publishOffAction(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GpioAction::Unlatch:
|
case GpioAction::Unlatch:
|
||||||
if(!networkInst->_offConnected) nukiInst->unlatch();
|
if(!_nukiOfficial->getOffConnected()) nukiInst->unlatch();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
networkInst->_offCommandExecutedTs = (esp_timer_get_time() / 1000) + 2000;
|
_nukiOfficial->setOffCommandExecutedTs((esp_timer_get_time() / 1000) + 2000);
|
||||||
networkInst->_offCommand = NukiLock::LockAction::Unlatch;
|
_offCommand = NukiLock::LockAction::Unlatch;
|
||||||
networkInst->publishOffAction(3);
|
_network->publishOffAction(3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GpioAction::LockNgo:
|
case GpioAction::LockNgo:
|
||||||
if(!networkInst->_offConnected) nukiInst->lockngo();
|
if(!_nukiOfficial->getOffConnected()) nukiInst->lockngo();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
networkInst->_offCommandExecutedTs = (esp_timer_get_time() / 1000) + 2000;
|
_nukiOfficial->setOffCommandExecutedTs((esp_timer_get_time() / 1000) + 2000);
|
||||||
networkInst->_offCommand = NukiLock::LockAction::LockNgo;
|
_offCommand = NukiLock::LockAction::LockNgo;
|
||||||
networkInst->publishOffAction(4);
|
_network->publishOffAction(4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GpioAction::LockNgoUnlatch:
|
case GpioAction::LockNgoUnlatch:
|
||||||
if(!networkInst->_offConnected) nukiInst->lockngounlatch();
|
if(!_nukiOfficial->getOffConnected()) nukiInst->lockngounlatch();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
networkInst->_offCommandExecutedTs = (esp_timer_get_time() / 1000) + 2000;
|
_nukiOfficial->setOffCommandExecutedTs((esp_timer_get_time() / 1000) + 2000);
|
||||||
networkInst->_offCommand = NukiLock::LockAction::LockNgoUnlatch;
|
_offCommand = NukiLock::LockAction::LockNgoUnlatch;
|
||||||
networkInst->publishOffAction(5);
|
_network->publishOffAction(5);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3142,13 +3000,12 @@ const bool NukiWrapper::hasKeypad() const
|
|||||||
|
|
||||||
void NukiWrapper::notify(Nuki::EventType eventType)
|
void NukiWrapper::notify(Nuki::EventType eventType)
|
||||||
{
|
{
|
||||||
if(!_network->_offConnected)
|
if(!_nukiOfficial->getOffConnected())
|
||||||
{
|
{
|
||||||
if(_offEnabled && _intervalHybridLockstate > 0 && (esp_timer_get_time() / 1000) > (_intervalHybridLockstate * 1000))
|
if(_nukiOfficial->getOffEnabled() && _intervalHybridLockstate > 0 && (esp_timer_get_time() / 1000) > (_intervalHybridLockstate * 1000))
|
||||||
{
|
{
|
||||||
Log->println("OffKeyTurnerStatusUpdated");
|
Log->println("OffKeyTurnerStatusUpdated");
|
||||||
_statusUpdated = true;
|
_statusUpdated = true;
|
||||||
_nextHybridLockStateUpdateTs = (esp_timer_get_time() / 1000) + _intervalHybridLockstate * 1000;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -3290,4 +3147,4 @@ void NukiWrapper::updateGpioOutputs()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,11 +8,12 @@
|
|||||||
#include "Gpio.h"
|
#include "Gpio.h"
|
||||||
#include "LockActionResult.h"
|
#include "LockActionResult.h"
|
||||||
#include "NukiDeviceId.h"
|
#include "NukiDeviceId.h"
|
||||||
|
#include "NukiOfficial.h"
|
||||||
|
|
||||||
class NukiWrapper : public Nuki::SmartlockEventHandler
|
class NukiWrapper : public Nuki::SmartlockEventHandler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NukiNetworkLock* network, Gpio* gpio, Preferences* preferences);
|
NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NukiNetworkLock* network, NukiOfficial* nukiOfficial, Gpio* gpio, Preferences* preferences);
|
||||||
virtual ~NukiWrapper();
|
virtual ~NukiWrapper();
|
||||||
|
|
||||||
void initialize(const bool& firstStart);
|
void initialize(const bool& firstStart);
|
||||||
@@ -56,12 +57,14 @@ private:
|
|||||||
static void onTimeControlCommandReceivedCallback(const char* value);
|
static void onTimeControlCommandReceivedCallback(const char* value);
|
||||||
static void onAuthCommandReceivedCallback(const char* value);
|
static void onAuthCommandReceivedCallback(const char* value);
|
||||||
static void gpioActionCallback(const GpioAction& action, const int& pin);
|
static void gpioActionCallback(const GpioAction& action, const int& pin);
|
||||||
|
LockActionResult onLockActionReceived(const char* value);
|
||||||
void onKeypadCommandReceived(const char* command, const uint& id, const String& name, const String& code, const int& enabled);
|
void onKeypadCommandReceived(const char* command, const uint& id, const String& name, const String& code, const int& enabled);
|
||||||
void onOfficialUpdateReceived(const char* topic, const char* value);
|
void onOfficialUpdateReceived(const char* topic, const char* value);
|
||||||
void onConfigUpdateReceived(const char* value);
|
void onConfigUpdateReceived(const char* value);
|
||||||
void onKeypadJsonCommandReceived(const char* value);
|
void onKeypadJsonCommandReceived(const char* value);
|
||||||
void onTimeControlCommandReceived(const char* value);
|
void onTimeControlCommandReceived(const char* value);
|
||||||
void onAuthCommandReceived(const char* value);
|
void onAuthCommandReceived(const char* value);
|
||||||
|
void onGpioActionReceived(const GpioAction& action, const int& pin);
|
||||||
|
|
||||||
void updateKeyTurnerState();
|
void updateKeyTurnerState();
|
||||||
void updateBatteryState();
|
void updateBatteryState();
|
||||||
@@ -93,6 +96,7 @@ private:
|
|||||||
NukiLock::NukiLock _nukiLock;
|
NukiLock::NukiLock _nukiLock;
|
||||||
BleScanner::Scanner* _bleScanner = nullptr;
|
BleScanner::Scanner* _bleScanner = nullptr;
|
||||||
NukiNetworkLock* _network = nullptr;
|
NukiNetworkLock* _network = nullptr;
|
||||||
|
NukiOfficial* _nukiOfficial = nullptr;
|
||||||
Gpio* _gpio = nullptr;
|
Gpio* _gpio = nullptr;
|
||||||
Preferences* _preferences;
|
Preferences* _preferences;
|
||||||
int _intervalLockstate = 0; // seconds
|
int _intervalLockstate = 0; // seconds
|
||||||
@@ -113,13 +117,14 @@ private:
|
|||||||
NukiLock::BatteryReport _batteryReport;
|
NukiLock::BatteryReport _batteryReport;
|
||||||
NukiLock::BatteryReport _lastBatteryReport;
|
NukiLock::BatteryReport _lastBatteryReport;
|
||||||
|
|
||||||
|
NukiLock::LockAction _offCommand = (NukiLock::LockAction)0xff;
|
||||||
|
|
||||||
NukiLock::Config _nukiConfig = {0};
|
NukiLock::Config _nukiConfig = {0};
|
||||||
NukiLock::AdvancedConfig _nukiAdvancedConfig = {0};
|
NukiLock::AdvancedConfig _nukiAdvancedConfig = {0};
|
||||||
bool _nukiConfigValid = false;
|
bool _nukiConfigValid = false;
|
||||||
bool _nukiAdvancedConfigValid = false;
|
bool _nukiAdvancedConfigValid = false;
|
||||||
bool _hassEnabled = false;
|
bool _hassEnabled = false;
|
||||||
bool _hassSetupCompleted = false;
|
bool _hassSetupCompleted = false;
|
||||||
bool _offEnabled = false;
|
|
||||||
bool _disableNonJSON = false;
|
bool _disableNonJSON = false;
|
||||||
bool _paired = false;
|
bool _paired = false;
|
||||||
bool _statusUpdated = false;
|
bool _statusUpdated = false;
|
||||||
@@ -136,7 +141,6 @@ private:
|
|||||||
int64_t _statusUpdatedTs = 0;
|
int64_t _statusUpdatedTs = 0;
|
||||||
int64_t _nextRetryTs = 0;
|
int64_t _nextRetryTs = 0;
|
||||||
int64_t _nextLockStateUpdateTs = 0;
|
int64_t _nextLockStateUpdateTs = 0;
|
||||||
int64_t _nextHybridLockStateUpdateTs = 0;
|
|
||||||
int64_t _nextBatteryReportTs = 0;
|
int64_t _nextBatteryReportTs = 0;
|
||||||
int64_t _nextConfigUpdateTs = 0;
|
int64_t _nextConfigUpdateTs = 0;
|
||||||
int64_t _waitAuthLogUpdateTs = 0;
|
int64_t _waitAuthLogUpdateTs = 0;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@
|
|||||||
#define preference_webserver_enabled (char*)"websrvena"
|
#define preference_webserver_enabled (char*)"websrvena"
|
||||||
#define preference_update_from_mqtt (char*)"updMqtt"
|
#define preference_update_from_mqtt (char*)"updMqtt"
|
||||||
#define preference_disable_non_json (char*)"disnonjson"
|
#define preference_disable_non_json (char*)"disnonjson"
|
||||||
#define preference_official_hybrid (char*)"offHybrid"
|
#define preference_official_hybrid_enabled (char*)"offHybrid"
|
||||||
|
|
||||||
// CHANGE DOES NOT REQUIRE REBOOT TO TAKE EFFECT
|
// CHANGE DOES NOT REQUIRE REBOOT TO TAKE EFFECT
|
||||||
#define preference_find_best_rssi (char*)"nwbestrssi"
|
#define preference_find_best_rssi (char*)"nwbestrssi"
|
||||||
@@ -278,7 +278,7 @@ private:
|
|||||||
preference_keypad_info_enabled, preference_keypad_publish_code, preference_timecontrol_control_enabled, preference_timecontrol_info_enabled, preference_conf_info_enabled,
|
preference_keypad_info_enabled, preference_keypad_publish_code, preference_timecontrol_control_enabled, preference_timecontrol_info_enabled, preference_conf_info_enabled,
|
||||||
preference_register_as_app, preference_register_opener_as_app, preference_command_nr_of_retries, preference_command_retry_delay, preference_cred_user,
|
preference_register_as_app, preference_register_opener_as_app, preference_command_nr_of_retries, preference_command_retry_delay, preference_cred_user,
|
||||||
preference_cred_password, preference_disable_non_json, preference_publish_authdata, preference_publish_debug_info,
|
preference_cred_password, preference_disable_non_json, preference_publish_authdata, preference_publish_debug_info,
|
||||||
preference_official_hybrid, preference_query_interval_hybrid_lockstate, preference_official_hybrid_actions, preference_official_hybrid_retry,
|
preference_official_hybrid_enabled, preference_query_interval_hybrid_lockstate, preference_official_hybrid_actions, preference_official_hybrid_retry,
|
||||||
preference_task_size_network, preference_task_size_nuki, preference_authlog_max_entries, preference_keypad_max_entries, preference_timecontrol_max_entries,
|
preference_task_size_network, preference_task_size_nuki, preference_authlog_max_entries, preference_keypad_max_entries, preference_timecontrol_max_entries,
|
||||||
preference_update_from_mqtt, preference_show_secrets, preference_ble_tx_power, preference_recon_netw_on_mqtt_discon, preference_webserial_enabled,
|
preference_update_from_mqtt, preference_show_secrets, preference_ble_tx_power, preference_recon_netw_on_mqtt_discon, preference_webserial_enabled,
|
||||||
preference_network_custom_mdc, preference_network_custom_clk, preference_network_custom_phy, preference_network_custom_addr, preference_network_custom_irq,
|
preference_network_custom_mdc, preference_network_custom_clk, preference_network_custom_phy, preference_network_custom_addr, preference_network_custom_irq,
|
||||||
@@ -297,7 +297,7 @@ private:
|
|||||||
preference_timecontrol_topic_per_entry, preference_keypad_topic_per_entry, preference_enable_bootloop_reset, preference_webserver_enabled, preference_find_best_rssi,
|
preference_timecontrol_topic_per_entry, preference_keypad_topic_per_entry, preference_enable_bootloop_reset, preference_webserver_enabled, preference_find_best_rssi,
|
||||||
preference_restart_on_disconnect, preference_keypad_control_enabled, preference_keypad_info_enabled, preference_keypad_publish_code, preference_show_secrets,
|
preference_restart_on_disconnect, preference_keypad_control_enabled, preference_keypad_info_enabled, preference_keypad_publish_code, preference_show_secrets,
|
||||||
preference_timecontrol_control_enabled, preference_timecontrol_info_enabled, preference_register_as_app, preference_register_opener_as_app, preference_ip_dhcp_enabled,
|
preference_timecontrol_control_enabled, preference_timecontrol_info_enabled, preference_register_as_app, preference_register_opener_as_app, preference_ip_dhcp_enabled,
|
||||||
preference_publish_authdata, preference_publish_debug_info, preference_network_wifi_fallback_disabled, preference_official_hybrid,
|
preference_publish_authdata, preference_publish_debug_info, preference_network_wifi_fallback_disabled, preference_official_hybrid_enabled,
|
||||||
preference_official_hybrid_actions, preference_official_hybrid_retry, preference_conf_info_enabled, preference_disable_non_json, preference_update_from_mqtt,
|
preference_official_hybrid_actions, preference_official_hybrid_retry, preference_conf_info_enabled, preference_disable_non_json, preference_update_from_mqtt,
|
||||||
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_recon_netw_on_mqtt_discon, preference_webserial_enabled,
|
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_recon_netw_on_mqtt_discon, preference_webserial_enabled,
|
||||||
preference_ntw_reconfigure
|
preference_ntw_reconfigure
|
||||||
|
|||||||
@@ -1254,9 +1254,9 @@ bool WebCfgServer::processArgs(PsychicRequest *request, String& message)
|
|||||||
}
|
}
|
||||||
else if(key == "OFFHYBRID")
|
else if(key == "OFFHYBRID")
|
||||||
{
|
{
|
||||||
if(_preferences->getBool(preference_official_hybrid, false) != (value == "1"))
|
if(_preferences->getBool(preference_official_hybrid_enabled, false) != (value == "1"))
|
||||||
{
|
{
|
||||||
_preferences->putBool(preference_official_hybrid, (value == "1"));
|
_preferences->putBool(preference_official_hybrid_enabled, (value == "1"));
|
||||||
if((value == "1")) _preferences->putBool(preference_register_as_app, true);
|
if((value == "1")) _preferences->putBool(preference_register_as_app, true);
|
||||||
Log->print(F("Setting changed: "));
|
Log->print(F("Setting changed: "));
|
||||||
Log->println(key);
|
Log->println(key);
|
||||||
@@ -2626,7 +2626,7 @@ esp_err_t WebCfgServer::buildHtml(PsychicRequest *request)
|
|||||||
String lockState = pinStateToString(_preferences->getInt(preference_lock_pin_status, 4));
|
String lockState = pinStateToString(_preferences->getInt(preference_lock_pin_status, 4));
|
||||||
printParameter(&response, "Nuki Lock PIN status", lockState.c_str(), "", "lockPin");
|
printParameter(&response, "Nuki Lock PIN status", lockState.c_str(), "", "lockPin");
|
||||||
|
|
||||||
if(_preferences->getBool(preference_official_hybrid, false))
|
if(_preferences->getBool(preference_official_hybrid_enabled, false))
|
||||||
{
|
{
|
||||||
String offConnected = _nuki->offConnected() ? "Yes": "No";
|
String offConnected = _nuki->offConnected() ? "Yes": "No";
|
||||||
printParameter(&response, "Nuki Lock hybrid mode connected", offConnected.c_str(), "", "lockHybrid");
|
printParameter(&response, "Nuki Lock hybrid mode connected", offConnected.c_str(), "", "lockHybrid");
|
||||||
@@ -2811,7 +2811,6 @@ esp_err_t WebCfgServer::buildMqttConfigHtml(PsychicRequest *request)
|
|||||||
// printCheckBox(&response, "HYBRIDRETRY", "Retry command sent using official MQTT over BLE if failed", _preferences->getBool(preference_official_hybrid_retry), ""); // NOT IMPLEMENTED (YET?)
|
// printCheckBox(&response, "HYBRIDRETRY", "Retry command sent using official MQTT over BLE if failed", _preferences->getBool(preference_official_hybrid_retry), ""); // NOT IMPLEMENTED (YET?)
|
||||||
response.print("</table>");
|
response.print("</table>");
|
||||||
response.print("* If no encryption is configured for the MQTT broker, leave empty.<br><br>");
|
response.print("* If no encryption is configured for the MQTT broker, leave empty.<br><br>");
|
||||||
|
|
||||||
response.print("<h3>IP Address assignment</h3>");
|
response.print("<h3>IP Address assignment</h3>");
|
||||||
response.print("<table>");
|
response.print("<table>");
|
||||||
printCheckBox(&response, "DHCPENA", "Enable DHCP", _preferences->getBool(preference_ip_dhcp_enabled), "");
|
printCheckBox(&response, "DHCPENA", "Enable DHCP", _preferences->getBool(preference_ip_dhcp_enabled), "");
|
||||||
|
|||||||
20
src/main.cpp
20
src/main.cpp
@@ -32,6 +32,7 @@ NukiNetworkLock* networkLock = nullptr;
|
|||||||
NukiNetworkOpener* networkOpener = nullptr;
|
NukiNetworkOpener* networkOpener = nullptr;
|
||||||
BleScanner::Scanner* bleScanner = nullptr;
|
BleScanner::Scanner* bleScanner = nullptr;
|
||||||
NukiWrapper* nuki = nullptr;
|
NukiWrapper* nuki = nullptr;
|
||||||
|
NukiOfficial* nukiOfficial = nullptr;
|
||||||
NukiOpenerWrapper* nukiOpener = nullptr;
|
NukiOpenerWrapper* nukiOpener = nullptr;
|
||||||
NukiDeviceId* deviceIdLock = nullptr;
|
NukiDeviceId* deviceIdLock = nullptr;
|
||||||
NukiDeviceId* deviceIdOpener = nullptr;
|
NukiDeviceId* deviceIdOpener = nullptr;
|
||||||
@@ -139,16 +140,21 @@ void networkTask(void *pvParameters)
|
|||||||
|
|
||||||
bool connected = network->update();
|
bool connected = network->update();
|
||||||
|
|
||||||
#ifndef NUKI_HUB_UPDATER
|
#ifndef NUKI_HUB_UPDATER
|
||||||
#ifdef DEBUG_NUKIHUB
|
if(connected && networkLock != nullptr)
|
||||||
|
{
|
||||||
|
networkLock->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_NUKIHUB
|
||||||
if(connected && reroute)
|
if(connected && reroute)
|
||||||
{
|
{
|
||||||
reroute = false;
|
reroute = false;
|
||||||
setReroute();
|
setReroute();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(connected && openerEnabled) networkOpener->update();
|
if(connected && openerEnabled) networkOpener->update();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if((esp_timer_get_time() / 1000) - networkLoopTs > 120000)
|
if((esp_timer_get_time() / 1000) - networkLoopTs > 120000)
|
||||||
{
|
{
|
||||||
@@ -466,10 +472,12 @@ void setup()
|
|||||||
|
|
||||||
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path);
|
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path);
|
||||||
|
|
||||||
|
nukiOfficial = new NukiOfficial(preferences);
|
||||||
|
|
||||||
network = new NukiNetwork(preferences, gpio, mqttLockPath, CharBuffer::get(), buffer_size);
|
network = new NukiNetwork(preferences, gpio, mqttLockPath, CharBuffer::get(), buffer_size);
|
||||||
network->initialize();
|
network->initialize();
|
||||||
|
|
||||||
networkLock = new NukiNetworkLock(network, preferences, CharBuffer::get(), buffer_size);
|
networkLock = new NukiNetworkLock(network, nukiOfficial, preferences, CharBuffer::get(), buffer_size);
|
||||||
networkLock->initialize();
|
networkLock->initialize();
|
||||||
|
|
||||||
if(openerEnabled)
|
if(openerEnabled)
|
||||||
@@ -481,7 +489,7 @@ void setup()
|
|||||||
Log->println(lockEnabled ? F("Nuki Lock enabled") : F("Nuki Lock disabled"));
|
Log->println(lockEnabled ? F("Nuki Lock enabled") : F("Nuki Lock disabled"));
|
||||||
if(lockEnabled)
|
if(lockEnabled)
|
||||||
{
|
{
|
||||||
nuki = new NukiWrapper("NukiHub", deviceIdLock, bleScanner, networkLock, gpio, preferences);
|
nuki = new NukiWrapper("NukiHub", deviceIdLock, bleScanner, networkLock, nukiOfficial, gpio, preferences);
|
||||||
nuki->initialize(firstStart);
|
nuki->initialize(firstStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user