mirror of
https://github.com/InfiniTimeOrg/InfiniTime.git
synced 2024-10-22 15:11:51 +02:00
Compare commits
12 commits
db77686ff7
...
f9dd8f1f07
Author | SHA1 | Date | |
---|---|---|---|
f9dd8f1f07 | |||
a2356f2f4a | |||
3db4e012ce | |||
a0cd439efc | |||
299edca193 | |||
8e29d82985 | |||
0e76bf1766 | |||
15daf4cb84 | |||
4aef5a9f4d | |||
145b45c501 | |||
96b171524f | |||
0e1a074720 |
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,6 +7,7 @@ cmake-build-*
|
|||
cmake-*/
|
||||
CMakeFiles
|
||||
**/CMakeCache.txt
|
||||
CMakeLists.txt.user*
|
||||
cmake_install.cmake
|
||||
Makefile
|
||||
build
|
||||
|
|
12
doc/ble.md
12
doc/ble.md
|
@ -14,6 +14,8 @@ This page describes the BLE implementation and API built in this firmware.
|
|||
- [BLE Services](#ble-services)
|
||||
- [CTS](#cts)
|
||||
- [ANS](#ans)
|
||||
- [BLE Clients](#ble-clients)
|
||||
- [IAC](#iac)
|
||||
- [Getting Information](#getting-information)
|
||||
- [Firmware Version](#firmware-version)
|
||||
- [Battery Level](#battery-level)
|
||||
|
@ -113,6 +115,16 @@ The following custom services are implemented in InfiniTime:
|
|||
|
||||
![ANS sequence diagram](./ble/ans_sequence.png "ANS sequence diagram")
|
||||
|
||||
## BLE clients
|
||||
|
||||
### IAC
|
||||
|
||||
InfiniTime implements Immediade Alert Service client, that can be used to send notifications to companion app.
|
||||
This is useful for "Find my Phone" functionality.
|
||||
|
||||
More documentation about this service can be found here.
|
||||
|
||||
[Immediade Alert Service](https://www.bluetooth.com/specifications/specs/immediate-alert-service-1-0/)
|
||||
---
|
||||
|
||||
### Getting Information
|
||||
|
|
|
@ -385,6 +385,7 @@ list(APPEND SOURCE_FILES
|
|||
displayapp/screens/Notifications.cpp
|
||||
displayapp/screens/Twos.cpp
|
||||
displayapp/screens/HeartRate.cpp
|
||||
displayapp/screens/FindMyPhone.cpp
|
||||
displayapp/screens/FlashLight.cpp
|
||||
displayapp/screens/List.cpp
|
||||
displayapp/screens/CheckboxList.cpp
|
||||
|
@ -459,6 +460,7 @@ list(APPEND SOURCE_FILES
|
|||
components/ble/BatteryInformationService.cpp
|
||||
components/ble/FSService.cpp
|
||||
components/ble/ImmediateAlertService.cpp
|
||||
components/ble/ImmediateAlertClient.cpp
|
||||
components/ble/ServiceDiscovery.cpp
|
||||
components/ble/HeartRateService.cpp
|
||||
components/ble/MotionService.cpp
|
||||
|
@ -528,6 +530,7 @@ list(APPEND RECOVERY_SOURCE_FILES
|
|||
components/ble/BatteryInformationService.cpp
|
||||
components/ble/FSService.cpp
|
||||
components/ble/ImmediateAlertService.cpp
|
||||
components/ble/ImmediateAlertClient.cpp
|
||||
components/ble/ServiceDiscovery.cpp
|
||||
components/ble/NavigationService.cpp
|
||||
components/ble/HeartRateService.cpp
|
||||
|
@ -608,6 +611,7 @@ set(INCLUDE_FILES
|
|||
displayapp/Apps.h
|
||||
displayapp/screens/Notifications.h
|
||||
displayapp/screens/HeartRate.h
|
||||
displayapp/screens/FindMyPhone.h
|
||||
displayapp/screens/Metronome.h
|
||||
displayapp/screens/Motion.h
|
||||
displayapp/screens/Timer.h
|
||||
|
@ -647,6 +651,7 @@ set(INCLUDE_FILES
|
|||
components/ble/BatteryInformationService.h
|
||||
components/ble/FSService.h
|
||||
components/ble/ImmediateAlertService.h
|
||||
components/ble/ImmediateAlertClient.h
|
||||
components/ble/ServiceDiscovery.h
|
||||
components/ble/BleClient.h
|
||||
components/ble/HeartRateService.h
|
||||
|
@ -835,7 +840,7 @@ if (${CMAKE_BUILD_TYPE} STREQUAL "Debug")
|
|||
# add_definitions(-DCLOCK_CONFIG_LOG_LEVEL=4)
|
||||
# add_definitions(-DRTC_CONFIG_LOG_ENABLED=1)
|
||||
# add_definitions(-DRTC_CONFIG_LOG_LEVEL=4)
|
||||
|
||||
|
||||
# Nimble Logging
|
||||
add_definitions(-DMYNEWT_VAL_NEWT_FEATURE_LOGCFG=1)
|
||||
# add_definitions(-DMYNEWT_VAL_LOG_LEVEL=0)
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
#define configTICK_RATE_HZ 1024
|
||||
#define configMAX_PRIORITIES (3)
|
||||
#define configMINIMAL_STACK_SIZE (120)
|
||||
#define configTOTAL_HEAP_SIZE (1024 * 40)
|
||||
#define configTOTAL_HEAP_SIZE (1024 * 39)
|
||||
#define configMAX_TASK_NAME_LEN (4)
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
|
|
|
@ -19,11 +19,13 @@
|
|||
#include "systemtask/SystemTask.h"
|
||||
#include "task.h"
|
||||
#include <chrono>
|
||||
#include <libraries/log/nrf_log.h>
|
||||
|
||||
using namespace Pinetime::Controllers;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
AlarmController::AlarmController(Controllers::DateTime& dateTimeController) : dateTimeController {dateTimeController} {
|
||||
AlarmController::AlarmController(Controllers::DateTime& dateTimeController, Controllers::FS& fs)
|
||||
: dateTimeController {dateTimeController}, fs {fs} {
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -36,11 +38,28 @@ namespace {
|
|||
void AlarmController::Init(System::SystemTask* systemTask) {
|
||||
this->systemTask = systemTask;
|
||||
alarmTimer = xTimerCreate("Alarm", 1, pdFALSE, this, SetOffAlarm);
|
||||
LoadSettingsFromFile();
|
||||
if (alarm.isEnabled) {
|
||||
NRF_LOG_INFO("[AlarmController] Loaded alarm was enabled, scheduling");
|
||||
ScheduleAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
void AlarmController::SaveAlarm() {
|
||||
// verify if it is necessary to save
|
||||
if (alarmChanged) {
|
||||
SaveSettingsToFile();
|
||||
}
|
||||
alarmChanged = false;
|
||||
}
|
||||
|
||||
void AlarmController::SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin) {
|
||||
hours = alarmHr;
|
||||
minutes = alarmMin;
|
||||
if (alarm.hours == alarmHr && alarm.minutes == alarmMin) {
|
||||
return;
|
||||
}
|
||||
alarm.hours = alarmHr;
|
||||
alarm.minutes = alarmMin;
|
||||
alarmChanged = true;
|
||||
}
|
||||
|
||||
void AlarmController::ScheduleAlarm() {
|
||||
|
@ -53,18 +72,19 @@ void AlarmController::ScheduleAlarm() {
|
|||
tm* tmAlarmTime = std::localtime(&ttAlarmTime);
|
||||
|
||||
// If the time being set has already passed today,the alarm should be set for tomorrow
|
||||
if (hours < dateTimeController.Hours() || (hours == dateTimeController.Hours() && minutes <= dateTimeController.Minutes())) {
|
||||
if (alarm.hours < dateTimeController.Hours() ||
|
||||
(alarm.hours == dateTimeController.Hours() && alarm.minutes <= dateTimeController.Minutes())) {
|
||||
tmAlarmTime->tm_mday += 1;
|
||||
// tm_wday doesn't update automatically
|
||||
tmAlarmTime->tm_wday = (tmAlarmTime->tm_wday + 1) % 7;
|
||||
}
|
||||
|
||||
tmAlarmTime->tm_hour = hours;
|
||||
tmAlarmTime->tm_min = minutes;
|
||||
tmAlarmTime->tm_hour = alarm.hours;
|
||||
tmAlarmTime->tm_min = alarm.minutes;
|
||||
tmAlarmTime->tm_sec = 0;
|
||||
|
||||
// if alarm is in weekday-only mode, make sure it shifts to the next weekday
|
||||
if (recurrence == RecurType::Weekdays) {
|
||||
if (alarm.recurrence == RecurType::Weekdays) {
|
||||
if (tmAlarmTime->tm_wday == 0) { // Sunday, shift 1 day
|
||||
tmAlarmTime->tm_mday += 1;
|
||||
} else if (tmAlarmTime->tm_wday == 6) { // Saturday, shift 2 days
|
||||
|
@ -79,7 +99,10 @@ void AlarmController::ScheduleAlarm() {
|
|||
xTimerChangePeriod(alarmTimer, secondsToAlarm * configTICK_RATE_HZ, 0);
|
||||
xTimerStart(alarmTimer, 0);
|
||||
|
||||
state = AlarmState::Set;
|
||||
if (!alarm.isEnabled) {
|
||||
alarm.isEnabled = true;
|
||||
alarmChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t AlarmController::SecondsToAlarm() const {
|
||||
|
@ -88,20 +111,72 @@ uint32_t AlarmController::SecondsToAlarm() const {
|
|||
|
||||
void AlarmController::DisableAlarm() {
|
||||
xTimerStop(alarmTimer, 0);
|
||||
state = AlarmState::Not_Set;
|
||||
isAlerting = false;
|
||||
if (alarm.isEnabled) {
|
||||
alarm.isEnabled = false;
|
||||
alarmChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AlarmController::SetOffAlarmNow() {
|
||||
state = AlarmState::Alerting;
|
||||
isAlerting = true;
|
||||
systemTask->PushMessage(System::Messages::SetOffAlarm);
|
||||
}
|
||||
|
||||
void AlarmController::StopAlerting() {
|
||||
// Alarm state is off unless this is a recurring alarm
|
||||
if (recurrence == RecurType::None) {
|
||||
state = AlarmState::Not_Set;
|
||||
isAlerting = false;
|
||||
// Disable alarm unless it is recurring
|
||||
if (alarm.recurrence == RecurType::None) {
|
||||
alarm.isEnabled = false;
|
||||
alarmChanged = true;
|
||||
} else {
|
||||
// set next instance
|
||||
ScheduleAlarm();
|
||||
}
|
||||
}
|
||||
|
||||
void AlarmController::SetRecurrence(RecurType recurrence) {
|
||||
if (alarm.recurrence != recurrence) {
|
||||
alarm.recurrence = recurrence;
|
||||
alarmChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AlarmController::LoadSettingsFromFile() {
|
||||
lfs_file_t alarmFile;
|
||||
AlarmSettings alarmBuffer;
|
||||
|
||||
if (fs.FileOpen(&alarmFile, "/.system/alarm.dat", LFS_O_RDONLY) != LFS_ERR_OK) {
|
||||
NRF_LOG_WARNING("[AlarmController] Failed to open alarm data file");
|
||||
return;
|
||||
}
|
||||
|
||||
fs.FileRead(&alarmFile, reinterpret_cast<uint8_t*>(&alarmBuffer), sizeof(alarmBuffer));
|
||||
fs.FileClose(&alarmFile);
|
||||
if (alarmBuffer.version != alarmFormatVersion) {
|
||||
NRF_LOG_WARNING("[AlarmController] Loaded alarm settings has version %u instead of %u, discarding",
|
||||
alarmBuffer.version,
|
||||
alarmFormatVersion);
|
||||
return;
|
||||
}
|
||||
|
||||
alarm = alarmBuffer;
|
||||
NRF_LOG_INFO("[AlarmController] Loaded alarm settings from file");
|
||||
}
|
||||
|
||||
void AlarmController::SaveSettingsToFile() const {
|
||||
lfs_dir systemDir;
|
||||
if (fs.DirOpen("/.system", &systemDir) != LFS_ERR_OK) {
|
||||
fs.DirCreate("/.system");
|
||||
}
|
||||
fs.DirClose(&systemDir);
|
||||
lfs_file_t alarmFile;
|
||||
if (fs.FileOpen(&alarmFile, "/.system/alarm.dat", LFS_O_WRONLY | LFS_O_CREAT) != LFS_ERR_OK) {
|
||||
NRF_LOG_WARNING("[AlarmController] Failed to open alarm data file for saving");
|
||||
return;
|
||||
}
|
||||
|
||||
fs.FileWrite(&alarmFile, reinterpret_cast<const uint8_t*>(&alarm), sizeof(alarm));
|
||||
fs.FileClose(&alarmFile);
|
||||
NRF_LOG_INFO("[AlarmController] Saved alarm settings with format version %u to file", alarm.version);
|
||||
}
|
||||
|
|
|
@ -30,47 +30,65 @@ namespace Pinetime {
|
|||
namespace Controllers {
|
||||
class AlarmController {
|
||||
public:
|
||||
AlarmController(Controllers::DateTime& dateTimeController);
|
||||
AlarmController(Controllers::DateTime& dateTimeController, Controllers::FS& fs);
|
||||
|
||||
void Init(System::SystemTask* systemTask);
|
||||
void SaveAlarm();
|
||||
void SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin);
|
||||
void ScheduleAlarm();
|
||||
void DisableAlarm();
|
||||
void SetOffAlarmNow();
|
||||
uint32_t SecondsToAlarm() const;
|
||||
void StopAlerting();
|
||||
enum class AlarmState { Not_Set, Set, Alerting };
|
||||
enum class RecurType { None, Daily, Weekdays };
|
||||
|
||||
uint8_t Hours() const {
|
||||
return hours;
|
||||
return alarm.hours;
|
||||
}
|
||||
|
||||
uint8_t Minutes() const {
|
||||
return minutes;
|
||||
return alarm.minutes;
|
||||
}
|
||||
|
||||
AlarmState State() const {
|
||||
return state;
|
||||
bool IsAlerting() const {
|
||||
return isAlerting;
|
||||
}
|
||||
|
||||
bool IsEnabled() const {
|
||||
return alarm.isEnabled;
|
||||
}
|
||||
|
||||
RecurType Recurrence() const {
|
||||
return recurrence;
|
||||
return alarm.recurrence;
|
||||
}
|
||||
|
||||
void SetRecurrence(RecurType recurType) {
|
||||
recurrence = recurType;
|
||||
}
|
||||
void SetRecurrence(RecurType recurrence);
|
||||
|
||||
private:
|
||||
// Versions 255 is reserved for now, so the version field can be made
|
||||
// bigger, should it ever be needed.
|
||||
static constexpr uint8_t alarmFormatVersion = 1;
|
||||
|
||||
struct AlarmSettings {
|
||||
uint8_t version = alarmFormatVersion;
|
||||
uint8_t hours = 7;
|
||||
uint8_t minutes = 0;
|
||||
RecurType recurrence = RecurType::None;
|
||||
bool isEnabled = false;
|
||||
};
|
||||
|
||||
bool isAlerting = false;
|
||||
bool alarmChanged = false;
|
||||
|
||||
Controllers::DateTime& dateTimeController;
|
||||
Controllers::FS& fs;
|
||||
System::SystemTask* systemTask = nullptr;
|
||||
TimerHandle_t alarmTimer;
|
||||
uint8_t hours = 7;
|
||||
uint8_t minutes = 0;
|
||||
AlarmSettings alarm;
|
||||
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> alarmTime;
|
||||
AlarmState state = AlarmState::Not_Set;
|
||||
RecurType recurrence = RecurType::None;
|
||||
|
||||
void LoadSettingsFromFile();
|
||||
void SaveSettingsToFile() const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
113
src/components/ble/ImmediateAlertClient.cpp
Normal file
113
src/components/ble/ImmediateAlertClient.cpp
Normal file
|
@ -0,0 +1,113 @@
|
|||
#include "components/ble/ImmediateAlertClient.h"
|
||||
#include <cstring>
|
||||
#include <nrf_log.h>
|
||||
#include "systemtask/SystemTask.h"
|
||||
|
||||
using namespace Pinetime::Controllers;
|
||||
|
||||
constexpr ble_uuid16_t ImmediateAlertClient::immediateAlertClientUuid;
|
||||
constexpr ble_uuid16_t ImmediateAlertClient::alertLevelCharacteristicUuid;
|
||||
|
||||
namespace {
|
||||
int OnDiscoveryEventCallback(uint16_t conn_handle, const struct ble_gatt_error* error, const struct ble_gatt_svc* service, void* arg) {
|
||||
auto client = static_cast<ImmediateAlertClient*>(arg);
|
||||
return client->OnDiscoveryEvent(conn_handle, error, service);
|
||||
}
|
||||
|
||||
int OnImmediateAlertCharacteristicDiscoveredCallback(uint16_t conn_handle,
|
||||
const struct ble_gatt_error* error,
|
||||
const struct ble_gatt_chr* chr,
|
||||
void* arg) {
|
||||
auto client = static_cast<ImmediateAlertClient*>(arg);
|
||||
return client->OnCharacteristicDiscoveryEvent(conn_handle, error, chr);
|
||||
}
|
||||
}
|
||||
|
||||
ImmediateAlertClient::ImmediateAlertClient(Pinetime::System::SystemTask& systemTask)
|
||||
: systemTask {systemTask},
|
||||
characteristicDefinition {{
|
||||
.uuid = &alertLevelCharacteristicUuid.u,
|
||||
.arg = this,
|
||||
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
|
||||
},
|
||||
{0}},
|
||||
serviceDefinition {
|
||||
{/* Device Information Service */
|
||||
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||
.uuid = &immediateAlertClientUuid.u,
|
||||
.characteristics = characteristicDefinition},
|
||||
{0},
|
||||
} {
|
||||
}
|
||||
|
||||
void ImmediateAlertClient::Init() {
|
||||
}
|
||||
|
||||
bool ImmediateAlertClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service) {
|
||||
if (service == nullptr && error->status == BLE_HS_EDONE) {
|
||||
if (isDiscovered) {
|
||||
NRF_LOG_INFO("IAS found, starting characteristics discovery");
|
||||
|
||||
ble_gattc_disc_all_chrs(connectionHandle, iasStartHandle, iasEndHandle, OnImmediateAlertCharacteristicDiscoveredCallback, this);
|
||||
} else {
|
||||
NRF_LOG_INFO("IAS not found");
|
||||
onServiceDiscovered(connectionHandle);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (service != nullptr && ble_uuid_cmp(&immediateAlertClientUuid.u, &service->uuid.u) == 0) {
|
||||
NRF_LOG_INFO("IAS discovered : 0x%x - 0x%x", service->start_handle, service->end_handle);
|
||||
isDiscovered = true;
|
||||
iasStartHandle = service->start_handle;
|
||||
iasEndHandle = service->end_handle;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ImmediateAlertClient::OnCharacteristicDiscoveryEvent(uint16_t conn_handle,
|
||||
const ble_gatt_error* error,
|
||||
const ble_gatt_chr* characteristic) {
|
||||
|
||||
if (error->status != 0 && error->status != BLE_HS_EDONE) {
|
||||
NRF_LOG_INFO("IAS Characteristic discovery ERROR");
|
||||
onServiceDiscovered(conn_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (characteristic == nullptr && error->status == BLE_HS_EDONE) {
|
||||
if (!isCharacteristicDiscovered) {
|
||||
NRF_LOG_INFO("IAS Characteristic discovery unsuccessful");
|
||||
onServiceDiscovered(conn_handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (characteristic != nullptr && ble_uuid_cmp(&alertLevelCharacteristicUuid.u, &characteristic->uuid.u) == 0) {
|
||||
NRF_LOG_INFO("AIS Characteristic discovered : 0x%x", characteristic->val_handle);
|
||||
isCharacteristicDiscovered = true;
|
||||
alertLevelHandle = characteristic->val_handle;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ImmediateAlertClient::Discover(uint16_t connectionHandle, std::function<void(uint16_t)> onServiceDiscovered) {
|
||||
NRF_LOG_INFO("[IAS] Starting discovery");
|
||||
this->onServiceDiscovered = onServiceDiscovered;
|
||||
ble_gattc_disc_svc_by_uuid(connectionHandle, &immediateAlertClientUuid.u, OnDiscoveryEventCallback, this);
|
||||
}
|
||||
|
||||
bool ImmediateAlertClient::sendImmediateAlert(ImmediateAlertClient::Levels level) {
|
||||
|
||||
auto* om = ble_hs_mbuf_from_flat(&level, 1);
|
||||
|
||||
uint16_t connectionHandle = systemTask.nimble().connHandle();
|
||||
|
||||
if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ble_gattc_write_no_rsp(connectionHandle, alertLevelHandle, om);
|
||||
return true;
|
||||
}
|
61
src/components/ble/ImmediateAlertClient.h
Normal file
61
src/components/ble/ImmediateAlertClient.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
#pragma once
|
||||
#define min // workaround: nimble's min/max macros conflict with libstdc++
|
||||
#define max
|
||||
#include <host/ble_gap.h>
|
||||
#undef max
|
||||
#undef min
|
||||
#include <cstdint>
|
||||
#include "components/ble/BleClient.h"
|
||||
|
||||
namespace Pinetime {
|
||||
namespace System {
|
||||
class SystemTask;
|
||||
}
|
||||
|
||||
namespace Controllers {
|
||||
class NotificationManager;
|
||||
|
||||
class ImmediateAlertClient : public BleClient {
|
||||
public:
|
||||
enum class Levels : uint8_t { NoAlert = 0, MildAlert = 1, HighAlert = 2 };
|
||||
|
||||
ImmediateAlertClient(Pinetime::System::SystemTask& systemTask);
|
||||
void Init();
|
||||
|
||||
bool OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service);
|
||||
int OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error* error, const ble_gatt_chr* characteristic);
|
||||
|
||||
bool sendImmediateAlert(Levels level);
|
||||
|
||||
static constexpr const ble_uuid16_t* Uuid() {
|
||||
return &ImmediateAlertClient::immediateAlertClientUuid;
|
||||
}
|
||||
|
||||
static constexpr const ble_uuid16_t* AlertLevelCharacteristicUuid() {
|
||||
return &ImmediateAlertClient::alertLevelCharacteristicUuid;
|
||||
}
|
||||
|
||||
void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) override;
|
||||
|
||||
private:
|
||||
Pinetime::System::SystemTask& systemTask;
|
||||
|
||||
static constexpr uint16_t immediateAlertClientId {0x1802};
|
||||
static constexpr uint16_t alertLevelId {0x2A06};
|
||||
|
||||
static constexpr ble_uuid16_t immediateAlertClientUuid {.u {.type = BLE_UUID_TYPE_16}, .value = immediateAlertClientId};
|
||||
static constexpr ble_uuid16_t alertLevelCharacteristicUuid {.u {.type = BLE_UUID_TYPE_16}, .value = alertLevelId};
|
||||
|
||||
bool isDiscovered = false;
|
||||
uint16_t iasStartHandle;
|
||||
uint16_t iasEndHandle;
|
||||
bool isCharacteristicDiscovered = false;
|
||||
|
||||
struct ble_gatt_chr_def characteristicDefinition[3];
|
||||
struct ble_gatt_svc_def serviceDefinition[2];
|
||||
|
||||
uint16_t alertLevelHandle;
|
||||
std::function<void(uint16_t)> onServiceDiscovered;
|
||||
};
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
#include "components/ble/MusicService.h"
|
||||
#include "components/ble/NimbleController.h"
|
||||
#include <cstring>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
|
||||
namespace {
|
||||
// 0000yyxx-78fc-48fe-8e23-433b3a1942d0
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <host/ble_uuid.h>
|
||||
#undef max
|
||||
#undef min
|
||||
#include <FreeRTOS.h>
|
||||
|
||||
namespace Pinetime {
|
||||
namespace Controllers {
|
||||
|
|
|
@ -46,10 +46,11 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask,
|
|||
weatherService {dateTimeController},
|
||||
batteryInformationService {batteryController},
|
||||
immediateAlertService {systemTask, notificationManager},
|
||||
iaClient {systemTask},
|
||||
heartRateService {*this, heartRateController},
|
||||
motionService {*this, motionController},
|
||||
fsService {systemTask, fs},
|
||||
serviceDiscovery({¤tTimeClient, &alertNotificationClient}) {
|
||||
serviceDiscovery({¤tTimeClient, &alertNotificationClient, &iaClient}) {
|
||||
}
|
||||
|
||||
void nimble_on_reset(int reason) {
|
||||
|
@ -95,6 +96,7 @@ void NimbleController::Init() {
|
|||
dfuService.Init();
|
||||
batteryInformationService.Init();
|
||||
immediateAlertService.Init();
|
||||
iaClient.Init();
|
||||
heartRateService.Init();
|
||||
motionService.Init();
|
||||
fsService.Init();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "components/ble/FSService.h"
|
||||
#include "components/ble/HeartRateService.h"
|
||||
#include "components/ble/ImmediateAlertService.h"
|
||||
#include "components/ble/ImmediateAlertClient.h"
|
||||
#include "components/ble/MusicService.h"
|
||||
#include "components/ble/NavigationService.h"
|
||||
#include "components/ble/ServiceDiscovery.h"
|
||||
|
@ -71,6 +72,10 @@ namespace Pinetime {
|
|||
return weatherService;
|
||||
};
|
||||
|
||||
Pinetime::Controllers::ImmediateAlertClient& immediateAlertClient() {
|
||||
return iaClient;
|
||||
}
|
||||
|
||||
uint16_t connHandle();
|
||||
void NotifyBatteryLevel(uint8_t level);
|
||||
|
||||
|
@ -103,6 +108,7 @@ namespace Pinetime {
|
|||
NavigationService navService;
|
||||
BatteryInformationService batteryInformationService;
|
||||
ImmediateAlertService immediateAlertService;
|
||||
ImmediateAlertClient iaClient;
|
||||
HeartRateService heartRateService;
|
||||
MotionService motionService;
|
||||
FSService fsService;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
using namespace Pinetime::Controllers;
|
||||
|
||||
ServiceDiscovery::ServiceDiscovery(std::array<BleClient*, 2>&& clients) : clients {clients} {
|
||||
ServiceDiscovery::ServiceDiscovery(std::array<BleClient*, 3>&& clients) : clients {clients} {
|
||||
}
|
||||
|
||||
void ServiceDiscovery::StartDiscovery(uint16_t connectionHandle) {
|
||||
|
@ -29,4 +29,4 @@ void ServiceDiscovery::DiscoverNextService(uint16_t connectionHandle) {
|
|||
this->OnServiceDiscovered(connectionHandle);
|
||||
};
|
||||
(*clientIterator)->Discover(connectionHandle, discoverNextService);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,13 +9,13 @@ namespace Pinetime {
|
|||
|
||||
class ServiceDiscovery {
|
||||
public:
|
||||
ServiceDiscovery(std::array<BleClient*, 2>&& bleClients);
|
||||
ServiceDiscovery(std::array<BleClient*, 3>&& bleClients);
|
||||
|
||||
void StartDiscovery(uint16_t connectionHandle);
|
||||
|
||||
private:
|
||||
BleClient** clientIterator;
|
||||
std::array<BleClient*, 2> clients;
|
||||
std::array<BleClient*, 3> clients;
|
||||
void OnServiceDiscovered(uint16_t connectionHandle);
|
||||
void DiscoverNextService(uint16_t connectionHandle);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "displayapp/DisplayApp.h"
|
||||
#include <libraries/log/nrf_log.h>
|
||||
#include "displayapp/screens/HeartRate.h"
|
||||
#include "displayapp/screens/FindMyPhone.h"
|
||||
#include "displayapp/screens/Motion.h"
|
||||
#include "displayapp/screens/Timer.h"
|
||||
#include "displayapp/screens/Alarm.h"
|
||||
|
@ -582,7 +583,7 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
|
|||
currentScreen = std::make_unique<Screens::SettingWakeUp>(settingsController);
|
||||
break;
|
||||
case Apps::SettingDisplay:
|
||||
currentScreen = std::make_unique<Screens::SettingDisplay>(this, settingsController);
|
||||
currentScreen = std::make_unique<Screens::SettingDisplay>(settingsController);
|
||||
break;
|
||||
case Apps::SettingSteps:
|
||||
currentScreen = std::make_unique<Screens::SettingSteps>(settingsController);
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace Pinetime {
|
|||
SettingChimes,
|
||||
SettingShakeThreshold,
|
||||
SettingBluetooth,
|
||||
FindMyPhone,
|
||||
Error
|
||||
};
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ else ()
|
|||
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Dice")
|
||||
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Metronome")
|
||||
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Navigation")
|
||||
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::FindMyPhone")
|
||||
set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Weather")
|
||||
#set(DEFAULT_USER_APP_TYPES "${DEFAULT_USER_APP_TYPES}, Apps::Motion")
|
||||
set(USERAPP_TYPES "${DEFAULT_USER_APP_TYPES}" CACHE STRING "List of user apps to build into the firmware")
|
||||
|
|
|
@ -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, 0xf002"
|
||||
}
|
||||
],
|
||||
"bpp": 1,
|
||||
|
|
|
@ -117,7 +117,7 @@ Alarm::Alarm(Controllers::AlarmController& alarmController,
|
|||
|
||||
UpdateAlarmTime();
|
||||
|
||||
if (alarmController.State() == Controllers::AlarmController::AlarmState::Alerting) {
|
||||
if (alarmController.IsAlerting()) {
|
||||
SetAlerting();
|
||||
} else {
|
||||
SetSwitchState(LV_ANIM_OFF);
|
||||
|
@ -125,14 +125,15 @@ Alarm::Alarm(Controllers::AlarmController& alarmController,
|
|||
}
|
||||
|
||||
Alarm::~Alarm() {
|
||||
if (alarmController.State() == AlarmController::AlarmState::Alerting) {
|
||||
if (alarmController.IsAlerting()) {
|
||||
StopAlerting();
|
||||
}
|
||||
lv_obj_clean(lv_scr_act());
|
||||
alarmController.SaveAlarm();
|
||||
}
|
||||
|
||||
void Alarm::DisableAlarm() {
|
||||
if (alarmController.State() == AlarmController::AlarmState::Set) {
|
||||
if (alarmController.IsEnabled()) {
|
||||
alarmController.DisableAlarm();
|
||||
lv_switch_off(enableSwitch, LV_ANIM_ON);
|
||||
}
|
||||
|
@ -172,7 +173,7 @@ bool Alarm::OnButtonPushed() {
|
|||
HideInfo();
|
||||
return true;
|
||||
}
|
||||
if (alarmController.State() == AlarmController::AlarmState::Alerting) {
|
||||
if (alarmController.IsAlerting()) {
|
||||
StopAlerting();
|
||||
return true;
|
||||
}
|
||||
|
@ -181,7 +182,7 @@ bool Alarm::OnButtonPushed() {
|
|||
|
||||
bool Alarm::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||
// Don't allow closing the screen by swiping while the alarm is alerting
|
||||
return alarmController.State() == AlarmController::AlarmState::Alerting && event == TouchEvents::SwipeDown;
|
||||
return alarmController.IsAlerting() && event == TouchEvents::SwipeDown;
|
||||
}
|
||||
|
||||
void Alarm::OnValueChanged() {
|
||||
|
@ -222,15 +223,10 @@ void Alarm::StopAlerting() {
|
|||
}
|
||||
|
||||
void Alarm::SetSwitchState(lv_anim_enable_t anim) {
|
||||
switch (alarmController.State()) {
|
||||
case AlarmController::AlarmState::Set:
|
||||
lv_switch_on(enableSwitch, anim);
|
||||
break;
|
||||
case AlarmController::AlarmState::Not_Set:
|
||||
lv_switch_off(enableSwitch, anim);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (alarmController.IsEnabled()) {
|
||||
lv_switch_on(enableSwitch, anim);
|
||||
} else {
|
||||
lv_switch_off(enableSwitch, anim);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,7 +243,7 @@ void Alarm::ShowInfo() {
|
|||
txtMessage = lv_label_create(btnMessage, nullptr);
|
||||
lv_obj_set_style_local_bg_color(btnMessage, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_NAVY);
|
||||
|
||||
if (alarmController.State() == AlarmController::AlarmState::Set) {
|
||||
if (alarmController.IsEnabled()) {
|
||||
auto timeToAlarm = alarmController.SecondsToAlarm();
|
||||
|
||||
auto daysToAlarm = timeToAlarm / 86400;
|
||||
|
|
126
src/displayapp/screens/FindMyPhone.cpp
Normal file
126
src/displayapp/screens/FindMyPhone.cpp
Normal file
|
@ -0,0 +1,126 @@
|
|||
#include "displayapp/screens/FindMyPhone.h"
|
||||
#include <lvgl/lvgl.h>
|
||||
|
||||
#include "displayapp/DisplayApp.h"
|
||||
#include "displayapp/InfiniTimeTheme.h"
|
||||
|
||||
using namespace Pinetime::Applications::Screens;
|
||||
|
||||
namespace {
|
||||
static constexpr char defaultLabelText[] = "Find my phone";
|
||||
static constexpr char alertSentLabelText[] = "Alert sent";
|
||||
static constexpr char noConnectionLabelText[] = "No connection";
|
||||
static constexpr auto restoreLabelTimeoutTicks = pdMS_TO_TICKS(2 * 1000);
|
||||
|
||||
void btnImmediateAlertEventHandler(lv_obj_t* obj, lv_event_t event) {
|
||||
auto* screen = static_cast<FindMyPhone*>(obj->user_data);
|
||||
screen->OnImmediateAlertEvent(obj, event);
|
||||
}
|
||||
|
||||
void RestoreLabelTaskCallback(lv_task_t* task) {
|
||||
auto* screen = static_cast<FindMyPhone*>(task->user_data);
|
||||
screen->RestoreLabelText();
|
||||
screen->StopRestoreLabelTask();
|
||||
}
|
||||
}
|
||||
|
||||
FindMyPhone::FindMyPhone(Pinetime::Controllers::ImmediateAlertClient& immediateAlertClient) : immediateAlertClient {immediateAlertClient} {
|
||||
last_level = Pinetime::Controllers::ImmediateAlertClient::Levels::NoAlert;
|
||||
|
||||
container = lv_cont_create(lv_scr_act(), nullptr);
|
||||
|
||||
lv_obj_set_size(container, LV_HOR_RES, LV_VER_RES);
|
||||
lv_obj_set_style_local_bg_color(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||
lv_obj_set_style_local_pad_all(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
lv_obj_set_style_local_pad_inner(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
lv_obj_set_style_local_border_width(container, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||
|
||||
label_title = lv_label_create(lv_scr_act(), nullptr);
|
||||
|
||||
lv_label_set_text_static(label_title, defaultLabelText);
|
||||
lv_obj_set_style_local_text_color(label_title, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
lv_obj_align(label_title, nullptr, LV_ALIGN_CENTER, 0, -40);
|
||||
|
||||
bt_none = lv_btn_create(container, nullptr);
|
||||
bt_none->user_data = this;
|
||||
lv_obj_set_event_cb(bt_none, btnImmediateAlertEventHandler);
|
||||
lv_obj_set_size(bt_none, 76, 76);
|
||||
lv_obj_align(bt_none, nullptr, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
|
||||
label_none = lv_label_create(bt_none, nullptr);
|
||||
lv_label_set_text_static(label_none, "None");
|
||||
lv_obj_set_style_local_bg_color(bt_none, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
|
||||
bt_mild = lv_btn_create(container, nullptr);
|
||||
bt_mild->user_data = this;
|
||||
lv_obj_set_event_cb(bt_mild, btnImmediateAlertEventHandler);
|
||||
lv_obj_set_size(bt_mild, 76, 76);
|
||||
lv_obj_align(bt_mild, nullptr, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||
label_mild = lv_label_create(bt_mild, nullptr);
|
||||
lv_label_set_text_static(label_mild, "Mild");
|
||||
lv_obj_set_style_local_bg_color(bt_mild, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
|
||||
|
||||
bt_high = lv_btn_create(container, nullptr);
|
||||
bt_high->user_data = this;
|
||||
lv_obj_set_event_cb(bt_high, btnImmediateAlertEventHandler);
|
||||
lv_obj_set_size(bt_high, 76, 76);
|
||||
lv_obj_align(bt_high, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
|
||||
label_high = lv_label_create(bt_high, nullptr);
|
||||
lv_label_set_text_static(label_high, "High");
|
||||
lv_obj_set_style_local_bg_color(bt_high, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||
}
|
||||
|
||||
FindMyPhone::~FindMyPhone() {
|
||||
lv_obj_clean(lv_scr_act());
|
||||
}
|
||||
|
||||
void FindMyPhone::OnImmediateAlertEvent(lv_obj_t* obj, lv_event_t event) {
|
||||
if (event == LV_EVENT_CLICKED) {
|
||||
if (obj == bt_none) {
|
||||
last_level = Pinetime::Controllers::ImmediateAlertClient::Levels::NoAlert;
|
||||
} else if (obj == bt_mild) {
|
||||
last_level = Pinetime::Controllers::ImmediateAlertClient::Levels::MildAlert;
|
||||
} else if (obj == bt_high) {
|
||||
last_level = Pinetime::Controllers::ImmediateAlertClient::Levels::HighAlert;
|
||||
}
|
||||
UpdateImmediateAlerts();
|
||||
}
|
||||
}
|
||||
|
||||
void FindMyPhone::UpdateImmediateAlerts() {
|
||||
switch (last_level) {
|
||||
case Pinetime::Controllers::ImmediateAlertClient::Levels::NoAlert:
|
||||
lv_obj_set_style_local_text_color(label_title, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
break;
|
||||
case Pinetime::Controllers::ImmediateAlertClient::Levels::MildAlert:
|
||||
lv_obj_set_style_local_text_color(label_title, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight);
|
||||
break;
|
||||
case Pinetime::Controllers::ImmediateAlertClient::Levels::HighAlert:
|
||||
lv_obj_set_style_local_text_color(label_title, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||
break;
|
||||
}
|
||||
if (immediateAlertClient.sendImmediateAlert(last_level)) {
|
||||
lv_label_set_text_static(label_title, alertSentLabelText);
|
||||
} else {
|
||||
lv_label_set_text_static(label_title, noConnectionLabelText);
|
||||
}
|
||||
ScheduleRestoreLabelTask();
|
||||
}
|
||||
|
||||
void FindMyPhone::ScheduleRestoreLabelTask() {
|
||||
if (taskRestoreLabelText) {
|
||||
return;
|
||||
}
|
||||
taskRestoreLabelText = lv_task_create(RestoreLabelTaskCallback, restoreLabelTimeoutTicks, LV_TASK_PRIO_MID, this);
|
||||
}
|
||||
|
||||
void FindMyPhone::StopRestoreLabelTask() {
|
||||
if (taskRestoreLabelText) {
|
||||
lv_task_del(taskRestoreLabelText);
|
||||
taskRestoreLabelText = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void FindMyPhone::RestoreLabelText() {
|
||||
lv_label_set_text_static(label_title, defaultLabelText);
|
||||
lv_obj_set_style_local_text_color(label_title, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray);
|
||||
}
|
62
src/displayapp/screens/FindMyPhone.h
Normal file
62
src/displayapp/screens/FindMyPhone.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <chrono>
|
||||
#include "displayapp/screens/Screen.h"
|
||||
#include "Symbols.h"
|
||||
#include "systemtask/SystemTask.h"
|
||||
#include "components/ble/ImmediateAlertClient.h"
|
||||
|
||||
#include <lvgl/src/lv_core/lv_style.h>
|
||||
#include <lvgl/src/lv_core/lv_obj.h>
|
||||
|
||||
namespace Pinetime {
|
||||
|
||||
namespace Controllers {
|
||||
class ImmediateAlertClient;
|
||||
}
|
||||
|
||||
namespace Applications {
|
||||
namespace Screens {
|
||||
|
||||
class FindMyPhone : public Screen {
|
||||
public:
|
||||
explicit FindMyPhone(Pinetime::Controllers::ImmediateAlertClient& immediateAlertClient);
|
||||
~FindMyPhone() override;
|
||||
|
||||
void OnImmediateAlertEvent(lv_obj_t* obj, lv_event_t event);
|
||||
|
||||
void ScheduleRestoreLabelTask();
|
||||
void StopRestoreLabelTask();
|
||||
void RestoreLabelText();
|
||||
|
||||
private:
|
||||
Pinetime::Controllers::ImmediateAlertClient& immediateAlertClient;
|
||||
|
||||
void UpdateImmediateAlerts();
|
||||
|
||||
lv_obj_t* container;
|
||||
lv_obj_t* label_title;
|
||||
lv_obj_t* bt_none;
|
||||
lv_obj_t* bt_high;
|
||||
lv_obj_t* bt_mild;
|
||||
lv_obj_t* label_none;
|
||||
lv_obj_t* label_high;
|
||||
lv_obj_t* label_mild;
|
||||
lv_task_t* taskRestoreLabelText = nullptr;
|
||||
|
||||
Pinetime::Controllers::ImmediateAlertClient::Levels last_level;
|
||||
};
|
||||
}
|
||||
|
||||
template <>
|
||||
struct AppTraits<Apps::FindMyPhone> {
|
||||
static constexpr Apps app = Apps::FindMyPhone;
|
||||
static constexpr const char* icon = Screens::Symbols::magnifyingGlass;
|
||||
|
||||
static Screens::Screen* Create(AppControllers& controllers) {
|
||||
return new Screens::FindMyPhone(controllers.systemTask->nimble().immediateAlertClient());
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
|
@ -39,6 +39,7 @@ namespace Pinetime {
|
|||
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* magnifyingGlass = "\xEF\x80\x82"; // f002
|
||||
|
||||
// fontawesome_weathericons.c
|
||||
// static constexpr const char* sun = "\xEF\x86\x85";
|
||||
|
|
|
@ -40,8 +40,7 @@ SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp* app,
|
|||
Pinetime::Controllers::MotionController& motionController,
|
||||
const Pinetime::Drivers::Cst816S& touchPanel,
|
||||
const Pinetime::Drivers::SpiNorFlash& spiNorFlash)
|
||||
: app {app},
|
||||
dateTimeController {dateTimeController},
|
||||
: dateTimeController {dateTimeController},
|
||||
batteryController {batteryController},
|
||||
brightnessController {brightnessController},
|
||||
bleController {bleController},
|
||||
|
|
|
@ -35,7 +35,6 @@ namespace Pinetime {
|
|||
bool OnTouchEvent(TouchEvents event) override;
|
||||
|
||||
private:
|
||||
DisplayApp* app;
|
||||
Pinetime::Controllers::DateTime& dateTimeController;
|
||||
const Pinetime::Controllers::Battery& batteryController;
|
||||
Pinetime::Controllers::BrightnessController& brightnessController;
|
||||
|
|
|
@ -24,8 +24,7 @@ namespace {
|
|||
|
||||
constexpr std::array<uint16_t, 6> SettingDisplay::options;
|
||||
|
||||
SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController)
|
||||
: app {app}, settingsController {settingsController} {
|
||||
SettingDisplay::SettingDisplay(Pinetime::Controllers::Settings& settingsController) : settingsController {settingsController} {
|
||||
|
||||
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);
|
||||
|
||||
|
|
|
@ -14,14 +14,13 @@ namespace Pinetime {
|
|||
|
||||
class SettingDisplay : public Screen {
|
||||
public:
|
||||
SettingDisplay(DisplayApp* app, Pinetime::Controllers::Settings& settingsController);
|
||||
SettingDisplay(Pinetime::Controllers::Settings& settingsController);
|
||||
~SettingDisplay() override;
|
||||
|
||||
void UpdateSelected(lv_obj_t* object, lv_event_t event);
|
||||
void ToggleAlwaysOn();
|
||||
|
||||
private:
|
||||
DisplayApp* app;
|
||||
static constexpr std::array<uint16_t, 6> options = {5000, 7000, 10000, 15000, 20000, 30000};
|
||||
|
||||
Controllers::Settings& settingsController;
|
||||
|
|
|
@ -15,8 +15,7 @@ bool SettingSetDateTime::OnTouchEvent(Pinetime::Applications::TouchEvents event)
|
|||
SettingSetDateTime::SettingSetDateTime(Pinetime::Applications::DisplayApp* app,
|
||||
Pinetime::Controllers::DateTime& dateTimeController,
|
||||
Pinetime::Controllers::Settings& settingsController)
|
||||
: app {app},
|
||||
dateTimeController {dateTimeController},
|
||||
: dateTimeController {dateTimeController},
|
||||
settingsController {settingsController},
|
||||
screens {app,
|
||||
0,
|
||||
|
|
|
@ -20,7 +20,6 @@ namespace Pinetime {
|
|||
void Quit();
|
||||
|
||||
private:
|
||||
DisplayApp* app;
|
||||
Controllers::DateTime& dateTimeController;
|
||||
Controllers::Settings& settingsController;
|
||||
|
||||
|
|
|
@ -54,8 +54,7 @@ SettingWatchFace::SettingWatchFace(Pinetime::Applications::DisplayApp* app,
|
|||
std::array<Screens::SettingWatchFace::Item, UserWatchFaceTypes::Count>&& watchfaceItems,
|
||||
Pinetime::Controllers::Settings& settingsController,
|
||||
Pinetime::Controllers::FS& filesystem)
|
||||
: app {app},
|
||||
watchfaceItems {std::move(watchfaceItems)},
|
||||
: watchfaceItems {std::move(watchfaceItems)},
|
||||
settingsController {settingsController},
|
||||
filesystem {filesystem},
|
||||
screens {app, 0, CreateScreenList(), Screens::ScreenListModes::UpDown} {
|
||||
|
|
|
@ -34,7 +34,6 @@ namespace Pinetime {
|
|||
bool OnTouchEvent(TouchEvents event) override;
|
||||
|
||||
private:
|
||||
DisplayApp* app;
|
||||
auto CreateScreenList() const;
|
||||
std::unique_ptr<Screen> CreateScreen(unsigned int screenNum) const;
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ Pinetime::Controllers::DateTime dateTimeController {settingsController};
|
|||
Pinetime::Drivers::Watchdog watchdog;
|
||||
Pinetime::Controllers::NotificationManager notificationManager;
|
||||
Pinetime::Controllers::MotionController motionController;
|
||||
Pinetime::Controllers::AlarmController alarmController {dateTimeController};
|
||||
Pinetime::Controllers::AlarmController alarmController {dateTimeController, fs};
|
||||
Pinetime::Controllers::TouchHandler touchHandler;
|
||||
Pinetime::Controllers::ButtonHandler buttonHandler;
|
||||
Pinetime::Controllers::BrightnessController brightnessController {};
|
||||
|
|
|
@ -216,7 +216,7 @@ void SystemTask::Work() {
|
|||
GoToSleep();
|
||||
break;
|
||||
case Messages::OnNewTime:
|
||||
if (alarmController.State() == Controllers::AlarmController::AlarmState::Set) {
|
||||
if (alarmController.IsEnabled()) {
|
||||
alarmController.ScheduleAlarm();
|
||||
}
|
||||
break;
|
||||
|
@ -317,8 +317,7 @@ void SystemTask::Work() {
|
|||
case Messages::OnNewHour:
|
||||
using Pinetime::Controllers::AlarmController;
|
||||
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
|
||||
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours &&
|
||||
alarmController.State() != AlarmController::AlarmState::Alerting) {
|
||||
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && !alarmController.IsAlerting()) {
|
||||
GoToRunning();
|
||||
displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
|
||||
}
|
||||
|
@ -326,8 +325,7 @@ void SystemTask::Work() {
|
|||
case Messages::OnNewHalfHour:
|
||||
using Pinetime::Controllers::AlarmController;
|
||||
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
|
||||
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours &&
|
||||
alarmController.State() != AlarmController::AlarmState::Alerting) {
|
||||
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && !alarmController.IsAlerting()) {
|
||||
GoToRunning();
|
||||
displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue