Merge remote-tracking branch 'upstream/master' into esp-nimble-nuki-ble-update

This commit is contained in:
iranl
2024-11-11 19:24:34 +01:00
30 changed files with 3497 additions and 3475 deletions

View File

@@ -4,7 +4,7 @@
#define NUKI_HUB_VERSION "9.02"
#define NUKI_HUB_BUILD "unknownbuildnr"
#define NUKI_HUB_DATE "2024-11-06"
#define NUKI_HUB_DATE "2024-11-08"
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"
@@ -22,6 +22,7 @@
#define GITHUB_BETA_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/beta/nuki_hub_updater_esp32c3.bin"
#define GITHUB_MASTER_RELEASE_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_esp32c3.bin"
#define GITHUB_MASTER_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_updater_esp32c3.bin"
#define NUKI_HUB_HW (char*)"ESP32-C3"
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
#if defined(CONFIG_SPIRAM_MODE_OCT)
#define GITHUB_LATEST_RELEASE_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_esp32s3oct.bin"
@@ -36,6 +37,7 @@
#define GITHUB_BETA_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/beta/nuki_hub_updater_esp32s3oct.bin"
#define GITHUB_MASTER_RELEASE_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_esp32s3oct.bin"
#define GITHUB_MASTER_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_updater_esp32s3oct.bin"
#define NUKI_HUB_HW (char*)"ESP32-S3 (Octal PSRAM)"
#else
#define GITHUB_LATEST_RELEASE_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_esp32s3.bin"
#define GITHUB_LATEST_UPDATER_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_updater_esp32s3.bin"
@@ -49,6 +51,7 @@
#define GITHUB_BETA_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/beta/nuki_hub_updater_esp32s3.bin"
#define GITHUB_MASTER_RELEASE_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_esp32s3.bin"
#define GITHUB_MASTER_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_updater_esp32s3.bin"
#define NUKI_HUB_HW (char*)"ESP32-S3"
#endif
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
#define GITHUB_LATEST_RELEASE_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_esp32c6.bin"
@@ -63,6 +66,7 @@
#define GITHUB_BETA_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/beta/nuki_hub_updater_esp32c6.bin"
#define GITHUB_MASTER_RELEASE_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_esp32c6.bin"
#define GITHUB_MASTER_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_updater_esp32c6.bin"
#define NUKI_HUB_HW (char*)"ESP32-C6"
#elif defined(CONFIG_IDF_TARGET_ESP32H2)
#define GITHUB_LATEST_RELEASE_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_esp32h2.bin"
#define GITHUB_LATEST_UPDATER_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_updater_esp32h2.bin"
@@ -76,6 +80,7 @@
#define GITHUB_BETA_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/beta/nuki_hub_updater_esp32h2.bin"
#define GITHUB_MASTER_RELEASE_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_esp32h2.bin"
#define GITHUB_MASTER_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_updater_esp32h2.bin"
#define NUKI_HUB_HW (char*)"ESP32-H2"
#else
#if defined(CONFIG_FREERTOS_UNICORE)
#define GITHUB_LATEST_RELEASE_BINARY_URL "https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_esp32-solo1.bin"
@@ -90,6 +95,7 @@
#define GITHUB_BETA_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/beta/nuki_hub_updater_esp32-solo1.bin"
#define GITHUB_MASTER_RELEASE_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_esp32-solo1.bin"
#define GITHUB_MASTER_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_updater_esp32-solo1.bin"
#define NUKI_HUB_HW (char*)"ESP32-SOLO1"
#else
#define GITHUB_LATEST_RELEASE_BINARY_URL "https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_esp32.bin"
#define GITHUB_LATEST_UPDATER_BINARY_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/nuki_hub_updater_esp32.bin"
@@ -103,6 +109,7 @@
#define GITHUB_BETA_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/beta/nuki_hub_updater_esp32.bin"
#define GITHUB_MASTER_RELEASE_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_esp32.bin"
#define GITHUB_MASTER_UPDATER_BINARY_URL_DBG (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/debug/master/nuki_hub_updater_esp32.bin"
#define NUKI_HUB_HW (char*)"ESP32"
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
#pragma once
#include <Preferences.h>
#include <ArduinoJson.h>
#include "networkDevices/NetworkDevice.h"
class HomeAssistantDiscovery
{
public:
explicit HomeAssistantDiscovery(NetworkDevice* device, Preferences* preferences, char* buffer, size_t bufferSize);
void setupHASS(int type, uint32_t nukiId, char* nukiName, const char* firmwareVersion, const char* hardwareVersion, bool hasDoorSensor, bool hasKeypad);
void disableHASS();
void removeHassTopic(const String& mqttDeviceType, const String& mqttDeviceName, const String& uidString);
void publishHassTopic(const String& mqttDeviceType,
const String& mqttDeviceName,
const String& uidString,
const String& uidStringPostfix,
const String& displayName,
const String& name,
const String& baseTopic,
const String& stateTopic,
const String& deviceType,
const String& deviceClass,
const String& stateClass = "",
const String& entityCat = "",
const String& commandTopic = "",
std::vector<std::pair<char*, char*>> additionalEntries = {}
);
private:
void publishHASSConfig(char *deviceType, const char *baseTopic, char *name, char *uidString, const char *softwareVersion, const char *hardwareVersion, const bool& hasDoorSensor, const bool& hasKeypad, const bool& publishAuthData, char *lockAction, char *unlockAction, char *openAction);
void publishHASSDeviceConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const char *softwareVersion, const char *hardwareVersion, const char* availabilityTopic, const bool& hasKeypad, char* lockAction, char* unlockAction, char* openAction);
void publishHASSNukiHubConfig();
void publishHASSConfigAdditionalLockEntities(char* deviceType, const char* baseTopic, char* name, char* uidString);
void publishHASSConfigDoorSensor(char* deviceType, const char* baseTopic, char* name, char* uidString);
void publishHASSConfigAdditionalOpenerEntities(char* deviceType, const char* baseTopic, char* name, char* uidString);
void publishHASSConfigAccessLog(char* deviceType, const char* baseTopic, char* name, char* uidString);
void publishHASSConfigKeypad(char* deviceType, const char* baseTopic, char* name, char* uidString);
void publishHASSConfigWifiRssi(char* deviceType, const char* baseTopic, char* name, char* uidString);
void removeHASSConfig(char* uidString);
void removeHASSConfigTopic(char* deviceType, char* name, char* uidString);
String createHassTopicPath(const String& mqttDeviceType, const String& mqttDeviceName, const String& uidString);
JsonDocument createHassJson(const String& uidString,
const String& uidStringPostfix,
const String& displayName,
const String& name,
const String& baseTopic,
const String& stateTopic,
const String& deviceType,
const String& deviceClass,
const String& stateClass = "",
const String& entityCat = "",
const String& commandTopic = "",
std::vector<std::pair<char*, char*>> additionalEntries = {}
);
NetworkDevice* _device = nullptr;
Preferences* _preferences = nullptr;
String _discoveryTopic;
String _baseTopic;
String _hostname;
char _nukiHubUidString[20];
bool _offEnabled = false;
bool _checkUpdates = false;
bool _updateFromMQTT = false;
char* _buffer;
const size_t _bufferSize;
};

View File

@@ -1,7 +1,5 @@
#pragma once
#include <Arduino.h>
class MqttReceiver
{
public:

View File

@@ -110,7 +110,7 @@
#define mqtt_topic_restart_reason_esp "/maintenance/restartReasonNukiEsp"
#define mqtt_topic_mqtt_connection_state "/maintenance/mqttConnectionState"
#define mqtt_topic_network_device "/maintenance/networkDevice"
#define mqtt_hybrid_state "/hybridConnected"
#define mqtt_topic_hybrid_state "/hybridConnected"
#define mqtt_topic_gpio_prefix "/gpio"
#define mqtt_topic_gpio_pin "/pin_"

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,7 @@
#include "Gpio.h"
#include <ArduinoJson.h>
#include "NukiConstants.h"
#include "HomeAssistantDiscovery.h"
#endif
class NukiNetwork
@@ -56,37 +57,31 @@ public:
void publishLongLong(const char* prefix, const char* topic, int64_t value, bool retain);
void publishBool(const char* prefix, const char* topic, const bool value, bool retain);
void publishString(const char* prefix, const char* topic, const char* value, bool retain);
void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const char *softwareVersion, const char *hardwareVersion, const char* availabilityTopic, const bool& hasKeypad, char* lockAction, char* unlockAction, char* openAction);
void publishHASSConfigAdditionalLockEntities(char* deviceType, const char* baseTopic, char* name, char* uidString);
void publishHASSConfigDoorSensor(char* deviceType, const char* baseTopic, char* name, char* uidString);
void publishHASSConfigAdditionalOpenerEntities(char* deviceType, const char* baseTopic, char* name, char* uidString);
void publishHASSConfigAccessLog(char* deviceType, const char* baseTopic, char* name, char* uidString);
void publishHASSConfigKeypad(char* deviceType, const char* baseTopic, char* name, char* uidString);
void publishHASSWifiRssiConfig(char* deviceType, const char* baseTopic, char* name, char* uidString);
void removeHASSConfig(char* uidString);
void removeHASSConfigTopic(char* deviceType, char* name, char* uidString);
void publishHassTopic(const String& mqttDeviceType,
const String& mqttDeviceName,
const String& uidString,
const String& uidStringPostfix,
const String& displayName,
const String& name,
const String& baseTopic,
const String& stateTopic,
const String& deviceType,
const String& deviceClass,
const String& stateClass = "",
const String& entityCat = "",
const String& commandTopic = "",
std::vector<std::pair<char*, char*>> additionalEntries = {}
);
void removeHassTopic(const String& mqttDeviceType, const String& mqttDeviceName, const String& uidString);
void publish(const char *topic, const char *value, bool retain);
void removeTopic(const String& mqttPath, const String& mqttTopic);
void batteryTypeToString(const Nuki::BatteryType battype, char* str);
void advertisingModeToString(const Nuki::AdvertisingMode advmode, char* str);
void timeZoneIdToString(const Nuki::TimeZoneId timeZoneId, char* str);
void setupHASS(int type, uint32_t nukiId, char* nukiName, const char* firmwareVersion, const char* hardwareVersion, bool hasDoorSensor, bool hasKeypad);
void disableHASS();
void publishHassTopic(const String& mqttDeviceType,
const String& mqttDeviceName,
const String& uidString,
const String& uidStringPostfix,
const String& displayName,
const String& name,
const String& baseTopic,
const String& stateTopic,
const String& deviceType,
const String& deviceClass,
const String& stateClass,
const String& entityCat,
const String& commandTopic,
std::vector<std::pair<char*, char*>> additionalEntries
);
void removeHassTopic(const String& mqttDeviceType, const String& mqttDeviceName, const String& uidString);
int mqttConnectionState(); // 0 = not connected; 1 = connected; 2 = connected and mqtt processed
bool mqttRecentlyConnected();
bool pathEquals(const char* prefix, const char* path, const char* referencePath);
@@ -113,8 +108,6 @@ private:
NetworkDeviceType _networkDeviceType = (NetworkDeviceType)-1;
bool _firstBootAfterDeviceChange = false;
bool _webEnabled = true;
bool _updateFromMQTT = false;
bool _offEnabled = false;
#ifndef NUKI_HUB_UPDATER
static void onMqttDataReceivedCallback(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total);
@@ -125,30 +118,16 @@ private:
void parseGpioTopics(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t& len, size_t& index, size_t& total);
void gpioActionCallback(const GpioAction& action, const int& pin);
bool comparePrefixedPath(const char* fullPath, const char* subPath);
String createHassTopicPath(const String& mqttDeviceType, const String& mqttDeviceName, const String& uidString);
JsonDocument createHassJson(const String& uidString,
const String& uidStringPostfix,
const String& displayName,
const String& name,
const String& baseTopic,
const String& stateTopic,
const String& deviceType,
const String& deviceClass,
const String& stateClass = "",
const String& entityCat = "",
const String& commandTopic = "",
std::vector<std::pair<char*, char*>> additionalEntries = {}
);
void buildMqttPath(char* outPath, std::initializer_list<const char*> paths);
void buildMqttPath(const char *path, char *outPath);
void buildMqttPath(char* outPath, std::initializer_list<const char*> paths);
const char* _lastWillPayload = "offline";
char _mqttConnectionStateTopic[211] = {0};
String _lockPath;
String _discoveryTopic;
String _brokerAddr;
HomeAssistantDiscovery* _hadiscovery = nullptr;
Gpio* _gpio;
int _mqttConnectionState = 0;

View File

@@ -1516,53 +1516,6 @@ bool NukiNetworkLock::comparePrefixedPath(const char *fullPath, const char *subP
return strcmp(fullPath, prefixedPath) == 0;
}
void NukiNetworkLock::publishHASSConfig(char *deviceType, const char *baseTopic, char *name, char *uidString, const char *softwareVersion, const char *hardwareVersion, const bool& hasDoorSensor, const bool& hasKeypad, const bool& publishAuthData, char *lockAction,
char *unlockAction, char *openAction)
{
String availabilityTopic = _preferences->getString(preference_mqtt_lock_path);
availabilityTopic.concat("/maintenance/mqttConnectionState");
_network->publishHASSConfig(deviceType, baseTopic, name, uidString, softwareVersion, hardwareVersion, availabilityTopic.c_str(), hasKeypad, lockAction, unlockAction, openAction);
_network->publishHASSConfigAdditionalLockEntities(deviceType, baseTopic, name, uidString);
if(hasDoorSensor)
{
_network->publishHASSConfigDoorSensor(deviceType, baseTopic, name, uidString);
}
else
{
_network->removeHASSConfigTopic((char*)"binary_sensor", (char*)"door_sensor", uidString);
}
#ifndef CONFIG_IDF_TARGET_ESP32H2
_network->publishHASSWifiRssiConfig(deviceType, baseTopic, name, uidString);
#endif
if(publishAuthData)
{
_network->publishHASSConfigAccessLog(deviceType, baseTopic, name, uidString);
}
else
{
_network->removeHASSConfigTopic((char*)"sensor", (char*)"last_action_authorization", uidString);
_network->removeHASSConfigTopic((char*)"sensor", (char*)"rolling_log", uidString);
}
if(hasKeypad)
{
_network->publishHASSConfigKeypad(deviceType, baseTopic, name, uidString);
}
else
{
_network->removeHASSConfigTopic((char*)"sensor", (char*)"keypad_status", uidString);
_network->removeHASSConfigTopic((char*)"binary_sensor", (char*)"keypad_battery_low", uidString);
}
}
void NukiNetworkLock::removeHASSConfig(char *uidString)
{
_network->removeHASSConfig(uidString);
}
void NukiNetworkLock::publishOffAction(const int value)
{
_network->publishInt(_nukiOfficial->getMqttPath(), mqtt_topic_official_lock_action, value, false);
@@ -1645,6 +1598,11 @@ uint8_t NukiNetworkLock::queryCommands()
return qc;
}
void NukiNetworkLock::setupHASS(int type, uint32_t nukiId, char* nukiName, const char* firmwareVersion, const char* hardwareVersion, bool hasDoorSensor, bool hasKeypad)
{
_network->setupHASS(type, nukiId, nukiName, firmwareVersion, hardwareVersion, hasDoorSensor, hasKeypad);
}
void NukiNetworkLock::buttonPressActionToString(const NukiLock::ButtonPressAction btnPressAction, char* str)
{
switch (btnPressAction)

View File

@@ -37,8 +37,6 @@ public:
void publishRssi(const int& rssi);
void publishRetry(const std::string& message);
void publishBleAddress(const std::string& address);
void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const char *softwareVersion, const char *hardwareVersion, const bool& hasDoorSensor, const bool& hasKeypad, const bool& publishAuthData, char* lockAction, char* unlockAction, char* openAction);
void removeHASSConfig(char* uidString);
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
void publishTimeControl(const std::list<NukiLock::TimeControlEntry>& timeControlEntries, uint maxTimeControlEntryCount);
void publishAuth(const std::list<NukiLock::AuthorizationEntry>& authEntries, uint maxAuthEntryCount);
@@ -58,6 +56,7 @@ public:
void setTimeControlCommandReceivedCallback(void (*timeControlCommandReceivedReceivedCallback)(const char* value));
void setAuthCommandReceivedCallback(void (*authCommandReceivedReceivedCallback)(const char* value));
void onMqttDataReceived(const char* topic, byte* payload, const unsigned int length) override;
void setupHASS(int type, uint32_t nukiId, char* nukiName, const char* firmwareVersion, const char* hardwareVersion, bool hasDoorSensor, bool hasKeypad);
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);

View File

@@ -859,38 +859,6 @@ void NukiNetworkOpener::publishBleAddress(const std::string &address)
publishString(mqtt_topic_lock_address, address, true);
}
void NukiNetworkOpener::publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const char *softwareVersion, const char *hardwareVersion, const bool& publishAuthData, const bool& hasKeypad, char* lockAction, char* unlockAction, char* openAction)
{
String availabilityTopic = _preferences->getString(preference_mqtt_lock_path);
availabilityTopic.concat("/maintenance/mqttConnectionState");
_network->publishHASSConfig(deviceType, baseTopic, name, uidString, softwareVersion, hardwareVersion, availabilityTopic.c_str(), hasKeypad, lockAction, unlockAction, openAction);
_network->publishHASSConfigAdditionalOpenerEntities(deviceType, baseTopic, name, uidString);
if(publishAuthData)
{
_network->publishHASSConfigAccessLog(deviceType, baseTopic, name, uidString);
}
else
{
_network->removeHASSConfigTopic((char*)"sensor", (char*)"last_action_authorization", uidString);
_network->removeHASSConfigTopic((char*)"sensor", (char*)"rolling_log", uidString);
}
if(hasKeypad)
{
_network->publishHASSConfigKeypad(deviceType, baseTopic, name, uidString);
}
else
{
_network->removeHASSConfigTopic((char*)"sensor", (char*)"keypad_status", uidString);
_network->removeHASSConfigTopic((char*)"binary_sensor", (char*)"keypad_battery_low", uidString);
}
}
void NukiNetworkOpener::removeHASSConfig(char* uidString)
{
_network->removeHASSConfig(uidString);
}
void NukiNetworkOpener::publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount)
{
bool publishCode = _preferences->getBool(preference_keypad_publish_code, false);
@@ -1588,6 +1556,11 @@ uint8_t NukiNetworkOpener::queryCommands()
return qc;
}
void NukiNetworkOpener::setupHASS(int type, uint32_t nukiId, char* nukiName, const char* firmwareVersion, const char* hardwareVersion, bool hasDoorSensor, bool hasKeypad)
{
_network->setupHASS(type, nukiId, nukiName, firmwareVersion, hardwareVersion, hasDoorSensor, hasKeypad);
}
void NukiNetworkOpener::buttonPressActionToString(const NukiOpener::ButtonPressAction btnPressAction, char* str)
{
switch (btnPressAction)

View File

@@ -30,8 +30,6 @@ public:
void publishRssi(const int& rssi);
void publishRetry(const std::string& message);
void publishBleAddress(const std::string& address);
void publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const char *softwareVersion, const char *hardwareVersion, const bool& publishAuthData, const bool& hasKeypad, char* lockAction, char* unlockAction, char* openAction);
void removeHASSConfig(char* uidString);
void publishKeypad(const std::list<NukiLock::KeypadEntry>& entries, uint maxKeypadCodeCount);
void publishTimeControl(const std::list<NukiOpener::TimeControlEntry>& timeControlEntries, uint maxTimeControlEntryCount);
void publishAuth(const std::list<NukiLock::AuthorizationEntry>& authEntries, uint maxAuthEntryCount);
@@ -49,6 +47,7 @@ public:
void setTimeControlCommandReceivedCallback(void (*timeControlCommandReceivedReceivedCallback)(const char* value));
void setAuthCommandReceivedCallback(void (*authCommandReceivedReceivedCallback)(const char* value));
void onMqttDataReceived(const char* topic, byte* payload, const unsigned int length) override;
void setupHASS(int type, uint32_t nukiId, char* nukiName, const char* firmwareVersion, const char* hardwareVersion, bool hasDoorSensor, bool hasKeypad);
int mqttConnectionState();
bool reconnected(); //SETBACK

View File

@@ -13,7 +13,6 @@ NukiOfficial::NukiOfficial(Preferences *preferences)
_disableNonJSON = preferences->getBool(preference_disable_non_json, false);
}
void NukiOfficial::setUid(const uint32_t& uid)
{
char uidString[20];
@@ -43,7 +42,6 @@ void NukiOfficial::setPublisher(NukiPublisher *publisher)
_publisher = publisher;
}
const char *NukiOfficial::getMqttPath() const
{
return mqttPath;
@@ -88,7 +86,7 @@ void NukiOfficial::onOfficialUpdateReceived(const char *topic, const char *value
bool publishBatteryJson = false;
memset(&str, 0, sizeof(str));
Log->println("Official Nuki change recieved");
Log->println("Official Nuki change received");
Log->print(F("Topic: "));
Log->println(topic);
Log->print(F("Value: "));
@@ -99,14 +97,14 @@ void NukiOfficial::onOfficialUpdateReceived(const char *topic, const char *value
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);
_publisher->publishBool(mqtt_topic_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);
_publisher->publishBool(mqtt_topic_hybrid_state, offConnected, true);
NukiLock::lockstateToString((NukiLock::LockState)offState, str);
_publisher->publishString(mqtt_topic_lock_state, str, true);

View File

@@ -54,7 +54,7 @@ void NukiOpenerWrapper::initialize()
_nukiOpener.setConnectTimeout(3);
_nukiOpener.setDisconnectTimeout(5000);
_hassEnabled = _preferences->getString(preference_mqtt_hass_discovery) != "";
_hassEnabled = _preferences->getBool(preference_mqtt_hass_enabled, false);
readSettings();
}
@@ -313,7 +313,8 @@ void NukiOpenerWrapper::update()
}
if(_hassEnabled && _nukiConfigValid && _nukiAdvancedConfigValid && !_hassSetupCompleted)
{
setupHASS();
_network->setupHASS(2, _nukiConfig.nukiId, (char*)_nukiConfig.name, _firmwareVersion.c_str(), _hardwareVersion.c_str(), false, _hasKeypad);
_hassSetupCompleted = true;
}
if(_rssiPublishInterval > 0 && (_nextRssiTs == 0 || ts > _nextRssiTs))
{
@@ -610,13 +611,13 @@ void NukiOpenerWrapper::updateConfig()
}
else
{
Log->println(F("Invalid/Unexpected opener config recieved, ID does not matched saved ID"));
Log->println(F("Invalid/Unexpected opener config received, ID does not matched saved ID"));
expectedConfig = false;
}
}
else
{
Log->println(F("Invalid/Unexpected opener config recieved, Config is not valid"));
Log->println(F("Invalid/Unexpected opener config received, Config is not valid"));
expectedConfig = false;
}
@@ -633,7 +634,7 @@ void NukiOpenerWrapper::updateConfig()
}
else
{
Log->println(F("Invalid/Unexpected opener advanced config recieved, Advanced config is not valid"));
Log->println(F("Invalid/Unexpected opener advanced config received, Advanced config is not valid"));
expectedConfig = false;
}
}
@@ -646,7 +647,7 @@ void NukiOpenerWrapper::updateConfig()
else
{
++_retryConfigCount;
Log->println(F("Invalid/Unexpected opener config and/or advanced config recieved, retrying in 10 seconds"));
Log->println(F("Invalid/Unexpected opener config and/or advanced config received, retrying in 10 seconds"));
int64_t ts = espMillis();
_nextConfigUpdateTs = ts + 10000;
}
@@ -3957,43 +3958,6 @@ void NukiOpenerWrapper::readAdvancedConfig()
postponeBleWatchdog();
}
void NukiOpenerWrapper::setupHASS()
{
if(!_nukiConfigValid)
{
return;
}
if(_preferences->getUInt(preference_nuki_id_opener, 0) != _nukiConfig.nukiId)
{
return;
}
String baseTopic = _preferences->getString(preference_mqtt_lock_path);
baseTopic.concat("/opener");
char uidString[20];
itoa(_nukiConfig.nukiId, uidString, 16);
if(_preferences->getBool(preference_opener_continuous_mode, false))
{
_network->publishHASSConfig((char*)"Opener", baseTopic.c_str(), (char*)_nukiConfig.name, uidString, _firmwareVersion.c_str(), _hardwareVersion.c_str(), _publishAuthData, _hasKeypad, (char*)"deactivateCM", (char*)"activateCM", (char*)"electricStrikeActuation");
}
else
{
_network->publishHASSConfig((char*)"Opener", baseTopic.c_str(), (char*)_nukiConfig.name, uidString, _firmwareVersion.c_str(), _hardwareVersion.c_str(), _publishAuthData, _hasKeypad, (char*)"deactivateRTO", (char*)"activateRTO", (char*)"electricStrikeActuation");
}
_hassSetupCompleted = true;
Log->println("HASS setup for opener completed.");
}
void NukiOpenerWrapper::disableHASS()
{
char uidString[20];
itoa(_preferences->getUInt(preference_nuki_id_opener, 0), uidString, 16);
_network->removeHASSConfig(uidString);
}
void NukiOpenerWrapper::printCommandResult(Nuki::CmdResult result)
{
char resultStr[15];

View File

@@ -31,9 +31,6 @@ public:
uint16_t getPin();
void unpair();
void disableHASS();
void disableWatchdog();
const NukiOpener::OpenerState& keyTurnerState();
@@ -77,8 +74,6 @@ private:
void readConfig();
void readAdvancedConfig();
void setupHASS();
void printCommandResult(Nuki::CmdResult result);
NukiOpener::LockAction lockActionToEnum(const char* str); // char array at least 14 characters

View File

@@ -1,6 +1,3 @@
#ifndef CONFIG_IDF_TARGET_ESP32H2
#include "esp_wifi.h"
#endif
#include "NukiWrapper.h"
#include "PreferencesKeys.h"
#include "MqttTopics.h"
@@ -50,7 +47,7 @@ NukiWrapper::~NukiWrapper()
}
void NukiWrapper::initialize(const bool& firstStart)
void NukiWrapper::initialize()
{
_nukiLock.initialize();
_nukiLock.registerBleScanner(_bleScanner);
@@ -58,75 +55,7 @@ void NukiWrapper::initialize(const bool& firstStart)
_nukiLock.setConnectTimeout(3);
_nukiLock.setDisconnectTimeout(5000);
if(firstStart)
{
Log->println("First start, setting preference defaults");
#ifndef CONFIG_IDF_TARGET_ESP32H2
wifi_config_t wifi_cfg;
if(esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK)
{
Log->println("Failed to get Wi-Fi configuration in RAM");
}
if (esp_wifi_set_storage(WIFI_STORAGE_FLASH) != ESP_OK)
{
Log->println("Failed to set storage Wi-Fi");
}
memset(wifi_cfg.sta.ssid, 0, sizeof(wifi_cfg.sta.ssid));
memset(wifi_cfg.sta.password, 0, sizeof(wifi_cfg.sta.password));
if (esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK)
{
Log->println("Failed to clear NVS Wi-Fi configuration");
}
#endif
_preferences->putString(preference_mqtt_lock_path, "nukihub");
_preferences->putBool(preference_check_updates, true);
_preferences->putBool(preference_opener_continuous_mode, false);
_preferences->putBool(preference_official_hybrid_enabled, false);
_preferences->putBool(preference_official_hybrid_actions, false);
_preferences->putBool(preference_official_hybrid_retry, false);
_preferences->putBool(preference_disable_non_json, false);
_preferences->putBool(preference_update_from_mqtt, false);
_preferences->putBool(preference_ip_dhcp_enabled, true);
_preferences->putBool(preference_enable_bootloop_reset, false);
_preferences->putBool(preference_show_secrets, false);
_preferences->putBool(preference_conf_info_enabled, true);
_preferences->putBool(preference_keypad_info_enabled, false);
_preferences->putBool(preference_keypad_topic_per_entry, false);
_preferences->putBool(preference_keypad_publish_code, false);
_preferences->putBool(preference_keypad_control_enabled, false);
_preferences->putBool(preference_timecontrol_info_enabled, false);
_preferences->putBool(preference_timecontrol_topic_per_entry, false);
_preferences->putBool(preference_timecontrol_control_enabled, false);
_preferences->putBool(preference_publish_authdata, false);
_preferences->putBool(preference_register_as_app, false);
_preferences->putBool(preference_register_opener_as_app, false);
_preferences->putInt(preference_mqtt_broker_port, 1883);
_preferences->putInt(preference_buffer_size, CHAR_BUFFER_SIZE);
_preferences->putInt(preference_task_size_network, NETWORK_TASK_SIZE);
_preferences->putInt(preference_task_size_nuki, NUKI_TASK_SIZE);
_preferences->putInt(preference_authlog_max_entries, MAX_AUTHLOG);
_preferences->putInt(preference_keypad_max_entries, MAX_KEYPAD);
_preferences->putInt(preference_timecontrol_max_entries, MAX_TIMECONTROL);
_preferences->putInt(preference_query_interval_hybrid_lockstate, 600);
_preferences->putInt(preference_rssi_publish_interval, 60);
_preferences->putInt(preference_network_timeout, 60);
_preferences->putInt(preference_command_nr_of_retries, 3);
_preferences->putInt(preference_command_retry_delay, 100);
_preferences->putInt(preference_restart_ble_beacon_lost, 60);
_preferences->putInt(preference_query_interval_lockstate, 1800);
_preferences->putInt(preference_query_interval_configuration, 3600);
_preferences->putInt(preference_query_interval_battery, 1800);
_preferences->putInt(preference_query_interval_keypad, 1800);
}
_hassEnabled = _preferences->getString(preference_mqtt_hass_discovery) != "";
_hassEnabled = _preferences->getBool(preference_mqtt_hass_enabled, false);
readSettings();
}
@@ -405,7 +334,8 @@ void NukiWrapper::update()
}
if(_hassEnabled && _nukiConfigValid && _nukiAdvancedConfigValid && !_hassSetupCompleted)
{
setupHASS();
_network->setupHASS(1, _nukiConfig.nukiId, (char*)_nukiConfig.name, _firmwareVersion.c_str(), _hardwareVersion.c_str(), hasDoorSensor(), _hasKeypad);
_hassSetupCompleted = true;
}
if(_rssiPublishInterval > 0 && (_nextRssiTs == 0 || ts > _nextRssiTs))
{
@@ -693,13 +623,13 @@ void NukiWrapper::updateConfig()
}
else
{
Log->println(F("Invalid/Unexpected lock config recieved, ID does not matched saved ID"));
Log->println(F("Invalid/Unexpected lock config received, ID does not matched saved ID"));
expectedConfig = false;
}
}
else
{
Log->println(F("Invalid/Unexpected lock config recieved, Config is not valid"));
Log->println(F("Invalid/Unexpected lock config received, Config is not valid"));
expectedConfig = false;
}
@@ -716,7 +646,7 @@ void NukiWrapper::updateConfig()
}
else
{
Log->println(F("Invalid/Unexpected lock advanced config recieved, Advanced config is not valid"));
Log->println(F("Invalid/Unexpected lock advanced config received, Advanced config is not valid"));
expectedConfig = false;
}
}
@@ -729,7 +659,7 @@ void NukiWrapper::updateConfig()
else
{
++_retryConfigCount;
Log->println(F("Invalid/Unexpected lock config and/or advanced config recieved, retrying in 10 seconds"));
Log->println(F("Invalid/Unexpected lock config and/or advanced config received, retrying in 10 seconds"));
int64_t ts = espMillis();
_nextConfigUpdateTs = ts + 10000;
}
@@ -4074,28 +4004,6 @@ void NukiWrapper::readAdvancedConfig()
}
}
void NukiWrapper::setupHASS()
{
if(!_nukiConfigValid)
{
return;
}
if(_preferences->getUInt(preference_nuki_id_lock, 0) != _nukiConfig.nukiId)
{
return;
}
String baseTopic = _preferences->getString(preference_mqtt_lock_path);
baseTopic.concat("/lock");
char uidString[20];
itoa(_nukiConfig.nukiId, uidString, 16);
_network->publishHASSConfig((char*)"SmartLock", baseTopic.c_str(),(char*)_nukiConfig.name, uidString, _firmwareVersion.c_str(), _hardwareVersion.c_str(), hasDoorSensor(), _hasKeypad, _publishAuthData, (char*)"lock", (char*)"unlock", (char*)"unlatch");
_hassSetupCompleted = true;
Log->println("HASS setup for lock completed.");
}
bool NukiWrapper::hasDoorSensor() const
{
return _keyTurnerState.doorSensorState == Nuki::DoorSensorState::DoorClosed ||
@@ -4103,13 +4011,6 @@ bool NukiWrapper::hasDoorSensor() const
_keyTurnerState.doorSensorState == Nuki::DoorSensorState::Calibrating;
}
void NukiWrapper::disableHASS()
{
char uidString[20];
itoa(_preferences->getUInt(preference_nuki_id_lock, 0), uidString, 16);
_network->removeHASSConfig(uidString);
}
const BLEAddress NukiWrapper::getBleAddress() const
{
return _nukiLock.getBleAddress();

View File

@@ -17,7 +17,7 @@ public:
NukiWrapper(const std::string& deviceName, NukiDeviceId* deviceId, BleScanner::Scanner* scanner, NukiNetworkLock* network, NukiOfficial* nukiOfficial, Gpio* gpio, Preferences* preferences);
virtual ~NukiWrapper();
void initialize(const bool& firstStart);
void initialize();
void readSettings();
void update();
@@ -33,8 +33,6 @@ public:
uint16_t getPin();
void unpair();
void disableHASS();
void disableWatchdog();
const NukiLock::KeyTurnerState& keyTurnerState();
@@ -81,8 +79,6 @@ private:
void readConfig();
void readAdvancedConfig();
void setupHASS();
void printCommandResult(Nuki::CmdResult result);
NukiLock::LockAction lockActionToEnum(const char* str); // char array at least 14 characters

View File

@@ -2,6 +2,9 @@
#include <vector>
#include "Config.h"
#ifndef CONFIG_IDF_TARGET_ESP32H2
#include "esp_wifi.h"
#endif
//CHANGE REQUIRES REBOOT TO TAKE EFFECT
#define preference_ip_dhcp_enabled (char*)"dhcpena"
@@ -48,6 +51,7 @@
#define preference_gpio_configuration (char*)"gpiocfg"
#define preference_mqtt_hass_enabled (char*)"hassena"
#define preference_mqtt_hass_discovery (char*)"hassdiscovery"
#define preference_hass_device_discovery (char*)"hassdevdisc"
#define preference_webserver_enabled (char*)"websrvena"
#define preference_update_from_mqtt (char*)"updMqtt"
#define preference_disable_non_json (char*)"disnonjson"
@@ -128,17 +132,17 @@
#define preference_presence_detection_timeout (char*)"prdtimeout"
#define preference_network_wifi_fallback_disabled (char*)"nwwififb"
inline bool initPreferences(Preferences* preferences)
inline void initPreferences(Preferences* preferences)
{
#ifdef NUKI_HUB_UPDATER
bool firstStart = false;
return firstStart;
return;
#else
bool firstStart = !preferences->getBool(preference_started_before);
#endif
if(firstStart)
{
Serial.println("First start, setting preference defaults");
preferences->putBool(preference_started_before, true);
preferences->putBool(preference_lock_enabled, true);
uint32_t aclPrefs[17] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
@@ -151,6 +155,69 @@ inline bool initPreferences(Preferences* preferences)
preferences->putBytes(preference_conf_lock_advanced_acl, (byte*)(&advancedLockConfigAclPrefs), sizeof(advancedLockConfigAclPrefs));
uint32_t advancedOpenerConfigAclPrefs[20] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
preferences->putBytes(preference_conf_opener_advanced_acl, (byte*)(&advancedOpenerConfigAclPrefs), sizeof(advancedOpenerConfigAclPrefs));
#ifndef CONFIG_IDF_TARGET_ESP32H2
wifi_config_t wifi_cfg;
if(esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK)
{
Serial.println("Failed to get Wi-Fi configuration in RAM");
}
if (esp_wifi_set_storage(WIFI_STORAGE_FLASH) != ESP_OK)
{
Serial.println("Failed to set storage Wi-Fi");
}
memset(wifi_cfg.sta.ssid, 0, sizeof(wifi_cfg.sta.ssid));
memset(wifi_cfg.sta.password, 0, sizeof(wifi_cfg.sta.password));
if (esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK)
{
Serial.println("Failed to clear NVS Wi-Fi configuration");
}
#endif
preferences->putString(preference_mqtt_lock_path, "nukihub");
preferences->putBool(preference_check_updates, true);
preferences->putBool(preference_opener_continuous_mode, false);
preferences->putBool(preference_official_hybrid_enabled, false);
preferences->putBool(preference_official_hybrid_actions, false);
preferences->putBool(preference_official_hybrid_retry, false);
preferences->putBool(preference_disable_non_json, false);
preferences->putBool(preference_update_from_mqtt, false);
preferences->putBool(preference_ip_dhcp_enabled, true);
preferences->putBool(preference_enable_bootloop_reset, false);
preferences->putBool(preference_show_secrets, false);
preferences->putBool(preference_conf_info_enabled, true);
preferences->putBool(preference_keypad_info_enabled, false);
preferences->putBool(preference_keypad_topic_per_entry, false);
preferences->putBool(preference_keypad_publish_code, false);
preferences->putBool(preference_keypad_control_enabled, false);
preferences->putBool(preference_timecontrol_info_enabled, false);
preferences->putBool(preference_timecontrol_topic_per_entry, false);
preferences->putBool(preference_timecontrol_control_enabled, false);
preferences->putBool(preference_publish_authdata, false);
preferences->putBool(preference_register_as_app, false);
preferences->putBool(preference_register_opener_as_app, false);
preferences->putInt(preference_mqtt_broker_port, 1883);
preferences->putInt(preference_buffer_size, CHAR_BUFFER_SIZE);
preferences->putInt(preference_task_size_network, NETWORK_TASK_SIZE);
preferences->putInt(preference_task_size_nuki, NUKI_TASK_SIZE);
preferences->putInt(preference_authlog_max_entries, MAX_AUTHLOG);
preferences->putInt(preference_keypad_max_entries, MAX_KEYPAD);
preferences->putInt(preference_timecontrol_max_entries, MAX_TIMECONTROL);
preferences->putInt(preference_query_interval_hybrid_lockstate, 600);
preferences->putInt(preference_rssi_publish_interval, 60);
preferences->putInt(preference_network_timeout, 60);
preferences->putInt(preference_command_nr_of_retries, 3);
preferences->putInt(preference_command_retry_delay, 100);
preferences->putInt(preference_restart_ble_beacon_lost, 60);
preferences->putInt(preference_query_interval_lockstate, 1800);
preferences->putInt(preference_query_interval_configuration, 3600);
preferences->putInt(preference_query_interval_battery, 1800);
preferences->putInt(preference_query_interval_keypad, 1800);
}
else
{
@@ -265,8 +332,7 @@ inline bool initPreferences(Preferences* preferences)
preferences->putInt(preference_config_version, atof(NUKI_HUB_VERSION) * 100);
}
}
return firstStart;
#endif
}
class DebugPreferences
@@ -294,7 +360,7 @@ private:
preference_network_custom_rst, preference_network_custom_cs, preference_network_custom_sck, preference_network_custom_miso, preference_network_custom_mosi,
preference_network_custom_pwr, preference_network_custom_mdio, preference_ntw_reconfigure, preference_lock_max_auth_entry_count, preference_opener_max_auth_entry_count,
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_auth_max_entries, preference_wifi_ssid, preference_wifi_pass,
preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_mqtt_hass_enabled
preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_mqtt_hass_enabled, preference_hass_device_discovery
};
std::vector<char*> _redact =
{
@@ -309,7 +375,7 @@ private:
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_official_hybrid_enabled, preference_mqtt_hass_enabled,
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_webserial_enabled,
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_webserial_enabled, preference_hass_device_discovery,
preference_ntw_reconfigure, preference_keypad_check_code_enabled, preference_disable_network_not_connected
};
std::vector<char*> _bytePrefs =

View File

@@ -1740,21 +1740,22 @@ bool WebCfgServer::processArgs(PsychicRequest *request, String& message)
//configChanged = true;
}
}
else if(key == "HADEVDISC")
{
if(_preferences->getBool(preference_hass_device_discovery, false) != (value == "1"))
{
_network->disableHASS();
_preferences->putBool(preference_hass_device_discovery, (value == "1"));
Log->print(F("Setting changed: "));
Log->println(key);
configChanged = true;
}
}
else if(key == "ENHADISC")
{
if(_preferences->getBool(preference_mqtt_hass_enabled, false) != (value == "1"))
{
if(!_preferences->getBool(preference_mqtt_hass_enabled, false))
{
if (_nuki != nullptr)
{
_nuki->disableHASS();
}
if (_nukiOpener != nullptr)
{
_nukiOpener->disableHASS();
}
}
_network->disableHASS();
_preferences->putBool(preference_mqtt_hass_enabled, (value == "1"));
Log->print(F("Setting changed: "));
Log->println(key);
@@ -1765,14 +1766,7 @@ bool WebCfgServer::processArgs(PsychicRequest *request, String& message)
{
if(_preferences->getString(preference_mqtt_hass_discovery, "") != value)
{
if (_nuki != nullptr)
{
_nuki->disableHASS();
}
if (_nukiOpener != nullptr)
{
_nukiOpener->disableHASS();
}
_network->disableHASS();
_preferences->putString(preference_mqtt_hass_discovery, value);
Log->print(F("Setting changed: "));
Log->println(key);
@@ -3548,6 +3542,7 @@ esp_err_t WebCfgServer::buildMqttConfigHtml(PsychicRequest *request)
response.print("<h3>Advanced MQTT Configuration</h3>");
response.print("<table>");
printInputField(&response, "HASSDISCOVERY", "Home Assistant discovery topic (usually \"homeassistant\")", _preferences->getString(preference_mqtt_hass_discovery).c_str(), 30, "class=\"chkHass\"");
//printCheckBox(&response, "HADEVDISC", "Use Home Assistant device based discovery (2024.11+)", _preferences->getBool(preference_hass_device_discovery), "");
if(_preferences->getBool(preference_opener_enabled, false))
{
printCheckBox(&response, "OPENERCONT", "Set Nuki Opener Lock/Unlock action in Home Assistant to Continuous mode", _preferences->getBool(preference_opener_continuous_mode), "");
@@ -4209,7 +4204,7 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request)
response.print(_preferences->getInt(preference_command_nr_of_retries, 3));
response.print("\nBluetooth command retry delay (ms): ");
response.print(_preferences->getInt(preference_command_retry_delay, 100));
response.print("\nSeconds until reboot when no BLE beacons recieved: ");
response.print("\nSeconds until reboot when no BLE beacons received: ");
response.print(_preferences->getInt(preference_restart_ble_beacon_lost, 60));
response.print("\n\n------------ QUERY / PUBLISH SETTINGS ------------");
response.print("\nLock/Opener state query interval (s): ");
@@ -4643,14 +4638,14 @@ esp_err_t WebCfgServer::processUnpair(PsychicRequest *request, bool opener)
if(!opener && _nuki != nullptr)
{
_nuki->disableHASS();
_nuki->unpair();
}
if(opener && _nukiOpener != nullptr)
{
_nukiOpener->disableHASS();
_nukiOpener->unpair();
}
_network->disableHASS();
waitAndProcess(false, 1000);
restartEsp(RestartReason::DeviceUnpaired);
return res;
@@ -4769,15 +4764,14 @@ esp_err_t WebCfgServer::processFactoryReset(PsychicRequest *request)
if(_nuki != nullptr)
{
_nuki->disableHASS();
_nuki->unpair();
}
if(_nukiOpener != nullptr)
{
_nukiOpener->disableHASS();
_nukiOpener->unpair();
}
_network->disableHASS();
_preferences->clear();
#ifndef CONFIG_IDF_TARGET_ESP32H2

View File

@@ -2,7 +2,9 @@
#include <Preferences.h>
#include <PsychicHttp.h>
#ifdef CONFIG_ESP_HTTPS_SERVER_ENABLE
#include <PsychicHttpsServer.h>
#endif
#include "esp_ota_ops.h"
#include "Config.h"

View File

@@ -446,7 +446,7 @@ void setup()
preferences = new Preferences();
preferences->begin("nukihub", false);
bool firstStart = initPreferences(preferences);
initPreferences(preferences);
bool doOta = false;
uint8_t partitionType = checkPartition();
@@ -468,13 +468,6 @@ void setup()
doOta = true;
}
#ifndef NUKI_HUB_UPDATER
if(preferences->getBool(preference_enable_bootloop_reset, false))
{
bootloopDetection();
}
#endif
#ifdef NUKI_HUB_UPDATER
Log->print(F("Nuki Hub OTA version "));
Log->println(NUKI_HUB_VERSION);
@@ -511,6 +504,11 @@ void setup()
});
}
#else
if(preferences->getBool(preference_enable_bootloop_reset, false))
{
bootloopDetection();
}
Log->print(F("Nuki Hub version "));
Log->println(NUKI_HUB_VERSION);
Log->print(F("Nuki Hub build "));
@@ -571,7 +569,7 @@ void setup()
}
nuki = new NukiWrapper("NukiHub", deviceIdLock, bleScanner, networkLock, nukiOfficial, gpio, preferences);
nuki->initialize(firstStart);
nuki->initialize();
}
Log->println(openerEnabled ? F("Nuki Opener enabled") : F("Nuki Opener disabled"));

View File

@@ -1,17 +1,14 @@
#include "EthernetDevice.h"
#include "../PreferencesKeys.h"
#include "../Logger.h"
#ifndef NUKI_HUB_UPDATER
#include "../MqttTopics.h"
#include "espMqttClient.h"
#endif
#include "../RestartReason.h"
#include "../EspMillis.h"
extern bool ethCriticalFailure;
extern bool wifiFallback;
EthernetDevice::EthernetDevice(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration, const std::string& deviceName, uint8_t phy_addr, int power, int mdc, int mdio, eth_phy_type_t ethtype, eth_clock_mode_t clock_mode)
: NetworkDevice(hostname, ipConfiguration),
: NetworkDevice(hostname, preferences, ipConfiguration),
_deviceName(deviceName),
_phy_addr(phy_addr),
_power(power),
@@ -22,7 +19,9 @@ EthernetDevice::EthernetDevice(const String& hostname, Preferences* preferences,
_useSpi(false),
_preferences(preferences)
{
init();
#ifndef NUKI_HUB_UPDATER
NetworkDevice::init();
#endif
}
EthernetDevice::EthernetDevice(const String &hostname,
@@ -37,7 +36,7 @@ EthernetDevice::EthernetDevice(const String &hostname,
int spi_miso,
int spi_mosi,
eth_phy_type_t ethtype)
: NetworkDevice(hostname, ipConfiguration),
: NetworkDevice(hostname, preferences, ipConfiguration),
_deviceName(deviceName),
_phy_addr(phy_addr),
_cs(cs),
@@ -49,52 +48,9 @@ EthernetDevice::EthernetDevice(const String &hostname,
_type(ethtype),
_useSpi(true),
_preferences(preferences)
{
init();
}
void EthernetDevice::init()
{
#ifndef NUKI_HUB_UPDATER
size_t caLength = _preferences->getString(preference_mqtt_ca, _ca, TLS_CA_MAX_SIZE);
size_t crtLength = _preferences->getString(preference_mqtt_crt, _cert, TLS_CERT_MAX_SIZE);
size_t keyLength = _preferences->getString(preference_mqtt_key, _key, TLS_KEY_MAX_SIZE);
_useEncryption = caLength > 1; // length is 1 when empty
if(_useEncryption)
{
Log->println(F("MQTT over TLS."));
_mqttClientSecure = new espMqttClientSecure(espMqttClientTypes::UseInternalTask::NO);
_mqttClientSecure->setCACert(_ca);
if(crtLength > 1 && keyLength > 1) // length is 1 when empty
{
Log->println(F("MQTT with client certificate."));
_mqttClientSecure->setCertificate(_cert);
_mqttClientSecure->setPrivateKey(_key);
}
} else
{
Log->println(F("MQTT without TLS."));
_mqttClient = new espMqttClient(espMqttClientTypes::UseInternalTask::NO);
}
if(_preferences->getBool(preference_mqtt_log_enabled, false) || _preferences->getBool(preference_webserial_enabled, false))
{
MqttLoggerMode mode;
if(_preferences->getBool(preference_mqtt_log_enabled, false) && _preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::MqttAndSerialAndWeb;
else if (_preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::SerialAndWeb;
else mode = MqttLoggerMode::MqttAndSerial;
_path = new char[200];
memset(_path, 0, sizeof(_path));
String pathStr = _preferences->getString(preference_mqtt_lock_path);
pathStr.concat(mqtt_topic_log);
strcpy(_path, pathStr.c_str());
Log = new MqttLogger(*getMqttClient(), _path, mode);
}
NetworkDevice::init();
#endif
}

View File

@@ -11,9 +11,6 @@
#include <NetworkClientSecure.h>
#include <Preferences.h>
#include "NetworkDevice.h"
#ifndef NUKI_HUB_UPDATER
#include "espMqttClient.h"
#endif
class EthernetDevice : public NetworkDevice
{
@@ -61,21 +58,24 @@ public:
private:
Preferences* _preferences;
void init();
void onDisconnected();
void onNetworkEvent(arduino_event_id_t event, arduino_event_info_t info);
bool _connected = false;
char* _path;
bool _hardwareInitialized = false;
bool _useSpi = false;
int64_t _checkIpTs = -1;
const std::string _deviceName;
uint8_t _phy_addr;
eth_phy_type_t _type;
// LAN8720
int _power;
int _mdc;
int _mdio;
eth_clock_mode_t _clock_mode;
// W55000 and DM9051
int _cs;
@@ -84,16 +84,4 @@ private:
int _spi_sck;
int _spi_miso;
int _spi_mosi;
int64_t _checkIpTs = -1;
eth_phy_type_t _type;
eth_clock_mode_t _clock_mode;
bool _useSpi = false;
#ifndef NUKI_HUB_UPDATER
char _ca[TLS_CA_MAX_SIZE] = {0};
char _cert[TLS_CERT_MAX_SIZE] = {0};
char _key[TLS_KEY_MAX_SIZE] = {0};
#endif
};

View File

@@ -2,19 +2,19 @@
#ifndef CONFIG_IDF_TARGET_ESP32
typedef enum {
ETH_CLOCK_GPIO0_IN = 0,
ETH_CLOCK_GPIO16_OUT = 2,
ETH_CLOCK_GPIO17_OUT = 3
} eth_clock_mode_t;
ETH_CLOCK_GPIO0_IN = 0,
ETH_CLOCK_GPIO16_OUT = 2,
ETH_CLOCK_GPIO17_OUT = 3
} eth_clock_mode_t;
#define ETH_PHY_TYPE_LAN8720 ETH_PHY_MAX
#define ETH_PHY_TYPE_LAN8720 ETH_PHY_MAX
#else
#define ETH_PHY_TYPE_LAN8720 ETH_PHY_LAN8720
#endif
#define ETH_CLK_MODE_LAN8720 ETH_CLOCK_GPIO0_IN
#define ETH_PHY_ADDR_LAN8720 0
#define ETH_PHY_MDC_LAN8720 23
#define ETH_PHY_MDIO_LAN8720 18
#define ETH_PHY_POWER_LAN8720 -1
#define ETH_RESET_PIN_LAN8720 1
#define ETH_CLK_MODE_LAN8720 ETH_CLOCK_GPIO0_IN
#define ETH_PHY_ADDR_LAN8720 0
#define ETH_PHY_MDC_LAN8720 23
#define ETH_PHY_MDIO_LAN8720 18
#define ETH_PHY_POWER_LAN8720 -1
#define ETH_RESET_PIN_LAN8720 1

View File

@@ -2,13 +2,52 @@
#include "NetworkDevice.h"
#include "../Logger.h"
void NetworkDevice::printError()
{
Log->print(F("Free Heap: "));
Log->println(ESP.getFreeHeap());
}
#ifndef NUKI_HUB_UPDATER
#include "../MqttTopics.h"
#include "PreferencesKeys.h"
void NetworkDevice::init()
{
size_t caLength = _preferences->getString(preference_mqtt_ca, _ca, TLS_CA_MAX_SIZE);
size_t crtLength = _preferences->getString(preference_mqtt_crt, _cert, TLS_CERT_MAX_SIZE);
size_t keyLength = _preferences->getString(preference_mqtt_key, _key, TLS_KEY_MAX_SIZE);
_useEncryption = caLength > 1; // length is 1 when empty
if(_useEncryption)
{
Log->println(F("MQTT over TLS."));
_mqttClientSecure = new espMqttClientSecure(espMqttClientTypes::UseInternalTask::NO);
_mqttClientSecure->setCACert(_ca);
if(crtLength > 1 && keyLength > 1) // length is 1 when empty
{
Log->println(F("MQTT with client certificate."));
_mqttClientSecure->setCertificate(_cert);
_mqttClientSecure->setPrivateKey(_key);
}
} else
{
Log->println(F("MQTT without TLS."));
_mqttClient = new espMqttClient(espMqttClientTypes::UseInternalTask::NO);
}
if(_preferences->getBool(preference_mqtt_log_enabled, false) || _preferences->getBool(preference_webserial_enabled, false))
{
MqttLoggerMode mode;
if(_preferences->getBool(preference_mqtt_log_enabled, false) && _preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::MqttAndSerialAndWeb;
else if (_preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::SerialAndWeb;
else mode = MqttLoggerMode::MqttAndSerial;
_path = new char[200];
memset(_path, 0, sizeof(_path));
String pathStr = _preferences->getString(preference_mqtt_lock_path);
pathStr.concat(mqtt_topic_log);
strcpy(_path, pathStr.c_str());
Log = new MqttLogger(*getMqttClient(), _path, mode);
}
}
void NetworkDevice::update()
{
if (_mqttEnabled)
@@ -90,7 +129,7 @@ bool NetworkDevice::mqttDisconnect(bool force)
return getMqttClient()->disconnect(force);
}
void NetworkDevice::setWill(const char *topic, uint8_t qos, bool retain, const char *payload)
void NetworkDevice::mqttSetWill(const char *topic, uint8_t qos, bool retain, const char *payload)
{
if (_useEncryption)
{
@@ -155,7 +194,7 @@ uint16_t NetworkDevice::mqttSubscribe(const char *topic, uint8_t qos)
return getMqttClient()->subscribe(topic, qos);
}
void NetworkDevice::disableMqtt()
void NetworkDevice::mqttDisable()
{
getMqttClient()->disconnect();
_mqttEnabled = false;

View File

@@ -2,16 +2,15 @@
#ifndef NUKI_HUB_UPDATER
#include "espMqttClient.h"
#include "MqttClientSetup.h"
#endif
#include "IPConfiguration.h"
#include "../EspMillis.h"
class NetworkDevice
{
public:
explicit NetworkDevice(const String& hostname, const IPConfiguration* ipConfiguration)
explicit NetworkDevice(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration)
: _hostname(hostname),
_preferences(preferences),
_ipConfiguration(ipConfiguration)
{}
@@ -19,7 +18,6 @@ public:
virtual void initialize() = 0;
virtual void reconfigure() = 0;
virtual void printError();
virtual void update();
virtual void scan(bool passive = false, bool async = true) = 0;
@@ -31,36 +29,45 @@ public:
virtual String BSSIDstr() = 0;
#ifndef NUKI_HUB_UPDATER
virtual bool mqttConnect();
virtual bool mqttDisconnect(bool force);
virtual void mqttDisable();
virtual bool mqttConnected() const;
virtual uint16_t mqttPublish(const char* topic, uint8_t qos, bool retain, const char* payload);
virtual uint16_t mqttPublish(const char* topic, uint8_t qos, bool retain, const uint8_t* payload, size_t length);
virtual uint16_t mqttSubscribe(const char* topic, uint8_t qos);
virtual void mqttSetServer(const char* host, uint16_t port);
virtual void mqttSetClientId(const char* clientId);
virtual void mqttSetCleanSession(bool cleanSession);
virtual void mqttSetKeepAlive(uint16_t keepAlive);
virtual uint16_t mqttPublish(const char* topic, uint8_t qos, bool retain, const char* payload);
virtual uint16_t mqttPublish(const char* topic, uint8_t qos, bool retain, const uint8_t* payload, size_t length);
virtual bool mqttConnected() const;
virtual void mqttSetServer(const char* host, uint16_t port);
virtual bool mqttConnect();
virtual bool mqttDisconnect(bool force);
virtual void setWill(const char* topic, uint8_t qos, bool retain, const char* payload);
virtual void mqttSetWill(const char* topic, uint8_t qos, bool retain, const char* payload);
virtual void mqttSetCredentials(const char* username, const char* password);
virtual void mqttOnMessage(espMqttClientTypes::OnMessageCallback callback);
virtual void mqttOnConnect(espMqttClientTypes::OnConnectCallback callback);
virtual void mqttOnDisconnect(espMqttClientTypes::OnDisconnectCallback callback);
virtual void disableMqtt();
virtual uint16_t mqttSubscribe(const char* topic, uint8_t qos);
#endif
protected:
const IPConfiguration* _ipConfiguration = nullptr;
Preferences* _preferences = nullptr;
#ifndef NUKI_HUB_UPDATER
espMqttClient *_mqttClient = nullptr;
espMqttClientSecure *_mqttClientSecure = nullptr;
bool _useEncryption = false;
bool _mqttEnabled = true;
void init();
MqttClient *getMqttClient() const;
bool _useEncryption = false;
bool _mqttEnabled = true;
char* _path;
char _ca[TLS_CA_MAX_SIZE] = {0};
char _cert[TLS_CERT_MAX_SIZE] = {0};
char _key[TLS_KEY_MAX_SIZE] = {0};
#endif
const String _hostname;
const IPConfiguration* _ipConfiguration = nullptr;
};

View File

@@ -1,61 +1,20 @@
#include "WifiDevice.h"
#include "esp_wifi.h"
#include <WiFi.h>
#include "WifiDevice.h"
#include "../PreferencesKeys.h"
#include "../Logger.h"
#ifndef NUKI_HUB_UPDATER
#include "../MqttTopics.h"
#include "espMqttClient.h"
#endif
#include "../RestartReason.h"
#include "../EspMillis.h"
WifiDevice::WifiDevice(const String& hostname, Preferences* preferences, const IPConfiguration* ipConfiguration)
: NetworkDevice(hostname, ipConfiguration),
: NetworkDevice(hostname, preferences, ipConfiguration),
_preferences(preferences)
{
#ifndef NUKI_HUB_UPDATER
size_t caLength = preferences->getString(preference_mqtt_ca, _ca, TLS_CA_MAX_SIZE);
size_t crtLength = preferences->getString(preference_mqtt_crt, _cert, TLS_CERT_MAX_SIZE);
size_t keyLength = preferences->getString(preference_mqtt_key, _key, TLS_KEY_MAX_SIZE);
_useEncryption = caLength > 1; // length is 1 when empty
if(_useEncryption)
{
Log->println(F("MQTT over TLS."));
_mqttClientSecure = new espMqttClientSecure(espMqttClientTypes::UseInternalTask::NO);
_mqttClientSecure->setCACert(_ca);
if(crtLength > 1 && keyLength > 1) // length is 1 when empty
{
Log->println(F("MQTT with client certificate."));
_mqttClientSecure->setCertificate(_cert);
_mqttClientSecure->setPrivateKey(_key);
}
}
else
{
Log->println(F("MQTT without TLS."));
_mqttClient = new espMqttClient(espMqttClientTypes::UseInternalTask::NO);
}
if(preferences->getBool(preference_mqtt_log_enabled, false) || preferences->getBool(preference_webserial_enabled, false))
{
MqttLoggerMode mode;
if(preferences->getBool(preference_mqtt_log_enabled, false) && preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::MqttAndSerialAndWeb;
else if (preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::SerialAndWeb;
else mode = MqttLoggerMode::MqttAndSerial;
_path = new char[200];
memset(_path, 0, sizeof(_path));
String pathStr = preferences->getString(preference_mqtt_lock_path);
pathStr.concat(mqtt_topic_log);
strcpy(_path, pathStr.c_str());
Log = new MqttLogger(*getMqttClient(), _path, mode);
}
#endif
#ifndef NUKI_HUB_UPDATER
NetworkDevice::init();
#endif
}
const String WifiDevice::deviceName() const
{
return "Built-in Wi-Fi";

View File

@@ -1,7 +1,5 @@
#pragma once
#include <WiFiClient.h>
#include <NetworkClientSecure.h>
#include <Preferences.h>
#include "NetworkDevice.h"
#include "IPConfiguration.h"
@@ -29,10 +27,10 @@ private:
void onDisconnected();
void onConnected();
bool connect();
char* _path;
Preferences* _preferences = nullptr;
char* _path;
int _foundNetworks = 0;
int _disconnectCount = 0;
bool _connectOnScanDone = false;
@@ -45,10 +43,4 @@ private:
uint8_t _connectedChannel = 0;
uint8_t* _connectedBSSID;
int64_t _disconnectTs = 0;
#ifndef NUKI_HUB_UPDATER
char _ca[TLS_CA_MAX_SIZE] = {0};
char _cert[TLS_CERT_MAX_SIZE] = {0};
char _key[TLS_KEY_MAX_SIZE] = {0};
#endif
};
};