Skip to content

Instantly share code, notes, and snippets.

@rugk
Last active July 19, 2026 14:48
Show Gist options
  • Select an option

  • Save rugk/2701fe967a879281c05064d3891a47b2 to your computer and use it in GitHub Desktop.

Select an option

Save rugk/2701fe967a879281c05064d3891a47b2 to your computer and use it in GitHub Desktop.
Home Assistant NFC check-in/out for a Shelly plug energy (session tracking)
blueprint:
name: NFC Session Tracker - Shared Desk
description: Tracks energy per person with cumulative history
domain: automation
input:
tag_id:
name: NFC tag_id
selector:
text:
energy_entity:
name: Shelly cumulative energy (kWh)
selector:
entity:
domain: sensor
power_entity:
name: Shelly power (W) - for power-off reset
selector:
entity:
domain: sensor
person_name:
name: Person identifier (for logging)
selector:
text:
person_cumulative_entity:
name: input_number for person's total energy
selector:
entity:
domain: input_number
# Shared entities
checked_in_boolean:
name: input_boolean "checked in"
selector:
entity:
domain: input_boolean
active_person_input:
name: input_text "active person"
selector:
entity:
domain: input_text
session_start_energy:
name: input_number "session start energy"
selector:
entity:
domain: input_number
delta_sensor:
name: Template sensor for current delta
selector:
entity:
domain: sensor
power_off_below:
name: Power-off threshold (W)
default: 1
selector:
number:
min: 0
max: 10000
step: 0.1
power_off_duration_minutes:
name: Power-off duration (minutes)
default: 2
selector:
number:
min: 0
max: 60
step: 1
trigger:
- platform: tag
tag_id: !input tag_id
- platform: numeric_state
entity_id: !input power_entity
below: !input power_off_below
for:
minutes: !input power_off_duration_minutes
variables:
is_nfc_scan: "{{ trigger.platform == 'tag' }}"
scanned_person: !input person_name
current_person: "{{ states(active_person_input) }}"
is_same_person: "{{ is_state(checked_in_boolean, 'on') and current_person == scanned_person }}"
session_delta: "{{ states(delta_sensor) | float(0) }}"
person_total_entity: !input person_cumulative_entity
current_total: "{{ states(person_total_entity) | float(0) }}"
action:
- choose:
# NFC tag scan
- conditions:
- condition: template
value_template: "{{ is_nfc_scan }}"
sequence:
- choose:
# Same person scans => CHECKOUT
- conditions:
- condition: template
value_template: "{{ is_same_person }}"
sequence:
# Add session delta to cumulative total
- service: input_number.set_value
target:
entity_id: "{{ person_total_entity }}"
data:
value: "{{ current_total + session_delta }}"
# Log to logbook with history
- service: logbook.log
data:
name: "Energy Tracking"
message: "{{ scanned_person }} checked out. Session: {{ session_delta | round(3) }} kWh, Total: {{ (current_total + session_delta) | round(3) }} kWh"
# Reset session state
- service: input_boolean.turn_off
target:
entity_id: !input checked_in_boolean
- service: input_text.set_value
target:
entity_id: !input active_person_input
data:
value: ""
- service: input_number.set_value
target:
entity_id: !input session_start_energy
data:
value: 0
# Different person or first check-in => CHECK-IN
- conditions: []
sequence:
# If someone was already checked in, auto-checkout
- if: "{{ is_state(checked_in_boolean, 'on') }}"
then:
- variables:
prev_person: "{{ current_person }}"
# Would need the previous person's entity as input...
# For now, just log
- service: logbook.log
data:
name: "Energy Tracking"
message: "Auto-checkout: {{ current_person }}. Session: {{ session_delta | round(3) }} kWh"
# Check in new person
- service: input_boolean.turn_on
target:
entity_id: !input checked_in_boolean
- service: input_text.set_value
target:
entity_id: !input active_person_input
data:
value: "{{ scanned_person }}"
- service: input_number.set_value
target:
entity_id: !input session_start_energy
data:
value: "{{ states(energy_entity) | float(0) }}"
- service: logbook.log
data:
name: "Energy Tracking"
message: "{{ scanned_person }} checked in"
# Power-off reset
- conditions:
- condition: template
value_template: "{{ not is_nfc_scan }}"
- condition: state
entity_id: !input checked_in_boolean
state: "on"
sequence:
- variables:
person_at_reset: "{{ current_person }}"
# Optionally log partial session if needed
- service: logbook.log
data:
name: "Energy Tracking"
message: "Power-off detected. {{ person_at_reset }} session reset (partial delta: {{ session_delta | round(3) }} kWh)"
# Clear session
- service: input_boolean.turn_off
target:
entity_id: !input checked_in_boolean
- service: input_text.set_value
target:
entity_id: !input active_person_input
data:
value: ""
- service: input_number.set_value
target:
entity_id: !input session_start_energy
data:
value: 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment