From af409b82f1a83b83a691ece14f29508c17ea09c2 Mon Sep 17 00:00:00 2001 From: joeycastillo Date: Fri, 25 Oct 2024 08:28:11 -0400 Subject: [PATCH] log activity to file --- movement_config.h | 2 +- watch-faces/io/chirpy_demo_face.c | 36 +++++++++++------- watch-faces/sensor/activity_logging_face.c | 44 ++++++++++++++-------- watch-faces/sensor/activity_logging_face.h | 14 +++++-- 4 files changed, 62 insertions(+), 34 deletions(-) diff --git a/movement_config.h b/movement_config.h index 1fc7ca35..fd01eac5 100644 --- a/movement_config.h +++ b/movement_config.h @@ -84,7 +84,7 @@ const watch_face_t watch_faces[] = { * 6: 2 days * 7: 7 days */ -#define MOVEMENT_DEFAULT_LOW_ENERGY_INTERVAL 1 +#define MOVEMENT_DEFAULT_LOW_ENERGY_INTERVAL 0 /* Set the led duration * Valid values are: diff --git a/watch-faces/io/chirpy_demo_face.c b/watch-faces/io/chirpy_demo_face.c index 65305124..673da201 100644 --- a/watch-faces/io/chirpy_demo_face.c +++ b/watch-faces/io/chirpy_demo_face.c @@ -34,7 +34,7 @@ typedef enum { } chirpy_demo_mode_t; typedef enum { - CDP_SCALE = 0, + CDP_CLEAR = 0, CDP_INFO_SHORT, CDP_INFO_LONG, CDP_INFO_NANOSEC, @@ -111,7 +111,7 @@ void chirpy_demo_face_activate(void *context) { memset(context, 0, sizeof(chirpy_demo_state_t)); state->mode = CDM_CHOOSE; - state->program = CDP_SCALE; + state->program = CDP_INFO_NANOSEC; // Do we have activity data? Load it. int32_t sz = filesystem_get_file_size(ACTIVITY_DATA_FILE_NAME); @@ -123,7 +123,7 @@ void chirpy_demo_face_activate(void *context) { activity_buffer_size = sz + 2; activity_buffer = malloc(activity_buffer_size); // First two bytes of prefix, so Chirpy RX can recognize this data type - activity_buffer[0] = 0xc0; + activity_buffer[0] = 0x41; activity_buffer[1] = 0x00; // Read file filesystem_read_file(ACTIVITY_DATA_FILE_NAME, (char*)&activity_buffer[2], sz); @@ -136,16 +136,18 @@ void chirpy_demo_face_activate(void *context) { static void _cdf_update_lcd(chirpy_demo_state_t *state) { watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "CH", "Chirp"); - if (state->program == CDP_SCALE) - watch_display_text(WATCH_POSITION_BOTTOM, " SCALE"); - else if (state->program == CDP_INFO_SHORT) + if (state->program == CDP_CLEAR) { + movement_force_led_on(255, 0, 0); + watch_display_text(WATCH_POSITION_BOTTOM, "CLEAR?"); + } else if (state->program == CDP_INFO_SHORT) { watch_display_text(WATCH_POSITION_BOTTOM, "SHORT "); - else if (state->program == CDP_INFO_LONG) + } else if (state->program == CDP_INFO_LONG) { watch_display_text(WATCH_POSITION_BOTTOM, " LOng "); - else if (state->program == CDP_INFO_NANOSEC) + } else if (state->program == CDP_INFO_NANOSEC) { watch_display_text(WATCH_POSITION_BOTTOM, " ACtIV"); - else + } else { watch_display_text(WATCH_POSITION_BOTTOM, "---- "); + } } static void _cdf_quit_chirping(chirpy_demo_state_t *state) { @@ -207,7 +209,7 @@ static void _cdf_countdown_tick(void *context) { tick_state->tick_count = -1; tick_state->seq_pos = 0; // We'll be chirping out a scale - if (state->program == CDP_SCALE) { + if (false) { // state->program == CDP_CLEAR) { tick_state->tick_fun = _cdf_scale_tick; } // We'll be chirping out data @@ -271,7 +273,7 @@ bool chirpy_demo_face_loop(movement_event_t event, void *context) { case EVENT_ALARM_BUTTON_UP: // If in choose mode: select next program if (state->mode == CDM_CHOOSE) { - if (state->program == CDP_SCALE) + if (state->program == CDP_CLEAR) state->program = CDP_INFO_SHORT; else if (state->program == CDP_INFO_SHORT) state->program = CDP_INFO_LONG; @@ -279,9 +281,9 @@ bool chirpy_demo_face_loop(movement_event_t event, void *context) { if (activity_buffer_size > 0) state->program = CDP_INFO_NANOSEC; else - state->program = CDP_SCALE; + state->program = CDP_CLEAR; } else if (state->program == CDP_INFO_NANOSEC) - state->program = CDP_SCALE; + state->program = CDP_CLEAR; _cdf_update_lcd(state); } // If chirping: stoppit @@ -292,7 +294,13 @@ bool chirpy_demo_face_loop(movement_event_t event, void *context) { case EVENT_ALARM_LONG_PRESS: // If in choose mode: start chirping if (state->mode == CDM_CHOOSE) { - _cdm_setup_chirp(state); + if (state->program == CDP_CLEAR) { + filesystem_write_file("activity.dat", "", 0); + movement_force_led_off(); + movement_move_to_next_face(); + } else { + _cdm_setup_chirp(state); + } } break; case EVENT_TICK: diff --git a/watch-faces/sensor/activity_logging_face.c b/watch-faces/sensor/activity_logging_face.c index 05e8fcc7..cdd8c98a 100644 --- a/watch-faces/sensor/activity_logging_face.c +++ b/watch-faces/sensor/activity_logging_face.c @@ -25,6 +25,7 @@ #include #include #include "activity_logging_face.h" +#include "filesystem.h" #include "watch.h" #ifdef HAS_ACCELEROMETER @@ -37,14 +38,27 @@ extern uint8_t active_minutes; static void _activity_logging_face_log_data(activity_logging_state_t *state) { watch_date_time_t date_time = movement_get_local_date_time(); size_t pos = state->data_points % ACTIVITY_LOGGING_NUM_DATA_POINTS; + activity_logging_data_point_t data_point = {0}; + + data_point.bit.day = date_time.unit.day; + data_point.bit.month = date_time.unit.month; + data_point.bit.hour = date_time.unit.hour; + data_point.bit.minute = date_time.unit.minute; + data_point.bit.active_minutes = active_minutes; + data_point.bit.orientation_changes = orientation_changes; + // print size of thing + printf("Size of data point: %d\n", sizeof(activity_logging_data_point_t)); + if (filesystem_append_file("activity.dat", (char *)&data_point, sizeof(activity_logging_data_point_t))) { + printf("Data point written\n", state->data_points); + } else { + printf("Failed to write data point\n"); + } + + state->data[pos].reg = data_point.reg; + state->data_points++; - state->data[pos].timestamp.reg = date_time.reg; - state->data[pos].active_minutes = active_minutes; - state->data[pos].orientation_changes = orientation_changes; active_minutes = 0; orientation_changes = 0; - - state->data_points++; } static void _activity_logging_face_update_display(activity_logging_state_t *state, bool clock_mode_24h) { @@ -63,26 +77,25 @@ static void _activity_logging_face_update_display(activity_logging_state_t *stat watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); } else if (state->ts_ticks) { // we are displaying the timestamp in response to a button press - watch_date_time_t date_time = state->data[pos].timestamp; watch_set_colon(); if (clock_mode_24h) { watch_set_indicator(WATCH_INDICATOR_24H); } else { - if (date_time.unit.hour > 11) watch_set_indicator(WATCH_INDICATOR_PM); - date_time.unit.hour %= 12; - if (date_time.unit.hour == 0) date_time.unit.hour = 12; + if (state->data[pos].bit.hour > 11) watch_set_indicator(WATCH_INDICATOR_PM); + state->data[pos].bit.hour %= 12; + if (state->data[pos].bit.hour == 0) state->data[pos].bit.hour = 12; } watch_display_text(WATCH_POSITION_TOP_LEFT, "AT"); - sprintf(buf, "%2d", date_time.unit.day); + sprintf(buf, "%2d", state->data[pos].bit.day); watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); - sprintf(buf, "%2d%02d%02d", date_time.unit.hour, date_time.unit.minute, date_time.unit.second); + sprintf(buf, "%2d%02d%02d", state->data[pos].bit.hour, state->data[pos].bit.minute, 0); watch_display_text(WATCH_POSITION_BOTTOM, buf); } else { // we are displaying the number of accelerometer wakeups and orientation changes watch_display_text(WATCH_POSITION_TOP, "AC"); sprintf(buf, "%2d", state->display_index); watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); - sprintf(buf, "%-3lu/%2d", state->data[pos].orientation_changes > 999 ? 999 : state->data[pos].orientation_changes, state->data[pos].active_minutes); + sprintf(buf, "%-3lu/%2d", state->data[pos].bit.orientation_changes > 999 ? 999 : state->data[pos].bit.orientation_changes, state->data[pos].bit.active_minutes); watch_display_text(WATCH_POSITION_BOTTOM, buf); } } @@ -92,6 +105,8 @@ void activity_logging_face_setup(uint8_t watch_face_index, void ** context_ptr) if (*context_ptr == NULL) { *context_ptr = malloc(sizeof(activity_logging_state_t)); memset(*context_ptr, 0, sizeof(activity_logging_state_t)); + // create file if it doesn't exist + if (!filesystem_file_exists("activity.dat")) filesystem_write_file("activity.dat", "", 0); } } @@ -146,9 +161,8 @@ movement_watch_face_advisory_t activity_logging_face_advise(void *context) { (void) context; movement_watch_face_advisory_t retval = { 0 }; - // this will get called at the top of each minute, so all we check is if we're at the top of the hour as well. - // if we are, we ask for a background task. - retval.wants_background_task = watch_rtc_get_date_time().unit.minute == 0; + // log data every 5 minutes + retval.wants_background_task = (movement_get_local_date_time().unit.minute % 5) == 0; return retval; } diff --git a/watch-faces/sensor/activity_logging_face.h b/watch-faces/sensor/activity_logging_face.h index 4848e637..86717f4c 100644 --- a/watch-faces/sensor/activity_logging_face.h +++ b/watch-faces/sensor/activity_logging_face.h @@ -41,10 +41,16 @@ #define ACTIVITY_LOGGING_NUM_DATA_POINTS (36) -typedef struct { - watch_date_time_t timestamp; - uint8_t active_minutes; - uint32_t orientation_changes; +typedef union { + struct { + uint32_t day: 5; + uint32_t month: 4; + uint32_t hour: 5; + uint32_t minute: 6; + uint32_t active_minutes: 3; + uint32_t orientation_changes: 9; + } bit; + uint32_t reg; } activity_logging_data_point_t; typedef struct {