SkillAgentSearch skills...

Kidsweather

Generates kid-friendly weather forecasts suitable for display on a large monitor. Uses OpenWeatherMap and a local or hosted LLM.

Install / Use

/learn @elidickinson/Kidsweather
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Kid-Friendly Weather Description Service

A Python service that generates natural, kid-friendly weather descriptions using OpenWeatherMap and an LLM API (can be a small, self hosted model).

I wrote a blog post about how I use it as part of a weather eInk display:

<img src="weather-display.jpeg" alt="Large eInk weather display showing kid-friendly weather forecast" width="400">

The display is driven by a $40 single board computer and shows weather forecasts that can be easily understood.


What It Does

Transforms complex weather data into simple, engaging descriptions that kids can understand. Instead of "Partly cloudy with 70% chance of precipitation," you get "It might rain later - maybe bring an umbrella! 🌧️"

The service includes:

  • Command-line weather reports with HTML rendering
  • A shared service layer (WeatherReportService) used by every entrypoint
  • API caching for performance
  • LLM interaction logging and replay capabilities
  • Support for multiple LLM providers with automatic fallback

Requirements

  • Python 3.9+
  • uv for dependency management (recommended) or pip
  • OpenWeatherMap API key (free tier works fine)
  • LLM API key (DeepSeek, OpenAI, OpenRouter, or any OpenAI-compatible API)

Installation

  1. Install uv if you haven't already:
curl -LsSf https://astral.sh/uv/install.sh | sh
  1. Clone this repository

  2. Create and activate a virtual environment:

uv venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
  1. Install dependencies:
uv sync
# OR without uv: pip install .
  1. Copy the example environment file and configure your API keys:
cp .env.example .env
# Edit .env with your API keys

Usage

Command-Line Script

Before running these commands, make sure your .env file is properly configured with API keys as described in the Installation section.

Generate a weather report for a specific location:

uv run python -m kidsweather --lat 38.9 --lon -77.0

Load test data from a file (files live in test_data/ by default):

uv run python -m kidsweather --load dc1

Save weather data for testing (writes to test_data/ unless you supply --save with a different path):

uv run python -m kidsweather --lat 38.9 --lon -77.0 --save dc_latest

Log LLM interactions:

uv run python -m kidsweather --lat 38.9 --lon -77.0 --log-interactions

See what the model was told:

uv run python -m kidsweather --lat 38.9 --lon -77.0 --verbose

Render HTML

Render weather report as HTML to a file:

uv run python -m kidsweather --render page.html

This generates a standalone HTML file with weather information, styled for display on e-ink screens or other devices.

LLM Replay Script

Replay logged LLM interactions with different prompts or models:

uv run python replay.py --log-id 5
uv run python replay.py --log-id 5 --new-model deepseek-coder
uv run python replay.py --log-id 5 --prompt "You are a pirate weather forecaster."

Example Output

{
  "description": "It's cool right now, maybe wear a light jacket. 🧥 The rest of the day looks cloudy but nice!",
  "daily_forecasts": [
    "Monday: Cloudy day ☁️",
    "Tuesday: Rain coming later 🌧️",
    "Wednesday: Still rainy",
    "Thursday: Cloudy again"
  ],
  "temperature": 47,
  "feels_like": 44,
  "conditions": "overcast clouds",
  "high_temp": 59,
  "low_temp": 47,
  "icon_url": "http://openweathermap.org/img/wn/04d@4x.png",
  "alerts": [],
  "last_updated": "Friday, April 11 at 11:30 AM"
}

API Keys

  1. OpenWeatherMap: Get a free API key at https://openweathermap.org/api
  2. LLM Provider: Choose from DeepSeek, OpenAI, OpenRouter, or any OpenAI-compatible API

Architecture Overview

The project is organized as a Python package with a clear separation of concerns:

  • Core (kidsweather/core/): Contains the main service orchestration and settings management
    • settings.py: Loads environment variables into a single dataclass tree and ensures required directories exist
    • service.py: The WeatherReportService orchestrates data fetch, formatting, LLM generation, and logging
  • Clients (kidsweather/clients/): External API integration layers
    • weather_client.py: Fetches current conditions and optional historical summaries from OpenWeatherMap, applying diskcache when configured
    • llm_client.py: Wraps the primary and optional fallback LLM providers, normalising JSON responses and caching successful calls
  • Formatting (kidsweather/formatting/): Data preparation and output generation
    • weather_formatter.py: Prepares both the LLM prompt context and the data needed for display
    • html.py: Contains render_to_file() function for HTML rendering using Jinja2 templates for e-ink displays
  • Infrastructure (kidsweather/infrastructure/): Cross-cutting concerns
    • cache_provider.py: Cache construction and management utilities
    • llm_logging.py: Persists LLM interactions to SQLite for replay and debugging
  • Templates (kidsweather/templates/): Jinja2 templates for HTML rendering
  • Tests (kidsweather/tests/): Unit and integration tests

The main CLI entry point is kidsweather/__main__.py, which delegates to the Click-based command interface in main.py.

Technical Notes

  • Uses OpenWeatherMap's One Call API 3.0
  • Supports any OpenAI-compatible chat completions API
  • Configuration lives in kidsweather/core/settings.py and is shared across every entrypoint
  • Temperatures are in Fahrenheit
  • Caches API and LLM responses for 10 minutes using diskcache
  • Logs LLM interactions to llm_log.sqlite3 for replay
  • Includes optional automatic fallback between LLM providers
  • HTML rendering uses Jinja2 templates from kidsweather/templates/
  • Organized package structure with clear separation of concerns

Related Skills

View on GitHub
GitHub Stars11
CategoryDevelopment
Updated4mo ago
Forks0

Languages

Python

Security Score

72/100

Audited on Nov 10, 2025

No findings