lots of stability improvements

This commit is contained in:
2021-09-19 02:51:16 +02:00
parent 2992cbb613
commit d6217492c7
11 changed files with 145 additions and 33 deletions

View File

@ -148,6 +148,7 @@ set(headers
utils.h
webserver.h
webserver_displaycontrol.h
webserver_lock.h
webserver_ota.h
webserver_settings.h
webserver_stringsettings.h

View File

@ -31,14 +31,14 @@ class InputDispatcher
public:
static void update()
{
if (upPressedSince && espchrono::ago(*upPressedSince) > (upPressRepeat > 3 ? 100ms : 500ms))
if (upPressedSince && espchrono::ago(*upPressedSince) > (upPressRepeat > 2 ? 50ms : 400ms))
{
upPressedSince = espchrono::millis_clock::now();
upPressRepeat++;
rotated -= 1;
}
if (downPressedSince && espchrono::ago(*downPressedSince) > (downPressRepeat > 3 ? 100ms : 500ms))
if (downPressedSince && espchrono::ago(*downPressedSince) > (downPressRepeat > 2 ? 50ms : 400ms))
{
downPressedSince = espchrono::millis_clock::now();
downPressRepeat++;

View File

@ -6,6 +6,7 @@
// 3rdparty lib includes
#include <wrappers/websocket_client.h>
#include <espwifistack.h>
#include <esphttpdutils.h>
// local includes
#include "globals.h"
@ -23,7 +24,9 @@ void startCloud();
void initCloud()
{
if (settings.cloudSettings.cloudEnabled)
if (settings.cloudSettings.cloudEnabled &&
!stringSettings.cloudUrl.empty() &&
esphttpdutils::urlverify(stringSettings.cloudUrl))
{
createCloud();
if (!cloudClient)
@ -38,7 +41,9 @@ void initCloud()
void handleCloud()
{
if (settings.cloudSettings.cloudEnabled)
if (settings.cloudSettings.cloudEnabled &&
!stringSettings.cloudUrl.empty() &&
esphttpdutils::urlverify(stringSettings.cloudUrl))
{
if (!cloudClient)
{

View File

@ -100,7 +100,7 @@ private:
Label m_labelWifiStatus{35, bottomLines[0]}; // 120, 15
Label m_labelLimit0{205, bottomLines[0]}; // 35, 15
Label m_labelIpAddress{25, bottomLines[1]}; // 130, 15
Label m_labelSignal{120, bottomLines[1]}; // 130, 15
Label m_labelSignal{125, bottomLines[1]}; // 130, 15
Label m_labelLimit1{205, bottomLines[1]}; // 35, 15
Label m_labelPerformance{40, bottomLines[2]}; // 40, 15
Label m_labelFreeMem{70, bottomLines[2]}; // 40, 15
@ -132,12 +132,12 @@ void StatusDisplay::initScreen()
tft.setTextFont(2);
tft.drawString("WiFi:", 0, bottomLines[0]);
m_labelWifiStatus.start();
tft.drawString("Limit0:", 160, bottomLines[0]);
tft.drawString("Lim0:", 173, bottomLines[0]);
m_labelLimit0.start();
tft.drawString("IP:", 0, bottomLines[1]);
m_labelIpAddress.start();
m_labelSignal.start();
tft.drawString("Limit1:", 160, bottomLines[1]);
tft.drawString("Lim1:", 173, bottomLines[1]);
m_labelLimit1.start();
tft.drawString("Perf:", 0, bottomLines[2]);
m_labelPerformance.start();

View File

@ -168,7 +168,7 @@ constexpr Settings::BoardcomputerHardware defaultBoardcomputerHardware {
#ifdef FEATURE_CLOUD
constexpr Settings::CloudSettings defaultCloudSettings {
.cloudEnabled = true,
.cloudEnabled = false,
.cloudTransmitTimeout = 10
};
#endif

View File

@ -15,6 +15,7 @@
#include <esphttpdutils.h>
// local includes
#include "webserver_lock.h"
#include "webserver_displaycontrol.h"
#ifdef FEATURE_OTA
#include "webserver_ota.h"
@ -26,8 +27,6 @@
namespace {
httpd_handle_t httpdHandle;
std::atomic<bool> shouldReboot;
void initWebserver();
void handleWebserver();
esp_err_t webserver_reboot_handler(httpd_req_t *req);
@ -36,7 +35,8 @@ esp_err_t webserver_reboot_handler(httpd_req_t *req);
namespace {
void initWebserver()
{
shouldReboot = false;
webserver_lock.construct();
webserver_lock->take(portMAX_DELAY);
{
httpd_config_t httpConfig HTTPD_DEFAULT_CONFIG();
@ -74,16 +74,13 @@ void initWebserver()
void handleWebserver()
{
if (shouldReboot)
{
shouldReboot = false;
esp_restart();
}
webserver_lock->give();
webserver_lock->take(portMAX_DELAY);
}
esp_err_t webserver_reboot_handler(httpd_req_t *req)
{
shouldReboot = true;
esp_restart();
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, "text/plain", "REBOOT called...")
}

View File

@ -15,10 +15,13 @@
#include <textinterface.h>
#include <menudisplay.h>
#include <changevaluedisplay.h>
#include <lockhelper.h>
#include <tickchrono.h>
// local includes
#include "buttons.h"
#include "globals.h"
#include "webserver_lock.h"
#ifdef FEATURE_WEBSERVER
namespace {
@ -33,6 +36,14 @@ using esphttpdutils::HtmlTag;
namespace {
esp_err_t webserver_root_handler(httpd_req_t *req)
{
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
constexpr const std::string_view msg = "could not lock webserver_lock";
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
std::string body;
{
@ -125,6 +136,14 @@ esp_err_t webserver_root_handler(httpd_req_t *req)
esp_err_t webserver_triggerButton_handler(httpd_req_t *req)
{
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
constexpr const std::string_view msg = "could not lock webserver_lock";
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
std::string query;
if (auto result = esphttpdutils::webserver_get_query(req))
query = *result;
@ -233,6 +252,14 @@ esp_err_t webserver_triggerButton_handler(httpd_req_t *req)
esp_err_t webserver_triggerItem_handler(httpd_req_t *req)
{
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
constexpr const std::string_view msg = "could not lock webserver_lock";
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
std::string query;
if (auto result = esphttpdutils::webserver_get_query(req))
query = *result;
@ -311,6 +338,14 @@ esp_err_t webserver_triggerItem_handler(httpd_req_t *req)
esp_err_t webserver_setValue_handler(httpd_req_t *req)
{
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
constexpr const std::string_view msg = "could not lock webserver_lock";
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
std::string query;
if (auto result = esphttpdutils::webserver_get_query(req))
query = *result;

11
main/webserver_lock.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
// 3rdparty lib includes
#include <delayedconstruction.h>
#include <wrappers/mutex_semaphore.h>
namespace {
cpputils::DelayedConstruction<espcpputils::mutex_semaphore> webserver_lock;
} // namespace

View File

@ -11,11 +11,14 @@
#include <fmt/core.h>
#include <espcppmacros.h>
#include <esphttpdutils.h>
#include <lockhelper.h>
#include <tickchrono.h>
// local includes
#ifdef FEATURE_OTA
#include "ota.h"
#endif
#include "webserver_lock.h"
#if defined(FEATURE_WEBSERVER) && defined(FEATURE_OTA)
namespace {
@ -28,6 +31,14 @@ using esphttpdutils::HtmlTag;
namespace {
esp_err_t webserver_ota_handler(httpd_req_t *req)
{
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
constexpr const std::string_view msg = "could not lock webserver_lock";
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
std::string body;
{
@ -208,6 +219,14 @@ esp_err_t webserver_ota_handler(httpd_req_t *req)
esp_err_t webserver_trigger_ota_handler(httpd_req_t *req)
{
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
constexpr const std::string_view msg = "could not lock webserver_lock";
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
std::string query;
if (auto result = esphttpdutils::webserver_get_query(req))
query = *result;

View File

@ -15,9 +15,12 @@
#include <espcppmacros.h>
#include <esphttpdutils.h>
#include <numberparsing.h>
#include <lockhelper.h>
#include <tickchrono.h>
// local includes
#include "globals.h"
#include "webserver_lock.h"
#ifdef FEATURE_WEBSERVER
namespace {
@ -41,11 +44,11 @@ template<typename T>
typename std::enable_if<std::is_same<T, bool>::value, bool>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
body += fmt::format("<input type=\"hidden\" name=\"{}\" value=\"false\" />"
"<input type=\"checkbox\" name=\"{}\" value=\"true\" {}/>",
body += fmt::format("<input type=\"checkbox\" name=\"{}\" value=\"true\" {}/>"
"<input type=\"hidden\" name=\"{}\" value=\"false\" />",
esphttpdutils::htmlentities(key),
esphttpdutils::htmlentities(key),
value ? "checked " : "");
value ? "checked " : "",
esphttpdutils::htmlentities(key));
return true;
}
@ -63,6 +66,14 @@ showInputForSetting(std::string_view key, T value, std::string &body)
esp_err_t webserver_settings_handler(httpd_req_t *req)
{
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
constexpr const std::string_view msg = "could not lock webserver_lock";
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
std::string body;
{
@ -190,6 +201,14 @@ saveSetting(T &value, std::string_view newValue, std::string &body)
esp_err_t webserver_saveSettings_handler(httpd_req_t *req)
{
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
constexpr const std::string_view msg = "could not lock webserver_lock";
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
std::string query;
if (auto result = esphttpdutils::webserver_get_query(req))
query = *result;
@ -204,13 +223,16 @@ esp_err_t webserver_saveSettings_handler(httpd_req_t *req)
settings.executeForEveryCommonSetting([&](std::string_view key, auto &value){
char valueBufEncoded[256];
if (const auto result = httpd_query_key_value(query.data(), key.data(), valueBufEncoded, 256); result != ESP_OK && result != ESP_ERR_NOT_FOUND)
if (const auto result = httpd_query_key_value(query.data(), key.data(), valueBufEncoded, 256); result != ESP_OK)
{
const auto msg = fmt::format("{}: httpd_query_key_value() failed with {}", key, esp_err_to_name(result));
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
body += msg;
body += '\n';
success = false;
if (result != ESP_ERR_NOT_FOUND)
{
const auto msg = fmt::format("{}: httpd_query_key_value() failed with {}", key, esp_err_to_name(result));
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
body += msg;
body += '\n';
success = false;
}
return;
}

View File

@ -11,9 +11,12 @@
#include <fmt/core.h>
#include <espcppmacros.h>
#include <esphttpdutils.h>
#include <lockhelper.h>
#include <tickchrono.h>
// local includes
#include "globals.h"
#include "webserver_lock.h"
#ifdef FEATURE_WEBSERVER
namespace {
@ -26,6 +29,14 @@ using esphttpdutils::HtmlTag;
namespace {
esp_err_t webserver_stringSettings_handler(httpd_req_t *req)
{
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
constexpr const std::string_view msg = "could not lock webserver_lock";
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
std::string body;
{
@ -107,6 +118,14 @@ esp_err_t webserver_stringSettings_handler(httpd_req_t *req)
esp_err_t webserver_saveStringSettings_handler(httpd_req_t *req)
{
espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil<espcpputils::ticks>(5s).count()};
if (!helper.locked())
{
constexpr const std::string_view msg = "could not lock webserver_lock";
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg);
}
std::string query;
if (auto result = esphttpdutils::webserver_get_query(req))
query = *result;
@ -121,13 +140,16 @@ esp_err_t webserver_saveStringSettings_handler(httpd_req_t *req)
stringSettings.executeForEveryCommonSetting([&](std::string_view key, auto &value){
char valueBufEncoded[256];
if (const auto result = httpd_query_key_value(query.data(), key.data(), valueBufEncoded, 256); result != ESP_OK && result != ESP_ERR_NOT_FOUND)
if (const auto result = httpd_query_key_value(query.data(), key.data(), valueBufEncoded, 256); result != ESP_OK)
{
const auto msg = fmt::format("{}: httpd_query_key_value() failed with {}", key, esp_err_to_name(result));
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
body += msg;
body += '\n';
success = false;
if (result != ESP_ERR_NOT_FOUND)
{
const auto msg = fmt::format("{}: httpd_query_key_value() failed with {}", key, esp_err_to_name(result));
ESP_LOGE(TAG, "%.*s", msg.size(), msg.data());
body += msg;
body += '\n';
success = false;
}
return;
}