Compare commits
2 Commits
new-idf
...
websocket-
Author | SHA1 | Date | |
---|---|---|---|
ee4092a722 | |||
5ff8864ac3 |
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -66,7 +66,7 @@
|
||||
url = ../../0xFEEDC0DE64/esp-protocols.git
|
||||
[submodule "components/TFT_eSPI"]
|
||||
path = components/TFT_eSPI
|
||||
url = ../../0xFEEDC0DE64/TFT_eSPI.git
|
||||
url = ../../bobbycar-graz/TFT_eSPI.git
|
||||
[submodule "esp_boost"]
|
||||
path = esp_boost
|
||||
url = ../../0xFEEDC0DE64/esp_boost.git
|
||||
|
Submodule components/TFT_eSPI updated: 4dacb617be...9fa26a02fb
@ -228,6 +228,7 @@ set(headers
|
||||
presets.h
|
||||
profilesettings.h
|
||||
qrimport.h
|
||||
remotedisplaywebsocket.h
|
||||
rotary.h
|
||||
screens.h
|
||||
serial_bobby.h
|
||||
@ -480,6 +481,7 @@ set(sources
|
||||
presets.cpp
|
||||
profilesettings.cpp
|
||||
qrimport.cpp
|
||||
remotedisplaywebsocket.cpp
|
||||
rotary.cpp
|
||||
screens.cpp
|
||||
serial_bobby.cpp
|
||||
@ -550,6 +552,11 @@ if(NOT DEFINED BOBBY_DEFAULT_USERNAME)
|
||||
message(FATAL_ERROR "Please define BOBBY_DEFAULT_USERNAME")
|
||||
endif()
|
||||
|
||||
message(WARNING "Git revision: ${GIT_REV}")
|
||||
message(WARNING "Git short revision: ${GIT_SHORT_REV}")
|
||||
message(WARNING "Git message: ${GIT_MESSAGE}")
|
||||
message(WARNING "Git branch: ${GIT_BRANCH}")
|
||||
|
||||
target_compile_options(${COMPONENT_TARGET}
|
||||
PRIVATE
|
||||
-fstack-reuse=all
|
||||
|
@ -47,6 +47,7 @@ struct CloudTransmitTimeoutAccessor : public NewSettingsAccessor<int16_t> { Conf
|
||||
struct CloudSendStatisticsAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.cloudSettings.sendStatistic; } };
|
||||
struct CloudURLAccessor : public NewSettingsAccessor<std::string> { ConfigWrapper<std::string> &getConfig() const override { return configs.cloudUrl; } };
|
||||
struct CloudKeyAccessor : public NewSettingsAccessor<std::string> { ConfigWrapper<std::string> &getConfig() const override { return configs.cloudSettings.cloudKey; } };
|
||||
struct CloudSendScreenAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.cloudSettings.sendScreen; } };
|
||||
|
||||
// Time
|
||||
//struct TimezoneOffsetAccessor : public NewSettingsAccessor<int32_t> { ConfigWrapper<int32_t> &getConfig() const override { return configs.timezoneOffset; } };
|
||||
|
@ -721,6 +721,9 @@ void cloudSend()
|
||||
if (configs.cloudUrl.value().empty())
|
||||
return;
|
||||
|
||||
if (!configs.cloudSettings.sendStatistic.value() && !configs.cloudSettings.sendScreen.value())
|
||||
return;
|
||||
|
||||
if (!cloudStarted)
|
||||
{
|
||||
if (espchrono::ago(lastStartTry) < 10s)
|
||||
@ -773,6 +776,43 @@ std::string getLoginMessage()
|
||||
configs.otaUsername.value(), tft.width(), tft.height(), configs.webserverPassword.value(), configs.cloudSettings.cloudKey.value());
|
||||
}
|
||||
|
||||
|
||||
void cloudSendDisplay(std::string_view data)
|
||||
{
|
||||
static std::string screenBuffer;
|
||||
static uint64_t msg_id{0};
|
||||
|
||||
if (!cloudStarted || !cloudClient || !cloudClient.is_connected() || espchrono::ago(isSendingNvs) < 4s)
|
||||
return;
|
||||
|
||||
/* custom menu display handling
|
||||
if (!espgui::currentDisplay)
|
||||
return;
|
||||
|
||||
if (const auto &menuDisplay = espgui::currentDisplay->asMenuDisplay(); menuDisplay)
|
||||
{
|
||||
// custom handle menu display
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
// fill 1024 bytes with the data
|
||||
screenBuffer += std::string{data} + '\u0000';
|
||||
|
||||
if (screenBuffer.length() > 1024)
|
||||
{
|
||||
// send data
|
||||
const auto timeout = std::chrono::ceil<espcpputils::ticks>(
|
||||
espchrono::milliseconds32{configs.cloudSettings.cloudTransmitTimeout.value()}).count();
|
||||
cloudClient.send_text(screenBuffer, timeout);
|
||||
|
||||
// clear buffer
|
||||
screenBuffer.clear();
|
||||
ESP_LOGI(TAG, "sent screen data %lu", msg_id);
|
||||
msg_id++;
|
||||
}
|
||||
}
|
||||
|
||||
void cloudEventHandler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
|
||||
{
|
||||
CPP_UNUSED(event_handler_arg);
|
||||
|
@ -24,5 +24,6 @@ void initCloud();
|
||||
void updateCloud();
|
||||
void cloudCollect();
|
||||
void cloudSend();
|
||||
void cloudSendDisplay(std::string_view data);
|
||||
|
||||
std::string getLoginMessage();
|
||||
|
@ -26,6 +26,7 @@ constexpr char TEXT_CLOUDKEY[] = "Cloud Key";
|
||||
constexpr char TEXT_CLOUDENABLED[] = "Cloud enabled";
|
||||
constexpr char TEXT_CLOUDTRANSMITTIMEOUT[] = "Transmit timeout";
|
||||
constexpr char TEXT_SENDSTATISTICS[] = "Send Statistics";
|
||||
constexpr char TEXT_SENDSCREEN[] = "Send Screen";
|
||||
constexpr char TEXT_CLOUDCOLLECTRATE[] = "Cloud collect rate";
|
||||
constexpr char TEXT_CLOUDSENDRATE[] = "Cloud send rate";
|
||||
constexpr char TEXT_BACK[] = "Back";
|
||||
@ -89,6 +90,7 @@ CloudSettingsMenu::CloudSettingsMenu()
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CLOUDKEY>, PushScreenAction<CloudKeyChangeScreen>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_CLOUDTRANSMITTIMEOUT>, PushScreenAction<CloudTransmitTimeoutChangeScreen>>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SENDSTATISTICS>, BobbyCheckbox, CloudSendStatisticsAccessor>>();
|
||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_SENDSCREEN>, BobbyCheckbox, CloudSendScreenAccessor>>();
|
||||
constructMenuItem<makeComponent<MenuItem, CloudCreatedText, DisabledColor, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, CloudStartedText, DisabledColor, DummyAction>>();
|
||||
constructMenuItem<makeComponent<MenuItem, CloudConnectedText, DisabledColor, DummyAction>>();
|
||||
|
@ -372,6 +372,7 @@ public:
|
||||
ConfigWrapperLegacy<int16_t> cloudTransmitTimeout{10, DoReset, {}, "clodTransmTmout" };
|
||||
ConfigWrapperLegacy<std::string> cloudKey {std::string{}, DoReset, {}, "cloudKey" };
|
||||
ConfigWrapperLegacy<bool> sendStatistic {false, DoReset, {}, "cloudSendStats" };
|
||||
ConfigWrapperLegacy<bool> sendScreen {false, DoReset, {}, "cloudSendScreen" };
|
||||
} cloudSettings;
|
||||
|
||||
struct {
|
||||
@ -718,6 +719,7 @@ public:
|
||||
x(cloudSettings.cloudTransmitTimeout) \
|
||||
x(cloudSettings.cloudKey) \
|
||||
x(cloudSettings.sendStatistic) \
|
||||
x(cloudSettings.sendScreen) \
|
||||
\
|
||||
x(udpCloudSettings.udpToken) \
|
||||
x(udpCloudSettings.udpCloudEnabled) \
|
||||
|
0
main/remotedisplaywebsocket.cpp
Normal file
0
main/remotedisplaywebsocket.cpp
Normal file
293
main/remotedisplaywebsocket.h
Normal file
293
main/remotedisplaywebsocket.h
Normal file
@ -0,0 +1,293 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
// 3rdparty lib includes
|
||||
#include <fmt/core.h>
|
||||
|
||||
// local includes
|
||||
#include "cloud.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#define RDWS_TAG "remotedisplay"
|
||||
|
||||
namespace remotedisplay {
|
||||
|
||||
namespace {
|
||||
|
||||
enum class msg_type : uint8_t
|
||||
{
|
||||
drawCentreString,
|
||||
drawChar,
|
||||
drawCircle,
|
||||
drawEllipse,
|
||||
drawHLine,
|
||||
drawVLine,
|
||||
drawLine,
|
||||
drawPixel,
|
||||
drawRect,
|
||||
drawRightString,
|
||||
drawRoundRect,
|
||||
drawString,
|
||||
drawSunkenRect,
|
||||
drawTriangle,
|
||||
fillCircle,
|
||||
fillEllipse,
|
||||
fillRect,
|
||||
fillRoundRect,
|
||||
fillScreen,
|
||||
fillTriangle
|
||||
};
|
||||
|
||||
struct drawString_msg
|
||||
{
|
||||
int16_t x, y;
|
||||
uint8_t font;
|
||||
};
|
||||
static_assert(sizeof(drawString_msg) == 6, "wrong size");
|
||||
|
||||
struct drawChar_msg
|
||||
{
|
||||
int16_t x, y;
|
||||
uint16_t c, color, bg;
|
||||
uint8_t size;
|
||||
};
|
||||
static_assert(sizeof(drawChar_msg) == 12, "wrong size");
|
||||
|
||||
struct drawCircle_msg
|
||||
{
|
||||
int16_t x, y, r;
|
||||
uint16_t color;
|
||||
};
|
||||
static_assert(sizeof(drawCircle_msg) == 8, "wrong size");
|
||||
|
||||
struct drawEllipse_msg
|
||||
{
|
||||
int16_t x, y, rx, ry;
|
||||
uint16_t color;
|
||||
};
|
||||
static_assert(sizeof(drawEllipse_msg) == 10, "wrong size");
|
||||
|
||||
struct drawHVLine_msg
|
||||
{
|
||||
int16_t x, y, wh;
|
||||
uint16_t color;
|
||||
};
|
||||
static_assert(sizeof(drawHVLine_msg) == 8, "wrong size");
|
||||
|
||||
struct drawLine_msg
|
||||
{
|
||||
int16_t xs, ys, xe, ye;
|
||||
uint16_t color;
|
||||
};
|
||||
static_assert(sizeof(drawLine_msg) == 10, "wrong size");
|
||||
|
||||
struct drawPixel_msg
|
||||
{
|
||||
int16_t x, y;
|
||||
uint16_t color;
|
||||
};
|
||||
static_assert(sizeof(drawPixel_msg) == 6, "wrong size");
|
||||
|
||||
struct drawRect_msg
|
||||
{
|
||||
int16_t x, y, w, h;
|
||||
uint16_t color;
|
||||
};
|
||||
static_assert(sizeof(drawRect_msg) == 10, "wrong size");
|
||||
|
||||
struct drawRoundRect_msg
|
||||
{
|
||||
int16_t x, y, w, h, radius;
|
||||
uint16_t color;
|
||||
};
|
||||
static_assert(sizeof(drawRoundRect_msg) == 12, "wrong size");
|
||||
|
||||
struct drawSunkenRect_msg
|
||||
{
|
||||
int16_t x, y, w, h;
|
||||
uint16_t color0, color1, color2;
|
||||
};
|
||||
static_assert(sizeof(drawSunkenRect_msg) == 14, "wrong size");
|
||||
|
||||
struct drawTriangle_msg
|
||||
{
|
||||
int16_t x1, y1, x2, y2, x3, y3;
|
||||
uint16_t color;
|
||||
};
|
||||
static_assert(sizeof(drawTriangle_msg) == 14, "wrong size");
|
||||
|
||||
constexpr size_t HEADER_SIZE = 1;
|
||||
void emitMessageHeader(std::string &dst, msg_type msg_type)
|
||||
{
|
||||
dst += (char)msg_type;
|
||||
}
|
||||
|
||||
void sendDrawMsg(msg_type type, std::string_view msg)
|
||||
{
|
||||
std::string buf;
|
||||
emitMessageHeader(buf, type);
|
||||
buf += msg;
|
||||
|
||||
cloudSendDisplay(buf);
|
||||
}
|
||||
|
||||
void drawGenericString(msg_type type, std::string_view string, int32_t x, int32_t y, uint8_t font)
|
||||
{
|
||||
if (string.size() > UINT8_MAX)
|
||||
{
|
||||
ESP_LOGW(RDWS_TAG, "String size too long (%zu > UINT8_MAX)", string.size());
|
||||
return;
|
||||
}
|
||||
|
||||
drawString_msg dcstr = { static_cast<int16_t>(x), static_cast<int16_t>(y), font };
|
||||
std::string buf;
|
||||
emitMessageHeader(buf, msg_type::drawCentreString);
|
||||
buf += std::string_view(reinterpret_cast<char *>(&dcstr), sizeof(dcstr));
|
||||
buf += (char)string.length();
|
||||
buf += string;
|
||||
|
||||
cloudSendDisplay(buf);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void drawCentreString(std::string_view string, int32_t x, int32_t y, uint8_t font)
|
||||
{
|
||||
drawGenericString(msg_type::drawCentreString, string, x, y, font);
|
||||
}
|
||||
|
||||
void drawChar(int32_t x, int32_t y, uint16_t c, uint16_t color, uint16_t bg, uint8_t size)
|
||||
{
|
||||
drawChar_msg dc = { static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<uint16_t>(c), color, bg, size };
|
||||
sendDrawMsg(msg_type::drawChar, std::string_view(reinterpret_cast<char *>(&dc), sizeof(dc)));
|
||||
}
|
||||
|
||||
void drawCircle(int32_t x, int32_t y, int32_t r, uint32_t color)
|
||||
{
|
||||
drawCircle_msg dcirc = { static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(r), static_cast<uint16_t>(color) };
|
||||
sendDrawMsg(msg_type::drawCircle, std::string_view(reinterpret_cast<char *>(&dcirc), sizeof(dcirc)));
|
||||
}
|
||||
|
||||
void drawEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color)
|
||||
{
|
||||
drawEllipse_msg dellip = { static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(rx), static_cast<int16_t>(ry), color };
|
||||
sendDrawMsg(msg_type::drawEllipse, std::string_view(reinterpret_cast<char *>(&dellip), sizeof(dellip)));
|
||||
}
|
||||
|
||||
void drawFastHLine(int32_t x, int32_t y, int32_t w, uint16_t color)
|
||||
{
|
||||
drawHVLine_msg dhl = { static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(w), color };
|
||||
sendDrawMsg(msg_type::drawHLine, std::string_view(reinterpret_cast<char *>(&dhl), sizeof(dhl)));
|
||||
}
|
||||
|
||||
void drawFastVLine(int32_t x, int32_t y, int32_t h, uint16_t color)
|
||||
{
|
||||
drawHVLine_msg dvl = { static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(h), color };
|
||||
sendDrawMsg(msg_type::drawVLine, std::string_view(reinterpret_cast<char *>(&dvl), sizeof(dvl)));
|
||||
}
|
||||
|
||||
void drawLine(int32_t xs, int32_t ys, int32_t xe, int32_t ye, uint16_t color)
|
||||
{
|
||||
drawLine_msg dl = { static_cast<int16_t>(xs), static_cast<int16_t>(ys), static_cast<int16_t>(xe), static_cast<int16_t>(ye), color };
|
||||
sendDrawMsg(msg_type::drawLine, std::string_view(reinterpret_cast<char *>(&dl), sizeof(dl)));
|
||||
}
|
||||
|
||||
void drawPixel(int32_t x, int32_t y, uint16_t color)
|
||||
{
|
||||
return; // won't support
|
||||
drawPixel_msg dp = { static_cast<int16_t>(x), static_cast<int16_t>(y), color };
|
||||
sendDrawMsg(msg_type::drawPixel, std::string_view(reinterpret_cast<char *>(&dp), sizeof(dp)));
|
||||
}
|
||||
|
||||
void drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color)
|
||||
{
|
||||
// same parameters as fillRect -> can use same struct
|
||||
drawRect_msg dr = { static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(w), static_cast<int16_t>(h), static_cast<uint16_t>(color) };
|
||||
sendDrawMsg(msg_type::drawRect, std::string_view(reinterpret_cast<char *>(&dr), sizeof(dr)));
|
||||
}
|
||||
|
||||
void drawRightString(std::string_view string, int32_t x, int32_t y, uint8_t font)
|
||||
{
|
||||
drawGenericString(msg_type::drawRightString, string, x, y, font);
|
||||
}
|
||||
|
||||
void drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color)
|
||||
{
|
||||
drawRoundRect_msg drr = {
|
||||
static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(w), static_cast<int16_t>(h),
|
||||
static_cast<int16_t>(radius), static_cast<uint16_t>(color)
|
||||
};
|
||||
sendDrawMsg(msg_type::drawRoundRect, std::string_view(reinterpret_cast<char *>(&drr), sizeof(drr)));
|
||||
}
|
||||
|
||||
void drawString(std::string_view string, int32_t poX, int32_t poY, uint8_t font)
|
||||
{
|
||||
drawGenericString(msg_type::drawString, string, poX, poY, font);
|
||||
}
|
||||
|
||||
void drawSunkenRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color0, uint32_t color1, uint32_t color2)
|
||||
{
|
||||
drawSunkenRect_msg dsr = {
|
||||
static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(w), static_cast<int16_t>(h),
|
||||
static_cast<uint16_t>(color0), static_cast<uint16_t>(color1), static_cast<uint16_t>(color2)
|
||||
};
|
||||
sendDrawMsg(msg_type::drawSunkenRect, std::string_view(reinterpret_cast<char *>(&dsr), sizeof(dsr)));
|
||||
}
|
||||
|
||||
void drawTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color)
|
||||
{
|
||||
drawTriangle_msg dt = {
|
||||
static_cast<int16_t>(x1), static_cast<int16_t>(y1), static_cast<int16_t>(x2), static_cast<int16_t>(y2), static_cast<int16_t>(x3), static_cast<int16_t>(y3),
|
||||
static_cast<uint16_t>(color)
|
||||
};
|
||||
sendDrawMsg(msg_type::drawTriangle, std::string_view(reinterpret_cast<char *>(&dt), sizeof(dt)));
|
||||
}
|
||||
|
||||
|
||||
void fillCircle(int32_t x, int32_t y, int32_t r, uint32_t color)
|
||||
{
|
||||
drawCircle_msg fcirc = { static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(r), static_cast<uint16_t>(color) };
|
||||
sendDrawMsg(msg_type::fillCircle, std::string_view(reinterpret_cast<char *>(&fcirc), sizeof(fcirc)));
|
||||
}
|
||||
|
||||
void fillEllipse(int16_t x, int16_t y, int32_t rx, int32_t ry, uint16_t color)
|
||||
{
|
||||
drawEllipse_msg fellip = { static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(rx), static_cast<int16_t>(ry), static_cast<uint16_t>(color) };
|
||||
sendDrawMsg(msg_type::fillEllipse, std::string_view(reinterpret_cast<char *>(&fellip), sizeof(fellip)));
|
||||
}
|
||||
|
||||
void fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint16_t color)
|
||||
{
|
||||
drawRect_msg fr = { static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(w), static_cast<int16_t>(h), color };
|
||||
sendDrawMsg(msg_type::fillRect, std::string_view(reinterpret_cast<char *>(&fr), sizeof(fr)));
|
||||
}
|
||||
|
||||
void fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t radius, uint32_t color)
|
||||
{
|
||||
drawRoundRect_msg frr = {
|
||||
static_cast<int16_t>(x), static_cast<int16_t>(y), static_cast<int16_t>(w), static_cast<int16_t>(h),
|
||||
static_cast<int16_t>(radius), static_cast<uint16_t>(color)
|
||||
};
|
||||
sendDrawMsg(msg_type::fillRoundRect, std::string_view(reinterpret_cast<char *>(&frr), sizeof(frr)));
|
||||
}
|
||||
|
||||
void fillScreen(uint32_t color)
|
||||
{
|
||||
auto fs = static_cast<uint16_t>(color);
|
||||
sendDrawMsg(msg_type::fillScreen, std::string_view(reinterpret_cast<char *>(&fs), sizeof(fs)));
|
||||
}
|
||||
|
||||
void fillTriangle(int32_t x1,int32_t y1, int32_t x2,int32_t y2, int32_t x3,int32_t y3, uint32_t color)
|
||||
{
|
||||
drawTriangle_msg ft = {
|
||||
static_cast<int16_t>(x1), static_cast<int16_t>(y1), static_cast<int16_t>(x2), static_cast<int16_t>(y2), static_cast<int16_t>(x3), static_cast<int16_t>(y3),
|
||||
static_cast<uint16_t>(color)
|
||||
};
|
||||
sendDrawMsg(msg_type::fillTriangle, std::string_view(reinterpret_cast<char *>(&ft), sizeof(ft)));
|
||||
}
|
||||
|
||||
} // namespace remotedisplay
|
Reference in New Issue
Block a user