Last active
July 19, 2026 14:48
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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