From bc3ab1742b125a5d5e25f2be2e729aee6b7f92e9 Mon Sep 17 00:00:00 2001 From: Jared Biehler Date: Mon, 15 Feb 2016 17:54:35 -0500 Subject: [PATCH] Yahoo has been replaced with Weather Underground for current conditions. --- README.md | 8 +- appinfo.json | 9 +- src/config.h | 4 +- src/js/pebble-js-app.js | 271 +++++++++++++++++++++++++++++----------- src/main.c | 4 +- src/network.c | 4 +- src/network.h | 2 +- src/weather_layer.c | 136 +++----------------- src/weather_layer.h | 1 - wscript | 25 +++- 10 files changed, 257 insertions(+), 207 deletions(-) diff --git a/README.md b/README.md index 7b432b8..35ac860 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ Weather My Way (Pebble SDK 2.0) This is my attempt at learning about the Pebble SDK by adjusting an app for my own needs. The original Futura Weather watchface was the cleanest and best looking design I had seen but I prefer YAHOO! Weather data. So, I added the option to switch between both, and added hourly data from Weather Underground. +* Update - as of 2016, Yahoo has decided to charge for API access when attempting to translate lat lon to woeid and therefor I have replaced their API with Weather Underground. + Give it a shot and let me know what you think: [download pbw here](https://github.com/jaredbiehler/weather-my-way/releases/) ![pebble screen1](https://raw.githubusercontent.com/jaredbiehler/weather-my-way/master/screenshots/pebble-screenshot1.png)  @@ -22,7 +24,7 @@ The hourly data for this app comes from the [Weather Underground API](http://www Query string variables: ``` -s=[yahoo|open] // weather service +s=[wunder|open] // weather service u=[F|C] // weather scale d=[true|false] // debug enabled b=[on|off] // battery enabled @@ -33,8 +35,8 @@ a=[apikey] // Weather Underground API Key ## Progress - Hourly weather! - - Configurable weather provider (YAHOO!, Open Weather map) - - More granularity in weather condition expression (via YAHOO!) + - Configurable weather provider (Weather Underground, Open Weather map) + - More granularity in weather condition expression - Configurable minimal battery display - Configurable weather scale (°F / °C) - Configurable debug mode ((L)ast updated, (P)ublish Date, Neighborhood) diff --git a/appinfo.json b/appinfo.json index f079536..d883fcf 100644 --- a/appinfo.json +++ b/appinfo.json @@ -3,12 +3,17 @@ "shortName": "Weather My Way", "longName": "Weather My Way", "companyName": "Jared Biehler", - "versionCode": 7, - "versionLabel": "1.2", + "versionCode": 8, + "versionLabel": "1.3", "capabilities": [ "configurable", "location" ], "watchapp": { "watchface": true }, + "sdkVersion": "3", + "targetPlatforms": [ + "aplite", + "basalt" + ], "appKeys": { "temperature": 0, "condition": 1, diff --git a/src/config.h b/src/config.h index a463dfb..d1e3b4b 100644 --- a/src/config.h +++ b/src/config.h @@ -1,7 +1,7 @@ // Persisted Values #define DEFAULT_WEATHER_SCALE "F" // F Fahrenheit or C Celsius -#define DEFAULT_DEBUG_MODE false -#define DEFAULT_WEATHER_SERVICE "yahoo" +#define DEFAULT_DEBUG_MODE true +#define DEFAULT_WEATHER_SERVICE "wunder" #define DEFAULT_DISPLAY_BATTERY true #define KEY_DEBUG_MODE 0 diff --git a/src/js/pebble-js-app.js b/src/js/pebble-js-app.js index 043346d..0204ab7 100644 --- a/src/js/pebble-js-app.js +++ b/src/js/pebble-js-app.js @@ -1,24 +1,25 @@ -var SERVICE_OPEN_WEATHER = "open"; -var SERVICE_YAHOO_WEATHER = "yahoo"; -var EXTERNAL_DEBUG_URL = ''; -var CONFIGURATION_URL = 'http://jaredbiehler.github.io/weather-my-way/config/'; +var SERVICE_OPEN_WEATHER = "open"; +var SERVICE_WUNDER_WEATHER = "wunder"; +var EXTERNAL_DEBUG_URL = ''; +var CONFIGURATION_URL = 'http://jaredbiehler.github.io/weather-my-way/config/'; var Global = { - externalDebug: false, // POST logs to external server - dangerous! lat lon recorded - wuApiKey: null, // register for a free api key! - hourlyIndex1: 2, // 3 Hours from now - hourlyIndex2: 8, // 9 hours from now - updateInProgress: false, - updateWaitTimeout: 1 * 60 * 1000, // one minute in ms - lastUpdateAttempt: new Date(), - maxRetry: 3, - retryWait: 500, // ms - config: { - debugEnabled: false, - batteryEnabled: true, - weatherService: SERVICE_YAHOO_WEATHER, - weatherScale: 'F' - }, + externalDebug: false, // POST logs to external server - dangerous! lat lon recorded + wuApiKey: null, // register for a free api key! + openWeatherApiKey: 'ecbc09f26372154da892444daf8fba4a', + hourlyIndex1: 2, // 3 Hours from now + hourlyIndex2: 8, // 9 hours from now + updateInProgress: false, + updateWaitTimeout: 1 * 60 * 1000, // one minute in ms + lastUpdateAttempt: new Date(), + maxRetry: 3, + retryWait: 500, // ms + config: { + debugEnabled: true, + batteryEnabled: true, + weatherService: SERVICE_WUNDER_WEATHER, + weatherScale: 'F' + } }; // Allow console messages to be turned on / off @@ -51,7 +52,7 @@ Pebble.addEventListener("ready", function(e) { Pebble.addEventListener("appmessage", function(data) { console.log("Got a message - Starting weather request ... " + JSON.stringify(data)); try { - Global.config.weatherService = data.payload.service === SERVICE_OPEN_WEATHER ? SERVICE_OPEN_WEATHER : SERVICE_YAHOO_WEATHER; + Global.config.weatherService = data.payload.service === SERVICE_OPEN_WEATHER ? SERVICE_OPEN_WEATHER : SERVICE_WUNDER_WEATHER; Global.config.debugEnabled = data.payload.debug === 1; Global.config.batteryEnabled = data.payload.battery === 1; Global.config.weatherScale = data.payload.scale === 'C' ? 'C' : 'F'; @@ -73,7 +74,7 @@ Pebble.addEventListener("showConfiguration", function (e) { 'u': Global.config.weatherScale, 'b': Global.config.batteryEnabled ? 'on' : 'off', 'a': Global.wuApiKey - } + }; var url = CONFIGURATION_URL+'?'+serialize(options); console.log('Configuration requested using url: '+url); Pebble.openURL(url); @@ -98,7 +99,7 @@ Pebble.addEventListener("webviewclosed", function(e) { settings.scale !== Global.config.weatherScale || settings.wuApiKey !== Global.wuApiKey); - Global.config.weatherService = settings.service === SERVICE_OPEN_WEATHER ? SERVICE_OPEN_WEATHER : SERVICE_YAHOO_WEATHER; + Global.config.weatherService = settings.service === SERVICE_OPEN_WEATHER ? SERVICE_OPEN_WEATHER : SERVICE_WUNDER_WEATHER; Global.config.weatherScale = settings.scale === 'C' ? 'C' : 'F'; Global.config.debugEnabled = settings.debug === 'true'; Global.config.batteryEnabled = settings.battery === 'on'; @@ -146,7 +147,7 @@ var nack = function (data, retry) { }); }, Global.retryWait + Math.floor(Math.random() * Global.retryWait)); } -} +}; var updateWeather = function () { if (Global.updateInProgress && @@ -159,7 +160,7 @@ var updateWeather = function () { var locationOptions = { "timeout": 15000, "maximumAge": 60000 }; navigator.geolocation.getCurrentPosition(locationSuccess, locationError, locationOptions); -} +}; var locationSuccess = function (pos) { var coordinates = pos.coords; @@ -167,10 +168,10 @@ var locationSuccess = function (pos) { if (Global.config.weatherService === SERVICE_OPEN_WEATHER) { fetchOpenWeather(coordinates.latitude, coordinates.longitude); } else { - fetchYahooWeather(coordinates.latitude, coordinates.longitude); + fetchWunderWeatherCurrent(coordinates.latitude, coordinates.longitude); } if (Global.wuApiKey !== null) { - fetchWunderWeather(coordinates.latitude, coordinates.longitude); + fetchWunderWeatherHourly(coordinates.latitude, coordinates.longitude); } else { var data = {hourly_enabled: 0}; console.log("Hourly disabled, no WU ApiKey"); @@ -178,7 +179,7 @@ var locationSuccess = function (pos) { nack(data); }); } -} +}; var locationError = function (err) { var message = 'Location error (' + err.code + '): ' + err.message; @@ -186,50 +187,12 @@ var locationError = function (err) { Pebble.sendAppMessage({ "error": "Loc unavailable" }, ack, nack); postDebugMessage({"error": message}); Global.updateInProgress = false; -} - -var fetchYahooWeather = function(latitude, longitude) { - - var subselect, neighbor, query, multi - , options = {}; - - subselect = 'SELECT woeid FROM geo.placefinder WHERE text="'+latitude+','+longitude+'" AND gflags="R"'; - neighbor = 'SELECT * FROM geo.placefinder WHERE text="'+latitude+','+longitude+'" AND gflags="R";'; - query = 'SELECT * FROM weather.forecast WHERE woeid IN ('+subselect+') AND u="'+Global.config.weatherScale.toLowerCase()+'";'; - multi = "SELECT * FROM yql.query.multi WHERE queries='"+query+" "+neighbor+"'"; - options.url = "https://query.yahooapis.com/v1/public/yql?format=json&q="+encodeURIComponent(multi)+"&nocache="+new Date().getTime(); - - options.parse = function(response) { - var sunrise, sunset, pubdate, locale; - sunrise = response.query.results.results[0].channel.astronomy.sunrise; - sunset = response.query.results.results[0].channel.astronomy.sunset; - pubdate = new Date(Date.parse(response.query.results.results[0].channel.item.pubDate)); - locale = response.query.results.results[1].Result.neighborhood; - if (locale === null) { - locale = response.query.results.results[1].Result.city; - } - if (locale === null) { - locale = 'unknown'; - } - - return { - condition: parseInt(response.query.results.results[0].channel.item.condition.code), - temperature: parseInt(response.query.results.results[0].channel.item.condition.temp), - sunrise: Date.parse(new Date().toDateString()+" "+sunrise) / 1000, - sunset: Date.parse(new Date().toDateString()+" "+sunset) / 1000, - locale: locale, - pubdate: pubdate.getHours()+':'+('0'+pubdate.getMinutes()).slice(-2), - tzoffset: new Date().getTimezoneOffset() * 60 - }; - }; - - fetchWeather(options); }; var fetchOpenWeather = function(latitude, longitude) { var options = {}; - options.url = "http://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&cnt=1"; + options.url = "http://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&cnt=1&appid=" + Global.openWeatherApiKey; options.parse = function(response) { var temperature, sunrise, sunset, condition, pubdate; @@ -247,7 +210,7 @@ var fetchOpenWeather = function(latitude, longitude) { condition = response.weather[0].id; sunrise = response.sys.sunrise; sunset = response.sys.sunset; - pubdate = new Date(response.dt*1000); + pubdate = new Date(response.dt * 1000); return { condition: condition, @@ -256,13 +219,67 @@ var fetchOpenWeather = function(latitude, longitude) { sunset: sunset, locale: response.name, pubdate: pubdate.getHours()+':'+('0'+pubdate.getMinutes()).slice(-2), - tzoffset: new Date().getTimezoneOffset() * 60 + tzoffset: 0 // new Date().getTimezoneOffset() * 60 }; }; fetchWeather(options); }; -var fetchWunderWeather = function(latitude, longitude) { +var fetchWunderWeatherCurrent = function (latitude, longitude) { + + var options = {}; + options.url = 'http://api.wunderground.com/api/' + Global.wuApiKey + + '/conditions/astronomy/q/'+latitude+','+longitude+'.json'; + + /* + options.parse = function(response) { + var sunrise, sunset, pubdate, locale; + sunrise = response.query.results.results[0].channel.astronomy.sunrise; + sunset = response.query.results.results[0].channel.astronomy.sunset; + pubdate = new Date(Date.parse(response.query.results.results[0].channel.item.pubDate)); + locale = response.query.results.results[1].Result.neighborhood; + + if (locale === null) { + locale = response.query.results.results[1].Result.city; + } + if (locale === null) { + locale = 'unknown'; + } + + return { + condition: parseInt(response.query.results.results[0].channel.item.condition.code), + temperature: parseInt(response.query.results.results[0].channel.item.condition.temp), + sunrise: Date.parse(new Date().toDateString()+" "+sunrise) / 1000, + sunset: Date.parse(new Date().toDateString()+" "+sunset) / 1000, + locale: locale, + pubdate: pubdate.getHours()+':'+('0'+pubdate.getMinutes()).slice(-2), + tzoffset: new Date().getTimezoneOffset() * 60 + }; + */ + + options.parse = function(response) { + + var co = response.current_observation; + var pubdate = new Date(co.observation_epoch * 1000); + + var sp = response.sun_phase; + var sunrise = sp.sunrise.hour + ":" + sp.sunrise.minute; // 6:59 + var sunset = sp.sunset.hour + ":" + sp.sunset.minute; // 17:30 + + return { + condition: translateConditionToFCTCode(co.weather), + temperature: Global.config.weatherScale === 'C' ? Math.round(co.temp_c) : Math.round(co.temp_f), + sunrise: Date.parse(new Date().toDateString()+" "+sunrise) / 1000, + sunset: Date.parse(new Date().toDateString()+" "+sunset) / 1000, + locale: co.observation_location.city, + pubdate: pubdate.getHours()+':'+('0'+pubdate.getMinutes()).slice(-2), + tzoffset: 0 // new Date().getTimezoneOffset() * 60 + }; + }; + fetchWeather(options); +}; + +var fetchWunderWeatherHourly = function(latitude, longitude) { var options = {}; options.url = 'http://api.wunderground.com/api/'+Global.wuApiKey+'/hourly/q/'+latitude+','+longitude+'.json'; @@ -273,11 +290,11 @@ var fetchWunderWeather = function(latitude, longitude) { , h2 = response.hourly_forecast[Global.hourlyIndex2]; return { - h1_temp: Global.config.weatherScale === 'C' ? parseInt(h1.temp.metric) : parseInt(h1.temp.english), + h1_temp: Global.config.weatherScale === 'C' ? Math.round(h1.temp.metric) : Math.round(h1.temp.english), h1_cond: parseInt(h1.fctcode), h1_time: parseInt(h1.FCTTIME.epoch), h1_pop: parseInt(h1.pop), - h2_temp: Global.config.weatherScale === 'C' ? parseInt(h2.temp.metric) : parseInt(h2.temp.english), + h2_temp: Global.config.weatherScale === 'C' ? Math.round(h2.temp.metric) : Math.round(h2.temp.english), h2_cond: parseInt(h2.fctcode), h2_time: parseInt(h2.FCTTIME.epoch), h2_pop: parseInt(h2.pop) @@ -289,7 +306,7 @@ var fetchWunderWeather = function(latitude, longitude) { var fetchWeather = function(options) { - //console.log('URL: ' + options.url); + console.log('URL: ' + options.url); getJson(options.url, function(err, response) { @@ -370,4 +387,112 @@ var serialize = function(obj) { str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); } return str.join("&"); -} \ No newline at end of file +}; + +var translateConditionToFCTCode = function (condition) { + var fctCode = 50; + + condition = condition.toLowerCase(); + var isHeavy = condition.indexOf('heavy') >= 0; + var isLight = condition.indexOf('light') >= 0; + condition = condition.replace('heavy ', ''); + condition = condition.replace('light ', ''); + + switch(condition) { + case 'clear': + fctCode = 1; + break; + case 'partly cloudy': + fctCode = 2; + break; + case 'mostly cloudy': + case 'scattered clouds': + fctCode = 3; + break; + case 'overcast': + fctCode = 4; + break; + case 'mist': + case 'fog': + case 'fog patches': + case 'smoke': + case 'haze': + case 'freezing fog': + case 'patches of fog': + case 'shallow fog': + case 'partial fog': + fctCode = 6; + break; + case 'drizzle': + case 'rain mist': + fctCode = 10; + break; + case 'rain': + case 'rain showers': + case 'unknown precipitation': + fctCode = 13; + break; + case 'thunderstorm': + case 'thunderstorms and rain': + case 'thunderstorms and snow': + case 'thunderstorms and ice pellets': + case 'thunderstorms with hail': + case 'thunderstorms with small hail': + case 'squalls': + case 'funnel cloud': + fctCode = 15; + break; + case 'ice crystals': + case 'ice pellets': + fctCode = 18; + break; + case 'snow': + case 'snow grains': + case 'low drifting snow': + case 'snow showers': + case 'snow blowing snow mist': + fctCode = 21; + break; + case 'hail': + case 'hail showers': + case 'small hail': + fctCode = 23; + break; + case 'volcanic ash': + case 'widespread dust': + case 'sand': + case 'spray': + case 'dust whirls': + case 'sandstorm': + case 'low drifting widespread dust': + case 'low drifting sand': + case 'blowing widespread dust': + case 'blowing sand': + fctCode = 30; + break; + case 'freezing drizzle': + case 'freezing rain': + case 'ice pellet showers': + case 'small hail showers': + fctCode = 31; + break; + case 'blowing snow': + fctCode = 33; + break; + case 'unknown': + default: + fctCode = 50; + break; + } + + // Respect modifiers if they exist where possible + if (fctCode === 13) { + fctCode = isLight ? 10 : fctCode; + } + + if (fctCode === 21) { + fctCode = isHeavy ? 33 : fctCode; + } + + return fctCode; +}; diff --git a/src/main.c b/src/main.c index 3236983..e4e46d1 100644 --- a/src/main.c +++ b/src/main.c @@ -40,7 +40,7 @@ static void handle_tick(struct tm *tick_time, TimeUnits units_changed) } /* - * Useful for showing all icons using Yahoo, subscribe to SECOND_UNIT tick service + * 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; @@ -56,7 +56,7 @@ static void handle_tick(struct tm *tick_time, TimeUnits units_changed) weather_layer_update(weather_data); */ - // Refresh the weather info every 30 mins, targeting 18 mins after the hour (Yahoo updates around then) + // 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) { diff --git a/src/network.c b/src/network.c index 76058ef..e821b17 100644 --- a/src/network.c +++ b/src/network.c @@ -18,7 +18,7 @@ static void appmsg_in_received(DictionaryIterator *received, void *context) { Tuple *error_tuple = dict_find(received, KEY_ERROR); Tuple *js_ready_tuple = dict_find(received, KEY_JS_READY); - // Current Weather (Via Yahoo, Open Weather Map) + // Current Weather (Via Weather Underground, Open Weather Map) Tuple *temperature_tuple = dict_find(received, KEY_TEMPERATURE); Tuple *condition_tuple = dict_find(received, KEY_CONDITION); Tuple *sunrise_tuple = dict_find(received, KEY_SUNRISE); @@ -68,7 +68,7 @@ static void appmsg_in_received(DictionaryIterator *received, void *context) { } // Configuration Update else if (service_tuple) { - char* service = strcmp(service_tuple->value->cstring, SERVICE_OPEN_WEATHER) == 0 ? SERVICE_OPEN_WEATHER : SERVICE_YAHOO_WEATHER; + char* service = strcmp(service_tuple->value->cstring, SERVICE_OPEN_WEATHER) == 0 ? SERVICE_OPEN_WEATHER : SERVICE_WUNDER_WEATHER; char* scale = strcmp(scale_tuple->value->cstring, SCALE_CELSIUS) == 0 ? SCALE_CELSIUS : SCALE_FAHRENHEIT; strncpy(weather->service, service, 6); strncpy(weather->scale, scale, 2); diff --git a/src/network.h b/src/network.h index b3a3a4d..8fc5a8e 100644 --- a/src/network.h +++ b/src/network.h @@ -24,7 +24,7 @@ #define KEY_HOURLY_ENABLED 21 #define SERVICE_OPEN_WEATHER "open" -#define SERVICE_YAHOO_WEATHER "yahoo" +#define SERVICE_WUNDER_WEATHER "wunder" #define SCALE_FAHRENHEIT "F" #define SCALE_CELSIUS "C" diff --git a/src/weather_layer.c b/src/weather_layer.c index b517cec..a8092c0 100644 --- a/src/weather_layer.c +++ b/src/weather_layer.c @@ -284,7 +284,7 @@ void weather_layer_update(WeatherData *weather_data) if (strcmp(weather_data->service, SERVICE_OPEN_WEATHER) == 0) { weather_layer_set_icon(open_weather_icon_for_condition(weather_data->condition, night_time), AREA_PRIMARY); } else { - weather_layer_set_icon(yahoo_weather_icon_for_condition(weather_data->condition, night_time), AREA_PRIMARY); + weather_layer_set_icon(wunder_weather_icon_for_condition(weather_data->condition, night_time), AREA_PRIMARY); } if (weather_data->hourly_updated != 0 && weather_data->hourly_enabled) { @@ -477,126 +477,12 @@ uint8_t open_weather_icon_for_condition(int c, bool night_time) } } -/* - * Converts the Yahoo API Weather Condition into one of our icons. - * Refer to: https://developer.yahoo.com/weather/#codes - */ -uint8_t yahoo_weather_icon_for_condition(int c, bool night_time) -{ - //APP_LOG(APP_LOG_LEVEL_DEBUG, "In Yahoo Weather icon selection. c: %i, night: %i", c, night_time); - - // Tornado / Hurricane / Wind - if ((c >= 0 && c <= 2) || c == 23 || c == 24) { - return W_ICON_WIND; - } - // Thunderstorm - else if (c == 3 || c == 4 || c == 38 || c == 39) { - return W_ICON_THUNDER; - } - // Rain & Snow - else if (c == 5) { - return W_ICON_RAIN_SNOW; - } - // Rain & Sleet / Mixed - else if (c == 6 || c == 8 || c == 10 || c == 35) { - return W_ICON_RAIN_SLEET; - } - // Snow & Sleet - else if (c == 7) { - return W_ICON_SNOW_SLEET; - } - // Drizzle // Showers - else if (c == 9 || c == 11) { - return W_ICON_DRIZZLE; - } - // Rain / Scattered Showers / Thundershowers - else if (c == 12 || c == 45) { - return W_ICON_RAIN; - } - // Snow / Scattered Snow / Show Showers - else if (c == 13 || c == 14 || c == 16 || c == 42 || c == 46) { - return W_ICON_SNOW; - } - // Heavy Snow / Blowing Snow - else if (c == 15 || c == 41 || c == 43) { - return W_ICON_HEAVY_SNOW; - } - // Sleet - else if (c == 17 || c == 18) { - return W_ICON_SLEET; - } - // Fog / Mist / Haze / etc. - else if (c >= 19 && c <= 22) { - return W_ICON_FOG; - } - // Cold - else if (c == 25) { - return W_ICON_COLD; - } - // Cloudy - else if (c == 26) { - return W_ICON_CLOUDY; - } - // Mostly Cloudy - else if (c == 27 || c == 28) { - if (night_time) - return W_ICON_CLOUDY; - else - return W_ICON_MOSTLY_CLOUDY_DAY; - } - // Partly Cloudy or Fair - else if (c == 29 || c == 30 || c == 44) { - if (night_time) - return W_ICON_PARTLY_CLOUDY_NIGHT; - else - return W_ICON_PARTLY_CLOUDY_DAY; - } - // Clear Day Night - else if (c == 31 || c == 32) { - if (night_time) - return W_ICON_CLEAR_NIGHT; - else - return W_ICON_CLEAR_DAY; - } - // Fair Day Night - else if (c == 33 || c == 34) { - if (night_time) - return W_ICON_FAIR_NIGHT; - else - return W_ICON_FAIR_DAY; - } - // Hot - else if (c == 36) { - return W_ICON_HOT; - } - // Isolated / Scattered Thunderstorm - else if ((c >= 37 && c <= 39) || c == 47) { - if (night_time) - return W_ICON_THUNDER; - else - return W_ICON_THUNDER_SUN; - } - // Scattered Showers - else if (c == 40) { - if (night_time) - return W_ICON_RAIN; - else - return W_ICON_RAIN_SUN; - } - // Weather condition not available - else { - return W_ICON_NOT_AVAILABLE; - } -} - /* * Converts the Weather Underground API Weather Condition into one of our icons. * Refer to: http://www.wunderground.com/weather/api/d/docs?d=resources/phrase-glossary#forecast_description_numbers */ uint8_t wunder_weather_icon_for_condition(int c, bool night_time) { - //APP_LOG(APP_LOG_LEVEL_DEBUG, "In Yahoo Weather icon selection. c: %i, night: %i", c, night_time); - // Clear if (c == 1) { if (night_time) @@ -643,7 +529,7 @@ uint8_t wunder_weather_icon_for_condition(int c, bool night_time) if (night_time) return W_ICON_DRIZZLE; else - return W_ICON_RAIN_SUN; + return W_ICON_DRIZZLE; } // Showers else if (c == 11) { @@ -654,7 +540,7 @@ uint8_t wunder_weather_icon_for_condition(int c, bool night_time) if (night_time) return W_ICON_RAIN; else - return W_ICON_RAIN_SUN; + return W_ICON_RAIN; } // Rain else if (c == 13) { @@ -683,6 +569,22 @@ uint8_t wunder_weather_icon_for_condition(int c, bool night_time) else if (c == 22 || c == 23) { return W_ICON_SLEET; } + // Wind + else if (c == 30) { + return W_ICON_WIND; + } + // Rain Sleet + else if (c == 31) { + return W_ICON_RAIN_SLEET; + } + // Rain Snow + else if (c == 32) { + return W_ICON_RAIN_SNOW; + } + // Heavy Snow + else if (c == 33) { + return W_ICON_HEAVY_SNOW; + } else { return W_ICON_NOT_AVAILABLE; } diff --git a/src/weather_layer.h b/src/weather_layer.h index 7326300..b9dd8a0 100644 --- a/src/weather_layer.h +++ b/src/weather_layer.h @@ -77,7 +77,6 @@ void weather_layer_destroy(); void weather_layer_set_temperature(int16_t t, bool is_stale); void weather_layer_clear_temperature(); uint8_t open_weather_icon_for_condition(int condition, bool night_time); -uint8_t yahoo_weather_icon_for_condition(int condition, bool night_time); uint8_t wunder_weather_icon_for_condition(int c, bool night_time); #endif diff --git a/wscript b/wscript index 0554dc8..040ab7c 100644 --- a/wscript +++ b/wscript @@ -5,6 +5,8 @@ # Feel free to customize this to your needs. # +import os.path + top = '.' out = 'build' @@ -17,8 +19,23 @@ def configure(ctx): def build(ctx): ctx.load('pebble_sdk') - ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'), - target='pebble-app.elf') + build_worker = os.path.exists('worker_src') + binaries = [] + + for p in ctx.env.TARGET_PLATFORMS: + ctx.set_env(ctx.all_envs[p]) + ctx.set_group(ctx.env.PLATFORM_NAME) + app_elf='{}/pebble-app.elf'.format(ctx.env.BUILD_DIR) + ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'), + target=app_elf) + + if build_worker: + worker_elf='{}/pebble-worker.elf'.format(ctx.env.BUILD_DIR) + binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf}) + ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/**/*.c'), + target=worker_elf) + else: + binaries.append({'platform': p, 'app_elf': app_elf}) - ctx.pbl_bundle(elf='pebble-app.elf', - js=ctx.path.ant_glob('src/js/**/*.js')) + ctx.set_group('bundle') + ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob('src/js/**/*.js'))