Rendering
This commit is contained in:
@@ -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
|
||||||
|
215
main/cloud.cpp
215
main/cloud.cpp
@@ -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,84 +95,87 @@ void cloudCollect()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cloudBuffer.empty())
|
if (configs.cloudSettings.cloudMode.value == CloudMode::STATISTICS || configs.cloudSettings.cloudMode.value == CloudMode::STATISTICS_AND_REMOTE_DISPLAY)
|
||||||
cloudBuffer = '[';
|
|
||||||
else
|
|
||||||
cloudBuffer += ',';
|
|
||||||
|
|
||||||
cloudBuffer += fmt::format("[{},{},{}",
|
|
||||||
std::chrono::floor<std::chrono::milliseconds>(espchrono::millis_clock::now().time_since_epoch()).count(),
|
|
||||||
std::chrono::floor<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)
|
if (cloudBuffer.empty())
|
||||||
cloudBuffer += fmt::format(",{}", result->rssi);
|
cloudBuffer = '[';
|
||||||
|
else
|
||||||
|
cloudBuffer += ',';
|
||||||
|
|
||||||
|
cloudBuffer += fmt::format("[{},{},{}",
|
||||||
|
std::chrono::floor<std::chrono::milliseconds>(espchrono::millis_clock::now().time_since_epoch()).count(),
|
||||||
|
std::chrono::floor<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
|
else
|
||||||
cloudBuffer += ",null";
|
cloudBuffer += ",null";
|
||||||
}
|
|
||||||
else
|
|
||||||
cloudBuffer += ",null";
|
|
||||||
|
|
||||||
if (raw_gas)
|
if (raw_gas)
|
||||||
cloudBuffer += fmt::format(",{}", *raw_gas);
|
cloudBuffer += fmt::format(",{}", *raw_gas);
|
||||||
else
|
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";
|
cloudBuffer += ",null";
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cloudBuffer += fmt::format(",[{:.02f},{:.02f}",
|
if (raw_brems)
|
||||||
controller.getCalibratedVoltage(),
|
cloudBuffer += fmt::format(",{}", *raw_brems);
|
||||||
fixBoardTemp(controller.feedback.boardTemp));
|
else
|
||||||
|
cloudBuffer += ",null";
|
||||||
|
|
||||||
constexpr const auto addMotor = [](const bobbycar::protocol::serial::MotorState &command,
|
if (gas)
|
||||||
const bobbycar::protocol::serial::MotorFeedback &feedback,
|
cloudBuffer += fmt::format(",{:.1f}", *gas);
|
||||||
bool invert){
|
else
|
||||||
cloudBuffer += fmt::format(",[{},{:.2f},{:.2f},{}]",
|
cloudBuffer += ",null";
|
||||||
command.pwm * (invert?-1:1),
|
|
||||||
convertToKmh(feedback.speed) * (invert?-1:1),
|
if (brems)
|
||||||
fixCurrent(feedback.dcLink),
|
cloudBuffer += fmt::format(",{:.1f}", *brems);
|
||||||
feedback.error);
|
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 += ']';
|
||||||
};
|
};
|
||||||
|
|
||||||
addMotor(controller.command.left, controller.feedback.left, controller.invertLeft);
|
addController(controllers.front);
|
||||||
addMotor(controller.command.right, controller.feedback.right, controller.invertRight);
|
addController(controllers.back);
|
||||||
|
|
||||||
cloudBuffer += ']';
|
//cloudBuffer += fmt::format("", );
|
||||||
};
|
|
||||||
|
|
||||||
addController(controllers.front);
|
cloudBuffer += "]";
|
||||||
addController(controllers.back);
|
}
|
||||||
|
|
||||||
//cloudBuffer += fmt::format("", );
|
|
||||||
|
|
||||||
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)
|
||||||
|
11
main/cloud.h
11
main/cloud.h
@@ -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();
|
||||||
|
@@ -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)
|
|
||||||
|
@@ -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)
|
|
||||||
|
@@ -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) \
|
||||||
|
29
main/remotedisplaywebsocket.cpp
Normal file
29
main/remotedisplaywebsocket.cpp
Normal 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));
|
||||||
|
}
|
||||||
|
*/
|
39
main/remotedisplaywebsocket.h
Normal file
39
main/remotedisplaywebsocket.h
Normal 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));
|
||||||
|
}
|
@@ -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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user