Added esp-now timesync

This commit is contained in:
CommanderRedYT
2021-12-14 19:15:14 +01:00
parent 647f86906b
commit 595a508d93
11 changed files with 162 additions and 17 deletions

View File

@ -78,6 +78,7 @@ set(headers
displays/menus/dynamicdebugmenu.h
displays/menus/enablemenu.h
displays/menus/espnowmenu.h
displays/menus/espnowsettingsmenu.h
displays/menus/feedbackdebugmenu.h
displays/menus/gametrakmodesettingsmenu.h
displays/menus/genericwifisettingsmenu.h
@ -282,6 +283,7 @@ set(sources
displays/menus/dynamicdebugmenu.cpp
displays/menus/enablemenu.cpp
displays/menus/espnowmenu.cpp
displays/menus/espnowsettingsmenu.cpp
displays/menus/feedbackdebugmenu.cpp
displays/menus/gametrakmodesettingsmenu.cpp
displays/menus/genericwifisettingsmenu.cpp

View File

@ -14,15 +14,19 @@ struct RefAccessorSaveSettings : public virtual espgui::RefAccessor<T>
void setValue(T value) override { espgui::RefAccessor<T>::setValue(value); saveSettings(); };
};
// Bms
#ifdef FEATURE_BMS
struct AutoConnectBmsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.autoConnectBms; } };
#endif
// Buzzer
struct ReverseBeepAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.buzzer.reverseBeep; } };
struct ReverseBeepFreq0Accessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.buzzer.reverseBeepFreq0; } };
struct ReverseBeepFreq1Accessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.buzzer.reverseBeepFreq1; } };
struct ReverseBeepDuration0Accessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.buzzer.reverseBeepDuration0; } };
struct ReverseBeepDuration1Accessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.buzzer.reverseBeepDuration1; } };
// Limits
struct IMotMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.iMotMax; } };
struct IDcMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.iDcMax; } };
struct NMotMaxKmhAccessor : public virtual espgui::AccessorInterface<int16_t>
@ -34,22 +38,27 @@ struct NMotMaxRpmAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &g
struct FieldWeakMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.fieldWeakMax; } };
struct PhaseAdvMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.limits.phaseAdvMax; } };
// WiFi
struct WifiStaEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.wifiSettings.wifiStaEnabled; } };
struct WifiApEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.wifiSettings.wifiApEnabled; } };
// Bluetooth
#ifdef FEATURE_BLUETOOTH
struct AutoBluetoothModeAccessor : public RefAccessorSaveSettings<BluetoothMode> { BluetoothMode &getRef() const override { return settings.bluetoothSettings.autoBluetoothMode; } };
#endif
// Bluetooth Low Energy
#ifdef FEATURE_BLE
struct BleEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.bleSettings.bleEnabled; } };
#endif
// Cloud
#ifdef FEATURE_CLOUD
struct CloudEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.cloudSettings.cloudEnabled; } };
struct CloudTransmitTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.cloudSettings.cloudTransmitTimeout; } };
#endif
// Time
struct TimezoneOffsetAccessor : public virtual espgui::AccessorInterface<int32_t>
{
int32_t getValue() const override { return settings.timeSettings.timezoneOffset.count(); }
@ -66,6 +75,7 @@ struct TimeSyncIntervalAccessor : public virtual espgui::AccessorInterface<int32
};
#endif
// Controller Hardware
struct FrontLeftEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableFrontLeft; } };
struct FrontRightEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableFrontRight; } };
struct BackLeftEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.enableBackLeft; } };
@ -89,6 +99,8 @@ struct SwapFrontBackAccessor : public RefAccessorSaveSettings<bool> {
void setValue(bool value) override { RefAccessorSaveSettings<bool>::setValue(value); updateSwapFrontBack(); };
#endif
};
// CAN
#ifdef FEATURE_CAN
struct SendFrontCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendFrontCanCmd; } };
struct SendBackCanCmdAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.controllerHardware.sendBackCanCmd; } };
@ -96,6 +108,7 @@ struct CanTransmitTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { in
struct CanReceiveTimeoutAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.controllerHardware.canReceiveTimeout; } };
#endif
// Input devices
struct SampleCountAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.sampleCount; } };
struct GasMinAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gasMin; } };
struct GasMaxAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.gasMax; } };
@ -117,9 +130,13 @@ struct ModeUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_
struct StatsUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.statsUpdateRate; } };
struct DisplayUpdateRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayUpdateRate; } };
struct DisplayRedrawRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.displayRedrawRate; } };
// CAN
#ifdef FEATURE_CAN
struct CanReceiveRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.canReceiveRate; } };
#endif
// Cloud
#ifdef FEATURE_CLOUD
struct CloudCollectRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.cloudCollectRate; } };
struct CloudSendRateAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.boardcomputerHardware.timersSettings.cloudSendRate; } };
@ -129,6 +146,7 @@ struct CloudDebugEnableAccessor : public RefAccessorSaveSettings<bool> { bool &g
struct UdpUseStdStringAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.cloudSettings.udpUseStdString; } };
#endif
// DefaultMode
struct DefaultModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.defaultMode.modelMode; } };
struct DefaultModeHybridModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.hybrid.hybridMode; } };
struct DefaultModeSquareGasAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.defaultMode.squareGas; } };
@ -153,15 +171,19 @@ struct DefaultModeEnableHybridAccessor : public RefAccessorSaveSettings<bool> {
struct DefaultModeHybridActivationLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.hybrid.activationLimit; } };
struct DefaultModeHybridDeactivationLimitAccessor : public RefAccessorSaveSettings<int16_t> { int16_t &getRef() const override { return settings.hybrid.deactivationLimit; } };
// TempomatMode
struct TempomatModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.tempomatMode.modelMode; } };
// LarsmMode
struct LarsmModeModelModeAccessor : public RefAccessorSaveSettings<UnifiedModelMode> { UnifiedModelMode &getRef() const override { return settings.larsmMode.modelMode; } };
struct LarsmModeModeAccessor : public RefAccessorSaveSettings<LarsmModeMode> { LarsmModeMode &getRef() const override { return settings.larsmMode.mode; } };
struct LarsmModeIterationsAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.larsmMode.iterations; } };
// MotortestMode
struct MotortestModeMultiplikatorAccessor : public RefAccessorSaveSettings<uint8_t> { uint8_t &getRef() const override { return settings.motortestMode.multiplikator; } };
struct MotortestMaxPwmAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.motortestMode.maxPwm; } };
// Ledstrip
#ifdef FEATURE_LEDSTRIP
struct EnableLedAnimationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableLedAnimation; } };
struct EnableBrakeLightsAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.ledstrip.enableBrakeLights; } };
@ -190,13 +212,19 @@ struct BatteryParallelCellsAccessor : public RefAccessorSaveSettings<uint8_t> {
struct BatteryWHperKMAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.battery.watthoursPerKilometer; } };
struct BatteryApplyCalibrationAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.battery.applyCalibration; } };
// Lockscreen
struct LockscreenAllowPresetSwitchAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.lockscreen.allowPresetSwitch; } };
template<uint8_t index>
struct LockscreenPinDigitAccessor : public RefAccessorSaveSettings<int8_t> { int8_t &getRef() const override { return settings.lockscreen.pin[index]; } };
// Handbremse
struct HandbremsEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.enable; } };
struct HandbremsModeAccessor : public RefAccessorSaveSettings<HandbremseMode> { HandbremseMode &getRef() const override { return settings.handbremse.mode; } };
struct HandbremsTimeoutAccessor : public RefAccessorSaveSettings<uint16_t> { uint16_t &getRef() const override { return settings.handbremse.triggerTimeout; } };
struct HandbremsAutomaticAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.automatic; } };
struct HandbremsVisualizeAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.handbremse.visualize; } };
// ESP Now
struct ESPNowSyncTimeEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.espnow.syncTime; } };
struct ESPNowSyncTimeWithOthersEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.espnow.syncTimeWithOthers; } };
struct ESPNowSyncBlinkEnabledAccessor : public RefAccessorSaveSettings<bool> { bool &getRef() const override { return settings.espnow.syncBlink; } };

View File

@ -6,8 +6,10 @@
#include "actions/toggleboolaction.h"
#include "checkboxicon.h"
#include "icons/back.h"
#include "icons/settings.h"
#include "icons/time.h"
#include "settingsmenu.h"
#include "displays/menus/espnowsettingsmenu.h"
#include "displays/menus/settingsmenu.h"
using namespace espgui;
@ -18,6 +20,7 @@ EspNowMenu::EspNowMenu() {
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_SENDTSMSG>, espnowmenu::SendBobbycarTimesyncMessageAction, StaticMenuItemIcon<&bobbyicons::time>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_RECEIVETS>, ToggleBoolAction, CheckboxIcon, espnowmenu::ReceiveTimeStampAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_RECEIVETSFROMBOBBY>, ToggleBoolAction, CheckboxIcon, espnowmenu::ReceiveTsFromOtherBobbycarsAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_SETTINGS>, SwitchScreenAction<EspNowSettingsMenu>, StaticMenuItemIcon<&bobbyicons::settings>>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<SettingsMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}

View File

@ -0,0 +1,29 @@
#include "espnowsettingsmenu.h"
#ifdef FEATURE_ESPNOW
#include "accessors/settingsaccessors.h"
#include "actions/dummyaction.h"
#include "actions/switchscreenaction.h"
#include "actions/toggleboolaction.h"
#include "checkboxicon.h"
#include "icons/back.h"
#include "icons/time.h"
#include "espnowmenu.h"
using namespace espgui;
namespace espnowsettingsmenu {
} // namespace
EspNowSettingsMenu::EspNowSettingsMenu() {
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_SYNCTIME>, ToggleBoolAction, CheckboxIcon, ESPNowSyncTimeEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_SYNCWITHOTHERS>, ToggleBoolAction, CheckboxIcon, ESPNowSyncTimeWithOthersEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_ESPNOW_SYNCBLINK>, ToggleBoolAction, CheckboxIcon, ESPNowSyncBlinkEnabledAccessor>>();
constructMenuItem<makeComponent<MenuItem, StaticText<TEXT_BACK>, SwitchScreenAction<EspNowMenu>, StaticMenuItemIcon<&espgui::icons::back>>>();
}
void EspNowSettingsMenu::back()
{
switchScreen<EspNowMenu>();
}
#endif

View File

@ -0,0 +1,29 @@
#pragma once
#ifdef FEATURE_ESPNOW
#include <accessorinterface.h>
#include <actioninterface.h>
#include <espchrono.h>
#include <fmt/core.h>
#include <menudisplay.h>
#include <textinterface.h>
#include <texts.h>
#include "espnowfunctions.h"
using namespace espgui;
namespace espnowsettingsmenu {
} // namespace
class EspNowSettingsMenu :
public espgui::MenuDisplay,
public espgui::StaticText<TEXT_ESPNOW_SETTINGS>
{
public:
EspNowSettingsMenu();
void back() override;
};
#endif

View File

@ -43,7 +43,7 @@ void onReceive(const uint8_t *mac_addr, const uint8_t *data, int data_len)
}
else
{
ESP_LOGW(TAG, "Invalid message: Could not find ':'");
ESP_LOGW(TAG, "Invalid message: Could not find ':' (%s)", data_str.c_str());
}
}
@ -116,15 +116,6 @@ void handle()
return;
}
if (receiveTimeStamp)
{
const auto thisYear = int(espchrono::toDateTime(espchrono::utc_clock::now()).date.year());
if (abs(thisYear - espnow::lastYear) > 1)
{
receiveTimeStamp = false;
}
}
if(message_queue.size())
{
for (const esp_now_message_t &msg : message_queue)
@ -134,7 +125,7 @@ void handle()
if (msg.type == "T")
{
if (!receiveTimeStamp)
if (!receiveTimeStamp || !settings.espnow.syncTime)
return;
if (const auto result = cpputils::fromString<uint64_t>(msg.content); result)
@ -148,8 +139,17 @@ void handle()
}
else if (msg.type == "BOBBYT")
{
if (!receiveTsFromOtherBobbycars)
if (!receiveTsFromOtherBobbycars || !settings.espnow.syncTimeWithOthers)
return;
if (const auto result = cpputils::fromString<uint64_t>(msg.content); result)
{
onRecvTs(*result, true);
}
else
{
ESP_LOGW(TAG, "could not parse number: %.*s", result.error().size(), result.error().data());
}
}
else
{
@ -159,11 +159,22 @@ void handle()
}
}
void onRecvTs(uint64_t millis)
void onRecvTs(uint64_t millis, bool isFromBobbycar)
{
const auto milliseconds = std::chrono::milliseconds(millis);
const auto timepoint = espchrono::utc_clock::time_point(milliseconds);
ESP_LOGW(TAG, "setting current time to %s", espchrono::toString(timepoint.time_since_epoch()).c_str());
time_set_now(timepoint);
if (receiveTimeStamp)
{
if (const auto thisYear = int(espchrono::toDateTime(espchrono::utc_clock::now()).date.year()); abs(thisYear - espnow::lastYear) > 1)
{
espnow::lastYear = thisYear;
receiveTimeStamp = false;
}
}
receiveTsFromOtherBobbycars = false;
}

View File

@ -23,7 +23,7 @@ extern std::list<esp_now_peer_info_t> peers;
void onReceive(const uint8_t *mac_addr, const uint8_t *data, int data_len);
void initESPNow();
void handle();
void onRecvTs(uint64_t millis);
void onRecvTs(uint64_t millis, bool isFromBobbycar = false);
esp_err_t send_espnow_message(std::string message);
} // namespace espnow
#endif

View File

@ -300,6 +300,19 @@ constexpr Settings::SavedStatistics defaultSavedStatistics {
.totalCentimeters = 0,
};
#ifdef FEATURE_ESPNOW
constexpr Settings::ESPNOW defaultEspNowSettings {
#ifndef FEATURE_NTP
.syncTime = true,
.syncTimeWithOthers = true,
#else
.syncTime = false,
.syncTimeWithOthers = false,
#endif
.syncBlink = false
};
#endif
constexpr Settings defaultSettings {
#ifdef FEATURE_BMS
.autoConnectBms = false,
@ -330,7 +343,10 @@ constexpr Settings defaultSettings {
.hybrid = defaultHybrid,
.lockscreen = defaultLockscreen,
.savedStatistics = defaultSavedStatistics,
.handbremse = defaultHandbremse
.handbremse = defaultHandbremse,
#ifdef FEATURE_ESPNOW
.espnow = defaultEspNowSettings,
#endif
};
StringSettings makeDefaultStringSettings();

View File

@ -224,6 +224,13 @@ struct Settings
bool enable;
bool visualize;
} handbremse;
#ifdef FEATURE_ESPNOW
struct ESPNOW {
bool syncTime;
bool syncTimeWithOthers;
bool syncBlink;
} espnow;
#endif
template<typename T>
void executeForEveryCommonSetting(T &&callable);
@ -362,6 +369,14 @@ void Settings::executeForEveryCommonSetting(T &&callable)
callable("handBremsM", handbremse.mode);
callable("handBremsT", handbremse.triggerTimeout);
callable("handBremsV", handbremse.visualize);
#ifdef FEATURE_ESPNOW
callable("espnowSyncT", espnow.syncTime);
callable("espnowSyncTWO", espnow.syncTimeWithOthers);
#ifdef FEATURE_LEDSTRIP
callable("espnowSyncBl", espnow.syncBlink);
#endif
#endif
}
template<typename T>

View File

@ -550,4 +550,10 @@ char TEXT_ESPNOW_MENU[] = "ESP-Now Menu";
char TEXT_ESPNOW_RECEIVETS[] = "Recv Ts State";
char TEXT_ESPNOW_RECEIVETSFROMBOBBY[] = "Recv BobbyTs State";
char TEXT_ESPNOW_SENDTSMSG[] = "Broadcast Time";
//EspNowSettingsMenu
char TEXT_ESPNOW_SETTINGS[] = "ESP-Now settings";
char TEXT_ESPNOW_SYNCTIME[] = "Sync time (no NTP)";
char TEXT_ESPNOW_SYNCWITHOTHERS[] = "Sync time with others";
char TEXT_ESPNOW_SYNCBLINK[] = "Sync blink";
} // namespace

View File

@ -550,6 +550,12 @@ extern char TEXT_ESPNOW_MENU[];
extern char TEXT_ESPNOW_RECEIVETS[];
extern char TEXT_ESPNOW_RECEIVETSFROMBOBBY[];
extern char TEXT_ESPNOW_SENDTSMSG[];
//EspNowSettingsMenu
extern char TEXT_ESPNOW_SETTINGS[];
extern char TEXT_ESPNOW_SYNCTIME[];
extern char TEXT_ESPNOW_SYNCWITHOTHERS[];
extern char TEXT_ESPNOW_SYNCBLINK[];
} // namespace
using namespace bobbytexts;