Merge pull request #375 from bobbycar-graz/fix-319-udpcloud
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_allfeatures)
|
set(BOBBY_APP_NAME bobbyquad_allfeatures)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME allfeatures)
|
set(BOBBY_DEFAULT_USERNAME allfeatures)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_aveexy)
|
set(BOBBY_APP_NAME bobbyquad_aveexy)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME aveexy)
|
set(BOBBY_DEFAULT_USERNAME aveexy)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_comred)
|
set(BOBBY_APP_NAME bobbyquad_comred)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME comred)
|
set(BOBBY_DEFAULT_USERNAMENAME comred)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_comred_new)
|
set(BOBBY_APP_NAME bobbyquad_comred_new)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME comred_new)
|
set(BOBBY_DEFAULT_USERNAME comred_new)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_feedc0de)
|
set(BOBBY_APP_NAME bobbyquad_feedc0de)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME feedc0de)
|
set(BOBBY_DEFAULT_USERNAME feedc0de)
|
||||||
|
|
||||||
set(BOBBYCAR_BUILDFLAGS
|
set(BOBBYCAR_BUILDFLAGS
|
||||||
# Pins
|
# Pins
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_feedc0de)
|
set(BOBBY_APP_NAME bobbyquad_feedc0de)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME feedc0de)
|
set(BOBBY_DEFAULT_USERNAME feedc0de)
|
||||||
|
|
||||||
set(BOBBYCAR_BUILDFLAGS
|
set(BOBBYCAR_BUILDFLAGS
|
||||||
# Pins
|
# Pins
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_gernot)
|
set(BOBBY_APP_NAME bobbyquad_gernot)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME gernot)
|
set(BOBBY_DEFAULT_USERNAME gernot)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_greyhash)
|
set(BOBBY_APP_NAME bobbyquad_greyhash)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME greyhash)
|
set(BOBBY_DEFAULT_USERNAME greyhash)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_mick)
|
set(BOBBY_APP_NAME bobbyquad_mick)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME mick)
|
set(BOBBY_DEFAULT_USERNAME mick)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_nofeatures)
|
set(BOBBY_APP_NAME bobbyquad_nofeatures)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME nofeatures)
|
set(BOBBY_DEFAULT_USERNAME nofeatures)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_peter)
|
set(BOBBY_APP_NAME bobbyquad_peter)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME peter)
|
set(BOBBY_DEFAULT_USERNAME peter)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME bobbyquad_seatbot)
|
set(BOBBY_APP_NAME bobbyquad_seatbot)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME seatbot)
|
set(BOBBY_DEFAULT_USERNAME seatbot)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME testdevice)
|
set(BOBBY_APP_NAME testdevice)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME testdevice)
|
set(BOBBY_DEFAULT_USERNAME testdevice)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
set(BOBBY_APP_NAME testdevice2)
|
set(BOBBY_APP_NAME testdevice2)
|
||||||
set(BOBBY_DEFAULT_OTA_NAME testdevice2)
|
set(BOBBY_DEFAULT_USERNAME testdevice2)
|
||||||
|
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-DUSER_SETUP_LOADED=1
|
-DUSER_SETUP_LOADED=1
|
||||||
|
@@ -175,6 +175,7 @@ set(headers
|
|||||||
drivingstatistics.h
|
drivingstatistics.h
|
||||||
espnowfunctions.h
|
espnowfunctions.h
|
||||||
esptexthelpers.h
|
esptexthelpers.h
|
||||||
|
feedbackemulator.h
|
||||||
feedbackparser.h
|
feedbackparser.h
|
||||||
globals.h
|
globals.h
|
||||||
handbremse.h
|
handbremse.h
|
||||||
@@ -425,6 +426,7 @@ set(sources
|
|||||||
drivingstatistics.cpp
|
drivingstatistics.cpp
|
||||||
espnowfunctions.cpp
|
espnowfunctions.cpp
|
||||||
esptexthelpers.cpp
|
esptexthelpers.cpp
|
||||||
|
feedbackemulator.cpp
|
||||||
feedbackparser.cpp
|
feedbackparser.cpp
|
||||||
globals.cpp
|
globals.cpp
|
||||||
handbremse.cpp
|
handbremse.cpp
|
||||||
@@ -544,8 +546,8 @@ string(REPLACE "\n" " " GIT_MESSAGE "${GIT_MESSAGE}")
|
|||||||
string(SUBSTRING "${GIT_MESSAGE}" 0 100 GIT_MESSAGE)
|
string(SUBSTRING "${GIT_MESSAGE}" 0 100 GIT_MESSAGE)
|
||||||
string(STRIP "${GIT_BRANCH}" GIT_BRANCH)
|
string(STRIP "${GIT_BRANCH}" GIT_BRANCH)
|
||||||
|
|
||||||
if(NOT DEFINED BOBBY_DEFAULT_OTA_NAME)
|
if(NOT DEFINED BOBBY_DEFAULT_USERNAME)
|
||||||
message(FATAL_ERROR "Please define BOBBY_DEFAULT_OTA_NAME")
|
message(FATAL_ERROR "Please define BOBBY_DEFAULT_USERNAME")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_compile_options(${COMPONENT_TARGET}
|
target_compile_options(${COMPONENT_TARGET}
|
||||||
@@ -561,6 +563,6 @@ target_compile_options(${COMPONENT_TARGET}
|
|||||||
-DGIT_SHORT_REV="${GIT_SHORT_REV}"
|
-DGIT_SHORT_REV="${GIT_SHORT_REV}"
|
||||||
-DGIT_MESSAGE="${GIT_MESSAGE}"
|
-DGIT_MESSAGE="${GIT_MESSAGE}"
|
||||||
-DGIT_BRANCH="${GIT_BRANCH}"
|
-DGIT_BRANCH="${GIT_BRANCH}"
|
||||||
-DBOBBY_DEFAULT_OTA_NAME="${BOBBY_DEFAULT_OTA_NAME}"
|
-DBOBBY_DEFAULT_USERNAME="${BOBBY_DEFAULT_USERNAME}"
|
||||||
${BOBBYCAR_BUILDFLAGS}
|
${BOBBYCAR_BUILDFLAGS}
|
||||||
)
|
)
|
||||||
|
@@ -129,8 +129,9 @@ struct CloudSendRateAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapp
|
|||||||
|
|
||||||
struct UdpCloudSendIntervalAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.timersSettings.udpSendRateMs; } };
|
struct UdpCloudSendIntervalAccessor : public NewSettingsAccessor<int16_t> { ConfigWrapper<int16_t> &getConfig() const override { return configs.boardcomputerHardware.timersSettings.udpSendRateMs; } };
|
||||||
struct UdpCloudEnabledAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.udpCloudSettings.udpCloudEnabled; } };
|
struct UdpCloudEnabledAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.udpCloudSettings.udpCloudEnabled; } };
|
||||||
struct CloudDebugEnableAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.udpCloudSettings.enableCloudDebug; } };
|
struct UdpCloudDebugEnableAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.udpCloudSettings.enableCloudDebug; } };
|
||||||
struct UdpUseStdStringAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<bool> &getConfig() const override { return configs.udpCloudSettings.udpUseStdString; } };
|
struct UdpCloudHostAccessor : public NewSettingsAccessor<std::string> { ConfigWrapper<std::string> &getConfig() const override { return configs.udpCloudSettings.udpCloudHost; } };
|
||||||
|
struct UdpCloudPortAccessor : public NewSettingsAccessor<uint16_t> { ConfigWrapper<uint16_t> &getConfig() const override { return configs.udpCloudSettings.udpCloudPort; } };
|
||||||
|
|
||||||
// DefaultMode
|
// DefaultMode
|
||||||
struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return profileSettings.defaultMode.modelMode; } };
|
struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return profileSettings.defaultMode.modelMode; } };
|
||||||
@@ -269,3 +270,4 @@ struct FlipScreenAccessor : public NewSettingsAccessor<bool> { ConfigWrapper<boo
|
|||||||
|
|
||||||
// Other
|
// Other
|
||||||
struct AnhaengerIdAccessor : public NewSettingsAccessor<uint16_t> { ConfigWrapper<uint16_t> &getConfig() const override { return configs.anhaenger_id; } };
|
struct AnhaengerIdAccessor : public NewSettingsAccessor<uint16_t> { ConfigWrapper<uint16_t> &getConfig() const override { return configs.anhaenger_id; } };
|
||||||
|
struct UsernameAccessor : public NewSettingsAccessor<std::string> { ConfigWrapper<std::string> &getConfig() const override { return configs.otaUsername; } };
|
||||||
|
@@ -82,6 +82,11 @@ void initCan()
|
|||||||
|
|
||||||
void updateCan()
|
void updateCan()
|
||||||
{
|
{
|
||||||
|
if (configs.emulateFeedback.value())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
if (!tryParseCanInput())
|
if (!tryParseCanInput())
|
||||||
break;
|
break;
|
||||||
|
@@ -73,7 +73,7 @@ DebugMenu::DebugMenu()
|
|||||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERYDEBUG>, PushScreenAction<BatteryDebugMenu>, StaticMenuItemIcon<&bobbyicons::battery>>>();
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BATTERYDEBUG>, PushScreenAction<BatteryDebugMenu>, StaticMenuItemIcon<&bobbyicons::battery>>>();
|
||||||
if (configs.feature.udpcloud.isEnabled.value())
|
if (configs.feature.udpcloud.isEnabled.value())
|
||||||
{
|
{
|
||||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_TOGGLECLOUDDEBUG>, BobbyCheckbox, CloudDebugEnableAccessor>>();
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_TOGGLECLOUDDEBUG>, BobbyCheckbox, UdpCloudDebugEnableAccessor>>();
|
||||||
}
|
}
|
||||||
constructMenuItem<makeComponent<MenuItem, LastRebootReasonText, StaticFont<2>, DisabledColor, DummyAction>>();
|
constructMenuItem<makeComponent<MenuItem, LastRebootReasonText, StaticFont<2>, DisabledColor, DummyAction>>();
|
||||||
#ifdef FEATURE_CAN
|
#ifdef FEATURE_CAN
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
#include "settingsmenu.h"
|
#include "settingsmenu.h"
|
||||||
|
|
||||||
// 3rdparty lib includes
|
// 3rdparty lib includes
|
||||||
#include "actions/pushscreenaction.h"
|
#include <actions/popscreenaction.h>
|
||||||
#include "actions/popscreenaction.h"
|
#include <actions/pushscreenaction.h>
|
||||||
#include "icons/back.h"
|
#include <changevaluedisplay_string.h>
|
||||||
|
#include <icons/back.h>
|
||||||
|
#include <textwithvaluehelper.h>
|
||||||
|
|
||||||
// local includes
|
// local includes
|
||||||
#include "accessors/settingsaccessors.h"
|
#include "accessors/settingsaccessors.h"
|
||||||
@@ -21,7 +23,6 @@
|
|||||||
#include "displays/menus/featureflagsmenu.h"
|
#include "displays/menus/featureflagsmenu.h"
|
||||||
#include "displays/menus/gitmenu.h"
|
#include "displays/menus/gitmenu.h"
|
||||||
#include "displays/menus/limitssettingsmenu.h"
|
#include "displays/menus/limitssettingsmenu.h"
|
||||||
#include "displays/menus/mainmenu.h"
|
|
||||||
#include "displays/menus/modessettingsmenu.h"
|
#include "displays/menus/modessettingsmenu.h"
|
||||||
#include "displays/menus/networksettingsmenu.h"
|
#include "displays/menus/networksettingsmenu.h"
|
||||||
#include "displays/menus/selectbuildservermenu.h"
|
#include "displays/menus/selectbuildservermenu.h"
|
||||||
@@ -37,8 +38,6 @@
|
|||||||
#include "icons/time.h"
|
#include "icons/time.h"
|
||||||
#include "icons/update.h"
|
#include "icons/update.h"
|
||||||
#include "icons/wifi.h"
|
#include "icons/wifi.h"
|
||||||
#include "textwithvaluehelper.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
constexpr char TEXT_SETTINGS[] = "Settings";
|
constexpr char TEXT_SETTINGS[] = "Settings";
|
||||||
@@ -56,6 +55,7 @@ constexpr char TEXT_MODESSETTINGS[] = "Modes settings";
|
|||||||
constexpr char TEXT_CONTROLLERHARDWARESETTINGS[] = "Controller H/W settings";
|
constexpr char TEXT_CONTROLLERHARDWARESETTINGS[] = "Controller H/W settings";
|
||||||
constexpr char TEXT_BOARDCOMPUTERHARDWARESETTINGS[] = "Boardcomputer H/W settings";
|
constexpr char TEXT_BOARDCOMPUTERHARDWARESETTINGS[] = "Boardcomputer H/W settings";
|
||||||
constexpr char TEXT_FEATUREFLAGS[] = "Feature flags";
|
constexpr char TEXT_FEATUREFLAGS[] = "Feature flags";
|
||||||
|
constexpr char TEXT_USERNAME[] = "Username"; // ota-name
|
||||||
constexpr char TEXT_ANHAENGER_ID[] = "Anhaenger ID";
|
constexpr char TEXT_ANHAENGER_ID[] = "Anhaenger ID";
|
||||||
constexpr char TEXT_AUTOCONNECTBMS[] = "Auto connect BMS";
|
constexpr char TEXT_AUTOCONNECTBMS[] = "Auto connect BMS";
|
||||||
constexpr char TEXT_BUZZER[] = "Buzzer";
|
constexpr char TEXT_BUZZER[] = "Buzzer";
|
||||||
@@ -83,6 +83,14 @@ using AnhaengerIdChangeScreen = espgui::makeComponent<
|
|||||||
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
||||||
espgui::BackActionInterface<espgui::PopScreenAction>
|
espgui::BackActionInterface<espgui::PopScreenAction>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
using UsernameChangeScreen = espgui::makeComponent<
|
||||||
|
BobbyChangeValueDisplay<std::string>,
|
||||||
|
espgui::StaticText<TEXT_USERNAME>,
|
||||||
|
UsernameAccessor,
|
||||||
|
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
||||||
|
espgui::BackActionInterface<espgui::PopScreenAction>
|
||||||
|
>;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
using namespace espgui;
|
using namespace espgui;
|
||||||
@@ -117,7 +125,8 @@ SettingsMenu::SettingsMenu()
|
|||||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>, PushScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BOARDCOMPUTERHARDWARESETTINGS>, PushScreenAction<BoardcomputerHardwareSettingsMenu>, StaticMenuItemIcon<&bobbyicons::hardware>>>();
|
||||||
}
|
}
|
||||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FEATUREFLAGS>, PushScreenAction<FeatureFlagsMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_FEATUREFLAGS>, PushScreenAction<FeatureFlagsMenu>, StaticMenuItemIcon<&bobbyicons::demos>>>();
|
||||||
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_ANHAENGER_ID, AnhaengerIdAccessor>, espgui::PushScreenAction<AnhaengerIdChangeScreen>>>();
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_USERNAME>, PushScreenAction<UsernameChangeScreen>>>();
|
||||||
|
constructMenuItem<makeComponent<MenuItem, TextWithValueHelper<TEXT_ANHAENGER_ID, AnhaengerIdAccessor>, PushScreenAction<AnhaengerIdChangeScreen>>>();
|
||||||
//#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
|
//#if defined(FEATURE_BLUETOOTH) && defined(FEATURE_BMS)
|
||||||
// constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOCONNECTBMS>, BobbyCheckbox, AutoConnectBmsAccessor>>();
|
// constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_AUTOCONNECTBMS>, BobbyCheckbox, AutoConnectBmsAccessor>>();
|
||||||
//#endif
|
//#endif
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
// 3rdparty lib includes
|
// 3rdparty lib includes
|
||||||
#include <actions/popscreenaction.h>
|
#include <actions/popscreenaction.h>
|
||||||
#include <actions/pushscreenaction.h>
|
#include <actions/pushscreenaction.h>
|
||||||
#include <changevaluedisplay.h>
|
#include <changevaluedisplay_string.h>
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <icons/back.h>
|
#include <icons/back.h>
|
||||||
#include <menuitem.h>
|
#include <menuitem.h>
|
||||||
@@ -17,7 +17,8 @@ namespace {
|
|||||||
constexpr char TEXT_UDPCLOUDSETTINGS[] = "UDP Cloud settings";
|
constexpr char TEXT_UDPCLOUDSETTINGS[] = "UDP Cloud settings";
|
||||||
constexpr char TEXT_UDPCLOUDENABLED[] = "Udp Cloud enabled";
|
constexpr char TEXT_UDPCLOUDENABLED[] = "Udp Cloud enabled";
|
||||||
constexpr char TEXT_UDPSENDRATE[] = "Udp send rate";
|
constexpr char TEXT_UDPSENDRATE[] = "Udp send rate";
|
||||||
constexpr char TEXT_UDPUSESTRING[] = "Udp use std::string";
|
constexpr char TEXT_UDPHOST[] = "Udp host";
|
||||||
|
constexpr char TEXT_UDPPORT[] = "Udp port";
|
||||||
constexpr char TEXT_BACK[] = "Back";
|
constexpr char TEXT_BACK[] = "Back";
|
||||||
|
|
||||||
using UdpCloudSendRateChangeDisplay = espgui::makeComponent<
|
using UdpCloudSendRateChangeDisplay = espgui::makeComponent<
|
||||||
@@ -27,6 +28,22 @@ using UdpCloudSendRateChangeDisplay = espgui::makeComponent<
|
|||||||
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
||||||
espgui::BackActionInterface<espgui::PopScreenAction>
|
espgui::BackActionInterface<espgui::PopScreenAction>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
using UdpCloudHostChangeDisplay = espgui::makeComponent<
|
||||||
|
BobbyChangeValueDisplay<std::string>,
|
||||||
|
espgui::StaticText<TEXT_UDPHOST>,
|
||||||
|
UdpCloudHostAccessor,
|
||||||
|
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
||||||
|
espgui::BackActionInterface<espgui::PopScreenAction>
|
||||||
|
>;
|
||||||
|
|
||||||
|
using UdpCloudPortChangeDisplay = espgui::makeComponent<
|
||||||
|
BobbyChangeValueDisplay<uint16_t>,
|
||||||
|
espgui::StaticText<TEXT_UDPPORT>,
|
||||||
|
UdpCloudPortAccessor,
|
||||||
|
espgui::ConfirmActionInterface<espgui::PopScreenAction>,
|
||||||
|
espgui::BackActionInterface<espgui::PopScreenAction>
|
||||||
|
>;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
using namespace espgui;
|
using namespace espgui;
|
||||||
@@ -34,8 +51,9 @@ using namespace espgui;
|
|||||||
UdpCloudSettingsMenu::UdpCloudSettingsMenu()
|
UdpCloudSettingsMenu::UdpCloudSettingsMenu()
|
||||||
{
|
{
|
||||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UDPCLOUDENABLED>, BobbyCheckbox, UdpCloudEnabledAccessor>>();
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UDPCLOUDENABLED>, BobbyCheckbox, UdpCloudEnabledAccessor>>();
|
||||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UDPUSESTRING>, BobbyCheckbox, UdpUseStdStringAccessor>>();
|
|
||||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UDPSENDRATE>, PushScreenAction<UdpCloudSendRateChangeDisplay>>>();
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UDPSENDRATE>, PushScreenAction<UdpCloudSendRateChangeDisplay>>>();
|
||||||
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UDPHOST>, PushScreenAction<UdpCloudHostChangeDisplay>>>();
|
||||||
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_UDPPORT>, PushScreenAction<UdpCloudPortChangeDisplay>>>();
|
||||||
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, PopScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>();
|
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, PopScreenAction, StaticMenuItemIcon<&espgui::icons::back>>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
55
main/feedbackemulator.cpp
Normal file
55
main/feedbackemulator.cpp
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
#include "feedbackemulator.h"
|
||||||
|
|
||||||
|
// 3rdparty lib includes
|
||||||
|
#include <esprandom.h>
|
||||||
|
#include <randomutils.h>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
namespace feedbackemulator {
|
||||||
|
void init()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void update()
|
||||||
|
{
|
||||||
|
if (!configs.emulateFeedback.value())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &controller: controllers)
|
||||||
|
{
|
||||||
|
controller.feedback.left.dcLink = cpputils::randomNumber<int16_t>(-500, 500, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.right.dcLink = cpputils::randomNumber<int16_t>(-500, 500, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.left.speed = cpputils::randomNumber<int16_t>(-1000, 1000, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.right.speed = cpputils::randomNumber<int16_t>(-1000, 1000, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.left.error = cpputils::randomNumber(0, 4, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.right.error = cpputils::randomNumber(0, 4, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.left.angle = 0;
|
||||||
|
controller.feedback.right.angle = 0;
|
||||||
|
controller.feedback.left.dcPhaA = cpputils::randomNumber<int16_t>(-5, 5, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.right.dcPhaA = cpputils::randomNumber<int16_t>(-5, 5, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.left.dcPhaB = cpputils::randomNumber<int16_t>(-5, 5, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.right.dcPhaB = cpputils::randomNumber<int16_t>(-5, 5, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.left.dcPhaC = cpputils::randomNumber<int16_t>(-5, 5, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.right.dcPhaC = cpputils::randomNumber<int16_t>(-5, 5, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.left.chops = 0;
|
||||||
|
controller.feedback.right.chops = 0;
|
||||||
|
controller.feedback.left.hallA = true;
|
||||||
|
controller.feedback.left.hallB = false;
|
||||||
|
controller.feedback.left.hallC = true;
|
||||||
|
controller.feedback.right.hallA = false;
|
||||||
|
controller.feedback.right.hallB = true;
|
||||||
|
controller.feedback.right.hallC = false;
|
||||||
|
controller.feedback.batVoltage = cpputils::randomNumber<int16_t>(3000, 5000, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.boardTemp = cpputils::randomNumber<int16_t>(200, 600, espcpputils::esp_random_device{});
|
||||||
|
controller.feedback.left.id = 0;
|
||||||
|
controller.feedback.right.id = 0;
|
||||||
|
controller.feedback.left.iq = 0;
|
||||||
|
controller.feedback.right.iq = 0;
|
||||||
|
|
||||||
|
controller.feedbackValid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // feedbackemulator
|
6
main/feedbackemulator.h
Normal file
6
main/feedbackemulator.h
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace feedbackemulator {
|
||||||
|
void init();
|
||||||
|
void update();
|
||||||
|
} // namespace feedbackemulator
|
@@ -23,7 +23,7 @@ std::string defaultHostname()
|
|||||||
|
|
||||||
std::string defaultUsername()
|
std::string defaultUsername()
|
||||||
{
|
{
|
||||||
return fmt::format("bobby_{}", BOBBY_DEFAULT_OTA_NAME);
|
return fmt::format("bobby_{}", BOBBY_DEFAULT_USERNAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConfigManager<ConfigContainer> configs;
|
ConfigManager<ConfigContainer> configs;
|
||||||
|
@@ -324,10 +324,9 @@ public:
|
|||||||
ConfigWrapperLegacy<int16_t> reverseBeepDuration1{500, DoReset, {}, "revBeepDur1" };
|
ConfigWrapperLegacy<int16_t> reverseBeepDuration1{500, DoReset, {}, "revBeepDur1" };
|
||||||
|
|
||||||
ConfigWrapperLegacy<std::string> cloudUrl {"ws://api.bobbycar.cloud/ws", DoReset, StringOr<StringEmpty, StringValidUrl>, "cloudUrl" };
|
ConfigWrapperLegacy<std::string> cloudUrl {"ws://api.bobbycar.cloud/ws", DoReset, StringOr<StringEmpty, StringValidUrl>, "cloudUrl" };
|
||||||
ConfigWrapperLegacy<std::string> udpCloudHost {"updates.bobbycar.cloud", DoReset, {}, "udpCloudHost" };
|
|
||||||
|
|
||||||
ConfigWrapperLegacy<std::string> otaUrl {std::string{}, DoReset, StringOr<StringEmpty, StringValidUrl>, "otaUrl" };
|
ConfigWrapperLegacy<std::string> otaUrl {std::string{}, DoReset, StringOr<StringEmpty, StringValidUrl>, "otaUrl" };
|
||||||
ConfigWrapperLegacy<std::string> otaUsername {std::string{BOBBY_DEFAULT_OTA_NAME}, DoReset, {}, "otaUsername" };
|
ConfigWrapperLegacy<std::string> otaUsername {std::string{BOBBY_DEFAULT_USERNAME}, DoReset, {}, "otaUsername" };
|
||||||
ConfigWrapperLegacy<std::string> otaServerUrl {std::string{}, DoReset, StringOr<StringEmpty, StringValidUrl>, "otaServerUrl" };
|
ConfigWrapperLegacy<std::string> otaServerUrl {std::string{}, DoReset, StringOr<StringEmpty, StringValidUrl>, "otaServerUrl" };
|
||||||
ConfigWrapperLegacy<std::string> otaServerBranch {std::string{}, DoReset, {}, "otaServerBranch" };
|
ConfigWrapperLegacy<std::string> otaServerBranch {std::string{}, DoReset, {}, "otaServerBranch" };
|
||||||
std::array<ConfiguredOtaServer, 5> otaServers {
|
std::array<ConfiguredOtaServer, 5> otaServers {
|
||||||
@@ -376,10 +375,11 @@ public:
|
|||||||
} cloudSettings;
|
} cloudSettings;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
ConfigWrapperLegacy<uint32_t> udpUid {0, DoReset, {}, "cloudUDPUid" };
|
ConfigWrapperLegacy<std::string> udpToken {std::string{}, DoReset, {}, "udpToken" };
|
||||||
ConfigWrapperLegacy<bool> udpCloudEnabled {false, DoReset, {}, "enUdpCloud" };
|
ConfigWrapperLegacy<bool> udpCloudEnabled {false, DoReset, {}, "enUdpCloud" };
|
||||||
ConfigWrapperLegacy<bool> enableCloudDebug {false, DoReset, {}, "debugCloud" };
|
ConfigWrapperLegacy<bool> enableCloudDebug {false, DoReset, {}, "debugCloud" };
|
||||||
ConfigWrapperLegacy<bool> udpUseStdString {false, DoReset, {}, "udpusestdstr" };
|
ConfigWrapperLegacy<uint16_t> udpCloudPort {24243, DoReset, {}, "udpCloudPort" };
|
||||||
|
ConfigWrapperLegacy<std::string> udpCloudHost {"updates.bobbycar.cloud", DoReset, {}, "udpCloudHost" };
|
||||||
} udpCloudSettings;
|
} udpCloudSettings;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
@@ -400,7 +400,7 @@ public:
|
|||||||
ConfigWrapperLegacy<uint8_t> brightness {255, DoReset, {}, "ledbrightness" };
|
ConfigWrapperLegacy<uint8_t> brightness {255, DoReset, {}, "ledbrightness" };
|
||||||
ConfigWrapperLegacy<bool> enableAnimBlink {false, DoReset, {}, "enAnimBlink" };
|
ConfigWrapperLegacy<bool> enableAnimBlink {false, DoReset, {}, "enAnimBlink" };
|
||||||
ConfigWrapperLegacy<OtaAnimationModes> otaMode {OtaAnimationModes::GreenProgressBar, DoReset, {}, "ledOtaAnim" };
|
ConfigWrapperLegacy<OtaAnimationModes> otaMode {OtaAnimationModes::GreenProgressBar, DoReset, {}, "ledOtaAnim" };
|
||||||
ConfigWrapperLegacy<uint32_t> maxMilliamps {3000, DoReset, {}, "ledMaxMilliamps" };
|
ConfigWrapperLegacy<uint32_t> maxMilliamps {3000, DoReset, {}, "ledMaxMilliamps" };
|
||||||
ConfigWrapperLegacy<bool> enableVisualizeBlink {false, DoReset, {}, "enVisualBlink" };
|
ConfigWrapperLegacy<bool> enableVisualizeBlink {false, DoReset, {}, "enVisualBlink" };
|
||||||
std::array<ConfigWrapperLegacy<uint32_t>, 8> custom_color {
|
std::array<ConfigWrapperLegacy<uint32_t>, 8> custom_color {
|
||||||
ConfigWrapperLegacy<uint32_t> {0, DoReset, {}, "ledCustomCol1" },
|
ConfigWrapperLegacy<uint32_t> {0, DoReset, {}, "ledCustomCol1" },
|
||||||
@@ -480,6 +480,7 @@ public:
|
|||||||
} feature;
|
} feature;
|
||||||
|
|
||||||
ConfigWrapperLegacy<uint16_t> anhaenger_id {0, DoReset, {}, "anhaenger_id" };
|
ConfigWrapperLegacy<uint16_t> anhaenger_id {0, DoReset, {}, "anhaenger_id" };
|
||||||
|
ConfigWrapperLegacy<bool> emulateFeedback {false, DoReset, {}, "emuFeedback" };
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
ConfigWrapperLegacy<bool> bleEnabled {true, DoReset, {}, "bleEnabled" };
|
ConfigWrapperLegacy<bool> bleEnabled {true, DoReset, {}, "bleEnabled" };
|
||||||
@@ -671,7 +672,6 @@ public:
|
|||||||
x(reverseBeepDuration1) \
|
x(reverseBeepDuration1) \
|
||||||
\
|
\
|
||||||
x(cloudUrl) \
|
x(cloudUrl) \
|
||||||
x(udpCloudHost) \
|
|
||||||
\
|
\
|
||||||
x(otaUrl) \
|
x(otaUrl) \
|
||||||
x(otaUsername) \
|
x(otaUsername) \
|
||||||
@@ -719,10 +719,11 @@ public:
|
|||||||
x(cloudSettings.cloudKey) \
|
x(cloudSettings.cloudKey) \
|
||||||
x(cloudSettings.sendStatistic) \
|
x(cloudSettings.sendStatistic) \
|
||||||
\
|
\
|
||||||
x(udpCloudSettings.udpUid) \
|
x(udpCloudSettings.udpToken) \
|
||||||
x(udpCloudSettings.udpCloudEnabled) \
|
x(udpCloudSettings.udpCloudEnabled) \
|
||||||
x(udpCloudSettings.enableCloudDebug) \
|
x(udpCloudSettings.enableCloudDebug) \
|
||||||
x(udpCloudSettings.udpUseStdString) \
|
x(udpCloudSettings.udpCloudPort) \
|
||||||
|
x(udpCloudSettings.udpCloudHost) \
|
||||||
\
|
\
|
||||||
x(ledstrip.enableLedAnimation) \
|
x(ledstrip.enableLedAnimation) \
|
||||||
x(ledstrip.enableBrakeLights) \
|
x(ledstrip.enableBrakeLights) \
|
||||||
@@ -802,7 +803,8 @@ public:
|
|||||||
x(feature.udpcloud.isEnabled) \
|
x(feature.udpcloud.isEnabled) \
|
||||||
x(feature.webserver.isEnabled) \
|
x(feature.webserver.isEnabled) \
|
||||||
x(feature.webserver_disable_lock.isEnabled) \
|
x(feature.webserver_disable_lock.isEnabled) \
|
||||||
x(bleSettings.bleEnabled)
|
x(bleSettings.bleEnabled) \
|
||||||
|
x(emulateFeedback)
|
||||||
|
|
||||||
#define FEATURES(x) \
|
#define FEATURES(x) \
|
||||||
x(feature.ble) \
|
x(feature.ble) \
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/*
|
/*
|
||||||
* In this file there will be
|
* In this file there will be
|
||||||
* - a web-handler to get qr as plain text from http://qr.bobbycar.cloud/files/[OTA_NAME].qr that can be later triggered via in qrimportdisplay.h
|
* - a web-handler to get qr as plain text from http://qr.bobbycar.cloud/files/[USERNAME].qr that can be later triggered via in qrimportdisplay.h
|
||||||
* - getter and setter that use NVS
|
* - getter and setter that use NVS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@@ -43,6 +43,7 @@
|
|||||||
#include "dnsannounce.h"
|
#include "dnsannounce.h"
|
||||||
#include "screens.h"
|
#include "screens.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "feedbackemulator.h"
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
@@ -83,12 +84,13 @@ BobbySchedulerTask schedulerTasksArr[] {
|
|||||||
BobbySchedulerTask { "ledstrip", initLedStrip, updateLedStrip, 30ms, false },
|
BobbySchedulerTask { "ledstrip", initLedStrip, updateLedStrip, 30ms, false },
|
||||||
BobbySchedulerTask { "espnow", espnow::initESPNow, espnow::handle, 100ms, false },
|
BobbySchedulerTask { "espnow", espnow::initESPNow, espnow::handle, 100ms, false },
|
||||||
BobbySchedulerTask { "cloud", initCloud, updateCloud, 50ms, false },
|
BobbySchedulerTask { "cloud", initCloud, updateCloud, 50ms, false },
|
||||||
BobbySchedulerTask { "udpcloud", udpCloudInit, udpCloudUpdate, 50ms, false },
|
BobbySchedulerTask { "udpcloud", udpCloudInit, udpCloudUpdate, 25ms, false },
|
||||||
BobbySchedulerTask { "drivingmode", initDrivingMode, updateDrivingMode, 20ms, false },
|
BobbySchedulerTask { "drivingmode", initDrivingMode, updateDrivingMode, 20ms, false },
|
||||||
BobbySchedulerTask { "drivingstatistics", initStatistics, calculateStatistics, 100ms, false },
|
BobbySchedulerTask { "drivingstatistics", initStatistics, calculateStatistics, 100ms, false },
|
||||||
BobbySchedulerTask { "dnsannounce", init_dns_announce, handle_dns_announce, 100ms, false },
|
BobbySchedulerTask { "dnsannounce", init_dns_announce, handle_dns_announce, 100ms, false },
|
||||||
BobbySchedulerTask { "updateDisp", not_needed, updateDisplay, 20ms, true },
|
BobbySchedulerTask { "updateDisp", not_needed, updateDisplay, 20ms, true },
|
||||||
BobbySchedulerTask { "redrawDisp", not_needed, redrawDisplay, 20ms, true },
|
BobbySchedulerTask { "redrawDisp", not_needed, redrawDisplay, 20ms, true },
|
||||||
|
BobbySchedulerTask { "feedbackEmulator", feedbackemulator::init, feedbackemulator::update, 500ms, false},
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@@ -1,25 +1,24 @@
|
|||||||
#include "udpcloud.h"
|
#include "udpcloud.h"
|
||||||
|
|
||||||
|
// system includes
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include <esp_ota_ops.h>
|
||||||
|
#include <lwip/dns.h>
|
||||||
|
|
||||||
// 3rd party includes
|
// 3rd party includes
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <FastLED.h>
|
#include <FastLED.h>
|
||||||
#include <espcppmacros.h>
|
#include <espchrono.h>
|
||||||
#include <espstrutils.h>
|
|
||||||
#include <esp_ota_ops.h>
|
|
||||||
#include <espwifistack.h>
|
#include <espwifistack.h>
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
// local includes
|
// local includes
|
||||||
#include "udpsender.h"
|
|
||||||
#include "espwifistack.h"
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "fmt/format.h"
|
|
||||||
#include "globals.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "lwip/dns.h"
|
|
||||||
#include "espchrono.h"
|
|
||||||
#include "battery.h"
|
#include "battery.h"
|
||||||
#include "drivingstatistics.h"
|
#include "drivingstatistics.h"
|
||||||
|
#include "globals.h"
|
||||||
#include "newsettings.h"
|
#include "newsettings.h"
|
||||||
|
#include "udpsender.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
@@ -27,6 +26,9 @@ namespace {
|
|||||||
constexpr const char * const TAG = "bobbycloud";
|
constexpr const char * const TAG = "bobbycloud";
|
||||||
|
|
||||||
espchrono::millis_clock::time_point timestampLastFailed;
|
espchrono::millis_clock::time_point timestampLastFailed;
|
||||||
|
espchrono::millis_clock::time_point lastSend;
|
||||||
|
|
||||||
|
uint8_t packageType{0}; // cycle through packages.
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Little "flash" on statusdisplay when udp stuff is happening
|
// Little "flash" on statusdisplay when udp stuff is happening
|
||||||
@@ -42,305 +44,154 @@ void udpCloudUpdate()
|
|||||||
if (!configs.feature.udpcloud.isEnabled.value())
|
if (!configs.feature.udpcloud.isEnabled.value())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (configs.udpCloudSettings.udpCloudEnabled.value() && configs.udpCloudSettings.udpUid.touched())
|
if (configs.udpCloudSettings.udpCloudEnabled.value() && configs.udpCloudSettings.udpToken.touched())
|
||||||
sendUdpCloudPacket();
|
sendUdpCloudPacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
void spamUdpBroadcast()
|
std::optional<std::string> buildUdpCloudJson()
|
||||||
{
|
{
|
||||||
wifi_stack::UdpSender sender;
|
StaticJsonDocument<512> doc;
|
||||||
|
|
||||||
if (!sender.ready())
|
switch (++packageType)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "could not init udp sender!");
|
default:
|
||||||
return;
|
packageType = 0;
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
// uptime, potis
|
||||||
|
const auto uptime = espchrono::millis_clock::now().time_since_epoch() / 1ms;
|
||||||
|
doc["upt"] = uptime;
|
||||||
|
|
||||||
|
if (gas)
|
||||||
|
doc["pcg"] = *gas; // poti calculated gas
|
||||||
|
if (raw_gas)
|
||||||
|
doc["prg"] = *raw_gas; // poti raw gas
|
||||||
|
if (brems)
|
||||||
|
doc["pcb"] = *brems; // poti calculated brems
|
||||||
|
if (raw_brems)
|
||||||
|
doc["prb"] = *raw_brems; // poti raw brems
|
||||||
|
|
||||||
|
doc["loc"] = isLocked;
|
||||||
|
doc["mdr"] = drivingStatistics.meters_driven;
|
||||||
|
doc["mdt"] = drivingStatistics.totalMeters;
|
||||||
|
doc["cdt"] = drivingStatistics.currentDrivingTime / 1ms;
|
||||||
|
doc["sha"] = GIT_REV;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
case 1:
|
||||||
std::string buf;
|
|
||||||
const auto uptime = espchrono::millis_clock::now().time_since_epoch() / 1ms;
|
|
||||||
|
|
||||||
buf = fmt::format("uptime: {}", uptime);
|
|
||||||
|
|
||||||
if (const auto result = sender.send(ESP_IF_WIFI_STA, 187, buf); !result)
|
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "broadcast failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string buildUdpCloudJson()
|
if (const auto avgVoltage = controllers.getAvgVoltage(); avgVoltage)
|
||||||
{
|
|
||||||
static std::string version_string;
|
|
||||||
if (version_string.empty() || version_string == "-")
|
|
||||||
{
|
|
||||||
if (const esp_app_desc_t *app_desc = esp_ota_get_app_description())
|
|
||||||
{
|
{
|
||||||
version_string = app_desc->version;
|
doc["bap"] = getBatteryPercentage(*avgVoltage, BatteryCellType(configs.battery.cellType.value()));
|
||||||
}
|
doc["bav"] = *avgVoltage; // battery voltage
|
||||||
else
|
doc["pwr"] = sumCurrent * *avgVoltage; // total watt
|
||||||
{
|
|
||||||
version_string = "-";
|
|
||||||
}
|
}
|
||||||
|
doc["whl"] = getRemainingWattHours(); // watt hours left
|
||||||
|
doc["kml"] = getRemainingWattHours() / configs.battery.watthoursPerKilometer.value(); // calculated kilometers left
|
||||||
|
doc["ekm"] = getEstimatedKmLeft(); // kilometers left live calculation
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
StaticJsonDocument<1024> doc;
|
case 2:
|
||||||
std::string buf;
|
{
|
||||||
const auto uptime = espchrono::millis_clock::now().time_since_epoch() / 1ms;
|
const auto &controller = controllers.front;
|
||||||
|
|
||||||
float watt{0};
|
|
||||||
const auto avgVoltage = controllers.getAvgVoltage();
|
|
||||||
if(avgVoltage)
|
|
||||||
watt = sumCurrent * *avgVoltage;
|
|
||||||
|
|
||||||
// const auto w_per_kmh = watt / avgSpeedKmh;
|
|
||||||
|
|
||||||
// User ID
|
|
||||||
doc["uid"] = configs.udpCloudSettings.udpUid.value();
|
|
||||||
doc["upt"] = uptime;
|
|
||||||
|
|
||||||
const auto addController = [&](const Controller &controller, const bool isBack) {
|
|
||||||
if (controller.feedbackValid)
|
if (controller.feedbackValid)
|
||||||
{
|
{
|
||||||
auto arr = doc.createNestedObject(!isBack ? "f":"b");
|
doc["fbv"] = controller.getCalibratedVoltage();
|
||||||
// Voltage
|
|
||||||
arr["V"] = controller.getCalibratedVoltage();
|
|
||||||
|
|
||||||
// Amperes
|
// Amperes
|
||||||
arr["lA"] = fixCurrent(controller.feedback.left.dcLink);
|
doc["fla"] = fixCurrent(controller.feedback.left.dcLink);
|
||||||
arr["rA"] = fixCurrent(controller.feedback.right.dcLink);
|
doc["fra"] = fixCurrent(controller.feedback.right.dcLink);
|
||||||
|
|
||||||
// Temperature
|
// Temperature
|
||||||
arr[!isBack ? "fT":"bT"] = fixBoardTemp(controller.feedback.boardTemp);
|
doc["fbt"] = fixBoardTemp(controller.feedback.boardTemp);
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
arr[!isBack ? "flE":"blE"] = controller.feedback.left.error;
|
doc["fle"] = controller.feedback.left.error;
|
||||||
arr[!isBack ? "frE":"brE"] = controller.feedback.right.error;
|
doc["fre"] = controller.feedback.right.error;
|
||||||
|
|
||||||
// Speed
|
// Speed
|
||||||
arr[!isBack ? "flS":"blS"] = convertToKmh(controller.feedback.left.speed) * (controller.invertLeft?-1:1);
|
doc["fls"] = convertToKmh(controller.feedback.left.speed) * (controller.invertLeft?-1:1);
|
||||||
arr[!isBack ? "frS":"brS"] = convertToKmh(controller.feedback.right.speed) * (controller.invertRight?-1:1);
|
doc["frs"] = convertToKmh(controller.feedback.right.speed) * (controller.invertRight?-1:1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
doc[!isBack ? "f":"b"] = nullptr;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
};
|
break;
|
||||||
|
}
|
||||||
addController(controllers.front, false);
|
case 3:
|
||||||
addController(controllers.back, true);
|
|
||||||
|
|
||||||
// Potis
|
|
||||||
{
|
{
|
||||||
auto arr = doc.createNestedObject("p");
|
const auto &controller = controllers.back;
|
||||||
if (gas)
|
if (controller.feedbackValid)
|
||||||
arr["g"] = *gas;
|
{
|
||||||
if (raw_gas)
|
doc["bbv"] = controller.getCalibratedVoltage();
|
||||||
arr["rg"] = *raw_gas;
|
|
||||||
if (brems)
|
// Amperes
|
||||||
arr["b"] = *brems;
|
doc["bla"] = fixCurrent(controller.feedback.left.dcLink);
|
||||||
if (raw_brems)
|
doc["bra"] = fixCurrent(controller.feedback.right.dcLink);
|
||||||
arr["rb"] = *raw_brems;
|
|
||||||
|
// Temperature
|
||||||
|
doc["bbt"] = fixBoardTemp(controller.feedback.boardTemp);
|
||||||
|
|
||||||
|
// Errors
|
||||||
|
doc["ble"] = controller.feedback.left.error;
|
||||||
|
doc["bre"] = controller.feedback.right.error;
|
||||||
|
|
||||||
|
// Speed
|
||||||
|
doc["bls"] = convertToKmh(controller.feedback.left.speed) * (controller.invertLeft?-1:1);
|
||||||
|
doc["brs"] = convertToKmh(controller.feedback.right.speed) * (controller.invertRight?-1:1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statistics
|
// if empty, return empty string
|
||||||
if(avgVoltage)
|
if (doc.isNull())
|
||||||
{
|
{
|
||||||
doc["bP"] = getBatteryPercentage(*avgVoltage, BatteryCellType(configs.battery.cellType.value()));
|
return std::nullopt;
|
||||||
doc["bV"] = *avgVoltage;
|
|
||||||
}
|
}
|
||||||
doc["l"] = isLocked;
|
|
||||||
doc["mN"] = drivingStatistics.meters_driven;
|
|
||||||
doc["mT"] = drivingStatistics.totalMeters;
|
|
||||||
doc["dT"] = drivingStatistics.currentDrivingTime / 1ms;
|
|
||||||
doc["cW"] = watt;
|
|
||||||
doc["wN"] = drivingStatistics.wh_used;
|
|
||||||
doc["wL"] = getRemainingWattHours();
|
|
||||||
doc["kmL"] = getRemainingWattHours() / configs.battery.watthoursPerKilometer.value();
|
|
||||||
doc["ver"] = version_string.substr(0, 6);
|
|
||||||
|
|
||||||
|
doc["__t"] = configs.udpCloudSettings.udpToken.value();
|
||||||
|
|
||||||
|
std::string buf;
|
||||||
serializeJson(doc, buf);
|
serializeJson(doc, buf);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as buildUdpCloudJson, but doesnt use ArduinoJson (Probably will not expand; added for performance testing)
|
|
||||||
std::string buildUdpCloudString()
|
|
||||||
{
|
|
||||||
static std::string version_string;
|
|
||||||
if (version_string.empty() || version_string == "-")
|
|
||||||
{
|
|
||||||
if (const esp_app_desc_t *app_desc = esp_ota_get_app_description())
|
|
||||||
{
|
|
||||||
version_string = app_desc->version;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
version_string = "-";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// StaticJsonDocument<1024> doc;
|
|
||||||
std::string buf;
|
|
||||||
buf.reserve(1024);
|
|
||||||
|
|
||||||
const auto uptime = espchrono::millis_clock::now().time_since_epoch() / 1ms;
|
|
||||||
|
|
||||||
float watt{0};
|
|
||||||
const auto avgVoltage = controllers.getAvgVoltage();
|
|
||||||
if(avgVoltage)
|
|
||||||
watt = sumCurrent * *avgVoltage;
|
|
||||||
// const auto w_per_kmh = watt / avgSpeedKmh;
|
|
||||||
|
|
||||||
buf += "{";
|
|
||||||
|
|
||||||
// User ID
|
|
||||||
if(configs.udpCloudSettings.udpUid.value())
|
|
||||||
buf += fmt::format("\"uid\":{},", configs.udpCloudSettings.udpUid.value());
|
|
||||||
else
|
|
||||||
buf += "\"uid\":null,";
|
|
||||||
|
|
||||||
if(uptime)
|
|
||||||
buf += fmt::format("\"upt\":{},", uptime);
|
|
||||||
else
|
|
||||||
buf += "\"uid\":null,";
|
|
||||||
|
|
||||||
const auto addController = [&](const Controller &controller, const bool isBack) {
|
|
||||||
if (controller.feedbackValid)
|
|
||||||
{
|
|
||||||
buf += fmt::format("\"{}\":{{", !isBack ? "f":"b");
|
|
||||||
// Voltage
|
|
||||||
if (controller.getCalibratedVoltage())
|
|
||||||
buf += fmt::format("\"V\":{},", controller.getCalibratedVoltage());
|
|
||||||
else
|
|
||||||
buf += "\"V\":null,";
|
|
||||||
|
|
||||||
// Amperes
|
|
||||||
if (controller.feedback.left.dcLink)
|
|
||||||
buf += fmt::format("\"lA\":{},", fixCurrent(controller.feedback.left.dcLink));
|
|
||||||
else
|
|
||||||
buf += "\"lA\":null,";
|
|
||||||
|
|
||||||
if (controller.feedback.right.dcLink)
|
|
||||||
buf += fmt::format("\"rA\":{},", fixCurrent(controller.feedback.right.dcLink));
|
|
||||||
else
|
|
||||||
buf += "\"rA\":null,";
|
|
||||||
|
|
||||||
// Temperature
|
|
||||||
if (controller.feedback.right.dcLink)
|
|
||||||
buf += fmt::format("\"{}\":{},", !isBack ? "fT":"bT", fixBoardTemp(controller.feedback.boardTemp));
|
|
||||||
else
|
|
||||||
buf += fmt::format("\"{}\":null,", !isBack ? "fT":"bT");
|
|
||||||
|
|
||||||
// Errors
|
|
||||||
if (controller.feedback.left.error)
|
|
||||||
buf += fmt::format("\"{}\":{},", !isBack ? "flE":"blE", controller.feedback.left.error);
|
|
||||||
else
|
|
||||||
buf += fmt::format("\"{}\":null,", !isBack ? "flE":"blE");
|
|
||||||
|
|
||||||
if (controller.feedback.right.error)
|
|
||||||
buf += fmt::format("\"{}\":{},", !isBack ? "frE":"brE", controller.feedback.right.error);
|
|
||||||
else
|
|
||||||
buf += fmt::format("\"{}\":null,", !isBack ? "frE":"brE");
|
|
||||||
|
|
||||||
|
|
||||||
// Speed
|
|
||||||
if (controller.feedback.left.speed)
|
|
||||||
buf += fmt::format("\"{}\":{},", !isBack ? "flS":"blS", convertToKmh(controller.feedback.left.speed) * (controller.invertLeft?-1:1));
|
|
||||||
else
|
|
||||||
buf += fmt::format("\"{}\":null,", !isBack ? "flS":"blS");
|
|
||||||
|
|
||||||
if (controller.feedback.right.speed)
|
|
||||||
buf += fmt::format("\"{}\":{},", !isBack ? "frS":"brS", convertToKmh(controller.feedback.right.speed) * (controller.invertRight?-1:1));
|
|
||||||
else
|
|
||||||
buf += fmt::format("\"{}\":null,", !isBack ? "frS":"brS");
|
|
||||||
|
|
||||||
buf += "},";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buf += fmt::format("\"{}\":null,", !isBack ? "f":"b");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
addController(controllers.front, false);
|
|
||||||
addController(controllers.back, true);
|
|
||||||
|
|
||||||
// Potis
|
|
||||||
{
|
|
||||||
buf += "\"p\":{";
|
|
||||||
if (gas)
|
|
||||||
buf += fmt::format("\"g\":{},",*gas);
|
|
||||||
else
|
|
||||||
buf += "\"g\":null,";
|
|
||||||
|
|
||||||
if (raw_gas)
|
|
||||||
buf += fmt::format("\"rg\":{},",*raw_gas);
|
|
||||||
else
|
|
||||||
buf += "\"rg\":null,";
|
|
||||||
|
|
||||||
if (brems)
|
|
||||||
buf += fmt::format("\"b\":{},",*brems);
|
|
||||||
else
|
|
||||||
buf += "\"b\":null,";
|
|
||||||
|
|
||||||
if (raw_brems)
|
|
||||||
buf += fmt::format("\"rb\":{},",*raw_brems);
|
|
||||||
else
|
|
||||||
buf += "\"rb\":null,";
|
|
||||||
|
|
||||||
buf += "},";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Statistics
|
|
||||||
if(avgVoltage)
|
|
||||||
{
|
|
||||||
buf += fmt::format("\"bP\":{},", getBatteryPercentage(*avgVoltage, BatteryCellType(configs.battery.cellType.value())));
|
|
||||||
buf += fmt::format("\"bV\":{},", *avgVoltage);
|
|
||||||
}
|
|
||||||
buf += fmt::format("\"l\":{},", isLocked);
|
|
||||||
buf += fmt::format("\"mN\":{},", drivingStatistics.meters_driven);
|
|
||||||
buf += fmt::format("\"mT\":{},", drivingStatistics.totalMeters);
|
|
||||||
buf += fmt::format("\"dT\":{},", drivingStatistics.currentDrivingTime / 1ms);
|
|
||||||
buf += fmt::format("\"cW\":{},", watt);
|
|
||||||
buf += fmt::format("\"wN\":{},", drivingStatistics.wh_used);
|
|
||||||
buf += fmt::format("\"wL\":{},", getRemainingWattHours());
|
|
||||||
buf += fmt::format("\"kmL\":{},", getRemainingWattHours() / configs.battery.watthoursPerKilometer.value());
|
|
||||||
buf += fmt::format("\"ver\":{}", version_string.substr(0, 6));
|
|
||||||
|
|
||||||
buf += "}";
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendUdpCloudPacket()
|
void sendUdpCloudPacket()
|
||||||
{
|
{
|
||||||
EVERY_N_MILLIS(configs.boardcomputerHardware.timersSettings.udpSendRateMs.value()) {
|
if (espchrono::ago(timestampLastFailed) < 2s)
|
||||||
if (espchrono::ago(timestampLastFailed) < 2s)
|
{
|
||||||
{
|
visualSendUdpPacket = false;
|
||||||
visualSendUdpPacket = false;
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (configs.udpCloudHost.value().empty())
|
if (configs.udpCloudSettings.udpCloudHost.value().empty() || configs.udpCloudSettings.udpCloudPort.value() == 0)
|
||||||
{
|
{
|
||||||
visualSendUdpPacket = false;
|
visualSendUdpPacket = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wifi_stack::get_sta_status() != wifi_stack::WiFiStaStatus::CONNECTED)
|
if (wifi_stack::get_sta_status() != wifi_stack::WiFiStaStatus::CONNECTED)
|
||||||
{
|
{
|
||||||
visualSendUdpPacket = false;
|
visualSendUdpPacket = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(espchrono::ago(lastSend) / 1ms > configs.boardcomputerHardware.timersSettings.udpSendRateMs.value())
|
||||||
|
{
|
||||||
|
lastSend = espchrono::millis_clock::now();
|
||||||
|
|
||||||
ip_addr_t udpCloudIp;
|
ip_addr_t udpCloudIp;
|
||||||
|
|
||||||
if (const auto res = dns_gethostbyname(configs.udpCloudHost.value().c_str(), &udpCloudIp, nullptr, nullptr); res != ERR_OK)
|
if (const auto res = dns_gethostbyname(configs.udpCloudSettings.udpCloudHost.value().c_str(), &udpCloudIp, nullptr, nullptr); res != ERR_OK)
|
||||||
{
|
{
|
||||||
if (res == ERR_INPROGRESS)
|
ESP_LOGE(TAG, "dns_gethostbyname() failed because: (%s) (%i)", lwip_strerr(res), res);
|
||||||
{
|
|
||||||
ESP_LOGD(TAG, "dns_gethostbyname() failed because: %i", res);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ESP_LOGE(TAG, "dns_gethostbyname() failed because: %i", res);
|
|
||||||
}
|
|
||||||
timestampLastFailed = espchrono::millis_clock::now();
|
timestampLastFailed = espchrono::millis_clock::now();
|
||||||
visualSendUdpPacket = false;
|
visualSendUdpPacket = false;
|
||||||
return;
|
return;
|
||||||
@@ -355,14 +206,21 @@ void sendUdpCloudPacket()
|
|||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_in receipient;
|
sockaddr_in receipient;
|
||||||
receipient.sin_port = htons(24242);
|
receipient.sin_port = htons(configs.udpCloudSettings.udpCloudPort.value());
|
||||||
receipient.sin_addr.s_addr = udpCloudIp.u_addr.ip4.addr;
|
receipient.sin_addr.s_addr = udpCloudIp.u_addr.ip4.addr;
|
||||||
receipient.sin_family = AF_INET;
|
receipient.sin_family = AF_INET;
|
||||||
|
|
||||||
wifi_stack::UdpSender udpCloudSender;
|
wifi_stack::UdpSender udpCloudSender;
|
||||||
std::string buf;
|
std::string buf;
|
||||||
buf = configs.udpCloudSettings.udpUseStdString.value() ? buildUdpCloudString() : buildUdpCloudJson();
|
|
||||||
|
|
||||||
|
if (const auto json = buildUdpCloudJson(); !json)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buf = *json;
|
||||||
|
}
|
||||||
|
|
||||||
if (const auto result = udpCloudSender.send(receipient, buf); !result)
|
if (const auto result = udpCloudSender.send(receipient, buf); !result)
|
||||||
{
|
{
|
||||||
@@ -370,7 +228,8 @@ void sendUdpCloudPacket()
|
|||||||
ESP_LOGE(TAG, "send to cloud failed: %.*s (ip=%s)", result.error().size(), result.error().data(), wifi_stack::toString(udpCloudIp.u_addr.ip4).c_str());
|
ESP_LOGE(TAG, "send to cloud failed: %.*s (ip=%s)", result.error().size(), result.error().data(), wifi_stack::toString(udpCloudIp.u_addr.ip4).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGD(TAG, "now: %s", buf.c_str());
|
// ESP_LOGI(TAG, "%s", buf.c_str());
|
||||||
|
|
||||||
visualSendUdpPacket = !visualSendUdpPacket;
|
visualSendUdpPacket = !visualSendUdpPacket;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// system includes
|
// system includes
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// Little "flash" on statusdisplay when udp stuff is happening
|
// Little "flash" on statusdisplay when udp stuff is happening
|
||||||
@@ -9,7 +10,5 @@ extern bool visualSendUdpPacket;
|
|||||||
void udpCloudInit();
|
void udpCloudInit();
|
||||||
void udpCloudUpdate();
|
void udpCloudUpdate();
|
||||||
|
|
||||||
void spamUdpBroadcast();
|
std::optional<std::string> buildUdpCloudJson();
|
||||||
std::string buildUdpCloudJson();
|
|
||||||
std::string buildUdpCloudString();
|
|
||||||
void sendUdpCloudPacket();
|
void sendUdpCloudPacket();
|
||||||
|
Reference in New Issue
Block a user