Search code examples
bashshellweathertemperature

How to get the current temperature from the shell?


I am wanting to retrieve the current temperature at my location from a Linux shell using only public APIs; nothing that requires a subscription or creating credentials with an API provider.


Solution

  • The solution requires you to have these tools installed to your Linux OS:

    • curl, to send GET requests to URLs.
    • jq, to query the JSON objects returned by the curl requests.

    TL;DR, here's the final command-line:

    curl -s -L "$(curl -s -L "https://api.weather.gov/points/$(curl -s -L "https://nominatim.openstreetmap.org/search.php?q=$(curl -s -L ipinfo.io | jq -r '"\(.city),\(.region)"')&polygon_geojson=1&format=jsonv2" | jq -r '"\(.[0].lat),\(.[0].lon)"')" | jq -r '.properties.forecastHourly')" | jq -r '.properties.periods[0].temperature'
    

    Breaking it down:

    (The ... represents the command from the previous step.)

    1. Send a request to ipinfo.io to view details about your location based on your public ip:
    curl -s -L ipinfo.io
    
    1. Parse the results of ipinfo.io request to get the city and region/state:
    ... | jq -r '"\(.city),\(.region)"'
    
    1. Add the city and state string you created with jq into a curl call to OpenStreetMap:
    curl -s -L "https://nominatim.openstreetmap.org/search.php?q=$(...)&polygon_geojson=1&format=jsonv2"
    
    1. Parse the response from OpenStreetMap into a "latitude,longitude" string:
    ... | jq -r '"\(.[0].lat),\(.[0].lon)"'
    
    1. Add the latitude and longitude into the url for a request to weather.gov:
    curl -s -L "https://api.weather.gov/points/$(...)"
    
    1. Parse out the url to the hourly weather forecast:
    ... | jq -r '.properties.forecastHourly'
    
    1. Make a curl call to the hourly forecast url:
    curl -s -L "$(...)"
    
    1. Last step: Pull the temperature property out of the JSON response:
    ... | jq -r '.properties.periods[0].temperature'
    

    Easy as that.

    P.S.

    As pointed out by David, the call to ipinfo.io actually does return the latitude and longitude, so the OpenStreetMap portion of the command can be left out entirely, e.g.:

    curl -s -L "$(curl -s -L "https://api.weather.gov/points/$(curl -s -L ipinfo.io | jq -r '"(.loc)"')" | jq -r '.properties.forecastHourly')" | jq -r '.properties.periods[0].temperature'