Custom Navigation Tiles - How to make a Dynamic Weather Tile using Weather Underground API

:arrow_forward: See this for Custom Navigation basics Navigation Screen customization

This tutorial will show how to design a basic Dynamic Weather Tile and expose you to some more advanced scripting features included in V5.

This implementation uses Weather Underground API located here:
http://api.wunderground.com/weather/api/
You will need to setup an account and acquire an API key.

:warning: Disclaimer: This was setup for a USA location. It will work for any country you simply just set your region and city in the tag {CALL:weather.current('region','city','apikey')}

Your API key will be a long string of random numbers and letters.

We will be using JSCRIPT and JSON to extract data from the API

Tile Template:

Tile Cache is to prevent it from updating the tile and hitting the weather API website an unnecessary amount of times. In the example I set it to only update every 2 minutes. Its suggested to set it longer like 5-10 minutes.

Example for the city of Newark in the state Arkansas in the USA

{CALL:weather.current('AR','Newark','APIKEY')}

Script:

function current(region,city,key)
{
  var nL = '<linebreak/>';
  var u = 'http://api.wunderground.com/api/'+key+'/conditions/q/'+region+'/'+city+'.json';
  var allweather = web.Download(u);
  var weather = JSON.parse(allweather);
  var temp = weather.current_observation.temperature_string;
  var icon = weather.current_observation.icon_url;
  var hum = weather.current_observation.relative_humidity;
  var percip = weather.current_observation.precip_today_metric;
  var cond = weather.current_observation.weather;
  return tag.Size(30,'<b><color Blue>Current Weather</color></b>  ') + tag.Img(icon) + nL + tag.Size(20,'<b>Conditions </b>') + tag.Color('red').Size(20,cond) + nL + tag.Size(20,'<b>Temp  </b>') + tag.Color('red').Size(20,temp) + nL + tag.Size(20,'<b>Relative Humidity  </b>') + tag.Color('red').Size(20,hum);
}

Or if you use Left Alignment for tile it would look like this:

1 Like

If you wish to have a more advanced Forecast View that looks like the picture above then here is the script for that:

var nl = '<linebreak/>';

function forecast(region,city,key,t)
{
  if (typeof(t) == "undefined") { var t = 'f'; }
  var result = nl;
  var weather = getCurrent(region,city,key)
  result += toBlock(cdegree(weather,t)) + nl;
  var root = getForecast(region,city,key);  
  for (i = 0; i < root.length; i++) {
    result += toBlock(toTile(root[i],t)); 
  }
  return result;
}

function getForecast(region,city,key)
{
  var u = 'http://api.wunderground.com/api/'+key+'/forecast/q/'+region+'/'+city+'.json';
  var allweather = web.Download(u);
  var weather = JSON.parse(allweather);
  return weather.forecast.simpleforecast.forecastday;  
}

function getCurrent(region,city,key)
{
  var u = 'http://api.wunderground.com/api/'+key+'/conditions/q/'+region+'/'+city+'.json';
  var allweather = web.Download(u);
  var weather = JSON.parse(allweather);
  return weather.current_observation;  
}

function toBlock(content)
{
   return '<block 30,0,0,0>' + content + '</block>'
}

function toTile(forecast,t)
{
   return forecast.date.weekday_short + ' ' +sym(forecast.icon) + nl + 
     degree(forecast.high,t) + ' / ' + degree(forecast.low,t);
}

function degree(value, t)
{
   return t=='c' ? value.celsius: value.fahrenheit;
}

function cdegree(value, t)
{
   var result = t=='c' ? value.temp_c: value.temp_f;
   return '<size 70><bold>'+result+' '+degreesym(t)+'</bold></size>';
}

function degreesym(t)
{
   return t=='c' ? 'C˚': 'F˚';
}
function sym(icon)
{
  if(icon.indexOf('partlycloudy') != -1) return '<sym></sym>';
  if(icon.indexOf('cloudy') != -1) return '<sym></sym>';
  if(icon.indexOf('rain') != -1) return '<sym></sym>';
  if(icon.indexOf('snow') != -1) return '<sym></sym>';
  if(icon.indexOf('clear') != -1) return '<sym></sym>';
  if(icon.indexOf('sleet') != -1) return '<sym></sym>'
  if(icon.indexOf('fog') != -1) return '<sym></sym>'
  if(icon.indexOf('storm') != -1) return '<sym></sym>'
  return icon;
}

Hi Kendash,
Thanks for the tutorial and the example scripts. That really helped me learn a couple more things.

One little suggestion to add to your tutorial to help us newbies. That being a screenshot of the Script page.
I couldn’t get my “Weather” tile to display the weather, even though when testing the script it always returned the expected result.
I had to go searching elsewhere in the forums to find the reason. Basically I had named the script “weather” but didn’t know I had to also enter something into the handler box. Once I added that it all worked great, simple when you know how :wink:

My mind is now wondering what else I can script…Controlling Spotify comes to mind and I see that you were also considering that sometime ago…hmmm

Many thanks again

Tony

2 Likes

Yes sorry I am trying to just get as much info out there for you guys as I can. Most of our stuff was in very long technical discussions and all parties understood most of that. So when transferring those into tutorials in live category I may miss a step here or there.

I will add that in thank you.

EDIT: On second thought I might do a generic tutorial on scripts and just reference it.

1 Like

I actually did it. But I dont use it anymore so I scrapped it lol.

The scripting is VERY powerful we will be adding lots of tutorials as we sift through our notes etc when we did the beta. The amount of stuff you can do with v5 vs v4 is so huge its going to take us some time to get it all out there to you.

PS: It may be difficult to follow but the V5 Features Compilation does list most of whats available. It may be hard to understand it all but it makes a good reference tool.

1 Like

hello, it is posible save the data of the wether of the day?

I dont understand your question… What would you do with that data if you saved it? Yes its possible but it would help if you explained your intentions.

Technically its saving it already into the cache for the tile… we can save it to file, save it in program setting,save it in email, save it in an add task action, we can script something to save it in the database somewhere…

1 Like

yes of course, sorry, my mistake, i notice that some days my restaurant have more customers than others, is just another thing to considerate when you are analizing the results

You are still not being very clear… but I think I somewhat understand… your wanting to use it in reports for performance indicators?

If this is the case you might want to consider the Add Task action to store this in a table format that is readable in reports… Unfortunately there is not much documentation on the use of this action yet. Hopefully soon we can get more information on it out.

yes, is exactly what i want, sorry my english it is limitated

Hi @Jesse I think this is a wonderful idea having weather output on the nav screen considering my business’ trade is largely weather dependant. I have been trying for a while to replicate what you have done but its not working for me. I have tried your location as well as mine, if I run this: http://api.wunderground.com/api/KEY/conditions/q/South_Africa/Jeffrey’s_Bay.json it returns the correct details but does not want to display on the nav screen. I have tried different tiles as well. I am currently on the accounts tile. see below

I then thought it must have something to do with the apostrophe and spaces in the names, got around that but still nothing.

Right now it looks like this, with all the above in place:

Male sure that terminal has Internet and it’s not blocked by firewall. You might want to set tile cache to 2 minutes so it won’t flood the API with too many requests. Try it without the accounts word just use the call.

Got internet, Firewall switched off, cache set to 5. removed account word line, see below dont know what it can be… such a cool feature to have though.

try {CALL:weather.forecast…} instead of {CALL:weather.current…}

1 Like

LOL good catch Emre. Also remember now that you have Cache set to 5 it will take 5 minutes before tile will update. Set it to 0 for testing and once working then set your cache how you want.

1 Like

I will add if you wanted Current weather and not Forecast then according to the script the function is getCurrent not current so your tag would be {CALL:weather.getCurrent(X)} The one you used was completely wrong there is no function called current which is why it was showing blank.

EDIT: Sorry Emre I meant to reply to his thread not yours.

1 Like

{CALL:weather.getForecast(‘ZA’,‘Jeffrey’s_Bay’,‘9c4fxxxxxx’)} returns nothing and so does {CALL:weather.getCurrent(‘ZA’,‘Jeffrey’s_Bay’,‘9c4fxxxxx’)} with cache set to 0. I changed the area to ZA seems to also work through URL.

Do you think it has something to do with the ’ in the town name? Should it be escaped with \ ?

the tag should be {CALL:weather.forecast('ZA','Jeffrey's_Bay','9c4fxxxxxx')}

You are probably correct.

EDIT: I escaped it and it worked just fine.

I also added the Tile Name back in with <bold> and <size> tags and it worked just fine.

1 Like

Bravo! The Challenges… Yes

2 Likes

OK F doesnt mean much where I am can it easily be changed to C do you know?