From 5810ab01947161847dbf94fb07b0c980edaf61b3 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 29 Apr 2026 18:55:59 +0000 Subject: [PATCH] Trim weather-tag vocabulary to audio-relevant precipitation only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drops clear/cloudy/fog/windy and the wind-speed override — those conditions sound the same on the recordings, so they don't earn a tag. Also renames "rainshower" → "rainstorm" and rebalances the rain mapping so 503/504/522 (extreme + heavy showers) get the storm tag. Final vocabulary: thunderstorm, rain, rainstorm, snow, snowstorm. Anything else falls through to the un-tagged filename. --- sky-cam.conf | 7 ++++--- weather-tag.sh | 51 +++++++++++++++++++------------------------------- 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/sky-cam.conf b/sky-cam.conf index 550b21c..f4d6dea 100644 --- a/sky-cam.conf +++ b/sky-cam.conf @@ -184,9 +184,10 @@ TIMEZONE="${TIMEZONE:-America/New_York}" # That way each chunk is labelled with what was happening DURING that chunk — # a foggy dawn won't mislabel the sunny afternoon files. # -# Tag vocabulary (fixed set — anything else → no tag): -# thunderstorm rain rainshower snow snowstorm -# fog windy cloudy clear +# Tag vocabulary (fixed set — only conditions that change the audio): +# thunderstorm rain rainstorm snow snowstorm +# Clear / cloudy / fog / wind sound the same on the recordings, so those +# conditions fall through to the un-tagged filename. # # Setup: # 1. Get a free API key: https://openweathermap.org/api diff --git a/weather-tag.sh b/weather-tag.sh index e113459..4ea3a83 100755 --- a/weather-tag.sh +++ b/weather-tag.sh @@ -3,8 +3,11 @@ # (LATITUDE, LONGITUDE), using the OpenWeather "Current weather" endpoint. # # Output: a single lowercase word from this fixed vocabulary, or empty: -# thunderstorm rain rainshower snow snowstorm -# fog windy cloudy clear +# thunderstorm rain rainstorm snow snowstorm +# +# Only conditions that change the audio character get a tag. Cloud, fog, +# clear, and wind sound essentially the same on the recordings, so they fall +# through to the un-tagged filename. # # Used by ambient-record.sh to suffix each 30-minute chunk's filename so the # file collection self-documents what the audio actually captured. @@ -20,7 +23,7 @@ # 3. Confirm LATITUDE / LONGITUDE are set in .env (already needed by sunrise.py) # 4. Flip WEATHER_ENABLED=true in sky-cam.conf # -# Manual test: ./weather-tag.sh (prints e.g. "cloudy" or nothing) +# Manual test: ./weather-tag.sh (prints e.g. "rain" or nothing) set -uo pipefail # NOT -e: we want to swallow every failure into "no tag" @@ -39,49 +42,33 @@ url="https://api.openweathermap.org/data/2.5/weather?lat=${LATITUDE}&lon=${LONGI resp=$(curl -s --connect-timeout 5 --max-time 8 "$url" 2>/dev/null) || exit 0 [ -n "$resp" ] || exit 0 -# ── Parse condition ID + wind speed ────────────────────────────────────────── +# ── Parse primary condition ID ─────────────────────────────────────────────── # Condition codes: https://openweathermap.org/weather-conditions # OpenWeather may return multiple entries in weather[]; the first is primary. if command -v jq >/dev/null 2>&1; then code=$(echo "$resp" | jq -r '.weather[0].id // empty' 2>/dev/null) - wind=$(echo "$resp" | jq -r '.wind.speed // 0' 2>/dev/null) else # Fallback parser if jq is missing — grabs the first "id":NNN it sees. code=$(echo "$resp" | grep -oE '"id":[0-9]+' | head -n1 | grep -oE '[0-9]+') - wind=$(echo "$resp" | grep -oE '"speed":[0-9.]+' | head -n1 | grep -oE '[0-9.]+') fi - [ -n "${code:-}" ] || exit 0 -wind="${wind:-0}" # ── Map condition code → tag (vocabulary documented at top of file) ────────── -# Group ranges follow OpenWeather's published condition-code table: -# 2xx thunder / 3xx drizzle / 5xx rain / 6xx snow / 7xx atmosphere / 800 clear / 80x clouds +# Only audio-relevant precipitation gets a tag. Group ranges follow +# OpenWeather's published condition-code table: +# 2xx thunder / 3xx drizzle / 5xx rain / 6xx snow +# All other groups (7xx atmosphere, 8xx clouds/clear) → no tag. tag="" case "$code" in - 2*) tag="thunderstorm" ;; - 3*) tag="rainshower" ;; # drizzle = light shower - 500|520|521|522|531) tag="rainshower" ;; # light / shower variants - 501|502|503|504|511) tag="rain" ;; # moderate → extreme + freezing - 600|601|612|613|615|616|620|621) tag="snow" ;; - 602|622) tag="snowstorm" ;; # heavy snow / heavy shower snow - 611) tag="snow" ;; # sleet - 701|711|721|741|762) tag="fog" ;; # mist / smoke / haze / fog / ash - 731|751|761|771) tag="windy" ;; # dust whirls / sand / dust / squall - 781) tag="thunderstorm" ;; # tornado → reuse strongest tag - 800) tag="clear" ;; - 801) tag="clear" ;; # few clouds — still mostly clear - 802|803|804) tag="cloudy" ;; - *) tag="" ;; # unknown code → no tag + 2*) tag="thunderstorm" ;; + 781) tag="thunderstorm" ;; # tornado → strongest tag + 3*) tag="rain" ;; # drizzle + 500|501|502|511|520|521|531) tag="rain" ;; # light → heavy + freezing + showers + 503|504|522) tag="rainstorm" ;; # very heavy / extreme / heavy shower + 600|601|611|612|613|615|616|620|621) tag="snow" ;; # light → moderate + sleet variants + 602|622) tag="snowstorm" ;; # heavy snow / heavy shower snow + *) tag="" ;; # everything else → no tag esac -# Wind override: gusty conditions drown out other audio cues. If the base -# tag is clear/cloudy and wind ≥ 8 m/s (~18 mph), promote to "windy". -if [ "$tag" = "clear" ] || [ "$tag" = "cloudy" ]; then - # bash can't compare floats — strip the decimal for an integer check. - wind_int="${wind%.*}" - [ "${wind_int:-0}" -ge 8 ] 2>/dev/null && tag="windy" -fi - [ -n "$tag" ] && printf '%s' "$tag" exit 0