Compare commits
No commits in common. "57d068ffad5ad3903b3eb03c6fe524b8ff9f34bb" and "f3df59b0fe0f0feaf01798d7e32b78f619a349a7" have entirely different histories.
57d068ffad
...
f3df59b0fe
@ -3,4 +3,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
project(esp-vfd-clock)
|
project(hello_world)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS "main.cpp" "wifi_provisioner.cpp" "clock_core.cpp"
|
SRCS "main.cpp" "wifi_provisioner.cpp"
|
||||||
INCLUDE_DIRS ""
|
INCLUDE_DIRS ""
|
||||||
REQUIRES nvs_flash esp_wifi esp_http_server etlcpp json
|
REQUIRES nvs_flash esp_wifi esp_http_server etlcpp json
|
||||||
EMBED_FILES "${CMAKE_CURRENT_LIST_DIR}/static/index.html"
|
EMBED_FILES "${CMAKE_CURRENT_LIST_DIR}/static/index.html"
|
||||||
|
|||||||
@ -1,166 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 25/01/24.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "clock_core.hpp"
|
|
||||||
|
|
||||||
#include "esp_expected.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include <esp_event.h>
|
|
||||||
#include <esp_log.h>
|
|
||||||
#include <esp_netif.h>
|
|
||||||
#include <esp_netif_sntp.h>
|
|
||||||
#include <esp_wifi.h>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
const char* TAG = "clock_core";
|
|
||||||
|
|
||||||
constexpr EventBits_t WIFI_FAIL_BIT = BIT0;
|
|
||||||
constexpr EventBits_t WIFI_CONNECTED_BIT = BIT1;
|
|
||||||
constexpr EventBits_t SNTP_SYNCED = BIT2;
|
|
||||||
EventGroupHandle_t clock_core_event_group_;
|
|
||||||
|
|
||||||
void wifiEventHandler(void* arg, esp_event_base_t event_base,
|
|
||||||
int32_t event_id, void* event_data)
|
|
||||||
{
|
|
||||||
static int retry_num = 0;
|
|
||||||
|
|
||||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
|
|
||||||
{
|
|
||||||
esp_wifi_connect();
|
|
||||||
}
|
|
||||||
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
|
|
||||||
{
|
|
||||||
if (retry_num < 10)
|
|
||||||
{
|
|
||||||
esp_wifi_connect();
|
|
||||||
retry_num++;
|
|
||||||
ESP_LOGI(TAG, "Retrying to connect to AP.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xEventGroupSetBits(clock_core_event_group_, WIFI_FAIL_BIT);
|
|
||||||
}
|
|
||||||
ESP_LOGW(TAG, "Connection to AP failed.");
|
|
||||||
}
|
|
||||||
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
|
|
||||||
{
|
|
||||||
auto* event = static_cast<ip_event_got_ip_t*>(event_data);
|
|
||||||
ESP_LOGI(TAG, "Connected to AP. Got IP: " IPSTR, IP2STR(&event->ip_info.ip));
|
|
||||||
retry_num = 0;
|
|
||||||
|
|
||||||
xEventGroupSetBits(clock_core_event_group_, WIFI_CONNECTED_BIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sntpEventHandler(struct timeval*)
|
|
||||||
{
|
|
||||||
xEventGroupSetBits(clock_core_event_group_, SNTP_SYNCED);
|
|
||||||
}
|
|
||||||
|
|
||||||
esp_err_t sntpInitialize()
|
|
||||||
{
|
|
||||||
esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("pool.ntp.org");
|
|
||||||
config.smooth_sync = true;
|
|
||||||
config.server_from_dhcp = true;
|
|
||||||
config.renew_servers_after_new_IP = true;
|
|
||||||
config.sync_cb = sntpEventHandler;
|
|
||||||
config.start = false;
|
|
||||||
config.ip_event_to_renew = IP_EVENT_STA_GOT_IP;
|
|
||||||
|
|
||||||
return esp_netif_sntp_init(&config);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::expected<void, esp_err_t> wifiInitialize(const char* wifi_ssid, const char* wifi_password)
|
|
||||||
{
|
|
||||||
TRY_ESP(esp_netif_init());
|
|
||||||
TRY_ESP(esp_event_loop_create_default());
|
|
||||||
esp_netif_create_default_wifi_sta();
|
|
||||||
|
|
||||||
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
|
|
||||||
TRY_ESP(esp_wifi_init(&config));
|
|
||||||
|
|
||||||
TRY_ESP(sntpInitialize());
|
|
||||||
|
|
||||||
esp_event_handler_instance_t instance_any_id;
|
|
||||||
esp_event_handler_instance_t instance_got_ip;
|
|
||||||
TRY_ESP(esp_event_handler_instance_register(WIFI_EVENT,
|
|
||||||
ESP_EVENT_ANY_ID,
|
|
||||||
&wifiEventHandler,
|
|
||||||
nullptr,
|
|
||||||
&instance_any_id));
|
|
||||||
TRY_ESP(esp_event_handler_instance_register(IP_EVENT,
|
|
||||||
IP_EVENT_STA_GOT_IP,
|
|
||||||
&wifiEventHandler,
|
|
||||||
nullptr,
|
|
||||||
&instance_got_ip));
|
|
||||||
|
|
||||||
wifi_sta_config_t sta_config;
|
|
||||||
std::memset(&sta_config, 0, sizeof(sta_config));
|
|
||||||
std::strncpy((char*) sta_config.ssid, wifi_ssid, 32);
|
|
||||||
std::strncpy((char*) sta_config.password, wifi_password, 64);
|
|
||||||
sta_config.threshold.authmode = WIFI_AUTH_WPA2_PSK;
|
|
||||||
|
|
||||||
wifi_config_t wifi_config = { .sta = sta_config };
|
|
||||||
|
|
||||||
TRY_ESP(esp_wifi_set_mode(WIFI_MODE_STA));
|
|
||||||
TRY_ESP(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
|
|
||||||
TRY_ESP(esp_wifi_start());
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace clock_core
|
|
||||||
{
|
|
||||||
|
|
||||||
void run(const char* wifi_ssid, const char* wifi_password)
|
|
||||||
{
|
|
||||||
clock_core_event_group_ = xEventGroupCreate();
|
|
||||||
|
|
||||||
if (const auto res = wifiInitialize(wifi_ssid, wifi_password);
|
|
||||||
!res.has_value())
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "WiFi setup errored in clock_core::run. Error: %s", esp_err_to_name(res.error()));
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
const EventBits_t bits = xEventGroupWaitBits(clock_core_event_group_,
|
|
||||||
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT | SNTP_SYNCED,
|
|
||||||
pdTRUE,
|
|
||||||
pdFALSE,
|
|
||||||
portMAX_DELAY);
|
|
||||||
|
|
||||||
if (bits & WIFI_CONNECTED_BIT)
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "WiFi setup in clock_core::run successful.");
|
|
||||||
if (const auto res = esp_netif_sntp_start();
|
|
||||||
res != ESP_OK)
|
|
||||||
{
|
|
||||||
ESP_LOGE(TAG, "SNTP setup failed. Error: %s", esp_err_to_name(res));
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (bits & WIFI_FAIL_BIT)
|
|
||||||
{
|
|
||||||
ESP_LOGE(TAG, "WiFi setup in clock_core::run failed.");
|
|
||||||
}
|
|
||||||
else if (bits & SNTP_SYNCED)
|
|
||||||
{
|
|
||||||
ESP_LOGI(TAG, "SNTP sync successful.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ESP_LOGE(TAG, "WiFi setup encountered an unexpected set of bits. %lu", bits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 25/01/24.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace clock_core
|
|
||||||
{
|
|
||||||
|
|
||||||
void run(const char* wifi_ssid, const char* wifi_password);
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -5,13 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <expected>
|
#include <expected>
|
||||||
#include <source_location>
|
|
||||||
#include <string_view>
|
|
||||||
#include <functional>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include <esp_err.h>
|
#include <esp_err.h>
|
||||||
#include <esp_rom_sys.h>
|
|
||||||
|
|
||||||
#define TRY(x) ({ \
|
#define TRY(x) ({ \
|
||||||
const auto& _x = (x); \
|
const auto& _x = (x); \
|
||||||
@ -27,33 +21,3 @@
|
|||||||
return std::unexpected(_x); \
|
return std::unexpected(_x); \
|
||||||
_x; \
|
_x; \
|
||||||
})
|
})
|
||||||
|
|
||||||
[[noreturn]] inline void abortWithError(const char* error, const std::source_location location = std::source_location::current())
|
|
||||||
{
|
|
||||||
esp_rom_printf("abortWithError called, reason: %s\n", error);
|
|
||||||
esp_rom_printf("file: \"%s\" line %d\n", location.file_name(), location.line());
|
|
||||||
if (location.function_name() != nullptr)
|
|
||||||
esp_rom_printf("func: %s\n", location.function_name());
|
|
||||||
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expected>
|
|
||||||
decltype(auto) unwrapOrAbort(Expected&& expected, const std::source_location location = std::source_location::current())
|
|
||||||
{
|
|
||||||
if (!expected.has_value())
|
|
||||||
abortWithError("Unwrapped an errored expected.", location);
|
|
||||||
else
|
|
||||||
return std::forward<Expected>(expected).value();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Expected, typename F>
|
|
||||||
decltype(auto) unwrapOr(Expected&& expected, F&& f)
|
|
||||||
{
|
|
||||||
if (!expected.has_value())
|
|
||||||
std::invoke(std::forward<F>(f), expected.error());
|
|
||||||
else
|
|
||||||
return std::forward<Expected>(expected).value();
|
|
||||||
|
|
||||||
std::unreachable();
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,17 +1,16 @@
|
|||||||
#include "nvs_flash.h"
|
#include "nvs_flash.h"
|
||||||
#include "nvs.h"
|
#include "nvs.h"
|
||||||
|
#include "nvs_handle.hpp"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#include <cinttypes>
|
#include <inttypes.h>
|
||||||
#include <cstdio>
|
#include <stdio.h>
|
||||||
#include <expected>
|
#include <expected>
|
||||||
|
|
||||||
#include "esp_expected.hpp"
|
|
||||||
#include "wifi_provisioner.hpp"
|
#include "wifi_provisioner.hpp"
|
||||||
#include "clock_core.hpp"
|
|
||||||
|
|
||||||
extern "C" void app_main(void)
|
extern "C" void app_main(void)
|
||||||
{
|
{
|
||||||
@ -26,10 +25,9 @@ extern "C" void app_main(void)
|
|||||||
|
|
||||||
ESP_ERROR_CHECK(err);
|
ESP_ERROR_CHECK(err);
|
||||||
|
|
||||||
auto* provisioner = new WifiProvisioner("wifi_settings", [task_id = xTaskGetCurrentTaskHandle()](const auto& params)
|
auto* provisioner = new WifiProvisioner("wifi_settings", [](const auto& params)
|
||||||
{
|
{
|
||||||
printf("Settings successfully done.");
|
printf("Settings successfully done.");
|
||||||
xTaskNotify(task_id, 0, eNoAction);
|
|
||||||
});
|
});
|
||||||
if (!provisioner->addParameter("SSID", "ssid", WifiProvisioner::Parameter::Type::STRING).has_value())
|
if (!provisioner->addParameter("SSID", "ssid", WifiProvisioner::Parameter::Type::STRING).has_value())
|
||||||
{
|
{
|
||||||
@ -43,45 +41,12 @@ extern "C" void app_main(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo: Remove later.
|
|
||||||
// provisioner->clearSettings();
|
|
||||||
|
|
||||||
if (!provisioner->parametersAreConfigured())
|
if (!provisioner->parametersAreConfigured())
|
||||||
{
|
{
|
||||||
auto result = provisioner->startProvisioning();
|
auto result = provisioner->startProvisioning();
|
||||||
if (!result.has_value())
|
if (!result.has_value())
|
||||||
{
|
printf("Error: %s\n", esp_err_to_name(result.error()));
|
||||||
ESP_ERROR_CHECK(result.error());
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Provisioning started...\n");
|
|
||||||
|
|
||||||
const auto notification_received = xTaskNotifyWait(pdFALSE, ULONG_MAX, nullptr, portMAX_DELAY);
|
|
||||||
if (notification_received == pdPASS)
|
|
||||||
{
|
|
||||||
printf("Notification happened.");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
printf("Provisioning started...\n");
|
||||||
abortWithError("Main task notification timed out.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto password = unwrapOrAbort(provisioner->getParameter("password")
|
|
||||||
.and_then([] (const auto& value)
|
|
||||||
{
|
|
||||||
return value.template getValue<etl::string<100>>();
|
|
||||||
}));
|
|
||||||
const auto ssid = unwrapOrAbort(provisioner->getParameter("ssid")
|
|
||||||
.and_then([] (const auto& value)
|
|
||||||
{
|
|
||||||
return value.template getValue<etl::string<100>>();
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Pack up the provisioner.
|
|
||||||
delete provisioner;
|
|
||||||
|
|
||||||
printf("We now have a wifi with SSID: %s, password: %s\n", ssid.c_str(), password.c_str());
|
|
||||||
|
|
||||||
clock_core::run(ssid.c_str(), password.c_str());
|
|
||||||
}
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ extern const char index_end[] asm("_binary_index_html_end");
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
const char* TAG = "ParamProvisioner";
|
const char* TAG = "wifi softAP";
|
||||||
const char* NVS_IS_INITED = "_is_inited";
|
const char* NVS_IS_INITED = "_is_inited";
|
||||||
|
|
||||||
ssize_t indexHtmlLength()
|
ssize_t indexHtmlLength()
|
||||||
@ -156,23 +156,20 @@ esp_err_t parametersGetHandler_(httpd_req_t* req)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::expected<WifiProvisioner::Parameter::Value, esp_err_t> WifiProvisioner::Parameter::tryReadAndAssignValue(nvs::NVSHandle* file_handle)
|
std::expected<WifiProvisioner::Parameter::Value, esp_err_t> WifiProvisioner::Parameter::getValue(nvs::NVSHandle* file_handle) const
|
||||||
{
|
{
|
||||||
if (type == Type::INT)
|
if (type == Type::INT)
|
||||||
{
|
{
|
||||||
std::int32_t value = 0;
|
std::int32_t value = 0;
|
||||||
TRY_ESP(file_handle->get_item(nvs_name.c_str(), value));
|
TRY_ESP(file_handle->get_item(nvs_name.c_str(), value));
|
||||||
data = value;
|
|
||||||
|
|
||||||
return data;
|
return value;
|
||||||
}
|
}
|
||||||
else if (type == Type::FLOAT)
|
else if (type == Type::FLOAT)
|
||||||
{
|
{
|
||||||
std::int32_t value_raw = 0;
|
std::int32_t value_raw = 0;
|
||||||
TRY_ESP(file_handle->get_item(nvs_name.c_str(), value_raw));
|
TRY_ESP(file_handle->get_item(nvs_name.c_str(), value_raw));
|
||||||
data = std::bit_cast<float>(value_raw);
|
return std::bit_cast<float>(value_raw);
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
else if (type == Type::STRING)
|
else if (type == Type::STRING)
|
||||||
{
|
{
|
||||||
@ -182,9 +179,7 @@ std::expected<WifiProvisioner::Parameter::Value, esp_err_t> WifiProvisioner::Par
|
|||||||
TRY_ESP(file_handle->get_string(nvs_name.c_str(), value.data(), value.size() - 1));
|
TRY_ESP(file_handle->get_string(nvs_name.c_str(), value.data(), value.size() - 1));
|
||||||
value.trim_to_terminator();
|
value.trim_to_terminator();
|
||||||
|
|
||||||
data = value;
|
return value;
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
@ -246,34 +241,18 @@ WifiProvisioner::~WifiProvisioner()
|
|||||||
{
|
{
|
||||||
httpd_stop(http_server_);
|
httpd_stop(http_server_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esp_netif_)
|
|
||||||
{
|
|
||||||
esp_wifi_stop();
|
|
||||||
esp_wifi_deinit();
|
|
||||||
|
|
||||||
esp_netif_destroy_default_wifi(esp_netif_);
|
|
||||||
esp_event_loop_delete_default();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WifiProvisioner::parametersAreConfigured()
|
bool WifiProvisioner::parametersAreConfigured()
|
||||||
{
|
{
|
||||||
if (!settings_initialized_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (params_.empty())
|
if (params_.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (auto& param : params_)
|
for (const auto& param : params_)
|
||||||
{
|
{
|
||||||
if (const auto value = param.tryReadAndAssignValue(file_handle_.get());
|
if (const auto value = param.getValue(file_handle_.get());
|
||||||
!value.has_value())
|
!value.has_value())
|
||||||
{
|
{
|
||||||
settings_initialized_ = false;
|
|
||||||
file_handle_->set_item(NVS_IS_INITED, settings_initialized_);
|
|
||||||
file_handle_->commit();
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,16 +260,6 @@ bool WifiProvisioner::parametersAreConfigured()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WifiProvisioner::clearSettings()
|
|
||||||
{
|
|
||||||
if (!settings_initialized_)
|
|
||||||
return;
|
|
||||||
|
|
||||||
settings_initialized_ = false;
|
|
||||||
ESP_ERROR_CHECK(file_handle_->set_item(NVS_IS_INITED, settings_initialized_));
|
|
||||||
ESP_ERROR_CHECK(file_handle_->commit());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::expected<void, esp_err_t> WifiProvisioner::startProvisioning()
|
std::expected<void, esp_err_t> WifiProvisioner::startProvisioning()
|
||||||
{
|
{
|
||||||
TRY(initializeWifiAp_());
|
TRY(initializeWifiAp_());
|
||||||
@ -300,28 +269,6 @@ std::expected<void, esp_err_t> WifiProvisioner::startProvisioning()
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const etl::vector<WifiProvisioner::Parameter, 10>& WifiProvisioner::getParameters()
|
|
||||||
{
|
|
||||||
if (!settings_initialized_)
|
|
||||||
abortWithError("WifiProvisioner read parameters without initialization.");
|
|
||||||
|
|
||||||
return params_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::expected<WifiProvisioner::Parameter, std::error_code> WifiProvisioner::getParameter(const etl::string<15>& name)
|
|
||||||
{
|
|
||||||
if (!settings_initialized_)
|
|
||||||
return std::unexpected{std::make_error_code(std::errc::not_connected)};
|
|
||||||
|
|
||||||
for (const auto& param : params_)
|
|
||||||
{
|
|
||||||
if (param.nvs_name == name)
|
|
||||||
return param;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::unexpected{std::make_error_code(std::errc::invalid_argument)};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::expected<void, std::error_code> WifiProvisioner::addParameter(const char* name, const char* nvs_name, const Parameter::Type type)
|
std::expected<void, std::error_code> WifiProvisioner::addParameter(const char* name, const char* nvs_name, const Parameter::Type type)
|
||||||
{
|
{
|
||||||
if (params_.full())
|
if (params_.full())
|
||||||
@ -391,7 +338,7 @@ std::expected<void, esp_err_t> WifiProvisioner::initializeWifiAp_()
|
|||||||
{
|
{
|
||||||
TRY_ESP(esp_netif_init());
|
TRY_ESP(esp_netif_init());
|
||||||
TRY_ESP(esp_event_loop_create_default());
|
TRY_ESP(esp_event_loop_create_default());
|
||||||
esp_netif_ = esp_netif_create_default_wifi_ap();
|
esp_netif_create_default_wifi_ap();
|
||||||
|
|
||||||
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
|
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
TRY_ESP(esp_wifi_init(&config));
|
TRY_ESP(esp_wifi_init(&config));
|
||||||
|
|||||||
@ -9,7 +9,6 @@
|
|||||||
#include <etl/vector.h>
|
#include <etl/vector.h>
|
||||||
#include <etl/string.h>
|
#include <etl/string.h>
|
||||||
#include <etl/delegate.h>
|
#include <etl/delegate.h>
|
||||||
#include <cstdint>
|
|
||||||
#include <expected>
|
#include <expected>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -54,7 +53,7 @@ public:
|
|||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
using Value = std::variant<std::monostate, std::int32_t, float, etl::string<100>>;
|
using Value = std::variant<std::int32_t, float, etl::string<100>>;
|
||||||
Value data;
|
Value data;
|
||||||
|
|
||||||
Parameter() = default;
|
Parameter() = default;
|
||||||
@ -62,43 +61,10 @@ public:
|
|||||||
: name(name)
|
: name(name)
|
||||||
, nvs_name(nvs_name)
|
, nvs_name(nvs_name)
|
||||||
, type(type)
|
, type(type)
|
||||||
, data(std::monostate())
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
std::expected<Value, esp_err_t> tryReadAndAssignValue(nvs::NVSHandle* file_handle);
|
std::expected<Value, esp_err_t> getValue(nvs::NVSHandle* file_handle) const;
|
||||||
std::expected<Value, const char*> tryValidateAndAssign(cJSON* object);
|
std::expected<Value, const char*> tryValidateAndAssign(cJSON* object);
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
std::expected<T, std::error_code> getValue() const
|
|
||||||
{
|
|
||||||
static_assert(std::is_same_v<T, std::int32_t> || std::is_same_v<T, float> || std::is_same_v<T, etl::string<100>>,
|
|
||||||
"T must be in the Value variant.");
|
|
||||||
|
|
||||||
if (holds_alternative<std::monostate>(data))
|
|
||||||
return std::unexpected(std::make_error_code(std::errc::io_error));
|
|
||||||
|
|
||||||
if constexpr (std::is_same_v<T, std::int32_t>)
|
|
||||||
{
|
|
||||||
if (type != Type::INT)
|
|
||||||
return std::unexpected(std::make_error_code(std::errc::invalid_argument));
|
|
||||||
|
|
||||||
return std::get<std::int32_t>(data);
|
|
||||||
}
|
|
||||||
else if constexpr (std::is_same_v<T, float>)
|
|
||||||
{
|
|
||||||
if (type != Type::FLOAT)
|
|
||||||
return std::unexpected(std::make_error_code(std::errc::invalid_argument));
|
|
||||||
|
|
||||||
return std::get<float>(data);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (type != Type::STRING)
|
|
||||||
return std::unexpected(std::make_error_code(std::errc::invalid_argument));
|
|
||||||
|
|
||||||
return std::get<etl::string<100>>(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit WifiProvisioner(const char* settings_namespace, etl::delegate<void (const etl::vector<Parameter, 10>&)> success_cb);
|
explicit WifiProvisioner(const char* settings_namespace, etl::delegate<void (const etl::vector<Parameter, 10>&)> success_cb);
|
||||||
@ -111,10 +77,8 @@ public:
|
|||||||
WifiProvisioner& operator=(WifiProvisioner&&) = delete;
|
WifiProvisioner& operator=(WifiProvisioner&&) = delete;
|
||||||
|
|
||||||
bool parametersAreConfigured();
|
bool parametersAreConfigured();
|
||||||
void clearSettings();
|
|
||||||
std::expected<void, esp_err_t> startProvisioning();
|
std::expected<void, esp_err_t> startProvisioning();
|
||||||
const etl::vector<Parameter, 10>& getParameters();
|
|
||||||
std::expected<Parameter, std::error_code> getParameter(const etl::string<15>& name);
|
|
||||||
|
|
||||||
std::expected<void, std::error_code> addParameter(const char* name, const char* nvs_name, const Parameter::Type type);
|
std::expected<void, std::error_code> addParameter(const char* name, const char* nvs_name, const Parameter::Type type);
|
||||||
CJsonPtr getParameterObjects() const;
|
CJsonPtr getParameterObjects() const;
|
||||||
@ -124,7 +88,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
std::unique_ptr<nvs::NVSHandle> file_handle_;
|
std::unique_ptr<nvs::NVSHandle> file_handle_;
|
||||||
bool settings_initialized_ = false;
|
bool settings_initialized_ = false;
|
||||||
void* esp_netif_ = nullptr;
|
|
||||||
httpd_handle_t http_server_ = nullptr;
|
httpd_handle_t http_server_ = nullptr;
|
||||||
etl::vector<Parameter, 10> params_;
|
etl::vector<Parameter, 10> params_;
|
||||||
etl::delegate<void (const etl::vector<Parameter, 10>& params)> success_cb_;
|
etl::delegate<void (const etl::vector<Parameter, 10>& params)> success_cb_;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user