Files
weather-station/server/src/spec.mjs
2026-06-27 18:31:44 -04:00

162 lines
9.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export const spec = {
openapi: '3.0.0',
info: {
title: 'Weather Station',
version: '1.0.0',
description: 'Hyperlocal weather station — sensor data, forecasts, celestial & space weather',
},
servers: [{ url: 'http://localhost:3000' }],
paths: {
'/api/position': {
get: {
summary: 'Station position',
description: 'Latest GPS position and altitude',
responses: {
200: {
description: 'Last known position',
content: { 'application/json': { schema: { $ref: '#/components/schemas/Position' } } }
}
}
}
},
'/api/current': {
get: {
summary: 'Current conditions',
description: 'Latest reading of all metrics — sensor, forecast, celestial & space weather merged into a single flat object',
parameters: [
{ name: 'fields', in: 'query', required: false, schema: { type: 'string' },
description: 'Comma-separated list of fields to return. Omit for all.' }
],
responses: {
200: {
description: 'Current conditions',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataRow' } } }
}
}
}
},
'/api/hourly': {
get: {
summary: 'Hourly data',
description: 'Hourly aggregated sensor data merged with Open-Meteo hourly forecast, celestial positions and space weather. Defaults to today.',
parameters: [
{ name: 'start', in: 'query', required: false, schema: { type: 'string', format: 'date-time' },
description: 'ISO8601 start timestamp. Defaults to today 00:00.' },
{ name: 'end', in: 'query', required: false, schema: { type: 'string', format: 'date-time' },
description: 'ISO8601 end timestamp. Defaults to now.' },
{ name: 'fields', in: 'query', required: false, schema: { type: 'string' },
description: 'Comma-separated list of fields to return. Omit for all.' },
],
responses: {
200: {
description: 'Array of hourly rows',
content: { 'application/json': { schema: { type: 'array', items: { $ref: '#/components/schemas/DataRow' } } } }
}
}
}
},
'/api/daily': {
get: {
summary: 'Daily data',
description: 'Daily aggregated sensor data (mean/min/max) merged with Open-Meteo daily forecast and celestial events. Defaults to today.',
parameters: [
{ name: 'start', in: 'query', required: false, schema: { type: 'string', format: 'date-time' },
description: 'ISO8601 start timestamp. Defaults to today 00:00.' },
{ name: 'end', in: 'query', required: false, schema: { type: 'string', format: 'date-time' },
description: 'ISO8601 end timestamp. Defaults to now.' },
{ name: 'fields', in: 'query', required: false, schema: { type: 'string' },
description: 'Comma-separated list of fields to return. Omit for all.' },
],
responses: {
200: {
description: 'Array of daily rows',
content: { 'application/json': { schema: { type: 'array', items: { $ref: '#/components/schemas/DataRow' } } } }
}
}
}
},
},
components: {
schemas: {
Position: {
type: 'object',
properties: {
latitude: { type: 'number', description: 'Latitude (°)' },
longitude: { type: 'number', description: 'Longitude (°)' },
altitude: { type: 'number', description: 'Altitude (m)' },
}
},
DataRow: {
type: 'object',
properties: {
time: { type: 'string', format: 'date-time', description: 'ISO8601 timestamp' },
// Environment
temperature: { type: 'number', description: 'Temperature (°C)' },
env_temp_min_c: { type: 'number', description: 'Daily min temperature (°C)' },
env_temp_max_c: { type: 'number', description: 'Daily max temperature (°C)' },
humidity: { type: 'number', description: 'Relative humidity (%)' },
humidity_abs: { type: 'number', description: 'Absolute humidity (g/m³)' },
dew_point: { type: 'number', description: 'Dew point (°C)' },
heat_index: { type: 'number', description: 'Feels like / heat index (°C)' },
vapor_pressure_deficit: { type: 'number', description: 'Vapour pressure deficit (kPa)' },
pressure_hpa: { type: 'number', description: 'Station pressure (hPa)' },
pressure_slp: { type: 'number', description: 'Sea level pressure (hPa)' },
pressure_rate: { type: 'number', description: 'Pressure change rate (hPa/hr)' },
pressure_trend: { type: 'string', enum: ['Rising','Falling','Stable'], description: 'Pressure trend label' },
frost_risk: { type: 'string', enum: ['None','Low','Moderate','High'], description: 'Frost risk level' },
air_quality: { type: 'number', description: 'Air quality index score (0100)' },
air_quality_label: { type: 'string', enum: ['Excellent','Good','Fair','Poor','Very Poor'] },
// Light & Solar
lux: { type: 'number', description: 'Illuminance (lux)' },
uv_index: { type: 'number', description: 'UV index' },
uv_index_max: { type: 'number', description: 'Daily max UV index' },
uv_dose: { type: 'number', description: 'Accumulated UV dose today (mJ/cm²)' },
solar_wm2: { type: 'number', description: 'Solar irradiance (W/m²)' },
daily_light_integral: { type: 'number', description: 'Daily light integral (mol/m²/day)' },
clouds: { type: 'number', description: 'Cloud cover fraction (01)' },
visibility: { type: 'number', description: 'Estimated visibility (km)' },
daylight: { type: 'number', description: 'Hours of daylight' },
// Weather
label: { type: 'string', description: 'Human readable weather label' },
icon: { type: 'string', description: 'OWM icon code e.g. 01d' },
raining: { type: 'string', enum: ['True','False'] },
precipitation: { type: 'number', description: 'Precipitation (mm)' },
precipitation_chance: { type: 'number', description: 'Precipitation probability (%)' },
accumulation: { type: 'number', description: 'Accumulated precipitation (mm)' },
storm_trend: { type: 'number', description: '1=worsening, 0=stable, -1=improving' },
// Wind
wind_speed: { type: 'number', description: 'Wind speed (km/h)' },
wind_gusts: { type: 'number', description: 'Wind gusts (km/h)' },
wind_direction: { type: 'number', description: 'Wind direction (°)' },
// Lightning
lightning_rate: { type: 'number', description: 'Strike rate (strikes/hr)' },
lightning_distance: { type: 'number', description: 'Lightning strike distance (km)' },
// Sun
sun_elevation: { type: 'number', description: 'Solar elevation angle (°)' },
sun_azimuth: { type: 'number', description: 'Solar azimuth (°)' },
sunrise: { type: 'string', format: 'date-time', description: 'Sunrise time' },
sunset: { type: 'string', format: 'date-time', description: 'Sunset time' },
daytime: { type: 'boolean', description: 'True if between sunrise and sunset' },
// Moon
moon_phase: { type: 'string', description: 'Moon phase name' },
moon_illumination: { type: 'number', description: 'Moon illumination (%)' },
moon_elevation: { type: 'number', description: 'Moon elevation (°)' },
moon_azimuth: { type: 'number', description: 'Moon azimuth (°)' },
moonrise: { type: 'string', format: 'date-time', description: 'Moonrise time' },
moonset: { type: 'string', format: 'date-time', description: 'Moonset time' },
moon_new: { type: 'string', format: 'date-time', description: 'Next new moon' },
moon_full: { type: 'string', format: 'date-time', description: 'Next full moon' },
// Seismic
seismic_magnitude: { type: 'number', description: 'Peak seismic magnitude (g)' },
// Ground
ground_distance: { type: 'number', description: 'LIDAR ground distance (cm)' },
// GPS
latitude: { type: 'number', description: 'Latitude (°)' },
longitude: { type: 'number', description: 'Longitude (°)' },
altitude: { type: 'number', description: 'Altitude (m)' },
}
}
}
}
}