Custom firmware for nRF51822 (e.g., cheap Chinese smart tags) that simultaneously emulates Apple AirTag (OpenHaystack), Google FMDN (Find My Device Network), and broadcasts the local battery percentage to Home Assistant (BTHome).
Ideal for tracking cars, bikes, or pets, maximizing privacy while minimizing power consumption. Optimized for hardware with strict constraints (256KB Flash / 16KB RAM).
The firmware intelligently alternates between three Bluetooth "personalities" in a continuous cycle:
- Apple Find My (8 seconds): Broadcasts the public key to passing iPhones.
- Google FMDN (4 seconds): Broadcasts the EIK to passing Android smartphones.
- BTHome (3 seconds, once every 20 minutes): Broadcasts the exact battery percentage measured by the internal chip. This happens only once every 20 minutes (100 cycles) to drastically maximize the coin cell battery life!
- nRF51822 Smart Tag (Note: For now, this firmware has only been tested on the QFAA variant commonly found in cheap Chinese smart tags).
- ST-Link V2 (Cheap $3 USB programmer) to flash the firmware.
- CR2032 Battery.
| ST-Link V2 | nRF51822 |
|---|---|
| SWDIO | SWDIO (D) |
| SWCLK | SWCLK (C) |
| GND | GND |
| 3.3V | VCC (Use only if the coin cell is removed!) |
Install system dependencies and Zephyr SDK:
sudo apt update
sudo apt install bluetooth bluez bluez-tools rfkill openocd python3-pip
pip3 install cryptography west
# (For the full Zephyr environment, follow the official guide)Use the included Python script to generate or inject your keys. You will need:
- For Apple: The script generates a new key pair. (If you have an old private key and want to restore it, decode it into
ble_addrandraw_airtag_payloadformat). - For Google: You must generate the 40-character key by running the
main.pyscript from their official GoogleFindMyTools repository. Once generated, paste it into the terminal when prompted.
cd nrf51822-tracker
python3 tools/generate_keys.py
⚠️ WARNING: The script will save aprivate_key.txtfile. KEEP IT SAFE! Without the Base64 Private Key, you will never be able to decrypt the locations uploaded by Apple devices!
Connect the ST-Link and run the interactive script. You will be asked to give your tracker a custom name (e.g., Bike_Tracker), after which it will format, compile, and flash the tag automatically:
./flash_stlink.shWhen you read COMPLETO! (COMPLETE!), disconnect the wires, insert the coin cell battery into the tag, and you are ready!
If your Home Assistant has a Bluetooth antenna (or an ESP32 Bluetooth Proxy around the house), it will automatically discover the tag as soon as you get home!
- Go to Settings ➔ Devices & Services.
- You will see a BTHome device appear with the name you chose (e.g.,
Bike_Tracker). - Click "Configure". You will have a precise sensor from 0% to 100%!
When you leave home with the tag, HA stops receiving the local Bluetooth packets and will mark the battery sensor as Unavailable. To make the dashboard always show the last known value, create a Helper:
- Settings ➔ Devices & Services ➔ Helpers ➔ Create Helper ➔ Template ➔ Template a sensor.
- Name:
Bike Tracker Battery Last Known - State template:
{{ states('sensor.bike_tracker_battery') if states('sensor.bike_tracker_battery') not in ['unavailable', 'unknown'] else this.state }}- Replace your old sensor with this new Helper in your dashboard to always keep the data frozen at the last sync outside your house!
By combining the GPS location data retrieved from Apple/Google and the local battery data, you can build a perfect tracking dashboard. For the best visual experience, instead of the default Home Assistant map, it is highly recommended to use the Google Maps Card from HACS.
- Open HACS (Home Assistant Community Store).
- Search for
Google Maps Cardand install it. - Add a custom card to your dashboard and link it to your tracker's
device_trackerentity. - You will get a beautiful, detailed map with dark mode support, custom icons, and advanced features directly in your Home Assistant!
The tag is a "blind" transmitter. To see where it is on the map:
- Apple Network: Use the Macless Haystack Home Assistant integration or the OpenHaystack macOS app. Enter your Private Key (Base64) when requested.
- Google Network: Use the HA integration to download the locations associated with your previously registered Google Key.
src/main.c: Core of the Tri-Tracker (Phase 1, Phase 2, Phase 3, internal VDD reading).src/keys.h: Contains the injected public cryptographic keys.flash_stlink.sh: Script for dynamic naming, compilation (west build), and flashing (openocd).tools/generate_keys.py: Elliptic curve SECP224R1 math algorithm.
Project created to optimize nRF51822 resources by merging seemingly incompatible ecosystems: Apple, Google, and Home Assistant!