Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/settings/SettingWeatherFormat.cpp
displayapp/screens/settings/SettingWakeUp.cpp
displayapp/screens/settings/SettingDisplay.cpp
displayapp/screens/settings/SettingHeartRate.cpp
displayapp/screens/settings/SettingSteps.cpp
displayapp/screens/settings/SettingSetDateTime.cpp
displayapp/screens/settings/SettingSetDate.cpp
Expand Down
8 changes: 4 additions & 4 deletions src/components/heartrate/HeartRateController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ void HeartRateController::Update(HeartRateController::States newState, uint8_t h
}
}

void HeartRateController::Start() {
void HeartRateController::Enable() {
if (task != nullptr) {
state = States::NotEnoughData;
task->PushMessage(Pinetime::Applications::HeartRateTask::Messages::StartMeasurement);
task->PushMessage(Pinetime::Applications::HeartRateTask::Messages::Enable);
}
}

void HeartRateController::Stop() {
void HeartRateController::Disable() {
if (task != nullptr) {
state = States::Stopped;
task->PushMessage(Pinetime::Applications::HeartRateTask::Messages::StopMeasurement);
task->PushMessage(Pinetime::Applications::HeartRateTask::Messages::Disable);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/components/heartrate/HeartRateController.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ namespace Pinetime {
namespace Controllers {
class HeartRateController {
public:
enum class States { Stopped, NotEnoughData, NoTouch, Running };
enum class States : uint8_t { Stopped, NotEnoughData, NoTouch, Running };

HeartRateController() = default;
void Start();
void Stop();
void Enable();
void Disable();
void Update(States newState, uint8_t heartRate);

void SetHeartRateTask(Applications::HeartRateTask* task);
Expand Down
5 changes: 5 additions & 0 deletions src/components/heartrate/Ppg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,12 @@ int8_t Ppg::Preprocess(uint16_t hrs, uint16_t als) {

int Ppg::HeartRate() {
if (dataIndex < dataLength) {
if (!enoughData) {
return -2;
}
return 0;
}
enoughData = true;
int hr = 0;
hr = ProcessHeartRate(resetSpectralAvg);
resetSpectralAvg = false;
Expand All @@ -171,6 +175,7 @@ int Ppg::HeartRate() {
void Ppg::Reset(bool resetDaqBuffer) {
if (resetDaqBuffer) {
dataIndex = 0;
enoughData = false;
}
avgIndex = 0;
dataAverage.fill(0.0f);
Expand Down
1 change: 1 addition & 0 deletions src/components/heartrate/Ppg.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ namespace Pinetime {
uint16_t dataIndex = 0;
float peakLocation;
bool resetSpectralAvg = true;
bool enoughData = false;

int ProcessHeartRate(bool init);
float HeartRateAverage(float hr);
Expand Down
20 changes: 19 additions & 1 deletion src/components/settings/Settings.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once
#include <cstdint>
#include <bitset>
#include <limits>
#include <optional>
#include "components/brightness/BrightnessController.h"
#include "components/fs/FS.h"
#include "displayapp/apps/Apps.h"
Expand Down Expand Up @@ -334,10 +336,25 @@ namespace Pinetime {
return (settings.dfuAndFsEnabledOnBoot ? DfuAndFsMode::Enabled : DfuAndFsMode::Disabled);
};

std::optional<uint16_t> GetHeartRateBackgroundMeasurementInterval() const {
if (settings.heartRateBackgroundPeriod == std::numeric_limits<uint16_t>::max()) {
return std::nullopt;
}
return settings.heartRateBackgroundPeriod;
}

void SetHeartRateBackgroundMeasurementInterval(std::optional<uint16_t> newIntervalInSeconds) {
newIntervalInSeconds = newIntervalInSeconds.value_or(std::numeric_limits<uint16_t>::max());
if (newIntervalInSeconds != settings.heartRateBackgroundPeriod) {
settingsChanged = true;
}
settings.heartRateBackgroundPeriod = newIntervalInSeconds.value();
}

private:
Pinetime::Controllers::FS& fs;

static constexpr uint32_t settingsVersion = 0x0009;
static constexpr uint32_t settingsVersion = 0x000a;

struct SettingsData {
uint32_t version = settingsVersion;
Expand Down Expand Up @@ -365,6 +382,7 @@ namespace Pinetime {
Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium;

bool dfuAndFsEnabledOnBoot = false;
uint16_t heartRateBackgroundPeriod = std::numeric_limits<uint16_t>::max(); // Disabled by default
};

SettingsData settings;
Expand Down
4 changes: 4 additions & 0 deletions src/displayapp/DisplayApp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "displayapp/screens/settings/SettingSteps.h"
#include "displayapp/screens/settings/SettingSetDateTime.h"
#include "displayapp/screens/settings/SettingChimes.h"
#include "displayapp/screens/settings/SettingHeartRate.h"
#include "displayapp/screens/settings/SettingShakeThreshold.h"
#include "displayapp/screens/settings/SettingBluetooth.h"
#include "displayapp/screens/settings/SettingOTA.h"
Expand Down Expand Up @@ -603,6 +604,9 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
case Apps::SettingWakeUp:
currentScreen = std::make_unique<Screens::SettingWakeUp>(settingsController);
break;
case Apps::SettingHeartRate:
currentScreen = std::make_unique<Screens::SettingHeartRate>(settingsController);
break;
case Apps::SettingDisplay:
currentScreen = std::make_unique<Screens::SettingDisplay>(settingsController);
break;
Expand Down
1 change: 1 addition & 0 deletions src/displayapp/apps/Apps.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ namespace Pinetime {
SettingWatchFace,
SettingTimeFormat,
SettingWeatherFormat,
SettingHeartRate,
SettingDisplay,
SettingWakeUp,
SettingSteps,
Expand Down
4 changes: 2 additions & 2 deletions src/displayapp/screens/HeartRate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@ void HeartRate::Refresh() {
void HeartRate::OnStartStopEvent(lv_event_t event) {
if (event == LV_EVENT_CLICKED) {
if (heartRateController.State() == Controllers::HeartRateController::States::Stopped) {
heartRateController.Start();
heartRateController.Enable();
UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped);
wakeLock.Lock();
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
} else {
heartRateController.Stop();
heartRateController.Disable();
UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped);
wakeLock.Release();
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
Expand Down
71 changes: 71 additions & 0 deletions src/displayapp/screens/settings/SettingHeartRate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "displayapp/screens/settings/SettingHeartRate.h"
#include <lvgl/lvgl.h>
#include "displayapp/screens/Styles.h"
#include "displayapp/screens/Symbols.h"

using namespace Pinetime::Applications::Screens;

namespace {
void EventHandler(lv_obj_t* obj, lv_event_t event) {
auto* screen = static_cast<SettingHeartRate*>(obj->user_data);
screen->UpdateSelected(obj, event);
}
}

SettingHeartRate::SettingHeartRate(Pinetime::Controllers::Settings& settingsController) : settingsController {settingsController} {
lv_obj_t* container = lv_cont_create(lv_scr_act(), nullptr);

lv_obj_set_style_local_bg_opa(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP);
lv_obj_set_style_local_pad_all(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
lv_obj_set_style_local_pad_inner(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
lv_obj_set_style_local_border_width(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);

lv_obj_set_pos(container, 10, 60);
lv_obj_set_width(container, LV_HOR_RES - 20);
lv_obj_set_height(container, LV_VER_RES - 50);
lv_cont_set_layout(container, LV_LAYOUT_PRETTY_TOP);

lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_text_static(title, "Backg. Interval");
lv_label_set_text(title, "Backg. Interval");
lv_label_set_align(title, LV_LABEL_ALIGN_CENTER);
lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 10, 15);

lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_label_set_text_static(icon, Symbols::heartBeat);
lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER);
lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0);

std::optional<uint16_t> currentInterval = settingsController.GetHeartRateBackgroundMeasurementInterval();

for (std::size_t i = 0; i < options.size(); i++) {
cbOption[i] = lv_checkbox_create(container, nullptr);
lv_checkbox_set_text(cbOption[i], options[i].name);
cbOption[i]->user_data = this;
lv_obj_set_event_cb(cbOption[i], EventHandler);
SetRadioButtonStyle(cbOption[i]);

if (options[i].intervalInSeconds == currentInterval) {
lv_checkbox_set_checked(cbOption[i], true);
}
}
}

SettingHeartRate::~SettingHeartRate() {
lv_obj_clean(lv_scr_act());
settingsController.SaveSettings();
}

void SettingHeartRate::UpdateSelected(lv_obj_t* object, lv_event_t event) {
if (event == LV_EVENT_CLICKED) {
for (std::size_t i = 0; i < options.size(); i++) {
if (object == cbOption[i]) {
lv_checkbox_set_checked(cbOption[i], true);
settingsController.SetHeartRateBackgroundMeasurementInterval(options[i].intervalInSeconds);
} else {
lv_checkbox_set_checked(cbOption[i], false);
}
}
}
}
44 changes: 44 additions & 0 deletions src/displayapp/screens/settings/SettingHeartRate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once

#include <cstdint>
#include <lvgl/lvgl.h>
#include <optional>
#include <array>

#include "components/settings/Settings.h"
#include "displayapp/screens/Screen.h"

namespace Pinetime {

namespace Applications {
namespace Screens {
class SettingHeartRate : public Screen {
public:
explicit SettingHeartRate(Pinetime::Controllers::Settings& settings);
~SettingHeartRate() override;

void UpdateSelected(lv_obj_t* object, lv_event_t event);

private:
struct Option {
std::optional<uint16_t> intervalInSeconds;
const char* name;
};

Pinetime::Controllers::Settings& settingsController;

static constexpr std::array<Option, 7> options = {{
{.intervalInSeconds = std::nullopt, .name = " Off"},
{.intervalInSeconds = 0, .name = "Cont"},
{.intervalInSeconds = 30, .name = " 30s"},
{.intervalInSeconds = 60, .name = " 1m"},
{.intervalInSeconds = 5 * 60, .name = " 5m"},
{.intervalInSeconds = 10 * 60, .name = " 10m"},
{.intervalInSeconds = 30 * 60, .name = " 30m"},
}};

lv_obj_t* cbOption[options.size()];
};
}
}
}
11 changes: 3 additions & 8 deletions src/displayapp/screens/settings/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,18 @@ namespace Pinetime {
{Symbols::home, "Watch face", Apps::SettingWatchFace},

{Symbols::shoe, "Steps", Apps::SettingSteps},
{Symbols::heartBeat, "Heartrate", Apps::SettingHeartRate},
{Symbols::clock, "Date & Time", Apps::SettingSetDateTime},
{Symbols::cloudSunRain, "Weather", Apps::SettingWeatherFormat},
{Symbols::batteryHalf, "Battery", Apps::BatteryInfo},

{Symbols::batteryHalf, "Battery", Apps::BatteryInfo},
{Symbols::clock, "Chimes", Apps::SettingChimes},
{Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold},
{Symbols::check, "Firmware", Apps::FirmwareValidation},
{Symbols::shieldAlt, "Over-the-air", Apps::SettingOTA},

{Symbols::shieldAlt, "Over-the-air", Apps::SettingOTA},
{Symbols::bluetooth, "Bluetooth", Apps::SettingBluetooth},
{Symbols::list, "About", Apps::SysInfo},

// {Symbols::none, "None", Apps::None},
// {Symbols::none, "None", Apps::None},
// {Symbols::none, "None", Apps::None},
// {Symbols::none, "None", Apps::None},

}};
ScreenList<nScreens> screens;
};
Expand Down
Loading
Loading