diff --git a/components/CameraManager/CameraManager/CameraManager.cpp b/components/CameraManager/CameraManager/CameraManager.cpp index 95c825d..5844b5d 100644 --- a/components/CameraManager/CameraManager/CameraManager.cpp +++ b/components/CameraManager/CameraManager/CameraManager.cpp @@ -225,7 +225,7 @@ bool CameraManager::setupCamera() void CameraManager::loadConfigData() { ESP_LOGD(CAMERA_MANAGER_TAG, "Loading camera config data"); - ProjectConfig::CameraConfig_t cameraConfig = projectConfig->getCameraConfig(); + CameraConfig_t cameraConfig = projectConfig->getCameraConfig(); this->setHFlip(cameraConfig.href); this->setVFlip(cameraConfig.vflip); this->setCameraResolution((framesize_t)cameraConfig.framesize); diff --git a/components/ProjectConfig/CMakeLists.txt b/components/ProjectConfig/CMakeLists.txt index fb197f6..73ab95d 100644 --- a/components/ProjectConfig/CMakeLists.txt +++ b/components/ProjectConfig/CMakeLists.txt @@ -1,4 +1,7 @@ -idf_component_register(SRCS "ProjectConfig/ProjectConfig.cpp" - INCLUDE_DIRS "ProjectConfig" +idf_component_register( + SRCS + "ProjectConfig/ProjectConfig.cpp" + INCLUDE_DIRS + "ProjectConfig" REQUIRES Preferences Helpers ) \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/Models.hpp b/components/ProjectConfig/ProjectConfig/Models.hpp new file mode 100644 index 0000000..d489ad7 --- /dev/null +++ b/components/ProjectConfig/ProjectConfig/Models.hpp @@ -0,0 +1,287 @@ +#pragma once +#ifndef _PROJECT_CONFIG_MODELS_HPP_ +#define _PROJECT_CONFIG_MODELS_HPP_ + +#include +#include +#include +#include "sdkconfig.h" +#include + +struct BaseConfigModel +{ + BaseConfigModel(Preferences *pref) : pref(pref) {} + + void load(); + void save(); + std::string toRepresentation(); + + Preferences *pref; +}; + +struct DeviceConfig_t : BaseConfigModel +{ + DeviceConfig_t(Preferences *pref) : BaseConfigModel(pref) {} + + std::string OTALogin; + std::string OTAPassword; + int OTAPort; + + void load() + { + this->OTALogin = this->pref->getString("OTALogin", "openiris").c_str(); + this->OTAPassword = this->pref->getString("OTAPassword", "openiris").c_str(); + this->OTAPort = this->pref->getInt("OTAPort", 3232); + }; + + void save() + { + this->pref->putString("OTALogin", this->OTALogin.c_str()); + this->pref->putString("OTAPassword", this->OTAPassword.c_str()); + this->pref->putInt("OTAPort", this->OTAPort); + }; + + std::string toRepresentation() + { + return Helpers::format_string( + "\"device_config\": {\"OTALogin\": \"%s\", \"OTAPassword\": \"%s\", " + "\"OTAPort\": %u}", + this->OTALogin.c_str(), this->OTAPassword.c_str(), this->OTAPort); + }; +}; + +struct MDNSConfig_t : public BaseConfigModel +{ + MDNSConfig_t(Preferences *pref) : BaseConfigModel(pref) {} + + std::string hostname; + + void load() + { + // by default, this will be openiris + // but we can override it at compile time + std::string default_hostname = CONFIG_MDNS_HOSTNAME; + + if (default_hostname.empty()) + { + default_hostname = "openiristracker"; + } + + this->hostname = this->pref->getString("hostname", default_hostname).c_str(); + }; + + void save() + { + this->pref->putString("hostname", this->hostname.c_str()); + }; + + std::string toRepresentation() + { + return Helpers::format_string( + "\"mdns_config\": {\"hostname\": \"%s\"}", + this->hostname.c_str()); + }; +}; + +struct CameraConfig_t : BaseConfigModel +{ + CameraConfig_t(Preferences *pref) : BaseConfigModel(pref) {} + + uint8_t vflip; + uint8_t href; + uint8_t framesize; + uint8_t quality; + uint8_t brightness; + + void load() + { + this->vflip = this->pref->getInt("vflip", 0); + this->href = this->pref->getInt("href", 0); + this->framesize = this->pref->getInt("framesize", 4); + this->quality = this->pref->getInt("quality", 7); + this->brightness = this->pref->getInt("brightness", 2); + }; + + void save() + { + this->pref->putInt("vflip", this->vflip); + this->pref->putInt("href", this->href); + this->pref->putInt("framesize", this->framesize); + this->pref->putInt("quality", this->quality); + this->pref->putInt("brightness", this->brightness); + }; + + std::string toRepresentation() + { + return Helpers::format_string( + "\"camera_config\": {\"vflip\": %d,\"framesize\": %d,\"href\": " + "%d,\"quality\": %d,\"brightness\": %d}", + this->vflip, this->framesize, this->href, this->quality, + this->brightness); + }; +}; + +// with wifi, we have to work a bit differently +// we can have multiple networks saved +// so, we not only need to keep track of them, we also have to +// save them under an indexed name and load them as such. +struct WiFiConfig_t : BaseConfigModel +{ + // default construcotr used for loading + WiFiConfig_t(Preferences *pref) : BaseConfigModel(pref) {} + + WiFiConfig_t( + Preferences *pref, + uint8_t index, + const std::string &name, + const std::string &ssid, + const std::string &password, + uint8_t channel, + uint8_t power) + : BaseConfigModel(pref), + index(index), + name(std::move(name)), + ssid(std::move(ssid)), + password(std::move(password)), + channel(channel), + power(power) {} + + uint8_t index; + std::string name; + std::string ssid; + std::string password; + uint8_t channel; + uint8_t power; + + void load(uint8_t index) + { + this->index = index; + char buffer[2]; + + std::string iter_str = Helpers::itoa(index, buffer, 10); + this->name = this->pref->getString(("name" + iter_str).c_str(), "").c_str(); + this->ssid = this->pref->getString(("ssid" + iter_str).c_str(), "").c_str(); + this->password = this->pref->getString(("password" + iter_str).c_str(), "").c_str(); + this->channel = this->pref->getUInt(("channel" + iter_str).c_str()); + this->power = this->pref->getUInt(("power" + iter_str).c_str()); + }; + + void save() + { + char buffer[2]; + std::string iter_str = Helpers::itoa(this->index, buffer, 10); + + this->pref->putString(("name" + iter_str).c_str(), this->name.c_str()); + this->pref->putString(("ssid" + iter_str).c_str(), this->ssid.c_str()); + this->pref->putString(("password" + iter_str).c_str(), this->password.c_str()); + this->pref->putUInt(("channel" + iter_str).c_str(), this->channel); + this->pref->putUInt(("power" + iter_str).c_str(), this->power); + }; + + std::string toRepresentation() + { + return Helpers::format_string( + "{\"name\": \"%s\", \"ssid\": \"%s\", \"password\": \"%s\", " + "\"channel\": " + "%u, \"power\": %u}", + this->name.c_str(), this->ssid.c_str(), this->password.c_str(), + this->channel, this->power); + }; +}; + +struct AP_WiFiConfig_t : BaseConfigModel +{ + AP_WiFiConfig_t(Preferences *pref) : BaseConfigModel(pref) {} + + std::string ssid; + std::string password; + uint8_t channel; + + void load() + { + this->ssid = this->pref->getString("apSSID", CONFIG_AP_WIFI_SSID).c_str(); + this->password = this->pref->getString("apPassword", CONFIG_AP_WIFI_PASSWORD).c_str(); + }; + + void save() + { + this->pref->putString("apSSID", this->ssid.c_str()); + this->pref->putString("apPass", this->password.c_str()); + this->pref->putUInt("apChannel", this->channel); + }; + + std::string toRepresentation() + { + return Helpers::format_string( + "\"ap_wifi_config\": {\"ssid\": \"%s\", \"password\": \"%s\", " + "\"channel\": %u}", + this->ssid.c_str(), this->password.c_str(), this->channel); + }; +}; + +struct WiFiTxPower_t : BaseConfigModel +{ + WiFiTxPower_t(Preferences *pref) : BaseConfigModel(pref) {} + + uint8_t power; + + void load() + { + this->power = this->pref->getUInt("txpower", 52); + }; + + void save() + { + this->pref->putUInt("txpower", this->power); + }; + + std::string toRepresentation() + { + return Helpers::format_string("\"wifi_tx_power\": {\"power\": %u}", this->power); + }; +}; + +class TrackerConfig_t +{ +public: + DeviceConfig_t device; + CameraConfig_t camera; + std::vector networks; + AP_WiFiConfig_t ap_network; + MDNSConfig_t mdns; + WiFiTxPower_t txpower; + + TrackerConfig_t( + DeviceConfig_t device, + CameraConfig_t camera, + std::vector networks, + AP_WiFiConfig_t ap_network, + MDNSConfig_t mdns, + WiFiTxPower_t txpower) : device(device), + camera(camera), + networks(networks), + ap_network(ap_network), + mdns(mdns), + txpower(txpower) {} + + std::string toRepresentation() + { + std::string WifiConfigRepresentation = ""; + + for (auto &network : this->networks) + { + WifiConfigRepresentation += Helpers::format_string(", %s", network.toRepresentation()); + } + + return Helpers::format_string( + "%s, %s, %s, %s, %s, %s", + this->device.toRepresentation().c_str(), + this->mdns.toRepresentation().c_str(), + this->camera.toRepresentation().c_str(), + WifiConfigRepresentation.c_str(), + this->mdns.toRepresentation().c_str(), + this->txpower.toRepresentation().c_str()); + } +}; + +#endif \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp index 2394af6..59c43d8 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.cpp @@ -1,156 +1,48 @@ #include "ProjectConfig.hpp" -// TODO the current implementation is kinda wack, rethink it +int getNetworkCount(Preferences *pref) +{ + return pref->getInt("netowrkcount", 0); +} -ProjectConfig::ProjectConfig(const std::string &name, - const std::string &mdnsName) - : _name(std::move(name)), - _mdnsName(std::move(mdnsName)), - _already_loaded(false) {} +void saveNetworkCount(Preferences *pref, int count) +{ + pref->putInt("networkcount", count); +} + +ProjectConfig::ProjectConfig(Preferences *pref) : pref(pref), + _already_loaded(false), + config(DeviceConfig_t(pref), + CameraConfig_t(pref), + std::vector{}, + AP_WiFiConfig_t(pref), + MDNSConfig_t(pref), + WiFiTxPower_t(pref)) {} ProjectConfig::~ProjectConfig() {} -/** - *@brief Initializes the structures with blank data to prevent empty memory - *sectors and nullptr errors. - *@brief This is to be called in setup() before loading the config. - */ -void ProjectConfig::initConfig() -{ - if (_name.empty()) - { - ESP_LOGE(CONFIGURATION_TAG, "Config name is null\n"); - _name = "openiris"; - } - - bool success = begin(_name.c_str()); - - ESP_LOGI(CONFIGURATION_TAG, "Config name: %s", _name.c_str()); - ESP_LOGI(CONFIGURATION_TAG, "Config loaded: %s", success ? "true" : "false"); - - /* - * If the config is not loaded, - * we need to initialize the config with default data - ! Do not initialize the WiFiConfig_t struct here, - ! as it will create a blank network which breaks the WiFiManager - */ - // TODO add support for OTA - // this->config.device = {OTA_LOGIN, OTA_PASSWORD, 3232}; - this->config.device = {"openiris", "openiris", 3232}; - - if (_mdnsName.empty()) - { - ESP_LOGE(CONFIGURATION_TAG, "MDNS name is null\n Auto-assigning name to 'openiristracker'"); - _mdnsName = "openiristracker"; - } - this->config.mdns = { - _mdnsName, - }; - - ESP_LOGI(CONFIGURATION_TAG, "MDNS name: %s", _mdnsName.c_str()); - - this->config.ap_network = { - "", - "", - 1, - }; - - this->config.camera = { - .vflip = 0, - .href = 0, - .framesize = 4, - .quality = 7, - .brightness = 2, - }; -} - void ProjectConfig::save() { ESP_LOGD(CONFIGURATION_TAG, "Saving project config"); - deviceConfigSave(); - mdnsConfigSave(); - cameraConfigSave(); - wifiConfigSave(); - wifiTxPowerConfigSave(); - end(); // we call end() here to close the connection to the NVS partition, we - // only do this because we call ESP.restart() next. + this->config.device.save(); + this->config.camera.save(); + this->config.mdns.save(); + this->config.txpower.save(); + this->config.ap_network.save(); - // TODO add the restart task - // OpenIrisTasks::ScheduleRestart(2000); -} - -void ProjectConfig::wifiConfigSave() -{ - ESP_LOGI(CONFIGURATION_TAG, "Saving wifi config"); - - /* WiFi Config */ - putInt("networkCount", this->config.networks.size()); - - std::string name = "name"; - std::string ssid = "ssid"; - std::string password = "pass"; - std::string channel = "channel"; - std::string power = "txpower"; - for (int i = 0; i < this->config.networks.size(); i++) + auto networks_count = this->config.networks.size(); + for (int i = 0; i < networks_count; i++) { - char buffer[2]; - std::string iter_str = Helpers::itoa(i, buffer, 10); - - name.append(iter_str); - ssid.append(iter_str); - password.append(iter_str); - channel.append(iter_str); - power.append(iter_str); - - putString(name.c_str(), this->config.networks[i].name.c_str()); - putString(ssid.c_str(), this->config.networks[i].ssid.c_str()); - putString(password.c_str(), this->config.networks[i].password.c_str()); - putUInt(channel.c_str(), this->config.networks[i].channel); - putUInt(power.c_str(), this->config.networks[i].power); + this->config.networks[i].save(); } - /* AP Config */ - putString("apSSID", this->config.ap_network.ssid.c_str()); - putString("apPass", this->config.ap_network.password.c_str()); - putUInt("apChannel", this->config.ap_network.channel); + saveNetworkCount(this->pref, networks_count); + this->pref->end(); // we call end() here to close the connection to the NVS partition, we + // only do this because we call ESP.restart() next. - ESP_LOGI(CONFIGURATION_TAG, "[Project Config]: Wifi configs saved"); -} - -void ProjectConfig::deviceConfigSave() -{ - /* Device Config */ - putString("OTAPassword", this->config.device.OTAPassword.c_str()); - putString("OTALogin", this->config.device.OTALogin.c_str()); - putInt("OTAPort", this->config.device.OTAPort); -} - -void ProjectConfig::mdnsConfigSave() -{ - /* Device Config */ - putString("hostname", this->config.mdns.hostname.c_str()); -} - -void ProjectConfig::wifiTxPowerConfigSave() -{ - /* Device Config */ - putInt("txpower", this->config.txpower.power); -} - -void ProjectConfig::cameraConfigSave() -{ - /* Camera Config */ - putInt("vflip", this->config.camera.vflip); - putInt("href", this->config.camera.href); - putInt("framesize", this->config.camera.framesize); - putInt("quality", this->config.camera.quality); - putInt("brightness", this->config.camera.brightness); -} - -bool ProjectConfig::reset() -{ - ESP_LOGW(CONFIGURATION_TAG, "Resetting project config"); - return clear(); + // TODO add the restart task + // https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/freertos_idf.html + // OpenIrisTasks::ScheduleRestart(2000); } void ProjectConfig::load() @@ -162,66 +54,33 @@ void ProjectConfig::load() return; } - initConfig(); + bool success = this->pref->begin("openiris"); - /* Device Config */ - this->config.device.OTALogin = getString("OTALogin", "openiris").c_str(); - this->config.device.OTAPassword = - getString("OTAPassword", "12345678").c_str(); - this->config.device.OTAPort = getInt("OTAPort", 3232); + ESP_LOGI(CONFIGURATION_TAG, "Config name: openiris"); + ESP_LOGI(CONFIGURATION_TAG, "Config loaded: %s", success ? "true" : "false"); - /* MDNS Config */ - this->config.mdns.hostname = getString("hostname", _mdnsName.c_str()).c_str(); + this->config.device.load(); + this->config.camera.load(); + this->config.mdns.load(); + this->config.txpower.load(); + this->config.ap_network.load(); - /* Wifi TX Power Config */ - // 11dBm is the default value - this->config.txpower.power = getUInt("txpower", 52); - - /* WiFi Config */ - int networkCount = getInt("networkCount", 0); - std::string name = "name"; - std::string ssid = "ssid"; - std::string password = "pass"; - std::string channel = "channel"; - std::string power = "txpower"; - for (int i = 0; i < networkCount; i++) + for (int i = 0; i < getNetworkCount(this->pref); i++) { - char buffer[2]; - std::string iter_str = Helpers::itoa(i, buffer, 10); - - name.append(iter_str); - ssid.append(iter_str); - password.append(iter_str); - channel.append(iter_str); - power.append(iter_str); - - const std::string &temp_1 = getString(name.c_str()).c_str(); - const std::string &temp_2 = getString(ssid.c_str()).c_str(); - const std::string &temp_3 = getString(password.c_str()).c_str(); - uint8_t temp_4 = getUInt(channel.c_str()); - uint8_t temp_5 = getUInt(power.c_str()); - - //! push_back creates a copy of the object, so we need to use emplace_back - this->config.networks.emplace_back( - temp_1, temp_2, temp_3, temp_4, temp_5, - false); // false because the networks we store in the config are the - // ones we want the esp to connect to, rather than host as AP + auto networkConfig = WiFiConfig_t(this->pref); + networkConfig.load(i); + this->config.networks.push_back(networkConfig); } - /* AP Config */ - this->config.ap_network.ssid = getString("apSSID").c_str(); - this->config.ap_network.password = getString("apPass").c_str(); - this->config.ap_network.channel = getUInt("apChannel"); - - /* Camera Config */ - this->config.camera.vflip = getInt("vflip", 0); - this->config.camera.href = getInt("href", 0); - this->config.camera.framesize = getInt("framesize", 4); - this->config.camera.quality = getInt("quality", 7); - this->config.camera.brightness = getInt("brightness", 2); - this->_already_loaded = true; } + +bool ProjectConfig::reset() +{ + ESP_LOGW(CONFIGURATION_TAG, "Resetting project config"); + return this->pref->clear(); +} + //********************************************************************************************************************** //* //! DeviceConfig @@ -268,26 +127,24 @@ void ProjectConfig::setWifiConfig(const std::string &networkName, size_t size = this->config.networks.size(); // rewrite it to std::find - for (auto it = this->config.networks.begin(); - it != this->config.networks.end();) + auto it = std::find_if( + this->config.networks.begin(), + this->config.networks.end(), + [&](WiFiConfig_t &network) + { return network.name == networkName; }); + + if (it != this->config.networks.end()) { - if (it->name == networkName) - { - ESP_LOGI(CONFIGURATION_TAG, "Found network %s, updating it ...", - it->name.c_str()); - it->name = networkName; - it->ssid = ssid; - it->password = password; - it->channel = channel; - it->power = power; + ESP_LOGI(CONFIGURATION_TAG, "Found network %s, updating it ...", + it->name.c_str()); - return; - } - else - { - ++it; - } + it->name = networkName; + it->ssid = ssid; + it->password = password; + it->channel = channel; + it->power = power; + return; } if (size < 3 && size > 0) @@ -296,16 +153,17 @@ void ProjectConfig::setWifiConfig(const std::string &networkName, // we don't have that network yet, we can add it as we still have some // space we're using emplace_back as push_back will create a copy of it, // we want to avoid that - this->config.networks.emplace_back(networkName, ssid, password, channel, - power, false); + uint8_t last_index = getNetworkCount(this->pref); + this->config.networks.emplace_back(this->pref, last_index, networkName, ssid, password, channel, + power); } // we're allowing to store up to three additional networks if (size == 0) { ESP_LOGI(CONFIGURATION_TAG, "No networks, We're adding a new network"); - this->config.networks.emplace_back(networkName, ssid, password, channel, - power, false); + this->config.networks.emplace_back(this->pref, (uint8_t)0, networkName, ssid, password, channel, + power); } } @@ -317,19 +175,17 @@ void ProjectConfig::deleteWifiConfig(const std::string &networkName) ESP_LOGI(CONFIGURATION_TAG, "No networks, nothing to delete"); } - for (auto it = this->config.networks.begin(); - it != this->config.networks.end();) + auto it = std::find_if( + this->config.networks.begin(), + this->config.networks.end(), + [&](WiFiConfig_t &network) + { return network.name == networkName; }); + + if (it != this->config.networks.end()) { - if (it->name == networkName) - { - ESP_LOGI(CONFIGURATION_TAG, "Found network %s", it->name.c_str()); - it = this->config.networks.erase(it); - ESP_LOGI(CONFIGURATION_TAG, "Deleted network %s", networkName.c_str()); - } - else - { - ++it; - } + ESP_LOGI(CONFIGURATION_TAG, "Found network %s", it->name.c_str()); + this->config.networks.erase(it); + ESP_LOGI(CONFIGURATION_TAG, "Deleted network %s", networkName.c_str()); } } @@ -349,117 +205,37 @@ void ProjectConfig::setAPWifiConfig(const std::string &ssid, ESP_LOGD(CONFIGURATION_TAG, "Updating access point config"); } -//********************************************************************************************************************** -//* -//! Representation -//* -//********************************************************************************************************************** - -std::string ProjectConfig::DeviceConfig_t::toRepresentation() -{ - std::string json = Helpers::format_string( - "\"device_config\": {\"OTALogin\": \"%s\", \"OTAPassword\": \"%s\", " - "\"OTAPort\": %u}", - this->OTALogin.c_str(), this->OTAPassword.c_str(), this->OTAPort); - return json; -} - -std::string ProjectConfig::MDNSConfig_t::toRepresentation() -{ - std::string json = Helpers::format_string( - "\"mdns_config\": {\"hostname\": \"%s\"}", - this->hostname.c_str()); - return json; -} - -std::string ProjectConfig::CameraConfig_t::toRepresentation() -{ - std::string json = Helpers::format_string( - "\"camera_config\": {\"vflip\": %d,\"framesize\": %d,\"href\": " - "%d,\"quality\": %d,\"brightness\": %d}", - this->vflip, this->framesize, this->href, this->quality, - this->brightness); - return json; -} - -std::string ProjectConfig::WiFiConfig_t::toRepresentation() -{ - std::string json = Helpers::format_string( - "{\"name\": \"%s\", \"ssid\": \"%s\", \"password\": \"%s\", " - "\"channel\": " - "%u, \"power\": %u}", - this->name.c_str(), this->ssid.c_str(), this->password.c_str(), - this->channel, this->power); - return json; -} - -std::string ProjectConfig::AP_WiFiConfig_t::toRepresentation() -{ - std::string json = Helpers::format_string( - "\"ap_wifi_config\": {\"ssid\": \"%s\", \"password\": \"%s\", " - "\"channel\": %u}", - this->ssid.c_str(), this->password.c_str(), this->channel); - return json; -} - -std::string ProjectConfig::WiFiTxPower_t::toRepresentation() -{ - std::string json = - Helpers::format_string("\"wifi_tx_power\": {\"power\": %u}", this->power); - return json; -} - -std::string ProjectConfig::TrackerConfig_t::toRepresentation() -{ - std::string WifiConfigRepresentation = ""; - - for (auto &network : this->networks) - { - WifiConfigRepresentation += Helpers::format_string(", %s", network.toRepresentation()); - } - - std::string json = Helpers::format_string( - "%s, %s, %s, %s, %s, %s", - this->device.toRepresentation().c_str(), - this->mdns.toRepresentation().c_str(), - this->camera.toRepresentation().c_str(), - WifiConfigRepresentation.c_str(), - this->mdns.toRepresentation().c_str(), - this->txpower.toRepresentation().c_str()); - return json; -} - //********************************************************************************************************************** //* //! Get Methods //* //********************************************************************************************************************** -ProjectConfig::DeviceConfig_t &ProjectConfig::getDeviceConfig() +DeviceConfig_t &ProjectConfig::getDeviceConfig() { return this->config.device; } -ProjectConfig::CameraConfig_t &ProjectConfig::getCameraConfig() +CameraConfig_t &ProjectConfig::getCameraConfig() { return this->config.camera; } -std::vector &ProjectConfig::getWifiConfigs() +std::vector &ProjectConfig::getWifiConfigs() { return this->config.networks; } -ProjectConfig::AP_WiFiConfig_t &ProjectConfig::getAPWifiConfig() +AP_WiFiConfig_t &ProjectConfig::getAPWifiConfig() { return this->config.ap_network; } -ProjectConfig::MDNSConfig_t &ProjectConfig::getMDNSConfig() +MDNSConfig_t &ProjectConfig::getMDNSConfig() { return this->config.mdns; } -ProjectConfig::WiFiTxPower_t &ProjectConfig::getWiFiTxPowerConfig() +WiFiTxPower_t &ProjectConfig::getWiFiTxPowerConfig() { return this->config.txpower; } -ProjectConfig::TrackerConfig_t &ProjectConfig::getTrackerConfig() +TrackerConfig_t &ProjectConfig::getTrackerConfig() { return this->config; } \ No newline at end of file diff --git a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp index 2db6508..28ad754 100644 --- a/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp +++ b/components/ProjectConfig/ProjectConfig/ProjectConfig.hpp @@ -6,15 +6,19 @@ #include #include #include +#include "Models.hpp" #include static const char *CONFIGURATION_TAG = "[CONFIGURATION]"; -class ProjectConfig : public Preferences -{ +int getNetworkCount(Preferences *pref); +void saveNetworkCount(Preferences *pref, int count); + +class ProjectConfig +{ public: - ProjectConfig(const std::string &name = std::string(), const std::string &mdnsName = std::string()); + ProjectConfig(Preferences *pref); virtual ~ProjectConfig(); void load(); @@ -26,81 +30,6 @@ public: void mdnsConfigSave(); void wifiTxPowerConfigSave(); bool reset(); - void initConfig(); - - struct DeviceConfig_t - { - std::string OTALogin; - std::string OTAPassword; - int OTAPort; - std::string toRepresentation(); - }; - - struct MDNSConfig_t - { - std::string hostname; - std::string toRepresentation(); - }; - - struct CameraConfig_t - { - uint8_t vflip; - uint8_t href; - uint8_t framesize; - uint8_t quality; - uint8_t brightness; - - std::string toRepresentation(); - }; - - struct WiFiConfig_t - { - //! Constructor for WiFiConfig_t - allows us to use emplace_back - WiFiConfig_t(const std::string &name, - const std::string &ssid, - const std::string &password, - uint8_t channel, - uint8_t power, - bool adhoc) - : name(std::move(name)), - ssid(std::move(ssid)), - password(std::move(password)), - channel(channel), - power(power) {} - std::string name; - std::string ssid; - std::string password; - uint8_t channel; - uint8_t power; - - std::string toRepresentation(); - }; - - struct AP_WiFiConfig_t - { - std::string ssid; - std::string password; - uint8_t channel; - - std::string toRepresentation(); - }; - - struct WiFiTxPower_t - { - uint8_t power; - std::string toRepresentation(); - }; - - struct TrackerConfig_t - { - DeviceConfig_t device; - CameraConfig_t camera; - std::vector networks; - AP_WiFiConfig_t ap_network; - MDNSConfig_t mdns; - WiFiTxPower_t txpower; - std::string toRepresentation(); - }; DeviceConfig_t &getDeviceConfig(); CameraConfig_t &getCameraConfig(); @@ -133,10 +62,9 @@ public: void setWiFiTxPower(uint8_t power); private: - TrackerConfig_t config; - std::string _name; - std::string _mdnsName; + Preferences *pref; bool _already_loaded; + TrackerConfig_t config; }; #endif \ No newline at end of file diff --git a/main/openiris_main.cpp b/main/openiris_main.cpp index 56c1b3b..3f969fe 100644 --- a/main/openiris_main.cpp +++ b/main/openiris_main.cpp @@ -31,8 +31,9 @@ static const char *TAG = "[MAIN]"; WebSocketLogger webSocketLogger; +Preferences preferences; -auto deviceConfig = std::make_shared("openiris", CONFIG_MDNS_HOSTNAME); +auto deviceConfig = std::make_shared(&preferences); WiFiManager wifiManager(deviceConfig); MDNSManager mdnsManager(deviceConfig); auto cameraHandler = std::make_shared(deviceConfig); @@ -86,11 +87,29 @@ extern "C" void app_main(void) // then port the mdns stuff - done // then port the camera manager - done // then port the streaming stuff (web and uvc) - done - // then add ADHOC and support for more networks in wifi manager - done - // then port the async web server - // then port the Elegant OTA stuff - // then port the serial manager - for wifi and mdns provisioning setup? + // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + // simplify commands - a simple dependency injection + std::function should do it + // something like + // template + // void registerService(std::shared_pointer service) + // services[std::type_index(typeid(T))] = service; + // where services is an std::unordered_map>; + // I can then use like std::shared_ptr resolve() { return services[typeid(T)]; } to get it in the command + // which can be like a second parameter of the command, like std::function + + // simplify config - DONE + // here I can decouple the loading, initializing and saving logic from the config class and move + // that into the separate modules, and have the config class only act as a container + + // port serial manager + // implement OTA stuff, but prepare it for future use + // add endpoint to check firmware version + // add firmware version somewhere + // setup CI and building for other boards + + // then port the Elegant OTA stuff - I'll roll my own // finish todos, overhaul stuff a bit // maybe swich websocket logging to udp logging @@ -104,12 +123,12 @@ extern "C" void app_main(void) mdnsManager.start(); restAPI.begin(); cameraHandler->setupCamera(); + // make sure the server runs on a separate core streamServer.startStreamServer(); #ifdef CONFIG_WIRED_MODE uvcStream.setup(); #endif - while (1) { ledManager.handleLED();