Rendering
This commit is contained in:
215
main/cloud.cpp
215
main/cloud.cpp
@@ -12,6 +12,7 @@
|
||||
#include <fmt/core.h>
|
||||
#include <tickchrono.h>
|
||||
#include <wrappers/websocket_client.h>
|
||||
#include <tftinstance.h>
|
||||
|
||||
// local includes
|
||||
#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> lastCloudSend;
|
||||
|
||||
bool hasAnnouncedItself{};
|
||||
|
||||
void initCloud()
|
||||
{
|
||||
if (configs.cloudSettings.cloudEnabled.value() &&
|
||||
!configs.cloudUrl.value().empty())
|
||||
!configs.cloudUrl.value().empty() && configs.cloudSettings.cloudMode.value() != CloudMode::INACTIVE)
|
||||
{
|
||||
createCloud();
|
||||
if (!cloudClient)
|
||||
@@ -92,84 +95,87 @@ void cloudCollect()
|
||||
return;
|
||||
}
|
||||
|
||||
if (cloudBuffer.empty())
|
||||
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 (configs.cloudSettings.cloudMode.value == CloudMode::STATISTICS || configs.cloudSettings.cloudMode.value == CloudMode::STATISTICS_AND_REMOTE_DISPLAY)
|
||||
{
|
||||
if (const auto &result = wifi_stack::get_sta_ap_info(); result)
|
||||
cloudBuffer += fmt::format(",{}", result->rssi);
|
||||
if (cloudBuffer.empty())
|
||||
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
|
||||
cloudBuffer += ",null";
|
||||
}
|
||||
else
|
||||
cloudBuffer += ",null";
|
||||
|
||||
if (raw_gas)
|
||||
cloudBuffer += fmt::format(",{}", *raw_gas);
|
||||
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)
|
||||
{
|
||||
if (raw_gas)
|
||||
cloudBuffer += fmt::format(",{}", *raw_gas);
|
||||
else
|
||||
cloudBuffer += ",null";
|
||||
return;
|
||||
}
|
||||
|
||||
cloudBuffer += fmt::format(",[{:.02f},{:.02f}",
|
||||
controller.getCalibratedVoltage(),
|
||||
fixBoardTemp(controller.feedback.boardTemp));
|
||||
if (raw_brems)
|
||||
cloudBuffer += fmt::format(",{}", *raw_brems);
|
||||
else
|
||||
cloudBuffer += ",null";
|
||||
|
||||
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);
|
||||
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";
|
||||
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);
|
||||
addMotor(controller.command.right, controller.feedback.right, controller.invertRight);
|
||||
addController(controllers.front);
|
||||
addController(controllers.back);
|
||||
|
||||
cloudBuffer += ']';
|
||||
};
|
||||
//cloudBuffer += fmt::format("", );
|
||||
|
||||
addController(controllers.front);
|
||||
addController(controllers.back);
|
||||
|
||||
//cloudBuffer += fmt::format("", );
|
||||
|
||||
cloudBuffer += "]";
|
||||
cloudBuffer += "]";
|
||||
}
|
||||
}
|
||||
|
||||
void cloudSend()
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -215,7 +221,81 @@ void cloudSend()
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -223,6 +303,7 @@ void cloudSend()
|
||||
|
||||
void createCloud()
|
||||
{
|
||||
hasAnnouncedItself = false;
|
||||
ESP_LOGI("BOBBY", "called");
|
||||
|
||||
if (cloudClient)
|
||||
@@ -239,6 +320,10 @@ void createCloud()
|
||||
|
||||
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)
|
||||
{
|
||||
ESP_LOGE(TAG, "websocket could not be constructed");
|
||||
@@ -250,6 +335,7 @@ void createCloud()
|
||||
|
||||
void startCloud()
|
||||
{
|
||||
hasAnnouncedItself = false;
|
||||
ESP_LOGI("BOBBY", "called");
|
||||
|
||||
if (!cloudClient)
|
||||
@@ -275,6 +361,7 @@ void startCloud()
|
||||
|
||||
void destroyCloud()
|
||||
{
|
||||
hasAnnouncedItself = false;
|
||||
ESP_LOGI("BOBBY", "called");
|
||||
|
||||
if (!cloudClient)
|
||||
|
Reference in New Issue
Block a user