I am trying to use the finger print sensor on my G4 POE to open the garage door so that I can put my bicycle away without needing to get my phone out. This automation works OK, except that the door opens itself randomly
In the HA documentation there is a worked example on how to use Finger Print in Automations UniFi Protect - Home Assistant with a complicated conditional template
condition:
- condition: template
value_template: >
{{
not trigger.event.data.old_state.attributes.get('restored', false) and
not trigger.event.data.old_state.state == 'unavailable' and
trigger.event.data.new_state is not none and
trigger.event.data.new_state.attributes.event_type == 'identified' and
(trigger.event.data.new_state.attributes.ulp_id|default('')) != '' and
trigger.event.data.new_state.attributes.ulp_id in ['ALLOWED_ID1', 'ALLOWED_ID2']
}}
Itās not crystal clear but I can see how this condition is trying to filter out spurious events. Iād really like to use this logic in conjunction with my finger_print attributes approach, but I have no way of testing something dynamic like this.
Is there anybody who can explain how I can re-phrase this to use finger_print instead of ulp_id? Thanks.
I have a G4 doorbell pro and I use the fingerprint scanner to disarm my alarm system. I noticed that when the G4 doorbell reboots (like after a firmware upgrade, power outage, network disconnect event, etc.) I get a āValid Fingerprintā event in HA (attributes.event_type='identified'); therefore, my alarm system would disarm if it was armed.
I performed some tests and discovered that the G4 Doorbell, as part of the startup process, is sending the last valid (cached) fingerprint. Iām not sure why but I think the same is happening for you and others - that is why the above template was provided. The template is very comprehensive and I can see how it is meant to cover all cases where the problematic restart condition could cause an issue.
I solved my issue by ignoring the valid fingerprint event if the previous state (old_state.state) was unavailable.
Thanks for that really useful reply. I tried adding the condition: {{ not trigger.event.data.old_state.state == "unavailable"}} but this generarates an error "Error: In 'template' condition: UndefinedError: 'event' is undefined" . Any chance you can show me your template condition? TIA
Event triggers are getting an overhaul soon (actually all triggers); the devs are aware that using events to trigger automations is a painful and tedious process because of the various issues.
For now, I recommend using the following template condition which will only pass events which are new (within the past 5 seconds):
I was struggling to get this working but figured it out with the help of Claude. I could not get the example in documentation to work.
One can get the ULP ID from the Unrecognized Fingerprint Scan notification.
Iām not a programmer and know very little yaml but Claude is pretty good with the correct prompts.
alias: Fingerprint Scan - Garage Door Control
description: |2-
**Last Modified**: 2025/12/18
**UniFi Protect G4 Doorbell Fingerprint Authentication**
**Summary:**
- Monitors fingerprint scans from UniFi Protect G4 Doorbell and opens garage door for authorized users
- Uses defensive filtering to prevent false triggers from restored states or stale events
- Filters by unique `ulp_id` (GUID) for robust user identification, displays `full_name` in notifications
- Notifies on unrecognized fingerprints for security monitoring
- Single mode prevents rapid re-scans from triggering multiple door operations
- Authorized users configured in action variables for easy maintenance (visible in UI)
- Supports user-specific actions for customized behavior per user
**Triggers:**
- `state_changed` event: Fires when `event.camera_doorbell_fingerprint` entity state changes
**Conditions:**
- **Defensive Filter**: Ensures event is valid (not restored, not unavailable, has ulp_id, event_type is 'identified')
- **5 Second Recency Check**: Only processes events that occurred within last 5 seconds to prevent stale triggers
**Notifications:**
- **User 1 Confirmation**: Sends confirmation notification when User 1 scans fingerprint
- Target: `notify.notify_phone` (customize to your notification service)
- Example: "[11:21:58 PM] Garage door opened by fingerprint scan."
- **Unrecognized Fingerprint**: When identified fingerprint doesn't match authorized users
- Target: `notify.notify_phone` (customize to your notification service)
- Example: "[11:21:58 PM] Fingerprint identified - Name: Unknown User, ULP ID: abc123..., Status: ACTIVE - No assigned action"
**Actions:**
- **User-Specific Actions**: Checks for specific user IDs first for custom behaviors
- User 1: Opens garage door + sends confirmation notification
- User 2: Opens garage door only (no notification)
- **General Authorized User Match**: Opens garage door when scanned `ulp_id` matches any ID in `authorized_users` list
- **Unauthorized/Unknown User**: Sends security notification with full fingerprint details including name, ID, and user status
**Variables:**
- `authorized_users`: List of authorized ULP IDs (GUIDs) that can trigger garage door opening (defined in action block)
- `scanned_ulp_id`: The ULP ID from the current fingerprint scan event (defined in action block)
- `user1_ulp_id`: User 1's specific ULP ID for user-specific conditions (defined in action block)
- `user2_ulp_id`: User 2's specific ULP ID for user-specific conditions (defined in action block)
**Dependencies:**
- `event.camera_doorbell_fingerprint`: UniFi Protect fingerprint event entity
- `cover.garage_door_door`: Garage door cover entity
- `notify.notify_phone`: Notification service (customize to your setup)
**Mode:** single
**Trace Storage:** 15 days
**Update Log:**
- 2025/12/18: Initial version with defensive filtering per UniFi Protect integration docs
variables:
# Extract the scanned fingerprint ULP ID from the trigger event
scanned_ulp_id: "{{ trigger.event.data.new_state.attributes.ulp_id }}"
triggers:
- alias: Fingerprint Scan Event
event_type: state_changed
event_data:
entity_id: event.camera_doorbell_fingerprint # Change to your fingerprint entity
trigger: event
conditions:
- alias: Defensive Filter - Valid Identified Event
condition: template
# This filter prevents false triggers from:
# - Home Assistant restarts (restored states)
# - Unavailable/stale states
# - Events without a valid ULP ID
# - Events that aren't "identified" type
value_template: |-
{{
trigger.event.data.old_state is not none and
trigger.event.data.new_state is not none and
not trigger.event.data.old_state.attributes.get('restored', false) and
trigger.event.data.old_state.state != 'unavailable' and
trigger.event.data.new_state.attributes.event_type == 'identified' and
(trigger.event.data.new_state.attributes.ulp_id | default('')) != ''
}}
- alias: 5 Second Recency Filter
condition: template
# Only process fingerprint scans that occurred within the last 5 seconds
# This prevents stale events from triggering the automation
value_template: >-
{{ trigger.event.data.new_state.state | as_datetime(as_datetime(0)) >
now() - timedelta(seconds=5) }}
actions:
- alias: Set User Configuration Variables
variables:
# IMPORTANT: These MUST be actual ULP IDs (GUIDs), not names!
# To get ULP IDs: Have each user scan their fingerprint, then check the
# notification or trace for their unique ulp_id GUID
# The comments after each ID are just for YOUR reference - HA ignores them
authorized_users:
- 7d71cc87-7993-4775-914f-7be3ab056d7c # User 1 - Replace with actual ULP ID
- abc123xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # User 2 - Replace with actual ULP ID
# - def456yy-yyyy-yyyy-yyyy-yyyyyyyyyyyy # Additional User (add more as needed)
# Individual user IDs for user-specific actions
# These allow you to give different users different behaviors
user1_ulp_id: 7d71cc87-7993-4775-914f-7be3ab056d7c # Replace with User 1's actual ULP ID
user2_ulp_id: abc123xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # Replace with User 2's actual ULP ID
- alias: Check User and Execute Actions
choose:
# ==========================================
# USER-SPECIFIC ACTIONS
# Add custom behaviors for individual users here
# ==========================================
- conditions:
- alias: User 1 - Specific Actions
condition: template
value_template: "{{ scanned_ulp_id == user1_ulp_id }}"
sequence:
- alias: Open Garage Door
action: cover.open_cover
metadata: {}
target:
entity_id: cover.garage_door_door # Change to your garage door entity
data: {}
- alias: Send User 1 Confirmation Notification
action: notify.notify_phone # Change to your notification service
metadata: {}
data:
title: š Garage Door Opened
message: >-
[{{ trigger.event.data.new_state.state | as_datetime | as_local | as_timestamp | timestamp_custom('%I:%M:%S %p') }}]
Garage door opened by fingerprint scan.
- conditions:
- alias: User 2 - Specific Actions
condition: template
value_template: "{{ scanned_ulp_id == user2_ulp_id }}"
sequence:
- alias: Open Garage Door
action: cover.open_cover
metadata: {}
target:
entity_id: cover.garage_door_door # Change to your garage door entity
data: {}
# User 2 gets no notification - customize actions here as needed
# Examples you could add:
# - Turn on entry lights
# - Disarm alarm system
# - Send notification to different phone
# - Log entry to a file/spreadsheet
# ==========================================
# CATCH-ALL FOR OTHER AUTHORIZED USERS
# Any user in authorized_users list but not specified above
# ==========================================
- conditions:
- alias: Any Other Authorized User
condition: template
# Checks if scanned ULP ID is in the authorized_users list
value_template: "{{ scanned_ulp_id in authorized_users }}"
sequence:
- alias: Open Garage Door
action: cover.open_cover
metadata: {}
target:
entity_id: cover.garage_door_door # Change to your garage door entity
data: {}
# ==========================================
# UNAUTHORIZED/UNRECOGNIZED FINGERPRINT
# Security alert for fingerprints not in authorized list
# ==========================================
default:
- alias: Notify Unrecognized Fingerprint
action: notify.notify_phone # Change to your notification service
metadata: {}
data:
title: š Unrecognized Fingerprint Scan
message: >-
[{{ trigger.event.data.new_state.state | as_datetime | as_local | as_timestamp | timestamp_custom('%I:%M:%S %p') }}]
Fingerprint identified but no assigned action:
Name: {{ trigger.event.data.new_state.attributes.full_name }}
ULP ID: {{ trigger.event.data.new_state.attributes.ulp_id }}
Status: {{ trigger.event.data.new_state.attributes.user_status }}
Event ID: {{ trigger.event.data.new_state.attributes.event_id }}
mode: single # Prevents multiple simultaneous executions - important for door security!
trace:
stored_traces: 15 # Keep 15 days of execution history for debugging
As a rule of thumb for Home Assistant: Filter by ID (ulp_id), but use Name (full_name) for notifications.
Filter by ID: The ulp_id is a unique GUID. Even if you change your name in UniFi Protect or fix a typo, the ID stays the same. It is the most robust way to ensure the door only opens for the right person.
Use Name for UI/Alerts: The full_name is āhuman-readable.ā Itās perfect for passing into a notification message so you donāt have to look up who a string of hex characters belongs to.