Betere thuisdetectie met Home Assistant: een BLE-sleuteltag in plaats van GPS
Ik woon in een kleine woning van 5,5 bij 5,5 meter, en een paar meter buiten de deur loopt een bus- en autoweg. Mijn smart home wist dat — op een slechte manier. Telkens als er een bus in de straat langsreed, meldde Home Assistant dat ik thuis was. Terwijl ik gewoon op de bank zat, of zelfs helemaal niet thuis was.
Dat was het GPS-probleem. En de oplossing bleek een Bluetooth-sleuteltag van nog geen twintig euro te zijn, een ESP32-bordje ter grootte van een postzegel, en een uur eerlijk uitzoekwerk.
Het probleem: GPS is te onnauwkeurig voor een huis
Mijn thuisdetectie werkte via de Home Assistant Companion-app op mijn telefoon. De app rapporteert je GPS-locatie, en Home Assistant zet je als “thuis” zodra je binnen de thuis-zone valt.
De cijfers lagen ver uit elkaar:
- Zone-radius: 9 meter
- GPS-nauwkeurigheid van de telefoon: vaak 100 meter
Een GPS-fix met een foutmarge van 100 meter zegt dus vrijwel niets over of je binnen die 9-meter-zone bent. Het resultaat: een bus die in de straat langsreed, een auto die voor de deur stilstond, of gewoon wat GPS-driftt — alles floepte de aanwezigheidssensor om naar “thuis” alsof er niets aan de hand was.
Frekwent knipperende lampen en verwarming die aansprong terwijl ik niet eens binnen was. Tijd voor iets dat het huis daadwerkelijk kan “aanraken” — en dat is precies wat Bluetooth doet.
De kernvraag: heeft de server zelf Bluetooth?
Mijn Home Assistant draait op een Intel NUC — een energiezuinig, maar oud bordje uit een vorig decennium. En het antwoord was kort: nee, die heeft geen Bluetooth-chip. Voordat je een oplossing bedenkt, moet je eerst weten of je hardware die überhaupt kan.
Laat ik dat scherp stellen: Home Assistant zelf is naadloos met Bluetooth geïntegreerd als de machine het heeft. Maar een NUC zonder Bluetooth-adapter kan het niet. Er bleven dus twee wegen over:
- een USB-Bluetooth-dongle in de NUC,
- een los ESP32-bordje dat Bluetooth scant en het resultaat over Wi-Fi doorgeeft.
De tweede weg is vaak beter: je kunt het bordje precies daar neerleggen waar je de detectie wilt (bij de voordeur), en de NUC blijft onaangeroerd.
De hardware
Ik had nog een M5Stack Atom Lite liggen — een piepklein bordje met een ESP32, Wi-Fi, Bluetooth en één RGB-LED, allemaal op een print van 24×24 millimeter. Ideaal voor deze klus.
Voor de tag koos ik een Fresh ’n Rebel Smart Finder. Dat is een sleutelhanger-tracker met een bluetooth-signaal en een speaker om je sleutels terug te vinden. Hij werkt met Apple’s “Find My”-netwerk, maar het mooie is: hij zendt zijn bluetooth-signaal voortdurend uit, of er nu een telefoon in de buurt is of niet.
Daarmee heb je een ding dat fysiek aanwezig is waar jij bent, zonder dat het via een telefoon of cloud loopt. Zolang de sleuteltag binnen bluetoothbereik is, ben jij waarschijnlijk thuis. En een bus die twee meter verderop langsrijdt, haalt die bluetoothgrens nooit — een bus is een grote metalen doos, en BLE is een kortbereiksignaal.
De valkuil: de MAC-adressen van de tag roteren
Tijdens het testen ontdekte ik iets belangrijks. Ik liet de ESP32 een paar uur lang loggen welke bluetooth-apparaten hij zag, en de Fresh ’n Rebel-tag verscheen met twee verschillende MAC-adressen:
| Periode | MAC-adres | Signaalsterkte |
|---|---|---|
| 17:13–17:17 | C6:D4:22:66:96:98 | -54 tot -88 dBm |
| 19:58–20:00 | F7:EC:52:FC:7D:10 | -61 tot -84 dBm |
Zelfde tag, ander adres. Dat is bewuste privacy-technologie: veel moderne trackers (inclusief de Apple “Find My”-achtige tags) roteren hun MAC-adres om de paar minuten, zodat je niet gevolgd kunt worden.
De consequentie is cruciaal voor thuisdetectie: je kunt de tag niet herkennen aan zijn MAC-adres, want dat verandert continu. Maar de tag zendt ook een uitzendnaam uit — en die bleef stabiel:
FnR 6ATAG72R
Dus de oplossing was simpel maar net niet voor de hand liggend: match op de naam, niet op het adres.
De config: match op naam
Met ESPHome flashte ik de Atom Lite. ESPHome is het perfecte gereedschap hier: je schrijft een YAML-bestand, en het wordt een volledige firmware voor de ESP32 die automatisch met Home Assistant praat.
De kern van de config:
esp32_ble_tracker:
on_ble_advertise:
- then:
- lambda: |-
if (x.get_name() != "FnR 6ATAG72R") return;
id(last_seen) = millis();
id(sleutels_thuis).publish_state(true);
id(sleutels_rssi).publish_state(x.get_rssi());
Elke bluetooth-advertentie die de ESP32 opvangt wordt bekeken. Als de naam niet die van mijn sleuteltag is, wordt hij genegeerd. Als hij wél matcht, wordt de binary sensor “Sleutels thuis” op aan gezet, samen met de signaalsterkte.
Daaronder een klein huisregeltje: als er 120 seconden geen signaal meer binnenkomt, gaat de sensor weer uit:
interval:
- interval: 30s
then:
- lambda: |-
if (millis() - id(last_seen) > 120000) {
id(sleutels_thuis).publish_state(false);
}
Zo heb je een “glad” presence-signaal: hij springt niet bij het eerste gemiste pakketje meteen uit, maar wacht tot de tag écht weg is.
Koppelen aan de persoon in Home Assistant
Een losse sensor is nog geen thuisdetectie. In Home Assistant is
person.eddy de plek waar al je aanwezigheidsbronnen samenkomen. Die wil
ik nu laten meebewegen met de sleuteltag.
De BLE-sensor is een binary_sensor, maar een persoon verwacht een
device_tracker. De moderne, nog-niet-verouderde manier om dat te
overbruggen is een template device_tracker:
template:
- device_tracker:
- name: "Sleutels thuis tracker"
unique_id: sleutels_thuis_tracker
in_zones: >
{% if is_state('binary_sensor.fnr_ble_detector_sleutels_thuis', 'on') %}
["zone.home"]
{% else %}
[]
{% endif %}
Dit maakt van de sensor een tracker die “home” is zolang de tag in de
thuis-zone zit, en “not_home” als dat niet zo is. Die tracker koppel ik aan
person.eddy, en de GPS-tracker van de telefoon verdwijnt uit de persoon.
Het eindresultaat is bevestigd in de state van de persoon:
person.eddy = home
source: device_tracker.sleutels_thuis_tracker
De thuisdetectie draait nu volledig op de bluetooth-sleuteltag, niet meer op de telefoon-GPS.
Wat het oplevert
Het verschil is groot:
- Geen bus meer die “thuis” meldt. Een bus heeft geen bluetooth die door je muren en ramen heen gaat tot bij de voordeur-detector. Een auto die langsrijdt ook niet.
- Detectie op de drempel zelf. De Atom Lite staat bij de deur. Stap je binnen, dan is de tag binnen bereik en springt je status om.
- Geen privacy-inlevering. Niets verlaat je huis; de tag praat alleen met je eigen ESP32, nooit met een cloud.
Een ding om te weten: wat de tag niet kan
De fitness-tracker om mijn pols (een Huawei Band 10) bleek niet bruikbaar voor dezelfde truc. Ik liet de ESP32 urenlang loggen terwijl ik de band droeg, en hij zond geen enkel bluetoothsignaal uit zolang hij aan mijn telefoon gekoppeld was. Veel fitness-trackers stoppen met adverteren zodra ze via de app aan je telefoon hangen — dan is er voor een BLE-detector niets te zien.
Dus als je dit nadoet: niet elke bluetooth-tracker is gelijk. Kies er een die continu adverteert. Een sleutelvinder die werkt met het Find My-netwerk is een veilige gok; een fitness-band die met je telefoon praat, vaak niet.
De beperking van “BLE-leidend”
Er is één bewust geaccepteerde afweging. Omdat de sleuteltag nu de enige bron is: als mijn sleutels ergens liggen terwijl ik thuis ben (bijvoorbeeld even de sleutels in de auto laten liggen), dan denkt het huis dat ik vertrokken ben. Dat is inherent aan elke aan-afwezigheidsdetectie die op één draagbaar object leunt — en in de praktijk is het eenvoudig terug te draaien zodra je de sleutels weer oppakt.
De code
Alles staat in een repository op mijn eigen Forgejo: de volledige ESPHome-config, een README met alle uitleg, en een template voor de secrets. Credentials zitten nooit in de repo.
De hele oplossing — hardware, firmware, Home Assistant-koppeling — komt neer op een paar tientjes en een paar uur klussen. Maar het gevoel dat je huis alleen reageert als jij er écht bent, en niet iedere keer dat er een bus voorbijrijdt, is meer dan de moeite waard.