Track visits / visitor log?

Any advice on how to create a visitor log? Say I have a bunch of presence sensors attached to different people, and I’m looking to end up with a dashboard widget that looks something like:

# Yesterday
Andrew                          14:15 - 17:23 (3hrs 7 mins)
Andrew                          08:00 - 08:14 (14 mins)
Jane                            Present all day

# Wednesday
Andrew                          14:15 - 17:23 (3hrs 7 mins)

So I know I can trigger automations when people arrive and leave. I’m thinking that in Node-RED I could set a context variable for the arrival time for each person, and then when they leave I can get both timestamps and create some kind of record, but where? Is there an event log I could write that to, and how might this be queried to create the report widget?

Anyone seen anything like this before, or any tips on where to start?

Update: so I have been playing around with custom components have have hacked together a fork of logbook-card, which fetches events from the history API and displays them as above. I’ve also made a heatmap-style thing for tracking my Gym attendance!

(as you can see making this card has actually reduced my gym attendance)

1 Like

No exactly this level of details as you require, but I made sort of such log to record events that happens at my house. Basically I use 20 input_text entities and script that:
a) rotate entries by one (e.g. value of 19th is copied to 20th, value of 18th is copied to 19th… value of 1st is copied to 2nd) and then
b) set value of 1st with most recent value I want to log.
c) for all events I want to track I added in specific automation call to this script with proper parameter.
Here is the code I use:

Script to register log entries:

################################################################
## Rotate log entries
################################################################
rotate_log:
  alias: Rotate Log entries
  sequence:
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_19
        value: "{{ states('input_text.log_entry_18') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_18
        value: "{{ states('input_text.log_entry_17') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_17
        value: "{{ states('input_text.log_entry_16') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_16
        value: "{{ states('input_text.log_entry_15') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_15
        value: "{{ states('input_text.log_entry_14') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_14
        value: "{{ states('input_text.log_entry_13') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_13
        value: "{{ states('input_text.log_entry_12') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_12
        value: "{{ states('input_text.log_entry_11') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_11
        value: "{{ states('input_text.log_entry_10') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_10
        value: "{{ states('input_text.log_entry_9') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_9
        value: "{{ states('input_text.log_entry_8') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_8
        value: "{{ states('input_text.log_entry_7') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_7
        value: "{{ states('input_text.log_entry_6') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_6
        value: "{{ states('input_text.log_entry_5') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_5
        value: "{{ states('input_text.log_entry_4') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_4
        value: "{{ states('input_text.log_entry_3') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_3
        value: "{{ states('input_text.log_entry_2') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_2
        value: "{{ states('input_text.log_entry_1') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_1
        value: "{{ states('input_text.log_entry_0') }}"
    - service: input_text.set_value
      data_template:
        entity_id: input_text.log_entry_0
        value: "{{ now().strftime('%d/%m/%y, %H:%M:%S') }}: {{ new_log_entry }}"

Sample automation calling the scipt and writing data to log (here example of logging my presence status change):

# Log Mirek status change
- id: 'log_mirek_presence'
  alias: Log Mirek status change
  initial_state: true
  trigger: 
    platform: state
    entity_id: person.mirek_malinowski
  condition:
    - condition: template
      value_template: "{{ trigger.to_state.state != trigger.from_state.state }}"
  action:
    - service: script.rotate_log
      data_template:
        new_log_entry: "Mirek is now {{ states('person.mirek_malinowski') }}"

Here is the code I use in lovelace to display the log:

content: >
  {{ states('input_text.log_entry_0') }} <br /> 
  {{ states('input_text.log_entry_1') }} <br /> 
  {{ states('input_text.log_entry_2') }} <br />
  {{ states('input_text.log_entry_3') }} <br />
  {{ states('input_text.log_entry_4') }} <br />
  {{ states('input_text.log_entry_5') }} <br />
  {{ states('input_text.log_entry_6') }} <br />
  {{ states('input_text.log_entry_7') }} <br />
  {{ states('input_text.log_entry_8') }} <br />
  {{ states('input_text.log_entry_9') }} <br />
  {{ states('input_text.log_entry_10') }} <br />
  {{ states('input_text.log_entry_11') }} <br />
  {{ states('input_text.log_entry_12') }} <br />
  {{ states('input_text.log_entry_13') }} <br />
  {{ states('input_text.log_entry_14') }} <br />
  {{ states('input_text.log_entry_15') }} <br />
  {{ states('input_text.log_entry_16') }} <br /> 
  {{ states('input_text.log_entry_17') }} <br />
  {{ states('input_text.log_entry_18') }} <br />
  {{ states('input_text.log_entry_19') }} <br />
title: HASSIO event log
type: markdown

And actual product as seen in UI:

I guess it can be done in more elegant way, not such brute force, but I’m using it mostly for debuging, so no need for something more fancy. I hope this might be sort of starting point for you.

Updated the top post but for context in the thread: I made a fork of logbook-card and can now do stuff like this:

Would anyone else be interested in this?

Hi @triblondon,

very nice stuff, can you try to expand the logbook card with your view - would be very nice to show custom logbooks in different designs!

Steffen

Hi @triblondon,

This heatmap like view looks great! Would you be able to share the details on how you did this ?

I’m a little late to the game here, but I would love to se your code for this. was about to embark on my own journey to make almost exactly this for a habit/chore tracker.