Merge branch 'gpio' of github.com:technyon/nuki_hub into gpio
This commit is contained in:
8
AccessLevel.h
Normal file
8
AccessLevel.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
enum class AccessLevel
|
||||
{
|
||||
Full = 0,
|
||||
LockOnly = 1,
|
||||
ReadOnly = 2
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.0.0)
|
||||
|
||||
set(ARDUINO_BOARD "ESP32 Dev Module [esp32.esp32]")
|
||||
if(NOT ARDUINO_BOARD)
|
||||
set(ARDUINO_BOARD "ESP32 Dev Module [esp32.esp32]")
|
||||
endif()
|
||||
|
||||
project(nuki_hub CXX)
|
||||
|
||||
@@ -40,8 +42,8 @@ include_directories(${PROJECT_NAME}
|
||||
)
|
||||
|
||||
set(SRCFILES
|
||||
Pins.h
|
||||
Config.h
|
||||
NukiDeviceId.cpp
|
||||
CharBuffer.cpp
|
||||
Network.cpp
|
||||
MqttReceiver.h
|
||||
@@ -54,6 +56,8 @@ set(SRCFILES
|
||||
networkDevices/ClientSyncW5500.cpp
|
||||
networkDevices/espMqttClientW5500.cpp
|
||||
networkDevices/IPConfiguration.cpp
|
||||
AccessLevel.h
|
||||
LockActionResult.h
|
||||
QueryCommand.h
|
||||
NukiWrapper.cpp
|
||||
NukiOpenerWrapper.cpp
|
||||
@@ -89,7 +93,7 @@ set(SRCFILES
|
||||
lib/BleScanner/src/BleScanner.cpp
|
||||
lib/MqttLogger/src/MqttLogger.cpp
|
||||
lib/AsyncTCP/src/AsyncTCP.cpp
|
||||
)
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SRCFILESREC
|
||||
lib/NimBLE-Arduino/src/*.c
|
||||
|
||||
2
Config.h
2
Config.h
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#define NUKI_HUB_VERSION "8.22-pre-1"
|
||||
#define NUKI_HUB_VERSION "8.23"
|
||||
|
||||
#define MQTT_QOS_LEVEL 1
|
||||
#define MQTT_CLEAN_SESSIONS false
|
||||
|
||||
5
Gpio.cpp
5
Gpio.cpp
@@ -1,7 +1,6 @@
|
||||
#include <esp32-hal.h>
|
||||
#include "Gpio.h"
|
||||
#include "Arduino.h"
|
||||
#include "Pins.h"
|
||||
#include "Logger.h"
|
||||
#include "PreferencesKeys.h"
|
||||
#include "RestartReason.h"
|
||||
@@ -289,10 +288,6 @@ void Gpio::setPinOutput(const uint8_t& pin, const uint8_t& state)
|
||||
digitalWrite(pin, state);
|
||||
}
|
||||
|
||||
#define TRIGGER_LOCK_PIN 32
|
||||
#define TRIGGER_UNLOCK_PIN 33
|
||||
#define TRIGGER_UNLATCH_PIN 27
|
||||
|
||||
void Gpio::migrateObsoleteSetting()
|
||||
{
|
||||
_pinConfiguration.clear();
|
||||
|
||||
9
LockActionResult.h
Normal file
9
LockActionResult.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
enum class LockActionResult
|
||||
{
|
||||
Success,
|
||||
UnknownAction,
|
||||
AccessDenied,
|
||||
Failed
|
||||
};
|
||||
@@ -20,6 +20,12 @@ Network::Network(Preferences *preferences, Gpio* gpio, const String& maintenance
|
||||
_buffer(buffer),
|
||||
_bufferSize(bufferSize)
|
||||
{
|
||||
// Remove obsolete W5500 hardware detection configuration
|
||||
if(_preferences->getInt(preference_network_hardware_gpio) != 0)
|
||||
{
|
||||
_preferences->remove(preference_network_hardware_gpio);
|
||||
}
|
||||
|
||||
_inst = this;
|
||||
_hostname = _preferences->getString(preference_hostname);
|
||||
|
||||
@@ -739,7 +745,7 @@ void Network::publishHASSConfig(char* deviceType, const char* baseTopic, char* n
|
||||
"reset",
|
||||
uidString,
|
||||
"_reset",
|
||||
"Reset",
|
||||
"Restart NUKI Hub",
|
||||
name,
|
||||
baseTopic,
|
||||
mqtt_topic_reset,
|
||||
|
||||
@@ -102,16 +102,36 @@ void NetworkLock::onMqttDataReceived(const char* topic, byte* payload, const uns
|
||||
|
||||
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 ||
|
||||
strcmp(value, "denied") == 0 ||
|
||||
strcmp(value, "error") == 0) return;
|
||||
|
||||
Log->print(F("Lock action received: "));
|
||||
Log->println(value);
|
||||
bool success = false;
|
||||
LockActionResult lockActionResult = LockActionResult::Failed;
|
||||
if(_lockActionReceivedCallback != NULL)
|
||||
{
|
||||
success = _lockActionReceivedCallback(value);
|
||||
lockActionResult = _lockActionReceivedCallback(value);
|
||||
}
|
||||
|
||||
switch(lockActionResult)
|
||||
{
|
||||
case LockActionResult::Success:
|
||||
publishString(mqtt_topic_lock_action, "ack");
|
||||
break;
|
||||
case LockActionResult::UnknownAction:
|
||||
publishString(mqtt_topic_lock_action, "unknown_action");
|
||||
break;
|
||||
case LockActionResult::AccessDenied:
|
||||
publishString(mqtt_topic_lock_action, "denied");
|
||||
break;
|
||||
case LockActionResult::Failed:
|
||||
publishString(mqtt_topic_lock_action, "error");
|
||||
break;
|
||||
}
|
||||
publishString(mqtt_topic_lock_action, success ? "ack" : "unknown_action");
|
||||
}
|
||||
|
||||
if(comparePrefixedPath(topic, mqtt_topic_keypad_command_action))
|
||||
@@ -458,7 +478,7 @@ void NetworkLock::publishKeypadCommandResult(const char* result)
|
||||
publishString(mqtt_topic_keypad_command_result, result);
|
||||
}
|
||||
|
||||
void NetworkLock::setLockActionReceivedCallback(bool (*lockActionReceivedCallback)(const char *))
|
||||
void NetworkLock::setLockActionReceivedCallback(LockActionResult (*lockActionReceivedCallback)(const char *))
|
||||
{
|
||||
_lockActionReceivedCallback = lockActionReceivedCallback;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "NukiLockConstants.h"
|
||||
#include "Network.h"
|
||||
#include "QueryCommand.h"
|
||||
#include "LockActionResult.h"
|
||||
|
||||
#define LOCK_LOG_JSON_BUFFER_SIZE 2048
|
||||
|
||||
@@ -38,7 +39,7 @@ public:
|
||||
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
|
||||
void publishKeypadCommandResult(const char* result);
|
||||
|
||||
void setLockActionReceivedCallback(bool (*lockActionReceivedCallback)(const char* value));
|
||||
void setLockActionReceivedCallback(LockActionResult (*lockActionReceivedCallback)(const char* value));
|
||||
void setConfigUpdateReceivedCallback(void (*configUpdateReceivedCallback)(const char* path, const char* value));
|
||||
void setKeypadCommandReceivedCallback(void (*keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code, const int& enabled));
|
||||
|
||||
@@ -84,7 +85,7 @@ private:
|
||||
char* _buffer;
|
||||
size_t _bufferSize;
|
||||
|
||||
bool (*_lockActionReceivedCallback)(const char* value) = nullptr;
|
||||
LockActionResult (*_lockActionReceivedCallback)(const char* value) = nullptr;
|
||||
void (*_configUpdateReceivedCallback)(const char* path, const char* value) = nullptr;
|
||||
void (*_keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code, const int& enabled) = nullptr;
|
||||
};
|
||||
|
||||
@@ -93,16 +93,36 @@ void NetworkOpener::onMqttDataReceived(const char* topic, byte* payload, const u
|
||||
|
||||
if(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(value, "") == 0 ||
|
||||
strcmp(value, "--") == 0 ||
|
||||
strcmp(value, "ack") == 0 ||
|
||||
strcmp(value, "unknown_action") == 0 ||
|
||||
strcmp(value, "denied") == 0 ||
|
||||
strcmp(value, "error") == 0) return;
|
||||
|
||||
Log->print(F("Opener lock action received: "));
|
||||
Log->print(F("Lock action received: "));
|
||||
Log->println(value);
|
||||
bool success = false;
|
||||
LockActionResult lockActionResult = LockActionResult::Failed;
|
||||
if(_lockActionReceivedCallback != NULL)
|
||||
{
|
||||
success = _lockActionReceivedCallback(value);
|
||||
lockActionResult = _lockActionReceivedCallback(value);
|
||||
}
|
||||
|
||||
switch(lockActionResult)
|
||||
{
|
||||
case LockActionResult::Success:
|
||||
publishString(mqtt_topic_lock_action, "ack");
|
||||
break;
|
||||
case LockActionResult::UnknownAction:
|
||||
publishString(mqtt_topic_lock_action, "unknown_action");
|
||||
break;
|
||||
case LockActionResult::AccessDenied:
|
||||
publishString(mqtt_topic_lock_action, "denied");
|
||||
break;
|
||||
case LockActionResult::Failed:
|
||||
publishString(mqtt_topic_lock_action, "error");
|
||||
break;
|
||||
}
|
||||
publishString(mqtt_topic_lock_action, success ? "ack" : "unknown_action");
|
||||
}
|
||||
|
||||
if(comparePrefixedPath(topic, mqtt_topic_keypad_command_action))
|
||||
@@ -508,7 +528,7 @@ void NetworkOpener::publishKeypadCommandResult(const char* result)
|
||||
publishString(mqtt_topic_keypad_command_result, result);
|
||||
}
|
||||
|
||||
void NetworkOpener::setLockActionReceivedCallback(bool (*lockActionReceivedCallback)(const char *))
|
||||
void NetworkOpener::setLockActionReceivedCallback(LockActionResult (*lockActionReceivedCallback)(const char *))
|
||||
{
|
||||
_lockActionReceivedCallback = lockActionReceivedCallback;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
|
||||
void publishKeypadCommandResult(const char* result);
|
||||
|
||||
void setLockActionReceivedCallback(bool (*lockActionReceivedCallback)(const char* value));
|
||||
void setLockActionReceivedCallback(LockActionResult (*lockActionReceivedCallback)(const char* value));
|
||||
void setConfigUpdateReceivedCallback(void (*configUpdateReceivedCallback)(const char* path, const char* value));
|
||||
void setKeypadCommandReceivedCallback(void (*keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code, const int& enabled));
|
||||
|
||||
@@ -86,7 +86,7 @@ private:
|
||||
char* _buffer;
|
||||
const size_t _bufferSize;
|
||||
|
||||
bool (*_lockActionReceivedCallback)(const char* value) = nullptr;
|
||||
LockActionResult (*_lockActionReceivedCallback)(const char* value) = nullptr;
|
||||
void (*_configUpdateReceivedCallback)(const char* path, const char* value) = nullptr;
|
||||
void (*_keypadCommandReceivedReceivedCallback)(const char* command, const uint& id, const String& name, const String& code, const int& enabled) = nullptr;
|
||||
};
|
||||
|
||||
44
NukiDeviceId.cpp
Normal file
44
NukiDeviceId.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <cstring>
|
||||
#include <Arduino.h>
|
||||
#include "NukiDeviceId.h"
|
||||
#include "PreferencesKeys.h"
|
||||
|
||||
NukiDeviceId::NukiDeviceId(Preferences* preferences, const std::string& preferencesId)
|
||||
: _preferences(preferences),
|
||||
_preferencesId(preferencesId)
|
||||
{
|
||||
_deviceId = _preferences->getUInt(_preferencesId.c_str());
|
||||
|
||||
if(_deviceId == 0)
|
||||
{
|
||||
assignNewId();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t NukiDeviceId::get()
|
||||
{
|
||||
return _deviceId;
|
||||
}
|
||||
|
||||
void NukiDeviceId::assignId(const uint32_t& id)
|
||||
{
|
||||
_deviceId = id;
|
||||
_preferences->putUInt(_preferencesId.c_str(), id);
|
||||
}
|
||||
|
||||
void NukiDeviceId::assignNewId()
|
||||
{
|
||||
assignId(getRandomId());
|
||||
}
|
||||
|
||||
uint32_t NukiDeviceId::getRandomId()
|
||||
{
|
||||
uint8_t rnd[4];
|
||||
for(int i=0; i<4; i++)
|
||||
{
|
||||
rnd[i] = random(255);
|
||||
}
|
||||
uint32_t deviceId;
|
||||
memcpy(&deviceId, &rnd, sizeof(deviceId));
|
||||
return deviceId;
|
||||
}
|
||||
22
NukiDeviceId.h
Normal file
22
NukiDeviceId.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <Preferences.h>
|
||||
|
||||
class NukiDeviceId
|
||||
{
|
||||
public:
|
||||
NukiDeviceId(Preferences* preferences, const std::string& preferencesId);
|
||||
|
||||
uint32_t get();
|
||||
|
||||
void assignId(const uint32_t& id);
|
||||
void assignNewId();
|
||||
|
||||
private:
|
||||
uint32_t getRandomId();
|
||||
|
||||
Preferences* _preferences;
|
||||
const std::string _preferencesId;
|
||||
uint32_t _deviceId = 0;
|
||||
};
|
||||
@@ -7,15 +7,20 @@
|
||||
#include <NukiOpenerUtils.h>
|
||||
|
||||
NukiOpenerWrapper* nukiOpenerInst;
|
||||
AccessLevel NukiOpenerWrapper::_accessLevel = AccessLevel::ReadOnly;
|
||||
|
||||
NukiOpenerWrapper::NukiOpenerWrapper(const std::string& deviceName, uint32_t id, BleScanner::Scanner* scanner, NetworkOpener* network, Gpio* gpio, Preferences* preferences)
|
||||
NukiOpenerWrapper::NukiOpenerWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NetworkOpener* network, Gpio* gpio, Preferences* preferences)
|
||||
: _deviceName(deviceName),
|
||||
_nukiOpener(deviceName, id),
|
||||
_deviceId(deviceId),
|
||||
_nukiOpener(deviceName, _deviceId->get()),
|
||||
_bleScanner(scanner),
|
||||
_network(network),
|
||||
_gpio(gpio),
|
||||
_preferences(preferences)
|
||||
{
|
||||
Log->print("Device id opener: ");
|
||||
Log->println(_deviceId->get());
|
||||
|
||||
nukiOpenerInst = this;
|
||||
|
||||
memset(&_lastKeyTurnerState, sizeof(NukiLock::KeyTurnerState), 0);
|
||||
@@ -55,6 +60,7 @@ void NukiOpenerWrapper::initialize()
|
||||
_nrOfRetries = _preferences->getInt(preference_command_nr_of_retries);
|
||||
_retryDelay = _preferences->getInt(preference_command_retry_delay);
|
||||
_rssiPublishInterval = _preferences->getInt(preference_rssi_publish_interval) * 1000;
|
||||
_accessLevel = (AccessLevel)_preferences->getInt(preference_access_level);
|
||||
|
||||
if(_retryDelay <= 100)
|
||||
{
|
||||
@@ -298,6 +304,7 @@ void NukiOpenerWrapper::setPin(const uint16_t pin)
|
||||
void NukiOpenerWrapper::unpair()
|
||||
{
|
||||
_nukiOpener.unPairNuki();
|
||||
_deviceId->assignNewId();
|
||||
_paired = false;
|
||||
}
|
||||
|
||||
@@ -465,11 +472,33 @@ NukiOpener::LockAction NukiOpenerWrapper::lockActionToEnum(const char *str)
|
||||
return (NukiOpener::LockAction)0xff;
|
||||
}
|
||||
|
||||
bool NukiOpenerWrapper::onLockActionReceivedCallback(const char *value)
|
||||
LockActionResult NukiOpenerWrapper::onLockActionReceivedCallback(const char *value)
|
||||
{
|
||||
NukiOpener::LockAction action = nukiOpenerInst->lockActionToEnum(value);
|
||||
nukiOpenerInst->_nextLockAction = action;
|
||||
return (int)action != 0xff;
|
||||
if((int)action == 0xff)
|
||||
{
|
||||
return LockActionResult::UnknownAction;
|
||||
}
|
||||
|
||||
switch(_accessLevel)
|
||||
{
|
||||
case AccessLevel::Full:
|
||||
nukiOpenerInst->_nextLockAction = action;
|
||||
return LockActionResult::Success;
|
||||
break;
|
||||
case AccessLevel::LockOnly:
|
||||
if(action == NukiOpener::LockAction::DeactivateRTO || action == NukiOpener::LockAction::DeactivateCM)
|
||||
{
|
||||
nukiOpenerInst->_nextLockAction = action;
|
||||
return LockActionResult::Success;
|
||||
}
|
||||
return LockActionResult::AccessDenied;
|
||||
break;
|
||||
case AccessLevel::ReadOnly:
|
||||
default:
|
||||
return LockActionResult::AccessDenied;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NukiOpenerWrapper::onConfigUpdateReceivedCallback(const char *topic, const char *value)
|
||||
@@ -503,6 +532,8 @@ void NukiOpenerWrapper::gpioActionCallback(const GpioAction &action, const int&
|
||||
|
||||
void NukiOpenerWrapper::onConfigUpdateReceived(const char *topic, const char *value)
|
||||
{
|
||||
if(_accessLevel != AccessLevel::Full) return;
|
||||
|
||||
if(strcmp(topic, mqtt_topic_config_button_enabled) == 0)
|
||||
{
|
||||
bool newValue = atoi(value) > 0;
|
||||
@@ -528,6 +559,8 @@ void NukiOpenerWrapper::onConfigUpdateReceived(const char *topic, const char *va
|
||||
|
||||
void NukiOpenerWrapper::onKeypadCommandReceived(const char *command, const uint &id, const String &name, const String &code, const int& enabled)
|
||||
{
|
||||
if(_accessLevel != AccessLevel::Full) return;
|
||||
|
||||
if(!_hasKeypad)
|
||||
{
|
||||
if(_configRead)
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
#include "NukiDataTypes.h"
|
||||
#include "BleScanner.h"
|
||||
#include "Gpio.h"
|
||||
#include "AccessLevel.h"
|
||||
#include "NukiDeviceId.h"
|
||||
|
||||
class NukiOpenerWrapper : public NukiOpener::SmartlockEventHandler
|
||||
{
|
||||
public:
|
||||
NukiOpenerWrapper(const std::string& deviceName, uint32_t id, BleScanner::Scanner* scanner, NetworkOpener* network, Gpio* gpio, Preferences* preferences);
|
||||
NukiOpenerWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NetworkOpener* network, Gpio* gpio, Preferences* preferences);
|
||||
virtual ~NukiOpenerWrapper();
|
||||
|
||||
void initialize();
|
||||
@@ -43,7 +45,7 @@ public:
|
||||
void notify(NukiOpener::EventType eventType) override;
|
||||
|
||||
private:
|
||||
static bool onLockActionReceivedCallback(const char* value);
|
||||
static LockActionResult onLockActionReceivedCallback(const char* value);
|
||||
static void onConfigUpdateReceivedCallback(const char* topic, const char* value);
|
||||
static void onKeypadCommandReceivedCallback(const char* command, const uint& id, const String& name, const String& code, const int& enabled);
|
||||
static void gpioActionCallback(const GpioAction& action, const int& pin);
|
||||
@@ -69,6 +71,7 @@ private:
|
||||
NukiOpener::LockAction lockActionToEnum(const char* str); // char array at least 14 characters
|
||||
|
||||
std::string _deviceName;
|
||||
NukiDeviceId* _deviceId = nullptr;
|
||||
NukiOpener::NukiOpener _nukiOpener;
|
||||
BleScanner::Scanner* _bleScanner = nullptr;
|
||||
NetworkOpener* _network = nullptr;
|
||||
@@ -85,6 +88,7 @@ private:
|
||||
int _retryDelay = 0;
|
||||
int _retryCount = 0;
|
||||
int _retryLockstateCount = 0;
|
||||
static AccessLevel _accessLevel;
|
||||
unsigned long _nextRetryTs = 0;
|
||||
std::vector<uint16_t> _keypadCodeIds;
|
||||
|
||||
|
||||
@@ -7,15 +7,20 @@
|
||||
#include <NukiLockUtils.h>
|
||||
|
||||
NukiWrapper* nukiInst;
|
||||
AccessLevel NukiWrapper::_accessLevel = AccessLevel::ReadOnly;
|
||||
|
||||
NukiWrapper::NukiWrapper(const std::string& deviceName, uint32_t id, BleScanner::Scanner* scanner, NetworkLock* network, Gpio* gpio, Preferences* preferences)
|
||||
NukiWrapper::NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NetworkLock* network, Gpio* gpio, Preferences* preferences)
|
||||
: _deviceName(deviceName),
|
||||
_deviceId(deviceId),
|
||||
_bleScanner(scanner),
|
||||
_nukiLock(deviceName, id),
|
||||
_nukiLock(deviceName, _deviceId->get()),
|
||||
_network(network),
|
||||
_gpio(gpio),
|
||||
_preferences(preferences)
|
||||
{
|
||||
Log->print("Device id lock: ");
|
||||
Log->println(_deviceId->get());
|
||||
|
||||
nukiInst = this;
|
||||
|
||||
memset(&_lastKeyTurnerState, sizeof(NukiLock::KeyTurnerState), 0);
|
||||
@@ -56,6 +61,7 @@ void NukiWrapper::initialize(const bool& firstStart)
|
||||
_nrOfRetries = _preferences->getInt(preference_command_nr_of_retries);
|
||||
_retryDelay = _preferences->getInt(preference_command_retry_delay);
|
||||
_rssiPublishInterval = _preferences->getInt(preference_rssi_publish_interval) * 1000;
|
||||
_accessLevel = (AccessLevel)_preferences->getInt(preference_access_level);
|
||||
|
||||
if(firstStart)
|
||||
{
|
||||
@@ -115,7 +121,7 @@ void NukiWrapper::update()
|
||||
{
|
||||
if (!_paired)
|
||||
{
|
||||
Log->println(F("Nuki start pairing"));
|
||||
Log->println(F("Nuki lock start pairing"));
|
||||
_network->publishBleAddress("");
|
||||
|
||||
Nuki::AuthorizationIdType idType = _preferences->getBool(preference_register_as_app) ?
|
||||
@@ -284,6 +290,7 @@ void NukiWrapper::setPin(const uint16_t pin)
|
||||
void NukiWrapper::unpair()
|
||||
{
|
||||
_nukiLock.unPairNuki();
|
||||
_deviceId->assignNewId();
|
||||
_paired = false;
|
||||
}
|
||||
|
||||
@@ -433,11 +440,34 @@ NukiLock::LockAction NukiWrapper::lockActionToEnum(const char *str)
|
||||
return (NukiLock::LockAction)0xff;
|
||||
}
|
||||
|
||||
bool NukiWrapper::onLockActionReceivedCallback(const char *value)
|
||||
LockActionResult NukiWrapper::onLockActionReceivedCallback(const char *value)
|
||||
{
|
||||
NukiLock::LockAction action = nukiInst->lockActionToEnum(value);
|
||||
nukiInst->_nextLockAction = action;
|
||||
return (int)action != 0xff;
|
||||
|
||||
if((int)action == 0xff)
|
||||
{
|
||||
return LockActionResult::UnknownAction;
|
||||
}
|
||||
|
||||
switch(_accessLevel)
|
||||
{
|
||||
case AccessLevel::Full:
|
||||
nukiInst->_nextLockAction = action;
|
||||
return LockActionResult::Success;
|
||||
break;
|
||||
case AccessLevel::LockOnly:
|
||||
if(action == NukiLock::LockAction::Lock)
|
||||
{
|
||||
nukiInst->_nextLockAction = action;
|
||||
return LockActionResult::Success;
|
||||
}
|
||||
return LockActionResult::AccessDenied;
|
||||
break;
|
||||
case AccessLevel::ReadOnly:
|
||||
default:
|
||||
return LockActionResult::AccessDenied;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NukiWrapper::onConfigUpdateReceivedCallback(const char *topic, const char *value)
|
||||
@@ -468,6 +498,8 @@ void NukiWrapper::gpioActionCallback(const GpioAction &action, const int& pin)
|
||||
|
||||
void NukiWrapper::onConfigUpdateReceived(const char *topic, const char *value)
|
||||
{
|
||||
if(_accessLevel != AccessLevel::Full) return;
|
||||
|
||||
if(strcmp(topic, mqtt_topic_config_button_enabled) == 0)
|
||||
{
|
||||
bool newValue = atoi(value) > 0;
|
||||
@@ -521,6 +553,8 @@ void NukiWrapper::onConfigUpdateReceived(const char *topic, const char *value)
|
||||
|
||||
void NukiWrapper::onKeypadCommandReceived(const char *command, const uint &id, const String &name, const String &code, const int& enabled)
|
||||
{
|
||||
if(_accessLevel != AccessLevel::Full) return;
|
||||
|
||||
if(!_hasKeypad)
|
||||
{
|
||||
if(_configRead)
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
#include "BleScanner.h"
|
||||
#include "NukiLock.h"
|
||||
#include "Gpio.h"
|
||||
#include "AccessLevel.h"
|
||||
#include "LockActionResult.h"
|
||||
#include "NukiDeviceId.h"
|
||||
|
||||
class NukiWrapper : public Nuki::SmartlockEventHandler
|
||||
{
|
||||
public:
|
||||
NukiWrapper(const std::string& deviceName, uint32_t id, BleScanner::Scanner* scanner, NetworkLock* network, Gpio* gpio, Preferences* preferences);
|
||||
NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NetworkLock* network, Gpio* gpio, Preferences* preferences);
|
||||
virtual ~NukiWrapper();
|
||||
|
||||
void initialize(const bool& firstStart);
|
||||
@@ -40,7 +43,7 @@ public:
|
||||
void notify(Nuki::EventType eventType) override;
|
||||
|
||||
private:
|
||||
static bool onLockActionReceivedCallback(const char* value);
|
||||
static LockActionResult onLockActionReceivedCallback(const char* value);
|
||||
static void onConfigUpdateReceivedCallback(const char* topic, const char* value);
|
||||
static void onKeypadCommandReceivedCallback(const char* command, const uint& id, const String& name, const String& code, const int& enabled);
|
||||
static void gpioActionCallback(const GpioAction& action, const int& pin);
|
||||
@@ -67,6 +70,7 @@ private:
|
||||
NukiLock::LockAction lockActionToEnum(const char* str); // char array at least 14 characters
|
||||
|
||||
std::string _deviceName;
|
||||
NukiDeviceId* _deviceId = nullptr;
|
||||
NukiLock::NukiLock _nukiLock;
|
||||
BleScanner::Scanner* _bleScanner = nullptr;
|
||||
NetworkLock* _network = nullptr;
|
||||
@@ -105,6 +109,7 @@ private:
|
||||
int _retryCount = 0;
|
||||
int _retryLockstateCount = 0;
|
||||
long _rssiPublishInterval = 0;
|
||||
static AccessLevel _accessLevel;
|
||||
unsigned long _nextRetryTs = 0;
|
||||
unsigned long _nextLockStateUpdateTs = 0;
|
||||
unsigned long _nextBatteryReportTs = 0;
|
||||
|
||||
5
Pins.h
5
Pins.h
@@ -1,5 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define TRIGGER_LOCK_PIN 32
|
||||
#define TRIGGER_UNLOCK_PIN 33
|
||||
#define TRIGGER_UNLATCH_PIN 27
|
||||
@@ -3,7 +3,8 @@
|
||||
#include <vector>
|
||||
|
||||
#define preference_started_before "run"
|
||||
#define preference_deviceId "deviceId"
|
||||
#define preference_device_id_lock "deviceId"
|
||||
#define preference_device_id_opener "deviceIdOp"
|
||||
#define preference_mqtt_broker "mqttbroker"
|
||||
#define preference_mqtt_broker_port "mqttport"
|
||||
#define preference_mqtt_user "mqttuser"
|
||||
@@ -25,6 +26,7 @@
|
||||
#define preference_ip_gateway "ipgtw"
|
||||
#define preference_ip_dns_server "dnssrv"
|
||||
#define preference_network_hardware "nwhw"
|
||||
#define preference_network_hardware_gpio "nwhwdt" // obsolete
|
||||
#define preference_rssi_publish_interval "rssipb"
|
||||
#define preference_hostname "hostname"
|
||||
#define preference_network_timeout "nettmout"
|
||||
@@ -36,13 +38,14 @@
|
||||
#define preference_query_interval_battery "batInterval"
|
||||
#define preference_query_interval_keypad "kpInterval"
|
||||
#define preference_keypad_control_enabled "kpEnabled"
|
||||
#define preference_access_level "accLvl"
|
||||
#define preference_register_as_app "regAsApp" // true = register as hub; false = register as app
|
||||
#define preference_command_nr_of_retries "nrRetry"
|
||||
#define preference_command_retry_delay "rtryDelay"
|
||||
#define preference_cred_user "crdusr"
|
||||
#define preference_cred_password "crdpass"
|
||||
#define preference_publish_authdata "pubauth"
|
||||
#define preference_gpio_locking_enabled "gpiolck"
|
||||
#define preference_gpio_locking_enabled "gpiolck" // obsolete
|
||||
#define preference_gpio_configuration "gpiocfg"
|
||||
#define preference_publish_debug_info "pubdbg"
|
||||
#define preference_presence_detection_timeout "prdtimeout"
|
||||
@@ -56,7 +59,7 @@ class DebugPreferences
|
||||
private:
|
||||
std::vector<char*> _keys =
|
||||
{
|
||||
preference_started_before, preference_deviceId, preference_mqtt_broker, preference_mqtt_broker_port,
|
||||
preference_started_before, preference_device_id_lock, preference_device_id_opener, preference_mqtt_broker, preference_mqtt_broker_port,
|
||||
preference_mqtt_user, preference_mqtt_password, preference_mqtt_log_enabled, preference_lock_enabled,
|
||||
preference_mqtt_lock_path, preference_opener_enabled, preference_mqtt_opener_path,
|
||||
preference_lock_max_keypad_code_count, preference_opener_max_keypad_code_count, preference_mqtt_ca,
|
||||
@@ -64,9 +67,10 @@ private:
|
||||
preference_ip_dhcp_enabled, preference_ip_address, preference_ip_subnet, preference_ip_gateway, preference_ip_dns_server,
|
||||
preference_network_hardware, preference_rssi_publish_interval,
|
||||
preference_hostname, preference_network_timeout, preference_restart_on_disconnect,
|
||||
preference_restart_timer, preference_restart_ble_beacon_lost, preference_query_interval_lockstate,
|
||||
preference_restart_ble_beacon_lost, preference_query_interval_lockstate,
|
||||
preference_query_interval_configuration, preference_query_interval_battery, preference_query_interval_keypad,
|
||||
preference_keypad_control_enabled, preference_register_as_app, preference_command_nr_of_retries,
|
||||
preference_keypad_control_enabled, preference_access_level,
|
||||
preference_register_as_app, preference_command_nr_of_retries,
|
||||
preference_command_retry_delay, preference_cred_user, preference_cred_password, preference_publish_authdata,
|
||||
preference_publish_debug_info, preference_presence_detection_timeout,
|
||||
preference_has_mac_saved, preference_has_mac_byte_0, preference_has_mac_byte_1, preference_has_mac_byte_2,
|
||||
|
||||
53
README.md
53
README.md
@@ -10,7 +10,7 @@ Supported devices:<br>
|
||||
NUKI Smart Lock 1.0<br>
|
||||
NUKI Smart Lock 2.0<br>
|
||||
NUKI Smart Lock 3.0<br>
|
||||
NUKI Smart Lock 3.0 Pro<br>
|
||||
NUKI Smart Lock 3.0 Pro (read FAQ below)<br>
|
||||
NUKI Opener<br>
|
||||
NUKI Keypad 1.0<br>
|
||||
NUKI Keypad 2.0
|
||||
@@ -23,6 +23,9 @@ As an alternative to Wifi, the following ESP32 modules with wired ethernet are s
|
||||
[M5Stack PoESP32 Unit](https://docs.m5stack.com/en/unit/poesp32)<br>
|
||||
[LilyGO-T-ETH-POE](https://github.com/Xinyuan-LilyGO/LilyGO-T-ETH-POE)<br>
|
||||
|
||||
<br>
|
||||
<b>Note for users upgrading from 8.21 or lower:</b> Please go to "MQTT and Network Configuration" and select
|
||||
"Wifi only" as the network device (unless you use other network hardware).
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -53,8 +56,8 @@ Note: It is possible to run NUKI Hub alongside a NUKI Bridge. This is not recomm
|
||||
## Support
|
||||
|
||||
If you haven't ordered your NUKI product yet, you can support me by using my referrer code when placing your order:<br>
|
||||
REFXQ847A4ZDG<br>
|
||||
This will also give you a 30€ discount for your order.
|
||||
REFW628ZPQW3R<br>
|
||||
This will also give you a 10% discount on your order.
|
||||
|
||||
This project is free to use for everyone. However if you feel like donating, you can buy me a coffee at ko-fi.com:
|
||||
|
||||
@@ -176,14 +179,27 @@ For example, to add a code:
|
||||
|
||||
## GPIO lock control (optional)
|
||||
|
||||
The lock can be controlled via GPIO. For security reasons, this has to be enabled in
|
||||
the configuration portal (check "Enable control via GPIO" in the NUKI configuration
|
||||
section). The Pins use pullup configuration, so they have to be connected to ground to
|
||||
trigger the action.<br><br>
|
||||
The Pin configuration is:<br>
|
||||
32: Lock<br>
|
||||
33: Unlock<br>
|
||||
27: Unlatch
|
||||
The lock can be controlled via GPIO. To enable GPIO control, go the the "GPIO Configuration" page where each GPIO
|
||||
can be configured for a specific role:
|
||||
|
||||
- Disabled: The GPIO is disabled
|
||||
- Input: Lock: When connect to Ground, a lock command is sent to the lock
|
||||
- Input: Unlock: When connect to Ground, an unlock command is sent to the lock
|
||||
- Input: Unlatch: When connect to Ground, an unlatch command is sent to the lock
|
||||
- Input: Electric strike actuation: When connect to Ground, an electric strike actuation command is sent to the opener (open door for configured amount of time)
|
||||
- Input: Activate RTO: When connect to Ground, Ring-to-open is activated (opener)
|
||||
- Input: Activate CM: When connect to Ground, Continuous mode is activated (opener)
|
||||
- Input: Deactivate RTO/CM: Disable RTO or CM, depending on which is active
|
||||
- Output: High when locked: Outputs a high signal when the door is locked
|
||||
- Output: High when unlocked: Outputs a high signal when the door is unlocked
|
||||
- Output: High when motor blocked: Outputs a high signal when the motor is blocked (lock)
|
||||
- Output: High when RTO active: Outputs a high signal when ring-to-open is active (opener)
|
||||
- Output: High when CM active: Outputs a high signal when continuous mode is active (opener)
|
||||
- Output: High when RTO or CM active: Outputs a high signal when either ring-to-open or continuous mode is active (opener)
|
||||
|
||||
Note: The old setting "Enable control via GPIO" is removed. If you had enabled this setting before upgrading to 8.22, the PINs are automatically configured to be
|
||||
compatible with the previously hard-coded PINs.
|
||||
|
||||
|
||||
## Connecting via LAN (Optional)
|
||||
|
||||
@@ -219,12 +235,14 @@ If this still doesn't fix the disconnects and the ESP becomes unreachable, the
|
||||
after a configured amount of time.
|
||||
|
||||
### Pairing with the Lock (or Opener) doesn't work
|
||||
First, try erasing the flash and then (re-)flash the firmware. To erase the flash, use the espressif download tool and click the "Erase" button.
|
||||
First, make sure the firmware version of the NUKI device is up-to-date, older versions have issues pairing<br>
|
||||
Next, try erasing the flash and then (re-)flash the firmware. To erase the flash, use the espressif download tool and click the "Erase" button.
|
||||
Afterwards flash the firmware as described in the readme within the 7z file.
|
||||
<br><br>
|
||||
Also, there are reports that ESP32 "DEVKIT1" module don't work and pairing is not possible. The reason is unknown, but if you use such a module, try a different one.
|
||||
<br><br>
|
||||
Reported as working are:<br>
|
||||
[M5Stack ATOM Lite](https://shop.m5stack.com/products/atom-lite-esp32-development-kit)<br>
|
||||
ESP32-WROOM-32D (DEVKIT V4)<br>
|
||||
ESP32-WROOM-32E<br>
|
||||
<br>
|
||||
@@ -235,6 +253,11 @@ Also, check that pairing is allowed. In the smartphone app, go to Settings --> F
|
||||
|
||||
## FAQ
|
||||
|
||||
### NUKI Hub doesn't work when the Wifi on my NUKI Smartlock Pro 3.0 is turned on.
|
||||
|
||||
This is by design and according to NUKI part of the specification of the Pro lock: You can user either the built-in Wifi or a Bridge (whic NUKI Hub registers as).
|
||||
Using both at the same time doesn't work.
|
||||
|
||||
### Certain functionality doesn't work (e. g. changing configuration, setting keypad codes)
|
||||
Some functionality is restricted by the lock (or opener) firmware and is only accessible when
|
||||
the PIN is provided. When setting up the lock (or opener), you have to set a PIN in the smartphone.
|
||||
@@ -246,13 +269,17 @@ See previous point, this needs the correct PIN to be configured.
|
||||
### Using home assistant, it's only possible to lock or unlock the door, but not to unlatch it
|
||||
Unlatching can be triggered using the lock.open service.
|
||||
|
||||
### When controlling two locks (or openers) connected to two ESPs, both devices react to the same command. When using Home Asistant, the same status is display for both locks.
|
||||
|
||||
When using multiple NUKI devices, different paths for each device have to be configured. Navigate to "NUKI Configuration" and change the "MQTT NUKI Smartlock Path"
|
||||
or "MQTT NUKI Opener Path" under "Basic NUKI Configuration" for at least one of the devices.
|
||||
|
||||
## Development VM
|
||||
|
||||
Since setting up the toolchain can be difficult, I've uploaded a virtual machine (vmware image) that is
|
||||
setup to compile NUKI Hub:
|
||||
|
||||
https://mega.nz/file/8uRkDKyS#F0FNVJZTsUdcTMhiJIB47Fm-7YqKuyQs15E5zznmroc
|
||||
https://drive.google.com/file/d/1fUVYHDtxXAZOAfQ321iRNIwkqFwuDsBp/view?usp=share_link
|
||||
|
||||
User and password for the VM are both "nuki" and "nuki". The source is checked out at ~/projects/nuki_hub,
|
||||
the cmake build directory is build. So to compile, run the following commands:
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Logger.h"
|
||||
#include "Config.h"
|
||||
#include "RestartReason.h"
|
||||
#include "AccessLevel.h"
|
||||
#include <esp_task_wdt.h>
|
||||
|
||||
WebCfgServer::WebCfgServer(NukiWrapper* nuki, NukiOpenerWrapper* nukiOpener, Network* network, Gpio* gpio, EthServer* ethServer, Preferences* preferences, bool allowRestartToPortal)
|
||||
@@ -361,11 +362,6 @@ bool WebCfgServer::processArgs(String& message)
|
||||
_preferences->putBool(preference_restart_on_disconnect, (value == "1"));
|
||||
configChanged = true;
|
||||
}
|
||||
else if(key == "RSTTMR")
|
||||
{
|
||||
_preferences->putInt(preference_restart_timer, value.toInt());
|
||||
configChanged = true;
|
||||
}
|
||||
else if(key == "MQTTLOG")
|
||||
{
|
||||
_preferences->putBool(preference_mqtt_log_enabled, (value == "1"));
|
||||
@@ -411,6 +407,11 @@ bool WebCfgServer::processArgs(String& message)
|
||||
_preferences->putInt(preference_query_interval_battery, value.toInt());
|
||||
configChanged = true;
|
||||
}
|
||||
else if(key == "ACCLVL")
|
||||
{
|
||||
_preferences->putInt(preference_access_level, value.toInt());
|
||||
configChanged = true;
|
||||
}
|
||||
else if(key == "KPINT")
|
||||
{
|
||||
_preferences->putInt(preference_query_interval_keypad, value.toInt());
|
||||
@@ -761,7 +762,6 @@ void WebCfgServer::buildMqttConfigHtml(String &response)
|
||||
printInputField(response, "RSSI", "RSSI Publish interval (seconds; -1 to disable)", _preferences->getInt(preference_rssi_publish_interval), 6);
|
||||
printInputField(response, "NETTIMEOUT", "Network Timeout until restart (seconds; -1 to disable)", _preferences->getInt(preference_network_timeout), 5);
|
||||
printCheckBox(response, "RSTDISC", "Restart on disconnect", _preferences->getBool(preference_restart_on_disconnect));
|
||||
printInputField(response, "RSTTMR", "Restart timer (minutes; -1 to disable)", _preferences->getInt(preference_restart_timer), 10);
|
||||
printCheckBox(response, "MQTTLOG", "Enable MQTT logging", _preferences->getBool(preference_mqtt_log_enabled));
|
||||
response.concat("</table>");
|
||||
response.concat("* If no encryption is configured for the MQTT broker, leave empty. Only supported for WiFi connections.<br><br>");
|
||||
@@ -803,10 +803,11 @@ void WebCfgServer::buildNukiConfigHtml(String &response)
|
||||
response.concat("<h3>Advanced NUKI Configuration</h3>");
|
||||
response.concat("<table>");
|
||||
|
||||
printCheckBox(response, "REGAPP", "Register as app (on: register as app, off: register as bridge; needs re-pairing if changed)", _preferences->getBool(preference_register_as_app));
|
||||
printInputField(response, "LSTINT", "Query interval lock state (seconds)", _preferences->getInt(preference_query_interval_lockstate), 10);
|
||||
printInputField(response, "CFGINT", "Query interval configuration (seconds)", _preferences->getInt(preference_query_interval_configuration), 10);
|
||||
printInputField(response, "BATINT", "Query interval battery (seconds)", _preferences->getInt(preference_query_interval_battery), 10);
|
||||
printDropDown(response, "ACCLVL", "Access level", String(_preferences->getInt(preference_access_level)), getAccessLevelOptions());
|
||||
|
||||
if((_nuki != nullptr && _nuki->hasKeypad()) || (_nukiOpener != nullptr && _nukiOpener->hasKeypad()))
|
||||
{
|
||||
printInputField(response, "KPINT", "Query interval keypad (seconds)", _preferences->getInt(preference_query_interval_keypad), 10);
|
||||
@@ -815,6 +816,7 @@ void WebCfgServer::buildNukiConfigHtml(String &response)
|
||||
printInputField(response, "NRTRY", "Number of retries if command failed", _preferences->getInt(preference_command_nr_of_retries), 10);
|
||||
printInputField(response, "TRYDLY", "Delay between retries (milliseconds)", _preferences->getInt(preference_command_retry_delay), 10);
|
||||
printCheckBox(response, "PUBAUTH", "Publish auth data (May reduce battery life)", _preferences->getBool(preference_publish_authdata));
|
||||
printCheckBox(response, "REGAPP", "Register as app (on: register as app, off: register as bridge; needs re-pairing if changed)", _preferences->getBool(preference_register_as_app));
|
||||
printInputField(response, "PRDTMO", "Presence detection timeout (seconds; -1 to disable)", _preferences->getInt(preference_presence_detection_timeout), 10);
|
||||
printInputField(response, "RSBC", "Restart if bluetooth beacons not received (seconds; -1 to disable)", _preferences->getInt(preference_restart_ble_beacon_lost), 10);
|
||||
response.concat("</table>");
|
||||
@@ -998,6 +1000,8 @@ void WebCfgServer::buildHtmlHeader(String &response)
|
||||
// response.concat("</style>");
|
||||
response.concat("<link rel='stylesheet' href='/style.css'>");
|
||||
response.concat("<TITLE>NUKI Hub</TITLE></HEAD><BODY>");
|
||||
|
||||
srand(millis());
|
||||
}
|
||||
|
||||
void WebCfgServer::printInputField(String& response,
|
||||
@@ -1295,6 +1299,17 @@ const std::vector<std::pair<String, String>> WebCfgServer::getGpioOptions() cons
|
||||
return options;
|
||||
}
|
||||
|
||||
const std::vector<std::pair<String, String>> WebCfgServer::getAccessLevelOptions() const
|
||||
{
|
||||
std::vector<std::pair<String, String>> options;
|
||||
|
||||
options.push_back(std::make_pair(std::to_string((int)AccessLevel::Full).c_str(), "Full"));
|
||||
options.push_back(std::make_pair(std::to_string((int)AccessLevel::LockOnly).c_str(), "Lock operation only"));
|
||||
options.push_back(std::make_pair(std::to_string((int)AccessLevel::ReadOnly).c_str(), "Read only"));
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
String WebCfgServer::getPreselectionForGpio(const uint8_t &pin)
|
||||
{
|
||||
const std::vector<PinEntry>& pinConfiguration = _gpio->pinConfiguration();
|
||||
|
||||
@@ -60,6 +60,7 @@ private:
|
||||
|
||||
const std::vector<std::pair<String, String>> getNetworkDetectionOptions() const;
|
||||
const std::vector<std::pair<String, String>> getGpioOptions() const;
|
||||
const std::vector<std::pair<String, String>> getAccessLevelOptions() const;
|
||||
String getPreselectionForGpio(const uint8_t& pin);
|
||||
|
||||
void printParameter(String& response, const char* description, const char* value, const char *link = "");
|
||||
|
||||
58
main.cpp
58
main.cpp
@@ -1,5 +1,4 @@
|
||||
#include "Arduino.h"
|
||||
#include "Pins.h"
|
||||
#include "NukiWrapper.h"
|
||||
#include "NetworkLock.h"
|
||||
#include "WebCfgServer.h"
|
||||
@@ -14,6 +13,7 @@
|
||||
#include "Config.h"
|
||||
#include "RestartReason.h"
|
||||
#include "CharBuffer.h"
|
||||
#include "NukiDeviceId.h"
|
||||
|
||||
Network* network = nullptr;
|
||||
NetworkLock* networkLock = nullptr;
|
||||
@@ -23,6 +23,8 @@ BleScanner::Scanner* bleScanner = nullptr;
|
||||
NukiWrapper* nuki = nullptr;
|
||||
NukiOpenerWrapper* nukiOpener = nullptr;
|
||||
PresenceDetection* presenceDetection = nullptr;
|
||||
NukiDeviceId* deviceIdLock = nullptr;
|
||||
NukiDeviceId* deviceIdOpener = nullptr;
|
||||
Preferences* preferences = nullptr;
|
||||
EthServer* ethServer = nullptr;
|
||||
Gpio* gpio = nullptr;
|
||||
@@ -113,18 +115,6 @@ void setupTasks()
|
||||
xTaskCreatePinnedToCore(presenceDetectionTask, "prdet", 896, NULL, 5, &presenceDetectionTaskHandle, 1);
|
||||
}
|
||||
|
||||
uint32_t getRandomId()
|
||||
{
|
||||
uint8_t rnd[4];
|
||||
for(int i=0; i<4; i++)
|
||||
{
|
||||
rnd[i] = random(255);
|
||||
}
|
||||
uint32_t deviceId;
|
||||
memcpy(&deviceId, &rnd, sizeof(deviceId));
|
||||
return deviceId;
|
||||
}
|
||||
|
||||
void initEthServer(const NetworkDeviceType device)
|
||||
{
|
||||
switch (device)
|
||||
@@ -154,11 +144,6 @@ bool initPreferences()
|
||||
preferences->putBool(preference_lock_enabled, true);
|
||||
}
|
||||
|
||||
if(preferences->getInt(preference_restart_timer) == 0)
|
||||
{
|
||||
preferences->putInt(preference_restart_timer, -1);
|
||||
}
|
||||
|
||||
return firstStart;
|
||||
}
|
||||
|
||||
@@ -173,11 +158,22 @@ void setup()
|
||||
|
||||
initializeRestartReason();
|
||||
|
||||
|
||||
uint32_t devIdOpener = preferences->getUInt(preference_device_id_opener);
|
||||
|
||||
deviceIdLock = new NukiDeviceId(preferences, preference_device_id_lock);
|
||||
deviceIdOpener = new NukiDeviceId(preferences, preference_device_id_opener);
|
||||
|
||||
if(deviceIdLock->get() != 0 && devIdOpener == 0)
|
||||
{
|
||||
deviceIdOpener->assignId(deviceIdLock->get());
|
||||
}
|
||||
|
||||
CharBuffer::initialize();
|
||||
|
||||
if(preferences->getInt(preference_restart_timer) > 0)
|
||||
if(preferences->getInt(preference_restart_timer) != 0)
|
||||
{
|
||||
restartTs = preferences->getInt(preference_restart_timer) * 60 * 1000;
|
||||
preferences->remove(preference_restart_timer);
|
||||
}
|
||||
|
||||
gpio = new Gpio(preferences);
|
||||
@@ -201,13 +197,6 @@ void setup()
|
||||
networkOpener->initialize();
|
||||
}
|
||||
|
||||
uint32_t deviceId = preferences->getUInt(preference_deviceId);
|
||||
if(deviceId == 0)
|
||||
{
|
||||
deviceId = getRandomId();
|
||||
preferences->putUInt(preference_deviceId, deviceId);
|
||||
}
|
||||
|
||||
initEthServer(network->networkDeviceType());
|
||||
|
||||
bleScanner = new BleScanner::Scanner();
|
||||
@@ -217,21 +206,14 @@ void setup()
|
||||
Log->println(lockEnabled ? F("NUKI Lock enabled") : F("NUKI Lock disabled"));
|
||||
if(lockEnabled)
|
||||
{
|
||||
nuki = new NukiWrapper("NukiHub", deviceId, bleScanner, networkLock, gpio, preferences);
|
||||
nuki = new NukiWrapper("NukiHub", deviceIdLock, bleScanner, networkLock, gpio, preferences);
|
||||
nuki->initialize(firstStart);
|
||||
|
||||
|
||||
|
||||
// if(preferences->getBool(preference_gpio_locking_enabled))
|
||||
// {
|
||||
// Gpio::init(nuki);
|
||||
// }
|
||||
}
|
||||
|
||||
Log->println(openerEnabled ? F("NUKI Opener enabled") : F("NUKI Opener disabled"));
|
||||
if(openerEnabled)
|
||||
{
|
||||
nukiOpener = new NukiOpenerWrapper("NukiHub", deviceId, bleScanner, networkOpener, gpio, preferences);
|
||||
nukiOpener = new NukiOpenerWrapper("NukiHub", deviceIdOpener, bleScanner, networkOpener, gpio, preferences);
|
||||
nukiOpener->initialize();
|
||||
}
|
||||
|
||||
@@ -245,4 +227,6 @@ void setup()
|
||||
}
|
||||
|
||||
void loop()
|
||||
{}
|
||||
{
|
||||
delay(60000);
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <Arduino.h>
|
||||
#include <WiFi.h>
|
||||
#include "W5500Device.h"
|
||||
#include "../Pins.h"
|
||||
#include "../PreferencesKeys.h"
|
||||
#include "../Logger.h"
|
||||
#include "../MqttTopics.h"
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user