feat: workout-suggester, weather-aware workouts from a local Gemma

Go + Templ + HTMX app that checks the weather (Open-Meteo, MET Norway
fallback), scores run/ride/walk with plain rules, and has a local
open-weight model (Gemma 4 E2B via any OpenAI-compatible server) write
the plan. Routes are loops from your door (BRouter) plus signposted
OpenStreetMap routes (Overpass), with GPX export.
This commit is contained in:
bdeb1337 committed 2026-10-11 19:29:58 +02:00
commit d7342d6096
42 files changed
+7219

No files matched your search

+1
View File
@@ -0,0 +1 @@
{"type":"Feature","geometry":{"type":"Point","coordinates":[3.72,51.05,13]},"properties":{"meta":{"updated_at":"2026-10-11T13:19:22Z","units":{"air_pressure_at_sea_level":"hPa","air_temperature":"celsius","air_temperature_max":"celsius","air_temperature_min":"celsius","apparent_air_temperature":"celsius","cloud_area_fraction":"%","cloud_area_fraction_high":"%","cloud_area_fraction_low":"%","cloud_area_fraction_medium":"%","dew_point_temperature":"celsius","fog_area_fraction":"%","precipitation_amount":"mm","relative_humidity":"%","ultraviolet_index_clear_sky":"1","wind_from_direction":"degrees","wind_speed":"m/s"}},"timeseries":[{"time":"2026-10-11T16:00:00Z","data":{"instant":{"details":{"air_pressure_at_sea_level":1014.1,"air_temperature":13.1,"apparent_air_temperature":12.5,"cloud_area_fraction":19.5,"cloud_area_fraction_high":0.0,"cloud_area_fraction_low":19.5,"cloud_area_fraction_medium":0.0,"dew_point_temperature":6.2,"fog_area_fraction":0.0,"relative_humidity":62.8,"ultraviolet_index_clear_sky":0.1,"wind_from_direction":283.8,"wind_speed":2.3}},"next_12_hours":{"summary":{"symbol_code":"fair_night"},"details":{}},"next_1_hours":{"summary":{"symbol_code":"fair_day"},"details":{"precipitation_amount":0.0}},"next_6_hours":{"summary":{"symbol_code":"clearsky_night"},"details":{"air_temperature_max":11.1,"air_temperature_min":8.0,"precipitation_amount":0.0}}}},{"time":"2026-10-11T17:00:00Z","data":{"instant":{"details":{"air_pressure_at_sea_level":1014.6,"air_temperature":11.1,"apparent_air_temperature":10.8,"cloud_area_fraction":6.2,"cloud_area_fraction_high":0.0,"cloud_area_fraction_low":6.2,"cloud_area_fraction_medium":0.0,"dew_point_temperature":6.6,"fog_area_fraction":0.0,"relative_humidity":74.1,"ultraviolet_index_clear_sky":0.0,"wind_from_direction":263.2,"wind_speed":1.6}},"next_12_hours":{"summary":{"symbol_code":"fair_night"},"details":{}},"next_1_hours":{"summary":{"symbol_code":"clearsky_night"},"details":{"precipitation_amount":0.0}},"next_6_hours":{"summary":{"symbol_code":"clearsky_night"},"details":{"air_temperature_max":10.3,"air_temperature_min":7.8,"precipitation_amount":0.0}}}},{"time":"2026-10-11T18:00:00Z","data":{"instant":{"details":{"air_pressure_at_sea_level":1015.2,"air_temperature":10.3,"apparent_air_temperature":9.7,"cloud_area_fraction":2.3,"cloud_area_fraction_high":0.0,"cloud_area_fraction_low":2.3,"cloud_area_fraction_medium":0.0,"dew_point_temperature":6.5,"fog_area_fraction":0.0,"relative_humidity":78.3,"ultraviolet_index_clear_sky":0.0,"wind_from_direction":247.4,"wind_speed":1.7}},"next_12_hours":{"summary":{"symbol_code":"fair_night"},"details":{}},"next_1_hours":{"summary":{"symbol_code":"clearsky_night"},"details":{"precipitation_amount":0.0}},"next_6_hours":{"summary":{"symbol_code":"clearsky_night"},"details":{"air_temperature_max":9.5,"air_temperature_min":7.6,"precipitation_amount":0.0}}}},{"time":"2026-10-11T19:00:00Z","data":{"instant":{"details":{"air_pressure_at_sea_level":1015.6,"air_temperature":9.5,"apparent_air_temperature":8.8,"cloud_area_fraction":0.0,"cloud_area_fraction_high":0.0,"cloud_area_fraction_low":0.0,"cloud_area_fraction_medium":0.0,"dew_point_temperature":6.2,"fog_area_fraction":0.0,"relative_humidity":80.3,"ultraviolet_index_clear_sky":0.0,"wind_from_direction":231.5,"wind_speed":1.8}},"next_12_hours":{"summary":{"symbol_code":"fair_night"},"details":{}},"next_1_hours":{"summary":{"symbol_code":"clearsky_night"},"details":{"precipitation_amount":0.0}},"next_6_hours":{"summary":{"symbol_code":"clearsky_night"},"details":{"air_temperature_max":9.0,"air_temperature_min":7.4,"precipitation_amount":0.0}}}},{"time":"2026-10-11T20:00:00Z","data":{"instant":{"details":{"air_pressure_at_sea_level":1015.9,"air_temperature":9.0,"apparent_air_temperature":8.1,"cloud_area_fraction":4.7,"cloud_area_fraction_high":0.0,"cloud_area_fraction_low":4.7,"cloud_area_fraction_medium":0.0,"dew_point_temperature":5.9,"fog_area_fraction":0.0,"relative_humidity":81.3,"ultraviolet_index_clear_sky":0.0,"wind_from_direction":218.5,"wind_speed":1.9}},"next_12_hours":{"summary":{"symbol_code":"fair_night"},"details":{}},"next_1_hours":{"summary":{"symbol_code":"clearsky_night"},"details":{"precipitation_amount":0.0}},"next_6_hours":{"summary":{"symbol_code":"clearsky_night"},"details":{"air_temperature_max":8.3,"air_temperature_min":7.1,"precipitation_amount":0.0}}}},{"time":"2026-10-11T21:00:00Z","data":{"instant":{"details":{"air_pressure_at_sea_level":1016.4,"air_temperature":8.3,"apparent_air_temperature":7.4,"cloud_area_fraction":0.8,"cloud_area_fraction_high":0.0,"cloud_area_fraction_low":0.8,"cloud_area_fraction_medium":0.0,"dew_point_temperature":5.6,"fog_area_fraction":0.0,"relative_humidity":83.0,"ultraviolet_index_clear_sky":0.0,"wind_from_direction":204.9,"wind_speed":1.8}},"next_12_hours":{"summary":{"symbol_code":"partlycloudy_night"},"details":{}},"next_1_hours":{"summary":{"symbol_code":"clearsky_night"},"details":{"precipitation_amount":0.0}},"next_6_hoLine truncated