static void tick(struct tm *tick_time, TimeUnits units_changed) { if (s_second_rate < 2) { layer_mark_dirty(s_date_layer); layer_mark_dirty(s_time_layer); } if (tick_time->tm_min == 0 && tick_time->tm_sec == 0 && s_vibe_hourly != SETTING_VIBE_DISABLED) { switch (s_vibe_hourly) { case SETTING_VIBE_LONG: vibes_long_pulse(); break; case SETTING_VIBE_SHORT: vibes_short_pulse(); break; case SETTING_VIBE_DOUBLE: vibes_double_pulse(); break; } } // Get weather update every 2 hours if (s_weather_icon == -1 || s_weather_temp == -100 || tick_time->tm_mday*100+tick_time->tm_hour > s_last_update_time + 1) { request_weather(); } if(tick_time->tm_hour % 2 == 0 && tick_time->tm_min == 0 && tick_time->tm_sec == 0) { request_weather(); } }
void handle_tick(struct tm *tick_time, TimeUnits units_changed) { static char date_text[] = "00 XXX"; static char time_text[] = "00:00"; clock_copy_time_string(time_text,sizeof time_text); APP_LOG(APP_LOG_LEVEL_DEBUG, "TICK @%s: (%d) %s%s%s%s", time_text, stale, (units_changed & DAY_UNIT) ? "D" : "-", (units_changed & HOUR_UNIT) ? "H" : "-", (units_changed & MINUTE_UNIT) ? "M" : "-", (units_changed & SECOND_UNIT) ? "S" : "-" ); if (units_changed & MINUTE_UNIT) { clock_copy_time_string(time_text,sizeof time_text); text_layer_set_text(time_layer,time_text); } if (units_changed & DAY_UNIT) { strftime(date_text, sizeof(date_text), "%a %e", tick_time); text_layer_set_text(date_layer,date_text); } if (units_changed & HOUR_UNIT) { if (bluetooth_ok) { request_weather(); } } }
static void window_load(Window *window) { Layer *window_layer = window_get_root_layer(window); GRect bounds = layer_get_bounds(window_layer); s_icon_layer = bitmap_layer_create(GRect(32, 10, 80, 80)); layer_add_child(window_layer, bitmap_layer_get_layer(s_icon_layer)); s_temperature_layer = text_layer_create(GRect(0, 75, bounds.size.w, 68)); text_layer_set_text_color(s_temperature_layer, GColorWhite); text_layer_set_background_color(s_temperature_layer, GColorClear); text_layer_set_font(s_temperature_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); text_layer_set_text_alignment(s_temperature_layer, GTextAlignmentCenter); layer_add_child(window_layer, text_layer_get_layer(s_temperature_layer)); s_city_layer = text_layer_create(GRect(0, 105, bounds.size.w, 68)); text_layer_set_text_color(s_city_layer, GColorWhite); text_layer_set_background_color(s_city_layer, GColorClear); text_layer_set_font(s_city_layer, fonts_get_system_font(FONT_KEY_GOTHIC_28_BOLD)); text_layer_set_text_alignment(s_city_layer, GTextAlignmentCenter); layer_add_child(window_layer, text_layer_get_layer(s_city_layer)); Tuplet initial_values[] = { TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1), TupletCString(WEATHER_TEMPERATURE_KEY, "1234\u00B0C"), TupletCString(WEATHER_CITY_KEY, "St Pebblesburg"), }; app_sync_init(&s_sync, s_sync_buffer, sizeof(s_sync_buffer), initial_values, ARRAY_LENGTH(initial_values), sync_tuple_changed_callback, sync_error_callback, NULL ); request_weather(); }
void location(float latitude, float longitude, float altitude, float accuracy, void* context) { // Fix the floats our_latitude = latitude * 10000; our_longitude = longitude * 10000; located = true; request_weather(); }
void weather_animate(void *context) { WeatherData *weather_data = (WeatherData*) context; WeatherLayerData *wld = layer_get_data(weather_layer); if (weather_data->updated == 0 && weather_data->error == WEATHER_E_OK) { animation_step = (animation_step % 3) + 1; layer_mark_dirty(wld->loading_layer); weather_animation_timer = app_timer_register(WEATHER_ANIMATION_REFRESH, weather_animate, weather_data); if (animation_step == WEATHER_INITIAL_RETRY_TIMEOUT) { // Fire off one last desperate attempt... request_weather(weather_data); } if (animation_step > WEATHER_ANIMATION_TIMEOUT) { weather_data->error = WEATHER_E_NETWORK; } } else if (weather_data->error != WEATHER_E_OK) { animation_step = 0; layer_set_hidden(wld->loading_layer, true); weather_layer_set_error(); } }
void handle_minute_tick(struct tm *tick_time, TimeUnits units_changed) { // Need to be static because they're used by the system later. static char date_text[] = "Sun Jan 00---------------------------"; static char wday_text[] = "XxxXxxXxxXxxXxx"; static char mnth_text[] = "YyyYyyYyyYyyYyy"; static char wdat_text[] = "00"; static char time_text[] = "00:00"; static int show = 0; char *time_format; strftime(wday_text, sizeof(wday_text), "%a", tick_time); strftime(mnth_text, sizeof(mnth_text), "%b", tick_time); strftime(wdat_text, sizeof(wdat_text), "%e", tick_time); strcpy(date_text, wday_text); strcat(date_text, " "); strcat(date_text, mnth_text); strcat(date_text, " "); strcat(date_text, wdat_text); text_layer_set_text(date_text_layer, date_text); if (clock_is_24h_style()) { time_format = "%R"; } else { time_format = "%I:%M"; } strftime(time_text, sizeof(time_text), time_format, tick_time); if (!clock_is_24h_style() && (time_text[0] == '0')) { memmove(time_text, &time_text[1], sizeof(time_text) - 1); } text_layer_set_text(time_text_layer, time_text); animate_amd_logo(); if (show == 0) request_weather(); show = (show + 1) % 30; }
static void handle_tick(struct tm *tick_time, TimeUnits units_changed) { if (units_changed & MINUTE_UNIT) { // Update the time - Deal with 12 / 24 format clock_copy_time_string(time_text, sizeof(time_text)); text_layer_set_text(time_layer, time_text); } if (units_changed & DAY_UNIT) { // Update the date - Without a leading 0 on the day of the month char day_text[4]; strftime(day_text, sizeof(day_text), "%a", tick_time); snprintf(date_text, sizeof(date_text), "%s %i", day_text, tick_time->tm_mday); text_layer_set_text(date_layer, date_text); } // Update the bottom half of the screen: icon and temperature static int animation_step = 0; if (weather_data->updated == 0 && weather_data->error == WEATHER_E_OK) { // 'Animate' loading icon until the first successful weather request if (animation_step == 0) { weather_layer_set_icon(weather_layer, WEATHER_ICON_LOADING1); } else if (animation_step == 1) { weather_layer_set_icon(weather_layer, WEATHER_ICON_LOADING2); } else if (animation_step >= 2) { weather_layer_set_icon(weather_layer, WEATHER_ICON_LOADING3); } animation_step = (animation_step + 1) % 3; } else { // Update the weather icon and temperature if (weather_data->error) { weather_layer_set_icon(weather_layer, WEATHER_ICON_PHONE_ERROR); } else { // Show the temperature as 'stale' if it has not been updated in 30 minutes bool stale = false; if (weather_data->updated > time(NULL) + 1800) { stale = true; } weather_layer_set_temperature(weather_layer, weather_data->temperature, stale); // Figure out if it's day or night. Not the best way to do this but the webservice // does not seem to return this info. bool night_time = false; if (tick_time->tm_hour >= 19 || tick_time->tm_hour < 7) night_time = true; weather_layer_set_icon(weather_layer, weather_icon_for_condition(weather_data->condition, night_time)); } } // Refresh the weather info every 15 minutes if (units_changed & MINUTE_UNIT && (tick_time->tm_min % 15) == 0) { request_weather(); } }
static void in_received_handler(DictionaryIterator *iter, void *context) { Tuple *message_tuple = dict_find(iter, WEATHER_MESSAGE_KEY); Tuple *icon_tuple = dict_find(iter, WEATHER_ICON_KEY); Tuple *temperature_tuple = dict_find(iter, WEATHER_TEMPERATURE_KEY); Tuple *city_tuple = dict_find(iter, WEATHER_CITY_KEY); Tuple *time_tuple = dict_find(iter, WEATHER_TIME_KEY); message_time = time(NULL); clock_copy_time_string(message_time_text,sizeof message_time_text); if (message_tuple) { strcpy(message,message_tuple->value->cstring); } else { return; } if (strcmp(message,"ready") == 0) { jsready = true; APP_LOG(APP_LOG_LEVEL_DEBUG, "RECEVIED ready message from PEBBLEJS"); request_weather(); } else if (strcmp(message,"weather") == 0) { stale = false; bitmap_layer_set_bitmap(notify_layer, icon_waiting); weather_icon = icon_tuple->value->uint8; weather_temperature = temperature_tuple->value->int8; strcpy(weather_city,city_tuple->value->cstring); weather_time = time_tuple->value->uint32; struct tm *tmpvar = localtime(&weather_time); if( clock_is_24h_style() ) { strftime(weather_time_text, sizeof(weather_time_text), "%H:%M", tmpvar); } else { strftime(weather_time_text, sizeof(weather_time_text), "%I:%M", tmpvar); } APP_LOG(APP_LOG_LEVEL_DEBUG, "%s ICON: %d, TEMPERATURE: %d, CITY: %s, TIME: %s", message_time_text, weather_icon, weather_temperature, weather_city, weather_time_text ); update_weather_display(); } else if (strcmp(message,"error") == 0) { stale = true; bitmap_layer_set_bitmap(notify_layer, icon_error); strcpy(weather_city, dict_find(iter, WEATHER_ERROR_KEY)->value->cstring); update_weather_display(); APP_LOG(APP_LOG_LEVEL_DEBUG, "WEATHER REQUEST FAILED!"); } }
/** * Wait for an official 'ready' from javascript or MAX_JS_READY_WAIT, whichever happens sooner */ void initial_jsready_callback() { initial_request = false; if (initial_jsready_timer) { app_timer_cancel(initial_jsready_timer); } request_weather(weather_data); }
static void handle_minute_tick(struct tm* tick_time, TimeUnits units_changed) { static char time_text[] = "00:00"; strftime(time_text, sizeof(time_text), "%T", tick_time); text_layer_set_text(time_layer, time_text); static char date_text[] = "XXX, XXX 00"; strftime(date_text, sizeof(date_text), "%a, %b %d", tick_time); text_layer_set_text(date_layer, date_text); if (tick_time->tm_min % 15 == 0) request_weather(); }
void app_received_msg(DictionaryIterator* received, void* context) { link_monitor_handle_success(&data); if(read_state_data(received, &data)) { //display_counters(&calls_layer, data, 1); //display_counters(&sms_layer, data, 2); if(!located) { request_weather(); } } }
static void appmsg_out_failed(DictionaryIterator *failed, AppMessageResult reason, void *context) { WeatherData *weather_data = (WeatherData*) context; APP_LOG(APP_LOG_LEVEL_DEBUG, "Out failed: %s", translate_error(reason)); retry_count++; switch (reason) { case APP_MSG_NOT_CONNECTED: weather_data->error = WEATHER_E_DISCONNECTED; request_weather(weather_data); break; case APP_MSG_SEND_REJECTED: case APP_MSG_SEND_TIMEOUT: default: weather_data->error = WEATHER_E_PHONE; request_weather(weather_data); break; } }
static void update_time() { // Get a tm structure time_t temp = time(NULL); struct tm *tick_time = localtime(&temp); if (tick_time->tm_min == 00) { vibes_short_pulse(); light_enable_interaction(); } if (tick_time->tm_min == 00 || tick_time->tm_min == 30) { request_weather(); } // Create a long-lived buffer static char hour_buffer[] = "00"; static char min_buffer[] = "00"; static char am_buffer[] = "00"; strftime(date_buffer, sizeof(date_buffer), " %a \n %b \n %e", tick_time); // Write the current hours and minutes into the buffer if(clock_is_24h_style() == true) { // Use 24 hour format strftime(hour_buffer, sizeof("00"), "%l", tick_time); strftime(min_buffer, sizeof("00"), "%M", tick_time); //"%H:%M", tick_time); strftime(am_buffer, sizeof("00"), "%p", tick_time); } else { // Use 12 hour format strftime(hour_buffer, sizeof("00"), "%l", tick_time); strftime(min_buffer, sizeof("00"), "%M", tick_time); strftime(am_buffer, sizeof("00"), "%p", tick_time); } // Display this time on the TextLayer //text_layer_set_text(s_time_layer, buffer); text_layer_set_text(hour_layer, hour_buffer); text_layer_set_text(min_layer, min_buffer); text_layer_set_text(date_layer, date_buffer); text_layer_set_text(am_layer, am_buffer); handle_battery(battery_state_service_peek()); }
void bt_handler(bool connected) { if (connected) { APP_LOG(APP_LOG_LEVEL_INFO, "Phone is connected!"); //bitmap_layer_set_bitmap(bt_layer, bt_bitmap); //bitmap_layer_set_background_color(bt_layer, GColorBlack); //bitmap_layer_destroy(no_phone_layer); layer_set_hidden(bitmap_layer_get_layer(no_phone_layer), true); layer_set_hidden(text_layer_get_layer(condition_layer), false); layer_set_hidden(text_layer_get_layer(temp_layer), false); layer_set_hidden(text_layer_get_layer(city_layer), false); request_weather(); } else { APP_LOG(APP_LOG_LEVEL_INFO, "Phone is not connected!"); //bitmap_layer_set_bitmap(bt_layer, blank_bitmap); //bitmap_layer_set_background_color(bt_layer, GColorYellow); //layer_add_child(window_get_root_layer(window), bitmap_layer_get_layer(no_phone_layer)); layer_set_hidden(bitmap_layer_get_layer(no_phone_layer), false); layer_set_hidden(text_layer_get_layer(condition_layer), true); layer_set_hidden(text_layer_get_layer(temp_layer), true); layer_set_hidden(text_layer_get_layer(city_layer), true); vibes_double_pulse(); //Tuplet initial_values[] = { //TupletInteger(WEATHER_ICON_KEY, (uint8_t) 5), //TupletCString(WEATHER_TEMPERATURE_KEY, " \u00B0F"), //TupletCString(WEATHER_CITY_KEY, "St Pebblesburg"), //}; //app_sync_init(&s_sync, s_sync_buffer, sizeof(s_sync_buffer), // initial_values, ARRAY_LENGTH(initial_values), //sync_tuple_changed_callback, sync_error_callback, NULL //); //request_weather(); update_time(); } }
static void handle_tick(struct tm *tick_time, TimeUnits units_changed) { if (units_changed & MINUTE_UNIT) { time_layer_update(); if (!initial_request) { debug_update_weather(weather_data); weather_layer_update(weather_data); } } if (units_changed & DAY_UNIT) { date_layer_update(tick_time); } /* * Useful for showing all icons using Wunder, subscribe to SECOND_UNIT tick service * weather_data->temperature = (tick_time->tm_sec + rand()%60) * (rand()%3 ? 1 : -1); weather_data->condition = tick_time->tm_sec; weather_data->updated = time(NULL); weather_data->hourly_enabled = true; weather_data->hourly_updated = time(NULL); weather_data->h1_cond = tick_time->tm_sec % 30; weather_data->h2_cond = tick_time->tm_sec % 30; weather_data->h1_time = time(NULL) + (tick_time->tm_sec * (rand()%3600)); weather_data->h2_time = time(NULL) + (tick_time->tm_sec * (rand()%3600)); weather_data->h1_temp = (tick_time->tm_sec + rand()%60) * (rand()%3 ? 1 : -1); weather_data->h2_temp = (tick_time->tm_sec + rand()%60) * (rand()%3 ? 1 : -1); weather_layer_update(weather_data); */ // Refresh the weather info every 30 mins, targeting 18 mins after the hour if ((units_changed & MINUTE_UNIT) && (tick_time->tm_min % 30 == 18) && !initial_request) { request_weather(weather_data); } }
void reconnect(void* context) { located = false; request_weather(); }
void reconnect(void* context) { request_weather(); }
static void main_window_load(Window *window) { //bg_color = GColorGreen; #define bg_color GColorBlack hour_layer = text_layer_create(GRect(-10,-15,94, 75)); min_layer = text_layer_create(GRect(66,60,85,85)); text_layer_set_text_color(hour_layer, COLOR_FALLBACK(GColorGreen, GColorWhite)); text_layer_set_text_color(min_layer, COLOR_FALLBACK(GColorGreen, GColorWhite)); text_layer_set_background_color(hour_layer, bg_color); text_layer_set_background_color(min_layer, bg_color); s_bg_layer = text_layer_create(GRect(0,0,144,168)); text_layer_set_background_color(s_bg_layer, COLOR_FALLBACK(GColorBlack, GColorBlack)); s_time_layer = text_layer_create(GRect(0,94,144,74));//0, 133, 115, 35)); am_layer = text_layer_create(GRect(125, 150, 19, 18)); battery_text_layer = text_layer_create(GRect(0, 150, 144, 20)); date_layer = text_layer_create(GRect(70 ,0, 74, 70)); s_battery_layer = text_layer_create(GRect(0, 160, 125, 20)); condition_layer = text_layer_create(GRect(0, 70, 70, 28)); //85 px tall temp_layer = text_layer_create(GRect(0, 90, 70, 28)); city_layer = text_layer_create(GRect(0, 112, 70, 28)); no_phone_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_NO_PHONE); no_phone_layer = bitmap_layer_create(GRect(0, 80, 60, 70)); bitmap_layer_set_bitmap(no_phone_layer, no_phone_bitmap); bitmap_layer_set_background_color(no_phone_layer, COLOR_FALLBACK(GColorCyan, GColorWhite)); layer_set_hidden(bitmap_layer_get_layer(no_phone_layer), true); bt_handler(bluetooth_connection_service_peek()); ///text_layer_set_text_color(s_battery_layer, COLOR_FALLBACK(GColorWhite, GColorWhite)); text_layer_set_background_color(s_time_layer, COLOR_FALLBACK(bg_color, GColorBlack)); text_layer_set_background_color(am_layer, COLOR_FALLBACK(GColorClear, GColorBlack)); text_layer_set_background_color(battery_text_layer, COLOR_FALLBACK(GColorClear, GColorClear)); //battery layer text_layer_set_background_color(s_battery_layer, COLOR_FALLBACK(GColorGreen, GColorWhite)); text_layer_set_background_color(condition_layer, COLOR_FALLBACK(GColorCyan, GColorWhite)); text_layer_set_background_color(temp_layer, COLOR_FALLBACK(GColorCyan, GColorWhite)); text_layer_set_background_color(city_layer, COLOR_FALLBACK(GColorCyan, GColorWhite)); text_layer_set_text_color(condition_layer, COLOR_FALLBACK(GColorBlack, GColorBlack)); text_layer_set_text_color(temp_layer, COLOR_FALLBACK(GColorBlack, GColorBlack)); text_layer_set_text_color(city_layer, COLOR_FALLBACK(GColorBlack, GColorBlack)); text_layer_set_text_color(battery_text_layer, COLOR_FALLBACK(GColorOrange, GColorWhite)); text_layer_set_background_color(date_layer, COLOR_FALLBACK(GColorOrange, GColorWhite)); text_layer_set_text_color(date_layer, COLOR_FALLBACK(GColorBlack, GColorBlack)); text_layer_set_text_color(am_layer, COLOR_FALLBACK(GColorRed, GColorWhite)); text_layer_set_text_color(s_time_layer, COLOR_FALLBACK(GColorGreen, GColorWhite)); text_layer_set_text_alignment(s_time_layer, GTextAlignmentCenter); text_layer_set_text_alignment(date_layer, GTextAlignmentCenter); text_layer_set_text_alignment(battery_text_layer, GTextAlignmentCenter); text_layer_set_text_alignment(condition_layer, GTextAlignmentCenter); text_layer_set_text_alignment(temp_layer, GTextAlignmentCenter); text_layer_set_text_alignment(city_layer, GTextAlignmentCenter); text_layer_set_text(s_time_layer, " : "); s_custom_font_24 = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_CHAMPAGNE_72)); s_custom_font_18 = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_CHAMPAGNE_20));//DS_DIGI_18)); s_custom_font_12 = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_CHAMPAGNE_12)); text_layer_set_font(s_time_layer, s_custom_font_24); //fonts_get_system_font(FONT_KEY_BITHAM_30_BLACK)); text_layer_set_font(date_layer, s_custom_font_18); text_layer_set_font(hour_layer, s_custom_font_24); text_layer_set_font(min_layer, s_custom_font_24); text_layer_set_font(condition_layer, s_custom_font_18); text_layer_set_font(temp_layer, s_custom_font_18); text_layer_set_font(city_layer, s_custom_font_12); layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_bg_layer)); //text_layer_set_font(s_battery_layer, s_custom_font_18); //layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_time_layer)); layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_battery_layer)); //layer_add_child(window_get_root_layer(window), text_layer_get_layer(am_layer)); layer_add_child(window_get_root_layer(window), text_layer_get_layer(hour_layer)); layer_add_child(window_get_root_layer(window), text_layer_get_layer(min_layer)); layer_add_child(window_get_root_layer(window), text_layer_get_layer(date_layer)); layer_add_child(window_get_root_layer(window), text_layer_get_layer(condition_layer)); layer_add_child(window_get_root_layer(window), text_layer_get_layer(temp_layer)); layer_add_child(window_get_root_layer(window), text_layer_get_layer(city_layer)); layer_add_child(window_get_root_layer(window), text_layer_get_layer(battery_text_layer)); layer_add_child(window_get_root_layer(window), bitmap_layer_get_layer(no_phone_layer)); Tuplet initial_values[] = { //TupletInteger(WEATHER_ICON_KEY, (uint8_t) 1), TupletCString(WEATHER_TEMPERATURE_KEY, ""), TupletCString(WEATHER_CITY_KEY, ""), TupletCString(WEATHER_CONDITION_KEY, "Loading") }; app_sync_init(&s_sync, s_sync_buffer, sizeof(s_sync_buffer), initial_values, ARRAY_LENGTH(initial_values), sync_tuple_changed_callback, sync_error_callback, NULL ); request_weather(); }
void failed(int32_t cookie, int http_status, void* context) { /* This is triggered by invalid responses from the bridge on the phone, * due to e.g. HTTP errors or phone disconnections. */ if(HTTP_INVALID_BRIDGE_RESPONSE) { // Phone can still be reached (assume HTTP error) if (http_time_request() == HTTP_OK) { /* Display 'cloud error' icon if: * - HTTP error is noticed upon inital load * - watch has recovered from a phone disconnection, but has no internet connection */ if (!has_temperature || phone_disconnected) { weather_layer_set_icon(&weather_layer, WEATHER_ICON_CLOUD_ERROR); phone_disconnected = false; } /* Assume that weather information is stale after 1 hour without a successful * weather request. Indicate this by removing the degree symbol. */ else if (has_timed_out || has_temperature || http_request_build_count > 0 || http_request_send_count > 0) { if (fail_count >= 60) { is_stale = true; weather_layer_set_temperature(&weather_layer, last_valid_temperature, is_stale); } } } else { /* Redundant check to make sure that HTTP time-outs are not triggering the * 'phone error' icon. If appearing to be timed out after 1 hour without a * successful weather request, indicate stale weather information by removing * the degree symbol. */ if (fail_count >= 60 && has_timed_out && !phone_disconnected) { is_stale = true; weather_layer_set_temperature(&weather_layer, last_valid_temperature, is_stale); } /* Display 'phone error' icon if: * - watch appears to be disconnected from phone * - watch appears to be disconnected from bridge app on phone * * In case this is triggered by a HTTP time-out, subsequently send a * weather request for a possible quick re-connection. */ else { if (http_status==1008) { phone_disconnected = true; weather_layer_set_icon(&weather_layer, WEATHER_ICON_PHONE_ERROR); link_monitor_handle_failure(http_status); http_location_request(); request_weather(); } } } } // Remove temperature text 30 minutes after a phone/bridge app disconnection if (fail_count >= 30 && phone_disconnected) { text_layer_set_text(weather_layer.temp_layer, " "); has_temperature = false; } // Indicate failure and activate fail counter (see handle_tick() function) has_failed = true; // Re-request the location and subsequently weather on next minute tick located = false; }