The forecast engine
Point @azohra/meteo.forecast at your launches and it publishes the forecasts: it fetches each model's newest run, derives the soaring numbers for every site in your catalogue, and writes plain JSON files wherever you host them — on a schedule you own, with one CLI.
Below is one of its runs — an HRDPS forecast for three sites. Browse any file in it.
data-sample/runs.json · 170 B · the whole file
{
"schemaVersion": 1,
"runs": {
"hrdps-continental": {
"referenceTime": "2026-08-12T12:00:00Z",
"generatedAt": "2026-08-12T18:22:29.601Z"
}
}
}meteo forecast runs-indexThe published dataset
Point the engine at a site catalogue and an output directory, and this tree is what lands there. This one is an HRDPS continental run over three test sites, served at meteo.azohra.com/data-sample/ — curl any path in it.
meteo.azohra.com/data-sample/
- data-sample/
- models.json10.1 kBthe model catalogue: grid, cadence, horizon, capabilities, sunset dates
- runs.json170 Bthe newest run per model — printed whole above
- sites.json530 Bthe site catalogue this run was built from
- site-context.json5.5 kBmeasured terrain per site: elevation, slope, aspect, relief, land cover — sources named
- hrdps-continental/
- manifest.json556 Bthis run: reference time, hours, sites, and what the build cost
- sites/
- test-hill.json10.7 kBone site document — excerpted at right
- test-ridge.json7.7 kB
- test-valley.json12.6 kB
- history/
- test-hill/2026-08.jsonl.gz2.0 kBappend-only month archive: one gzip member per published run
- test-hill/2026-08.index.json273 Bsidecar index: byte offset and length per member
- test-ridge/2026-08.jsonl.gz1.6 kB
- test-ridge/2026-08.index.json273 B
- test-valley/2026-08.jsonl.gz2.3 kB
- test-valley/2026-08.index.json273 B
hrdps-continental/sites/test-hill.json · excerpt, pretty-printed
{
"schemaVersion": 2,
"model": "hrdps-continental",
"run": {
"referenceTime": "2026-08-12T12:00:00Z",
"generatedAt": "2026-08-12T18:22:29Z"
},
"site": {
"id": "test-hill",
"name": "Test Hill",
"latitude": 49.4581,
"longitude": -117.3956,
"modelElevationM": 1180.8,
"timeZone": "America/Vancouver"
},
"semantics": {
"gust": "hourMax",
"precipitation": "windowMeanRate"
},
"hours": [
… 7 earlier hours …
{
"validAt": "2026-08-12T20:00:00Z",
"surface": { … 12 surface quantities … },
"levels": [ … 7 pressure levels, 875–600 hPa … ],
"derived": {
"boundaryLayerTopM": 2136.9,
"thermalVelocityMps": 1.8,
"cloudBaseM": 2362.8,
"usableLiftTopM": 2362.8
}
}
]
}thermalVelocityMps goes 0 →1.8 and usableLiftTopM goesnull → 2362.8 — derived by the engine from the sampled fields. The equations behind every derived quantity are in Meteogram derivations. The full file: test-hill.json.The documents above total 54.6 kB. manifest.stats records what building them cost the engine: 717 provider downloads, 1.44 GB fetched,106 s, 28 retries.
From model cycle to browser
.idx-indexed byte ranges; ECCC models stream one whole-domain file at a time, sampled in memory and discarded. The reference is Provider transports.The CLI
Installing the package puts the meteo binary on your path. Six commands: meteo forecast <build|migrate|terrain|runs-index|freshness|catalogue>.
a first build
$ pnpm add @azohra/meteo.forecast
# plan it first: prints what it would build, fetches and writes nothing
$ pnpm exec meteo forecast build --model hrdps-continental \
--sites ./sites.json --output ./public/data --dry-runthe build behind the dataset above
$ pnpm --dir forecast build
$ node forecast/dist/cli.js forecast build --model hrdps-continental \
--sites scenarios/catalog/sites.json \
--output site/public/data-sample --max-steps 8Drop --dry-run and the engine fetches the newest complete run and writes the tree shown above. --max-steps 8 is what holds the dataset above to eight of the model's 48 hourly steps.
Engine, not instance
The engine is a package, not a hosted service. A running instance — the cron schedule that triggers builds, the site catalogue it builds from, the bucket the documents land in and its credentials — is yours to own; none of it ships in the package. acrophobia.ca runs the reference instance. To stand up your own, Run one model walks the first build end to end; the engine's reference is the forecast documentation.