/* * Update event timer */ void minute_timer(int tm_min) { // First time if (g_first_time) { g_first_time = false; calendar_request(); return; } // Only on the 10 minute clicks (importantly includes midnight) if (tm_min % 10 != 0) return; calendar_request(); }
/* * Messages incoming from the phone */ void received_message(DictionaryIterator *received, void *context) { Event temp_event; Tuple *tuple = dict_find(received, RECONNECT_KEY); if (tuple) { vibes_short_pulse(); calendar_request(); } // Gather the bits of a calendar together tuple = dict_find(received, CALENDAR_RESPONSE_KEY); if (tuple) { set_status(STATUS_REPLY); uint8_t i, j; if (g_count > g_received_rows) { i = g_received_rows; j = 0; } else { g_count = tuple->value->data[0]; i = 0; j = 1; } while (i < g_count && j < tuple->length) { memcpy(&temp_event, &tuple->value->data[j], sizeof(Event)); if (temp_event.index < MAX_EVENTS) memcpy(&g_events[temp_event.index], &temp_event, sizeof(Event)); i++; j += sizeof(Event); } g_received_rows = i; if (g_count == g_received_rows) { g_max_entries = g_count; process_rot_events(); if (nothing_showing) { nothing_showing = false; show_next_event(); } battery_request(); } } tuple = dict_find(received, BATTERY_RESPONSE_KEY); if (tuple) { memcpy(&g_battery_status, &tuple->value->data[0], sizeof(BatteryStatus)); set_battery(g_battery_status.state, g_battery_status.level); } }
/* * Clock syncronised timer */ void sync_timed_event(int tm_min, AppContextRef ctx) { // Only on the 10 minute clicks (importantly includes midnight) if (tm_min % 10 != 0 && !g_first_time) return; if (g_first_time) { g_first_time = false; calendar_request(); } else { // Delay for 35 seconds after the minute to ensure that alerts have already happened app_timer_send_event(ctx, 35000, REQUEST_CALENDAR_KEY); } }
/* * Timer handling. Includes a hold off for a period of time if there is resource contention */ void handle_calendar_timer(AppContextRef app_ctx, AppTimerHandle handle, uint32_t cookie) { // If we're rotating the visible event, get on with it. Slower overnight to save power if (cookie == ROTATE_EVENT) { // Clobber the timer app_timer_cancel_event(app_ctx, handle); // Show next event show_next_event(); // Kick off new timer if (is_overnight()) app_timer_send_event(app_ctx, ROTATE_EVENT_INTERVAL_OVERNIGHT_MS, cookie); else app_timer_send_event(app_ctx, ROTATE_EVENT_INTERVAL_MS, cookie); // Retire from active duty return; } // Show the alert and let the world know if (cookie >= ALERT_EVENT && cookie <= (ALERT_EVENT + (MAX_EVENTS * 2))) { app_timer_cancel_event(app_ctx, handle); int num = cookie - ALERT_EVENT; if (g_timer_rec[num].active == false) return; // Already had the data for this event deleted - cannot show it. g_timer_rec[num].active = false; g_showing_alert = true; set_event_display(g_timer_rec[num].event_desc, g_timer_rec[num].relative_desc, g_timer_rec[num].location, 0); set_invert_when_showing_event(true); app_timer_send_event(app_ctx, 30000, RESTORE_DATE); app_timer_send_event(app_ctx, 15000, SECOND_ALERT); vibes_double_pulse(); light_enable_interaction(); return; } // Let us know again if (cookie == SECOND_ALERT) { app_timer_cancel_event(app_ctx, handle); vibes_double_pulse(); light_enable_interaction(); return; } // Put the date back into the display area if (cookie == RESTORE_DATE) { app_timer_cancel_event(app_ctx, handle); g_showing_alert = false; show_next_event(); set_invert_when_showing_event(false); return; } // Fire the calendar request if (cookie == REQUEST_CALENDAR_KEY) { app_timer_cancel_event(app_ctx, handle); calendar_request(); } }
/* * Timer handling. Includes a hold off for a period of time if there is resource contention */ void handle_calendar_timer(void *cookie) { // Show the alert and let the world know if ((int)cookie >= ALERT_EVENT && (int)cookie <= ALERT_EVENT + MAX_EVENTS) { int num = (int)cookie - ALERT_EVENT; if (timer_rec[num].active == false) return; // Already had the data for this event deleted - cannot show it. timer_rec[num].active = false; for (int i = num + 1; i < max_entries; i++) { if (timer_rec[i].active == true) { handle_calendar_timer((void *)100 + i); vibes_short_pulse(); light_enable_interaction(); return; } } //draw_date(); return; } if ((int)cookie >= 100 && (int)cookie <= 100 + MAX_EVENTS) { int num = (int)cookie - 100; if (timer_rec[num].active == false) return; // Already had the data for this event Event event = events[num]; // Compute the event start time as a figure in ms int time_position = 9; if (event.start_date[5] != '/') time_position = 6; int hour = a_to_i(&event.start_date[time_position],2); int minute_position = time_position + 3; if (event.start_date[time_position + 1] == ':') minute_position = time_position + 2; int minute = a_to_i(&event.start_date[minute_position],2); uint32_t event_in_ms = (hour * 3600 + minute * 60) * 1000; // Get now as ms time_t rawtime; time(&rawtime); struct tm *time = localtime(&rawtime); uint32_t now_in_ms = (time->tm_hour * 3600 + time->tm_min * 60 + time->tm_sec) * 1000; // Work out the alert interval int32_t alert_event = event_in_ms - now_in_ms; // If this is negative then we are after the alert period if (alert_event >= 0) { set_relative_desc(num, alert_event); display_event_text(timer_rec[num].event_desc, timer_rec[num].relative_desc); if (alert_event == 0) { timer_rec[num].handle = app_timer_register(30000, handle_calendar_timer, (void *)ALERT_EVENT + num); vibes_double_pulse(); light_enable_interaction(); } else if (alert_event > 0) { timer_rec[num].handle = app_timer_register(60000 - time->tm_sec * 1000, handle_calendar_timer, (void *)100 + num); } } return; } // Server requests if ((int)cookie != REQUEST_CALENDAR_KEY) return; // If we're going to make a call to the phone, then a dictionary is a good idea. DictionaryIterator *iter; app_message_outbox_begin(&iter); // We didn't get a dictionary - so go away and wait until resources are available if (!iter) { // Can't get an dictionary then come back in a second app_timer_register(1000, handle_calendar_timer, (void *)cookie); return; } // Make the appropriate call to the server if ((int)cookie == REQUEST_CALENDAR_KEY) { calendar_request(iter); app_timer_register(REQUEST_CALENDAR_INTERVAL_MS, handle_calendar_timer, (void *)cookie); } }