From 316f74ada8085c0f11c8129316a1f4acbb59ab01 Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Tue, 2 Nov 2021 11:39:36 +0100 Subject: [PATCH] More rewrite --- main/ble_bobby.cpp | 267 ++++++++++++++++++ main/ble_bobby.h | 261 +---------------- main/cloud.cpp | 251 ++++++++++++++++ main/cloud.h | 248 +--------------- main/displays/menus/aboutmenu.cpp | 25 +- main/displays/menus/aboutmenu.h | 21 +- .../menus/accesspointwifisettingsmenu.h | 5 - .../boardcomputerhardwaresettingsmenu.cpp | 8 +- main/displays/menus/genericwifisettingsmenu.h | 6 - main/displays/menus/limitssettingsmenu.cpp | 75 +++++ main/displays/menus/limitssettingsmenu.h | 75 +---- .../displays/menus/lockscreensettingsmenu.cpp | 65 +++++ main/displays/menus/lockscreensettingsmenu.h | 65 +---- .../menus/stationwifisettingsmenu.cpp | 52 ++++ main/displays/menus/stationwifisettingsmenu.h | 59 +--- main/displays/menus/wifiscanmenu.h | 5 - main/displays/menus/wifisettingsmenu.cpp | 27 ++ main/displays/menus/wifisettingsmenu.h | 28 +- main/ledstrip.h | 2 + main/wifitexthelpers.cpp | 167 +++++++++++ main/wifitexthelpers.h | 240 +++++----------- 21 files changed, 1057 insertions(+), 895 deletions(-) diff --git a/main/ble_bobby.cpp b/main/ble_bobby.cpp index e69de29..ece99bf 100644 --- a/main/ble_bobby.cpp +++ b/main/ble_bobby.cpp @@ -0,0 +1,267 @@ +#include "ble_bobby.h" + +// esp-idf includes +#include + +namespace { +constexpr const char * const TAG = "BOBBYBLE"; +} // namespace + +#ifdef FEATURE_BLE +BLEServer *pServer{}; +BLEService *pService{}; +BLECharacteristic *livestatsCharacteristic{}; +BLECharacteristic *remotecontrolCharacteristic{}; +#ifdef FEATURE_WIRELESS_CONFIG +BLECharacteristic *wirelessConfig{}; +BLECharacteristic *getwifilist{}; +#endif + +RemoteControlCallbacks bleRemoteCallbacks; + +#ifdef FEATURE_WIRELESS_CONFIG +WirelessSettingsCallbacks bleWirelessSettingsCallbacks; +WiFiListCallbacks bleWiFiListCallbacks; +#endif + +void createBle() +{ + ESP_LOGI("BOBBY", "called"); + + BLEDevice::init(deviceName); + + const auto serviceUuid{"0335e46c-f355-4ce6-8076-017de08cee98"}; + + pServer = BLEDevice::createServer(); + + pService = pServer->createService(serviceUuid); + + livestatsCharacteristic = pService->createCharacteristic("a48321ea-329f-4eab-a401-30e247211524", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); + remotecontrolCharacteristic = pService->createCharacteristic("4201def0-a264-43e6-946b-6b2d9612dfed", NIMBLE_PROPERTY::WRITE); + remotecontrolCharacteristic->setCallbacks(&bleRemoteCallbacks); +#ifdef FEATURE_WIRELESS_CONFIG + wirelessConfig = pService->createCharacteristic("4201def1-a264-43e6-946b-6b2d9612dfed", NIMBLE_PROPERTY::WRITE); + wirelessConfig->setCallbacks(&bleWirelessSettingsCallbacks); + getwifilist = pService->createCharacteristic("4201def2-a264-43e6-946b-6b2d9612dfed", NIMBLE_PROPERTY::READ); + getwifilist->setCallbacks(&bleWiFiListCallbacks); +#endif + + pService->start(); + + BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); + pAdvertising->addServiceUUID(serviceUuid); + pAdvertising->setScanResponse(true); + BLEDevice::startAdvertising(); +} + +void destroyBle() +{ + ESP_LOGI("BOBBY", "called"); + + BLEDevice::deinit(true); + + pServer = {}; + pService = {}; + livestatsCharacteristic = {}; + remotecontrolCharacteristic = {}; +#ifdef FEATURE_WIRELESS_CONFIG + wirelessConfig = {}; + getwifilist = {}; +#endif +} + +void initBle() +{ + if (settings.bleSettings.bleEnabled) + createBle(); +} + + +void handleBle() +{ + if (settings.bleSettings.bleEnabled) + { + if (!pServer) + createBle(); + + if (livestatsCharacteristic->getSubscribedCount()) + { + StaticJsonDocument<1024> doc; + { + auto arr = doc.createNestedArray("v"); + if (controllers.front.feedbackValid) + arr.add(controllers.front.getCalibratedVoltage()); + else + arr.add(nullptr); + if (controllers.back.feedbackValid) + arr.add(controllers.back.getCalibratedVoltage()); + else + arr.add(nullptr); + } + + { + auto arr = doc.createNestedArray("t"); + if (controllers.front.feedbackValid) + arr.add(fixBoardTemp(controllers.front.feedback.boardTemp)); + else + arr.add(nullptr); + if (controllers.back.feedbackValid) + arr.add(fixBoardTemp(controllers.back.feedback.boardTemp)); + else + arr.add(nullptr); + } + + { + auto arr = doc.createNestedArray("e"); + if (controllers.front.feedbackValid) + { + arr.add(controllers.front.feedback.left.error); + arr.add(controllers.front.feedback.right.error); + } + else + { + arr.add(nullptr); + arr.add(nullptr); + } + if (controllers.back.feedbackValid) + { + arr.add(controllers.back.feedback.left.error); + arr.add(controllers.back.feedback.right.error); + } + else + { + arr.add(nullptr); + arr.add(nullptr); + } + } + + { + auto arr = doc.createNestedArray("s"); + if (controllers.front.feedbackValid) + { + arr.add(convertToKmh(controllers.front.feedback.left.speed * (settings.controllerHardware.invertFrontLeft ? -1 : 1))); + arr.add(convertToKmh(controllers.front.feedback.right.speed * (settings.controllerHardware.invertFrontRight ? -1 : 1))); + } + else + { + arr.add(nullptr); + arr.add(nullptr); + } + if (controllers.back.feedbackValid) + { + arr.add(convertToKmh(controllers.back.feedback.left.speed * (settings.controllerHardware.invertBackLeft ? -1 : 1))); + arr.add(convertToKmh(controllers.back.feedback.right.speed * (settings.controllerHardware.invertBackRight ? -1 : 1))); + } + else + { + arr.add(nullptr); + arr.add(nullptr); + } + } + + { + auto arr = doc.createNestedArray("a"); + if (controllers.front.feedbackValid) + { + arr.add(fixCurrent(controllers.front.feedback.left.dcLink) * 2); + arr.add(fixCurrent(controllers.front.feedback.right.dcLink) * 2); + } + else + { + arr.add(nullptr); + arr.add(nullptr); + } + if (controllers.back.feedbackValid) + { + arr.add(fixCurrent(controllers.back.feedback.left.dcLink) * 2); + arr.add(fixCurrent(controllers.back.feedback.right.dcLink) * 2); + } + else + { + arr.add(nullptr); + arr.add(nullptr); + } + } + + std::string json; + serializeJson(doc, json); + + livestatsCharacteristic->setValue(json); + livestatsCharacteristic->notify(); + } + } + else if (pServer) + { + destroyBle(); + } +} + +void RemoteControlCallbacks::onWrite(NimBLECharacteristic* pCharacteristic) +{ + const auto &val = pCharacteristic->getValue(); + + StaticJsonDocument<256> doc; + if (const auto error = deserializeJson(doc, val)) + { + ESP_LOGW(TAG, "ignoring cmd with invalid json: %.*s %s", val.size(), val.data(), error.c_str()); + return; + } + +#ifdef FEATURE_LEDSTRIP + auto newBlinkAnimation = doc["anim"].as(); + if (blinkAnimation != newBlinkAnimation) blinkAnimation = newBlinkAnimation; +#endif + + if (!simplified) + { + modes::remoteControlMode.setCommand(RemoteCommand{ + .frontLeft = doc["fl"].as(), + .frontRight = doc["fr"].as(), + .backLeft = doc["bl"].as(), + .backRight = doc["br"].as() + }); + } +} + +#ifdef FEATURE_WIRELESS_CONFIG +void WirelessSettingsCallbacks::onWrite(NimBLECharacteristic* pCharacteristic) +{ + const auto &val = pCharacteristic->getValue(); + + StaticJsonDocument<256> doc; + if (const auto error = deserializeJson(doc, val)) + { + ESP_LOGW(TAG, "ignoring cmd with invalid json: %.*s %s", val.size(), val.data(), error.c_str()); + return; + } + + auto write_type = doc["type"].as(); + + if (write_type == "wifi") { + const int index = doc["wifi_index"].as(); + ESP_LOGI(TAG, "[ble_config]: Set wifi%i: WiFi-SSID: %s, WiFi-Password: ***", doc["wifi_index"].as(), doc["wifi_ssid"].as()); + stringSettings.wifis[index].ssid = doc["wifi_ssid"].as(); + stringSettings.wifis[index].key = doc["wifi_pass"].as(); + saveSettings(); + } else { + const auto deserialized = deserializeJson(doc, val); + ESP_LOGW(TAG, "Unkown type %s -> json: %.*s %s", doc["type"].as(), val.size(), val.data(), deserialized.c_str()); + } +} + +void WiFiListCallbacks::onRead(NimBLECharacteristic *pCharacteristic) { + StaticJsonDocument<768> responseDoc; + auto wifis = stringSettings.wifis; + auto wifiArray = responseDoc.createNestedArray("wifis"); + ESP_LOGI(TAG, "[ble_wifilist] Got request for listing wifi ssids."); + for (unsigned int index = 0; index < wifis.size(); index++) { + wifiArray.add(wifis[index].ssid); + } + responseDoc["wifi_count"] = wifis.size(); + std::string json; + serializeJson(responseDoc, json); + pCharacteristic->setValue(json); +} +#endif + +#endif diff --git a/main/ble_bobby.h b/main/ble_bobby.h index 069a4d4..032f679 100644 --- a/main/ble_bobby.h +++ b/main/ble_bobby.h @@ -1,8 +1,5 @@ #pragma once -// esp-idf includes -#include - // 3rdparty lib includes #include #ifdef FEATURE_BLE @@ -21,15 +18,14 @@ //wifistack #include "wifi_bobbycar.h" -namespace { #ifdef FEATURE_BLE -BLEServer *pServer{}; -BLEService *pService{}; -BLECharacteristic *livestatsCharacteristic{}; -BLECharacteristic *remotecontrolCharacteristic{}; +extern BLEServer *pServer; +extern BLEService *pService; +extern BLECharacteristic *livestatsCharacteristic; +extern BLECharacteristic *remotecontrolCharacteristic; #ifdef FEATURE_WIRELESS_CONFIG -BLECharacteristic *wirelessConfig{}; -BLECharacteristic *getwifilist{}; +extern BLECharacteristic *wirelessConfig; +extern BLECharacteristic *getwifilist; #endif void createBle(); @@ -55,250 +51,15 @@ public: }; #endif -RemoteControlCallbacks bleRemoteCallbacks; +extern RemoteControlCallbacks bleRemoteCallbacks; #ifdef FEATURE_WIRELESS_CONFIG -WirelessSettingsCallbacks bleWirelessSettingsCallbacks; -WiFiListCallbacks bleWiFiListCallbacks; +extern WirelessSettingsCallbacks bleWirelessSettingsCallbacks; +extern WiFiListCallbacks bleWiFiListCallbacks; #endif -void initBle() -{ - if (settings.bleSettings.bleEnabled) - createBle(); -} +void initBle(); -void handleBle() -{ - if (settings.bleSettings.bleEnabled) - { - if (!pServer) - createBle(); +void handleBle(); - if (livestatsCharacteristic->getSubscribedCount()) - { - StaticJsonDocument<1024> doc; - { - auto arr = doc.createNestedArray("v"); - if (controllers.front.feedbackValid) - arr.add(controllers.front.getCalibratedVoltage()); - else - arr.add(nullptr); - if (controllers.back.feedbackValid) - arr.add(controllers.back.getCalibratedVoltage()); - else - arr.add(nullptr); - } - - { - auto arr = doc.createNestedArray("t"); - if (controllers.front.feedbackValid) - arr.add(fixBoardTemp(controllers.front.feedback.boardTemp)); - else - arr.add(nullptr); - if (controllers.back.feedbackValid) - arr.add(fixBoardTemp(controllers.back.feedback.boardTemp)); - else - arr.add(nullptr); - } - - { - auto arr = doc.createNestedArray("e"); - if (controllers.front.feedbackValid) - { - arr.add(controllers.front.feedback.left.error); - arr.add(controllers.front.feedback.right.error); - } - else - { - arr.add(nullptr); - arr.add(nullptr); - } - if (controllers.back.feedbackValid) - { - arr.add(controllers.back.feedback.left.error); - arr.add(controllers.back.feedback.right.error); - } - else - { - arr.add(nullptr); - arr.add(nullptr); - } - } - - { - auto arr = doc.createNestedArray("s"); - if (controllers.front.feedbackValid) - { - arr.add(convertToKmh(controllers.front.feedback.left.speed * (settings.controllerHardware.invertFrontLeft ? -1 : 1))); - arr.add(convertToKmh(controllers.front.feedback.right.speed * (settings.controllerHardware.invertFrontRight ? -1 : 1))); - } - else - { - arr.add(nullptr); - arr.add(nullptr); - } - if (controllers.back.feedbackValid) - { - arr.add(convertToKmh(controllers.back.feedback.left.speed * (settings.controllerHardware.invertBackLeft ? -1 : 1))); - arr.add(convertToKmh(controllers.back.feedback.right.speed * (settings.controllerHardware.invertBackRight ? -1 : 1))); - } - else - { - arr.add(nullptr); - arr.add(nullptr); - } - } - - { - auto arr = doc.createNestedArray("a"); - if (controllers.front.feedbackValid) - { - arr.add(fixCurrent(controllers.front.feedback.left.dcLink) * 2); - arr.add(fixCurrent(controllers.front.feedback.right.dcLink) * 2); - } - else - { - arr.add(nullptr); - arr.add(nullptr); - } - if (controllers.back.feedbackValid) - { - arr.add(fixCurrent(controllers.back.feedback.left.dcLink) * 2); - arr.add(fixCurrent(controllers.back.feedback.right.dcLink) * 2); - } - else - { - arr.add(nullptr); - arr.add(nullptr); - } - } - - std::string json; - serializeJson(doc, json); - - livestatsCharacteristic->setValue(json); - livestatsCharacteristic->notify(); - } - } - else if (pServer) - { - destroyBle(); - } -} - -void createBle() -{ - ESP_LOGI("BOBBY", "called"); - - BLEDevice::init(deviceName); - - const auto serviceUuid{"0335e46c-f355-4ce6-8076-017de08cee98"}; - - pServer = BLEDevice::createServer(); - - pService = pServer->createService(serviceUuid); - - livestatsCharacteristic = pService->createCharacteristic("a48321ea-329f-4eab-a401-30e247211524", NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::NOTIFY); - remotecontrolCharacteristic = pService->createCharacteristic("4201def0-a264-43e6-946b-6b2d9612dfed", NIMBLE_PROPERTY::WRITE); - remotecontrolCharacteristic->setCallbacks(&bleRemoteCallbacks); -#ifdef FEATURE_WIRELESS_CONFIG - wirelessConfig = pService->createCharacteristic("4201def1-a264-43e6-946b-6b2d9612dfed", NIMBLE_PROPERTY::WRITE); - wirelessConfig->setCallbacks(&bleWirelessSettingsCallbacks); - getwifilist = pService->createCharacteristic("4201def2-a264-43e6-946b-6b2d9612dfed", NIMBLE_PROPERTY::READ); - getwifilist->setCallbacks(&bleWiFiListCallbacks); #endif - - pService->start(); - - BLEAdvertising *pAdvertising = BLEDevice::getAdvertising(); - pAdvertising->addServiceUUID(serviceUuid); - pAdvertising->setScanResponse(true); - BLEDevice::startAdvertising(); -} - -void destroyBle() -{ - ESP_LOGI("BOBBY", "called"); - - BLEDevice::deinit(true); - - pServer = {}; - pService = {}; - livestatsCharacteristic = {}; - remotecontrolCharacteristic = {}; -#ifdef FEATURE_WIRELESS_CONFIG - wirelessConfig = {}; - getwifilist = {}; -#endif -} - -void RemoteControlCallbacks::onWrite(NimBLECharacteristic* pCharacteristic) -{ - const auto &val = pCharacteristic->getValue(); - - StaticJsonDocument<256> doc; - if (const auto error = deserializeJson(doc, val)) - { - ESP_LOGW(TAG, "ignoring cmd with invalid json: %.*s %s", val.size(), val.data(), error.c_str()); - return; - } - -#ifdef FEATURE_LEDSTRIP - auto newBlinkAnimation = doc["anim"].as(); - if (blinkAnimation != newBlinkAnimation) blinkAnimation = newBlinkAnimation; -#endif - - if (!simplified) - { - modes::remoteControlMode.setCommand(RemoteCommand{ - .frontLeft = doc["fl"].as(), - .frontRight = doc["fr"].as(), - .backLeft = doc["bl"].as(), - .backRight = doc["br"].as() - }); - } -} - -#ifdef FEATURE_WIRELESS_CONFIG -void WirelessSettingsCallbacks::onWrite(NimBLECharacteristic* pCharacteristic) -{ - const auto &val = pCharacteristic->getValue(); - - StaticJsonDocument<256> doc; - if (const auto error = deserializeJson(doc, val)) - { - ESP_LOGW(TAG, "ignoring cmd with invalid json: %.*s %s", val.size(), val.data(), error.c_str()); - return; - } - - auto write_type = doc["type"].as(); - - if (write_type == "wifi") { - const int index = doc["wifi_index"].as(); - ESP_LOGI(TAG, "[ble_config]: Set wifi%i: WiFi-SSID: %s, WiFi-Password: ***", doc["wifi_index"].as(), doc["wifi_ssid"].as()); - stringSettings.wifis[index].ssid = doc["wifi_ssid"].as(); - stringSettings.wifis[index].key = doc["wifi_pass"].as(); - saveSettings(); - } else { - const auto deserialized = deserializeJson(doc, val); - ESP_LOGW(TAG, "Unkown type %s -> json: %.*s %s", doc["type"].as(), val.size(), val.data(), deserialized.c_str()); - } -} - -void WiFiListCallbacks::onRead(NimBLECharacteristic *pCharacteristic) { - StaticJsonDocument<768> responseDoc; - auto wifis = stringSettings.wifis; - auto wifiArray = responseDoc.createNestedArray("wifis"); - ESP_LOGI(TAG, "[ble_wifilist] Got request for listing wifi ssids."); - for (unsigned int index = 0; index < wifis.size(); index++) { - wifiArray.add(wifis[index].ssid); - } - responseDoc["wifi_count"] = wifis.size(); - std::string json; - serializeJson(responseDoc, json); - pCharacteristic->setValue(json); -} -#endif -#endif -} diff --git a/main/cloud.cpp b/main/cloud.cpp index e69de29..b6a0eaa 100644 --- a/main/cloud.cpp +++ b/main/cloud.cpp @@ -0,0 +1,251 @@ +#include "cloud.h" + +// esp-idf includes +#include + +using namespace std::chrono_literals; + +namespace { +constexpr const char * const TAG = "BOBBYCLOUD"; +} // namespace + +#ifdef FEATURE_CLOUD + +espcpputils::websocket_client cloudClient; +bool cloudStarted{}; +espchrono::millis_clock::time_point lastCreateTry; +espchrono::millis_clock::time_point lastStartTry; +std::string cloudBuffer; + +void initCloud() +{ + if (settings.cloudSettings.cloudEnabled && + !stringSettings.cloudUrl.empty() && + esphttpdutils::urlverify(stringSettings.cloudUrl)) + { + createCloud(); + if (!cloudClient) + return; + + if (wifi_stack::get_sta_status() != wifi_stack::WiFiStaStatus::CONNECTED) + return; + + startCloud(); + } +} + +void cloudCollect() +{ + if (!cloudClient) + { + cloudBuffer.clear(); + return; + } + + if (!cloudStarted) + { + cloudBuffer.clear(); + return; + } + + if (!cloudClient.is_connected()) + { + cloudBuffer.clear(); + return; + } + + if (cloudBuffer.empty()) + cloudBuffer = '['; + else + cloudBuffer += ','; + + cloudBuffer += fmt::format("[{},{},{}", + std::chrono::milliseconds{espchrono::millis_clock::now().time_since_epoch()}.count(), + std::chrono::milliseconds{espchrono::utc_clock::now().time_since_epoch()}.count(), + heap_caps_get_free_size(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)); + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + { + if (const auto &result = wifi_stack::get_sta_ap_info(); result) + cloudBuffer += fmt::format(",{}", result->rssi); + else + cloudBuffer += ",null"; + } + else + cloudBuffer += ",null"; + + if (raw_gas) + cloudBuffer += fmt::format(",{}", *raw_gas); + else + cloudBuffer += ",null"; + + if (raw_brems) + cloudBuffer += fmt::format(",{}", *raw_brems); + else + cloudBuffer += ",null"; + + if (gas) + cloudBuffer += fmt::format(",{:.1f}", *gas); + else + cloudBuffer += ",null"; + + if (brems) + cloudBuffer += fmt::format(",{:.1f}", *brems); + else + cloudBuffer += ",null"; + + constexpr const auto addController = [](const Controller &controller){ + if (!controller.feedbackValid) + { + cloudBuffer += ",null"; + return; + } + + cloudBuffer += fmt::format(",[{:.02f},{:.02f}", + controller.getCalibratedVoltage(), + fixBoardTemp(controller.feedback.boardTemp)); + + constexpr const auto addMotor = [](const bobbycar::protocol::serial::MotorState &command, + const bobbycar::protocol::serial::MotorFeedback &feedback, + bool invert){ + cloudBuffer += fmt::format(",[{},{:.2f},{:.2f},{}]", + command.pwm * (invert?-1:1), + convertToKmh(feedback.speed) * (invert?-1:1), + fixCurrent(feedback.dcLink), + feedback.error); + }; + + addMotor(controller.command.left, controller.feedback.left, controller.invertLeft); + addMotor(controller.command.right, controller.feedback.right, controller.invertRight); + + cloudBuffer += ']'; + }; + + addController(controllers.front); + addController(controllers.back); + + cloudBuffer += "]"; +} + +void cloudSend() +{ + if (settings.cloudSettings.cloudEnabled && + !stringSettings.cloudUrl.empty() && + esphttpdutils::urlverify(stringSettings.cloudUrl)) + { + if (!cloudClient) + { + if (espchrono::ago(lastCreateTry) < 10s) + return; + createCloud(); + } + if (!cloudClient) + return; + + if (!cloudStarted) + { + if (espchrono::ago(lastStartTry) < 10s) + return; + + if (wifi_stack::get_sta_status() != wifi_stack::WiFiStaStatus::CONNECTED) + return; + + startCloud(); + } + if (!cloudStarted) + return; + + if (!cloudClient.is_connected()) + return; + + if (cloudBuffer.empty()) + return; + + cloudBuffer += ']'; + + const auto timeout = std::chrono::ceil(espchrono::milliseconds32{settings.cloudSettings.cloudTransmitTimeout}).count(); + const auto written = cloudClient.send_text(cloudBuffer, timeout); + + if (written < 0) + { + ESP_LOGE("BOBBY", "cloudClient.send_text() failed with %i", written); + } + else if (written != cloudBuffer.size()) + { + ESP_LOGE("BOBBY", "websocket sent size mismatch, sent=%i, expected=%i", written, cloudBuffer.size()); + } + + cloudBuffer.clear(); + } + else if (cloudClient) + { + destroyCloud(); + } +} + +void createCloud() +{ + ESP_LOGI("BOBBY", "called"); + + if (cloudClient) + { + ESP_LOGE(TAG, "cloud client already created"); + return; + } + + lastCreateTry = espchrono::millis_clock::now(); + + const esp_websocket_client_config_t config = { + .uri = stringSettings.cloudUrl.c_str(), + }; + + cloudClient = espcpputils::websocket_client{&config}; + + if (!cloudClient) + { + ESP_LOGE(TAG, "websocket could not be constructed"); + return; + } + + ESP_LOGI("BOBBY", "cloud client created"); +} + +void startCloud() +{ + ESP_LOGI("BOBBY", "called"); + + if (!cloudClient) + { + ESP_LOGE(TAG, "cloud client not created"); + return; + } + + if (cloudStarted) + { + ESP_LOGE(TAG, "cloud client already started"); + return; + } + + lastStartTry = espchrono::millis_clock::now(); + + const auto result = cloudClient.start(); + ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), "BOBBY", "cloudClient.start() returned: %s", esp_err_to_name(result)); + + if (result == ESP_OK) + cloudStarted = true; +} + +void destroyCloud() +{ + ESP_LOGI("BOBBY", "called"); + + if (!cloudClient) + { + ESP_LOGE(TAG, "cloud client not created"); + return; + } + + cloudClient = {}; + cloudStarted = false; +} + +#endif diff --git a/main/cloud.h b/main/cloud.h index 61b5d13..84029f2 100644 --- a/main/cloud.h +++ b/main/cloud.h @@ -1,8 +1,5 @@ #pragma once -// esp-idf includes -#include - // 3rdparty lib includes #include #include @@ -14,247 +11,18 @@ #include "globals.h" #include "utils.h" -namespace { #ifdef FEATURE_CLOUD -espcpputils::websocket_client cloudClient; -bool cloudStarted{}; -espchrono::millis_clock::time_point lastCreateTry; -espchrono::millis_clock::time_point lastStartTry; -std::string cloudBuffer; +extern espcpputils::websocket_client cloudClient; +extern bool cloudStarted; +extern espchrono::millis_clock::time_point lastCreateTry; +extern espchrono::millis_clock::time_point lastStartTry; +extern std::string cloudBuffer; void createCloud(); void destroyCloud(); void startCloud(); -void initCloud() -{ - if (settings.cloudSettings.cloudEnabled && - !stringSettings.cloudUrl.empty() && - esphttpdutils::urlverify(stringSettings.cloudUrl)) - { - createCloud(); - if (!cloudClient) - return; - - if (wifi_stack::get_sta_status() != wifi_stack::WiFiStaStatus::CONNECTED) - return; - - startCloud(); - } -} - -void cloudCollect() -{ - if (!cloudClient) - { - cloudBuffer.clear(); - return; - } - - if (!cloudStarted) - { - cloudBuffer.clear(); - return; - } - - if (!cloudClient.is_connected()) - { - cloudBuffer.clear(); - return; - } - - if (cloudBuffer.empty()) - cloudBuffer = '['; - else - cloudBuffer += ','; - - cloudBuffer += fmt::format("[{},{},{}", - std::chrono::milliseconds{espchrono::millis_clock::now().time_since_epoch()}.count(), - std::chrono::milliseconds{espchrono::utc_clock::now().time_since_epoch()}.count(), - heap_caps_get_free_size(MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)); - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - { - if (const auto &result = wifi_stack::get_sta_ap_info(); result) - cloudBuffer += fmt::format(",{}", result->rssi); - else - cloudBuffer += ",null"; - } - else - cloudBuffer += ",null"; - - if (raw_gas) - cloudBuffer += fmt::format(",{}", *raw_gas); - else - cloudBuffer += ",null"; - - if (raw_brems) - cloudBuffer += fmt::format(",{}", *raw_brems); - else - cloudBuffer += ",null"; - - if (gas) - cloudBuffer += fmt::format(",{:.1f}", *gas); - else - cloudBuffer += ",null"; - - if (brems) - cloudBuffer += fmt::format(",{:.1f}", *brems); - else - cloudBuffer += ",null"; - - constexpr const auto addController = [](const Controller &controller){ - if (!controller.feedbackValid) - { - cloudBuffer += ",null"; - return; - } - - cloudBuffer += fmt::format(",[{:.02f},{:.02f}", - controller.getCalibratedVoltage(), - fixBoardTemp(controller.feedback.boardTemp)); - - constexpr const auto addMotor = [](const bobbycar::protocol::serial::MotorState &command, - const bobbycar::protocol::serial::MotorFeedback &feedback, - bool invert){ - cloudBuffer += fmt::format(",[{},{:.2f},{:.2f},{}]", - command.pwm * (invert?-1:1), - convertToKmh(feedback.speed) * (invert?-1:1), - fixCurrent(feedback.dcLink), - feedback.error); - }; - - addMotor(controller.command.left, controller.feedback.left, controller.invertLeft); - addMotor(controller.command.right, controller.feedback.right, controller.invertRight); - - cloudBuffer += ']'; - }; - - addController(controllers.front); - addController(controllers.back); - - cloudBuffer += "]"; -} - -void cloudSend() -{ - if (settings.cloudSettings.cloudEnabled && - !stringSettings.cloudUrl.empty() && - esphttpdutils::urlverify(stringSettings.cloudUrl)) - { - if (!cloudClient) - { - if (espchrono::ago(lastCreateTry) < 10s) - return; - createCloud(); - } - if (!cloudClient) - return; - - if (!cloudStarted) - { - if (espchrono::ago(lastStartTry) < 10s) - return; - - if (wifi_stack::get_sta_status() != wifi_stack::WiFiStaStatus::CONNECTED) - return; - - startCloud(); - } - if (!cloudStarted) - return; - - if (!cloudClient.is_connected()) - return; - - if (cloudBuffer.empty()) - return; - - cloudBuffer += ']'; - - const auto timeout = std::chrono::ceil(espchrono::milliseconds32{settings.cloudSettings.cloudTransmitTimeout}).count(); - const auto written = cloudClient.send_text(cloudBuffer, timeout); - - if (written < 0) - { - ESP_LOGE("BOBBY", "cloudClient.send_text() failed with %i", written); - } - else if (written != cloudBuffer.size()) - { - ESP_LOGE("BOBBY", "websocket sent size mismatch, sent=%i, expected=%i", written, cloudBuffer.size()); - } - - cloudBuffer.clear(); - } - else if (cloudClient) - { - destroyCloud(); - } -} - -void createCloud() -{ - ESP_LOGI("BOBBY", "called"); - - if (cloudClient) - { - ESP_LOGE(TAG, "cloud client already created"); - return; - } - - lastCreateTry = espchrono::millis_clock::now(); - - const esp_websocket_client_config_t config = { - .uri = stringSettings.cloudUrl.c_str(), - }; - - cloudClient = espcpputils::websocket_client{&config}; - - if (!cloudClient) - { - ESP_LOGE(TAG, "websocket could not be constructed"); - return; - } - - ESP_LOGI("BOBBY", "cloud client created"); -} - -void startCloud() -{ - ESP_LOGI("BOBBY", "called"); - - if (!cloudClient) - { - ESP_LOGE(TAG, "cloud client not created"); - return; - } - - if (cloudStarted) - { - ESP_LOGE(TAG, "cloud client already started"); - return; - } - - lastStartTry = espchrono::millis_clock::now(); - - const auto result = cloudClient.start(); - ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), "BOBBY", "cloudClient.start() returned: %s", esp_err_to_name(result)); - - if (result == ESP_OK) - cloudStarted = true; -} - -void destroyCloud() -{ - ESP_LOGI("BOBBY", "called"); - - if (!cloudClient) - { - ESP_LOGE(TAG, "cloud client not created"); - return; - } - - cloudClient = {}; - cloudStarted = false; -} +void initCloud(); +void cloudCollect(); +void cloudSend(); #endif -} // namespace diff --git a/main/displays/menus/aboutmenu.cpp b/main/displays/menus/aboutmenu.cpp index 548eb41..6cf864e 100644 --- a/main/displays/menus/aboutmenu.cpp +++ b/main/displays/menus/aboutmenu.cpp @@ -6,15 +6,38 @@ #include "actions/switchscreenaction.h" #include "icons/back.h" #include "esptexthelpers.h" +#include "displays/menus/settingsmenu.h" + #ifdef FEATURE_OTA #include #include #include "fmt/core.h" #endif +namespace { +class CurrentVersionText : public virtual espgui::TextInterface +{ +public: + std::string text() const override + { +#ifdef FEATURE_OTA + if (const esp_app_desc_t *app_desc = esp_ota_get_app_description()) + { + return fmt::format("Version: {}", app_desc->version); + } +#endif + return "Version: 1.0"; + }; +}; + +constexpr char TEXT_VERSION[] = "Version: 1.0"; +} // namespace + +using namespace espgui; + AboutMenu::AboutMenu() { - constructMenuItem>(); + constructMenuItem>(); constructMenuItem, DisabledColor, DummyAction>>(); constructMenuItem, DisabledColor, DummyAction>>(); constructMenuItem, DisabledColor, DummyAction>>(); diff --git a/main/displays/menus/aboutmenu.h b/main/displays/menus/aboutmenu.h index b3a30bc..eac7dec 100644 --- a/main/displays/menus/aboutmenu.h +++ b/main/displays/menus/aboutmenu.h @@ -6,29 +6,12 @@ // local includes #include "texts.h" -using namespace espgui; - -namespace { -class CurrentVersionText : public virtual TextInterface { public: std::string text() const override { -#ifdef FEATURE_OTA - if (const esp_app_desc_t *app_desc = esp_ota_get_app_description()) - { - return fmt::format("Version: {}", app_desc->version); - } -#endif - return "Version: 1.0"; - }; -}; - -constexpr char TEXT_VERSION[] = "Version: 1.0"; - class AboutMenu : - public MenuDisplay, - public StaticText + public espgui::MenuDisplay, + public espgui::StaticText { public: AboutMenu(); void back() override; }; -} // namespace diff --git a/main/displays/menus/accesspointwifisettingsmenu.h b/main/displays/menus/accesspointwifisettingsmenu.h index 71b4a2a..11be9f9 100644 --- a/main/displays/menus/accesspointwifisettingsmenu.h +++ b/main/displays/menus/accesspointwifisettingsmenu.h @@ -12,11 +12,6 @@ #include "accessors/settingsaccessors.h" #include "texts.h" -// forward declares -namespace { -class WifiSettingsMenu; -} // namespace - using namespace espgui; namespace { diff --git a/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp b/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp index afe098a..b5d71f8 100644 --- a/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp +++ b/main/displays/menus/boardcomputerhardwaresettingsmenu.cpp @@ -15,9 +15,12 @@ #include "accessors/settingsaccessors.h" #include "displays/menus/lockscreensettingsmenu.h" #include "displays/calibratedisplay.h" +#include "displays/menus/timersmenu.h" +#include "displays/menus/settingsmenu.h" namespace { -struct GasText : public virtual espgui::TextInterface { +struct GasText : public virtual espgui::TextInterface +{ public: std::string text() const override { @@ -27,7 +30,8 @@ public: gas ? fmt::format("{:.02f}", *gas) : "?"); } }; -struct BremsText : public virtual espgui::TextInterface { +struct BremsText : public virtual espgui::TextInterface +{ public: std::string text() const override { diff --git a/main/displays/menus/genericwifisettingsmenu.h b/main/displays/menus/genericwifisettingsmenu.h index c8cc09d..6ebc436 100644 --- a/main/displays/menus/genericwifisettingsmenu.h +++ b/main/displays/menus/genericwifisettingsmenu.h @@ -13,12 +13,6 @@ #include "accessors/wifiaccessors.h" #include "texts.h" -// forward declares -namespace { -class GenericWifiSettingsMenu; -class WifiSettingsMenu; -} // namespace - using namespace espgui; namespace { diff --git a/main/displays/menus/limitssettingsmenu.cpp b/main/displays/menus/limitssettingsmenu.cpp index e69de29..9f8ad91 100644 --- a/main/displays/menus/limitssettingsmenu.cpp +++ b/main/displays/menus/limitssettingsmenu.cpp @@ -0,0 +1,75 @@ +#include "limitssettingsmenu.h" + +// 3rdparty lib includes +#include "changevaluedisplay.h" +#include "menuitem.h" +#include "actions/switchscreenaction.h" +#include "icons/back.h" + +// local includes +#include "utils.h" +#include "accessors/settingsaccessors.h" +#include "displays/menus/settingsmenu.h" + +namespace { +using IMotMaxChangeScreen = espgui::makeComponent< + espgui::ChangeValueDisplay, + espgui::StaticText, + IMotMaxAccessor, + espgui::BackActionInterface>, + espgui::SwitchScreenAction +>; +using IDcMaxChangeScreen = espgui::makeComponent< + espgui::ChangeValueDisplay, + espgui::StaticText, + IDcMaxAccessor, + espgui::BackActionInterface>, + espgui::SwitchScreenAction +>; +using NMotMaxKmhChangeScreen = espgui::makeComponent< + espgui::ChangeValueDisplay, + espgui::StaticText, + NMotMaxKmhAccessor, + espgui::BackActionInterface>, + espgui::SwitchScreenAction +>; +using NMotMaxRpmChangeScreen = espgui::makeComponent< + espgui::ChangeValueDisplay, + espgui::StaticText, + NMotMaxRpmAccessor, + espgui::BackActionInterface>, + espgui::SwitchScreenAction +>; +using FieldWeakMaxChangeScreen = espgui::makeComponent< + espgui::ChangeValueDisplay, + espgui::StaticText, + FieldWeakMaxAccessor, + espgui::BackActionInterface>, + espgui::SwitchScreenAction +>; +using PhaseAdvMaxChangeScreen = espgui::makeComponent< + espgui::ChangeValueDisplay, + espgui::StaticText, + PhaseAdvMaxAccessor, + espgui::BackActionInterface>, + espgui::SwitchScreenAction +>; +} // namespace + +using namespace espgui; + +LimitsSettingsMenu::LimitsSettingsMenu() +{ + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void LimitsSettingsMenu::back() +{ + switchScreen(); +} diff --git a/main/displays/menus/limitssettingsmenu.h b/main/displays/menus/limitssettingsmenu.h index a40417c..25c0d63 100644 --- a/main/displays/menus/limitssettingsmenu.h +++ b/main/displays/menus/limitssettingsmenu.h @@ -1,76 +1,17 @@ #pragma once -// local includes +// 3rdparty lib includes #include "menudisplay.h" -#include "utils.h" -#include "changevaluedisplay.h" -#include "menuitem.h" -#include "actions/switchscreenaction.h" -#include "icons/back.h" + +// local includes #include "texts.h" -#include "accessors/settingsaccessors.h" - -using namespace espgui; - -namespace { -using IMotMaxChangeScreen = makeComponent< - ChangeValueDisplay, - StaticText, - IMotMaxAccessor, - BackActionInterface>, - SwitchScreenAction ->; -using IDcMaxChangeScreen = makeComponent< - ChangeValueDisplay, - StaticText, - IDcMaxAccessor, - BackActionInterface>, - SwitchScreenAction ->; -using NMotMaxKmhChangeScreen = makeComponent< - ChangeValueDisplay, - StaticText, - NMotMaxKmhAccessor, - BackActionInterface>, - SwitchScreenAction ->; -using NMotMaxRpmChangeScreen = makeComponent< - ChangeValueDisplay, - StaticText, - NMotMaxRpmAccessor, - BackActionInterface>, - SwitchScreenAction ->; -using FieldWeakMaxChangeScreen = makeComponent< - ChangeValueDisplay, - StaticText, - FieldWeakMaxAccessor, - BackActionInterface>, - SwitchScreenAction ->; -using PhaseAdvMaxChangeScreen = makeComponent< - ChangeValueDisplay, - StaticText, - PhaseAdvMaxAccessor, - BackActionInterface>, - SwitchScreenAction ->; class LimitsSettingsMenu : - public MenuDisplay, - public StaticText, - public BackActionInterface> + public espgui::MenuDisplay, + public espgui::StaticText { public: - LimitsSettingsMenu() - { - constructMenuItem, SwitchScreenAction>>(); - constructMenuItem, SwitchScreenAction>>(); - constructMenuItem, SwitchScreenAction>>(); - constructMenuItem, SwitchScreenAction>>(); - constructMenuItem, SwitchScreenAction>>(); - constructMenuItem, SwitchScreenAction>>(); - constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); - } + LimitsSettingsMenu(); + + void back() override; }; -} // namespace diff --git a/main/displays/menus/lockscreensettingsmenu.cpp b/main/displays/menus/lockscreensettingsmenu.cpp index e69de29..57b9a08 100644 --- a/main/displays/menus/lockscreensettingsmenu.cpp +++ b/main/displays/menus/lockscreensettingsmenu.cpp @@ -0,0 +1,65 @@ +#include "lockscreensettingsmenu.h" + +// 3rdparty lib includes +#include "menuitem.h" +#include "actions/toggleboolaction.h" +#include "actions/switchscreenaction.h" +#include "icons/back.h" +#include "checkboxicon.h" +#include "changevaluedisplay.h" + +// local includes +#include "globals.h" +#include "accessors/settingsaccessors.h" +#include "displays/menus/boardcomputerhardwaresettingsmenu.h" + +namespace { +using LockscreenPinDigit0ChangeScreen = espgui::makeComponent< + espgui::ChangeValueDisplay, + espgui::StaticText, + LockscreenPinDigitAccessor<0>, + espgui::BackActionInterface>, + espgui::SwitchScreenAction +>; + +using LockscreenPinDigit1ChangeScreen = espgui::makeComponent< + espgui::ChangeValueDisplay, + espgui::StaticText, + LockscreenPinDigitAccessor<1>, + espgui::BackActionInterface>, + espgui::SwitchScreenAction +>; + +using LockscreenPinDigit2ChangeScreen = espgui::makeComponent< + espgui::ChangeValueDisplay, + espgui::StaticText, + LockscreenPinDigitAccessor<2>, + espgui::BackActionInterface>, + espgui::SwitchScreenAction +>; + +using LockscreenPinDigit3ChangeScreen = espgui::makeComponent< + espgui::ChangeValueDisplay, + espgui::StaticText, + LockscreenPinDigitAccessor<3>, + espgui::BackActionInterface>, + espgui::SwitchScreenAction +>; +} // namespace + +using namespace espgui; + +LockscreenSettingsMenu::LockscreenSettingsMenu() +{ + constructMenuItem, ToggleBoolAction, CheckboxIcon, LockscreenAllowPresetSwitchAccessor>>(); + constructMenuItem>, SwitchScreenAction>>(); + constructMenuItem>, SwitchScreenAction>>(); + constructMenuItem>, SwitchScreenAction>>(); + constructMenuItem>, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void LockscreenSettingsMenu::back() +{ + switchScreen(); +} diff --git a/main/displays/menus/lockscreensettingsmenu.h b/main/displays/menus/lockscreensettingsmenu.h index d1a2d2b..82cf322 100644 --- a/main/displays/menus/lockscreensettingsmenu.h +++ b/main/displays/menus/lockscreensettingsmenu.h @@ -1,66 +1,17 @@ #pragma once -// local includes +// 3rdparty lib includes #include "menudisplay.h" -#include "menuitem.h" -#include "actions/toggleboolaction.h" -#include "actions/switchscreenaction.h" + +// local includes #include "texts.h" -#include "icons/back.h" -#include "checkboxicon.h" -#include "globals.h" -#include "accessors/settingsaccessors.h" -#include "changevaluedisplay.h" - -using namespace espgui; - -namespace { -using LockscreenPinDigit0ChangeScreen = makeComponent< - ChangeValueDisplay, - StaticText, - LockscreenPinDigitAccessor<0>, - BackActionInterface>, - SwitchScreenAction ->; - -using LockscreenPinDigit1ChangeScreen = makeComponent< - ChangeValueDisplay, - StaticText, - LockscreenPinDigitAccessor<1>, - BackActionInterface>, - SwitchScreenAction ->; - -using LockscreenPinDigit2ChangeScreen = makeComponent< - ChangeValueDisplay, - StaticText, - LockscreenPinDigitAccessor<2>, - BackActionInterface>, - SwitchScreenAction ->; - -using LockscreenPinDigit3ChangeScreen = makeComponent< - ChangeValueDisplay, - StaticText, - LockscreenPinDigitAccessor<3>, - BackActionInterface>, - SwitchScreenAction ->; class LockscreenSettingsMenu : - public MenuDisplay, - public StaticText, - public BackActionInterface> + public espgui::MenuDisplay, + public espgui::StaticText { public: - LockscreenSettingsMenu() - { - constructMenuItem, ToggleBoolAction, CheckboxIcon, LockscreenAllowPresetSwitchAccessor>>(); - constructMenuItem>, SwitchScreenAction>>(); - constructMenuItem>, SwitchScreenAction>>(); - constructMenuItem>, SwitchScreenAction>>(); - constructMenuItem>, SwitchScreenAction>>(); - constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); - } + LockscreenSettingsMenu(); + + void back() override; }; -} // namespace diff --git a/main/displays/menus/stationwifisettingsmenu.cpp b/main/displays/menus/stationwifisettingsmenu.cpp index e69de29..29e850f 100644 --- a/main/displays/menus/stationwifisettingsmenu.cpp +++ b/main/displays/menus/stationwifisettingsmenu.cpp @@ -0,0 +1,52 @@ +#include "stationwifisettingsmenu.h" + +// 3rdparty lib includes +#include "menuitem.h" +#include "actions/dummyaction.h" +#include "actions/switchscreenaction.h" +#include "actions/toggleboolaction.h" +#include "checkboxicon.h" +#include "icons/back.h" + +// local includes +#include "utils.h" +#include "actions/wifiscanaction.h" +#include "icons/scan.h" +#include "wifitexthelpers.h" +#include "accessors/wifiaccessors.h" +#include "accessors/settingsaccessors.h" +#include "displays/menus/wifiscanmenu.h" +#include "displays/menus/wifisettingsmenu.h" + +using namespace espgui; + +StationWifiSettingsMenu::StationWifiSettingsMenu() +{ + constructMenuItem, ToggleBoolAction, CheckboxIcon, WifiStaEnabledAccessor>>(); + constructMenuItem, WifiScanAction>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::scan>>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, DisabledColor, DummyAction>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void StationWifiSettingsMenu::back() +{ + switchScreen(); +} diff --git a/main/displays/menus/stationwifisettingsmenu.h b/main/displays/menus/stationwifisettingsmenu.h index 8046255..84cc9ea 100644 --- a/main/displays/menus/stationwifisettingsmenu.h +++ b/main/displays/menus/stationwifisettingsmenu.h @@ -1,60 +1,17 @@ #pragma once -// local includes +// 3rdparty lib includes #include "menudisplay.h" -#include "utils.h" -#include "menuitem.h" -#include "actions/dummyaction.h" -#include "actions/switchscreenaction.h" -#include "actions/wifiscanaction.h" -#include "actions/toggleboolaction.h" -#include "checkboxicon.h" -#include "icons/scan.h" -#include "icons/back.h" -#include "wifitexthelpers.h" -#include "accessors/wifiaccessors.h" -#include "accessors/settingsaccessors.h" + +// local includes #include "texts.h" -// forward declares -namespace { -class WifiScanMenu; -class WifiSettingsMenu; -} // namespace - -using namespace espgui; - -namespace { class StationWifiSettingsMenu : - public MenuDisplay, - public StaticText, - public BackActionInterface> + public espgui::MenuDisplay, + public espgui::StaticText { public: - StationWifiSettingsMenu() - { - constructMenuItem, ToggleBoolAction, CheckboxIcon, WifiStaEnabledAccessor>>(); - constructMenuItem, WifiScanAction>>(); - constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&bobbyicons::scan>>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, DisabledColor, DummyAction>>(); - constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); - } + StationWifiSettingsMenu(); + + void back() override; }; -} // namespace diff --git a/main/displays/menus/wifiscanmenu.h b/main/displays/menus/wifiscanmenu.h index 3fa2c10..ec6d2dc 100644 --- a/main/displays/menus/wifiscanmenu.h +++ b/main/displays/menus/wifiscanmenu.h @@ -21,11 +21,6 @@ #include "texts.h" #include "wifi_bobbycar.h" -// forward declares -namespace { -class StationWifiSettingsMenu; -} // namespace - using namespace std::chrono_literals; using namespace espgui; diff --git a/main/displays/menus/wifisettingsmenu.cpp b/main/displays/menus/wifisettingsmenu.cpp index e69de29..613de4b 100644 --- a/main/displays/menus/wifisettingsmenu.cpp +++ b/main/displays/menus/wifisettingsmenu.cpp @@ -0,0 +1,27 @@ +#include "wifisettingsmenu.h" + +// 3rdparty lib includes +#include "actions/switchscreenaction.h" +#include "icons/back.h" + +// local includes +#include "utils.h" +#include "displays/menus/genericwifisettingsmenu.h" +#include "displays/menus/stationwifisettingsmenu.h" +#include "displays/menus/accesspointwifisettingsmenu.h" +#include "displays/menus/settingsmenu.h" + +using namespace espgui; + +WifiSettingsMenu::WifiSettingsMenu() +{ + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction>>(); + constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); +} + +void WifiSettingsMenu::back() +{ + switchScreen(); +} diff --git a/main/displays/menus/wifisettingsmenu.h b/main/displays/menus/wifisettingsmenu.h index febf58a..c9350d3 100644 --- a/main/displays/menus/wifisettingsmenu.h +++ b/main/displays/menus/wifisettingsmenu.h @@ -1,29 +1,17 @@ #pragma once -// local includes +// 3rdparty lib includes #include "menudisplay.h" -#include "utils.h" -#include "actions/switchscreenaction.h" -#include "icons/back.h" + +// local includes #include "texts.h" -using namespace espgui; - -namespace { -class WifiSettingsMenu; - class WifiSettingsMenu : - public MenuDisplay, - public StaticText, - public BackActionInterface> + public espgui::MenuDisplay, + public espgui::StaticText { public: - WifiSettingsMenu() - { - constructMenuItem, SwitchScreenAction>>(); - constructMenuItem, SwitchScreenAction>>(); - constructMenuItem, SwitchScreenAction>>(); - constructMenuItem, SwitchScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>(); - } + WifiSettingsMenu(); + + void back() override; }; -} // namespace diff --git a/main/ledstrip.h b/main/ledstrip.h index 205c257..25f84ef 100644 --- a/main/ledstrip.h +++ b/main/ledstrip.h @@ -9,6 +9,8 @@ #include "espchrono.h" #include "ledstripdefines.h" +using namespace std::chrono_literals; + namespace { enum Bobbycar_Side { diff --git a/main/wifitexthelpers.cpp b/main/wifitexthelpers.cpp index e69de29..a8afbe8 100644 --- a/main/wifitexthelpers.cpp +++ b/main/wifitexthelpers.cpp @@ -0,0 +1,167 @@ +#include "wifitexthelpers.h" + +// 3rdparty lib includes +#include +#include +#include +#include + +std::string WifiStatusText::text() const +{ + return fmt::format("Status: {}", wifi_stack::toString(wifi_stack::get_sta_status())); +} + +std::string WifiScanStatusText::text() const +{ + return fmt::format("ScanStatus: {}", wifi_stack::toString(wifi_stack::get_scan_status())); +} + +std::string WifiHostnameText::text() const +{ + std::string text = "Hostname: "; + const char *hostname{}; + if (const auto result = esp_netif_get_hostname(wifi_stack::esp_netifs[ESP_IF_WIFI_STA], &hostname); result == ESP_OK) + if (hostname) + text += hostname; + return text; +} + +std::string WifiMacText::text() const +{ + std::string text = "MAC: "; + if (const auto result = wifi_stack::get_base_mac_addr()) + text += wifi_stack::toString(*result); + return text; +} + +std::string WifiSsidText::text() const +{ + std::string text = "SSID: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const auto &result = wifi_stack::get_sta_ap_info(); result) + text += std::string_view{reinterpret_cast(result->ssid)}; + return text; +} + +std::string WifiBssidText::text() const +{ + std::string text = "BSSID: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const auto &result = wifi_stack::get_sta_ap_info(); result) + text += wifi_stack::toString(wifi_stack::mac_t{result->bssid}); + return text; +} + +std::string WifiRssiText::text() const +{ + std::string text = "RSSI: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const auto &result = wifi_stack::get_sta_ap_info(); result) + text += fmt::format("{}dB", result->rssi); + return text; +} + +std::string WifiEncryptionTypeText::text() const +{ + std::string text = "encryptionType: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const auto &result = wifi_stack::get_sta_ap_info(); result) + text += wifi_stack::toString(result->authmode); + return text; +} + +std::string WifiPairwiseCipherText::text() const +{ + std::string text = "pairwiseCipher: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const auto &result = wifi_stack::get_sta_ap_info(); result) + text += wifi_stack::toString(result->pairwise_cipher); + return text; +} + +std::string WifiGroupCipherText::text() const +{ + std::string text = "groupCipher: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const auto &result = wifi_stack::get_sta_ap_info(); result) + text += wifi_stack::toString(result->group_cipher); + return text; +} + +std::string WifiIpText::text() const +{ + std::string text = "ip: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result) + text += wifi_stack::toString(result->ip); + return text; +} + +std::string WifiNetmaskText::text() const +{ + std::string text = "netmask: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result) + text += wifi_stack::toString(result->netmask); + return text; +} + +std::string WifiGatewayText::text() const +{ + std::string text = "gateway: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result) + text += wifi_stack::toString(result->gw); + return text; +} + +std::string WifiIpv6LinklocalText::text() const +{ + std::string text = "ipv6: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + { + esp_ip6_addr_t addr; + if (const auto result = esp_netif_get_ip6_linklocal(wifi_stack::esp_netifs[ESP_IF_WIFI_STA], &addr); result == ESP_OK) + text += wifi_stack::toString(addr); + } + return text; +} + +std::string WifiIpv6GlobalText::text() const +{ + std::string text = "ipv6: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + { + esp_ip6_addr_t addr; + if (const auto result = esp_netif_get_ip6_global(wifi_stack::esp_netifs[ESP_IF_WIFI_STA], &addr); result == ESP_OK) + text += wifi_stack::toString(addr); + } + return text; +} + +std::string WifiDns0Text::text() const +{ + std::string text = "dns0: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const ip_addr_t *dns_ip = dns_getserver(0)) + text += wifi_stack::toString(*dns_ip); + return text; +} + +std::string WifiDns1Text::text() const +{ + std::string text = "dns1: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const ip_addr_t *dns_ip = dns_getserver(1)) + text += wifi_stack::toString(*dns_ip); + return text; +} + +std::string WifiDns2Text::text() const +{ + std::string text = "dns2: "; + if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) + if (const ip_addr_t *dns_ip = dns_getserver(2)) + text += wifi_stack::toString(*dns_ip); + return text; +} diff --git a/main/wifitexthelpers.h b/main/wifitexthelpers.h index 82f592a..c6f2872 100644 --- a/main/wifitexthelpers.h +++ b/main/wifitexthelpers.h @@ -1,233 +1,129 @@ #pragma once -// 3rdparty lib includes -#include -#include -#include -#include - // local includes #include "textinterface.h" -namespace { -class WifiStatusText : public virtual TextInterface { public: std::string text() const override { - return fmt::format("Status: {}", wifi_stack::toString(wifi_stack::get_sta_status())); }}; - -class WifiScanStatusText : public virtual TextInterface { public: std::string text() const override { - return fmt::format("ScanStatus: {}", wifi_stack::toString(wifi_stack::get_scan_status())); }}; - -class WifiHostnameText : public virtual TextInterface { +class WifiStatusText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "Hostname: "; - const char *hostname{}; - if (const auto result = esp_netif_get_hostname(wifi_stack::esp_netifs[ESP_IF_WIFI_STA], &hostname); result == ESP_OK) - if (hostname) - text += hostname; - return text; - } + std::string text() const override; }; -class WifiMacText : public virtual TextInterface { +class WifiScanStatusText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "MAC: "; - if (const auto result = wifi_stack::get_base_mac_addr()) - text += wifi_stack::toString(*result); - return text; - } + std::string text() const override; }; -class WifiSsidText : public virtual TextInterface { +class WifiHostnameText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "SSID: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const auto &result = wifi_stack::get_sta_ap_info(); result) - text += std::string_view{reinterpret_cast(result->ssid)}; - return text; - } + std::string text() const override; }; -class WifiBssidText : public virtual TextInterface { +class WifiMacText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "BSSID: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const auto &result = wifi_stack::get_sta_ap_info(); result) - text += wifi_stack::toString(wifi_stack::mac_t{result->bssid}); - return text; - } + std::string text() const override; }; -class WifiRssiText : public virtual TextInterface { +class WifiSsidText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "RSSI: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const auto &result = wifi_stack::get_sta_ap_info(); result) - text += fmt::format("{}dB", result->rssi); - return text; - } + std::string text() const override; }; -class WifiEncryptionTypeText : public virtual TextInterface { +class WifiBssidText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "encryptionType: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const auto &result = wifi_stack::get_sta_ap_info(); result) - text += wifi_stack::toString(result->authmode); - return text; - } + std::string text() const override; }; -class WifiPairwiseCipherText : public virtual TextInterface { +class WifiRssiText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "pairwiseCipher: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const auto &result = wifi_stack::get_sta_ap_info(); result) - text += wifi_stack::toString(result->pairwise_cipher); - return text; - } + std::string text() const override; }; -class WifiGroupCipherText : public virtual TextInterface { +class WifiEncryptionTypeText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "groupCipher: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const auto &result = wifi_stack::get_sta_ap_info(); result) - text += wifi_stack::toString(result->group_cipher); - return text; - } + std::string text() const override; }; -class WifiIpText : public virtual TextInterface { +class WifiPairwiseCipherText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "ip: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result) - text += wifi_stack::toString(result->ip); - return text; - } + std::string text() const override; }; -class WifiNetmaskText : public virtual TextInterface { +class WifiGroupCipherText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "netmask: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result) - text += wifi_stack::toString(result->netmask); - return text; - } + std::string text() const override; }; -class WifiGatewayText : public virtual TextInterface { +class WifiIpText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "gateway: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const auto result = wifi_stack::get_ip_info(TCPIP_ADAPTER_IF_STA); result) - text += wifi_stack::toString(result->gw); - return text; - } + std::string text() const override; }; -class WifiIpv6LinklocalText : public virtual TextInterface { +class WifiNetmaskText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "ipv6: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - { - esp_ip6_addr_t addr; - if (const auto result = esp_netif_get_ip6_linklocal(wifi_stack::esp_netifs[ESP_IF_WIFI_STA], &addr); result == ESP_OK) - text += wifi_stack::toString(addr); - } - return text; - } + std::string text() const override; }; -class WifiIpv6GlobalText : public virtual TextInterface { +class WifiGatewayText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "ipv6: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - { - esp_ip6_addr_t addr; - if (const auto result = esp_netif_get_ip6_global(wifi_stack::esp_netifs[ESP_IF_WIFI_STA], &addr); result == ESP_OK) - text += wifi_stack::toString(addr); - } - return text; - } + std::string text() const override; }; -class WifiDns0Text : public virtual TextInterface { +class WifiIpv6LinklocalText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "dns0: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const ip_addr_t *dns_ip = dns_getserver(0)) - text += wifi_stack::toString(*dns_ip); - return text; - } + std::string text() const override; }; -class WifiDns1Text : public virtual TextInterface { +class WifiIpv6GlobalText : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "dns1: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const ip_addr_t *dns_ip = dns_getserver(1)) - text += wifi_stack::toString(*dns_ip); - return text; - } + std::string text() const override; }; -class WifiDns2Text : public virtual TextInterface { +class WifiDns0Text : public virtual espgui::TextInterface +{ public: - std::string text() const override - { - std::string text = "dns2: "; - if (wifi_stack::get_sta_status() == wifi_stack::WiFiStaStatus::CONNECTED) - if (const ip_addr_t *dns_ip = dns_getserver(2)) - text += wifi_stack::toString(*dns_ip); - return text; - } + std::string text() const override; +}; + +class WifiDns1Text : public virtual espgui::TextInterface +{ +public: + std::string text() const override; +}; + +class WifiDns2Text : public virtual espgui::TextInterface +{ +public: + std::string text() const override; }; constexpr char TEXT_SOFTAPGETSTATIONNUM[] = "softAPgetStationNum: "; -using WifiSoftApGetStationNumText = StaticText; //StatusTextHelper +using WifiSoftApGetStationNumText = espgui::StaticText; //StatusTextHelper constexpr char TEXT_SOFTAPIP[] = "softAPIP: "; -using WifiSoftApIpText = StaticText; //StatusTextHelper +using WifiSoftApIpText = espgui::StaticText; //StatusTextHelper constexpr char TEXT_SOFTAPBROADCASTIP[] = "softAPBroadcastIP: "; -using WifiSoftApBroadcastIpText = StaticText; //StatusTextHelper +using WifiSoftApBroadcastIpText = espgui::StaticText; //StatusTextHelper constexpr char TEXT_SOFTAPNETWORKID[] = "softAPNetworkID: "; -using WifiSoftApNetworkIdText = StaticText; //StatusTextHelper +using WifiSoftApNetworkIdText = espgui::StaticText; //StatusTextHelper constexpr char TEXT_SOFTAPSUBNETCIDR[] = "softAPSubnetCIDR: "; -using WifiSoftApSubnetCidrText = StaticText; //StatusTextHelper +using WifiSoftApSubnetCidrText = espgui::StaticText; //StatusTextHelper constexpr char TEXT_SOFTAPIPV6[] = "softAPIPv6: "; -using WifiSoftApIpV6Text = StaticText; //StatusTextHelper +using WifiSoftApIpV6Text = espgui::StaticText; //StatusTextHelper constexpr char TEXT_SOFTAPGETHOSTNAME[] = "softAPgetHostname: "; -using WifiSoftApHostnameText = StaticText; //StatusTextHelper +using WifiSoftApHostnameText = espgui::StaticText; //StatusTextHelper constexpr char TEXT_SOFTAPMACADDRESS[] = "softAPmacAddress: "; -using WifiSoftApMacAddressText = StaticText; //StatusTextHelper -} +using WifiSoftApMacAddressText = espgui::StaticText; //StatusTextHelper