Arduino Core 3 (#407)
* Add and remove libs and components for Arduino Core 3 * Arduino Core 3 * Add back Solo1 * Change ESP32-S3 to 4MB build * Update README.md * Fix retain and number of retries * Fix rolling log * Fix defaults * Fix BleScanner on Solo1 * Export settings * Import settings * Fix HA Battery voltage * Change submodule * Update espMqttClient and AsyncTCP * Webserial and MQTT/Network reconnecting * Update nuki_ble --------- Co-authored-by: iranl <iranl@github.com>
This commit is contained in:
278
src/main.cpp
278
src/main.cpp
@@ -1,40 +1,62 @@
|
||||
#include "Arduino.h"
|
||||
#include "NukiWrapper.h"
|
||||
#include "NetworkLock.h"
|
||||
#include "WebCfgServer.h"
|
||||
#include <RTOS.h>
|
||||
#include "PreferencesKeys.h"
|
||||
#include "PresenceDetection.h"
|
||||
#include "hardware/W5500EthServer.h"
|
||||
#include "hardware/WifiEthServer.h"
|
||||
#include "NukiOpenerWrapper.h"
|
||||
#include "Gpio.h"
|
||||
#include "Logger.h"
|
||||
#include "Config.h"
|
||||
#include "RestartReason.h"
|
||||
#include "CharBuffer.h"
|
||||
#include "NukiDeviceId.h"
|
||||
|
||||
#define IS_VALID_DETECT 0xa00ab00bc00bd00d;
|
||||
|
||||
Network* network = nullptr;
|
||||
NetworkLock* networkLock = nullptr;
|
||||
NetworkOpener* networkOpener = nullptr;
|
||||
WebCfgServer* webCfgServer = nullptr;
|
||||
#include "Arduino.h"
|
||||
#include "hardware/W5500EthServer.h"
|
||||
#include "hardware/WifiEthServer.h"
|
||||
#include "esp_crt_bundle.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_http_client.h"
|
||||
#include "esp_https_ota.h"
|
||||
#include "Config.h"
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
#include "NukiWrapper.h"
|
||||
#include "NukiNetworkLock.h"
|
||||
#include "PresenceDetection.h"
|
||||
#include "NukiOpenerWrapper.h"
|
||||
#include "Gpio.h"
|
||||
#include "CharBuffer.h"
|
||||
#include "NukiDeviceId.h"
|
||||
#include "WebCfgServer.h"
|
||||
#include "Logger.h"
|
||||
#include "PreferencesKeys.h"
|
||||
#include "RestartReason.h"
|
||||
|
||||
NukiNetworkLock* networkLock = nullptr;
|
||||
NukiNetworkOpener* networkOpener = nullptr;
|
||||
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;
|
||||
|
||||
bool lockEnabled = false;
|
||||
bool openerEnabled = false;
|
||||
|
||||
TaskHandle_t nukiTaskHandle = nullptr;
|
||||
TaskHandle_t presenceDetectionTaskHandle = nullptr;
|
||||
|
||||
unsigned long restartTs = (2^32) - 5 * 60000;
|
||||
|
||||
#else
|
||||
#include "../../src/WebCfgServer.h"
|
||||
#include "../../src/Logger.h"
|
||||
#include "../../src/PreferencesKeys.h"
|
||||
#include "../../src/Config.h"
|
||||
#include "../../src/RestartReason.h"
|
||||
#include "../../src/NukiNetwork.h"
|
||||
|
||||
unsigned long restartTs = 10 * 60000;
|
||||
|
||||
#endif
|
||||
|
||||
NukiNetwork* network = nullptr;
|
||||
WebCfgServer* webCfgServer = nullptr;
|
||||
Preferences* preferences = nullptr;
|
||||
EthServer* ethServer = nullptr;
|
||||
|
||||
RTC_NOINIT_ATTR int restartReason;
|
||||
RTC_NOINIT_ATTR uint64_t restartReasonValidDetect;
|
||||
RTC_NOINIT_ATTR bool rebuildGpioRequested;
|
||||
@@ -45,9 +67,8 @@ RTC_NOINIT_ATTR int8_t bootloopCounter;
|
||||
bool restartReason_isValid;
|
||||
RestartReason currentRestartReason = RestartReason::NotApplicable;
|
||||
|
||||
TaskHandle_t otaTaskHandle = nullptr;
|
||||
TaskHandle_t networkTaskHandle = nullptr;
|
||||
TaskHandle_t nukiTaskHandle = nullptr;
|
||||
TaskHandle_t presenceDetectionTaskHandle = nullptr;
|
||||
|
||||
void networkTask(void *pvParameters)
|
||||
{
|
||||
@@ -61,6 +82,8 @@ void networkTask(void *pvParameters)
|
||||
}
|
||||
|
||||
bool connected = network->update();
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
if(connected && openerEnabled)
|
||||
{
|
||||
networkOpener->update();
|
||||
@@ -70,6 +93,9 @@ void networkTask(void *pvParameters)
|
||||
{
|
||||
webCfgServer->update();
|
||||
}
|
||||
#else
|
||||
webCfgServer->update();
|
||||
#endif
|
||||
|
||||
// millis() is about to overflow. Restart device to prevent problems with overflow
|
||||
if(millis() > restartTs)
|
||||
@@ -80,16 +106,10 @@ void networkTask(void *pvParameters)
|
||||
}
|
||||
|
||||
delay(100);
|
||||
|
||||
// if(wmts < millis())
|
||||
// {
|
||||
// Serial.print("# ");
|
||||
// Serial.println(uxTaskGetStackHighWaterMark(NULL));
|
||||
// wmts = millis() + 60000;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
void nukiTask(void *pvParameters)
|
||||
{
|
||||
while(true)
|
||||
@@ -115,13 +135,120 @@ void nukiTask(void *pvParameters)
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void setupTasks()
|
||||
uint8_t checkPartition()
|
||||
{
|
||||
const esp_partition_t* running_partition = esp_ota_get_running_partition();
|
||||
Log->print(F("Partition size: "));
|
||||
Log->println(running_partition->size);
|
||||
Log->print(F("Partition subtype: "));
|
||||
Log->println(running_partition->subtype);
|
||||
|
||||
if(running_partition->size == 1966080) return 0; //OLD PARTITION TABLE
|
||||
else if(running_partition->subtype == ESP_PARTITION_SUBTYPE_APP_OTA_0) return 1; //NEW PARTITION TABLE, RUNNING MAIN APP
|
||||
else return 2; //NEW PARTITION TABLE, RUNNING UPDATER APP
|
||||
}
|
||||
|
||||
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
||||
{
|
||||
switch (evt->event_id) {
|
||||
case HTTP_EVENT_ERROR:
|
||||
Log->println("HTTP_EVENT_ERROR");
|
||||
break;
|
||||
case HTTP_EVENT_ON_CONNECTED:
|
||||
Log->println("HTTP_EVENT_ON_CONNECTED");
|
||||
break;
|
||||
case HTTP_EVENT_HEADER_SENT:
|
||||
Log->println("HTTP_EVENT_HEADER_SENT");
|
||||
break;
|
||||
case HTTP_EVENT_ON_HEADER:
|
||||
Log->println("HTTP_EVENT_ON_HEADER");
|
||||
break;
|
||||
case HTTP_EVENT_ON_DATA:
|
||||
Log->println("HTTP_EVENT_ON_DATA");
|
||||
break;
|
||||
case HTTP_EVENT_ON_FINISH:
|
||||
Log->println("HTTP_EVENT_ON_FINISH");
|
||||
break;
|
||||
case HTTP_EVENT_DISCONNECTED:
|
||||
Log->println("HTTP_EVENT_DISCONNECTED");
|
||||
break;
|
||||
#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0))
|
||||
case HTTP_EVENT_REDIRECT:
|
||||
Log->println("HTTP_EVENT_REDIRECT");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(5, 0, 0))
|
||||
void otaTask(void *pvParameter)
|
||||
{
|
||||
uint8_t partitionType = checkPartition();
|
||||
String updateUrl;
|
||||
|
||||
if(partitionType==1)
|
||||
{
|
||||
updateUrl = preferences->getString(preference_ota_updater_url);
|
||||
preferences->putString(preference_ota_updater_url, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
updateUrl = preferences->getString(preference_ota_main_url);
|
||||
preferences->putString(preference_ota_main_url, "");
|
||||
}
|
||||
Log->println("Starting OTA task");
|
||||
esp_http_client_config_t config = {
|
||||
.url = updateUrl.c_str(),
|
||||
.event_handler = _http_event_handler,
|
||||
.crt_bundle_attach = esp_crt_bundle_attach,
|
||||
.keep_alive_enable = true,
|
||||
};
|
||||
|
||||
esp_https_ota_config_t ota_config = {
|
||||
.http_config = &config,
|
||||
};
|
||||
Log->print(F("Attempting to download update from "));
|
||||
Log->println(config.url);
|
||||
esp_err_t ret = esp_https_ota(&ota_config);
|
||||
if (ret == ESP_OK) {
|
||||
Log->println("OTA Succeeded, Rebooting...");
|
||||
esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL));
|
||||
restartEsp(RestartReason::OTACompleted);
|
||||
} else {
|
||||
Log->println("Firmware upgrade failed");
|
||||
restartEsp(RestartReason::OTAAborted);
|
||||
}
|
||||
while (1) {
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void setupTasks(bool ota)
|
||||
{
|
||||
// configMAX_PRIORITIES is 25
|
||||
|
||||
xTaskCreatePinnedToCore(networkTask, "ntw", preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), NULL, 3, &networkTaskHandle, 1);
|
||||
xTaskCreatePinnedToCore(nukiTask, "nuki", preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), NULL, 2, &nukiTaskHandle, 1);
|
||||
if(ota)
|
||||
{
|
||||
#if (ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0))
|
||||
xTaskCreatePinnedToCore(networkTask, "ntw", preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), NULL, 3, &networkTaskHandle, 1);
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
xTaskCreatePinnedToCore(nukiTask, "nuki", preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), NULL, 2, &nukiTaskHandle, 1);
|
||||
#endif
|
||||
#else
|
||||
xTaskCreatePinnedToCore(otaTask, "ota", 8192, NULL, 2, &otaTaskHandle, 1);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
xTaskCreatePinnedToCore(networkTask, "ntw", preferences->getInt(preference_task_size_network, NETWORK_TASK_SIZE), NULL, 3, &networkTaskHandle, 1);
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
xTaskCreatePinnedToCore(nukiTask, "nuki", preferences->getInt(preference_task_size_nuki, NUKI_TASK_SIZE), NULL, 2, &nukiTaskHandle, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void initEthServer(const NetworkDeviceType device)
|
||||
@@ -145,24 +272,22 @@ bool initPreferences()
|
||||
preferences = new Preferences();
|
||||
preferences->begin("nukihub", false);
|
||||
|
||||
// preferences->putBool(preference_network_wifi_fallback_disabled, false);
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
bool firstStart = !preferences->getBool(preference_started_before);
|
||||
|
||||
if(firstStart)
|
||||
{
|
||||
preferences->putBool(preference_started_before, true);
|
||||
preferences->putBool(preference_lock_enabled, true);
|
||||
preferences->putBool(preference_conf_info_enabled, true);
|
||||
uint32_t aclPrefs[17] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
preferences->putBytes(preference_acl, (byte*)(&aclPrefs), sizeof(aclPrefs));
|
||||
uint32_t basicLockConfigAclPrefs[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
uint32_t basicLockConfigAclPrefs[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
preferences->putBytes(preference_conf_lock_basic_acl, (byte*)(&basicLockConfigAclPrefs), sizeof(basicLockConfigAclPrefs));
|
||||
uint32_t basicOpenerConfigAclPrefs[14] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
uint32_t basicOpenerConfigAclPrefs[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
preferences->putBytes(preference_conf_opener_basic_acl, (byte*)(&basicOpenerConfigAclPrefs), sizeof(basicOpenerConfigAclPrefs));
|
||||
uint32_t advancedLockConfigAclPrefs[22] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
uint32_t advancedLockConfigAclPrefs[22] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
preferences->putBytes(preference_conf_lock_advanced_acl, (byte*)(&advancedLockConfigAclPrefs), sizeof(advancedLockConfigAclPrefs));
|
||||
uint32_t advancedOpenerConfigAclPrefs[20] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
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));
|
||||
}
|
||||
else
|
||||
@@ -182,7 +307,7 @@ bool initPreferences()
|
||||
preferences->putBool(preference_keypad_info_enabled, false);
|
||||
}
|
||||
|
||||
switch(preferences->getInt(preference_access_level))
|
||||
switch(preferences->getInt(preference_access_level, 10))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
@@ -244,6 +369,21 @@ bool initPreferences()
|
||||
preferences->putBytes(preference_conf_opener_advanced_acl, (byte*)(&advancedOpenerConfigAclPrefs), sizeof(advancedOpenerConfigAclPrefs));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
preferences->putBool(preference_keypad_control_enabled, true);
|
||||
uint32_t aclPrefs[17] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
preferences->putBytes(preference_acl, (byte*)(&aclPrefs), sizeof(aclPrefs));
|
||||
uint32_t basicLockConfigAclPrefs[16] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
preferences->putBytes(preference_conf_lock_basic_acl, (byte*)(&basicLockConfigAclPrefs), sizeof(basicLockConfigAclPrefs));
|
||||
uint32_t basicOpenerConfigAclPrefs[14] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
preferences->putBytes(preference_conf_opener_basic_acl, (byte*)(&basicOpenerConfigAclPrefs), sizeof(basicOpenerConfigAclPrefs));
|
||||
uint32_t advancedLockConfigAclPrefs[22] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
preferences->putBytes(preference_conf_lock_advanced_acl, (byte*)(&advancedLockConfigAclPrefs), sizeof(advancedLockConfigAclPrefs));
|
||||
uint32_t advancedOpenerConfigAclPrefs[20] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
preferences->putBytes(preference_conf_opener_advanced_acl, (byte*)(&advancedOpenerConfigAclPrefs), sizeof(advancedOpenerConfigAclPrefs));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,6 +392,9 @@ bool initPreferences()
|
||||
}
|
||||
|
||||
return firstStart;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void bootloopDetection()
|
||||
@@ -297,19 +440,30 @@ void setup()
|
||||
Serial.begin(115200);
|
||||
Log = &Serial;
|
||||
|
||||
Log->print(F("Nuki Hub version ")); Log->println(NUKI_HUB_VERSION);
|
||||
Log->print(F("Nuki Hub build ")); Log->println(NUKI_HUB_BUILD);
|
||||
|
||||
bool firstStart = initPreferences();
|
||||
preferences->remove(preference_bootloop_counter);
|
||||
uint8_t partitionType = checkPartition();
|
||||
|
||||
initializeRestartReason();
|
||||
|
||||
|
||||
if(preferences->getBool(preference_enable_bootloop_reset, false))
|
||||
{
|
||||
bootloopDetection();
|
||||
}
|
||||
|
||||
#ifdef NUKI_HUB_UPDATER
|
||||
Log->print(F("Nuki Hub OTA version ")); Log->println(NUKI_HUB_VERSION);
|
||||
Log->print(F("Nuki Hub OTA build ")); Log->println(NUKI_HUB_BUILD);
|
||||
|
||||
network = new NukiNetwork(preferences);
|
||||
network->initialize();
|
||||
initEthServer(network->networkDeviceType());
|
||||
webCfgServer = new WebCfgServer(network, ethServer, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType);
|
||||
webCfgServer->initialize();
|
||||
#else
|
||||
Log->print(F("Nuki Hub version ")); Log->println(NUKI_HUB_VERSION);
|
||||
Log->print(F("Nuki Hub build ")); Log->println(NUKI_HUB_BUILD);
|
||||
|
||||
uint32_t devIdOpener = preferences->getUInt(preference_device_id_opener);
|
||||
|
||||
deviceIdLock = new NukiDeviceId(preferences, preference_device_id_lock);
|
||||
@@ -319,16 +473,11 @@ void setup()
|
||||
{
|
||||
deviceIdOpener->assignId(deviceIdLock->get());
|
||||
}
|
||||
|
||||
|
||||
char16_t buffer_size = preferences->getInt(preference_buffer_size, 4096);
|
||||
|
||||
CharBuffer::initialize(buffer_size);
|
||||
|
||||
if(preferences->getInt(preference_restart_timer) != 0)
|
||||
{
|
||||
preferences->remove(preference_restart_timer);
|
||||
}
|
||||
|
||||
gpio = new Gpio(preferences);
|
||||
String gpioDesc;
|
||||
gpio->getConfigurationText(gpioDesc, gpio->pinConfiguration(), "\n\r");
|
||||
@@ -340,7 +489,7 @@ void setup()
|
||||
|
||||
if(preferences->getInt(preference_presence_detection_timeout) >= 0)
|
||||
{
|
||||
presenceDetection = new PresenceDetection(preferences, bleScanner, CharBuffer::get(), CHAR_BUFFER_SIZE);
|
||||
presenceDetection = new PresenceDetection(preferences, bleScanner, CharBuffer::get(), buffer_size);
|
||||
presenceDetection->initialize();
|
||||
}
|
||||
|
||||
@@ -348,15 +497,16 @@ void setup()
|
||||
openerEnabled = preferences->getBool(preference_opener_enabled);
|
||||
|
||||
const String mqttLockPath = preferences->getString(preference_mqtt_lock_path);
|
||||
network = new Network(preferences, presenceDetection, gpio, mqttLockPath, CharBuffer::get(), buffer_size);
|
||||
|
||||
network = new NukiNetwork(preferences, presenceDetection, gpio, mqttLockPath, CharBuffer::get(), buffer_size);
|
||||
network->initialize();
|
||||
|
||||
networkLock = new NetworkLock(network, preferences, CharBuffer::get(), buffer_size);
|
||||
networkLock = new NukiNetworkLock(network, preferences, CharBuffer::get(), buffer_size);
|
||||
networkLock->initialize();
|
||||
|
||||
if(openerEnabled)
|
||||
{
|
||||
networkOpener = new NetworkOpener(network, preferences, CharBuffer::get(), buffer_size);
|
||||
networkOpener = new NukiNetworkOpener(network, preferences, CharBuffer::get(), buffer_size);
|
||||
networkOpener->initialize();
|
||||
}
|
||||
|
||||
@@ -378,14 +528,24 @@ void setup()
|
||||
|
||||
if(preferences->getBool(preference_webserver_enabled, true))
|
||||
{
|
||||
webCfgServer = new WebCfgServer(nuki, nukiOpener, network, gpio, ethServer, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi);
|
||||
webCfgServer = new WebCfgServer(nuki, nukiOpener, network, gpio, ethServer, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType);
|
||||
webCfgServer->initialize();
|
||||
}
|
||||
#endif
|
||||
|
||||
setupTasks();
|
||||
if((partitionType==1 && preferences->getString(preference_ota_updater_url).length() > 0) || (partitionType==2 && preferences->getString(preference_ota_main_url).length() > 0)) setupTasks(true);
|
||||
else setupTasks(false);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void printBeforeSetupInfo()
|
||||
{
|
||||
}
|
||||
|
||||
void printAfterSetupInfo()
|
||||
{
|
||||
}
|
||||
Reference in New Issue
Block a user