Schedule

birdpal runs and exits, so each schedule is a oneshot service plus a timer. A timer never starts a run while the last one is still going, output goes to the journal, and Persistent=true makes up for runs missed while the machine was off.

The .deb and .rpm packages install these user units in /usr/lib/systemd/user/:

Unit Schedule Command Typical run
birdpal.timer Hourly --sync --tags (new media only) 5 to 10 seconds with nothing new
birdpal-full.timer Sunday 03:30 --sync --update --full --tags about 1 minute for 1,500 media

Turn it on

1. Put your settings in ~/.config/birdpal/birdpal.env, then edit the file (see Usage):

mkdir -p ~/.config/birdpal
install -m 600 /usr/share/doc/birdpal/birdpal.env.example ~/.config/birdpal/birdpal.env

2. Add your coordinates if you want the media on Immich's map. This opens an editor with a copy of the unit; add --gps LAT,LON to ExecStart, and do the same for birdpal-full.service:

systemctl --user edit --full birdpal.service

3. Run the service once by hand and check that it ends with success:

systemctl --user start birdpal.service
systemctl --user show birdpal.service -p Result

4. Turn on the timers:

systemctl --user enable --now birdpal.timer birdpal-full.timer

5. Turn on lingering, once per machine. Without it, user timers only run while you are logged in:

sudo loginctl enable-linger $USER

The units

birdpal.service:

[Unit]
Description=birdpal: sync new Bird Buddy media into Immich
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
EnvironmentFile=%h/.config/birdpal/birdpal.env
ExecStart=/usr/bin/birdpal --sync --tags
TimeoutStartSec=30min
Nice=10

birdpal.timer:

[Unit]
Description=Run birdpal hourly (new media only)

[Timer]
OnCalendar=hourly
RandomizedDelaySec=5min
Persistent=true

[Install]
WantedBy=timers.target

birdpal-full.service is the same as birdpal.service with ExecStart=/usr/bin/birdpal --sync --update --full --tags. birdpal-full.timer uses OnCalendar=Sun *-*-* 03:30:00.

Without a package, copy the four files from packaging/systemd/ in the .tar.gz to ~/.config/systemd/user/ and run systemctl --user daemon-reload.

Change the time

Run systemctl --user edit --full birdpal.timer and change OnCalendar=. Test a value before you use it:

systemd-analyze calendar --iterations=3 'Sun *-*-* 03:30:00'
OnCalendar= Runs
hourly at the start of every hour
*:0/30 every 30 minutes
*-*-* 06..22:00:00 every hour from 06:00 to 22:00
daily every day at 00:00
Sun *-*-* 03:30:00 Sundays at 03:30
Mon,Thu *-*-* 04:00:00 Mondays and Thursdays at 04:00

Check on it

systemctl --user list-timers 'birdpal*'
journalctl --user -u birdpal -u birdpal-full --since today

Cron instead

Load the variables from the file, so no secret is on the command line. Cron does not stop two runs from overlapping.

# hourly: new media only
0 * * * *  set -a && . ~/.config/birdpal/birdpal.env && set +a && birdpal --sync --tags >>~/birdpal.log 2>&1
# weekly: full refresh
30 3 * * 0 set -a && . ~/.config/birdpal/birdpal.env && set +a && birdpal --sync --update --full --tags >>~/birdpal.log 2>&1