log activity to file

This commit is contained in:
joeycastillo 2024-10-25 08:28:11 -04:00
parent c0514ad39a
commit af409b82f1
4 changed files with 62 additions and 34 deletions

View File

@ -84,7 +84,7 @@ const watch_face_t watch_faces[] = {
* 6: 2 days * 6: 2 days
* 7: 7 days * 7: 7 days
*/ */
#define MOVEMENT_DEFAULT_LOW_ENERGY_INTERVAL 1 #define MOVEMENT_DEFAULT_LOW_ENERGY_INTERVAL 0
/* Set the led duration /* Set the led duration
* Valid values are: * Valid values are:

View File

@ -34,7 +34,7 @@ typedef enum {
} chirpy_demo_mode_t; } chirpy_demo_mode_t;
typedef enum { typedef enum {
CDP_SCALE = 0, CDP_CLEAR = 0,
CDP_INFO_SHORT, CDP_INFO_SHORT,
CDP_INFO_LONG, CDP_INFO_LONG,
CDP_INFO_NANOSEC, CDP_INFO_NANOSEC,
@ -111,7 +111,7 @@ void chirpy_demo_face_activate(void *context) {
memset(context, 0, sizeof(chirpy_demo_state_t)); memset(context, 0, sizeof(chirpy_demo_state_t));
state->mode = CDM_CHOOSE; state->mode = CDM_CHOOSE;
state->program = CDP_SCALE; state->program = CDP_INFO_NANOSEC;
// Do we have activity data? Load it. // Do we have activity data? Load it.
int32_t sz = filesystem_get_file_size(ACTIVITY_DATA_FILE_NAME); 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_size = sz + 2;
activity_buffer = malloc(activity_buffer_size); activity_buffer = malloc(activity_buffer_size);
// First two bytes of prefix, so Chirpy RX can recognize this data type // 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; activity_buffer[1] = 0x00;
// Read file // Read file
filesystem_read_file(ACTIVITY_DATA_FILE_NAME, (char*)&activity_buffer[2], sz); 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) { static void _cdf_update_lcd(chirpy_demo_state_t *state) {
watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "CH", "Chirp"); watch_display_text_with_fallback(WATCH_POSITION_TOP_LEFT, "CH", "Chirp");
if (state->program == CDP_SCALE) if (state->program == CDP_CLEAR) {
watch_display_text(WATCH_POSITION_BOTTOM, " SCALE"); movement_force_led_on(255, 0, 0);
else if (state->program == CDP_INFO_SHORT) watch_display_text(WATCH_POSITION_BOTTOM, "CLEAR?");
} else if (state->program == CDP_INFO_SHORT) {
watch_display_text(WATCH_POSITION_BOTTOM, "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 "); 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"); watch_display_text(WATCH_POSITION_BOTTOM, " ACtIV");
else } else {
watch_display_text(WATCH_POSITION_BOTTOM, "---- "); watch_display_text(WATCH_POSITION_BOTTOM, "---- ");
}
} }
static void _cdf_quit_chirping(chirpy_demo_state_t *state) { 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->tick_count = -1;
tick_state->seq_pos = 0; tick_state->seq_pos = 0;
// We'll be chirping out a scale // 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; tick_state->tick_fun = _cdf_scale_tick;
} }
// We'll be chirping out data // 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: case EVENT_ALARM_BUTTON_UP:
// If in choose mode: select next program // If in choose mode: select next program
if (state->mode == CDM_CHOOSE) { if (state->mode == CDM_CHOOSE) {
if (state->program == CDP_SCALE) if (state->program == CDP_CLEAR)
state->program = CDP_INFO_SHORT; state->program = CDP_INFO_SHORT;
else if (state->program == CDP_INFO_SHORT) else if (state->program == CDP_INFO_SHORT)
state->program = CDP_INFO_LONG; 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) if (activity_buffer_size > 0)
state->program = CDP_INFO_NANOSEC; state->program = CDP_INFO_NANOSEC;
else else
state->program = CDP_SCALE; state->program = CDP_CLEAR;
} else if (state->program == CDP_INFO_NANOSEC) } else if (state->program == CDP_INFO_NANOSEC)
state->program = CDP_SCALE; state->program = CDP_CLEAR;
_cdf_update_lcd(state); _cdf_update_lcd(state);
} }
// If chirping: stoppit // If chirping: stoppit
@ -292,7 +294,13 @@ bool chirpy_demo_face_loop(movement_event_t event, void *context) {
case EVENT_ALARM_LONG_PRESS: case EVENT_ALARM_LONG_PRESS:
// If in choose mode: start chirping // If in choose mode: start chirping
if (state->mode == CDM_CHOOSE) { 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; break;
case EVENT_TICK: case EVENT_TICK:

View File

@ -25,6 +25,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "activity_logging_face.h" #include "activity_logging_face.h"
#include "filesystem.h"
#include "watch.h" #include "watch.h"
#ifdef HAS_ACCELEROMETER #ifdef HAS_ACCELEROMETER
@ -37,14 +38,27 @@ extern uint8_t active_minutes;
static void _activity_logging_face_log_data(activity_logging_state_t *state) { static void _activity_logging_face_log_data(activity_logging_state_t *state) {
watch_date_time_t date_time = movement_get_local_date_time(); watch_date_time_t date_time = movement_get_local_date_time();
size_t pos = state->data_points % ACTIVITY_LOGGING_NUM_DATA_POINTS; 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; active_minutes = 0;
orientation_changes = 0; orientation_changes = 0;
state->data_points++;
} }
static void _activity_logging_face_update_display(activity_logging_state_t *state, bool clock_mode_24h) { 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); watch_display_text(WATCH_POSITION_TOP_RIGHT, buf);
} else if (state->ts_ticks) { } else if (state->ts_ticks) {
// we are displaying the timestamp in response to a button press // we are displaying the timestamp in response to a button press
watch_date_time_t date_time = state->data[pos].timestamp;
watch_set_colon(); watch_set_colon();
if (clock_mode_24h) { if (clock_mode_24h) {
watch_set_indicator(WATCH_INDICATOR_24H); watch_set_indicator(WATCH_INDICATOR_24H);
} else { } else {
if (date_time.unit.hour > 11) watch_set_indicator(WATCH_INDICATOR_PM); if (state->data[pos].bit.hour > 11) watch_set_indicator(WATCH_INDICATOR_PM);
date_time.unit.hour %= 12; state->data[pos].bit.hour %= 12;
if (date_time.unit.hour == 0) date_time.unit.hour = 12; if (state->data[pos].bit.hour == 0) state->data[pos].bit.hour = 12;
} }
watch_display_text(WATCH_POSITION_TOP_LEFT, "AT"); 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); 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); watch_display_text(WATCH_POSITION_BOTTOM, buf);
} else { } else {
// we are displaying the number of accelerometer wakeups and orientation changes // we are displaying the number of accelerometer wakeups and orientation changes
watch_display_text(WATCH_POSITION_TOP, "AC"); watch_display_text(WATCH_POSITION_TOP, "AC");
sprintf(buf, "%2d", state->display_index); sprintf(buf, "%2d", state->display_index);
watch_display_text(WATCH_POSITION_TOP_RIGHT, buf); 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); 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) { if (*context_ptr == NULL) {
*context_ptr = malloc(sizeof(activity_logging_state_t)); *context_ptr = malloc(sizeof(activity_logging_state_t));
memset(*context_ptr, 0, 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; (void) context;
movement_watch_face_advisory_t retval = { 0 }; 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. // log data every 5 minutes
// if we are, we ask for a background task. retval.wants_background_task = (movement_get_local_date_time().unit.minute % 5) == 0;
retval.wants_background_task = watch_rtc_get_date_time().unit.minute == 0;
return retval; return retval;
} }

View File

@ -41,10 +41,16 @@
#define ACTIVITY_LOGGING_NUM_DATA_POINTS (36) #define ACTIVITY_LOGGING_NUM_DATA_POINTS (36)
typedef struct { typedef union {
watch_date_time_t timestamp; struct {
uint8_t active_minutes; uint32_t day: 5;
uint32_t orientation_changes; 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; } activity_logging_data_point_t;
typedef struct { typedef struct {