From 8d3f25d328fabf051a25d61ef1a90e1a2d3f35a9 Mon Sep 17 00:00:00 2001 From: JustScott Date: Tue, 31 Dec 2024 16:34:33 -0600 Subject: [PATCH 1/8] Add sleep settings Add a settings page for enabling/disabling actions to be done when sleep is turned on or off. Added Options: - [x] Allow Always on Display - [x] Allow Chimes - [x] Allow Notifications - [x] Disable BLE --- src/CMakeLists.txt | 1 + src/components/settings/Settings.h | 42 +++++++++- src/displayapp/DisplayApp.cpp | 6 ++ src/displayapp/apps/Apps.h.in | 1 + src/displayapp/fonts/fonts.json | 2 +- src/displayapp/screens/Symbols.h | 3 +- .../screens/settings/QuickSettings.cpp | 27 ++++++- .../screens/settings/SettingSleep.cpp | 79 +++++++++++++++++++ .../screens/settings/SettingSleep.h | 39 +++++++++ src/displayapp/screens/settings/Settings.h | 5 +- src/systemtask/SystemTask.cpp | 28 ++++--- 11 files changed, 212 insertions(+), 21 deletions(-) create mode 100644 src/displayapp/screens/settings/SettingSleep.cpp create mode 100644 src/displayapp/screens/settings/SettingSleep.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e2b69b8b02..b971a5333f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -412,6 +412,7 @@ list(APPEND SOURCE_FILES displayapp/screens/settings/SettingWakeUp.cpp displayapp/screens/settings/SettingDisplay.cpp displayapp/screens/settings/SettingSteps.cpp + displayapp/screens/settings/SettingSleep.cpp displayapp/screens/settings/SettingSetDateTime.cpp displayapp/screens/settings/SettingSetDate.cpp displayapp/screens/settings/SettingSetTime.cpp diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 602de3a585..e049b7b080 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -14,6 +14,7 @@ namespace Pinetime { enum class Notification : uint8_t { On, Off, Sleep }; enum class ChimesOption : uint8_t { None, Hours, HalfHours }; enum class WakeUpMode : uint8_t { SingleTap = 0, DoubleTap = 1, RaiseWrist = 2, Shake = 3, LowerWrist = 4 }; + enum class SleepOption : uint8_t { AllowAOD = 0, AllowChimes = 1, AllowNotify = 2, DisableBle = 3 }; enum class Colors : uint8_t { White, Silver, @@ -215,7 +216,11 @@ namespace Pinetime { }; bool GetAlwaysOnDisplay() const { - return settings.alwaysOnDisplay && GetNotificationStatus() != Notification::Sleep; + if (isSleepOptionOn(Controllers::Settings::SleepOption::AllowAOD)) { + return settings.alwaysOnDisplay; + } else { + return settings.alwaysOnDisplay && GetNotificationStatus() != Notification::Sleep; + } }; void SetAlwaysOnDisplaySetting(bool state) { @@ -268,6 +273,37 @@ namespace Pinetime { return getWakeUpModes()[static_cast(mode)]; } + bool sleepDisabledBle = false; + + void setSleepOption(SleepOption option, bool enabled) { + if (enabled != isSleepOptionOn(option)) { + settingsChanged = true; + } + settings.sleepOption.set(static_cast(option), enabled); + + // Handle special behavior + if (enabled) { + switch (option) { + case SleepOption::AllowNotify: + settings.sleepOption.set(static_cast(SleepOption::DisableBle), false); + break; + case SleepOption::DisableBle: + settings.sleepOption.set(static_cast(SleepOption::AllowNotify), false); + break; + default: + break; + } + } + }; + + std::bitset<4> getSleepOptions() const { + return settings.sleepOption; + } + + bool isSleepOptionOn(const SleepOption option) const { + return getSleepOptions()[static_cast(option)]; + } + void SetBrightness(Controllers::BrightnessController::Levels level) { if (level != settings.brightLevel) { settingsChanged = true; @@ -301,7 +337,7 @@ namespace Pinetime { private: Pinetime::Controllers::FS& fs; - static constexpr uint32_t settingsVersion = 0x0008; + static constexpr uint32_t settingsVersion = 0x0009; struct SettingsData { uint32_t version = settingsVersion; @@ -324,6 +360,8 @@ namespace Pinetime { std::bitset<5> wakeUpMode {0}; uint16_t shakeWakeThreshold = 150; + std::bitset<4> sleepOption {0}; + Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; }; diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 6671ac9e51..d322bae104 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -45,6 +45,7 @@ #include "displayapp/screens/settings/SettingWakeUp.h" #include "displayapp/screens/settings/SettingDisplay.h" #include "displayapp/screens/settings/SettingSteps.h" +#include "displayapp/screens/settings/SettingSleep.h" #include "displayapp/screens/settings/SettingSetDateTime.h" #include "displayapp/screens/settings/SettingChimes.h" #include "displayapp/screens/settings/SettingShakeThreshold.h" @@ -301,6 +302,7 @@ void DisplayApp::Refresh() { if (state != States::Running || !systemTask->IsSleeping()) { break; } + while (brightnessController.Level() != Controllers::BrightnessController::Levels::Low) { brightnessController.Lower(); vTaskDelay(100); @@ -311,6 +313,7 @@ void DisplayApp::Refresh() { } else { brightnessController.Set(Controllers::BrightnessController::Levels::Off); } + // Since the active screen is not really an app, go back to Clock. if (currentApp == Apps::Launcher || currentApp == Apps::Notifications || currentApp == Apps::QuickSettings || currentApp == Apps::Settings) { @@ -611,6 +614,9 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio case Apps::SettingSteps: currentScreen = std::make_unique(settingsController); break; + case Apps::SettingSleep: + currentScreen = std::make_unique(settingsController); + break; case Apps::SettingSetDateTime: currentScreen = std::make_unique(this, dateTimeController, settingsController); break; diff --git a/src/displayapp/apps/Apps.h.in b/src/displayapp/apps/Apps.h.in index 2104a267c0..255926133b 100644 --- a/src/displayapp/apps/Apps.h.in +++ b/src/displayapp/apps/Apps.h.in @@ -38,6 +38,7 @@ namespace Pinetime { SettingDisplay, SettingWakeUp, SettingSteps, + SettingSleep, SettingSetDateTime, SettingChimes, SettingShakeThreshold, diff --git a/src/displayapp/fonts/fonts.json b/src/displayapp/fonts/fonts.json index 41c383c0d4..1e5cf8b39c 100644 --- a/src/displayapp/fonts/fonts.json +++ b/src/displayapp/fonts/fonts.json @@ -7,7 +7,7 @@ }, { "file": "FontAwesome5-Solid+Brands+Regular.woff", - "range": "0xf294, 0xf242, 0xf54b, 0xf21e, 0xf1e6, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf06e, 0xf015, 0xf00c, 0xf0f3, 0xf522, 0xf743" + "range": "0xf294, 0xf242, 0xf54b, 0xf21e, 0xf1e6, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569, 0xf06e, 0xf015, 0xf00c, 0xf0f3, 0xf522, 0xf743, 0xf186" } ], "bpp": 1, diff --git a/src/displayapp/screens/Symbols.h b/src/displayapp/screens/Symbols.h index bd958b285f..dac78ddfe0 100644 --- a/src/displayapp/screens/Symbols.h +++ b/src/displayapp/screens/Symbols.h @@ -38,7 +38,7 @@ namespace Pinetime { static constexpr const char* dice = "\xEF\x94\xA2"; static constexpr const char* eye = "\xEF\x81\xAE"; static constexpr const char* home = "\xEF\x80\x95"; - static constexpr const char* sleep = "\xEE\xBD\x84"; + static constexpr const char* crescentMoon = "\xEF\x86\x86"; // fontawesome_weathericons.c // static constexpr const char* sun = "\xEF\x86\x85"; @@ -61,6 +61,7 @@ namespace Pinetime { static constexpr const char* notificationsOff = "\xEE\x9F\xB6"; static constexpr const char* notificationsOn = "\xEE\x9F\xB7"; + static constexpr const char* sleep = "\xEE\xBD\x84"; static constexpr const char* flashlight = "\xEF\x80\x8B"; static constexpr const char* paintbrushLg = "\xEE\x90\x8A"; diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index c5c3071aef..db5b44a53a 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -146,22 +146,45 @@ void QuickSettings::OnButtonEvent(lv_obj_t* object) { settingsController.SetBrightness(brightness.Level()); } else if (object == btn3) { - + // Turn notifications off if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::On) { settingsController.SetNotificationStatus(Controllers::Settings::Notification::Off); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOff); lv_obj_set_state(btn3, static_cast(ButtonState::NotificationsOff)); + // Turn sleep on } else if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::Off) { settingsController.SetNotificationStatus(Controllers::Settings::Notification::Sleep); lv_label_set_text_static(btn3_lvl, Symbols::sleep); lv_obj_set_state(btn3, static_cast(ButtonState::Sleep)); - } else { + + if (settingsController.isSleepOptionOn(Controllers::Settings::SleepOption::DisableBle)) { + if (settingsController.GetBleRadioEnabled()) { + settingsController.SetBleRadioEnabled(false); + app->PushMessage(Pinetime::Applications::Display::Messages::BleRadioEnableToggle); + settingsController.sleepDisabledBle = true; + } + } + // Turn notifications on + } else if (settingsController.GetNotificationStatus() == Controllers::Settings::Notification::Sleep) { settingsController.SetNotificationStatus(Controllers::Settings::Notification::On); lv_label_set_text_static(btn3_lvl, Symbols::notificationsOn); lv_obj_set_state(btn3, static_cast(ButtonState::NotificationsOn)); motorController.RunForDuration(35); } + // Re-enable Bluetooth settings for all notification statuses except Sleep + // (Prevents the need to modify logic if additional statuses are added) + if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep) { + // Enable Ble if previously disabled + if (settingsController.sleepDisabledBle == true) { + if (!settingsController.GetBleRadioEnabled()) { + settingsController.SetBleRadioEnabled(true); + this->app->PushMessage(Pinetime::Applications::Display::Messages::BleRadioEnableToggle); + } + settingsController.sleepDisabledBle = false; + } + } + } else if (object == btn4) { settingsController.SetSettingsMenu(0); app->StartApp(Apps::Settings, DisplayApp::FullRefreshDirections::Up); diff --git a/src/displayapp/screens/settings/SettingSleep.cpp b/src/displayapp/screens/settings/SettingSleep.cpp new file mode 100644 index 0000000000..b9b6b4cec2 --- /dev/null +++ b/src/displayapp/screens/settings/SettingSleep.cpp @@ -0,0 +1,79 @@ +#include "displayapp/screens/settings/SettingSleep.h" +#include +#include "displayapp/DisplayApp.h" +#include "displayapp/screens/Screen.h" +#include "displayapp/screens/Symbols.h" +#include "components/settings/Settings.h" +#include "displayapp/screens/Styles.h" + +using namespace Pinetime::Applications::Screens; + +constexpr std::array SettingSleep::options; + +namespace { + void event_handler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast(obj->user_data); + if (event == LV_EVENT_VALUE_CHANGED) { + screen->UpdateSelected(obj); + } + } +} + +SettingSleep::SettingSleep(Pinetime::Controllers::Settings& settingsController) : settingsController {settingsController} { + lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); + + lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + lv_obj_set_pos(container1, 10, 35); + lv_obj_set_width(container1, LV_HOR_RES - 20); + lv_obj_set_height(container1, LV_VER_RES - 20); + lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); + + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_text_static(title, "Sleep Actions"); + lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); + lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 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_ORANGE); + lv_label_set_text_static(icon, Symbols::crescentMoon); + lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); + lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); + + for (unsigned int i = 0; i < options.size(); i++) { + cbOption[i] = lv_checkbox_create(container1, nullptr); + lv_checkbox_set_text(cbOption[i], options[i].name); + if (settingsController.isSleepOptionOn(static_cast(i))) { + lv_checkbox_set_checked(cbOption[i], true); + } + cbOption[i]->user_data = this; + lv_obj_set_event_cb(cbOption[i], event_handler); + } +} + +SettingSleep::~SettingSleep() { + lv_obj_clean(lv_scr_act()); + settingsController.SaveSettings(); +} + +void SettingSleep::UpdateSelected(lv_obj_t* object) { + // Find the index of the checkbox that triggered the event + for (size_t i = 0; i < options.size(); i++) { + if (cbOption[i] == object) { + bool currentState = settingsController.isSleepOptionOn(options[i].sleepOption); + settingsController.setSleepOption(options[i].sleepOption, !currentState); + break; + } + } + + // Update checkbox according to current sleep options. + // This is needed because we can have extra logic when setting or unsetting sleep options, + // for example, when setting AllowNotify, DisableBle is unset and vice versa. + auto sleepOptions = settingsController.getSleepOptions(); + for (size_t i = 0; i < options.size(); ++i) { + lv_checkbox_set_checked(cbOption[i], sleepOptions[i]); + } +} diff --git a/src/displayapp/screens/settings/SettingSleep.h b/src/displayapp/screens/settings/SettingSleep.h new file mode 100644 index 0000000000..af441675e3 --- /dev/null +++ b/src/displayapp/screens/settings/SettingSleep.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include +#include "components/settings/Settings.h" +#include "displayapp/screens/Screen.h" + +namespace Pinetime { + + namespace Applications { + namespace Screens { + + class SettingSleep : public Screen { + public: + SettingSleep(Pinetime::Controllers::Settings& settingsController); + ~SettingSleep() override; + + void UpdateSelected(lv_obj_t* object); + + private: + struct Option { + Controllers::Settings::SleepOption sleepOption; + const char* name; + }; + + Controllers::Settings& settingsController; + static constexpr std::array options = {{ + {Controllers::Settings::SleepOption::AllowAOD, "Allow AOD"}, + {Controllers::Settings::SleepOption::AllowChimes, "Allow Chimes"}, + {Controllers::Settings::SleepOption::AllowNotify, "Allow Notify"}, + {Controllers::Settings::SleepOption::DisableBle, "Disable BLE"}, + }}; + + lv_obj_t* cbOption[options.size()]; + }; + } + } +} diff --git a/src/displayapp/screens/settings/Settings.h b/src/displayapp/screens/settings/Settings.h index 3722c2be39..27483a3e4c 100644 --- a/src/displayapp/screens/settings/Settings.h +++ b/src/displayapp/screens/settings/Settings.h @@ -37,16 +37,17 @@ namespace Pinetime { {Symbols::clock, "Time format", Apps::SettingTimeFormat}, {Symbols::home, "Watch face", Apps::SettingWatchFace}, + {Symbols::crescentMoon, "Sleep", Apps::SettingSleep}, {Symbols::shoe, "Steps", Apps::SettingSteps}, {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::bluetooth, "Bluetooth", Apps::SettingBluetooth}, + {Symbols::bluetooth, "Bluetooth", Apps::SettingBluetooth}, {Symbols::list, "About", Apps::SysInfo}, // {Symbols::none, "None", Apps::None}, diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index eb013d6d1a..3f39d7ccec 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -207,7 +207,9 @@ void SystemTask::Work() { } break; case Messages::OnNewNotification: - if (settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::On) { + if (settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::On || + (settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::Sleep && + settingsController.isSleepOptionOn(Pinetime::Controllers::Settings::SleepOption::AllowNotify))) { if (IsSleeping()) { GoToRunning(); } @@ -321,19 +323,17 @@ void SystemTask::Work() { stepCounterMustBeReset = true; break; case Messages::OnNewHour: - using Pinetime::Controllers::AlarmController; - if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep && - settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && !alarmController.IsAlerting()) { - GoToRunning(); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime); - } - break; case Messages::OnNewHalfHour: using Pinetime::Controllers::AlarmController; - if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep && - settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && !alarmController.IsAlerting()) { - GoToRunning(); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime); + + if (settingsController.GetChimeOption() != Controllers::Settings::ChimesOption::None && !alarmController.IsAlerting()) { + if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep || + settingsController.isSleepOptionOn(Pinetime::Controllers::Settings::SleepOption::AllowChimes)) { + if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep) { + GoToRunning(); + } + displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime); + } } break; case Messages::OnChargingEvent: @@ -418,10 +418,12 @@ void SystemTask::GoToSleep() { if (IsSleepDisabled()) { return; } - NRF_LOG_INFO("[systemtask] Going to sleep"); + if (settingsController.GetAlwaysOnDisplay()) { + NRF_LOG_INFO("[systemtask] Going To Always On Display"); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToAOD); } else { + NRF_LOG_INFO("[systemtask] Going To sleep"); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep); } heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep); From 7c9b630274201a44cefa0dd6158acfd05854e61e Mon Sep 17 00:00:00 2001 From: JustScott Date: Sat, 15 Feb 2025 23:30:33 -0600 Subject: [PATCH 2/8] Replace Allow AOD with Enable AOD Leaving it as "Allow AOD" assumes the user wants it the same during the day as during sleep. In my opinion the user would either want AOD on during sleep or they wouldn't. --- src/components/settings/Settings.h | 8 ++------ src/displayapp/screens/settings/SettingSleep.h | 2 +- src/systemtask/SystemTask.cpp | 8 ++++++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index e049b7b080..cf4f28bf86 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -14,7 +14,7 @@ namespace Pinetime { enum class Notification : uint8_t { On, Off, Sleep }; enum class ChimesOption : uint8_t { None, Hours, HalfHours }; enum class WakeUpMode : uint8_t { SingleTap = 0, DoubleTap = 1, RaiseWrist = 2, Shake = 3, LowerWrist = 4 }; - enum class SleepOption : uint8_t { AllowAOD = 0, AllowChimes = 1, AllowNotify = 2, DisableBle = 3 }; + enum class SleepOption : uint8_t { AllowChimes = 0, AllowNotify = 1, DisableBle = 2, EnableAOD = 3 }; enum class Colors : uint8_t { White, Silver, @@ -216,11 +216,7 @@ namespace Pinetime { }; bool GetAlwaysOnDisplay() const { - if (isSleepOptionOn(Controllers::Settings::SleepOption::AllowAOD)) { - return settings.alwaysOnDisplay; - } else { - return settings.alwaysOnDisplay && GetNotificationStatus() != Notification::Sleep; - } + return settings.alwaysOnDisplay && GetNotificationStatus() != Notification::Sleep; }; void SetAlwaysOnDisplaySetting(bool state) { diff --git a/src/displayapp/screens/settings/SettingSleep.h b/src/displayapp/screens/settings/SettingSleep.h index af441675e3..1c29af961d 100644 --- a/src/displayapp/screens/settings/SettingSleep.h +++ b/src/displayapp/screens/settings/SettingSleep.h @@ -26,10 +26,10 @@ namespace Pinetime { Controllers::Settings& settingsController; static constexpr std::array options = {{ - {Controllers::Settings::SleepOption::AllowAOD, "Allow AOD"}, {Controllers::Settings::SleepOption::AllowChimes, "Allow Chimes"}, {Controllers::Settings::SleepOption::AllowNotify, "Allow Notify"}, {Controllers::Settings::SleepOption::DisableBle, "Disable BLE"}, + {Controllers::Settings::SleepOption::EnableAOD, "Enable AOD"}, }}; lv_obj_t* cbOption[options.size()]; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 3f39d7ccec..54246a9f94 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -419,11 +419,15 @@ void SystemTask::GoToSleep() { return; } - if (settingsController.GetAlwaysOnDisplay()) { + if (settingsController.isSleepOptionOn(Pinetime::Controllers::Settings::SleepOption::EnableAOD) && + settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::Sleep) { + NRF_LOG_INFO("[systemtask] Always On Display Enabled For Sleep"); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToAOD); + } else if (settingsController.GetAlwaysOnDisplay()) { NRF_LOG_INFO("[systemtask] Going To Always On Display"); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToAOD); } else { - NRF_LOG_INFO("[systemtask] Going To sleep"); + NRF_LOG_INFO("[systemtask] Going To Sleep"); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep); } heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep); From d98f8e924fe8b6d91808db4f3cd7b3db940064e9 Mon Sep 17 00:00:00 2001 From: JustScott Date: Tue, 18 Feb 2025 09:43:28 -0600 Subject: [PATCH 3/8] Add support for sleepSteps in MotionController --- src/components/motion/MotionController.cpp | 3 +++ src/components/motion/MotionController.h | 9 ++++++++- src/components/settings/Settings.h | 1 + src/main.cpp | 2 +- src/systemtask/SystemTask.cpp | 1 + 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index 72507ac5cd..ad615523e9 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -35,6 +35,9 @@ namespace { } } +MotionController::MotionController(Controllers::Settings& settingsController) : settingsController {settingsController} { +} + void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) { if (this->nbSteps != nbSteps && service != nullptr) { service->OnNewStepCountValue(nbSteps); diff --git a/src/components/motion/MotionController.h b/src/components/motion/MotionController.h index be0241d32e..3a91fe2777 100644 --- a/src/components/motion/MotionController.h +++ b/src/components/motion/MotionController.h @@ -6,12 +6,15 @@ #include "drivers/Bma421.h" #include "components/ble/MotionService.h" +#include "components/settings/Settings.h" #include "utility/CircularBuffer.h" namespace Pinetime { namespace Controllers { class MotionController { public: + MotionController(Controllers::Settings& settingsController); + enum class DeviceTypes { Unknown, BMA421, @@ -33,7 +36,10 @@ namespace Pinetime { } uint32_t NbSteps() const { - return nbSteps; + if (nbSteps > settingsController.sleepSteps) { + return nbSteps - settingsController.sleepSteps; + } + return 0; } void ResetTrip() { @@ -100,6 +106,7 @@ namespace Pinetime { DeviceTypes deviceType = DeviceTypes::Unknown; Pinetime::Controllers::MotionService* service = nullptr; + Controllers::Settings& settingsController; }; } } diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index cf4f28bf86..93c7b3a1a7 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -270,6 +270,7 @@ namespace Pinetime { } bool sleepDisabledBle = false; + uint32_t sleepSteps = 0; void setSleepOption(SleepOption option, bool enabled) { if (enabled != isSleepOptionOn(option)) { diff --git a/src/main.cpp b/src/main.cpp index 24f13caddd..0c2a0ab720 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -103,7 +103,7 @@ Pinetime::Controllers::MotorController motorController {}; Pinetime::Controllers::DateTime dateTimeController {settingsController}; Pinetime::Drivers::Watchdog watchdog; Pinetime::Controllers::NotificationManager notificationManager; -Pinetime::Controllers::MotionController motionController; +Pinetime::Controllers::MotionController motionController {settingsController}; Pinetime::Controllers::AlarmController alarmController {dateTimeController, fs}; Pinetime::Controllers::TouchHandler touchHandler; Pinetime::Controllers::ButtonHandler buttonHandler; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 54246a9f94..e85903229e 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -321,6 +321,7 @@ void SystemTask::Work() { // We might be sleeping (with TWI device disabled. // Remember we'll have to reset the counter next time we're awake stepCounterMustBeReset = true; + settingsController.sleepSteps = 0; break; case Messages::OnNewHour: case Messages::OnNewHalfHour: From a4380f948524dda32ece0ae5c1bfedbe1e70095a Mon Sep 17 00:00:00 2001 From: JustScott Date: Tue, 18 Feb 2025 09:46:33 -0600 Subject: [PATCH 4/8] Swap Disable BLE and Enable AOD positions in sleep settings --- src/components/settings/Settings.h | 2 +- src/displayapp/screens/settings/SettingSleep.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 93c7b3a1a7..242ea78b6d 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -14,7 +14,7 @@ namespace Pinetime { enum class Notification : uint8_t { On, Off, Sleep }; enum class ChimesOption : uint8_t { None, Hours, HalfHours }; enum class WakeUpMode : uint8_t { SingleTap = 0, DoubleTap = 1, RaiseWrist = 2, Shake = 3, LowerWrist = 4 }; - enum class SleepOption : uint8_t { AllowChimes = 0, AllowNotify = 1, DisableBle = 2, EnableAOD = 3 }; + enum class SleepOption : uint8_t { AllowChimes = 0, AllowNotify = 1, EnableAOD = 2, DisableBle = 3 }; enum class Colors : uint8_t { White, Silver, diff --git a/src/displayapp/screens/settings/SettingSleep.h b/src/displayapp/screens/settings/SettingSleep.h index 1c29af961d..3f740af24e 100644 --- a/src/displayapp/screens/settings/SettingSleep.h +++ b/src/displayapp/screens/settings/SettingSleep.h @@ -28,8 +28,8 @@ namespace Pinetime { static constexpr std::array options = {{ {Controllers::Settings::SleepOption::AllowChimes, "Allow Chimes"}, {Controllers::Settings::SleepOption::AllowNotify, "Allow Notify"}, - {Controllers::Settings::SleepOption::DisableBle, "Disable BLE"}, {Controllers::Settings::SleepOption::EnableAOD, "Enable AOD"}, + {Controllers::Settings::SleepOption::DisableBle, "Disable BLE"}, }}; lv_obj_t* cbOption[options.size()]; From 68844737b848b7eac01a767cc9016917165c43a8 Mon Sep 17 00:00:00 2001 From: JustScott Date: Tue, 18 Feb 2025 09:52:46 -0600 Subject: [PATCH 5/8] Add IgnoreSteps sleep option (no logic yet) --- src/components/settings/Settings.h | 6 +++--- src/displayapp/screens/settings/SettingSleep.cpp | 2 +- src/displayapp/screens/settings/SettingSleep.h | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 242ea78b6d..f07bd4b9c8 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -14,7 +14,7 @@ namespace Pinetime { enum class Notification : uint8_t { On, Off, Sleep }; enum class ChimesOption : uint8_t { None, Hours, HalfHours }; enum class WakeUpMode : uint8_t { SingleTap = 0, DoubleTap = 1, RaiseWrist = 2, Shake = 3, LowerWrist = 4 }; - enum class SleepOption : uint8_t { AllowChimes = 0, AllowNotify = 1, EnableAOD = 2, DisableBle = 3 }; + enum class SleepOption : uint8_t { AllowChimes = 0, AllowNotify = 1, EnableAOD = 2, DisableBle = 3, IgnoreSteps = 4 }; enum class Colors : uint8_t { White, Silver, @@ -293,7 +293,7 @@ namespace Pinetime { } }; - std::bitset<4> getSleepOptions() const { + std::bitset<5> getSleepOptions() const { return settings.sleepOption; } @@ -357,7 +357,7 @@ namespace Pinetime { std::bitset<5> wakeUpMode {0}; uint16_t shakeWakeThreshold = 150; - std::bitset<4> sleepOption {0}; + std::bitset<5> sleepOption {0}; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; }; diff --git a/src/displayapp/screens/settings/SettingSleep.cpp b/src/displayapp/screens/settings/SettingSleep.cpp index b9b6b4cec2..a3f427b7c8 100644 --- a/src/displayapp/screens/settings/SettingSleep.cpp +++ b/src/displayapp/screens/settings/SettingSleep.cpp @@ -8,7 +8,7 @@ using namespace Pinetime::Applications::Screens; -constexpr std::array SettingSleep::options; +constexpr std::array SettingSleep::options; namespace { void event_handler(lv_obj_t* obj, lv_event_t event) { diff --git a/src/displayapp/screens/settings/SettingSleep.h b/src/displayapp/screens/settings/SettingSleep.h index 3f740af24e..a689b831c0 100644 --- a/src/displayapp/screens/settings/SettingSleep.h +++ b/src/displayapp/screens/settings/SettingSleep.h @@ -25,11 +25,12 @@ namespace Pinetime { }; Controllers::Settings& settingsController; - static constexpr std::array options = {{ + static constexpr std::array options = {{ {Controllers::Settings::SleepOption::AllowChimes, "Allow Chimes"}, {Controllers::Settings::SleepOption::AllowNotify, "Allow Notify"}, {Controllers::Settings::SleepOption::EnableAOD, "Enable AOD"}, {Controllers::Settings::SleepOption::DisableBle, "Disable BLE"}, + {Controllers::Settings::SleepOption::IgnoreSteps, "Ignore Steps"}, }}; lv_obj_t* cbOption[options.size()]; From 1997c092ae1df6f32175c8f4e4c254af22c7908a Mon Sep 17 00:00:00 2001 From: JustScott Date: Tue, 18 Feb 2025 09:59:07 -0600 Subject: [PATCH 6/8] Add logic for IgnoreSteps sleep option --- src/components/motion/MotionController.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index ad615523e9..e6e04d33a3 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -64,6 +64,11 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) currentTripSteps += deltaSteps; } this->nbSteps = nbSteps; + + if (settingsController.isSleepOptionOn(Settings::SleepOption::IgnoreSteps) && + settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::Sleep) { + settingsController.sleepSteps += deltaSteps; + } } MotionController::AccelStats MotionController::GetAccelStats() const { From cfa8c791c5063edaee69b367c0ed45174a596ec0 Mon Sep 17 00:00:00 2001 From: JustScott Date: Tue, 18 Feb 2025 10:37:02 -0600 Subject: [PATCH 7/8] Handle sleepSteps internally in motionController Renamed to ignoreSteps in motionController, gets rid of the `settingsController.sleepSteps` variable --- src/components/motion/MotionController.cpp | 2 +- src/components/motion/MotionController.h | 9 +++++++-- src/components/settings/Settings.h | 1 - src/systemtask/SystemTask.cpp | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index e6e04d33a3..9d205afa79 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -67,7 +67,7 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) if (settingsController.isSleepOptionOn(Settings::SleepOption::IgnoreSteps) && settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::Sleep) { - settingsController.sleepSteps += deltaSteps; + ignoreSteps += deltaSteps; } } diff --git a/src/components/motion/MotionController.h b/src/components/motion/MotionController.h index 3a91fe2777..853f39945f 100644 --- a/src/components/motion/MotionController.h +++ b/src/components/motion/MotionController.h @@ -36,8 +36,8 @@ namespace Pinetime { } uint32_t NbSteps() const { - if (nbSteps > settingsController.sleepSteps) { - return nbSteps - settingsController.sleepSteps; + if (nbSteps > ignoreSteps) { + return nbSteps - ignoreSteps; } return 0; } @@ -46,6 +46,10 @@ namespace Pinetime { currentTripSteps = 0; } + void ResetIgnoreSteps() { + ignoreSteps = 0; + } + uint32_t GetTripSteps() const { return currentTripSteps; } @@ -75,6 +79,7 @@ namespace Pinetime { private: uint32_t nbSteps = 0; uint32_t currentTripSteps = 0; + uint32_t ignoreSteps = 0; TickType_t lastTime = 0; TickType_t time = 0; diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index f07bd4b9c8..30df13f9c2 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -270,7 +270,6 @@ namespace Pinetime { } bool sleepDisabledBle = false; - uint32_t sleepSteps = 0; void setSleepOption(SleepOption option, bool enabled) { if (enabled != isSleepOptionOn(option)) { diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index e85903229e..279660a27d 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -321,7 +321,6 @@ void SystemTask::Work() { // We might be sleeping (with TWI device disabled. // Remember we'll have to reset the counter next time we're awake stepCounterMustBeReset = true; - settingsController.sleepSteps = 0; break; case Messages::OnNewHour: case Messages::OnNewHalfHour: @@ -447,6 +446,7 @@ void SystemTask::UpdateMotion() { if (stepCounterMustBeReset) { motionSensor.ResetStepCounter(); + motionController.ResetIgnoreSteps(); stepCounterMustBeReset = false; } From 8c32e5fa64d120156e4b2ae77863b32d09a5c5a6 Mon Sep 17 00:00:00 2001 From: JustScott Date: Thu, 20 Feb 2025 13:14:40 -0600 Subject: [PATCH 8/8] Fix ignore steps logic Don't count up trip steps during sleep. Check if deltaSteps is greater than zero before adding to ignoreSteps as well as trip steps. --- src/components/motion/MotionController.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index 9d205afa79..55db6fa2f4 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -60,15 +60,17 @@ void MotionController::Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps) stats = GetAccelStats(); int32_t deltaSteps = nbSteps - this->nbSteps; + if (deltaSteps > 0) { - currentTripSteps += deltaSteps; + if (settingsController.isSleepOptionOn(Settings::SleepOption::IgnoreSteps) && + settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::Sleep) { + ignoreSteps += deltaSteps; + } else { + currentTripSteps += deltaSteps; + } } - this->nbSteps = nbSteps; - if (settingsController.isSleepOptionOn(Settings::SleepOption::IgnoreSteps) && - settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::Sleep) { - ignoreSteps += deltaSteps; - } + this->nbSteps = nbSteps; } MotionController::AccelStats MotionController::GetAccelStats() const {