Command-line Weather Tool (with minimal dependencies)


Disclaimer: I am no bash scripting veteran by any stretch of the imagination! If you see anything that’s done improperly, could be done more efficiently, or is done in an incredibly stupid manner kindly post a comment explaining the why’s and how’s of the better way! I’m just doing my best to make a free tool that will hopefully help a few people out, and if I can learn to do something better, well that’s great too! I hope you find this useful, and if it doesn’t work on your system please let me know what the problem is and I’ll try to solve it and update the script – or if you have a fix for a problem let me know and I’ll implement it, and give you credit (a mention or a name & url in the change-log, if you’d like) for finding and/or solving it! I’ve done my best to make this script safe to run, even if it doesn’t work on your system for some reason… but that being said, look it over first, try to understand it first, and of course this script is provided ‘as-is’ and comes with no warranty, implied or otherwise, blah blah blah…

Here’s a couple of screen shots to give you an idea of what this simple weather script does. All the info you should need to use it should be in the screen shots below, and the comments of the script itself (below the pictures). If you find this at all useful PLEASE post a comment letting me about your experiences with Weather Tool!

An example of the script's output using the --full-report option.
An example of the script’s output using the –full-report option.
Help info for the weather-tool.sh script
Help info for the weather-tool.sh script
#!/bin/bash
#
# Weather Tool // weather-tool.sh
# (c)2012, by Adam Gaskins : self@adamgaskins.com
# Homepage: http://linuxlusers.com/weather-tool
#
# This script retrieves weather data and returns a weather
# report in various formats. It was created out of my frus-
# tration when trying to find a simple CLI weather tool. I
# initially tried two existing CLI weather programs and
# both suffered from problems related to old dependencies.
# A goal of this script is minimal dependencies. Awk, sed
# and curl are used, all of which are standard on virtual-
# ly every modern linux distro, so no additional effort
# should be required to run this script.
#
# A list of all available weather stations can be found at:
#  - http://w1.weather.gov/xml/current_obs/
# Just choose your state and find the 4 letter code for the
# location nearest to you.
#
# Usage:
#   $ ./weather-tool.sh KLFI --full-report
#   (use the --help option for more details)
#
# Coming Soon:
#   Profile support - running the script with no parameters
#   will retrieve the first station ID specified in a file
#   and return a report for this default location. Further,
#   this file could possibly contain  several station IDs 
#   which could be recalled via a user defined label (e.g.
#   home, office, or a proper city name).
#
#   A  --one-liner option similar to --brief-report but all
#   on a single line.
#
#   User-defined reports where %values can be used to specify
#   what data is to be displayed in the output (e.g. %temp
#   would output the temperature value, etc.)
#
# Changelog:
#   1.1 - Added wind-chill feature, corrected some typos

script_name='weather-tool.sh'
script_version='1.1'

# Weather data source
weather_uri='http://w1.weather.gov/xml/current_obs'

# Takes a parameter corresponding to a tag in the weather report XML file and
# returns it's value (pretty sure this pipe cluster could be simplified)
function get_val {
    echo `echo "$xml_data" | grep "<$1>" | sed -e :a -e 's/<[^>]*>//g;'`
}
function wind_chill {
    t=`get_val 'temp_f'`
    w=`get_val 'wind_mph'`
    wcf=$(printf "%0.1f" `awk "BEGIN { print 35.74 + 0.6215 * $t - 35.75 * $w^0.16 + 0.4275 * $t * $w^0.16 }"`)
    wcc=$(printf "%0.1f" `awk "BEGIN { print ($wcf - 32) / 1.8 }"`)
    echo "Wind-chill: $wcf F ($wcc C) [considered valid only for temps below 50F(10C)]"
}

### Main functions // the following functions correspond to CLI options
function brief_report {
    echo "`get_val 'location'` (Station ID: `get_val 'station_id'`)"
    echo "Temperature: `get_val 'temperature_string'`"
    echo "Conditions: `get_val 'weather'`"
}

function full_report {
    echo ''
    echo "`get_val 'location'` (Station ID: `get_val 'station_id'`, Lon/Lat: `get_val 'longitude'`/`get_val 'latitude'`)"
    echo ''
    echo '  Weather report:'
    echo "    Temperature: `get_val 'temperature_string'`"
    echo "    Conditions: `get_val 'weather'`"
    echo "    Visibility: `get_val 'visibility_mi'` miles"
    echo "    Wind: `get_val 'wind_string'`"
    echo "    Pressure: `get_val 'pressure_in'` inches (`get_val 'pressure_mb'` mbar)"
    echo "    Relative humidity: `get_val 'relative_humidity'`%"
    echo "    Dew-point: `get_val 'dewpoint_string'`"
    echo ''
    echo "  `get_val 'observation_time'` from '$weather_uri'"
    echo ''
}

function dump_xml {
    echo "$xml_data"
}

function help {
    echo "Usage: $script_name STATION_ID [OPTION]..."
    echo 'Display a weather report for STATION_ID.'
    echo 'STATION_ID is typically a four letter code corresponding to a weather station'
    echo 'A list of all available weather stations can be found at:'
    echo '    http://w1.weather.gov/xml/current_obs/'
    echo "Example: $script_name KLFI --full-report"
    echo ''
    echo 'Options:'
    echo '  -b, --brief         brief report, just temp & conditions (default behavior)'
    echo '  -f, --full-report   prints out a full report with all available data'
    echo '  -h, --help          display this help info'
    echo '  -o, --one-liner     display a minimal one-line report'
    echo '  -v, --version       output version information'
    echo '  -w, --wind-chill    calculate wind-chill factor, experimental'
    echo '  -x, --xml           output raw XML content'
    echo ''
    echo 'Report bugs to self@adamgaskins.com'
    echo "$script_name home page: www.linuxlusers.com/weather_tool"
}

function version {
    echo "$script_name v$script_version"
}

### END OF FUNCTIONS ###

# Verify the station ID
if [[ "$1" != '--help' && "$1" != '-h' && \
      "$1" != '--version' && "$1" != '-v' ]]
then
    # Download data
    xml_data=`curl -s "$weather_uri/$1.xml"`

    # Validate station ID & data
    if [[ -z $1 || `echo "$1" | grep -E -v '^[a-zA-Z]{4}
` ]];then
        echo 'You must specify a valid station ID (or try the --help option for complete usage information).'
        exit 0
    elif [[ `echo $xml_data | grep -i "cannot be found"` ]];then
        echo "There was a problem retrieving data for the requested station ID ($1)."
        echo 'Please verify that station ID is valid at:'
        echo "    $weather_uri"
        exit 0
    fi
fi

# Configure getopt
ARGS=`getopt -o "bfwxhv" -l "brief,full-report,wind-chill,xml,help,version" -n "$0" -- "$@"`
eval set -- "$ARGS"

# handle options
while true; do
    case "$1" in
        -b|--brief)
            brief_report
            shift;;

        -f|--full-report)
            full_report
            shift;;

        -w|--wind-chill)
            wind_chill
            shift;;

        -x|--xml)
            dump_xml
            shift;;

        -h|--help)
            help
            shift;;

        -v|--version)
            version
            shift;;

        --)
            shift
            break;;
    esac
done

exit 1

Leave a Reply