Mailfob is an open source smart mailbox alerter using a Raspberry Pi Zero 2 W, an SW-420 vibration sensor, Home Assistant, MQTT, and an optional Arducam Raspberry Pi Zero camera.
Everything needed to build the Mailfob mailbox alerter.
Main computer that runs the Mailfob Python service and connects to Wi-Fi.
Detects mailbox vibration when the door moves or mail is dropped inside.
Optional 5MP Raspberry Pi Zero camera module for capturing delivery photos.
16GB or larger recommended for Raspberry Pi OS Lite and Mailfob scripts.
Use USB power, a battery pack, or a weather-safe outdoor power setup.
Protects the Pi and sensor wiring from dust, movement, and moisture.
Mailfob only needs three sensor wires plus the optional camera ribbon cable.
Use for SW-420 VCC
Connects to the VCC pin on the SW-420 sensor module.
Use for SW-420 GND
Connects to the GND pin on the SW-420 sensor module.
Use for SW-420 DO
Connects to the DO digital output pin on the SW-420.
| Device | Device Pin | Raspberry Pi Physical Pin | GPIO Name | Use |
|---|---|---|---|---|
| SW-420 Vibration Sensor | VCC | Pin 1 | 3.3V | Sensor power |
| SW-420 Vibration Sensor | GND | Pin 6 | Ground | Sensor ground |
| SW-420 Vibration Sensor | DO | Pin 11 | GPIO17 | Digital vibration signal |
| Arducam OV5647 Camera | Ribbon Cable | CSI Camera Port | Camera Interface | Optional mailbox photo |
Install Raspberry Pi OS Lite, enable SSH, connect Wi-Fi, then install the packages needed to run Mailfob.
sudo apt update
sudo apt upgrade -y
sudo apt install -y python3-pip python3-gpiozero python3-paho-mqtt
sudo apt install -y python3-picamera2 libcamera-apps
This script listens for vibration on GPIO17 and sends MQTT alerts.
from gpiozero import DigitalInputDevice
from signal import pause
from datetime import datetime
import time
import os
import paho.mqtt.publish as publish
SENSOR_GPIO = 17
MQTT_ENABLED = True
MQTT_HOST = "homeassistant.local"
MQTT_PORT = 1883
MQTT_USERNAME = ""
MQTT_PASSWORD = ""
MQTT_TOPIC_STATE = "mailfob/mailbox/state"
MQTT_TOPIC_EVENT = "mailfob/mailbox/event"
CAMERA_ENABLED = False
PHOTO_DIR = "/home/pi/mailfob/photos"
DEBOUNCE_SECONDS = 60
last_trigger_time = 0
sensor = DigitalInputDevice(SENSOR_GPIO, pull_up=False)
def send_mqtt(topic, payload):
if not MQTT_ENABLED:
return
auth = None
if MQTT_USERNAME and MQTT_PASSWORD:
auth = {
"username": MQTT_USERNAME,
"password": MQTT_PASSWORD
}
publish.single(
topic,
payload,
hostname=MQTT_HOST,
port=MQTT_PORT,
auth=auth
)
def take_photo():
if not CAMERA_ENABLED:
return None
os.makedirs(PHOTO_DIR, exist_ok=True)
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
photo_path = f"{PHOTO_DIR}/mail_{timestamp}.jpg"
os.system(f"libcamera-still -o {photo_path} --width 1280 --height 720 --timeout 1000")
return photo_path
def mail_detected():
global last_trigger_time
now = time.time()
if now - last_trigger_time < DEBOUNCE_SECONDS:
return
last_trigger_time = now
timestamp = datetime.now().isoformat()
print(f"Mailfob detected mailbox movement at {timestamp}")
photo_path = take_photo()
send_mqtt(MQTT_TOPIC_STATE, "mail_detected")
send_mqtt(MQTT_TOPIC_EVENT, f"time={timestamp}, photo={photo_path if photo_path else 'none'}")
sensor.when_activated = mail_detected
print("Mailfob is running...")
print("Using SW-420 on GPIO17 / physical pin 11")
print("Waiting for mailbox vibration...")
send_mqtt(MQTT_TOPIC_STATE, "online")
pause()
Mailfob publishes to MQTT so Home Assistant can show mailbox status and send phone notifications.
mqtt:
sensor:
- name: "Mailfob Mailbox"
state_topic: "mailfob/mailbox/state"
icon: mdi:mailbox
alias: Mailfob Mail Delivered Alert
description: Sends a notification when Mailfob detects mailbox movement
trigger:
- platform: mqtt
topic: mailfob/mailbox/state
payload: mail_detected
action:
- service: notify.mobile_app_your_phone
data:
title: "Mailfob"
message: "Mail was detected in your mailbox."
mode: single
Place the parts where they can detect mail but stay protected.
Mount the SW-420 near the mailbox door, inside wall, or bottom rear of the mailbox.
Put the Pi in a small project box and keep wiring away from water and bare metal.
Adjust the blue screw on the SW-420 so wind does not trigger it, but mail delivery does.