#!/usr/bin/env python3 """ Weather Agent Fetches weather for Providence, UT and returns structured data + markdown section. Called by the Daily Briefing agent. Can also run standalone. """ import sys from datetime import datetime from shared import MT, api_request, log_run AGENT_ID = "weather" # Providence, UT LAT = 41.7064 LON = -111.8133 WEATHER_URL = ( f"https://api.open-meteo.com/v1/forecast?" f"latitude={LAT}&longitude={LON}" f"¤t=temperature_2m,apparent_temperature,weather_code,wind_speed_10m,relative_humidity_2m" f"&daily=weather_code,temperature_2m_max,temperature_2m_min,precipitation_sum,wind_speed_10m_max,sunrise,sunset" f"&temperature_unit=fahrenheit&wind_speed_unit=mph&precipitation_unit=inch" f"&timezone=America/Denver&forecast_days=7" ) WMO_CODES = { 0: "Clear sky", 1: "Mainly clear", 2: "Partly cloudy", 3: "Overcast", 45: "Foggy", 48: "Icy fog", 51: "Light drizzle", 53: "Drizzle", 55: "Heavy drizzle", 61: "Light rain", 63: "Rain", 65: "Heavy rain", 66: "Freezing rain", 67: "Heavy freezing rain", 71: "Light snow", 73: "Snow", 75: "Heavy snow", 77: "Snow grains", 80: "Light showers", 81: "Showers", 82: "Heavy showers", 85: "Light snow showers", 86: "Heavy snow showers", 95: "Thunderstorm", 96: "Thunderstorm w/ hail", 99: "Severe thunderstorm", } DAY_NAMES = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] def fetch_weather(): """Fetch weather data from Open-Meteo.""" return api_request(WEATHER_URL) def format_section(weather): """Format weather into a markdown section and a one-line summary.""" now = datetime.now(MT) current = weather["current"] daily = weather["daily"] condition = WMO_CODES.get(current["weather_code"], "Unknown") temp = round(current["temperature_2m"]) feels = round(current["apparent_temperature"]) wind = round(current["wind_speed_10m"]) humidity = current["relative_humidity_2m"] md = "## Weather\n\n" md += "### Current Conditions\n\n" md += "| | |\n|---|---|\n" md += f"| **Condition** | {condition} |\n" md += f"| **Temperature** | {temp}°F (feels like {feels}°F) |\n" md += f"| **Wind** | {wind} mph |\n" md += f"| **Humidity** | {humidity}% |\n\n" md += "### 7-Day Forecast\n\n" md += "| Day | Condition | High | Low | Precip | Wind |\n" md += "|-----|-----------|------|-----|--------|------|\n" for i in range(len(daily["time"])): d = datetime.strptime(daily["time"][i], "%Y-%m-%d") day_name = DAY_NAMES[d.weekday()] if i == 0: day_name = "**Today**" elif i == 1: day_name = "Tomorrow" cond = WMO_CODES.get(daily["weather_code"][i], "?") hi = round(daily["temperature_2m_max"][i]) lo = round(daily["temperature_2m_min"][i]) precip = daily["precipitation_sum"][i] wind_max = round(daily["wind_speed_10m_max"][i]) precip_str = f'{precip}"' if precip > 0 else "-" md += f"| {day_name} | {cond} | {hi}°F | {lo}°F | {precip_str} | {wind_max} mph |\n" sunrise = daily["sunrise"][0].split("T")[1] if daily["sunrise"][0] else "?" sunset = daily["sunset"][0].split("T")[1] if daily["sunset"][0] else "?" md += f"\n**Sunrise:** {sunrise} | **Sunset:** {sunset}\n" summary = f"{condition}, {temp}°F (feels like {feels}°F), wind {wind} mph" return md, summary def run(): """Run the weather agent. Returns (markdown_section, summary) or raises.""" weather = fetch_weather() section, summary = format_section(weather) log_run(AGENT_ID, "success", output=summary) return section, summary if __name__ == "__main__": try: section, summary = run() print(section) print(f"\nSummary: {summary}") except Exception as e: err_msg = f"{type(e).__name__}: {e}" print(f"Error: {err_msg}", file=sys.stderr) log_run(AGENT_ID, "failed", err=err_msg) sys.exit(1)