mirror of
https://github.com/google/pebble.git
synced 2025-11-30 19:22:22 -05:00
535 lines
25 KiB
C
535 lines
25 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "activity.h"
|
|
#include "hr_util.h"
|
|
|
|
#include "applib/event_service_client.h"
|
|
#include "kernel/events.h"
|
|
#include "os/mutex.h"
|
|
#include "services/normal/data_logging/data_logging_service.h"
|
|
#include "services/normal/settings/settings_file.h"
|
|
#include "system/hexdump.h"
|
|
#include "system/logging.h"
|
|
#include "util/attributes.h"
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#define ACTIVITY_LOG_DEBUG(fmt, args...) \
|
|
PBL_LOG_D(LOG_DOMAIN_ACTIVITY, LOG_LEVEL_DEBUG, fmt, ## args)
|
|
|
|
#define ACTIVITY_HEXDUMP(data, length) \
|
|
PBL_HEXDUMP_D(LOG_DOMAIN_DATA_ACTIVITY, LOG_LEVEL_DEBUG, data, length)
|
|
|
|
// How often we update settings with the current step/sleep stats for today.
|
|
#define ACTIVITY_SETTINGS_UPDATE_MIN 15
|
|
|
|
// How often we recompute the activity sessions (like sleep, walks, runs). This has significant
|
|
// enough CPU requirements to warrant only recomputing occasionally
|
|
#define ACTIVITY_SESSION_UPDATE_MIN 15
|
|
|
|
// Every scalar metric and setting is stored in globals and in the settings file using this
|
|
// typedef
|
|
typedef uint16_t ActivityScalarStore;
|
|
#define ACTIVITY_SCALAR_MAX UINT16_MAX
|
|
|
|
// Each step average interval covers this many minutes
|
|
#define ACTIVITY_STEP_AVERAGES_MINUTES (MINUTES_PER_DAY / ACTIVITY_NUM_METRIC_AVERAGES)
|
|
|
|
// flash vs. the most amount of data we could lose if we reset.
|
|
#define ACTIVITY_STEP_AVERAGES_PER_KEY 4
|
|
#define ACTIVITY_STEP_AVERAGES_KEYS_PER_DAY \
|
|
(ACTIVITY_NUM_METRIC_AVERAGES / ACTIVITY_STEP_AVERAGES_PER_KEY)
|
|
|
|
// If we see at least this many steps in a minute, it was an "active minute"
|
|
#define ACTIVITY_ACTIVE_MINUTE_MIN_STEPS 40
|
|
|
|
// We consider any sleep session that ends after this minute of the day (representing 9pm) as
|
|
// part of the next day's sleep
|
|
#define ACTIVITY_LAST_SLEEP_MINUTE_OF_DAY (21 * MINUTES_PER_HOUR)
|
|
|
|
// Default HeartRate sampling period (Must take a sample every X seconds by default)
|
|
#define ACTIVITY_DEFAULT_HR_PERIOD_SEC (10 * SECONDS_PER_MINUTE)
|
|
|
|
// Default HeartRate sampling ON time (Stays on for X seconds every
|
|
// ACTIVITY_DEFAULT_HR_PERIOD_SEC seconds)
|
|
#define ACTIVITY_DEFAULT_HR_ON_TIME_SEC (SECONDS_PER_MINUTE)
|
|
|
|
// Turn off the HR device after we've received X number of thresholded samples
|
|
#define ACTIVITY_MIN_NUM_SAMPLES_SHORT_CIRCUIT (15)
|
|
|
|
// The minimum number of samples needed before we can approximate the user's HR zone
|
|
#define ACTIVITY_MIN_NUM_SAMPLES_FOR_HR_ZONE (10)
|
|
|
|
#define ACTIVITY_MIN_HR_QUALITY_THRESH (HRMQuality_Good)
|
|
|
|
// HRM Subscription values during ON and OFF periods
|
|
#define ACTIVITY_HRM_SUBSCRIPTION_ON_PERIOD_SEC (1)
|
|
#define ACTIVITY_HRM_SUBSCRIPTION_OFF_PERIOD_SEC (SECONDS_PER_DAY)
|
|
|
|
// Max number of stored HR samples to compute the median
|
|
#define ACTIVITY_MAX_HR_SAMPLES (3 * SECONDS_PER_MINUTE)
|
|
|
|
// Conversion factors
|
|
#define ACTIVITY_DAG_PER_KG 100
|
|
|
|
|
|
// -----------------------------------------------------------------------------------------
|
|
// Settings file info and keys
|
|
#define ACTIVITY_SETTINGS_FILE_NAME "activity"
|
|
#define ACTIVITY_SETTINGS_FILE_LEN 0x4000
|
|
|
|
// The version of our settings file
|
|
// Version 1 - ActivitySettingsKeyVersion didn't exist
|
|
// Version 2 - Changed file size from 2k to 16k
|
|
#define ACTIVITY_SETTINGS_CURRENT_VERSION 2
|
|
|
|
typedef struct {
|
|
uint32_t utc_sec; // timestamp of first entry in list
|
|
// One entry per day. The most recent day (today) is stored at index 0
|
|
ActivityScalarStore values[ACTIVITY_HISTORY_DAYS];
|
|
} ActivitySettingsValueHistory;
|
|
|
|
|
|
// Keys of the settings we save in our settings file.
|
|
typedef enum {
|
|
ActivitySettingsKeyInvalid = 0, // Used for error discovery
|
|
ActivitySettingsKeyVersion, // uint16_t: ACTIVITY_SETTINGS_CURRENT_VERSION
|
|
ActivitySettingsKeyUnused0, // Unused
|
|
ActivitySettingsKeyUnused1, // Unused
|
|
ActivitySettingsKeyUnused2, // Unused
|
|
ActivitySettingsKeyUnused3, // Unused
|
|
|
|
ActivitySettingsKeyStepCountHistory, // ActivitySettingsValueHistory
|
|
ActivitySettingsKeyStepMinutesHistory, // ActivitySettingsValueHistory
|
|
ActivitySettingsKeyUnused4, // Unused
|
|
ActivitySettingsKeyDistanceMetersHistory, // ActivitySettingsValueHistory
|
|
ActivitySettingsKeySleepTotalMinutesHistory, // ActivitySettingsValueHistory
|
|
ActivitySettingsKeySleepDeepMinutesHistory, // ActivitySettingsValueHistory
|
|
ActivitySettingsKeySleepEntryMinutesHistory, // ActivitySettingsValueHistory
|
|
// How long it took to fall asleep
|
|
ActivitySettingsKeySleepEnterAtHistory, // ActivitySettingsValueHistory
|
|
// What time the user fell asleep. Measured in
|
|
// minutes after midnight.
|
|
ActivitySettingsKeySleepExitAtHistory, // ActivitySettingsValueHistory
|
|
// What time the user woke up. Measured in
|
|
// minutes after midnight
|
|
ActivitySettingsKeySleepState, // uint16_t
|
|
ActivitySettingsKeySleepStateMinutes, // uint16_t
|
|
ActivitySettingsKeyStepAveragesWeekdayFirst, // ACTIVITY_STEP_AVERAGES_PER_CHUNK * uint16_t
|
|
ActivitySettingsKeyStepAveragesWeekdayLast =
|
|
ActivitySettingsKeyStepAveragesWeekdayFirst + ACTIVITY_STEP_AVERAGES_KEYS_PER_DAY - 1,
|
|
|
|
ActivitySettingsKeyStepAveragesWeekendFirst, // ACTIVITY_STEP_AVERAGES_PER_CHUNK * uint16_t
|
|
ActivitySettingsKeyStepAveragesWeekendLast =
|
|
ActivitySettingsKeyStepAveragesWeekendFirst + ACTIVITY_STEP_AVERAGES_KEYS_PER_DAY - 1,
|
|
ActivitySettingsKeyAgeYears, // uint16_t: age in years
|
|
|
|
ActivitySettingsKeyUnused5, // Unused
|
|
|
|
ActivitySettingsKeyInsightSleepRewardTime, // time_t: time we last showed the sleep reward
|
|
// This will be 0 if we haven't triggered one yet
|
|
ActivitySettingsKeyInsightActivityRewardTime, // time_t: time we last showed the activity reward
|
|
// This will be 0 if we haven't triggered one yet
|
|
ActivitySettingsKeyInsightActivitySummaryState, // SummaryPinLastState: the UUID and last time the
|
|
// pin was added
|
|
ActivitySettingsKeyInsightSleepSummaryState, // SummaryPinLastState: the UUID and last time the
|
|
// pin was added
|
|
ActivitySettingsKeyRestingKCaloriesHistory, // ActivitySettingsValueHistory
|
|
ActivitySettingsKeyActiveKCaloriesHistory, // ActivitySettingsValueHistory
|
|
ActivitySettingsKeyLastSleepActivityUTC, // time_t: UTC timestamp of the last sleep related
|
|
// activity we logged to analytics
|
|
ActivitySettingsKeyLastRestfulSleepActivityUTC, // time_t: UTC timestamp of the last restful sleep
|
|
// related activity we logged to analytics
|
|
ActivitySettingsKeyLastStepActivityUTC, // time_t: UTC timestamp of the last step related
|
|
// activity we logged to analytics
|
|
ActivitySettingsKeyStoredActivities, // ActivitySession[
|
|
// ACTIVITY_MAX_ACTIVITY_SESSIONS_COUNT]
|
|
ActivitySettingsKeyInsightNapSessionTime, // time_t: time we last showed the nap pin
|
|
ActivitySettingsKeyInsightActivitySessionTime, // time_t: time we last showed the activity pin
|
|
ActivitySettingsKeyLastVMC, // uint16_t: the VMC at the last processed minute
|
|
ActivitySettingsKeyRestingHeartRate, // ActivitySettingsValueHistory
|
|
ActivitySettingsKeyHeartRateZone1Minutes,
|
|
ActivitySettingsKeyHeartRateZone2Minutes,
|
|
ActivitySettingsKeyHeartRateZone3Minutes,
|
|
} ActivitySettingsKey;
|
|
|
|
|
|
// -----------------------------------------------------------------------------------------
|
|
// Internal structs
|
|
// IMPORTANT: activity_metrics_prv_get_metric_info() assumes that every element of ActivityStepData
|
|
// is an ActivityScalarStore
|
|
typedef struct {
|
|
ActivityScalarStore steps;
|
|
ActivityScalarStore step_minutes;
|
|
ActivityScalarStore distance_meters;
|
|
ActivityScalarStore resting_kcalories;
|
|
ActivityScalarStore active_kcalories;
|
|
} ActivityStepData;
|
|
|
|
// IMPORTANT: activity_metrics_prv_get_metric_info() assumes that every element of ActivitySleepData
|
|
// is an ActivityScalarStore
|
|
typedef struct {
|
|
ActivityScalarStore total_minutes;
|
|
ActivityScalarStore restful_minutes;
|
|
ActivityScalarStore enter_at_minute; // minutes after midnight
|
|
ActivityScalarStore exit_at_minute; // minutes after midnight
|
|
ActivityScalarStore cur_state; // HealthActivity
|
|
ActivityScalarStore cur_state_elapsed_minutes;
|
|
} ActivitySleepData;
|
|
|
|
// IMPORTANT: activity_metrics_prv_get_metric_info() assumes that elements of
|
|
// ActivityHeartRateData are ActivityScalarStore by default. The update_time_utc is
|
|
// specially coded as a 32-bit metric and is allowed to be because we don't persist it in
|
|
// the settings file and it has no history
|
|
typedef struct {
|
|
ActivityScalarStore current_bpm; // Most current reading
|
|
uint32_t current_update_time_utc; // Timestamp of the current HR reading
|
|
ActivityScalarStore current_hr_zone;
|
|
ActivityScalarStore resting_bpm;
|
|
ActivityScalarStore current_quality; // HRMQuality
|
|
ActivityScalarStore last_stable_bpm;
|
|
uint32_t last_stable_bpm_update_time_utc; // Timestamp of the last stable BPM
|
|
ActivityScalarStore previous_median_bpm; // Most recently calculated median HR in a minute
|
|
int32_t previous_median_total_weight_x100;
|
|
ActivityScalarStore minutes_in_zone[HRZoneCount];
|
|
bool is_hr_elevated;
|
|
} ActivityHeartRateData;
|
|
|
|
|
|
// This callback used to convert a metric from the storage format (as a ActivityScalarStore) into
|
|
// the return format (uint32_t) returned by activity_get_metric. It might convert minutes to
|
|
// seconds, etc.
|
|
typedef uint32_t (*ActivityMetricConverter)(ActivityScalarStore storage_value);
|
|
|
|
// Filled in by activity_metrics_prv_get_metric_info()
|
|
typedef struct {
|
|
ActivityScalarStore *value_p; // pointer to storage in globals
|
|
uint32_t *value_u32p; // alternate value pointer for 32-bit metrics. These
|
|
// can NOT have history and settings_key MUST be
|
|
// ActivitySettingsKeyInvalid.
|
|
bool has_history; // True if this metric has history. This determines the
|
|
// size of the value as stored in settings
|
|
ActivitySettingsKey settings_key; // Settings key for this value
|
|
ActivityMetricConverter converter; // convert from storage value to return value.
|
|
} ActivityMetricInfo;
|
|
|
|
// Used by activity_feed_samples
|
|
typedef struct {
|
|
uint16_t num_samples;
|
|
AccelRawData data[];
|
|
} ActivityFeedSamples;
|
|
|
|
// Version of our legacy sleep session logging records (prior to FW 3.11). NOTE: The version
|
|
// field is treated as a bitfield. For version 1, only bit 0 is set. As long as we keep bit 0 set,
|
|
// we are free to add more fields to the end of ActivityLegacySleepSessionDataLoggingRecord and the
|
|
// mobile app will continue to assume it can parse the blob. If bit 0 is cleared, the mobile app
|
|
// will know that it has no chance of parsing the blob (until the mobile app is updated of course).
|
|
#define ACTIVITY_SLEEP_SESSION_LOGGING_VERSION 1
|
|
|
|
// Data logging record used to send sleep sessions to the phone
|
|
typedef struct PACKED {
|
|
uint16_t version; // set to ACTIVITY_SLEEP_SESSION_LOGGING_VERSION
|
|
int32_t utc_to_local; // Add this to UTC to get local time
|
|
uint32_t start_utc; // The start time in UTC
|
|
uint32_t end_utc; // The end time in UTC
|
|
uint32_t restful_secs;
|
|
} ActivityLegacySleepSessionDataLoggingRecord;
|
|
|
|
// Version of our activity session logging records. NOTE: The version field is treated as a
|
|
// bitfield. For version 1, only bit 0 is set. As long as we keep bit 0 set, we are free to
|
|
// add more fields to the end of ActivitySessionDataLoggingRecord and the mobile app
|
|
// will continue to assume it can parse the blob. If bit 0 is cleared, the mobile app will know that
|
|
// it has no chance of parsing the blob (until the mobile app is updated of course).
|
|
#define ACTIVITY_SESSION_LOGGING_VERSION 3
|
|
|
|
// Data logging record used to send activity sessions to the phone
|
|
// NOTE: modifying this struct requires a bump to the ACTIVITY_SESSION_LOGGING_VERSION and
|
|
// an update to documentation on this wiki page:
|
|
// https://pebbletechnology.atlassian.net/wiki/pages/viewpage.action?pageId=46301269
|
|
typedef struct PACKED {
|
|
uint16_t version; // set to ACTIVITY_SESSION_LOGGING_VERSION
|
|
uint16_t size; // size of this structure
|
|
uint16_t activity; // ActivitySessionType: the type of activity
|
|
int32_t utc_to_local; // Add this to UTC to get local time
|
|
uint32_t start_utc; // The start time in UTC
|
|
uint32_t elapsed_sec; // Elapsed time in seconds
|
|
|
|
// New fields add in version 3
|
|
union {
|
|
ActivitySessionDataStepping step_data;
|
|
ActivitySessionDataSleeping sleep_data;
|
|
};
|
|
} ActivitySessionDataLoggingRecord;
|
|
|
|
// -----------------------------------------------------------------------------------------
|
|
// Globals
|
|
|
|
// Support for raw accel sample collection
|
|
typedef struct {
|
|
// The data logging session for the current sample collection session
|
|
DataLoggingSession *dls_session;
|
|
|
|
// Most recently encoded accel sample value. Used for detecting and encoding runs of the same
|
|
// value
|
|
uint32_t prev_sample; // See comments in ActivityRawSamplesRecord for encoding
|
|
uint8_t run_size; // run size of prev_sample
|
|
|
|
// The currently forming record
|
|
ActivityRawSamplesRecord record;
|
|
|
|
// large enough to base64 encode half of the record at once.
|
|
char base64_buf[sizeof(ActivityRawSamplesRecord)];
|
|
|
|
// True if we are forming the first record
|
|
bool first_record;
|
|
} ActivitySampleCollectionData;
|
|
|
|
// This type is defined in measurements_log.h but we can't include measurements_log.h in this header
|
|
// because of build issues with the auto-generated SDK files.
|
|
typedef void *ProtobufLogRef;
|
|
|
|
// Support for heart rate
|
|
typedef struct {
|
|
ActivityHeartRateData metrics; // ActivityMetrics for heart rate
|
|
|
|
HRMSessionRef hrm_session; // The HRM session we use
|
|
ProtobufLogRef log_session; // The measurements log we send data to
|
|
|
|
bool currently_sampling; // Are we activity sampling the HR
|
|
uint32_t toggled_sampling_at_ts; // When we last toggled our sampling rate
|
|
// (from time_get_uptime_seconds)
|
|
|
|
uint32_t last_sample_ts; // When we last received a HR sample
|
|
// (from time_get_uptime_seconds)
|
|
|
|
uint16_t num_samples; // number of samples in the past minute
|
|
uint16_t num_quality_samples; // number of samples in the past minute that have met our
|
|
// quality threshold ACTIVITY_MIN_HR_QUALITY_THRESH
|
|
// NOTE: Used to short circuit
|
|
// our HR polling when enough samples have been taken
|
|
uint8_t samples[ACTIVITY_MAX_HR_SAMPLES]; // HR Samples stored
|
|
uint8_t weights[ACTIVITY_MAX_HR_SAMPLES]; // HR Sample Weights
|
|
} ActivityHRSupport;
|
|
|
|
typedef struct {
|
|
// Mutex for serializing access to these globals
|
|
PebbleRecursiveMutex *mutex;
|
|
|
|
// Semaphore used for waiting for KernelBG to finish a callback
|
|
SemaphoreHandle_t bg_wait_semaphore;
|
|
|
|
// Accel session ref
|
|
AccelServiceState *accel_session;
|
|
|
|
// Event Service to keep track of whether the charger is connected
|
|
EventServiceInfo charger_subscription;
|
|
|
|
// Cumulative stats for today
|
|
ActivityStepData step_data;
|
|
ActivitySleepData sleep_data;
|
|
|
|
// We accumulate distance in mm to and active/resting calories in calories (not kcalories) to
|
|
// minimize rounding errors since we increment them every time we get a new rate reading from the
|
|
// algorithm (every 5 seconds).
|
|
uint32_t distance_mm;
|
|
uint32_t active_calories;
|
|
uint32_t resting_calories;
|
|
ActivityScalarStore last_vmc;
|
|
uint8_t last_orientation;
|
|
time_t rate_last_update_time;
|
|
|
|
// Most recently calculated minute average walking rate
|
|
ActivityScalarStore steps_per_minute;
|
|
ActivityScalarStore steps_per_minute_last_steps;
|
|
|
|
// The most recent minute that had any significant step activity. Used for computing
|
|
// amount of time it takes to fall asleep
|
|
uint16_t last_active_minute;
|
|
|
|
// Heart rate support
|
|
ActivityHRSupport hr;
|
|
|
|
// Most recent values from prv_get_day()
|
|
uint16_t cur_day_index;
|
|
|
|
// Modulo counter used to periodically update settings file
|
|
int8_t update_settings_counter;
|
|
|
|
// Captured activity sessions
|
|
uint16_t activity_sessions_count; // how many sessions we have captured
|
|
ActivitySession activity_sessions[ACTIVITY_MAX_ACTIVITY_SESSIONS_COUNT];
|
|
bool need_activities_saved; // true if activities need to be persisted
|
|
|
|
// Set to true when a new sleep session is registered
|
|
bool sleep_sessions_modified;
|
|
|
|
// Exit time for the last sleep/step activities we logged. Used to prevent logging the same event
|
|
// more than once.
|
|
time_t logged_sleep_activity_exit_at_utc;
|
|
time_t logged_restful_sleep_activity_exit_at_utc;
|
|
time_t logged_step_activity_exit_at_utc;
|
|
|
|
// Data logging session used for sending activity sessions (introduced in v3.11)
|
|
DataLoggingSession *activity_dls_session;
|
|
|
|
// Variables used for detecting "significant activity" events
|
|
time_t activity_event_start_utc; // UTC of first active minute, 0 if none detected
|
|
|
|
// True if service has been enabled via services_set_runlevel.
|
|
bool enabled_run_level;
|
|
// True if the current state of charging allows the service to run.
|
|
bool enabled_charging_state;
|
|
|
|
// True if activity tracking should be started. If enabled is false, this can still be true
|
|
// and will tell us that we should re-start tracking once enabled gets set again.
|
|
bool should_be_started;
|
|
|
|
// True if tracking has actually been started. This will only ever be set if enabled is also
|
|
// true.
|
|
bool started;
|
|
|
|
// Support for raw accel sample collection
|
|
bool sample_collection_enabled;
|
|
uint16_t sample_collection_session_id; // raw sample collection session id
|
|
time_t sample_collection_seconds; // if enabled is true, the UTC when sample
|
|
// collection started, else the # of seconds of
|
|
// of data in recently ended session
|
|
uint16_t sample_collection_num_samples; // number of samples collected so far
|
|
ActivitySampleCollectionData *sample_collection_data;
|
|
|
|
// True if activity_start_tracking was called with test_mode = true
|
|
bool test_mode;
|
|
bool pending_test_cb;
|
|
} ActivityState;
|
|
|
|
//! Get pointer to the activity state
|
|
ActivityState *activity_private_state(void);
|
|
|
|
//! Get whether HRM is present
|
|
bool activity_is_hrm_present(void);
|
|
|
|
//! Shared with activity_insights.c - opens the activity settings file
|
|
//! IMPORTANT: This function must only be called during activity init routines or while holding
|
|
//! the activity mutex
|
|
SettingsFile *activity_private_settings_open(void);
|
|
|
|
//! Shared with activity_insights.c - closes the activity settings file
|
|
//! IMPORTANT: This function must only be called during activity init routines or while holding
|
|
//! the activity mutex
|
|
void activity_private_settings_close(SettingsFile *file);
|
|
|
|
//! Used by test apps (running on firmware): Re-initialize activity service. If reset_settings is
|
|
//! true, all persistent data is cleared
|
|
//! @param[in] reset_settings if true, reset all stored settings
|
|
//! @param[in] tracking_on if true, turn on tracking if not already on. Otherwise, preserve
|
|
//! the current tracking status
|
|
//! @param[in] sleep_history if not NULL, rewrite sleep history to these values
|
|
//! @param[in] step_history if not NULL, rewrite step history to these values
|
|
bool activity_test_reset(bool reset_settings, bool tracking_on,
|
|
const ActivitySettingsValueHistory *sleep_history,
|
|
const ActivitySettingsValueHistory *step_history);
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// Activity Sessions
|
|
// Load in the stored activities from our settings file
|
|
void activity_sessions_prv_init(SettingsFile *file, time_t utc_now);
|
|
|
|
// Get the UTC time bounds for the current day
|
|
void activity_sessions_prv_get_sleep_bounds_utc(time_t now_utc, time_t *enter_utc,
|
|
time_t *exit_utc);
|
|
|
|
// Remove all activity sessions that are older than "today", those that are invalid because they
|
|
// are in the future, and optionally those that are still ongoing.
|
|
void activity_sessions_prv_remove_out_of_range_activity_sessions(time_t utc_sec,
|
|
bool remove_ongoing);
|
|
|
|
//! Return true if the given activity type is sleep related
|
|
bool activity_sessions_prv_is_sleep_activity(ActivitySessionType activity_type);
|
|
|
|
//! Return true if the given activity type has session that is currently ongoing.
|
|
bool activity_sessions_is_session_type_ongoing(ActivitySessionType activity_type);
|
|
|
|
//! Register a new activity session. This is called by the algorithm logic when it detects a new
|
|
//! activity.
|
|
void activity_sessions_prv_add_activity_session(ActivitySession *session);
|
|
|
|
//! Delete an activity session. This is called by the algorithm logic when it decides to not
|
|
//! register a sleep session after all. Only sessions that are still 'ongoing' are allowed to be
|
|
//! deleted.
|
|
void activity_sessions_prv_delete_activity_session(ActivitySession *session);
|
|
|
|
//! Perform our once a minute activity session maintenance logic
|
|
void activity_sessions_prv_minute_handler(time_t utc_sec);
|
|
|
|
//! Send an activity session to data logging
|
|
void activity_sessions_prv_send_activity_session_to_data_logging(ActivitySession *session);
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Activity Metrics
|
|
|
|
//! Init all metrics
|
|
void activity_metrics_prv_init(SettingsFile *file, time_t utc_now);
|
|
|
|
//! Returns info about each metric we capture
|
|
void activity_metrics_prv_get_metric_info(ActivityMetric metric, ActivityMetricInfo *info);
|
|
|
|
//! Perform our once a minute metrics maintenance logic
|
|
void activity_metrics_prv_minute_handler(time_t utc_sec);
|
|
|
|
//! Returns the number of millimeters the user has walked so far today (since midnight)
|
|
uint32_t activity_metrics_prv_get_distance_mm(void);
|
|
|
|
//! Returns the number of resting calories the user has consumed so far today (since midnight)
|
|
uint32_t activity_metrics_prv_get_resting_calories(void);
|
|
|
|
//! Returns the number of active calories the user has consumed so far today (since midnight)
|
|
uint32_t activity_metrics_prv_get_active_calories(void);
|
|
|
|
//! Retrieve the median heart rate and the total weight x100 since it was last reset.
|
|
//! If no readings were recorded since it was reset, it will return 0.
|
|
//! This median can be reset using activity_metrics_prv_reset_hr_stats().
|
|
//! It is by default reset once a minute.
|
|
void activity_metrics_prv_get_median_hr_bpm(int32_t *median_out,
|
|
int32_t *heart_rate_total_weight_x100_out);
|
|
|
|
//! Retrieve the current HR zone since it was last reset.
|
|
//! If no readings were recorded since it was reset, it will return 0.
|
|
//! This HR zone can be reset using activity_metrics_prv_reset_hr_stats().
|
|
//! It is by default reset once a minute.
|
|
HRZone activity_metrics_prv_get_hr_zone(void);
|
|
|
|
//! Reset the average / median heart rate and hr zone
|
|
void activity_metrics_prv_reset_hr_stats(void);
|
|
|
|
//! Feed in a new heart rate sample that will be used to update the median. This updates
|
|
//! the value returned by activity_metrics_prv_get_median_hr_bpm().
|
|
void activity_metrics_prv_add_median_hr_sample(PebbleHRMEvent *hrm_event, time_t now_utc,
|
|
time_t now_uptime);
|
|
|
|
//! Returns the number of steps the user has taken so far today (since midnight)
|
|
uint32_t activity_metrics_prv_get_steps(void);
|
|
|
|
//! Returns the number of steps the user has walked in the past minute
|
|
ActivityScalarStore activity_metrics_prv_steps_per_minute(void);
|
|
|
|
//! Set a metric's value. Used from BlobDB to honor requests from the phone
|
|
void activity_metrics_prv_set_metric(ActivityMetric metric, DayInWeek day, int32_t value);
|