Worum geht’s?
Die UniFi G4 Doorbell kann nach Updates oder Reboots sogenannte Ghost-Events auslösen.
Nach Updates, Stromausfällen oder einem Reboot der UniFi Protect G4 Doorbell melden die Protect-Entitäten in Home Assistant für wenige Sekunden scheinbar echte NFC-/Fingerprint-Zugriffe. Diese Ghost-Events können eine „Tür öffnen“-Automation auslösen — obwohl niemand an der Tür steht.
Die Lösung ist simpel: Erkenne den Doorbell-Reconnect, aktiviere einen kurzen Cooldown, und reagiere nur auf frische, echte Events.
Verwendete Komponenten
- Home Assistant (aktueller Stand)
- UniFi Protect Integration mit G4 Doorbell
(liefert u. a.event.*-Entitäten für Fingerprint, NFC und Klingel) - Smart-Lock (z. B. SwitchBot, Nuki, Yale …)
- Optional: HA-Mobile-App für Push-Mitteilungen
- Kamera-Snapshot über die Protect-Kamera
So funktioniert die Lösung (Konzept)
- Beim Doorbell-Neustart fallen mehrere Protect-Entitäten kurz auf
unavailableund kommen verfügbar zurück. - Genau dann aktiviert eine Cooldown-Automation einen Umschalter für ~120 s.
- Die Zutritts-Automation prüft:
- Cooldown aus → Tür darf öffnen.
- Event ist frisch (< 10 s alt) und kein direkter Wechsel aus
unavailable. - Event-ID hat sich geändert (Dedupe gegen Wiederholer).
Schritt 1 – Helfer anlegen
Lege einen Umschalter an:
- Name: Protect Cooldown
- Entitäts-ID:
input_boolean.protect_cooldown
Pfad: Einstellungen → Geräte & Dienste → Helfer → Hinzufügen → Umschalter
Weitere (optionale) Helfer für Protokoll/Anzeige:
input_text.last_zutritt_hashinput_datetime.last_zutritt_eventinput_text.zutrittsinfoinput_text.zutrittsprotokoll
Diese werden in der Beispiel-Automation unten verwendet (du kannst sie sonst entfernen).
Schritt 2 – Cooldown bei Doorbell-Reconnect
Diese Automation schaltet den Cooldown ein, sobald irgendeine Doorbell-Entität von unavailable/unknown wieder verfügbar wird (typisch nach Reboot/Update).
Passe die Entity-IDs an deine Installation an (Beispiele unten).
alias: Haustür – Cooldown bei Doorbell-Reconnect
description: Sperre Tür-Aktionen kurz nach Neustart/Reconnect der G4 Doorbell.
mode: restart
triggers:
- trigger: state
entity_id:
- binary_sensor.frontdoor_doorbell
- binary_sensor.frontdoor_smoke_alarm_detected
- binary_sensor.frontdoor_co_alarm_detected
- media_player.frontdoor_speaker
- select.frontdoor_hdr_mode
from:
- 'unavailable'
- 'unknown'
conditions: []
actions:
- action: input_boolean.turn_on
target:
entity_id: input_boolean.protect_cooldown
- delay: "00:02:00" # 120 s; je nach Setup auf 90–180 s anpassen
- action: input_boolean.turn_off
target:
entity_id: input_boolean.protect_cooldown
Schritt 3 – Zutritts-Automation (mit Cooldown & Frische-Check)
Diese Version öffnet nur bei echten Finger/NFC-Events und ignoriert Reconnect-Geister.
Platzhalter, die du ersetzen solltest:
event.frontdoor_fingerprint,event.frontdoor_nfc,event.frontdoor_doorbelllock.your_lock_entityoderdevice_id: YOUR_LOCK_DEVICE_IDcamera.frontdoor_high_resolution_channelnotify.mobile_app_phone1/notify.mobile_app_phone2- NFC-IDs und Namen sind absichtlich generisch gehalten.
alias: >-
Zutritt & Klingel: Snapshot, Push, Türöffnung, Protokoll
(mit Event-ID + Cooldown/Frische)
description: >
Öffnet die Tür nur bei echten, frischen NFC/Fingerprint-Events.
Verhindert Auslösungen nach Doorbell-Reconnect (Cooldown) und ignoriert
Zustandswechsel direkt aus 'unavailable/unknown'. Klingel darf triggern,
öffnet aber nie die Tür.
mode: single
triggers:
- trigger: state
entity_id:
- event.frontdoor_fingerprint
- event.frontdoor_nfc
- event.frontdoor_doorbell
# --- Schutz & Fachlogik ---
conditions:
# 1) Cooldown muss AUS sein
- condition: state
entity_id: input_boolean.protect_cooldown
state: 'off'
# 2) Trigger darf nicht direkt aus 'unavailable/unknown' kommen
- condition: template
value_template: >
{{ trigger.from_state is not none and
trigger.from_state.state not in ['unavailable','unknown'] }}
# 3) Eventwechsel muss frisch sein (< 10 s)
- condition: template
value_template: >
{{ (as_timestamp(now()) - as_timestamp(trigger.to_state.last_changed)) < 10 }}
# 4) Fachlogik: erlaubte Event-Arten
- condition: or
conditions:
# Finger: identifiziert + Name vorhanden
- condition: template
value_template: >
{{ trigger.entity_id == 'event.frontdoor_fingerprint' and
trigger.to_state.attributes.event_type == 'identified' and
(trigger.to_state.attributes.full_name | default('')) != '' }}
# NFC: nur freigegebene IDs (Platzhalter!)
- condition: template
value_template: >
{{ trigger.entity_id == 'event.frontdoor_nfc' and
(trigger.to_state.attributes.nfc_id | default('')) in ['AAAA1111','BBBB2222'] }}
# Klingel: darf Ereignisse melden (Tür bleibt aber zu)
- condition: template
value_template: >
{{ trigger.entity_id == 'event.frontdoor_doorbell' and
trigger.to_state.attributes.event_type == 'ring' }}
actions:
- variables:
zugangstyp: >
{% if trigger.entity_id == 'event.frontdoor_fingerprint' %}Finger
{% elif trigger.entity_id == 'event.frontdoor_nfc' %}NFC
{% else %}Klingel{% endif %}
name: |
{% if zugangstyp == 'Finger' %}
{{ trigger.to_state.attributes.full_name if trigger.to_state.attributes.full_name is not none else 'Unbekannt' }}
{% elif zugangstyp == 'NFC' %}
{{ {'AAAA1111': 'Max Beispiel', 'BBBB2222': 'Erika Muster'}.get(trigger.to_state.attributes.nfc_id, 'Unbekannt') }}
{% else %}
Unbekannt
{% endif %}
timestamp: "{{ now().strftime('%Y-%m-%d_%H-%M-%S') }}"
snapshot_filename: zugang_{{ name | lower | replace(' ', '_') }}_{{ timestamp }}.jpg
snapshot_path: /media/snapshots/{{ snapshot_filename }}
snapshot_url: https://ha.example.com/local/snapshots/{{ snapshot_filename }}
letzter_snapshot_path: /config/www/snapshots/letzter.jpg
letzter_snapshot_url: https://ha.example.com/local/snapshots/letzter.jpg
neuer_eintrag: "{{ now().strftime('%d.%m.%Y %H:%M') }} – {{ name }} ({{ zugangstyp }})"
current_event_id: "{{ trigger.to_state.attributes.event_id | default('') }}"
last_event_id: "{{ states('input_text.last_zutritt_hash') }}"
# Tür nur bei Finger/NFC UND neuer event_id öffnen
- choose:
- conditions:
- condition: template
value_template: "{{ zugangstyp != 'Klingel' }}"
- condition: template
value_template: >
{{ (current_event_id | string) != (last_event_id | string) and
(current_event_id | string) != '' }}
sequence:
# Variante A: per Entity
- action: lock.unlock
target:
entity_id: lock.your_lock_entity
# Alternative Variante B (falls du lieber device_id nutzt):
# - action: lock.unlock
# target: { device_id: YOUR_LOCK_DEVICE_ID }
- action: input_datetime.set_datetime
data:
entity_id: input_datetime.last_zutritt_event
datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
- action: input_text.set_value
data:
entity_id: input_text.last_zutritt_hash
value: "{{ current_event_id }}"
# Snapshot erstellen
- action: camera.snapshot
data:
entity_id: camera.frontdoor_high_resolution_channel
filename: "{{ snapshot_path }}"
# Push an zwei Geräte (Platzhalter ersetzen/ergänzen)
- repeat:
for_each:
- notify.mobile_app_phone1
- notify.mobile_app_phone2
sequence:
- action: notify.notify
data:
title: "{{ 'Es hat geklingelt' if zugangstyp == 'Klingel' else 'Zutritt erkannt' }}"
message: "{{ neuer_eintrag }}"
data:
image: "{{ letzter_snapshot_url }}?{{ now().timestamp() }}"
url: https://ha.example.com/dashboard-zentrale/zutritt-klingel-details
# "letzter.jpg" aktualisieren (optional)
- action: shell_command.copy_letzter_snapshot
data:
source: "{{ snapshot_path }}"
target: "{{ letzter_snapshot_path }}"
# Textfelder für Dashboard/Protokoll (optional)
- action: input_text.set_value
data:
entity_id: input_text.zutrittsinfo
value: "Name: {{ name }} | Zeit: {{ timestamp }} | Zutrittsart: {{ zugangstyp }}"
- action: input_text.set_value
data:
entity_id: input_text.zutrittsprotokoll
value: >
{% set e = state_attr('input_text.zutrittsprotokoll','value') %}
{% set e = e.split('\n') if e else [] %}
{% set e = [neuer_eintrag] + e[:4] %}
{{ e | join('\n') }}
Optional: shell_command definieren
Wenn du das Kopieren für letzter.jpg nutzt, hinterlege den Befehl in deiner configuration.yaml:
shell_command:
copy_letzter_snapshot: "cp {{ source }} {{ target }}"
Schritt 4 – Testplan
- Cooldown erzwingen: Doorbell kurz vom Strom trennen → nach Reconnect muss
input_boolean.protect_cooldown~120 s auf Ein stehen. - Ghost-Events prüfen: In Protect/HA-Logbuch werden „NFC/Fingerprint erkannt“ auftauchen; Tür bleibt zu.
- Echter Zutritt: Nach Cooldown Fingerprint oder freigegebene NFC-Karte nutzen → Tür öffnet; Snapshot/Push/Protokoll aktualisieren sich.
- Klingel: Darf jederzeit Events/Push auslösen, öffnet aber nie die Tür.
Troubleshooting & Tipps
- Cooldown zu kurz? Wenn im Log noch Ghost-Events nach 2 min auftauchen, erhöhe auf 180 s.
- Falsche Entitäten im Reconnect-Trigger: Nimm 2–3 Doorbell-Entitäten, die beim Reboot immer
unavailablewerden (z. B.binary_sensor.*_doorbell,media_player.*_speaker, Alarmsensoren oderselect.*_hdr_mode). - Kein
event.*verfügbar? Manche Setups nutzen stattdessen Binary-Sensoren für NFC/Fingerprint. Du kannst die Trigger entsprechend anpassen; die Bedingungen (Cooldown, Frische, keinunavailable) bleiben gleich. - Mehr Sicherheit: Ergänze Präsenz- und Zeitfenster-Checks (z. B. „nur wenn du zu Hause bist“, „nur 06:00–23:00“).
Fazit
Mit Reconnect-Erkennung + Cooldown + Frische-/ID-Prüfung gehören Ghost-Events beim Doorbell-Neustart der Vergangenheit an. Deine Haustür öffnet nur noch bei realen, autorisierten Finger- oder NFC-Zugriffen — nicht mehr nach Updates oder Stromausfällen.





0 Kommentare