pebble/src/fw/services/normal/activity/insights_settings.h
2025-01-27 11:38:16 -08:00

136 lines
6.3 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 "services/normal/filesystem/pfs.h"
#include "util/attributes.h"
#define ACTIVITY_INSIGHTS_SETTINGS_SLEEP_REWARD "sleep_reward"
#define ACTIVITY_INSIGHTS_SETTINGS_SLEEP_SUMMARY "sleep_summary"
#define ACTIVITY_INSIGHTS_SETTINGS_ACTIVITY_REWARD "activity_reward"
#define ACTIVITY_INSIGHTS_SETTINGS_ACTIVITY_SUMMARY "activity_summary"
#define ACTIVITY_INSIGHTS_SETTINGS_ACTIVITY_SESSION "activity_session"
typedef struct PACKED ActivityRewardSettings {
// Note: these parameters are the number of days in addition to 'today' that we want to look at
uint8_t min_days_data; //!< How many days of the metric's history we require
uint8_t continuous_min_days_data; //!< How many consecutive days of history we require
uint8_t target_qualifying_days; //!< Days that must be above target (on top of 'today')
uint16_t target_percent_of_median; //!< Percentage of median qualifying days must hit
uint32_t notif_min_interval_seconds; //!< How often we allow this insight to be shown
// Insight-specific values
union {
struct PACKED {
uint16_t trigger_after_wakeup_seconds; //!< Time we wait before showing sleep reward
} sleep;
struct PACKED {
uint8_t trigger_active_minutes; //!< Time we must be currently active before showing reward
uint8_t trigger_steps_per_minute; //!< Steps per minute required for an 'active' minute
} activity;
};
} ActivityRewardSettings;
typedef struct PACKED ActivitySummarySettings {
int8_t above_avg_threshold; //!< Values greater than this are counted as above avg
//!< In relation to 100% (eg 105% would be 5)
int8_t below_avg_threshold; //!< Values less than this are counted as above avg
//!< In relation to 100% (eg 93% would be -7)
int8_t fail_threshold; //!< Values less than this are counted as fail
//!< In releastion to 100% (e.g. 55% would be -45)
union {
struct PACKED {
uint16_t trigger_minute; //!< Minute of the day that we trigger the pin
uint16_t update_threshold_steps; //!< Step delta that will cause the pin to update
uint32_t update_max_interval_seconds; //!< Max time we'll go without updating the pin
bool show_notification; //!< Whether to show a notification
uint16_t max_fail_steps; //!< Don't show negative if walked more than X steps
} activity;
struct PACKED {
uint16_t max_fail_minutes; //!< Don't show negative if slept more than X minutes
uint16_t trigger_notif_seconds; //!< Time in seconds after wakeup to notify about sleep
uint16_t trigger_notif_activity; //!< Minimum amount of steps per minute to trigger the
//!< Sleep summary notification
uint8_t trigger_notif_active_minutes; //!< Minimum amount of active minutes to trigger the
//!< Sleep summary notification
} sleep;
};
} ActivitySummarySettings;
typedef struct PACKED ActivitySessionSettings {
bool show_notification; //!< Whether to show a notification
union {
struct PACKED {
uint16_t trigger_elapsed_minutes; //!< Minimum length of a walk to be given an insight
uint16_t trigger_cooldown_minutes; //!< Minutes wait after end of session before notifying
} activity;
};
} ActivitySessionSettings;
typedef struct PACKED ActivityInsightSettings {
// Common parameters
uint8_t version; //!< Current version of the struct - must be first
bool enabled; //!< Insight enabled
uint8_t unused; //!< Unused
union {
ActivityRewardSettings reward;
ActivitySummarySettings summary;
ActivitySessionSettings session;
};
} ActivityInsightSettings;
//! Read a setting from the insights settings
//! @param insights_name the name of the insight for which to get a setting
//! @param[out] settings out an ActivityInsightSettings struct to which the data will be written
//! @returns true if the setting was found and the data is valid, false otherwise
//! @note if this function returns false, settings_out will be zeroed out.
bool activity_insights_settings_read(const char *insight_name,
ActivityInsightSettings *settings_out);
//! Write a setting to the insights settings (used for testing)
//! @param insights_name the name of the insight for which to get a setting
//! @param settings an ActivityInsightSettings struct which contains the data to be written
//! @returns true if the setting was successfully saved
bool activity_insights_settings_write(const char *insight_name,
ActivityInsightSettings *settings);
//! Get the current version of the insights settings
//! @return the version number for the current insights settings
//! @note this is separate from the struct version
uint16_t activity_insights_settings_get_version(void);
//! Initialize insights settings
void activity_insights_settings_init(void);
//! Watch the insights settings file. The callback is called whenever the file is closed with
//! modifications or deleted
//! @param callback Function to call when the file has been modified
//! @return Callback handle for passing into \ref activity_insights_settings_unwatch
PFSCallbackHandle activity_insights_settings_watch(PFSFileChangedCallback callback);
//! Stop watching the settings file
//! @param cb_handle Callback handle which was returned by \ref activity_insights_settings_watch
void activity_insights_settings_unwatch(PFSCallbackHandle cb_handle);