Maak je deurbel slim met Home Assistant en Zigbee

De klassieke deurbel slim maken: ESP32-H2 met Zigbee

Ik heb een volstrekt gewone deurbel aan de muur – geen video, geen app, geen cloud-account. In de binneneenheid kan ik echter drie punten aftappen: +5V, ground (massa) en een signaallijn die naar 5V gaat wanneer iemand aanbelt. Bij mijn m-e Vistador ADV-100 systeem zijn deze aansluitingen eigenlijk bedoeld voor een draadloze zender die een extra radio-chime toevoegt. Kijk in de handleiding van je eigen deurbel; veel systemen bieden een manier om het signaal (bel/chime) af te tappen.

Dit is precies wat ik omzet in een sensor voor Home Assistant. Het hart hiervan is een ESP32-H2 die de bel-puls via Zigbee rapporteert en daarnaast fungeert als repeater die het Zigbee-mesh-netwerk versterkt.

Waarom specifiek de ESP32-H2?

De ESP32-H2 is de buitenbeentje in de familie: hij heeft geen wifi. Wat hij wel heeft, is een 802.15.4 radio – dus Thread en Zigbee – plus Bluetooth LE. Voor een deurbelsensor is dat perfect: de node is permanent gevoed, verzendt minimale hoeveelheden data en werkt direct als een volledige router in het Zigbee-netwerk. De ESPHome-documentatie raadt de H2 zelfs expliciet aan boven de ESP32-C6, omdat de H2 betrouwbaarder zou werken.

Het nadeel is dat er zonder wifi geen ESPHome API en geen OTA (Over-The-Air) updates zijn. Elke latere wijziging in de configuratie betekent dat je een USB-kabel moet aansluiten en het apparaat opnieuw moet flashen. Volgens de ESPHome-docs moet je het apparaat dan ook verwijderen uit het Zigbee-netwerk en opnieuw koppelen. Daarom voltooi ik de configuratie volledig op mijn bureau voordat het in de deurbel gaat.

De hardware

  • Waveshare ESP32-H2-Zero: Een klein board met een ESP32-H2FH4S, 4 MB flash en USB-C.
  • Optocoupler-module met een PC817: Isoleert de deurbellijn van de ESP en brengt de 5V terug naar 3,3V.
  • Zigbee-coordinator in Home Assistant: Ik gebruik ZHA, maar Zigbee2MQTT werkt net zo goed.
  • USB-A naar USB-C datakabel: Let op: veel goedkope kabels bevatten alleen stroomdraden. Met zo'n kabel wordt het board niet herkend door de computer.

Het Waveshare-board is handig omdat de USB-C poort direct op de native USB-Serial/JTAG van de chip zit, waardoor je niet met BOOT- en RESET-knoppen hoeft te knutselen tijdens het flashen. Bovendien gaat de 5V-pin direct naar de spanningsregelaar (een ME6217C33M5G tot 800 mA), dus de 5V van de binneneenheid kan direct worden aangesloten.

Let op bij de pinnen: Bepaalde pinnen moet je vermijden om een schone boot te garanderen of om de USB-poort niet onbruikbaar te maken:

PinReden voor uitsluiting
GPIO8Strapping pin (LOG) en de gesoldeerde RGB LED
GPIO9Strapping pin, verbonden met de BOOT-knop
GPIO26 / GPIO27USB D− en D+
GPIO23 / GPIO24UART0 RX/TX
GPIO2 – GPIO5JTAG (MTMS/MTDO/MTCK/MTDI) – bruikbaar, maar onnodig risicovol

Voor het deurbelsignaal gebruik ik GPIO12: een schone general-purpose pin zonder secundaire functie.

Stroomverbruik: Een Zigbee-router slaapt nooit; de ontvanger staat altijd aan. Houd rekening met een constant verbruik van circa 40 tot 80 mA. Controleer of de 5V-rail van je deurbel dit permanent kan leveren, anders kan het board in de muur constant herstarten.

Bedrading en aansluitingen

De verdeling van taken is hier cruciaal: de signaallijn van de deurbel drijft alleen de LED in de optocoupler aan. Aan de andere kant van de isolatiebarrière schakelt de fototransistor GPIO12. Zo bereikt de 5V van de deurbel nooit de ESP, wat essentieel is omdat de GPIO's slechts 3,3V tolereren. De 5V-pin van het board wordt wel gebruikt om de spanningsregelaar te voeden.

Ik kies voor een pragmatische route met de optocoupler: ik verwijder de jumpers en sluit de output-voeding VCC niet aan. De output van een PC817 is een open collector – hij kan alleen naar ground trekken. Dit is voldoende omdat de ESP32-H2 een interne pull-up heeft: in rust houdt hij GPIO12 op 3,3V, en wanneer er wordt aangebeld, trekt de fototransistor de pin naar ground. Dit bespaart een draad en voorkomt dat er vreemde spanningen bij de GPIO komen.

Tijdens het testen is het handig dat elk kanaal een eigen status-LED heeft die oplicht zodra de input actief is. Zo weet je of de deurbel de optocoupler triggert voordat je Home Assistant raadpleegt.

De ESPHome-configuratie

Sinds begin 2026 is Zigbee direct geïntegreerd in ESPHome, waardoor externe componenten niet langer nodig zijn.

esphome:
  name: doorbell-sensor
  friendly_name: doorbell-sensor

esp32:
  variant: esp32h2
  flash_size: 4MB
  framework:
    type: esp-idf

logger:
  level: INFO

zigbee:
  id: zb
  router: true              # Router in plaats van End Device = repeater
  power_source: DC_SOURCE   # Netstroom, slaapt nooit
  on_join:
    then:
      - logger.log: "Joined the Zigbee network"

sensor:
  - platform: uptime
    name: "Uptime"
    update_interval: 60s

binary_sensor:
  - platform: gpio
    id: doorbell_gpio
    name: "Doorbell"
    report: force        # Vereist voor ZHA, anders is het rapportage-interval 30s
    pin:
      number: GPIO12
      inverted: true     # De optocoupler trekt de pin naar GND
      mode:
        input: true
        pullup: true
    filters:
      - delayed_on: 30ms
      - delayed_off: 500ms

Belangrijke details:

  • router: true: Maakt van de node een Zigbee-router (repeater).
  • powersource: DCSOURCE: Meldt aan de coordinator dat het apparaat niet in slaap gaat.
  • report: force: Cruciaal voor ZHA, anders wordt de melding vertraagd tot 30 seconden, wat een deurbel onbruikbaar maakt.
  • uptime sensor: De enige manier om in Home Assistant te zien of de node nog online is, aangezien de ESPHome API ontbreekt.
  • Geen wifi, api of ota: Dit is bewust weggelaten. Het apparaat verschijnt daarom als "offline" in het ESPHome-dashboard, wat normaal is.

Het apparaat maken en flashen

  1. Gebruik de ESPHome add-on in Home Assistant.
  2. Kies bij het maken van een nieuw apparaat voor het board Espressif ESP32-H2-DevKit (de Waveshare is hiermee pin-compatibel).
  3. Vervang de standaardconfiguratie door de bovenstaande YAML.
  4. Installeer via de route "Plug into this computer". Gebruik Chrome of Edge voor Web Serial ondersteuning.
  5. Selecteer de poort die verschijnt als "USB JTAG/serial debug unit".
  6. Wacht tot de compilatie is voltooid (dit duurt de eerste keer langer omdat de RISC-V toolchain wordt gedownload).
  7. Controleer in het logvenster of de chip correct wordt herkend als ESP32-H2 rev1.2 en of zb_fct in de partitietabel staat.

Koppel het apparaat daarna aan in Home Assistant via Instellingen → Zigbee → Apparaat toevoegen. De entiteiten "Uptime" en "Doorbell" verschijnen nu in je systeem.

Alternatief: Shelly en andere modules

Als je niet wilt solderen, kun je een kant-en-klaar relais- of inputmodule op de bestaande deurbeltransformator plaatsen. Een Shelly 1 Gen4 is hiervoor zeer geschikt; deze werkt op 12V of 24V DC en heeft een potentiaalvrije input die de deurbel-puls direct oppikt zonder optocoupler. Het principe blijft hetzelfde: de module registreert de puls en rapporteert dit als een binaire sensor aan Home Assistant.

Geavanceerde automatiseringen

Nu de deurbel als binaire sensor (binary_sensor.doorbell) in Home Assistant staat, kunnen we slimme functies toevoegen.

Automatisch de camerastream naar je telefoon sturen

Het doel is een pushmelding met een snapshot van de camera, waarbij een tik op de melding de livestream opent. Om vertraging door 4K-camerashots te voorkomen, wordt de melding in twee stappen verzonden: eerst een directe melding zonder foto, gevolgd door een update met de foto zodra deze klaar is.

Automatisering YAML:

alias: Doorbell - camera stream to my phone
description: Directe melding bij bel, snapshot volgt
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.doorbell
    to: "on"
actions:
  # 1. Directe melding zonder camera-access (instant)
  - action: notify.mobile_app_dein_smartphone
    data:
      title: "🔔 Er staat iemand voor de deur"
      message: "Camerabeeld wordt geladen..."
      data:
        tag: doorbell
        push:
          interruption-level: time-sensitive

  # 2. Snapshot maken van de lokale stream
  - action: camera.snapshot
    target:
      entity_id: camera.hausture_rtsp
    data:
      filename: /config/www/doorbell_snapshot.jpg

  # 3. Overschrijf de eerste melding met de foto (via dezelfde tag)
  - action: notify.mobile_app_dein_smartphone
    data:
      title: "🔔 Er staat iemand voor de deur"
      message: "Tik voor de livestream"
      data:
        tag: doorbell
        attachment:
          url: /local/doorbell_snapshot.jpg
          entity_id: camera.hausture_rtsp
        push:
          sound: none
          interruption-level: time-sensitive
mode: single

Belangrijke opmerkingen voor de notificaties:

  • Tag: De tag: doorbell zorgt ervoor dat de tweede melding de eerste vervangt in plaats van een nieuwe melding te maken.
  • iOS vs Android: Op iOS moet je attachment: url: gebruiken; image: werkt niet. Voor Android voeg je clickAction: entityId:camera.hausture_rtsp toe.
  • Interruption-level: time-sensitive zorgt ervoor dat de melding door "Niet storen" of Focus-modi heen komt op iOS.
  • Snapshot-locatie: De map /config/www/ is bereikbaar via /local/. Let op: bestanden in deze map zijn niet beveiligd door de HA-login. Gebruik /media/ voor meer privacy.
  • Snelheid: Gebruik voor de snapshot de lokale stream (RTSP/ONVIF) in plaats van de cloud-entiteit, en gebruik indien mogelijk een substream (lagere resolutie) voor een snellere reactie.

De camera laten draaien naar de voordeur

Als je een PTZ-camera hebt met auto-tracking, kijkt deze niet altijd naar de deur als er wordt aangebeld. Via de ONVIF-integratie kun je de camera naar een preset-positie sturen. Voeg deze acties toe in de automatisering vóór de camera.snapshot:

- action: onvif.ptz
  target:
    entity_id: camera.hausture_onvif_mainstream
  data:
    move_mode: GotoPreset
    preset: "1"
- delay:
    seconds: 1

Variant: Een pop-up op het wandtablet

Met de HACS-extensie browser_mod kun je een camera-pop-up tonen op een tablet in de gang.

Probleem met slapende schermen: Een tablet (zoals de Shelly Wall Display) die in slaapstand staat, ontvangt geen pop-up omdat de verbinding met Home Assistant dan verbroken is. Je moet het scherm dus eerst wekken via een RPC-interface.

Voeg de volgende rest_command toe aan je configuration.yaml:

rest_command:
  wd_screen_on:
    url: 'http://192.168.x.x/rpc/Ui.Screen.Set?params={"on":true}'
    authentication: digest
    username: admin
    password: !secret shelly_wd_password
  wd_ringtone:
    url: 'http://192.168.x.x/rpc/Media.MediaPlayer.PlayRingtone?id={{ id }}&volume={{ volume }}'
    authentication: digest
    username: admin
    password: !secret shelly_wd_password
  wd_helligkeit:
    url: 'http://192.168.x.x/rpc'
    method: post
    content_type: 'application/json'
    payload: '{"id":1,"src":"ha","method":"Ui.SetConfig","params":{"config":{"brightness":{"level":100,"auto":false}}}}'
    authentication: digest
    username: admin
    password: !secret shelly_wd_password

In de automatisering voeg je deze acties toe vóór de pop-up call:

  1. restcommand.wdhelligkeit
  2. restcommand.wdscreen_on
  3. restcommand.wdringtone
  4. Een korte pauze (delay: 500ms) zodat de browserverbinding kan herstellen.
  5. De browser_mod.popup actie.

Veelgestelde vragen (FAQ)

Heb ik een slimme deurbel nodig voor deze automatisering? Nee, je bestaande deurbel is voldoende. Een kleine module op de transformator (zoals een Shelly) rapporteert de druk op de knop aan Home Assistant.

Werkt dit ook met een draadloze deurbel? Dat hangt af van de ontvanger. Als de draadloze chime een potentiaalvrij contact of relais-output heeft, kun je deze aftappen. Zo niet, dan kun je kijken naar de signaal-LED van de ontvanger of de drukknop vervangen door een Zigbee-knop.

Ontvang ik de melding ook als ik niet thuis ben? De melding zelf wel, via de push-service van Apple of Google. Echter, de camera-afbeelding wordt door de app direct van je Home Assistant-instantie opgehaald. Hiervoor moet je HA extern bereikbaar zijn (bijv. via Nabu Casa, Cloudflare Tunnel of VPN).

Werkt de automatisering ook op Android? Ja, met twee aanpassingen: gebruik clickAction voor het tik-doel in plaats van de iOS entity_id fallback, en gebruik priority: high en ttl: 0 in plaats van interruption-level om de melding direct te ontvangen bij een uitgeschakeld scherm.