[FEAT] frame: --ebird-key enables the eBird fallback in BirdWeather mode (#14)

This commit is contained in:
Teddy Warner
2026-06-23 08:55:00 -07:00
committed by GitHub
parent 454c64cd77
commit f8b467e9a2
2 changed files with 18 additions and 1 deletions
+1 -1
View File
@@ -65,4 +65,4 @@ Pick how the frame gets its birds:
Each one enables SPI + I2C, installs the deps and a systemd timer, writes `~/.birdframe/config.toml`, and reboots once to bring SPI up. Full options live in [`config.example.toml`](config.example.toml). Each one enables SPI + I2C, installs the deps and a systemd timer, writes `~/.birdframe/config.toml`, and reboots once to bring SPI up. Full options live in [`config.example.toml`](config.example.toml).
BirdWeather mode renders on the Pi from this repo's illustrations on GitHub, so there is no image set to copy over. ZIP codes with no station nearby fall back to the closest ones, and an optional `EBIRD_API_KEY` covers the most remote spots. BirdWeather mode renders on the Pi from this repo's illustrations on GitHub, so there is no image set to copy over. ZIP codes with no station nearby fall back to the closest ones. If you are far from any BirdWeather station, add `--ebird-key <key>` (a free key from [ebird.org/api/keygen](https://ebird.org/api/keygen)) and the frame fills from eBird sightings instead.
+17
View File
@@ -8,6 +8,7 @@
# ./install.sh --image-url <URL> fetch a ready-made frame PNG instead # ./install.sh --image-url <URL> fetch a ready-made frame PNG instead
# (e.g. a public Cloudflare Worker) # (e.g. a public Cloudflare Worker)
# ./install.sh --bird-weather --zip <ZIP> standalone from BirdWeather, no mic # ./install.sh --bird-weather --zip <ZIP> standalone from BirdWeather, no mic
# (add --ebird-key <KEY> for remote ZIPs)
set -euo pipefail set -euo pipefail
cd "$(dirname "$0")" cd "$(dirname "$0")"
FRAME="$(pwd)" FRAME="$(pwd)"
@@ -15,6 +16,7 @@ FRAME="$(pwd)"
MODE=local # local | image | birdweather MODE=local # local | image | birdweather
ZIP="" ZIP=""
IMAGE_URL="" IMAGE_URL=""
EBIRD_KEY=""
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case "$1" in case "$1" in
--bird-weather) MODE=birdweather; shift ;; --bird-weather) MODE=birdweather; shift ;;
@@ -24,6 +26,9 @@ while [ $# -gt 0 ]; do
--image-url) [ $# -ge 2 ] || { echo "--image-url needs a URL, e.g. --image-url https://bird.example/frame.png" >&2; exit 1; } --image-url) [ $# -ge 2 ] || { echo "--image-url needs a URL, e.g. --image-url https://bird.example/frame.png" >&2; exit 1; }
MODE=image; IMAGE_URL="$2"; shift 2 ;; MODE=image; IMAGE_URL="$2"; shift 2 ;;
--image-url=*) MODE=image; IMAGE_URL="${1#*=}"; shift ;; --image-url=*) MODE=image; IMAGE_URL="${1#*=}"; shift ;;
--ebird-key) [ $# -ge 2 ] || { echo "--ebird-key needs a value (a free key from ebird.org/api/keygen)" >&2; exit 1; }
EBIRD_KEY="$2"; shift 2 ;;
--ebird-key=*) EBIRD_KEY="${1#*=}"; shift ;;
*) echo "unknown argument: $1" >&2; exit 1 ;; *) echo "unknown argument: $1" >&2; exit 1 ;;
esac esac
done done
@@ -32,6 +37,10 @@ if [ -n "$ZIP" ] && [ "$MODE" != birdweather ]; then
echo "--zip only applies with --bird-weather" >&2 echo "--zip only applies with --bird-weather" >&2
exit 1 exit 1
fi fi
if [ -n "$EBIRD_KEY" ] && [ "$MODE" != birdweather ]; then
echo "--ebird-key only applies with --bird-weather" >&2
exit 1
fi
# Validate inputs up front: a bad value would otherwise land in a config file or # Validate inputs up front: a bad value would otherwise land in a config file or
# a systemd unit verbatim. These checks also reject a flag passed as a value # a systemd unit verbatim. These checks also reject a flag passed as a value
@@ -45,6 +54,10 @@ if [ "$MODE" = birdweather ]; then
echo "--zip should look like a postal code, e.g. 94107 or SW1A 1AA" >&2 echo "--zip should look like a postal code, e.g. 94107 or SW1A 1AA" >&2
exit 1 exit 1
fi fi
if [ -n "$EBIRD_KEY" ] && ! printf '%s' "$EBIRD_KEY" | LC_ALL=C grep -qE '^[A-Za-z0-9]+$'; then
echo "--ebird-key should be the alphanumeric token from ebird.org/api/keygen" >&2
exit 1
fi
fi fi
if [ "$MODE" = image ]; then if [ "$MODE" = image ]; then
if [ -z "$IMAGE_URL" ]; then if [ -z "$IMAGE_URL" ]; then
@@ -151,6 +164,10 @@ Environment=PYTHONUNBUFFERED=1
Nice=10 Nice=10
TimeoutStartSec=300 TimeoutStartSec=300
SERVICE SERVICE
# Remote ZIPs with no nearby station fall back to eBird, which needs a key.
if [ -n "$EBIRD_KEY" ]; then
echo "Environment=EBIRD_API_KEY=$EBIRD_KEY" | sudo tee -a /etc/systemd/system/birdframe.service >/dev/null
fi
# BirdWeather's recent-species list drifts slowly, so refresh a few times a day. # BirdWeather's recent-species list drifts slowly, so refresh a few times a day.
sed 's|OnUnitActiveSec=.*|OnUnitActiveSec=6h|' systemd/birdframe.timer \ sed 's|OnUnitActiveSec=.*|OnUnitActiveSec=6h|' systemd/birdframe.timer \
| sudo tee /etc/systemd/system/birdframe.timer >/dev/null | sudo tee /etc/systemd/system/birdframe.timer >/dev/null