How to access the follow JSON?

I have this...

{visibility=>10000, main=>{temp=>16.870001, humidity=>88, temp_min=>16.670000, temp_max=>17, pressure=>1022}, weather=>[{main=>Rain, id=>500, description=>light rain, icon=>10n}], coord=>{lat=>50.830002, lon=>-0.140000}, cod=>200, dt=>1439327967, sys=>{sunset=>1439321264, message=>0.012800, type=>1, sunrise=>1439268153, id=>5089, country=>GB}, base=>stations, wind=>{deg=>30, speed=>2.600000}, clouds=>{all=>92}, id=>2654710, name=>Brighton}

And can access for example the temp like this

w.temperature = data["main"]["temp"];

But how can I access the weather/description as this doesn't work

w.weather = data["weather"]["description"];

TIA!
  • Here's how I get the simple weather state:

    weatherdata=data["weather"];
    weather=weatherdata[0]["main"];

    In your post, weather would be "Rain"

    This should work for you. It's in an array...
    weatherdata=data["weather"];
    weather=weatherdata[0]["description"];


    here is would be "Light Rain".

    BTW, data["dt"] is an interesting one to also catch - it's the "unix time" for the data, so you can see how old the data is. (sunrise and sunset are in the same format).

    Even if you don't display the reading time, you may want to check it out using Sys.println() as I found the data was often an hour or two old, and in fact that is why I gave up on using this as a data source for weather info. The one I use now is more like 1-5 minutes old.

    Also, "temp_min" and "temp_max" are not daily ranges. It's for available stations at about the same time, so it doesn't really tell you much.
  • Thanks! Out of interest what feed do you use now?
  • Thanks! Out of interest what feed do you use now?


    Weather Underground. (wunderground.com) It may only have data for the US (I've never checked), but one of the thousands of weather stations it has is the one in my own back yard. It requires an API key to access the data with a json request.
  • Do you pay? The free sub is only 500 calls a day or is your widget just for personal use? Thanks as ever!
  • Do you pay? The free sub is only 500 calls a day or is your widget just for personal use? Thanks as ever!



    Yes, I'm using the free version, but have the key in the Object Store, and I'm hoping with user config in SDK 1.2.0, users will be able to set their own apikey. I've made OS's for a few users with their own keys already, and Garmin has used my key/widget to help reproduce a problem. 500 a day would probably be good for a few people to share (10-20?) I have an app that accesses the same site, and have it set to request a data update every 15 minutes, and with that 24x7 is would be about 100 calls a day. With the widget itself, I might use it 10 times/day.

    Oh, as another hint on the widget - with mine, the first time it's used, it gets the gps location, and then the weather for that location. It save the location in the OS. After that, it skips getting the location and just gets the data for the saved location. A tap on the screen tells it to go out and get the current GPS location and use that, so it will handle changing locations, but saves a bit of time by only getting the current location if the user requests it.

    The app version has two screens. The main screen looks like a watchface, and includes stuff like current temp, steps/goal/move bar etc. (it only updates once per minute, so no seconds) The second page shows details of the current weather (wind dir/speed/gusts, baro, rain, etc) but with zero delay as there is no need to request the current data, as the app has it already.
  • And the next question is have you got an epoch --> human readable time function ?

    :-)
  • It also handles 12/24hr format:

    epoch=data["dt"];

    Sys.println(epoch);
    var now = Time.Gregorian.moment({:year=>0,:month=>0,:day=>0}); //Moment with value of 0
    var offset = new Toybox.Time.Duration(epoch);
    now = now.add( offset );

    var today = Calendar.info(now, Time.FORMAT_MEDIUM);
    if(Sys.getDeviceSettings().is24Hour)
    {
    timestamp=today.month+" @ "+today.day+" "+today.hour+":"+today.min.format("%02d");
    }
    else
    {
    var hour = today.hour % 12;
    hour = (hour == 0) ? 12 : hour;

    var AMPM = (today.hour>11) ? "pm" : "am";

    timestamp=today.month+" "+today.day+" @ "+hour+":"+today.min.format("%02d")+" "+AMPM;
    }
  • this is doing my head in! I do this

    w.temperature = (data["main"]["temp"]).toFloat();
    var temp = Lang.format("Temp: $1$", [w.temperature]);
    dc.drawText(0, 15, Gfx.FONT_TINY, temp, Gfx.TEXT_JUSTIFY_LEFT);

    But for the LIFE OF ME, I cannot figure out how to get the temp to say a .2f format, ie. 00.00

    I thought I should be OK to do

    var temp = Lang.format("Temp: $1$", [w.temperature.format("%0.2f")]);
  • this is doing my head in! I do this

    w.temperature = (data["main"]["temp"]).toFloat();
    var temp = Lang.format("Temp: $1$", [w.temperature]);
    dc.drawText(0, 15, Gfx.FONT_TINY, temp, Gfx.TEXT_JUSTIFY_LEFT);

    But for the LIFE OF ME, I cannot figure out how to get the temp to say a .2f format, ie. 00.00

    I thought I should be OK to do

    var temp = Lang.format("Temp: $1$", [w.temperature.format("%0.2f")]);


    try
    temp=data["main"]["temp"].format("%0.2f");
    dc.drawText(0, 15, Gfx.FONT_TINY, temp, Gfx.TEXT_JUSTIFY_LEFT);


    Not sure why, but when I get data from OW, the temp is in degrees Kelvin, so a conversion is needed. Could it have to do with the location?
    In your code, data["main"]["temp"] is already a number, so no need for the "toFloat()". That could be waht's confusing it.

    The actual call I used was:

    temperature = kelvinToFarenheight(data["main"]["temp"]).format("%.1f");