/* * MIT License * * Copyright (c) 2025 Konrad Rieck * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* * This watch face monitors daily hydration by tracking and logging water intake. * * In tracking mode: Display current water intake and percentage * - Alarm button: +100ml (or configured glass size) * - Light button: -100ml (or configured glass size) * - Alarm long press: Display deviation from estimate * - Light long press: Switch to settings mode * - Alarm really long press: Switch to log mode * * In settings mode: Configure glass size, daily goal, wake time, sleep time, alert interval * - Light button: Switch to next setting * - Alarm button: Advance current setting * - Alarm long press: Reset to default value * - Mode button: Switch to tracking mode * In log mode: Display log entries of water intake, date and deviation from goal * - Alarm button: Switch to next log entry * - Light button: Cycle through intake, date and deviation * - Mode button: Switch to tracking mode * * Background tasks: * - Automatic reset at wake time * - Alert if intake below estimate at sleep time * - Alert at interval if intake below estimate * */ #include "movement.h" /* Number of log entries */ #define HYDRATION_LOG_ENTRIES 30 /* Number of log types */ #define HYDRATION_LOG_TYPES 3 typedef enum { PAGE_HYDRATION_TRACKING, PAGE_HYDRATION_SETTINGS, PAGE_HYDRATION_LOG } hydration_page_t; typedef enum { HYDRATION_SETTING_WATER_GLASS, HYDRATION_SETTING_WATER_GOAL, HYDRATION_SETTING_WAKE_TIME, HYDRATION_SETTING_SLEEP_TIME, HYDRATION_SETTING_ALERT_INTERVAL, } hydration_setting_t; typedef enum { HYDRATION_LOG_INTAKE, HYDRATION_LOG_DATE, HYDRATION_LOG_DEVIATION, } hydration_log_type_t; typedef struct { void (*display)(void *, uint8_t); void (*advance)(void *); } hydration_settings_t; typedef struct { uint8_t water_intake; /* Logged intake (intake / 100) */ uint16_t date; /* Logged date (ts / 86400) */ } hydration_log_t; typedef struct { uint16_t water_intake; /* Current water intake in ml */ uint16_t water_glass; /* Glass size in ml (default 100ml) */ uint16_t water_goal; /* Target daily water intake (default 1600ml) */ uint8_t wake_hour; /* Hour for wake time (default 7) */ uint8_t sleep_hour; /* Hour for sleep time (default 22) */ uint8_t alert_interval; /* Alert interval in hours (default 2) */ uint8_t face_index; /* Face index */ uint8_t display_deviation; /* Display deviation from estimate */ bool alert_enabled; /* Alert enabled */ hydration_page_t page; /* Current page */ /* Log */ hydration_log_t log[HYDRATION_LOG_ENTRIES]; /* Log entries */ hydration_log_type_t log_type; /* Log type */ uint8_t log_index; /* Log index */ uint8_t log_head; /* Log head */ /* Settings */ hydration_setting_t settings_page; /* Current settings page */ hydration_settings_t *settings; /* Settings configuration */ } hydration_state_t; void hydration_face_setup(uint8_t watch_face_index, void **context_ptr); void hydration_face_activate(void *context); bool hydration_face_loop(movement_event_t event, void *context); void hydration_face_resign(void *context); movement_watch_face_advisory_t hydration_face_advise(void *context); #define hydration_face ((const watch_face_t){ \ hydration_face_setup, \ hydration_face_activate, \ hydration_face_loop, \ hydration_face_resign, \ hydration_face_advise, \ })