A Home Assistant custom integration for Haikubox bird audio detection devices. Surfaces recent detections, daily and yearly species counts, and highlights unusual visitors — all with bird photos and custom Lovelace cards.
- Recent detections — species heard in the last hour, updated every 10 minutes
- Last detected species — persists the most recently heard bird, never goes unknown between detections
- Most unusual recent detection — ranked by rarity against your box's own yearly baseline; also persists across quiet windows
- New species detected — flags species appearing for the first time ever on your box, backed by persistent storage that survives HA restarts
- Daily counts — total detections and distinct species heard today
- Bird details sensors — top species this year, top species today, and rarest species over the past 7 days
- Custom Lovelace cards — bird photo cards and ranked list cards with tap-to-expand detail views
- Bird photos cached locally for offline resilience
- Open HACS → Integrations → ⋮ → Custom repositories
- Add
https://github.com/eklundjon/ha-haikuboxwith category Integration - Search for Haikubox and install
- Restart Home Assistant
- Copy the
custom_components/haikuboxfolder into your HAconfig/custom_components/directory - Restart Home Assistant
- Go to Settings → Devices & Services → Add Integration
- Search for Haikubox
- Enter the serial number from the bottom of your device (e.g.
100000003d7c9f2b)
The integration will verify the serial against the Haikubox API and create a device named after your box (e.g. "Bird Shazam").
To change the serial number later, go to the integration entry and select Reconfigure.
All entities are grouped under a single device per Haikubox. Entity IDs are prefixed with your device name (e.g. sensor.bird_shazam_*).
| Entity | State | Key attributes |
|---|---|---|
sensor.recent_detections |
Species count in current 1-hour window | detections — list with species, scientific_name, last_seen, rarity_score |
sensor.last_detected |
Most recently heard species | last_seen, scientific_name, image_url |
sensor.notable_detection |
Most unusual species in the current window | notable_detections — full list sorted by rarity; rarity_score, yearly_rank |
sensor.new_species |
Most recently first-detected species | recent_first_detections list, lifetime_species_count |
sensor.daily_count |
Total detections today | species_counts — per-species breakdown |
sensor.daily_species |
Distinct species heard today | — |
These sensors expose ranked species lists and are designed to be used with the haikubox-bird-list-card custom card. Each exposes its data under an items attribute.
| Entity | State | items contents |
|---|---|---|
sensor.top_species_this_year |
Number of species in yearly baseline | species, scientific_name, count, rank, last_seen, image_url |
sensor.top_species_today |
Number of species heard today | species, scientific_name, count, last_seen, image_url |
sensor.rarest_species_7_days |
Number of species in rolling 7-day window | species, scientific_name, count, yearly_rank, last_seen, image_url |
scientific_name and last_seen on yearly and daily sensors accumulate over time as species pass through detection polls. The 7-day rarity sensor has full metadata immediately.
The notable_detection sensor and 7-day rare sensor score each species against your box's own yearly history. A species absent from the yearly top-75 scores 1.0; the most commonly detected species scores close to 0. This means a Cooper's Hawk scores as more unusual on a box that rarely records raptors than on one that hears them daily.
last_detected and notable_detection never clear between polls. The following data is written to .storage/ and survives HA restarts:
| Store file | Contents |
|---|---|
haikubox.<serial>.seen_species |
Lifetime first-detection log |
haikubox.<serial>.sp_codes |
Species → species code lookup |
haikubox.<serial>.sci_names |
Species → scientific name lookup |
haikubox.<serial>.last_seen |
Species → most recent detection timestamp |
haikubox.<serial>.yearly |
Yearly species baseline |
haikubox.<serial>.seven_day |
Rolling 7-day detection data |
The integration registers two custom Lovelace cards automatically — no manual resource configuration required.
Displays a single bird detection with a photo, species name, scientific name, and a relative timestamp.
type: custom:haikubox-bird-card
entity: sensor.bird_shazam_most_unusual_recent_detection
grid_options:
columns: 6
rows: 4The card is fully responsive to both width and height:
- Portrait — photo fills the card width up to a square (1:1), text is centred below. When space is tight, the scientific name is dropped and the photo shrinks to maintain at most a 3:2 aspect ratio.
- Wide — when the card is wider than 3:2, the photo moves to the left and text appears on the right.
The card ships sensible size defaults via getGridOptions(); resize it from the card's Layout tab in the dashboard editor, or set grid_options (columns, rows) in YAML. It adapts gracefully at any reasonable aspect ratio. (Requires Home Assistant 2024.11+ for the sections grid sizing API.)
Works with any sensor that exposes image_url, scientific_name, and last_seen attributes (e.g. last_detected, notable_detection).
The card uses Home Assistant's standard tap_action schema. Supported actions: more-info (default — opens the bound sensor's dialog), navigate, url, and none (card is inert, the pre-0.4 behaviour).
navigation_path and url_path accept {species}, {sp_code}, and {scientific_name} tokens, URL-encoded and filled from the card's bound entity — so the action can be specific to the bird currently shown:
# Open an external page for the bird currently displayed.
# Substitute whatever URL scheme the target site uses; this just
# shows token substitution.
type: custom:haikubox-bird-card
entity: sensor.bird_shazam_last_detected
tap_action:
action: url
url_path: https://www.google.com/search?q={scientific_name}+bird# Jump to a dashboard view, anchored to the species
type: custom:haikubox-bird-card
entity: sensor.bird_shazam_most_unusual_recent_detection
tap_action:
action: navigate
navigation_path: /lovelace-birds/species#{species}The visual editor exposes a Tap action picker; the YAML option works with or without it.
A ranked species list with tap-to-expand detail rows. Works with all three bird details sensors.
type: custom:haikubox-bird-list-card
entity: sensor.bird_shazam_top_species_this_year
title: Top Species This Year # optional; blank or omitted → entity friendly name
top: 10 # max items to render (default: 10)
grid_options:
columns: 12
rows: 4 # controls card height; list scrolls if content exceeds itTapping any row slides open an expanded view showing a larger photo, scientific name, and contextual metrics:
- All lists — detection count with period context ("47× this year", "8× today", "3× in one day") and last heard timestamp
- 7-day rare list — also shows yearly rank ("ranked #62 this year")
The badge adapts automatically — no different card type is needed for each sensor. Point it at whichever sensor you want:
# Yearly top
type: custom:haikubox-bird-list-card
entity: sensor.bird_shazam_top_species_this_year
title: Top Species This Year
top: 20
grid_options:
columns: 12
rows: 6
# Daily top
type: custom:haikubox-bird-list-card
entity: sensor.bird_shazam_top_species_today
title: Top Species Today
grid_options:
columns: 12
rows: 4
# 7-day rarity
type: custom:haikubox-bird-list-card
entity: sensor.bird_shazam_rarest_species_7_days
title: Unusual Birds This Week
grid_options:
columns: 12
rows: 4A three-column details view using the sections layout:
type: sections
title: Bird Details
sections:
- type: grid
cards:
- type: custom:haikubox-bird-list-card
entity: sensor.bird_shazam_top_species_this_year
title: Top Species This Year
top: 20
- type: grid
cards:
- type: custom:haikubox-bird-list-card
entity: sensor.bird_shazam_top_species_today
title: Top Species Today
top: 10
- type: grid
cards:
- type: custom:haikubox-bird-list-card
entity: sensor.bird_shazam_rarest_species_7_days
title: Unusual Birds This Week
top: 10By default the integration polls the Haikubox API every 10 minutes, requesting a 1-hour detection window. The yearly species baseline is refreshed once per calendar day.
There is no per-interval setting; instead the integration honours Home Assistant's standard polling control. To run on your own schedule (for example, to poll less often and be kinder to the Haikubox cloud, or more often for near-real-time updates):
- Go to Settings → Devices & Services, open the Haikubox entry, use the ⋮ menu → System options, and turn off "Enable polling for updates". Automatic polling stops.
- Add an automation that refreshes the data on your chosen schedule. All Haikubox sensors share one data coordinator, so updating any one of them refreshes them all:
automation:
- alias: Refresh Haikubox every 30 minutes
triggers:
- trigger: time_pattern
minutes: "/30"
actions:
- action: homeassistant.update_entity
target:
entity_id: sensor.bird_shazam_last_detectedThis is Home Assistant's built-in, integration-agnostic mechanism for a custom polling interval — see the HA docs on polling.
MIT License — see LICENSE for details.