Rendering

This commit is contained in:
CommanderRedYT
2022-02-06 00:45:39 +01:00
parent a462e97d5f
commit 72ce9fb3a5
9 changed files with 269 additions and 73 deletions

View File

@@ -225,6 +225,7 @@ set(headers
presets.h presets.h
profilesettings.h profilesettings.h
qrimport.h qrimport.h
remotedisplaywebsocket.h
rotary.h rotary.h
screens.h screens.h
serial_bobby.h serial_bobby.h
@@ -473,6 +474,7 @@ set(sources
presets.cpp presets.cpp
profilesettings.cpp profilesettings.cpp
qrimport.cpp qrimport.cpp
remotedisplaywebsocket.cpp
rotary.cpp rotary.cpp
screens.cpp screens.cpp
serial_bobby.cpp serial_bobby.cpp

View File

@@ -12,6 +12,7 @@
#include <fmt/core.h> #include <fmt/core.h>
#include <tickchrono.h> #include <tickchrono.h>
#include <wrappers/websocket_client.h> #include <wrappers/websocket_client.h>
#include <tftinstance.h>
// local includes // local includes
#include "globals.h" #include "globals.h"
@@ -34,10 +35,12 @@ std::string cloudBuffer;
std::optional<espchrono::millis_clock::time_point> lastCloudCollect; std::optional<espchrono::millis_clock::time_point> lastCloudCollect;
std::optional<espchrono::millis_clock::time_point> lastCloudSend; std::optional<espchrono::millis_clock::time_point> lastCloudSend;
bool hasAnnouncedItself{};
void initCloud() void initCloud()
{ {
if (configs.cloudSettings.cloudEnabled.value() && if (configs.cloudSettings.cloudEnabled.value() &&
!configs.cloudUrl.value().empty()) !configs.cloudUrl.value().empty() && configs.cloudSettings.cloudMode.value() != CloudMode::INACTIVE)
{ {
createCloud(); createCloud();
if (!cloudClient) if (!cloudClient)
@@ -92,6 +95,8 @@ void cloudCollect()
return; return;
} }
if (configs.cloudSettings.cloudMode.value == CloudMode::STATISTICS || configs.cloudSettings.cloudMode.value == CloudMode::STATISTICS_AND_REMOTE_DISPLAY)
{
if (cloudBuffer.empty()) if (cloudBuffer.empty())
cloudBuffer = '['; cloudBuffer = '[';
else else
@@ -164,12 +169,13 @@ void cloudCollect()
//cloudBuffer += fmt::format("", ); //cloudBuffer += fmt::format("", );
cloudBuffer += "]"; cloudBuffer += "]";
}
} }
void cloudSend() void cloudSend()
{ {
if (configs.cloudSettings.cloudEnabled.value() && if (configs.cloudSettings.cloudEnabled.value() &&
!configs.cloudUrl.value().empty()) !configs.cloudUrl.value().empty() && (configs.cloudSettings.cloudMode.value() == CloudMode::STATISTICS || configs.cloudSettings.cloudMode.value() == CloudMode::STATISTICS_AND_REMOTE_DISPLAY))
{ {
if (!cloudClient) if (!cloudClient)
{ {
@@ -215,7 +221,81 @@ void cloudSend()
cloudBuffer.clear(); cloudBuffer.clear();
} }
else if (cloudClient) else if (cloudClient && !configs.cloudSettings.cloudEnabled.value)
{
destroyCloud();
}
}
std::string getLoginMessage()
{
using namespace espgui;
return fmt::format("{{\"type\": \"hello\", \"name\": \"{}\", \"res\": \"{}x{}\", \"pass\": \"{}\", \"key\": \"{}\"}}",
configs.otaUsername.value, tft.width(), tft.height(), configs.webserverPassword.value, configs.cloudSettings.cloudKey.value);
}
void cloudSendDisplay(std::string_view data)
{
if (configs.cloudSettings.cloudEnabled.value &&
!configs.cloudUrl.value.empty() && configs.cloudSettings.cloudMode.value != CloudMode::INACTIVE)
{
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;
auto timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{configs.cloudSettings.cloudTransmitTimeout.value}).count();
int written;
if (!hasAnnouncedItself)
{
std::string helloWorld = getLoginMessage();
ESP_LOGW(TAG, "%s", helloWorld.c_str());
written = cloudClient.send_text(helloWorld, timeout);
if (written == helloWorld.size())
{
hasAnnouncedItself = true;
timeout = std::chrono::ceil<espcpputils::ticks>(espchrono::milliseconds32{configs.cloudSettings.cloudTransmitTimeout.value}).count();
}
}
if (hasAnnouncedItself)
written = cloudClient.send_text(data, timeout);
else
return;
ESP_LOGW(TAG, "%s", fmt::format("{}", data).c_str());
if (written < 0)
{
ESP_LOGE("BOBBY", "cloudClient.send_text() failed with %i", written);
hasAnnouncedItself = false;
}
else if (written != data.size())
{
ESP_LOGE("BOBBY", "websocket sent size mismatch, sent=%i, expected=%i", written, data.size());
}
}
else if (cloudClient && !configs.cloudSettings.cloudEnabled.value)
{ {
destroyCloud(); destroyCloud();
} }
@@ -223,6 +303,7 @@ void cloudSend()
void createCloud() void createCloud()
{ {
hasAnnouncedItself = false;
ESP_LOGI("BOBBY", "called"); ESP_LOGI("BOBBY", "called");
if (cloudClient) if (cloudClient)
@@ -239,6 +320,10 @@ void createCloud()
cloudClient = espcpputils::websocket_client{&config}; cloudClient = espcpputils::websocket_client{&config};
cloudClient.register_events(WEBSOCKET_EVENT_CONNECTED, [](void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data){
hasAnnouncedItself = false;
}, nullptr);
if (!cloudClient) if (!cloudClient)
{ {
ESP_LOGE(TAG, "websocket could not be constructed"); ESP_LOGE(TAG, "websocket could not be constructed");
@@ -250,6 +335,7 @@ void createCloud()
void startCloud() void startCloud()
{ {
hasAnnouncedItself = false;
ESP_LOGI("BOBBY", "called"); ESP_LOGI("BOBBY", "called");
if (!cloudClient) if (!cloudClient)
@@ -275,6 +361,7 @@ void startCloud()
void destroyCloud() void destroyCloud()
{ {
hasAnnouncedItself = false;
ESP_LOGI("BOBBY", "called"); ESP_LOGI("BOBBY", "called");
if (!cloudClient) if (!cloudClient)

View File

@@ -5,6 +5,7 @@
// 3rdparty lib includes // 3rdparty lib includes
#include <wrappers/websocket_client.h> #include <wrappers/websocket_client.h>
#include <cpptypesafeenum.h>
#include <espchrono.h> #include <espchrono.h>
extern espcpputils::websocket_client cloudClient; extern espcpputils::websocket_client cloudClient;
@@ -13,6 +14,13 @@ extern espchrono::millis_clock::time_point lastCreateTry;
extern espchrono::millis_clock::time_point lastStartTry; extern espchrono::millis_clock::time_point lastStartTry;
extern std::string cloudBuffer; extern std::string cloudBuffer;
#define CloudModeValues(x) \
x(INACTIVE) \
x(STATISTICS) \
x(REMOTE_DISPLAY) \
x(STATISTICS_AND_REMOTE_DISPLAY)
DECLARE_TYPESAFE_ENUM(CloudMode, : uint8_t, CloudModeValues)
void createCloud(); void createCloud();
void destroyCloud(); void destroyCloud();
void startCloud(); void startCloud();
@@ -21,3 +29,6 @@ void initCloud();
void updateCloud(); void updateCloud();
void cloudCollect(); void cloudCollect();
void cloudSend(); void cloudSend();
void cloudSendDisplay(std::string_view data);
std::string getLoginMessage();

View File

@@ -6,12 +6,14 @@
// local includes // local includes
#include "battery.h" #include "battery.h"
#include "ledstrip.h"
#include "handbremse.h"
#include "bobbyquickactions.h" #include "bobbyquickactions.h"
#include "cloud.h"
#include "handbremse.h"
#include "ledstrip.h"
IMPLEMENT_NVS_GET_SET_ENUM(OtaAnimationModes) IMPLEMENT_NVS_GET_SET_ENUM(BatteryCellType)
IMPLEMENT_NVS_GET_SET_ENUM(BobbyQuickActions)
IMPLEMENT_NVS_GET_SET_ENUM(CloudMode)
IMPLEMENT_NVS_GET_SET_ENUM(HandbremseMode) IMPLEMENT_NVS_GET_SET_ENUM(HandbremseMode)
IMPLEMENT_NVS_GET_SET_ENUM(LedstripAnimation) IMPLEMENT_NVS_GET_SET_ENUM(LedstripAnimation)
IMPLEMENT_NVS_GET_SET_ENUM(BobbyQuickActions) IMPLEMENT_NVS_GET_SET_ENUM(OtaAnimationModes)
IMPLEMENT_NVS_GET_SET_ENUM(BatteryCellType)

View File

@@ -4,8 +4,9 @@
#define CONFIGWRAPPER_TOSTRING_USINGS using ::toString; #define CONFIGWRAPPER_TOSTRING_USINGS using ::toString;
#include <configwrapper_priv.h> #include <configwrapper_priv.h>
INSTANTIATE_CONFIGWRAPPER_TEMPLATES(OtaAnimationModes) INSTANTIATE_CONFIGWRAPPER_TEMPLATES(BatteryCellType)
INSTANTIATE_CONFIGWRAPPER_TEMPLATES(BobbyQuickActions)
INSTANTIATE_CONFIGWRAPPER_TEMPLATES(CloudMode)
INSTANTIATE_CONFIGWRAPPER_TEMPLATES(HandbremseMode) INSTANTIATE_CONFIGWRAPPER_TEMPLATES(HandbremseMode)
INSTANTIATE_CONFIGWRAPPER_TEMPLATES(LedstripAnimation) INSTANTIATE_CONFIGWRAPPER_TEMPLATES(LedstripAnimation)
INSTANTIATE_CONFIGWRAPPER_TEMPLATES(BobbyQuickActions) INSTANTIATE_CONFIGWRAPPER_TEMPLATES(OtaAnimationModes)
INSTANTIATE_CONFIGWRAPPER_TEMPLATES(BatteryCellType)

View File

@@ -27,6 +27,10 @@
#include "handbremse.h" #include "handbremse.h"
#include "ledstrip.h" #include "ledstrip.h"
#include "unifiedmodelmode.h" #include "unifiedmodelmode.h"
#include "displays/lockscreen.h"
#include "handbremse.h"
#include "bobbyquickactions.h"
#include "cloud.h"
using namespace espconfig; using namespace espconfig;
@@ -361,6 +365,8 @@ public:
struct { struct {
ConfigWrapperLegacy<bool> cloudEnabled {false, DoReset, {}, "cloudEnabled" }; ConfigWrapperLegacy<bool> cloudEnabled {false, DoReset, {}, "cloudEnabled" };
ConfigWrapperLegacy<int16_t> cloudTransmitTimeout{10, DoReset, {}, "clodTransmTmout" }; ConfigWrapperLegacy<int16_t> cloudTransmitTimeout{10, DoReset, {}, "clodTransmTmout" };
ConfigWrapperLegacy<CloudMode> cloudMode {CloudMode::INACTIVE, DoReset, {}, "cloudMode" };
ConfigWrapperLegacy<std::string> cloudKey {std::string{}, DoReset, {}, "cloudKey" };
} cloudSettings; } cloudSettings;
struct { struct {
@@ -702,6 +708,8 @@ public:
\ \
x(cloudSettings.cloudEnabled) \ x(cloudSettings.cloudEnabled) \
x(cloudSettings.cloudTransmitTimeout) \ x(cloudSettings.cloudTransmitTimeout) \
x(cloudSettings.cloudMode) \
x(cloudSettings.cloudKey) \
\ \
x(udpCloudSettings.udpUid) \ x(udpCloudSettings.udpUid) \
x(udpCloudSettings.udpCloudEnabled) \ x(udpCloudSettings.udpCloudEnabled) \

View File

@@ -0,0 +1,29 @@
#include "remotedisplaywebsocket.h"
/*
// local includes
#include "cloud.h"
void handleDrawPixel(uint16_t x, uint16_t y, uint16_t color)
{
}
void handleDrawRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color)
{
cloudSendDisplay(fmt::format("{\"type\":\"drawRect\",\"x\":{},\"y\":{},\"w\":{},\"h\":{},\"C\":\"{}\"}", x, y, width, height, color));
}
void handleFillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color)
{
cloudSendDisplay(fmt::format("{\"type\":\"fillRect\",\"x\":{},\"y\":{},\"w\":{},\"h\":{},\"C\":\"{}\"}", x, y, width, height, color));
}
void handleDrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
cloudSendDisplay(fmt::format("{\"type\":\"drawLine\",\"x1\":{},\"y1\":{},\"x2\":{},\"y2\":{},\"C\":\"{}\"}", x1, y1, x2, y2, color));
}
void handleFillScreen(uint16_t color)
{
cloudSendDisplay(fmt::format("{\"type\":\"fillScreen\",\"C\":\"{}\"}", color));
}
*/

View File

@@ -0,0 +1,39 @@
#pragma once
// system includes
#include <cstdint>
#include <string>
#include <fmt/core.h>
void cloudSendDisplay(std::string_view data);
void handleDrawPixel(uint16_t x, uint16_t y, uint16_t color);
void handleDrawRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color);
void handleFillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color);
void handleDrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
void handleFillScreen(uint16_t color);
void handleDrawPixel(uint16_t x, uint16_t y, uint16_t color)
{
cloudSendDisplay(fmt::format("{{\"type\":\"drawPixel\",\"x\":{},\"y\":{},\"C\":\"{}\"}}", x, y, color));
}
void handleDrawRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color)
{
cloudSendDisplay(fmt::format("{{\"type\":\"drawRect\",\"x\":{},\"y\":{},\"w\":{},\"h\":{},\"C\":\"{}\"}}", x, y, width, height, color));
}
void handleFillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color)
{
cloudSendDisplay(fmt::format("{{\"type\":\"fillRect\",\"x\":{},\"y\":{},\"w\":{},\"h\":{},\"C\":\"{}\"}}", x, y, width, height, color));
}
void handleDrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
cloudSendDisplay(fmt::format("{{\"type\":\"drawLine\",\"x1\":{},\"y1\":{},\"x2\":{},\"y2\":{},\"C\":\"{}\"}}", x1, y1, x2, y2, color));
}
void handleFillScreen(uint16_t color)
{
cloudSendDisplay(fmt::format("{{\"type\":\"fillScreen\",\"C\":\"{}\"}}", color));
}

View File

@@ -52,6 +52,7 @@ typename std::enable_if<
!std::is_same_v<T, OtaAnimationModes> && !std::is_same_v<T, OtaAnimationModes> &&
!std::is_same_v<T, LedstripAnimation> && !std::is_same_v<T, LedstripAnimation> &&
!std::is_same_v<T, HandbremseMode> && !std::is_same_v<T, HandbremseMode> &&
!std::is_same_v<T, CloudMode> &&
!std::is_same_v<T, BobbyQuickActions> !std::is_same_v<T, BobbyQuickActions>
, void>::type , void>::type
showInputForSetting(std::string_view key, T value, std::string &body) showInputForSetting(std::string_view key, T value, std::string &body)
@@ -255,6 +256,20 @@ showInputForSetting(std::string_view key, T value, std::string &body)
body += esphttpdutils::htmlentities(enumKey); body += esphttpdutils::htmlentities(enumKey);
}); });
} }
template<typename T>
typename std::enable_if<
std::is_same_v<T, CloudMode>
, void>::type
showInputForSetting(std::string_view key, T value, std::string &body)
{
HtmlTag select{"select", fmt::format("name=\"{}\"", esphttpdutils::htmlentities(key)), body};
iterateCloudMode([&](T enumVal, std::string_view enumKey){
HtmlTag option{"option", fmt::format("value=\"{}\"{}", std::to_underlying(enumVal), value == enumVal ? " selected" : ""), body};
body += esphttpdutils::htmlentities(enumKey);
});
}
} // namespace } // namespace
esp_err_t webserver_newSettings_handler(httpd_req_t *req) esp_err_t webserver_newSettings_handler(httpd_req_t *req)
@@ -392,6 +407,7 @@ typename std::enable_if<
!std::is_same_v<T, OtaAnimationModes> && !std::is_same_v<T, OtaAnimationModes> &&
!std::is_same_v<T, LedstripAnimation> && !std::is_same_v<T, LedstripAnimation> &&
!std::is_same_v<T, HandbremseMode> && !std::is_same_v<T, HandbremseMode> &&
!std::is_same_v<T, CloudMode> &&
!std::is_same_v<T, BobbyQuickActions> !std::is_same_v<T, BobbyQuickActions>
, tl::expected<void, std::string>>::type , tl::expected<void, std::string>>::type
saveSetting(ConfigWrapper<T> &config, std::string_view newValue) saveSetting(ConfigWrapper<T> &config, std::string_view newValue)
@@ -479,7 +495,8 @@ typename std::enable_if<
std::is_same_v<T, OtaAnimationModes> || std::is_same_v<T, OtaAnimationModes> ||
std::is_same_v<T, LedstripAnimation> || std::is_same_v<T, LedstripAnimation> ||
std::is_same_v<T, HandbremseMode> || std::is_same_v<T, HandbremseMode> ||
std::is_same_v<T, BobbyQuickActions> std::is_same_v<T, BobbyQuickActions> ||
std::is_same_v<T, CloudMode>
, tl::expected<void, std::string>>::type , tl::expected<void, std::string>>::type
saveSetting(ConfigWrapper<T> &config, std::string_view newValue) saveSetting(ConfigWrapper<T> &config, std::string_view newValue)
{ {