Make a sensor of your ordinary doorbell with RPi GPIO

I wanted to connect my ordinary, wired, current doorbell to HA. And since my HA is running on a Raspberry Pi, I wanted to connect my doorbell button and doorbell chime to the GPIO interface of the RPi.

Of course 100+ others have connected a doorbell in 100+ ways, but my goals were to reuse the current components I had (Raspberry Pi, doorbell button, doorbell chime) and find a solution without soldering and as cheap as possible.

Then this would be the HA way to activate the chime when somebody is pushing the doorbell button:

- alias: 'Doorbell: Chime'
  trigger:
    - platform: state
      entity_id: binary_sensor.doorbell_button
      to: 'on'
  action:
    - service: switch.turn_on
      entity_id: switch.doorbell_chime
    - service: switch.turn_off
      entity_id: switch.doorbell_chime

The possibilities would be endless:

  • don’t chime in the night
  • multiple pushes on the button resulting in chiming only once
  • activate other things when somebody pushes the button
  • use the chime in other automations
  • etc.

Well, it worked. Let’s describe what I did.

Please note that my knowledge of electronic circuits is very limited. Most of the solution was found by combining various things on the internet. I could easily have blown up my RPi and you can do also. Check everything and be careful with your setup, because doorbell transformers can harm or hurt you, even with low voltages.

The old situation

This was the old setup: a doorbell button connected to a doorbell chime that was powered by a transformer.

old_situation

I wanted to cut the wires somewhere between the button and the chime and connect all the wires somehow to some of the 40 pins of the GPIO interface of the Raspberry Pi. There is a component to set up sensors and switches in HA that use the GPIO:

Setting up the hardware and the wiring

There has to be an extra hardware component between the chime and the RPi, because the voltage of the chime is too high for the RPi to handle. I my case the doorbell transformer gives 8V. The RPi can handle max 5V directly. I bought an SPDT Relay.
This 2-Channel SPDT Relay has two single pole - double throw (SPDT) switches. It only requires low-voltage and low current signals to control those switches. Specifically, you can use 5V DC to control max.250V AC or 110V DC. Just what I needed, if you neglect the fact that I will use only one of the two switches. And for less than 10 euros including a nice transparant case and some wires.

This is my wiring schedule. Mind you, it’s on Bert&Ernie level. Blue is 8V, green is 5V, orange is 3.3V. You can see that the 8V is never reaching the RPi. You have to cut the current wiring between the button and the chime and reconnect both sides of the cut to the GPIO directly resp. to the SPDT Relay.

The green wires belong to the switch in HA that controls the chime. The orange wires belong to the binary_sensor in HA that senses the doorbell button. More details about the GPIO pin layout can be found here.

Here’s a picture of the relay that’s connected to the RPi. Of course there’s a piece of duct tape. Every DIY project has to have some.
:wink:

How it should work

What happens if somebody pushes the doorbell button?

  1. When you press the button, the current starts to flow from pin 1 to pin 37 and the RPi will sense it.
  2. The automation in HA will trigger on the binary_sensor connected to GPIO 26 (pin 37) and will activate the switch connected to GPIO 4 (pin 7).
  3. Current will start flowing and SIG1 of the SPDT Relay will sense it and switch the high voltage side of this component. Current will flow in the circuit that’s now created in the blue wires and the chime will ‘ding’.
  4. After a short time the automation will turn off the switch again. Current will stop flowing in the green wires, the relay will switch off the circuit in the blue wires and the chime will ‘dong’. *)

*) You can read ‘starts to ring’ for ‘ding’ and ‘stops to ring’ for ‘dong’ if you don’t have a ding-dong chime but a ringing chime.

Configuring HA

Now for the software side. You have to configure a couple of things. First the binary_sensor for the doorbell button and the switch for the doorbell chime.

binary_sensor:
- platform: rpi_gpio
  pull_mode: 'DOWN'
  ports:
    26: Doorbell button

switch:
- platform: rpi_gpio
  ports:
    4: Doorbell chime

I’ve split the automation (form the top of the topic) in an automation and a script. In that way you can also use the activation of the chime better in other automations or UI buttons.

I added a condition to restrict the chime to once each 10 seconds no matter how often the button is pushed.

automation:
- alias: 'Doorbell: Chime'
  trigger:
    - platform: state
      entity_id: binary_sensor.doorbell_button
  condition:
    # At least 10 seconds between chimes.
    - condition: template
      value_template: >-
        {%- if state_attr("script.chime_doorbell", "last_triggered") -%}
          {{ as_timestamp(now()) - as_timestamp(state_attr("script.chime_doorbell", "last_triggered")) > 10 }}
        {%- else -%}
          true
        {%- endif -%}
  action:
    - service: script.turn_on
      entity_id: script.chime_doorbell

In the script I tried to use a delay of 500 msecs, but that didn’t work. The delay became too large sometimes. The current script looks rather strange, but it helps to keep a consistent delay.

script:
  chime_doorbell:
    alias: 'Chime doorbell'
    sequence:
    - service: switch.turn_on
      entity_id: switch.doorbell_chime
    - service: input_boolean.turn_on
      entity_id: input_boolean.dummy_delay
    - service: input_boolean.turn_off
      entity_id: input_boolean.dummy_delay
    - service: input_boolean.turn_on
      entity_id: input_boolean.dummy_delay
    - service: input_boolean.turn_off
      entity_id: input_boolean.dummy_delay
    - service: input_boolean.turn_on
      entity_id: input_boolean.dummy_delay
    - service: input_boolean.turn_off
      entity_id: input_boolean.dummy_delay
    - service: input_boolean.turn_on
      entity_id: input_boolean.dummy_delay
    - service: input_boolean.turn_off
      entity_id: input_boolean.dummy_delay
    - service: input_boolean.turn_on
      entity_id: input_boolean.dummy_delay
    - service: input_boolean.turn_off
      entity_id: input_boolean.dummy_delay
    - service: switch.turn_off
      entity_id: switch.doorbell_chime

input_boolean:
  dummy_delay:
    name: Dummy delay
    initial: false

Have fun! Please help me to answer questions of users that need a more in-depth knowledge of electrical circuits.

2 Likes

Be aware there may be issues with short pulses from the doorbell switch:

I wasn’t aware of this bug in the GPIO component. So actually it’s on the binary_sensor part (that’s triggered by the hardware switch in the doorbell button). I don’t want to end up with an unreliable doorbell setup of course. Thx for reporting.

I didn’t experience any issue so far, but I will do some manual testing to see if and how severe I’m impacted by this bug.

It seems to be more of a problem when HA is busy and for short pulses (<1 sec). There’s more discussion here: https://community.home-assistant.io/t/pi-gpio-binary-sesnsor/

I did some testing (n=100+) and found out that indeed I’m hit by the RPi GPIO bug.
:frowning:

In 20% of the doorbell pushes HA missed the ‘on’ event. In another 12% the ‘off’ wasn’t seen. This results in a chime of 74% on all future doorbell pushes (because of I’m only chiming on the ‘on’ event). That’s too low for a reliable doorbell.

I changed the automation to trigger on all state changes of the binary_sensor by removing the to: 'on' line. This results in a chime of 80% on all future doorbell pushes. That’s a bit better, but still too low for a reliable doorbell.

When I take into account that my doorbell chime is situated close to the front door and people will push twice if they didn’t hear the chime, then this results in a chime of 96% on all future times somebody wants to chime. In all cases the chime will max sound once because of the condition in the automation. Not sure if this will be enough for the WAF…

I saw your work around with a separate RPi + python script. I will give it a couple of weeks in production, but maybe I have to switch to this solution also if the bug isn’t solved quickly.

I found a much easier solution than the python script. It’s a GPio to MQTT client configured with yaml:

2 Likes

I replaced the RPi GPIO with a Wemos D1 Mini (about 5 euro) last week. I was still using the solution with the RPi GPIO. The new solution has some big advantages over the old solution:

  • No more false positives (a.k.a. phantom ringing). At least: not till now. :wink:
  • No more false negatives (a.k.a. “hey, your bell does’t work, I had to ring twice”)
  • Works even when HA is restarting or in another non-available state, because part of the automation is moved to the D1 Mini.

Thanks for sharing your wiring diagram! I took the plunge and went with @tom_l’s suggestion to use pi-mqtt-gpio, here is my config.yaml configuration file to detect the doorbell, set your MQTT server address and credentials accordingly:

mqtt:
  host: localhost
  port: 1883
  user: [username]
  password: [password]
  topic_prefix: home

gpio_modules:
  - name: raspberrypi
    module: raspberrypi

digital_inputs:
  - name: doorbell_button
    module: raspberrypi
    pin: 26
    on_payload: "ON"
    off_payload: "OFF"
    pullup: no
    pulldown: yes

And here is my Home Assistant configuration to expose the doorbell over MQTT (make sure you configure your MQTT component in the HA UI first):

binary_sensor:
  - platform: mqtt
    name: Doorbell Button
    state_topic: "home/input/doorbell_button"
    payload_on: "ON"
    payload_off: "OFF"

And finally my automation to send a push notification whenever the doorbell rings, [mydevice1] and [mydevice2] are just the names of the app entities:

notify:
  - name: All Devices
    platform: group
    services:
      - service: mobile_app_[mydevice1]
      - service: mobile_app_[mydevice2]

automation:
- alias: Doorbell Notification
  description: Sends a notification when the doorbell rings
  trigger:
  - entity_id: binary_sensor.doorbell_button
    platform: state
    from: 'off'
    to: 'on'
  action:
  - service: notify.all_devices
    data:
      title: "🔔 Ding dong!"
      message: "Someone is at the door"

I didn’t do the actual doorbell wiring because I’d like to use my Sonos speakers to do the actual chime, but this setup gives me a push notification reliably every time I push the doorbell! With direct Home Assistant integration I missed a ton of activations.

Thanks again for describing your solution!

1 Like

This beauty works out of the box :slight_smile:

I am also trying to get the doorbell (a simple switch) working via a GPIO of the RPi, where Home Assistant is running on.
I do have the HACS integration “Raspberry Pi GPIO” running, but can’t figure out how to get the entity in my list.

The following in comfiguration.yaml does not give an error obviously, but how to get the status read by Home Assistant?

template:
  - binary_sensor:
    - name: Deurbel-14
      unique_id: deurbel_voordeur_sensor_poort_17
    #   platform: rpi_gpio
    #   ports:
    #     17: deurbel
      state: >-
        {{ true }}

I think to have solved it by getting the code outside the template. This helped me understanding the whole better :wink:

binary_sensor:
  - platform: rpi_gpio
    sensors:
      - port: 17
        name: "Deurbel-14"
        unique_id: "deurbel_voordeur_sensor_poort_17"
        bouncetime: 80
        invert_logic: true
        pull_mode: "UP"