A few weeks ago I wrote about building Backyard Birds, the Next.js dashboard I put on top of the BirdNET pipeline after Grafana and I gave up on each other. I ended that post saying notifications for first-time species was the obvious next thing.

I did not build notifications.
I made the whole thing available for download instead, and the work that got me there went somewhere I did not expect. It stopped being about showing the data and started being about trusting it.
It is on GitHub now
The code is up at github.com/philoking/backyard-birds. What were two separate repos in the original post, the listener and the dashboard, are now one monorepo, stitched together with git subtree so each side keeps its own commit history. There is also a third service in there that did not exist when I wrote last time. Everything still runs as Docker containers on a single host, and the database is still the only thing the services talk through. No service calls another service. They all just read and write the same TimescaleDB.
The weather service
The new service is weatherlistener. It sits on the LAN and catches the WeatherFlow Tempest hub’s token-free UDP broadcasts, writing a weather row every minute. That feeds a set of weather response curves on the Patterns tab, so I can finally line up bird activity against temperature, wind, and pressure instead of guessing.

There is a one-off backfill script that walks the Tempest cloud API backward from my earliest detection, so the history is not just from the day I turned it on.
Hearing them, not just counting them
The original dashboard could tell me a Western Tanager showed up at 5:14am. It could not let me hear the thing. Now it can. The listener saves a short padded Opus clip of recent detections, a few seconds with a little lead-in and tail, and the species page plays it back.

Next to it, the same page pulls a reference recording from xeno-canto, a clean example of what that species is supposed to sound like. So I get my actual backyard clip and the textbook version side by side. That comparison turned out to be the whole game, which leads to the part I actually care about.
Learning to doubt the data
BirdNET is good. It is not always right. The original dashboard showed me everything it heard as if it were gospel, and I had no way to push back on a bad call.

The release adds a Flagged tab, an actual review queue. It cross-references what I am detecting against what eBird says people are reporting near my coordinates, and surfaces the detections that look out of place. From there I can flag a false positive or suppress a species that keeps misfiring. The dashboard now reads through a database view that quietly hides anything I have flagged, so once I correct something, it stays corrected everywhere it shows up.
That is the real difference between the post and the release. The first version was a nice way to look at the data. This version lets me argue with it. Being able to hear the clip, compare it against the xeno-canto reference, check it against eBird, and then tell the system it got one wrong is the difference between a dashboard and something I actually trust.
What is next (still not notifications)
Notifications are still sitting there unbuilt. I know how I would do it, but I am not sure if it would really be useful. I have the MQTT broker Eclipse running and connected to Home Assistant. Wiring in notifications would be a piece of cake by simply publishing events there. It turns out I would rather have data I believe than an alert telling me about data I do not. The backend has been logging unattended this whole time, the way it always does. The repo is public now if you want to point it at your own yard.