Using the National Weather Service in a Console App...

Started by airr, July 08, 2024, 08:13:01 PM

Previous topic - Next topic

airr

Played around with the API for the National Weather Service today (https://www.weather.gov/documentation/services-web-api).

The API responds with JSON data, so I used the Parson json library (with a few fixes so it would compile cleanly with Pelles and MSVC).

Here's the code (see attachment for .bas file and Parson):


#include "parson.c"

type LOCATION
    zipcode as string
    country as string
    city as string
    state as string
    longitude as string
    latitude as string
end type


Function main(argc as integer, argv as pchar ptr)

    dim as LOCATION record
    dim head$

    if argc <> 2 then
        print "Usage: ", AppExeName$, " <US Zip Code>"
        end = 1
    end if
   
    set_location(&record,command$(1))

    sprint head$, "7 Day Forecast for ", record.city,", ",record.state,", ", record.zipcode

    ClearScreen()

    print repeat$(70, "-"),crlf$,cpad$(head$,70), crlf$, repeat$(70, "-")
    get_forecast(get_weather_url(record.latitude, record.longitude))

End Function

function get_text(json_object as JSON_Object Ptr, query as string) as string
    dim res as string

    if json_object_dotget_value(json_object, query) then
        res = json_object_dotget_string(json_object, query)
    end if

    function = res
end function

function load_json(filename as string) as JSON_Object Ptr
    dim as integer fileSize = lof(filename)
    dim as JSON_Value Ptr json
    dim as JSON_Object Ptr root
    dim jFile$*fileSize

    jFile$ = loadfile$(filename)
    json = json_parse_string(jFile)
    root = json_value_get_object(json)
   
    if root then return root
    return null

end function

Sub set_location(byref record as LOCATION, zip as string)
    dim as JSON_Object* root, obj
    dim as JSON_Array* place
    dim url$, path$

    sprint url$,"http://api.zippopotam.us/us/", zip
    sprint path$, tempdir$,"/location.json"


    If Download(url$, path$) Then

        root = load_json(path$)

        place = json_object_get_array(root, "places")
        obj = json_array_get_object (place, 0)

        with record
            .zipcode = get_text(root, "post code")
            .country = get_text(root, "country abbreviation")
            .city = get_text(obj, "place name")
            .state = get_text(obj, "state abbreviation")
            .longitude = get_text(obj, "longitude")
            .latitude = get_text(obj, "latitude")
        end with

        kill path$
    ELSE
        Print "Download Failed"
    End If

End Sub

Function get_weather_url(latitude as string, longitude as string) as string
    dim as JSON_Object* root
    dim url$, path$

    sprint url$,"https://api.weather.gov/points/",latitude,",",longitude
    sprint path$, tempdir$,"/api.json"

    If Download(url$, path$) Then
        root = load_json(path$)
        sprint url$, get_text(root, "properties.forecast")
        kill path$
        return url$
    End IF

    return ""

End Function

Sub get_forecast(url$)
    dim as JSON_Object* root, obj
    dim as JSON_Array* arr
    dim path$

    sprint path$, tempdir$,"/forcast.json"

    If Download(url$, path$) Then
        root = load_json(path$)
        arr = json_object_dotget_array(root, "properties.periods")
        for int i = 0 to json_array_get_count(arr)-1
            obj = json_array_get_object (arr, i)
            if json_object_get_boolean(obj,"isDaytime") then
                print crlf$,"Period: ", tab$,get_text(obj, "name")
                print "Temperature: ", tab$, str$(json_object_get_number(obj, "temperature"),1), get_text(obj, "temperatureUnit")
                print "Forecast: ", tab$, replace$(get_text(obj,"detailedForecast"),".","."+crlf$+space$(15))
                print repeat$(70,"-")
            end if
        next
        kill path$
    End if
End Sub

Sub ClearScreen()
    !printf("\33[1;1H\33[2J\33[3J");
End Sub



The data returned includes daytime and evening forecasts, but I filtered on daytime only in this demo.

AIR.

MrBcx

Brrrrrr ... it's gonna be chilly a week from now!



----------------------------------------------------------------------
            7 Day Forecast for Apache Junction, AZ, 85119
----------------------------------------------------------------------

Period:         Tuesday
Temperature:    112F
Forecast:       Sunny.
                High near 112, with temperatures falling to around 110 in the afternoon.
                South wind around 5 mph.

----------------------------------------------------------------------

Period:         Wednesday
Temperature:    112F
Forecast:       Sunny, with a high near 112.
                South southwest wind 5 to 10 mph.

----------------------------------------------------------------------

Period:         Thursday
Temperature:    112F
Forecast:       Sunny, with a high near 112.
                South southwest wind around 5 mph.

----------------------------------------------------------------------

Period:         Friday
Temperature:    111F
Forecast:       A slight chance of showers and thunderstorms after 5pm.
                Sunny, with a high near 111.
                South southwest wind around 5 mph.
                Chance of precipitation is 20%.

----------------------------------------------------------------------

Period:         Saturday
Temperature:    109F
Forecast:       A chance of showers and thunderstorms between 11am and 5pm, then a chance of showers and thunderstorms.
                Mostly sunny, with a high near 109.
                South southwest wind around 5 mph.
                Chance of precipitation is 30%.
                New rainfall amounts less than a tenth of an inch possible.

----------------------------------------------------------------------

Period:         Sunday
Temperature:    105F
Forecast:       A chance of showers and thunderstorms after 11am.
                Mostly sunny, with a high near 105.
                West southwest wind 0 to 10 mph.
                Chance of precipitation is 40%.
                New rainfall amounts between a tenth and quarter of an inch possible.

----------------------------------------------------------------------

Period:         Monday
Temperature:    104F
Forecast:       A chance of showers and thunderstorms after 11am.
                Mostly sunny, with a high near 104.
                Southwest wind 0 to 10 mph.
                Chance of precipitation is 40%.

----------------------------------------------------------------------

Ad_Rienks

How do you live there? 40 deg. Celsius; 30 at night?

I am so glad with the weather overhere, in the Netherlands; around 20 Celsius is my ideal weather; some rain, some sun, sometimes cloudy!

MrBcx

Quote from: Ad_Rienks on July 08, 2024, 11:00:53 PM
How do you live there? 40 deg. Celsius; 30 at night?

I am so glad with the weather overhere, in the Netherlands; around 20 Celsius is my ideal weather; some rain, some sun, sometimes cloudy!

We have a well worn saying ... Yes, but it's a DRY HEAT.

We live in our air conditioned houses, we drive in our air conditioned cars, and go to our air conditioned offices, shops, malls, etc.

Four months out of the year, it's like living in hell but the rest of the time our weather is heavenly.