More rewrite

This commit is contained in:
2021-11-02 11:39:36 +01:00
parent 1de44c630b
commit 316f74ada8
21 changed files with 1057 additions and 895 deletions

View File

@ -0,0 +1,267 @@
#include "ble_bobby.h"
// esp-idf includes
#include <esp_log.h>
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<int16_t>();
if (blinkAnimation != newBlinkAnimation) blinkAnimation = newBlinkAnimation;
#endif
if (!simplified)
{
modes::remoteControlMode.setCommand(RemoteCommand{
.frontLeft = doc["fl"].as<int16_t>(),
.frontRight = doc["fr"].as<int16_t>(),
.backLeft = doc["bl"].as<int16_t>(),
.backRight = doc["br"].as<int16_t>()
});
}
}
#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<std::string>();
if (write_type == "wifi") {
const int index = doc["wifi_index"].as<int>();
ESP_LOGI(TAG, "[ble_config]: Set wifi%i: WiFi-SSID: %s, WiFi-Password: ***", doc["wifi_index"].as<int>(), doc["wifi_ssid"].as<const char*>());
stringSettings.wifis[index].ssid = doc["wifi_ssid"].as<std::string>();
stringSettings.wifis[index].key = doc["wifi_pass"].as<std::string>();
saveSettings();
} else {
const auto deserialized = deserializeJson(doc, val);
ESP_LOGW(TAG, "Unkown type %s -> json: %.*s %s", doc["type"].as<const char*>(), 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

View File

@ -1,8 +1,5 @@
#pragma once
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes
#include <ArduinoJson.h>
#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<int16_t>();
if (blinkAnimation != newBlinkAnimation) blinkAnimation = newBlinkAnimation;
#endif
if (!simplified)
{
modes::remoteControlMode.setCommand(RemoteCommand{
.frontLeft = doc["fl"].as<int16_t>(),
.frontRight = doc["fr"].as<int16_t>(),
.backLeft = doc["bl"].as<int16_t>(),
.backRight = doc["br"].as<int16_t>()
});
}
}
#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<std::string>();
if (write_type == "wifi") {
const int index = doc["wifi_index"].as<int>();
ESP_LOGI(TAG, "[ble_config]: Set wifi%i: WiFi-SSID: %s, WiFi-Password: ***", doc["wifi_index"].as<int>(), doc["wifi_ssid"].as<const char*>());
stringSettings.wifis[index].ssid = doc["wifi_ssid"].as<std::string>();
stringSettings.wifis[index].key = doc["wifi_pass"].as<std::string>();
saveSettings();
} else {
const auto deserialized = deserializeJson(doc, val);
ESP_LOGW(TAG, "Unkown type %s -> json: %.*s %s", doc["type"].as<const char*>(), 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
}

View File

@ -0,0 +1,251 @@
#include "cloud.h"
// esp-idf includes
#include <esp_log.h>
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<espcpputils::ticks>(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

View File

@ -1,8 +1,5 @@
#pragma once
// esp-idf includes
#include <esp_log.h>
// 3rdparty lib includes
#include <wrappers/websocket_client.h>
#include <espwifistack.h>
@ -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<espcpputils::ticks>(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

View File

@ -6,15 +6,38 @@
#include "actions/switchscreenaction.h"
#include "icons/back.h"
#include "esptexthelpers.h"
#include "displays/menus/settingsmenu.h"
#ifdef FEATURE_OTA
#include <espasyncota.h>
#include <esp_ota_ops.h>
#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<makeComponent<MenuItem, currentVersionText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, CurrentVersionText, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapTotal8Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapFree8Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, HeapMinFree8Text, StaticFont<2>, DisabledColor, DummyAction>>();

View File

@ -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<TEXT_ABOUT>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_ABOUT>
{
public:
AboutMenu();
void back() override;
};
} // namespace

View File

@ -12,11 +12,6 @@
#include "accessors/settingsaccessors.h"
#include "texts.h"
// forward declares
namespace {
class WifiSettingsMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -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
{

View File

@ -13,12 +13,6 @@
#include "accessors/wifiaccessors.h"
#include "texts.h"
// forward declares
namespace {
class GenericWifiSettingsMenu;
class WifiSettingsMenu;
} // namespace
using namespace espgui;
namespace {

View File

@ -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<int16_t>,
espgui::StaticText<TEXT_IMOTMAX>,
IMotMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<LimitsSettingsMenu>>,
espgui::SwitchScreenAction<LimitsSettingsMenu>
>;
using IDcMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_IDCMAX>,
IDcMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<LimitsSettingsMenu>>,
espgui::SwitchScreenAction<LimitsSettingsMenu>
>;
using NMotMaxKmhChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_NMOTMAXKMH>,
NMotMaxKmhAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<LimitsSettingsMenu>>,
espgui::SwitchScreenAction<LimitsSettingsMenu>
>;
using NMotMaxRpmChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_NMOTMAX>,
NMotMaxRpmAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<LimitsSettingsMenu>>,
espgui::SwitchScreenAction<LimitsSettingsMenu>
>;
using FieldWeakMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_FIELDWEAKMAX>,
FieldWeakMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<LimitsSettingsMenu>>,
espgui::SwitchScreenAction<LimitsSettingsMenu>
>;
using PhaseAdvMaxChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int16_t>,
espgui::StaticText<TEXT_PHASEADVMAX>,
PhaseAdvMaxAccessor,
espgui::BackActionInterface<espgui::SwitchScreenAction<LimitsSettingsMenu>>,
espgui::SwitchScreenAction<LimitsSettingsMenu>
>;
} // namespace
using namespace espgui;
LimitsSettingsMenu::LimitsSettingsMenu()
{
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_IMOTMAX, IMotMaxAccessor>, SwitchScreenAction<IMotMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_IDCMAX, IDcMaxAccessor>, SwitchScreenAction<IDcMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_NMOTMAXKMH, NMotMaxKmhAccessor>, SwitchScreenAction<NMotMaxKmhChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_NMOTMAX, NMotMaxRpmAccessor>, SwitchScreenAction<NMotMaxRpmChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_FIELDWEAKMAX, FieldWeakMaxAccessor>, SwitchScreenAction<FieldWeakMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PHASEADVMAX, PhaseAdvMaxAccessor>, SwitchScreenAction<PhaseAdvMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void LimitsSettingsMenu::back()
{
switchScreen<SettingsMenu>();
}

View File

@ -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<int16_t>,
StaticText<TEXT_IMOTMAX>,
IMotMaxAccessor,
BackActionInterface<SwitchScreenAction<LimitsSettingsMenu>>,
SwitchScreenAction<LimitsSettingsMenu>
>;
using IDcMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_IDCMAX>,
IDcMaxAccessor,
BackActionInterface<SwitchScreenAction<LimitsSettingsMenu>>,
SwitchScreenAction<LimitsSettingsMenu>
>;
using NMotMaxKmhChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_NMOTMAXKMH>,
NMotMaxKmhAccessor,
BackActionInterface<SwitchScreenAction<LimitsSettingsMenu>>,
SwitchScreenAction<LimitsSettingsMenu>
>;
using NMotMaxRpmChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_NMOTMAX>,
NMotMaxRpmAccessor,
BackActionInterface<SwitchScreenAction<LimitsSettingsMenu>>,
SwitchScreenAction<LimitsSettingsMenu>
>;
using FieldWeakMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_FIELDWEAKMAX>,
FieldWeakMaxAccessor,
BackActionInterface<SwitchScreenAction<LimitsSettingsMenu>>,
SwitchScreenAction<LimitsSettingsMenu>
>;
using PhaseAdvMaxChangeScreen = makeComponent<
ChangeValueDisplay<int16_t>,
StaticText<TEXT_PHASEADVMAX>,
PhaseAdvMaxAccessor,
BackActionInterface<SwitchScreenAction<LimitsSettingsMenu>>,
SwitchScreenAction<LimitsSettingsMenu>
>;
class LimitsSettingsMenu :
public MenuDisplay,
public StaticText<TEXT_LIMITSSETTINGS>,
public BackActionInterface<SwitchScreenAction<SettingsMenu>>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_LIMITSSETTINGS>
{
public:
LimitsSettingsMenu()
{
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_IMOTMAX, IMotMaxAccessor>, SwitchScreenAction<IMotMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_IDCMAX, IDcMaxAccessor>, SwitchScreenAction<IDcMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_NMOTMAXKMH, NMotMaxKmhAccessor>, SwitchScreenAction<NMotMaxKmhChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_NMOTMAX, NMotMaxRpmAccessor>, SwitchScreenAction<NMotMaxRpmChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_FIELDWEAKMAX, FieldWeakMaxAccessor>, SwitchScreenAction<FieldWeakMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PHASEADVMAX, PhaseAdvMaxAccessor>, SwitchScreenAction<PhaseAdvMaxChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
LimitsSettingsMenu();
void back() override;
};
} // namespace

View File

@ -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<int8_t>,
espgui::StaticText<TEXT_PINDIGIT0>,
LockscreenPinDigitAccessor<0>,
espgui::BackActionInterface<espgui::SwitchScreenAction<LockscreenSettingsMenu>>,
espgui::SwitchScreenAction<LockscreenSettingsMenu>
>;
using LockscreenPinDigit1ChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int8_t>,
espgui::StaticText<TEXT_PINDIGIT1>,
LockscreenPinDigitAccessor<1>,
espgui::BackActionInterface<espgui::SwitchScreenAction<LockscreenSettingsMenu>>,
espgui::SwitchScreenAction<LockscreenSettingsMenu>
>;
using LockscreenPinDigit2ChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int8_t>,
espgui::StaticText<TEXT_PINDIGIT2>,
LockscreenPinDigitAccessor<2>,
espgui::BackActionInterface<espgui::SwitchScreenAction<LockscreenSettingsMenu>>,
espgui::SwitchScreenAction<LockscreenSettingsMenu>
>;
using LockscreenPinDigit3ChangeScreen = espgui::makeComponent<
espgui::ChangeValueDisplay<int8_t>,
espgui::StaticText<TEXT_PINDIGIT3>,
LockscreenPinDigitAccessor<3>,
espgui::BackActionInterface<espgui::SwitchScreenAction<LockscreenSettingsMenu>>,
espgui::SwitchScreenAction<LockscreenSettingsMenu>
>;
} // namespace
using namespace espgui;
LockscreenSettingsMenu::LockscreenSettingsMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ALLOWPRESETSWITCH>, ToggleBoolAction, CheckboxIcon, LockscreenAllowPresetSwitchAccessor>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT0, LockscreenPinDigitAccessor<0>>, SwitchScreenAction<LockscreenPinDigit0ChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT1, LockscreenPinDigitAccessor<1>>, SwitchScreenAction<LockscreenPinDigit1ChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT2, LockscreenPinDigitAccessor<2>>, SwitchScreenAction<LockscreenPinDigit2ChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT3, LockscreenPinDigitAccessor<3>>, SwitchScreenAction<LockscreenPinDigit3ChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void LockscreenSettingsMenu::back()
{
switchScreen<BoardcomputerHardwareSettingsMenu>();
}

View File

@ -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<int8_t>,
StaticText<TEXT_PINDIGIT0>,
LockscreenPinDigitAccessor<0>,
BackActionInterface<SwitchScreenAction<LockscreenSettingsMenu>>,
SwitchScreenAction<LockscreenSettingsMenu>
>;
using LockscreenPinDigit1ChangeScreen = makeComponent<
ChangeValueDisplay<int8_t>,
StaticText<TEXT_PINDIGIT1>,
LockscreenPinDigitAccessor<1>,
BackActionInterface<SwitchScreenAction<LockscreenSettingsMenu>>,
SwitchScreenAction<LockscreenSettingsMenu>
>;
using LockscreenPinDigit2ChangeScreen = makeComponent<
ChangeValueDisplay<int8_t>,
StaticText<TEXT_PINDIGIT2>,
LockscreenPinDigitAccessor<2>,
BackActionInterface<SwitchScreenAction<LockscreenSettingsMenu>>,
SwitchScreenAction<LockscreenSettingsMenu>
>;
using LockscreenPinDigit3ChangeScreen = makeComponent<
ChangeValueDisplay<int8_t>,
StaticText<TEXT_PINDIGIT3>,
LockscreenPinDigitAccessor<3>,
BackActionInterface<SwitchScreenAction<LockscreenSettingsMenu>>,
SwitchScreenAction<LockscreenSettingsMenu>
>;
class LockscreenSettingsMenu :
public MenuDisplay,
public StaticText<TEXT_LOCKSCREENSETTINGS>,
public BackActionInterface<SwitchScreenAction<BoardcomputerHardwareSettingsMenu>>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_LOCKSCREENSETTINGS>
{
public:
LockscreenSettingsMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ALLOWPRESETSWITCH>, ToggleBoolAction, CheckboxIcon, LockscreenAllowPresetSwitchAccessor>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT0, LockscreenPinDigitAccessor<0>>, SwitchScreenAction<LockscreenPinDigit0ChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT1, LockscreenPinDigitAccessor<1>>, SwitchScreenAction<LockscreenPinDigit1ChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT2, LockscreenPinDigitAccessor<2>>, SwitchScreenAction<LockscreenPinDigit2ChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_PINDIGIT3, LockscreenPinDigitAccessor<3>>, SwitchScreenAction<LockscreenPinDigit3ChangeScreen>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
LockscreenSettingsMenu();
void back() override;
};
} // namespace

View File

@ -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<makeComponent<MenuItem, StaticText<TEXT_WIFISTAENABLED>, ToggleBoolAction, CheckboxIcon, WifiStaEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFITRIGGERSCAN>, WifiScanAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISCANRESULTS>, SwitchScreenAction<WifiScanMenu>, StaticMenuItemIcon<&bobbyicons::scan>>>();
constructMenuItem<makeComponent<MenuItem, WifiStatusText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiScanStatusText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiHostnameText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiMacText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSsidText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiBssidText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiRssiText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiEncryptionTypeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiPairwiseCipherText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiGroupCipherText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiIpText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiNetmaskText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiGatewayText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiIpv6LinklocalText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiIpv6GlobalText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiDns0Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiDns1Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiDns2Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void StationWifiSettingsMenu::back()
{
switchScreen<WifiSettingsMenu>();
}

View File

@ -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<TEXT_STATIONWIFISETTINGS>,
public BackActionInterface<SwitchScreenAction<WifiSettingsMenu>>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_STATIONWIFISETTINGS>
{
public:
StationWifiSettingsMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISTAENABLED>, ToggleBoolAction, CheckboxIcon, WifiStaEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFITRIGGERSCAN>, WifiScanAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_WIFISCANRESULTS>, SwitchScreenAction<WifiScanMenu>, StaticMenuItemIcon<&bobbyicons::scan>>>();
constructMenuItem<makeComponent<MenuItem, WifiStatusText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiScanStatusText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiHostnameText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiMacText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiSsidText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiBssidText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiRssiText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiEncryptionTypeText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiPairwiseCipherText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiGroupCipherText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiIpText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiNetmaskText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiGatewayText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiIpv6LinklocalText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiIpv6GlobalText, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiDns0Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiDns1Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, WifiDns2Text, StaticFont<2>, DisabledColor, DummyAction>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<WifiSettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
StationWifiSettingsMenu();
void back() override;
};
} // namespace

View File

@ -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;

View File

@ -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<makeComponent<MenuItem, StaticText<TEXT_GENERICWIFISETTINGS>, SwitchScreenAction<GenericWifiSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATIONWIFISETTINGS>, SwitchScreenAction<StationWifiSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ACCESSPOINTWIFISETTINGS>, SwitchScreenAction<AccessPointWifiSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void WifiSettingsMenu::back()
{
switchScreen<SettingsMenu>();
}

View File

@ -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<TEXT_WIFISETTINGS>,
public BackActionInterface<SwitchScreenAction<SettingsMenu>>
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_WIFISETTINGS>
{
public:
WifiSettingsMenu()
{
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_GENERICWIFISETTINGS>, SwitchScreenAction<GenericWifiSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_STATIONWIFISETTINGS>, SwitchScreenAction<StationWifiSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ACCESSPOINTWIFISETTINGS>, SwitchScreenAction<AccessPointWifiSettingsMenu>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
WifiSettingsMenu();
void back() override;
};
} // namespace

View File

@ -9,6 +9,8 @@
#include "espchrono.h"
#include "ledstripdefines.h"
using namespace std::chrono_literals;
namespace {
enum Bobbycar_Side {

View File

@ -0,0 +1,167 @@
#include "wifitexthelpers.h"
// 3rdparty lib includes
#include <fmt/core.h>
#include <espwifistack.h>
#include <esp_netif.h>
#include <lwip/dns.h>
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<const char*>(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;
}

View File

@ -1,233 +1,129 @@
#pragma once
// 3rdparty lib includes
#include <fmt/core.h>
#include <espwifistack.h>
#include <esp_netif.h>
#include <lwip/dns.h>
// 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<const char*>(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<TEXT_SOFTAPGETSTATIONNUM>; //StatusTextHelper<TEXT_SOFTAPGETSTATIONNUM, &WiFi.softAPgetStationNum>
using WifiSoftApGetStationNumText = espgui::StaticText<TEXT_SOFTAPGETSTATIONNUM>; //StatusTextHelper<TEXT_SOFTAPGETSTATIONNUM, &WiFi.softAPgetStationNum>
constexpr char TEXT_SOFTAPIP[] = "softAPIP: ";
using WifiSoftApIpText = StaticText<TEXT_SOFTAPIP>; //StatusTextHelper<TEXT_SOFTAPIP, &WiFi.softAPIP>
using WifiSoftApIpText = espgui::StaticText<TEXT_SOFTAPIP>; //StatusTextHelper<TEXT_SOFTAPIP, &WiFi.softAPIP>
constexpr char TEXT_SOFTAPBROADCASTIP[] = "softAPBroadcastIP: ";
using WifiSoftApBroadcastIpText = StaticText<TEXT_SOFTAPBROADCASTIP>; //StatusTextHelper<TEXT_SOFTAPBROADCASTIP, &WiFi.softAPBroadcastIP>
using WifiSoftApBroadcastIpText = espgui::StaticText<TEXT_SOFTAPBROADCASTIP>; //StatusTextHelper<TEXT_SOFTAPBROADCASTIP, &WiFi.softAPBroadcastIP>
constexpr char TEXT_SOFTAPNETWORKID[] = "softAPNetworkID: ";
using WifiSoftApNetworkIdText = StaticText<TEXT_SOFTAPNETWORKID>; //StatusTextHelper<TEXT_SOFTAPNETWORKID, &WiFi.softAPNetworkID>
using WifiSoftApNetworkIdText = espgui::StaticText<TEXT_SOFTAPNETWORKID>; //StatusTextHelper<TEXT_SOFTAPNETWORKID, &WiFi.softAPNetworkID>
constexpr char TEXT_SOFTAPSUBNETCIDR[] = "softAPSubnetCIDR: ";
using WifiSoftApSubnetCidrText = StaticText<TEXT_SOFTAPSUBNETCIDR>; //StatusTextHelper<TEXT_SOFTAPSUBNETCIDR, &WiFi.softAPSubnetCIDR>
using WifiSoftApSubnetCidrText = espgui::StaticText<TEXT_SOFTAPSUBNETCIDR>; //StatusTextHelper<TEXT_SOFTAPSUBNETCIDR, &WiFi.softAPSubnetCIDR>
constexpr char TEXT_SOFTAPIPV6[] = "softAPIPv6: ";
using WifiSoftApIpV6Text = StaticText<TEXT_SOFTAPIPV6>; //StatusTextHelper<TEXT_SOFTAPIPV6, &WiFi.softAPIPv6>
using WifiSoftApIpV6Text = espgui::StaticText<TEXT_SOFTAPIPV6>; //StatusTextHelper<TEXT_SOFTAPIPV6, &WiFi.softAPIPv6>
constexpr char TEXT_SOFTAPGETHOSTNAME[] = "softAPgetHostname: ";
using WifiSoftApHostnameText = StaticText<TEXT_SOFTAPGETHOSTNAME>; //StatusTextHelper<TEXT_SOFTAPGETHOSTNAME, &WiFi.softAPgetHostname>
using WifiSoftApHostnameText = espgui::StaticText<TEXT_SOFTAPGETHOSTNAME>; //StatusTextHelper<TEXT_SOFTAPGETHOSTNAME, &WiFi.softAPgetHostname>
constexpr char TEXT_SOFTAPMACADDRESS[] = "softAPmacAddress: ";
using WifiSoftApMacAddressText = StaticText<TEXT_SOFTAPMACADDRESS>; //StatusTextHelper<TEXT_SOFTAPMACADDRESS, &WiFi.softAPmacAddress>
}
using WifiSoftApMacAddressText = espgui::StaticText<TEXT_SOFTAPMACADDRESS>; //StatusTextHelper<TEXT_SOFTAPMACADDRESS, &WiFi.softAPmacAddress>