Skip to main content

@happyvertical/weather

Weather data provider abstraction for the HAppyVertical SDK.

Overview

The @happyvertical/weather package provides a unified interface for fetching weather forecasts from multiple providers. It follows the same architectural pattern as @happyvertical/ai, @happyvertical/files, and @happyvertical/sql.

Supported Providers

  • Environment Canada - Government weather service for Canadian locations (free)
  • OpenWeatherMap - Global weather data with free and paid tiers
    • Standard API: 5-day/3-hour forecasts (free tier)
    • One Call API 3.0: 48hr hourly + 8-day daily forecasts (paid tier)

Installation

pnpm add @happyvertical/weather

Claude Code Context

Install Claude Code context files for AI-assisted development:

npx have-weather-context

This copies the package's AGENT.md documentation and metadata.json metadata to your project's .claude/ directory, enabling Claude to provide better assistance when working with this package.

Usage

Basic Example

import { getWeatherAdapter } from '@happyvertical/weather';

// Create adapter for Environment Canada
const weather = await getWeatherAdapter({
provider: 'environment-canada'
});

// Fetch forecast for a location (latitude, longitude)
const forecasts = await weather.fetchForLocation(51.0447, -114.0719);

forecasts.forEach(forecast => {
console.log(`${forecast.timestamp}: ${forecast.temperature}°C - ${forecast.conditions}`);
});

OpenWeatherMap (Free Tier)

const weather = await getWeatherAdapter({
provider: 'openweathermap',
apiKey: process.env.OPENWEATHER_API_KEY
});

const forecasts = await weather.fetchForLocation(51.0447, -114.0719);

OpenWeatherMap One Call (Paid Tier)

const weather = await getWeatherAdapter({
provider: 'openweathermap-onecall',
apiKey: process.env.OPENWEATHER_API_KEY
});

const forecasts = await weather.fetchForLocation(51.0447, -114.0719);

Environment Variable Configuration

# .env
HAVE_WEATHER_PROVIDER=openweathermap
OPENWEATHER_API_KEY=your-api-key-here
HAVE_WEATHER_TIMEOUT=15000
// Automatically uses environment variables
const weather = await getWeatherAdapter();
const forecasts = await weather.fetchForLocation(51.0447, -114.0719);

API Reference

getWeatherAdapter(options?): Promise<IWeatherAdapter>

Factory function for creating weather adapters.

Options:

  • provider: 'environment-canada' | 'openweathermap' | 'openweathermap-onecall'
  • apiKey: API key (required for OpenWeatherMap providers)
  • timeout: Request timeout in milliseconds (default: 10000)

IWeatherAdapter

interface IWeatherAdapter {
fetchForLocation(
latitude: number,
longitude: number,
options?: FetchOptions
): Promise<WeatherForecast[]>

testConnection(): Promise<boolean>

supportsLocation(latitude: number, longitude: number): Promise<boolean>
}

WeatherForecast

interface WeatherForecast {
timestamp: Date
temperature: number // °C
feelsLike?: number // °C
temperatureMin?: number // °C
temperatureMax?: number // °C
conditions: string // Human-readable description
humidity: number // Percentage 0-100
windSpeed: number // km/h
windDirection?: number // Degrees 0-360
windGust?: number // km/h
pressure?: number // hPa
cloudCover?: number // Percentage 0-100
visibility?: number // km
precipProbability?: number // Percentage 0-100
precipAmount?: number // mm
confidence?: number // Provider's confidence 0-100
raw: any // Provider-specific raw data
}

Environment Variables

VariableTypeDescription
HAVE_WEATHER_PROVIDERstringProvider name
OPENWEATHER_API_KEYstringOpenWeatherMap API key
HAVE_WEATHER_TIMEOUTnumberRequest timeout (ms)

Provider Comparison

FeatureEnvironment CanadaOpenWeatherMapOWM One Call
CostFreeFree tier availablePaid
CoverageCanada onlyGlobalGlobal
ForecastDay/night3-hour for 5 daysHourly + daily
API KeyNot requiredRequiredRequired
Update Frequency~hourly3 hourshourly

License

MIT