0.0
The project is in a healthy, maintained state
Developed by Sebastian Madrid Ontiveros. Fetch rainfall stations, 15-minute timeseries, and values from the SEPA KiWIS API. Pure Ruby, stdlib only, no native extensions or external gem dependencies. Compatible with InfoWorks ICM 2027 embedded Ruby. Built by a hydraulic modeller to support rainfall data ingestion, 1D-2D model build workflows, and flood risk assessment in the UK. If this gem saves you time, you can support development at https://buymeacoffee.com/smadrid.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies
 Project Readme

smo_sepa_kiwis

A pure-Ruby client for the SEPA Time Series KiWIS API. Fetch rainfall stations, 15-minute timeseries metadata, and timeseries values. Export everything to CSV.

Built specifically for use inside InfoWorks ICM 2027's embedded Ruby interpreter, where no gem install step is possible.

Support

This gem is free and open source. If it saves you time on a hydraulic modelling project, you can support development here:

Buy Me a Coffee QR code
buymeacoffee.com/smadrid

Why this gem

Hydraulic modellers working in InfoWorks ICM often need rainfall observations from SEPA gauges to drive 1D-2D simulations or validate model performance. Pulling that data manually through the SEPA web portal does not scale beyond a handful of stations.

This gem makes the SEPA KiWIS API directly callable from any Ruby environment, including ICM's embedded interpreter. It uses stdlib only (net/http, uri, json, csv, date, time), has no native extensions, and no Bundler runtime dependencies.

Installation

gem install smo_sepa_kiwis
require "smo_sepa_kiwis"

Quick start

require "smo_sepa_kiwis"

client = SmoSepaKiwis::Client.new
# Optional kwargs: base_url:, timeout: (default 60), user_agent:

1. List all rainfall stations

stations = client.rainfall_stations
# => Array<SmoSepaKiwis::Station>
# Station fields: no, name, lat, lon, catchment, river

2. Find 15-minute timeseries for a specific station

series = client.rainfall_15min_timeseries(station_no: "14964")
# => Array<SmoSepaKiwis::Timeseries>
# Timeseries fields: ts_id, ts_path, ts_name, station_no, coverage_from, coverage_to

3. Network-wide inventory in one call

inventory = client.rainfall_15min_inventory
# => Array<Hash> with keys:
#    :station_no, :station_name, :lat, :lon, :catchment, :river,
#    :ts_id, :ts_path, :coverage_from, :coverage_to

4. Download timeseries values

values = client.timeseries_values(
  ts_id: 55570010,
  from:  "2021-10-22",
  to:    "2021-10-25"
)
# => Array<SmoSepaKiwis::Value>
# Value fields: timestamp (Time UTC), value (Float or nil), quality_code (Integer or nil)

from and to accept String, Date, Time, or DateTime.

For long date ranges, use chunk_days to split the request into smaller windows and avoid server timeouts:

values = client.timeseries_values(
  ts_id:      55570010,
  from:       "2020-01-01",
  to:         "2021-01-01",
  chunk_days: 30
)

5. Export the full network inventory to CSV

client.rainfall_15min_inventory_to_csv("inventory.csv")

6. Export timeseries values to CSV

client.timeseries_values_to_csv(
  ts_id: 55570010,
  from:  "2021-10-22",
  to:    "2021-10-25",
  path:  "rainfall.csv"
)

Data fidelity

This gem returns SEPA fields verbatim. String fields that are blank in the API response are set to nil. Numeric fields (lat, lon, ts_id) are coerced from the string representation SEPA provides. Timestamps are parsed as ISO 8601 and converted to UTC. No values are derived, interpolated, or synthesised.

If you need British National Grid coordinates, the companion gem smo_wgs84_to_bng converts WGS84 lat/lon to BNG easting/northing.

Examples

The examples/ directory contains runnable scripts:

  • 01_list_rainfall_stations.rb: fetch all rainfall stations and save to CSV
  • 02_find_15min_timeseries.rb: list 15-min series for a given station
  • 03_download_rainfall_event.rb: download a storm event window
  • 04_bulk_export_csv.rb: full inventory plus the last 7 days of values for every station

Run any of them with:

ruby -Ilib examples/01_list_rainfall_stations.rb

Compatibility

  • Ruby 3.2 and above
  • Tested with InfoWorks ICM 2027 embedded Ruby (3.4.6)
  • No external runtime dependencies

Author

Sebastian Madrid Ontiveros, Senior Hydraulic Modeller (Edinburgh, UK). GitHub: Sebasmadridmx

Support this work

If this gem saves you time on a hydraulic modelling project, consider buying me a coffee:

Buy Me a Coffee QR code
buymeacoffee.com/smadrid

License

MIT. Copyright (c) 2026 Sebastian Madrid Ontiveros.