Transforming an Old Doorbell with Smart Alerts

Kyle Niewiada on July 03, 2022

5 Minute Read | Medium project

Updated on July 03, 2022

Original doorbell to the house

For the last year I’ve been retrofitting tech into our home. Our house is the epitome of luxury featuring a ragged carpeted wall to promote sound deadening. Due to this ingenious addition, it’s difficult to hear things like the doorbell while we’re watching TV or in a meeting.

How do we solve this? Take out the carpeted wall and make the doorbell louder. NO. We make the doorbell smart 🧠 and take pride it doing it ourselves!

This is going to be super casual.

It will be a pretty high level overview at getting Shelly 1 relays to intercept my doorbell signals. I will skip over things like how to flash ESPHome onto the Shelly relay.

It’s really to allow users near this ecosystem to steal from my project. Just like how I stole some ideas from Frenck.



Hardware Requirements

Here’s an approximation for the hardware costs involved with the project.

I used a waterproof junction box because the doorbell wiring was too close to the main water line for my comfort. It helps me sleep better.

Two Shelly 1 inside of a conduit box wired up to each doorbellWiring a Shelly 1 for each doorbell

Software Requirements

This guide is going to assume the user is familiar with Home Assistant and ESPHome. If they are not, check them out! Those are great projects.


Two Shelly Relays?

If you’ve read the hardware requirements above, you might be asking yourself “Why are there two Shelly 1 relays? Surely you don’t need that.”

You’d be right! However, did you know some homes have two doorbells? I guess the thought is that you put the second doorbell by your back door in case a neighbor is stopping by.

When this happens, a chime box can be wired to give each doorbell a different chime (Ding vs Ding Dong) allowing the homeowner to know which door their visitor is at. Neat!

Except our second doorbell is also in the front of our house.. just 15 steps from the first doorbell. We’ve had people ring our second doorbell before, so we’re just going to proceed supporting it because I think it’s bougie. 😎

Shelly 1 Configuration

Mentioned earlier, we’re going to use ESPHome to configure our Shelly 1 relays.

There are 5 inputs on the Shelly 1 relay.

The Shelly 1 relay will be powered from our low voltage wires (or really, whatever you can find for the line and neutral).

We’ll connect the Shelly 1 input connector to the doorbell transformer power. That power (when switched on) will travel through the Shelly 1 output connector, triggering the chime box.

Finally, the doorbell button signal will be captured by the Shelly 1 switch input.

Capturing the doorbell signal with the switch input accomplishes two things.

  1. We now know via software that the doorbell was pressed since we triggered it via the Shelly switch input.
  2. Because we’re choosing to pass the signal onto our doorbell chime, we can also choose not to pass the signal along 🔇.

I’ve added functionality to mute the doorbell chime via an exposed input. It’s useful to pair with bedtime routines to keep the house quiet.

🏅 Achievement unlocked: Muting a doorbell

Home Assistant dashboard showing contents of the front door doorbellHome Assistant dashboard of Front Door Doorbell

But we can take that a step further. Since we’re in control of when our doorbell chimes, why not have some fun with that power? In the ESPHome config below, I’ve included a little script that will repeatedly trigger the doorbell chime for 30s when toggled on. DING-DONG.. Ding-Dong.. ding-dong.. After 30s, the script should stop toggling the relay.

Why have I done this? I’m not really sure. It just seemed like a fun idea. Maybe you enjoy making dogs bark, annoying your significant other, or pretending to have a high-tech burglar alarm to annoy them away.

It’s probably a bad idea. But don’t let that stop you! Just be careful of burning out your relay or doorbell chime. I’m at least 20% sure it’s not meant to operate like that (hence the 30s cap).

🏅 Achievement unlocked: Annoying as bell

# Basic Config
# shelly-one-01
# Front Door Doorbell

  devicename: Front Door Doorbell
  deviceid: front_door_doorbell

  name: shelly-one-01
  comment: ${devicename}
  platform: ESP8266
  board: esp01_1m

  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
    ssid: "${plugtag} Hotspot"
    password: !secret ap_hotspot_password

# Enable captive portal if wifi ever changes

# Enable Home Assistant API
  password: !secret api_password
    key: !secret encryption_pre_shared_key

  password: !secret ota_password

# Global to store the on/off state of the chime
  - id: chime_var
    type: bool
    restore_value: true
    initial_value: 'true'
  - id: chime_alarm_var
    type: bool
    restore_value: false
    initial_value: 'false'  

# Enable logging

  - platform: homeassistant
    id: my_time

# Sensors that the ESPhome unit is capable of reporting
  - platform: wifi_signal
    name: "${devicename} WiFi Signal"
    update_interval: 300s

  - platform: gpio
      number: GPIO5
    name: ${devicename}
      - delayed_on: 100ms
      - delayed_off: 25ms
      # Only turn on the chime when it is active.
            - switch.is_on: chime_is_enabled
            - switch.turn_on: relay
      # On release, turn of the chime.
      - switch.turn_off: relay

  # Switch to enable/disable chime when
  # doorbell button is pushed.
  - platform: template
    id: chime_is_enabled
    name: ${devicename} Chime
    icon: mdi:power-settings
    restore_state: false
      - globals.set:
          id: chime_var
          value: 'true'
      - globals.set:
          id: chime_var
          value: 'false'
    lambda: |-
      return id(chime_var);
  - platform: template
    id: chime_alarm
    name: ${devicename} Alarm
    icon: mdi:alarm-bell
    restore_state: false
      - globals.set:
          id: chime_alarm_var
          value: 'true'
      - script.execute: alarm_script
      - delay: 30s
      - switch.turn_off: chime_alarm
      - globals.set:
          id: chime_alarm_var
          value: 'false'
    lambda: |-
      return id(chime_alarm_var);
  - platform: gpio
    id: relay
    internal: true
    name: ${devicename} Doorbell Switch
    pin: GPIO4
    restore_mode: RESTORE_DEFAULT_OFF
  - id: alarm_script
    - while:
          lambda: |-
            return id(chime_alarm_var);
        - switch.turn_on: relay
        - delay: 500ms
        - switch.turn_off: relay
        - delay: 500ms

Alerts for All

Great, we have a chime that we can add into Home Assistant. That’s not very useful yet. So let’s add notifications!

I also happen to have a camera by the doorbell, so I include a camera snapshot in my notifications.

Using the companion Home Assistant app on our phone, we can push notifications to our device using the notify service.

Simulated phone doorbell notificationSimulated phone notification from a doorbell press

If we use an Android TV, we can also use the nfandroidtv integration in order to display alerts on our TV.

Simulated Android TV doorbell notificationSimulated Android TV notification from a doorbell press

Here’s a useful Home Assistant automation blueprint that I use to configure my doorbells and notify my various devices.

There’s probably a better way to send the images without saving them to the disk in different locations. But it’s malleable enough that I can tweak settings without too many breaking changes.

  name: Doorbell Alert Notifications
  description: >
    This automation blueprint creates a camera snapshot if doorbell is detected 
    and sends a notification to your device with the picture.
      - Add `- /tmp` to `allowlist_external_dirs:` in the `configuration.yaml`
    Required entities:
      - Doorbell sensor (binary_sensor in None class)
      - Camera entity
      - Notify device entity    
  domain: automation

      name: Doorbell sensor
      description: The sensor which triggers the snapshot creation (domain binary_sensor).
            domain: binary_sensor

      name: Camera
      description: The camera to create the snapshot (domain camera).
          domain: camera
      name: (Optional) Camera Delay
      description: Delay after doorbell before taking a snapshot from the camera. Useful when your camera stream has a bit of lag.
      default: 1
            min: 0
            max: 15
            unit_of_measurement: seconds
            mode: slider             

      name: (Optional) Snapshot Delay
      description: Delay before sending the notification after writing the camera snapshot to disk.
      default: 1
            min: 0
            max: 15
            unit_of_measurement: seconds
            mode: slider            
      name: (Optional) Rate Limit
      description: How many seconds to wait before we can send another notification.
      default: 10
            min: 0
            max: 60
            unit_of_measurement: seconds
            mode: slider             

      name: (Optional) Notification title
      description: 'Default: "🔔 {{doorbell_sensor_name}}"'
      default: "🔔 {{doorbell_sensor_name}}"
      name: (Optional) Notification Standard message
      description: 'Default: "{{ doorbell_sensor_name }} triggered."'
      default: "{{ doorbell_sensor_name }} triggered."      

  platform: state
  entity_id: !input doorbell_sensor
  from: "off"
  to: "on"

  doorbell_sensor: !input doorbell_sensor
  doorbell_sensor_name: "{{ states[doorbell_sensor].name }}"
  camera: !input camera
  notification_title: !input notification_title
  snapshot_delay: !input snapshot_delay
  camera_delay: !input camera_delay  
  rate_limit: !input rate_limit
  snapshot_file_path: "/config/www/tmp/snapshot_{{ states[camera].object_id }}.jpg"
  snapshot_image_path: "/local/tmp/snapshot_{{ states[camera].object_id }}.jpg"
  notification_message_standard: !input notification_message_standard

  - delay: "{{ camera_delay }}"   
  - service: camera.snapshot
    entity_id: !input camera
      filename: "{{ snapshot_file_path }}"
  - delay: "{{ snapshot_delay }}"      

  # Update this service group with whomever you'd like to notify
  - service:
      title: "{{ notification_title }}"
      message: "{{ notification_message_standard }}"        
        notification_icon: mdi:bell
        group: doorbell
        channel: doorbell
          ttl: '0'
          priority: high
          interruption-level: time-sensitive
        image: "{{ snapshot_image_path }}"

  # Update this service group with whomever you'd like to notify
  - service: notify.screens
      title: "{{ notification_title }}"
      message: "{{ notification_message_standard }}"
        duration: 10
          path: "{{ snapshot_file_path }}" 

  - delay: "{{ rate_limit }}"

mode: single
max_exceeded: silent     


Final Thoughts

I don’t think I’m a luddite, but sometimes I really appreciate older things. Who knows, maybe I’ll come around to buying a video doorbell once they are better looking.

It’s super useful to get alerts when I’m busy, away from home, or have the ability to mute alerts while the baby naps.

I had an existing doorbell, existing camera, and accessible wiring. With a little bit of fun, I was able to transform (pun intended) our doorbell setup into something I’d seen advertised by other smart doorbells. But doing it myself makes me happy.

Previous Article Next Article
comments powered by Disqus