Reconstructing parts of the webserver again
This commit is contained in:
@ -40,7 +40,7 @@ add_definitions(
|
|||||||
-DDEFAULT_FIELDADVMAX=40
|
-DDEFAULT_FIELDADVMAX=40
|
||||||
-DDEVICE_PREFIX=bobbyquad
|
-DDEVICE_PREFIX=bobbyquad
|
||||||
-DAP_PASSWORD=Passwort_123
|
-DAP_PASSWORD=Passwort_123
|
||||||
# -DFEATURE_WEBSERVER
|
-DFEATURE_WEBSERVER
|
||||||
# -DFEATURE_ARDUINOOTA
|
# -DFEATURE_ARDUINOOTA
|
||||||
# -DFEATURE_WEBOTA
|
# -DFEATURE_WEBOTA
|
||||||
-DFEATURE_DPAD_5WIRESW
|
-DFEATURE_DPAD_5WIRESW
|
||||||
|
@ -178,12 +178,9 @@ set(sources
|
|||||||
|
|
||||||
set(dependencies
|
set(dependencies
|
||||||
libsodium freertos nvs_flash esp_http_server esp_https_ota mdns app_update esp_system esp_websocket_client driver
|
libsodium freertos nvs_flash esp_http_server esp_https_ota mdns app_update esp_system esp_websocket_client driver
|
||||||
arduino-esp32 ArduinoJson
|
arduino-esp32 ArduinoJson esp-nimble-cpp
|
||||||
# AsyncTCP
|
|
||||||
bobbycar-protocol cpputils cxx-ring-buffer date
|
bobbycar-protocol cpputils cxx-ring-buffer date
|
||||||
# ESPAsyncWebServer
|
|
||||||
espchrono espcpputils espwifistack expected fmt TFT_eSPI
|
espchrono espcpputils espwifistack expected fmt TFT_eSPI
|
||||||
esp-nimble-cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
idf_component_register(
|
idf_component_register(
|
||||||
|
@ -224,7 +224,13 @@ void CalibrateDisplay::redraw()
|
|||||||
void CalibrateDisplay::stop()
|
void CalibrateDisplay::stop()
|
||||||
{
|
{
|
||||||
if (currentMode == &m_mode)
|
if (currentMode == &m_mode)
|
||||||
|
{
|
||||||
|
// to avoid crash after deconstruction
|
||||||
|
m_mode.stop();
|
||||||
|
lastMode = nullptr;
|
||||||
|
|
||||||
currentMode = m_oldMode;
|
currentMode = m_oldMode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CalibrateDisplay::rotate(int offset)
|
void CalibrateDisplay::rotate(int offset)
|
||||||
|
@ -143,7 +143,13 @@ void Lockscreen::stop()
|
|||||||
Base::stop();
|
Base::stop();
|
||||||
|
|
||||||
if (currentMode == &m_mode)
|
if (currentMode == &m_mode)
|
||||||
|
{
|
||||||
|
// to avoid crash after deconstruction
|
||||||
|
m_mode.stop();
|
||||||
|
lastMode = nullptr;
|
||||||
|
|
||||||
currentMode = m_oldMode;
|
currentMode = m_oldMode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lockscreen::confirm()
|
void Lockscreen::confirm()
|
||||||
|
@ -86,6 +86,7 @@ BluetoothSerial bluetoothSerial;
|
|||||||
|
|
||||||
TFT_eSPI tft = TFT_eSPI();
|
TFT_eSPI tft = TFT_eSPI();
|
||||||
|
|
||||||
|
ModeInterface *lastMode{};
|
||||||
ModeInterface *currentMode{};
|
ModeInterface *currentMode{};
|
||||||
|
|
||||||
std::unique_ptr<Display> currentDisplay;
|
std::unique_ptr<Display> currentDisplay;
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
constexpr const char * const TAG = "BOBBY";
|
||||||
|
|
||||||
// system includes
|
// system includes
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
@ -100,7 +102,6 @@ using namespace std::chrono_literals;
|
|||||||
#include "wifi_bobbycar.h"
|
#include "wifi_bobbycar.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
ModeInterface *lastMode{};
|
|
||||||
std::optional<espchrono::millis_clock::time_point> lastPotiRead;
|
std::optional<espchrono::millis_clock::time_point> lastPotiRead;
|
||||||
std::optional<espchrono::millis_clock::time_point> lastModeUpdate;
|
std::optional<espchrono::millis_clock::time_point> lastModeUpdate;
|
||||||
std::optional<espchrono::millis_clock::time_point> lastStatsUpdate;
|
std::optional<espchrono::millis_clock::time_point> lastStatsUpdate;
|
||||||
|
506
main/webserver.h
506
main/webserver.h
@ -1,9 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// 3rdparty lib includes
|
// system includes
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
// esp-idf includes
|
||||||
#ifdef FEATURE_WEBSERVER
|
#ifdef FEATURE_WEBSERVER
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <esp_http_server.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <esp_log.h>
|
||||||
|
|
||||||
// local includes
|
// local includes
|
||||||
#include "screens.h"
|
#include "screens.h"
|
||||||
@ -13,237 +17,76 @@
|
|||||||
#include "displays/updatedisplay.h"
|
#include "displays/updatedisplay.h"
|
||||||
//#include "esputils.h"
|
//#include "esputils.h"
|
||||||
#include "buttons.h"
|
#include "buttons.h"
|
||||||
|
#include "espcppmacros.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
#ifdef FEATURE_WEBSERVER
|
#ifdef FEATURE_WEBSERVER
|
||||||
AsyncWebServer webServer{80};
|
httpd_handle_t httpdHandle;
|
||||||
|
|
||||||
bool shouldReboot;
|
std::atomic<bool> shouldReboot;
|
||||||
|
|
||||||
class HtmlTag {
|
class HtmlTag {
|
||||||
public:
|
public:
|
||||||
HtmlTag(const char *tagName, AsyncResponseStream *response) :
|
HtmlTag(const char *tagName, std::string &body) :
|
||||||
m_tagName{tagName},
|
m_tagName{tagName},
|
||||||
m_response{response}
|
m_body{body}
|
||||||
{
|
{
|
||||||
m_response->printf("<%s>", m_tagName);
|
m_body += '<';
|
||||||
|
m_body += m_tagName;
|
||||||
|
m_body += '>';
|
||||||
}
|
}
|
||||||
|
|
||||||
~HtmlTag()
|
~HtmlTag()
|
||||||
{
|
{
|
||||||
m_response->printf("</%s>", m_tagName);
|
m_body += "</";
|
||||||
|
m_body += m_tagName;
|
||||||
|
m_body += '>';
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char * const m_tagName;
|
const char * const m_tagName;
|
||||||
AsyncResponseStream * const m_response;
|
std::string &m_body;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
esp_err_t webserver_root_handler(httpd_req_t *req);
|
||||||
|
esp_err_t webserver_up_handler(httpd_req_t *req);
|
||||||
|
esp_err_t webserver_down_handler(httpd_req_t *req);
|
||||||
|
esp_err_t webserver_confirm_handler(httpd_req_t *req);
|
||||||
|
esp_err_t webserver_back_handler(httpd_req_t *req);
|
||||||
|
esp_err_t webserver_triggerItem_handler(httpd_req_t *req);
|
||||||
|
esp_err_t webserver_setValue_handler(httpd_req_t *req);
|
||||||
|
esp_err_t webserver_reboot_handler(httpd_req_t *req);
|
||||||
|
|
||||||
void initWebserver()
|
void initWebserver()
|
||||||
{
|
{
|
||||||
shouldReboot = false;
|
shouldReboot = false;
|
||||||
|
|
||||||
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", "*");
|
{
|
||||||
|
httpd_config_t httpConfig HTTPD_DEFAULT_CONFIG();
|
||||||
|
httpConfig.core_id = 1;
|
||||||
|
|
||||||
webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
const auto result = httpd_start(&httpdHandle, &httpConfig);
|
||||||
AsyncResponseStream *response = request->beginResponseStream("text/html");
|
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "httpd_start(): %s", esp_err_to_name(result));
|
||||||
|
if (result != ESP_OK)
|
||||||
{
|
|
||||||
HtmlTag htmlTag{"html", response};
|
|
||||||
|
|
||||||
{
|
|
||||||
HtmlTag headTag{"head", response};
|
|
||||||
|
|
||||||
{
|
|
||||||
HtmlTag titleTag{"title", response};
|
|
||||||
response->print("Bobbycar remote");
|
|
||||||
}
|
|
||||||
|
|
||||||
response->print("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\" />");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
HtmlTag bodyTag{"body", response};
|
|
||||||
|
|
||||||
{
|
|
||||||
HtmlTag h1Tag{"h1", response};
|
|
||||||
response->print("Bobbycar remote");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
HtmlTag pTag{"p", response};
|
|
||||||
response->print("<a href=\"/up\">Up</a> "
|
|
||||||
"<a href=\"/down\">Down</a> "
|
|
||||||
"<a href=\"/confirm\">Confirm</a> "
|
|
||||||
"<a href=\"/back\">Back</a>");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auto constCurrentDisplay = static_cast<const Display *>(currentDisplay.get()))
|
|
||||||
{
|
|
||||||
if (const auto *textInterface = constCurrentDisplay->asTextInterface())
|
|
||||||
{
|
|
||||||
HtmlTag h2Tag{"h2", response};
|
|
||||||
response->print(textInterface->text().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto *menuDisplay = constCurrentDisplay->asMenuDisplay())
|
|
||||||
{
|
|
||||||
HtmlTag ulTag{"ul", response};
|
|
||||||
|
|
||||||
int i{0};
|
|
||||||
menuDisplay->runForEveryMenuItem([&,selectedIndex=menuDisplay->selectedIndex()](const MenuItem &menuItem){
|
|
||||||
response->print("<li");
|
|
||||||
|
|
||||||
if (i == selectedIndex)
|
|
||||||
response->print(" style=\"border: 1px solid black;\"");
|
|
||||||
|
|
||||||
response->print("><a href=\"/triggerItem?index=");
|
|
||||||
response->print(i);
|
|
||||||
response->print("\">");
|
|
||||||
response->print(menuItem.text().c_str());
|
|
||||||
response->print("</a></li>");
|
|
||||||
|
|
||||||
i++;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else if (const auto *changeValueDisplay = constCurrentDisplay->asChangeValueDisplayInterface())
|
|
||||||
{
|
|
||||||
response->print("<form action=\"/setValue\" method=\"GET\">");
|
|
||||||
response->print(("<input type=\"number\" name=\"value\" value=\"" + std::to_string(changeValueDisplay->shownValue()) + "\" />").c_str());
|
|
||||||
response->print("<button type=\"submit\">Update</button>");
|
|
||||||
response->print("</form>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response->print("No web control implemented for current display.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
response->print("Currently no screen instantiated.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
request->send(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
webServer.on("/up", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
||||||
InputDispatcher::rotate(-1);
|
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
|
||||||
response->addHeader("Location", "/");
|
|
||||||
request->send(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
webServer.on("/down", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
||||||
InputDispatcher::rotate(1);
|
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
|
||||||
response->addHeader("Location", "/");
|
|
||||||
request->send(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
webServer.on("/confirm", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
||||||
InputDispatcher::confirmButton(true);
|
|
||||||
InputDispatcher::confirmButton(false);
|
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
|
||||||
response->addHeader("Location", "/");
|
|
||||||
request->send(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
webServer.on("/back", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
||||||
InputDispatcher::backButton(true);
|
|
||||||
InputDispatcher::backButton(false);
|
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
|
||||||
response->addHeader("Location", "/");
|
|
||||||
request->send(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
webServer.on("/triggerItem", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
||||||
if (!request->hasArg("index"))
|
|
||||||
{
|
|
||||||
request->send(400, "text/plain", "index parameter missing");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!currentDisplay)
|
|
||||||
{
|
|
||||||
request->send(400, "text/plain", "currentDisplay is null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *menuDisplay = currentDisplay->asMenuDisplay();
|
|
||||||
if (!menuDisplay)
|
|
||||||
{
|
|
||||||
request->send(400, "text/plain", "currentDisplay is not a menu display");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto indexStr = request->arg("index");
|
|
||||||
|
|
||||||
char *ptr;
|
|
||||||
const auto index = std::strtol(std::begin(indexStr), &ptr, 10);
|
|
||||||
|
|
||||||
if (ptr != std::end(indexStr))
|
|
||||||
{
|
|
||||||
request->send(400, "text/plain", "index could not be parsed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index < 0 || index >= menuDisplay->menuItemCount())
|
|
||||||
{
|
|
||||||
request->send(400, "text/plain", "index out of range");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
menuDisplay->getMenuItem(index).triggered();
|
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
|
||||||
response->addHeader("Location", "/");
|
|
||||||
request->send(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
webServer.on("/setValue", HTTP_GET, [](AsyncWebServerRequest *request){
|
|
||||||
if (!request->hasArg("value"))
|
|
||||||
{
|
|
||||||
request->send(400, "text/plain", "value parameter missing");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currentDisplay)
|
|
||||||
{
|
|
||||||
request->send(400, "text/plain", "currentDisplay is null");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto *changeValueDisplay = currentDisplay->asChangeValueDisplayInterface();
|
|
||||||
if (!changeValueDisplay)
|
|
||||||
{
|
|
||||||
request->send(400, "text/plain", "currentDisplay is not a change value display");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto valueStr = request->arg("value");
|
|
||||||
|
|
||||||
char *ptr;
|
|
||||||
const auto value = std::strtol(std::begin(valueStr), &ptr, 10);
|
|
||||||
|
|
||||||
if (ptr != std::end(valueStr))
|
|
||||||
{
|
|
||||||
request->send(400, "text/plain", "value could not be parsed");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
changeValueDisplay->setShownValue(value);
|
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
|
||||||
response->addHeader("Location", "/");
|
|
||||||
request->send(response);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
for (const httpd_uri_t &uri : {
|
||||||
|
httpd_uri_t { .uri = "/", .method = HTTP_GET, .handler = webserver_root_handler, .user_ctx = NULL },
|
||||||
|
httpd_uri_t { .uri = "/up", .method = HTTP_GET, .handler = webserver_up_handler, .user_ctx = NULL },
|
||||||
|
httpd_uri_t { .uri = "/down", .method = HTTP_GET, .handler = webserver_down_handler, .user_ctx = NULL },
|
||||||
|
httpd_uri_t { .uri = "/confirm", .method = HTTP_GET, .handler = webserver_confirm_handler, .user_ctx = NULL },
|
||||||
|
httpd_uri_t { .uri = "/back", .method = HTTP_GET, .handler = webserver_back_handler, .user_ctx = NULL },
|
||||||
|
httpd_uri_t { .uri = "/triggerItem", .method = HTTP_GET, .handler = webserver_triggerItem_handler, .user_ctx = NULL },
|
||||||
|
httpd_uri_t { .uri = "/setValue", .method = HTTP_GET, .handler = webserver_setValue_handler, .user_ctx = NULL },
|
||||||
|
httpd_uri_t { .uri = "/reboot", .method = HTTP_GET, .handler = webserver_reboot_handler, .user_ctx = NULL }
|
||||||
|
})
|
||||||
|
{
|
||||||
|
const auto result = httpd_register_uri_handler(httpdHandle, &uri);
|
||||||
|
ESP_LOG_LEVEL_LOCAL((result == ESP_OK ? ESP_LOG_INFO : ESP_LOG_ERROR), TAG, "httpd_register_uri_handler() for %s: %s", uri.uri, esp_err_to_name(result));
|
||||||
|
//if (result != ESP_OK)
|
||||||
|
// return result;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef FEATURE_WEBOTA
|
#ifdef FEATURE_WEBOTA
|
||||||
webServer.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
webServer.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
@ -338,8 +181,6 @@ void initWebserver()
|
|||||||
webServer.on("/updateCode", HTTP_POST, handleUpdate, createHandleUpdtateUpload((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000, U_FLASH));
|
webServer.on("/updateCode", HTTP_POST, handleUpdate, createHandleUpdtateUpload((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000, U_FLASH));
|
||||||
webServer.on("/updateData", HTTP_POST, handleUpdate, createHandleUpdtateUpload(UPDATE_SIZE_UNKNOWN, U_SPIFFS));
|
webServer.on("/updateData", HTTP_POST, handleUpdate, createHandleUpdtateUpload(UPDATE_SIZE_UNKNOWN, U_SPIFFS));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
webServer.begin();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleWebserver()
|
void handleWebserver()
|
||||||
@ -347,8 +188,253 @@ void handleWebserver()
|
|||||||
if (shouldReboot)
|
if (shouldReboot)
|
||||||
{
|
{
|
||||||
shouldReboot = false;
|
shouldReboot = false;
|
||||||
ESP.restart();
|
esp_restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t webserver_root_handler(httpd_req_t *req)
|
||||||
|
{
|
||||||
|
std::string body;
|
||||||
|
|
||||||
|
{
|
||||||
|
HtmlTag htmlTag{"html", body};
|
||||||
|
|
||||||
|
{
|
||||||
|
HtmlTag headTag{"head", body};
|
||||||
|
|
||||||
|
{
|
||||||
|
HtmlTag titleTag{"title", body};
|
||||||
|
body += ("Bobbycar remote");
|
||||||
|
}
|
||||||
|
|
||||||
|
body += ("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\" />");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
HtmlTag bodyTag{"body", body};
|
||||||
|
|
||||||
|
{
|
||||||
|
HtmlTag h1Tag{"h1", body};
|
||||||
|
body += ("Bobbycar remote");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
HtmlTag pTag{"p", body};
|
||||||
|
body += ("<a href=\"/up\">Up</a> "
|
||||||
|
"<a href=\"/down\">Down</a> "
|
||||||
|
"<a href=\"/confirm\">Confirm</a> "
|
||||||
|
"<a href=\"/back\">Back</a>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auto constCurrentDisplay = static_cast<const Display *>(currentDisplay.get()))
|
||||||
|
{
|
||||||
|
if (const auto *textInterface = constCurrentDisplay->asTextInterface())
|
||||||
|
{
|
||||||
|
HtmlTag h2Tag{"h2", body};
|
||||||
|
body += (textInterface->text().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto *menuDisplay = constCurrentDisplay->asMenuDisplay())
|
||||||
|
{
|
||||||
|
HtmlTag ulTag{"ul", body};
|
||||||
|
|
||||||
|
int i{0};
|
||||||
|
menuDisplay->runForEveryMenuItem([&,selectedIndex=menuDisplay->selectedIndex()](const MenuItem &menuItem){
|
||||||
|
body += ("<li");
|
||||||
|
|
||||||
|
if (i == selectedIndex)
|
||||||
|
body += (" style=\"border: 1px solid black;\"");
|
||||||
|
|
||||||
|
body += ("><a href=\"/triggerItem?index=");
|
||||||
|
body += (i);
|
||||||
|
body += ("\">");
|
||||||
|
body += (menuItem.text().c_str());
|
||||||
|
body += ("</a></li>");
|
||||||
|
|
||||||
|
i++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (const auto *changeValueDisplay = constCurrentDisplay->asChangeValueDisplayInterface())
|
||||||
|
{
|
||||||
|
body += ("<form action=\"/setValue\" method=\"GET\">");
|
||||||
|
body += (("<input type=\"number\" name=\"value\" value=\"" + std::to_string(changeValueDisplay->shownValue()) + "\" />").c_str());
|
||||||
|
body += ("<button type=\"submit\">Update</button>");
|
||||||
|
body += ("</form>");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
body += ("No web control implemented for current display.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
body += ("Currently no screen instantiated.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL_AND_EXIT_ON_ERROR(httpd_resp_set_type, req, "text/html")
|
||||||
|
CALL_AND_EXIT_ON_ERROR(httpd_resp_send, req, body.data(), body.size())
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t webserver_up_handler(httpd_req_t *req)
|
||||||
|
{
|
||||||
|
#ifdef OLD_CODE
|
||||||
|
InputDispatcher::rotate(-1);
|
||||||
|
|
||||||
|
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
||||||
|
response->addHeader("Location", "/");
|
||||||
|
request->send(response);
|
||||||
|
#else
|
||||||
|
return ESP_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t webserver_down_handler(httpd_req_t *req)
|
||||||
|
{
|
||||||
|
#ifdef OLD_CODE
|
||||||
|
InputDispatcher::rotate(1);
|
||||||
|
|
||||||
|
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
||||||
|
response->addHeader("Location", "/");
|
||||||
|
request->send(response);
|
||||||
|
#else
|
||||||
|
return ESP_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t webserver_confirm_handler(httpd_req_t *req)
|
||||||
|
{
|
||||||
|
#ifdef OLD_CODE
|
||||||
|
InputDispatcher::confirmButton(true);
|
||||||
|
InputDispatcher::confirmButton(false);
|
||||||
|
|
||||||
|
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
||||||
|
response->addHeader("Location", "/");
|
||||||
|
request->send(response);
|
||||||
|
#else
|
||||||
|
return ESP_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t webserver_back_handler(httpd_req_t *req)
|
||||||
|
{
|
||||||
|
#ifdef OLD_CODE
|
||||||
|
InputDispatcher::backButton(true);
|
||||||
|
InputDispatcher::backButton(false);
|
||||||
|
|
||||||
|
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
||||||
|
response->addHeader("Location", "/");
|
||||||
|
request->send(response);
|
||||||
|
#else
|
||||||
|
return ESP_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t webserver_triggerItem_handler(httpd_req_t *req)
|
||||||
|
{
|
||||||
|
#ifdef OLD_CODE
|
||||||
|
if (!request->hasArg("index"))
|
||||||
|
{
|
||||||
|
request->send(400, "text/plain", "index parameter missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!currentDisplay)
|
||||||
|
{
|
||||||
|
request->send(400, "text/plain", "currentDisplay is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *menuDisplay = currentDisplay->asMenuDisplay();
|
||||||
|
if (!menuDisplay)
|
||||||
|
{
|
||||||
|
request->send(400, "text/plain", "currentDisplay is not a menu display");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto indexStr = request->arg("index");
|
||||||
|
|
||||||
|
char *ptr;
|
||||||
|
const auto index = std::strtol(std::begin(indexStr), &ptr, 10);
|
||||||
|
|
||||||
|
if (ptr != std::end(indexStr))
|
||||||
|
{
|
||||||
|
request->send(400, "text/plain", "index could not be parsed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < 0 || index >= menuDisplay->menuItemCount())
|
||||||
|
{
|
||||||
|
request->send(400, "text/plain", "index out of range");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
menuDisplay->getMenuItem(index).triggered();
|
||||||
|
|
||||||
|
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
||||||
|
response->addHeader("Location", "/");
|
||||||
|
request->send(response);
|
||||||
|
#else
|
||||||
|
return ESP_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t webserver_setValue_handler(httpd_req_t *req)
|
||||||
|
{
|
||||||
|
#ifdef OLD_CODE
|
||||||
|
if (!request->hasArg("value"))
|
||||||
|
{
|
||||||
|
request->send(400, "text/plain", "value parameter missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!currentDisplay)
|
||||||
|
{
|
||||||
|
request->send(400, "text/plain", "currentDisplay is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *changeValueDisplay = currentDisplay->asChangeValueDisplayInterface();
|
||||||
|
if (!changeValueDisplay)
|
||||||
|
{
|
||||||
|
request->send(400, "text/plain", "currentDisplay is not a change value display");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto valueStr = request->arg("value");
|
||||||
|
|
||||||
|
char *ptr;
|
||||||
|
const auto value = std::strtol(std::begin(valueStr), &ptr, 10);
|
||||||
|
|
||||||
|
if (ptr != std::end(valueStr))
|
||||||
|
{
|
||||||
|
request->send(400, "text/plain", "value could not be parsed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
changeValueDisplay->setShownValue(value);
|
||||||
|
|
||||||
|
AsyncWebServerResponse *response = request->beginResponse(302, "text/plain", "ok");
|
||||||
|
response->addHeader("Location", "/");
|
||||||
|
request->send(response);
|
||||||
|
#else
|
||||||
|
return ESP_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t webserver_reboot_handler(httpd_req_t *req)
|
||||||
|
{
|
||||||
|
std::string_view body{"REBOOT called..."};
|
||||||
|
CALL_AND_EXIT_ON_ERROR(httpd_resp_set_type, req, "text/html")
|
||||||
|
CALL_AND_EXIT_ON_ERROR(httpd_resp_send, req, body.data(), body.size())
|
||||||
|
|
||||||
|
shouldReboot = true;
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user