Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🏄 SurfCast AI

Local-first, open-source surf condition forecasting powered by LightGBM and free marine APIs.

SurfCast AI downloads free weather, wave and tide data, trains a machine-learning model on your machine, and predicts surf quality for any beach you configure — all without a paid API key or cloud service.


⚠️ Disclaimer

SurfCast AI is an experimental hobby project. Surf-quality predictions are based on synthetic physics-derived labels, not verified surf reports. Never rely on this tool for safety decisions in the ocean. Always check official forecasts, know your limits, and surf with others.


Features

  • Free data only — Open-Meteo (weather + marine), NOAA CO-OPS (US tides), harmonic model (global tides)
  • Aggressive local caching — minimal network requests; continues working offline with cached data
  • LightGBM baseline — fast, interpretable gradient-boosting regressor
  • Walk-forward backtesting — chronological splits only, no data leakage
  • Feature explanations — top positive and negative factors per prediction
  • Polished TUI — seven-screen Textual application (Home, Forecast, Benchmark, Data Sync, Beaches, Model, Settings)
  • CLI — sync, train, predict, benchmark, list/add beaches
  • Local-first — all data stored in DuckDB under ~/.local/share/surfcast/
  • XDG-compliant paths for config, data and cache

Installation

# 1. Clone
git clone https://github.com/danh2011/surfcast.git
cd surfcast

# 2. Install
pip install -e .

---

## Quick Start

```bash
# 1. Copy and customise the example configuration
cp config.example.toml ~/.config/surfcast/config.toml
$EDITOR ~/.config/surfcast/config.toml

# 2. Download data (90 days by default)
surfcast sync-data

# 3. Train the model
surfcast train

# 4. Predict surf quality
surfcast predict "Pipeline, Oahu" --date 2024-06-15 --hour 8

# 5. Launch the interactive TUI
surfcast tui

Configuration

Config lives at ~/.config/surfcast/config.toml (created automatically on first run).

[general]
cache_ttl_hours = 6    # how long to trust cached HTTP responses
history_days    = 90   # how many days of history to download
log_level       = "INFO"

[model]
num_leaves        = 63
learning_rate     = 0.05
n_estimators      = 500
min_child_samples = 20

[[beaches]]
name        = "Pipeline, Oahu"
lat         = 21.6647
lon         = -158.0492
orientation = 350          # degrees the beach faces (0=N, 90=E …)
exposure    = 5            # 1 (sheltered) – 5 (open ocean)
country     = "US"
timezone    = "Pacific/Honolulu"
# noaa_station = "1612340" # optional: NOAA station ID for US tides

Orientation tip: set this to the compass direction waves come from to reach the beach. A west-facing beach that receives westerly swells would be 270.


Data Sources

Source Data Key
Open-Meteo Archive Historical weather None
Open-Meteo Forecast 7-day weather forecast None
Open-Meteo Marine Wave height, period, swell None
NOAA CO-OPS US tide predictions None
Harmonic model (built-in) Global tide approximation None

All data is cached to disk under ~/.cache/surfcast/http/.


CLI Usage

# Sync all beaches (uses config history_days)
surfcast sync-data

# Sync a specific beach for 60 days
surfcast sync-data --beach "Bells Beach, Victoria" --days 60

# Train on all beaches
surfcast train

# Train on one beach, custom window
surfcast train --beach "Fistral Beach, Newquay" --days 45

# Predict surf quality
surfcast predict "Pipeline, Oahu"
surfcast predict "Bells Beach, Victoria" --date 2024-12-01 --hour 6

# Backtest over 60 days
surfcast benchmark "Pipeline, Oahu" --days 60

# Manage beaches
surfcast list-beaches
surfcast add-beach

# Launch TUI
surfcast tui

# Show version
surfcast --version

TUI Usage

Launch with surfcast tui. Navigate using the sidebar or keyboard shortcuts 17.

Key Screen
1 🏠 Home – dashboard and status
2 🏄 Forecast – pick beach / time, run prediction
3 📊 Benchmark – configure and run backtests
4 🔄 Data Sync – download data, view cache status
5 🏖️ Beaches – browse and add beaches
6 🤖 Model – training info and feature importances
7 ⚙️ Settings – config values and paths
q Quit

Benchmarking

SurfCast uses walk-forward (expanding-window) backtesting — the training window grows forward in time, and each test fold evaluates only on future data the model has never seen. This prevents data leakage.

Train ─────────────────────────▶ Test ────
         Fold 1                 ▶ Fold 2
              Fold 2            ▶ Fold 3
                   Fold 3       ▶ Fold 4

Reported metrics:

Metric Description
MAE Mean Absolute Error (score units, 0–10)
RMSE Root Mean Squared Error
Band Accuracy % predictions in the correct quality band (Flat / Poor / Fair / Good / Epic)

All benchmark runs are saved to the local DuckDB database.


Project Structure

surfcast/
├── config.example.toml          # Copy to ~/.config/surfcast/config.toml
├── pyproject.toml
├── README.md
├── src/surfcast/
│   ├── __init__.py
│   ├── cli.py                   # Click CLI entry point
│   ├── config.py                # TOML config loader
│   ├── database.py              # DuckDB schema & CRUD
│   ├── data/
│   │   ├── fetcher.py           # Orchestrates data downloads
│   │   └── sources/
│   │       ├── open_meteo.py    # Weather + marine API client
│   │       └── tides.py         # NOAA + harmonic tide model
│   ├── features/
│   │   └── engineer.py          # Feature engineering + synthetic labels
│   ├── models/
│   │   ├── base.py              # Abstract model interface
│   │   └── lgbm_model.py        # LightGBM implementation
│   ├── benchmarking/
│   │   └── backtester.py        # Walk-forward backtester
│   ├── tui/
│   │   ├── app.py               # Textual app + navigation
│   │   └── screens/
│   │       ├── home.py
│   │       ├── forecast.py
│   │       ├── benchmark.py
│   │       ├── data_sync.py
│   │       ├── beaches.py
│   │       ├── model_status.py
│   │       └── settings.py
│   └── utils/
│       ├── paths.py             # XDG path helpers
│       └── logging_setup.py     # Structured logging
└── tests/
    ├── test_config.py
    ├── test_database.py
    ├── test_features.py
    ├── test_model.py
    ├── test_tides.py
    └── test_backtester.py

Development

# Install dev extras
pip install -e ".[dev]"

# Run tests
pytest

# Run tests with coverage
pytest --cov=surfcast --cov-report=term-missing

# Lint
ruff check src/ tests/

# Type-check
mypy src/surfcast/

Testing

The test suite covers:

  • Config loading and defaults
  • DuckDB schema, upserts and JOIN queries
  • Feature engineering (all columns present, no NaNs, cyclical bounds)
  • Physics-based surf scorer (range, flat/good conditions)
  • LightGBM train / predict / save / load round-trip
  • Harmonic tide model (count, timezone, oscillation, range)
  • Walk-forward backtester (result structure, metric sanity on synthetic data)
32 passed in 5.5 s

Roadmap

  • Real surf-report labels (Surfline open data, Magic Seaweed)
  • SHAP values for richer per-prediction explanations
  • Multi-model registry (XGBoost, MLP, ensemble)
  • Swell-window alerts (notify when score exceeds threshold)
  • Web dashboard option (FastAPI + HTMX)
  • Docker / Nix packaging
  • CI/CD with GitHub Actions

License

MIT — see LICENSE.


Acknowledgements

About

Local, ML-powered surf forecaster.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages