diff --git a/src/c/weather_date.c b/src/c/weather_date.c new file mode 100644 index 0000000..bc98011 --- /dev/null +++ b/src/c/weather_date.c @@ -0,0 +1,317 @@ +#include +#include "weather_date.h" +#include "constants.h" +#include "sliding_time_wd.h" + +#define DEBUG_DATE "Sun 02 Oct" + +extern TextLayer *weather_layer1, *weather_layer2, *weather_layer_center, *date_layer; +extern AppTimer *lohi_display_timer; +GFont g_weatherdate_font; + +extern Options s_options; + +//adds/configures weather/date display lines +void add_weatherdate_layers(Layer *window_layer, int16_t width) { + + int weather_Y_readability_offset = 0; + int date_Y_readability_offset = 0; + int chalk_weather1_Y_offset = 0; + #if defined(PBL_ROUND) + int chalk_weather_center_Y_offset = 0; + int chalk_weather2_Y_offset = 0; + #endif + int chalk_date_Y_offset = 0; + + #if defined(PBL_RECT) + chalk_weather1_Y_offset = 0; + chalk_date_Y_offset = 0; + #elif defined(PBL_ROUND) + chalk_weather1_Y_offset = DEFAULT_CHALK_WEATHER1_Y_OFFSET; + chalk_weather_center_Y_offset = DEFAULT_CHALK_WEATHER_CENTER_Y_OFFSET; + chalk_weather2_Y_offset = DEFAULT_CHALK_WEATHER2_Y_OFFSET; + chalk_date_Y_offset = DEFAULT_CHALK_DATE_Y_OFFSET; + #endif + + if (s_options.weatherdate_readability) { + weather_Y_readability_offset = DEFAULT_WEATHER_Y_OFFSET_READABILITY; + date_Y_readability_offset = DEFAULT_DATE_Y_OFFSET_READABILITY; + g_weatherdate_font = fonts_get_system_font(FONT_KEY_GOTHIC_24); + } + else { + weather_Y_readability_offset = 0; + date_Y_readability_offset = 0; + g_weatherdate_font = fonts_get_system_font(FONT_KEY_GOTHIC_18); + } + + //weather layer + weather_layer1 = text_layer_create(GRect(0, 0 - weather_Y_readability_offset + chalk_weather1_Y_offset, width, 28)); + init_static_row(weather_layer1, g_weatherdate_font); + layer_add_child(window_layer, text_layer_get_layer(weather_layer1)); + + //weather layer 2 and weather layer center used for Chalk only + #if defined(PBL_ROUND) + weather_layer2 = text_layer_create(GRect(0, 0 - weather_Y_readability_offset + chalk_weather2_Y_offset, width, 28)); + init_static_row(weather_layer2, g_weatherdate_font); + layer_add_child(window_layer, text_layer_get_layer(weather_layer2)); + + weather_layer_center = text_layer_create(GRect(0, 0 - weather_Y_readability_offset + chalk_weather_center_Y_offset, width, 28)); + init_static_row(weather_layer_center, g_weatherdate_font); + layer_add_child(window_layer, text_layer_get_layer(weather_layer_center)); + #endif + + //date layer + date_layer = text_layer_create(GRect(0, 145 - date_Y_readability_offset + chalk_date_Y_offset, width, 28)); + init_static_row(date_layer, g_weatherdate_font); + layer_add_child(window_layer, text_layer_get_layer(date_layer)); +} + +//checks/updates date display line +void update_date_layer() { + static char date_buffer[16]; + const char *current_date_layer; + + //if displaying date + if (s_options.display_date) { + + //get current date_layer text + current_date_layer = text_layer_get_text(date_layer); + + //get current date + time_t temp = time(NULL); + struct tm *tick_time = localtime(&temp); + strftime(date_buffer, sizeof(date_buffer), "%a %d %b", tick_time); + #if DEBUG + strftime(date_buffer, sizeof(date_buffer), DEBUG_DATE, tick_time); //for screen shots + #endif + + if (current_date_layer != date_buffer) { + text_layer_set_text(date_layer, date_buffer); + #if DEBUG + APP_LOG(APP_LOG_LEVEL_DEBUG, "update_date_layer: text_layer_set_text date_layer: %s", date_buffer); + #endif + } + } + else { + text_layer_set_text(date_layer, ""); + } +} + +//checks updates weather display lines +void update_weather_layer() { + static char weather1_layer_buffer[32]; + #if defined(PBL_ROUND) + static char weather2_layer_buffer[32]; + static char weather_center_layer_buffer[32]; + #endif + + //check if need to convert options (if too long) + convert_conditions(s_options.condition_code); + + if (s_options.use_celsius){ + #if defined(PBL_RECT) + snprintf(weather1_layer_buffer, sizeof(weather1_layer_buffer), "%dC - %s", s_options.tempC, s_options.conditions); + #elif defined(PBL_ROUND) + memset(weather1_layer_buffer, 0,sizeof(weather1_layer_buffer)); + snprintf(weather_center_layer_buffer, sizeof(weather_center_layer_buffer), "%dC - %s", s_options.tempC, s_options.conditions); + memset(weather2_layer_buffer, 0,sizeof(weather2_layer_buffer)); + if (strlen(s_options.conditions) > MAX_CHALK_SINGLE_LINE_CONDITIONS_LEN) { + snprintf(weather1_layer_buffer, sizeof(weather1_layer_buffer), "%dC", s_options.tempC); + memset(weather_center_layer_buffer, 0,sizeof(weather_center_layer_buffer)); + snprintf(weather2_layer_buffer, sizeof(weather2_layer_buffer), "%s", s_options.conditions); + } + #endif + } + else { + #if defined(PBL_RECT) + snprintf(weather1_layer_buffer, sizeof(weather1_layer_buffer), "%dF - %s", s_options.tempF, s_options.conditions); + #elif defined(PBL_ROUND) + memset(weather1_layer_buffer, 0,sizeof(weather1_layer_buffer)); + snprintf(weather_center_layer_buffer, sizeof(weather_center_layer_buffer), "%dF - %s", s_options.tempF, s_options.conditions); + memset(weather2_layer_buffer, 0,sizeof(weather2_layer_buffer)); + if (strlen(s_options.conditions) > MAX_CHALK_SINGLE_LINE_CONDITIONS_LEN) { + snprintf(weather1_layer_buffer, sizeof(weather1_layer_buffer), "%dF", s_options.tempF); + memset(weather_center_layer_buffer, 0,sizeof(weather_center_layer_buffer)); + snprintf(weather2_layer_buffer, sizeof(weather2_layer_buffer), "%s", s_options.conditions); + } + #endif + } + + //write weather text row + if (strlen(s_options.conditions) != 0) { + #if defined(PBL_RECT) + text_layer_set_text(weather_layer1, weather1_layer_buffer); + #elif defined(PBL_ROUND) + text_layer_set_text(weather_layer1, weather1_layer_buffer); + text_layer_set_text(weather_layer_center, weather_center_layer_buffer); + text_layer_set_text(weather_layer2, weather2_layer_buffer); + #endif + #if DEBUG + APP_LOG(APP_LOG_LEVEL_DEBUG, "update_weather_layer: Successful weather row information written at %s. ", s_options.last_weather_update24hr); + #endif + + } + else { //empty temp & conditions + #if defined(PBL_RECT) + text_layer_set_text(weather_layer1, DEFAULT_ERROR_WEATHER_UPDATE); + #elif defined(PBL_ROUND) + text_layer_set_text(weather_layer1, ""); + text_layer_set_text(weather_layer_center, DEFAULT_ERROR_WEATHER_UPDATE); + text_layer_set_text(weather_layer2, ""); + #endif + #if DEBUG + APP_LOG(APP_LOG_LEVEL_DEBUG, "update_weather_layer: Error displaying weather %s. ", s_options.last_weather_update24hr); + #endif + } +} + +void handle_timer(void *data) { + update_weather_layer(); + update_date_layer(); +} + +//temporarily sets and displays Lo/Hi temp and last updates info on weather/date lines +void display_lohi_weather_info() { + static char weather1_layer_buffer[32]; + #if defined(PBL_ROUND) + static char weather2_layer_buffer[32]; + static char weather_center_layer_buffer[32]; + #endif + + if (s_options.use_celsius){ + #if defined(PBL_RECT) + snprintf(weather1_layer_buffer, sizeof(weather1_layer_buffer), "Lo %dC - Hi %dC", s_options.tempCLo, s_options.tempCHi); + #elif defined(PBL_ROUND) + memset(weather1_layer_buffer, 0,sizeof(weather1_layer_buffer)); + snprintf(weather_center_layer_buffer, sizeof(weather_center_layer_buffer), "Lo %dC - Hi %dC", s_options.tempCLo, s_options.tempCHi); + memset(weather2_layer_buffer, 0,sizeof(weather2_layer_buffer)); + #endif + } + else { + #if defined(PBL_RECT) + snprintf(weather1_layer_buffer, sizeof(weather1_layer_buffer), "Lo %dF - Hi %dF", s_options.tempFLo, s_options.tempFHi); + #elif defined(PBL_ROUND) + memset(weather1_layer_buffer, 0,sizeof(weather1_layer_buffer)); + snprintf(weather_center_layer_buffer, sizeof(weather_center_layer_buffer), "Lo %dF - Hi %dF", s_options.tempFLo, s_options.tempFHi); + memset(weather2_layer_buffer, 0,sizeof(weather2_layer_buffer)); + #endif + } + + //write weather text row + if (strlen(s_options.conditions) != 0) { + if (clock_is_24h_style()) { + text_layer_set_text(date_layer, s_options.last_weather_update24hr); + } + else { + text_layer_set_text(date_layer, s_options.last_weather_update12hr); + } + #if defined(PBL_RECT) + text_layer_set_text(weather_layer1, weather1_layer_buffer); + #elif defined(PBL_ROUND) + text_layer_set_text(weather_layer1, weather1_layer_buffer); + text_layer_set_text(weather_layer_center, weather_center_layer_buffer); + text_layer_set_text(weather_layer2, weather2_layer_buffer); + #endif + } + else { //empty temp & conditions + text_layer_set_text(date_layer, s_options.last_weather_update12hr); + text_layer_set_text(date_layer, s_options.last_weather_update24hr); + #if defined(PBL_RECT) + text_layer_set_text(weather_layer1, DEFAULT_ERROR_WEATHER_UPDATE); + #elif defined(PBL_ROUND) + text_layer_set_text(weather_layer1, ""); + text_layer_set_text(weather_layer_center, DEFAULT_ERROR_WEATHER_UPDATE); + text_layer_set_text(weather_layer2, ""); + #endif + } + + lohi_display_timer = app_timer_register(DEFAULT_DISPLAY_LOHI_TIMER, handle_timer, NULL); + +} + +//check if need to convert weather condition codes (too long) +void convert_conditions(int conditionCode) { + + switch(conditionCode) { + case 0: // tornado + case 1: // tropical storm + case 2: // hurricane + case 4: // thunderstorms + case 8: //freezing drizzle + case 9: //drizzle + case 10: //freezing rain + case 11: //showers + case 12: //showers + case 13: //snow flurries + case 15: //blowing snow + case 16: //snow + case 17: //hail + case 18: //sleet + case 19: //dust + case 20: //foggy + case 21: //haze + case 22: //smoky + case 23: //blustery + case 24: //windy + case 25: //cold + case 26: //cloudy + case 32: //sunny + case 36: //hot + case 40: //scattered showers + case 41: //heavy snow + case 43: //heavy snow + case 44: //partly cloudy + case 45: //thundershowers + case 46: //snow showers + //no need to convert, do nothing + break; + case 3: // severe thunderstorms + case 37: //isolated thunderstorms + case 38: //scattered thunderstorms + case 39: //scattered thunderstorms + snprintf(s_options.conditions, sizeof(s_options.conditions), "Thunderstorms"); + break; + case 5: //mixed rain and snow + snprintf(s_options.conditions, sizeof(s_options.conditions), "Rain and Snow"); + break; + case 6: //mixed rain and sleet + snprintf(s_options.conditions, sizeof(s_options.conditions), "Rain and Sleet"); + break; + case 7: //mixed snow and sleet + snprintf(s_options.conditions, sizeof(s_options.conditions), "Snow and Sleet"); + break; + case 14: //light snow showers + snprintf(s_options.conditions, sizeof(s_options.conditions), "Snow Showers"); + break; + case 27: //mostly cloudy (night) + case 28: //mostly cloudy (day) + snprintf(s_options.conditions, sizeof(s_options.conditions), "Mostly Cloudy"); + break; + case 29: //partly cloudy (night) + case 30: //partly cloudy (day) + snprintf(s_options.conditions, sizeof(s_options.conditions), "Partly Cloudy"); + break; + case 31: //clear (night) + snprintf(s_options.conditions, sizeof(s_options.conditions), "Clear"); + break; + case 33: //fair (night) + case 34: //fair (day) + snprintf(s_options.conditions, sizeof(s_options.conditions), "Fair"); + break; + case 35: //mixed rain and hail + snprintf(s_options.conditions, sizeof(s_options.conditions), "Rain and Hail"); + break; + case 42: //scattered snow showers + snprintf(s_options.conditions, sizeof(s_options.conditions), "Snow Showers"); + break; + case 47: //isolated thundershowers + snprintf(s_options.conditions, sizeof(s_options.conditions), "Thundershowers"); + break; + case 3200: //Unknown + snprintf(s_options.conditions, sizeof(s_options.conditions), " ..... "); + break; + default: //invalid condition code, clear conditions + memset(s_options.conditions, 0,sizeof(s_options.conditions)); + break; + } +} \ No newline at end of file diff --git a/src/c/weather_date.h b/src/c/weather_date.h new file mode 100644 index 0000000..eaa28bf --- /dev/null +++ b/src/c/weather_date.h @@ -0,0 +1,9 @@ +#pragma once + + void add_weatherdate_layers(Layer *window_layer, int16_t width); //adds/configures weather/date display lines + void update_date_layer(); //checks/updates date display line + void update_weather_layer(); //checks updates weather display lines + void display_lohi_weather_info(); //temporarily sets and displays Lo/Hi temp and last updates info on weather/date lines + void handle_timer(void *data); //sets weather/date lines back to weather/date info after timer expires + void convert_conditions(int conditionCode); //check if need to convert weather condition codes (too long) +