Mailbox-Sensor (dynamically adding attributes when mail arrives)

Hey there,

I wanted to share my current project, especially because I could need help setting it up… :confused:

As the title suggests, my intention was to create a smart automation for my mailbox using a zigbee motion-sensor (which is housed in my mailbox and reliably tells me if someone opened it).

Everytime I get mail, the sensor can tell the date and time it arrived… very useful indeed, BUT:

I don’t only want to be notified when it was opened last,
instead I want to count the times it was opened until I reset the counter (for instance if I was not at home a few days)…

And on top of that, I wanted only one single sensor and automation to make it work.

(I know its ambitious, but I found this Idea from a movement detection sensor somewhere in this forum, which works great for me for years now:

data_template:
  "0": "{{ states('var.last_motion') }}"
  "1": "{{ state_attr('var.last_motion', '0') }}"
  "2": "{{ state_attr('var.last_motion', '1') }}"
  "3": "{{ state_attr('var.last_motion', '2') }}"
  "4": "{{ state_attr('var.last_motion', '3') }}"
  "5": "{{ state_attr('var.last_motion', '4') }}"
  "6": "{{ state_attr('var.last_motion', '5') }}"
  "7": "{{ state_attr('var.last_motion', '6') }}"
  "8": "{{ state_attr('var.last_motion', '7') }}"
  "9": "{{ state_attr('var.last_motion', '8') }}"
  entity_id: var.last_motion
  state: >-
    {{ trigger.to_state.attributes.friendly_name }}: {{
    as_timestamp(trigger.to_state.last_changed) | timestamp_custom('%H:%M:%S')
    }}
service: python_script.set_state

This is an Automation, using a custom python script (set_state.py) to set a “variable”-entity with 10 attributes, adding the actual state and cycling through, as soon as it runs again…

So far so good…
Problem here is, this is limited to 10 “last states”, so I thought about some templating to get the attribute-list filled based on the last attributes-count (adding it up everytime someone triggers the automation)…

it took me hours to figure this out (esp. the formatting of the data block):

data:
{
  Last Empty:
  "{{as_timestamp(states.automation.empty_mailbox.attributes.last_triggered) | timestamp_custom('%A %d. %B %Y') }}",
  Last Mail: "{{ as_timestamp(trigger.to_state.last_changed) | timestamp_custom('%A %d. %B %Y (%H:%M)') }}",
  {%- set lettercount = states.var.mailbox_status.attributes | count -4 | int -%}
  {%- set attributes = states.var.mailbox_status.attributes | list -%}

  {% for i in range(lettercount+1) -%}
  "{{ loop.index }}": "{{ state_attr('var.mailbox_status', attributes[lettercount]) }}",
  {% endfor %}

  entity_id: "var.mailbox_status",
  state: "{{ lettercount }}"
}
service: python_script.set_state

attributes” lists all attributes of the sensor for me to later move its data to another line.
lettercount” = counts the attributes of the sensor and subtracts the 3 static attributes, which are shown by states.var.mailbox_status.attributes in HA:

mailbox_status:
  unit_of_measurement: 'Postings'
  friendly_name: Mailbox Status
  icon: hass:email-sync-outline

Plus a 4th and 5th one, when I add the “Last Empty” and “Last Mail” Attributes…
But somehow this is not working reliably enough…

Does someone of you have any good Idea how to realize what I’m trying to do?

Random question, couldn’t you use an integer helper and use the last modified time if all your after is the total count and last time you had any post?

I could make a helper, yes… but initially wanted it to be only one sensor with some smart logic…
But after all simple things are easier to maintain…

I will probably end up doing a mix of my initial Idea and yours.
Thank you very much for your hint.

I solved it using a helper counter:

Automation mailbox_new:

action:
  - service: counter.increment
    data: {}
    target:
      entity_id: counter.mailbox
  - service: python_script.set_state
    data: >
      {
      "entity_id": "var.mailbox",
      "state": "{{ states('counter.mailbox') }}",
      {%- set lastmail = as_timestamp(trigger.to_state.last_changed)|timestamp_custom('%d.%m.%Y (%H:%M)') -%}
      {%- set lastempty = as_timestamp(state_attr('automation.empty_mailbox','last_triggered'))|timestamp_custom('%d.%m.%Y (%H:%M Uhr)') -%}
      "Last Empty": "{{ lastempty }}",
      "Last Mail": "{{ lastmail }}",
      "{{ states('counter.mailbox') }}": "{{ lastmail }}"
      }

Automation empty_mailbox:

action:
  - service: homeassistant.update_entity
    target:
      entity_id: var.mailbox
  - service: counter.reset
    target:
      entity_id: counter.mailbox
  - service: python_script.set_state
    data:
      "Last Mail": "{{ as_timestamp(state_attr('automation.mailbox_new','last_triggered'))|timestamp_custom('%d.%m.%Y (%H:%M)') }}"
      entity_id: var.mailbox
      state: 0