loader image

How to Get on Your Xubuntu Panel to Show Weather Data

What makes us different from other similar websites? Forums Tech How to Get on Your Xubuntu Panel to Show Weather Data

Viewing 1 post (of 1 total)
  • Author
    Posts
  • #8156
    thumbtak
    Moderator

    I’ve been working on a neat little bash script to display dynamic weather information directly on my Xubuntu panel using the Generic Monitor tool. This script fetches feels like temperature, a daily forecast description (like Partly Cloudy or Heavy Rain), and the expected amount of rain for a random location within New York City. Each time it updates, it picks a new spot, which is pretty cool!

    I wanted to share it and provide instructions on how to set it up.

    How to Get Random NYC Weather on Your Xubuntu Panel (change latitude and longitude for your location)

    This guide will walk you through setting up this script to display weather data on your Xubuntu panel using the Generic Monitor tool.

    Step 1: Install Prerequisites

    First, you need to ensure you have curl (for fetching data from the web) and jq (for parsing JSON data) installed on your system.

    Open your terminal (usually by pressing Ctrl + Alt + T) and run the following command:

    $ sudo apt update
    $ sudo apt install curl jq

    $ sudo apt update: Refreshes your package lists.
    $ sudo apt install curl jq: Installs both curl and jq. You might be asked for your password.

    Step 2: Save the Weather Script

    Next, you’ll save the bash script to a file on your computer.

    1. Create the script file:

    Open your terminal again and create a new file. A good place for user scripts is usually ~/.local/bin/ or ~/bin/. Let’s use ~/.local/bin/ for this example.

    $ mkdir -p ~/.local/bin/
    $ mousepad ~/.local/bin/random_nyc_weather.sh

    (You can replace mousepad with your preferred text editor like gedit or nano.)

    2. Paste the script content:

    Copy the entire script below and paste it into the random_nyc_weather.sh file you just opened.

    #!/bin/bash
    
    # Define the approximate bounding box for New York City
    # Latitude: ~40.5° N to ~40.9° N
    # Longitude: ~-74.25° W to ~-73.7° W
    MIN_LAT="40.50"
    MAX_LAT="40.90"
    MIN_LON="-74.25"
    MAX_LON="-73.70"
    
    # Generate random latitude and longitude within NYC boundaries
    # Use awk for floating-point arithmetic and random number generation
    # We use 'printf "%.4f"' to limit decimal places for better readability and API compatibility
    RANDOM_LAT=$(awk -v min="$MIN_LAT" -v max="$MAX_LAT" 'BEGIN{srand(); printf "%.4f", min + rand() * (max - min)}')
    RANDOM_LON=$(awk -v min="$MIN_LON" -v max="$MAX_LON" 'BEGIN{srand(); printf "%.4f", min + rand() * (max - min)}')
    
    # Fetch weather data from Open-Meteo API for the random NYC location
    # Request hourly apparent_temperature (feels like), daily weather code,
    # and daily precipitation sum. All temperatures in Fahrenheit, precipitation in mm.
    # The 'timezone=auto' parameter will automatically determine the timezone based on coordinates.
    # 'forecast_days=1' ensures we get data for the current day only.
    WEATHER_DATA=$(curl -s "[https://api.open-meteo.com/v1/forecast?latitude=$RANDOM_LAT&longitude=$RANDOM_LON&hourly=apparent_temperature&daily=weathercode,precipitation_sum&temperature_unit=fahrenheit&forecast_days=1&timezone=auto&precipitation_unit=mm](https://api.open-meteo.com/v1/forecast?latitude=$RANDOM_LAT&longitude=$RANDOM_LON&hourly=apparent_temperature&daily=weathercode,precipitation_sum&temperature_unit=fahrenheit&forecast_days=1&timezone=auto&precipitation_unit=mm)")
    
    # Check if data was fetched successfully
    # If WEATHER_DATA is empty, it indicates a problem with the curl request or network.
    if [ -z "$WEATHER_DATA" ]; then
    echo "Weather data N/A (Failed to fetch from API. Check network connection or API availability.)"
    exit 1
    fi
    
    # Check for API errors in the response (e.g., invalid coordinates, rate limits, or other API-specific issues)
    # 'jq -e .error' checks if an 'error' field exists and is true.
    # 'jq -r .reason' extracts the reason message.
    if echo "$WEATHER_DATA" | jq -e '.error' > /dev/null; then
    ERROR_MESSAGE=$(echo "$WEATHER_DATA" | jq -r '.reason // "Unknown API error occurred."')
    echo "Weather API Error: $ERROR_MESSAGE"
    exit 1
    fi
    
    # --- Extract "Feels Like" Temperature ---
    # '.hourly.apparent_temperature[0]' gets the apparent temperature for the current hour.
    # '// "N/A"' provides a default value if the data is missing.
    APPARENT_TEMP=$(echo "$WEATHER_DATA" | jq -r '.hourly.apparent_temperature[0] // "N/A"')
    if [ "$APPARENT_TEMP" == "N/A" ] || [ "$APPARENT_TEMP" == "null" ]; then
    APPARENT_TEMP_STRING="Feels Like: N/A"
    else
    APPARENT_TEMP_STRING="Feels Like: ${APPARENT_TEMP}°F"
    fi
    
    # --- Extract Daily Weather Code and Description ---
    # '.daily.weathercode[0]' gets the weather code for the current day.
    DAILY_WEATHER_CODE=$(echo "$WEATHER_DATA" | jq -r '.daily.weathercode[0] // -1')
    WEATHER_DESCRIPTION="N/A"
    
    # Map WMO (World Meteorological Organization) weather codes to descriptive text.
    # This mapping provides human-readable conditions based on the numeric codes from Open-Meteo.
    case "$DAILY_WEATHER_CODE" in
    0) WEATHER_DESCRIPTION="Clear Sky" ;;
    1) WEATHER_DESCRIPTION="Mainly Clear" ;;
    2) WEATHER_DESCRIPTION="Partly Cloudy" ;;
    3) WEATHER_DESCRIPTION="Overcast" ;;
    45) WEATHER_DESCRIPTION="Fog" ;;
    48) WEATHER_DESCRIPTION="Depositing Rime Fog" ;;
    51) WEATHER_DESCRIPTION="Light Drizzle" ;;
    53) WEATHER_DESCRIPTION="Moderate Drizzle" ;;
    55) WEATHER_DESCRIPTION="Dense Drizzle" ;;
    56) WEATHER_DESCRIPTION="Light Freezing Drizzle" ;;
    57) WEATHER_DESCRIPTION="Dense Freezing Drizzle" ;;
    61) WEATHER_DESCRIPTION="Slight Rain" ;;
    63) WEATHER_DESCRIPTION="Moderate Rain" ;;
    65) WEATHER_DESCRIPTION="Heavy Rain" ;;
    66) WEATHER_DESCRIPTION="Light Freezing Rain" ;;
    67) WEATHER_DESCRIPTION="Heavy Freezing Rain" ;;
    71) WEATHER_DESCRIPTION="Light Snow Fall" ;;
    73) WEATHER_DESCRIPTION="Moderate Snow Fall" ;;
    75) WEATHER_DESCRIPTION="Heavy Snow Fall" ;;
    77) WEATHER_DESCRIPTION="Snow Grains" ;;
    80) WEATHER_DESCRIPTION="Light Rain Showers" ;;
    81) WEATHER_DESCRIPTION="Moderate Rain Showers" ;;
    82) WEATHER_DESCRIPTION="Violent Rain Showers" ;;
    85) WEATHER_DESCRIPTION="Light Snow Showers" ;;
    86) WEATHER_DESCRIPTION="Heavy Snow Showers" ;;
    95) WEATHER_DESCRIPTION="Thunderstorm" ;;
    96) WEATHER_DESCRIPTION="Thunderstorm with Light Hail" ;;
    99) WEATHER_DESCRIPTION="Thunderstorm with Heavy Hail" ;;
    *) WEATHER_DESCRIPTION="Unknown Condition (Code: $DAILY_WEATHER_CODE)" ;; # Fallback for unmapped codes
    esac
    
    DAILY_FORECAST_STRING="Forecast: ${WEATHER_DESCRIPTION}"
    
    # --- Extract Daily Precipitation and Convert to Inches ---
    # '.daily.precipitation_sum[0]' gets the total precipitation for the day in millimeters.
    DAILY_PRECIPITATION_MM=$(echo "$WEATHER_DATA" | jq -r '.daily.precipitation_sum[0] // "0"')
    
    # Convert millimeters to inches (1 inch = 25.4 mm)
    # 'bc -l' is used for floating-point calculations.
    PRECIPITATION_INCHES=$(awk "BEGIN {printf \"%.2f\", $DAILY_PRECIPITATION_MM / 25.4}")
    
    # Format precipitation string based on whether rain is expected.
    if (( $(echo "$PRECIPITATION_INCHES > 0" | bc -l) )); then
    PRECIPITATION_STRING="Rain Expected: ${PRECIPITATION_INCHES} in"
    else
    PRECIPITATION_STRING="No Rain Expected"
    fi
    
    # --- Combine all into the final display string ---
    # This line concatenates all extracted information for a comprehensive output.
    DISPLAY_STRING="Location: (${RANDOM_LAT}, ${RANDOM_LON}) | ${APPARENT_TEMP_STRING} | ${DAILY_FORECAST_STRING} | ${PRECIPITATION_STRING}"
    
    echo "$DISPLAY_STRING"
    
    # Note: This script requires 'jq' for parsing JSON responses.
    # 'jq' is a powerful command-line JSON processor.
    # If 'jq' is not installed on your system, you can typically install it using:
    # On Debian/Ubuntu: sudo apt-get install jq
    # On Fedora: sudo dnf install jq
    # On macOS: brew install jq

    If you used nano, save the file by pressing Ctrl + O, then Enter, and exit with Ctrl + X.

    Step 3: Make the Script Executable

    You need to give the script permission to run. In your terminal, run:

    $ chmod +x ~/.local/bin/random_nyc_weather.sh

    Step 4: Test the Script (Optional but Recommended)

    Before adding it to the panel, you can test if the script works correctly by running it directly in the terminal:

    ~/.local/bin/random_nyc_weather.sh

    You should see output similar to: Feels Like: 75.2°F | Forecast: Partly Cloudy | No Rain Expected

    Step 5: Add to Xubuntu Panel using Generic Monitor

    Now, let’s add this script’s output to your Xubuntu panel.

    • Right-click on an empty space on your Xubuntu panel.
    • Select “Panel” -> “Add New Items…”
    • Scroll down and find “Generic Monitor”. Select it and click “Add”.
    • A new Generic Monitor item will appear on your panel. Right-click on it and select “Properties”.

    In the Generic Monitor Properties window:

    • Command: Enter the full path to your script:

    ~/.local/bin/random_nyc_weather.sh

    Label: You can leave this blank or give it a short label like “NYC Weather”.
    Period (seconds): This is how often the script will run and update the display. For weather, a reasonable period is 300 (5 minutes) or 600 (10 minutes) to avoid excessive API calls.
    • You can adjust other display options like font and colors if you wish.

    6. Close the properties window.

    You should now see the weather information for a random NYC location (or yours if you set it) appearing on your panel, updating at the interval you set!

Viewing 1 post (of 1 total)
  • You must be logged in to reply to this topic.
TAKs Shack