Have you ever waited so keenly for your mail to be delivered that you kept an eye on the mailbox all day, just waiting for the postie to arrive? This project aims to help with exactly that: Use sensors mounted in the mailbox to detect when new mail is deposited, and use it as a trigger to send a notification.

Contact sensors are good for monitoring individual doors and windows around the house, but I was interested in using two contact sensors together to assess the presence of mail in a mailbox, by monitoring both the deposit slot and the rear door.

An example video from my Twitter post

Interaction flow

A diagram showing how messages from the Mijia contact sensors are delivered to Home Assistant and then through to Pushbullet.
Two Zigbee contact sensors communicate to Zigbee2mqtt and Home Assistant to influence the state of a synthetic mailbox sensor.

Devices

For each contact sensor, the main part includes a reed switch, a battery, and a Zigbee transmitter. The small part is just a magnet that triggers the reed switch in the main part when it is nearby.

When mounting contact sensors, it's important keep the "reset" button hole on the main part accessible to make it easier to pair and re-pair it with the Zigbee hub.

Deposit slot contact sensor

As shown here, the deposit slot contact sensor is mounted in two parts inside the mailbox. The main part is glued to the inside below the deposit slot, and the small part is glued to a plastic hinge which is suspended from the ceiling. The hinge support also has a thick "butt" of extra plastic to prevent it from opening too far, which could cause the small part to accidentally become attracted to the mailbox ceiling.

Rear door contact sensor

The contact sensor for the rear door is mounted more simply at the back of the mailbox. The main part is glued to the ceiling close to the rear door, while the small part is glued inside the door in such a way that opening the door moves the small part further away from the main part.

Home Assistant configuration

As the contact sensors are just normal Zigbee2mqtt device integrations, it's easy to use their state changes to update a synthetic template sensor.

I also included a 'clear' script that is able to clear the mailbox state, in case I want to acknowledge some mail that is already present, but want to continue to get alerted when more mail arrives.

A flowchart showing how the mailbox state is calculated based on the state of the contact sensors and the 'clear mailbox' script.
Using the contact sensor device states and script execution state to calculate the mailbox sensor value.
$ cat ${HOME_ASSISTANT}/configuration.yaml
    
...
binary_sensor:
  - platform: template
    sensors:
      mailbox:
        friendly_name: "Mailbox"
        entity_id:
          - binary_sensor.0x00158d000357fe12_contact
          - binary_sensor.0x00158d000357feef_contact
        device_class: motion
        value_template: >-
          {% if is_state('binary_sensor.mailbox', 'off') %}
            {{ is_state('binary_sensor.0x00158d000357fe12_contact', 'on') }}
          {% else %}
            {{ is_state('binary_sensor.0x00158d000357feef_contact', 'off') and is_state('script.clear_mailbox', 'off') }}
          {% endif %}
        icon_template: >-
          {% if is_state('binary_sensor.mailbox', 'off') %}
            {{ 'mdi:mailbox-up-outline' if is_state('binary_sensor.0x00158d000357fe12_contact', 'on') else 'mdi:mailbox-outline' }}
          {% else %}
            {{ 'mdi:mailbox-up-outline' if is_state('binary_sensor.0x00158d000357feef_contact', 'off') and is_state('script.clear_mailbox', 'off') else 'mdi:mailbox-outline'}}
          {% endif %}
...

The script simply triggers an entity update, and waits until the mailbox sensor has been reset.

$ cat /home/homeassistant/.homeassistant/scripts.yaml
    
...
clear_mailbox:
  alias: 'Clear mailbox'
  sequence:
    - wait_template: "{{ is_state('script.clear_mailbox', 'on') }}"
    - service: homeassistant.update_entity
      data:
      entity_id: binary_sensor.mailbox
    - wait_template: "{{ is_state('binary_sensor.mailbox', 'off') }}"
      timeout: '00:00:02'
...

And finally, the automation to trigger a Pushbullet notification.

$ cat /home/homeassistant/.homeassistant/automations.yaml
    
...
- alias: 'Mailbox sensor'
  trigger:
    - entity_id: binary_sensor.mailbox
      platform: state
      to: 'on'
  action:
    - service: notify.notify_pushbullet
      data:
        message: 'Mail delivery!'
...

Wrap-up

I was worried about the Zigbee signal range of the contact sensors resulting in missing updates, but they appear to report their state to the Zigbee2mqtt hub consistently, even though each update reports a link_quality of 0. Nevertheless, I'm happy to call this a success.

If you have any feedback or questions related to this article, please reply to my post on Twitter.

This article is part of the Home automation set.