refactor part 1

This commit is contained in:
2026-06-23 22:17:01 -04:00
parent 214cf50908
commit d5bb7ff24f
18 changed files with 508 additions and 398 deletions

View File

@@ -7,6 +7,19 @@ export const spec = {
},
servers: [{ url: 'http://localhost:3000' }],
paths: {
'/api/position': {
get: {
summary: 'Station position',
description: 'Latest GPS position and info',
parameters: [ ],
responses: {
200: {
description: 'Last known position',
content: { 'application/json': { schema: { $ref: '#/components/schemas/DataRow' } } }
}
}
}
},
'/api/data': {
get: {
summary: 'Current conditions',
@@ -66,41 +79,49 @@ export const spec = {
},
components: {
schemas: {
Position: {
type: 'object',
properties: {
lat: { type: 'number', description: 'Latitude' },
lon: { type: 'number', description: 'Longitude' },
alt: { type: 'number', description: 'Altitude' },
}
},
DataRow: {
type: 'object',
properties: {
time: { type: 'string', description: 'ISO8601 timestamp or date' },
// Environment
env_temp_c: { type: 'number', description: 'Temperature (°C)' },
temperature: { type: 'number', description: 'Temperature (°C)' },
env_temp_f: { type: 'number', description: 'Temperature (°F)' },
env_temp_min_c: { type: 'number', description: 'Daily min temperature (°C)' },
env_temp_max_c: { type: 'number', description: 'Daily max temperature (°C)' },
env_humidity: { type: 'number', description: 'Relative humidity (%)' },
env_dew_point_c: { type: 'number', description: 'Dew point (°C)' },
env_heat_index_c: { type: 'number', description: 'Feels like / heat index (°C)' },
env_pressure_hpa: { type: 'number', description: 'Station pressure (hPa)' },
env_pressure_slp: { type: 'number', description: 'Sea level pressure (hPa)' },
env_pressure_rate: { type: 'number', description: 'Pressure change rate (hPa/hr)' },
env_pressure_trend: { type: 'string', enum: ['Rising','Falling','Stable'], description: 'Pressure trend label' },
env_abs_humidity: { type: 'number', description: 'Absolute humidity (g/m³)' },
env_vpd_kpa: { type: 'number', description: 'Vapour pressure deficit (kPa)' },
env_gas_ohms: { type: 'number', description: 'BME680 gas resistance (Ω)' },
env_aqi_score: { type: 'number', description: 'Air quality index score (0100)' },
env_aqi_label: { type: 'string', enum: ['Excellent','Good','Fair','Poor','Very Poor'] },
env_frost_risk: { type: 'string', enum: ['None','Low','Moderate','High'] },
humidity: { type: 'number', description: 'Relative humidity (%)' },
dew_point: { type: 'number', description: 'Dew point (°C)' },
heat_index: { type: 'number', description: 'Feels like / heat index (°C)' },
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' },
humidity_abs: { type: 'number', description: 'Absolute humidity (g/m³)' },
vapor_pressure_deficit: { type: 'number', description: 'Vapour pressure deficit (kPa)' },
air_quality_ohms: { type: 'number', description: 'BME680 gas resistance (Ω)' },
air_quality: { type: 'number', description: 'Air quality index score (0100)' },
air_quality_label: { type: 'string', enum: ['Excellent','Good','Fair','Poor','Very Poor'] },
frost_risk: { type: 'string', enum: ['None','Low','Moderate','High'] },
// Light
light_lux: { type: 'number', description: 'Illuminance (lux)' },
light_uvi: { type: 'number', description: 'UV index' },
light_solar_wm2: { type: 'number', description: 'Solar irradiance (W/m²)' },
light_uv_dose_mj: { type: 'number', description: 'Accumulated UV dose today (mJ/cm²)' },
lux: { type: 'number', description: 'Illuminance (lux)' },
uv_index: { type: 'number', description: 'UV index' },
solar_wm2: { type: 'number', description: 'Solar irradiance (W/m²)' },
uv_dose: { type: 'number', description: 'Accumulated UV dose today (mJ/cm²)' },
light_burn_time_min: { type: 'number', description: 'Time to sunburn skin type 2 (min)' },
light_cloud_pct: { type: 'number', description: 'Estimated cloud cover (%)' },
clouds: { type: 'number', description: 'Estimated cloud cover (%)' },
light_cloud_label: { type: 'string', enum: ['Clear','Partly Cloudy','Mostly Cloudy','Overcast'] },
light_dli: { type: 'number', description: 'Daily light integral (mol/m²/day)' },
light_daylight_hours: { type: 'number', description: 'Hours above daylight threshold today' },
light_visibility_km: { type: 'number', description: 'Estimated visibility (km)' },
light_uvi_max: { type: 'number', description: 'Daily max UV index' },
light_solar_wm2_sum: { type: 'number', description: 'Daily solar radiation sum (MJ/m²)' },
daylight: { type: 'number', description: 'Hours above daylight threshold today' },
visibility: { type: 'number', description: 'Estimated visibility (km)' },
uv_index_max: { type: 'number', description: 'Daily max UV index' },
solar_wm2_sum: { type: 'number', description: 'Daily solar radiation sum (MJ/m²)' },
// Wind (Open-Meteo)
wind_speed_kmh: { type: 'number', description: 'Wind speed (km/h)' },
wind_direction_deg: { type: 'number', description: 'Wind direction (°)' },
@@ -129,22 +150,22 @@ export const spec = {
compass_y: { type: 'number' },
compass_z: { type: 'number' },
// Ground / Accumulation
ground_distance_cm: { type: 'number', description: 'LIDAR ground distance (cm)' },
ground_lidar_strength: { type: 'number', description: 'LIDAR signal strength' },
ground_calibrated_baseline_cm: { type: 'number', description: 'Calibrated baseline distance (cm)' },
ground_accumulation_depth_cm: { type: 'number', description: 'Snow/flood depth (cm)' },
ground_distance: { type: 'number', description: 'LIDAR ground distance (cm)' },
lidar_strength: { type: 'number', description: 'LIDAR signal strength' },
ground_calibration: { type: 'number', description: 'Calibrated baseline distance (cm)' },
accumulation: { type: 'number', description: 'Snow/flood depth (cm)' },
ground_accumulation_type: { type: 'string', enum: ['snow','slush','ice','flood'], description: 'Accumulation type' },
// Lightning
lightning_distance_km: { type: 'number', description: 'Lightning strike distance (km)' },
lightning_distance: { type: 'number', description: 'Lightning strike distance (km)' },
lightning_energy: { type: 'number', description: 'Lightning energy' },
lightning_strikes_per_hour: { type: 'number', description: 'Strike rate (strikes/hr)' },
lightning_storm_trend: { type: 'string', enum: ['Approaching','Retreating','Stationary'] },
storm_direction: { type: 'string', enum: ['Approaching','Retreating','Stationary'] },
lightning_false_positive: { type: 'number', description: '1 if disturber/false positive' },
lightning_detector_sensitivity:{ type: 'number', description: 'AS3935 noise floor setting (07)' },
// GPS
gps_lat: { type: 'number', description: 'Latitude (°)' },
gps_lon: { type: 'number', description: 'Longitude (°)' },
gps_alt_m: { type: 'number', description: 'Altitude (m)' },
latitude: { type: 'number', description: 'Latitude (°)' },
longitude: { type: 'number', description: 'Longitude (°)' },
altitude: { type: 'number', description: 'Altitude (m)' },
gps_satellites: { type: 'number', description: 'Satellites in view' },
gps_speed_kmh: { type: 'number', description: 'Ground speed (km/h)' },
gps_heading: { type: 'number', description: 'GPS heading (°)' },