Make any doorbell smart and detect press event locally (tuya too!)

I own Tuya Doorbell which recently got integrated into Home Assistant. However, it is still missing press event and is cloud only. I wanted to trigger an automation on when someone presses the doorbell, even if my internet (or cloud) is offline. I wasn’t able to find too many tutorials on how to do this, so below is my overview on how to achieve this.

After reading this, you will be able to:

  • Detect when doorbell is pressed
  • Ring the doorbell via Home Assistant

My doorbell communicates through 433mhz with in house unit. Meaning, this solution will also work for any doorbell communicating via 433mhz with an exception of rolling codes.

I am not going to cover every step in detail. Steps not covered in too much details have a lot of other more detailed guides available through google and youtube. I am going to cover parts which I needed to discover on my own.

Hardware needed: Sonoff 433 RF Bridge

1.) Flash Sonoff 433 RF Bridge with Tasmota, including the RF chip. This is not as hard as it first seems, no soldering or device modification is needed at all. You do not need to damage the lines for 3v3 and ground from usb when flashing the chip, just connect the 3v3 and GND lines just like when flashing tasmota.
2.) Make sure that your devices module is set up as Sonoff Bridge (25) and you have turned ON RF chip before closing up the device.
3.) Connect Tasmota to your MQTT server, note down your devices topic from MQTT settings, you will need this later. It should be in format of tasmota_* unless changed manually.
4.) Add tasmota integration for the device into Home Assistant

At this point you are pretty much set up HW wise, all you need now discover your doorbell RF code. For detecting the code, follow this part of the guide. Make sure to get a few codes of the same action (press doorbell multiple times) and select the most similar one. You can now use this code to make your doorbell ring by using this service:

service: mqtt.publish
  data:
     topic: cmnd/YOUR_TOPIC_YOU_NOTED_DOWN/rfraw
     payload: B1_TO_B0_CONVERTED_CODE

Make sure to remove any spaces from B1_TO_B0_CONVERTED_CODE. In my case, doorbell always sent 3 individual codes spaced around 300ms apart. What I have done is converted all of those and simply chained them in a script like so:


ring_doorbell:
  sequence:
    - service: mqtt.publish
      data:
        topic: cmnd/MY_TOPIC/rfraw
        payload: CONVERTED_CODE_1
    - service: mqtt.publish
      data:
        payload: CONVERTED_CODE_2
        topic: cmnd/MY_TOPIC/rfraw
    - service: mqtt.publish
      data:
        payload: CONVERTED_CODE_3
        topic: cmnd/MY_TOPIC/rfraw
  mode: single
  alias: Ring doorbell

You can now run the script and hopefully you will hear your doorbell ring! That is nice for training dogs not to bark, but how can we listen to doorbell press?

Your Tasmota integration exposes sensor sensor.tasmota_last_restart_time. We will use this to turn on learning mode every time our device reboots, so that it always listens. We can do it with this simple automation:

id: '1640021011774'
  alias: Turn on RF listener
  description: ''
  trigger:
  - platform: template
    value_template: '{{ as_timestamp(now()) - as_timestamp(states.sensor.tasmota_last_restart_time.state)
      < 60 }}'
  condition: []
  action:
  - service: mqtt.publish
    data:
      topic: cmnd/YOUR_TOPIC_YOU_NOTED_DOWN/rfraw
      payload: '177'
  mode: single

Now, go ahead and create a helper input_boolean entity. I called this Doorbell. Add following automation below:

id: '1640017923836'
  alias: Detect doorbell
  description: ''
  trigger:
  - platform: mqtt
    topic: tele/YOUR_TOPIC_YOU_NOTED_DOWN/RESULT
  condition:
  - condition: or
    conditions:
    - condition: template
      value_template: '{{ ''CONVERTED_CODE'' in trigger.payload_json[''RfRaw''][''Data''] }}'
    - condition: template
      value_template: '{{ ''CONVERTED_CODE'' in trigger.payload_json[''RfRaw''][''Data''] }}'
  action:
  - service: input_boolean.turn_on
    target:
      entity_id: input_boolean.doorbell
  - delay:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 0
  - service: input_boolean.turn_off
    target:
      entity_id: input_boolean.doorbell
  mode: single

This will turn on the helper input boolean on for one second, and turn it back off as soon as it detects RF code matching the conditions. In my case, only a part of the RF code was always the same, so I used that. Some doorbells or devices might be using multiple rolling codes (like 4 repeating), in that case just add more conditions into or section. As my second code, I added a random remote I had laying around for testing the automation so I do not have to go out every time.

Now you are almost finished, all you need now is an automation that does stuff on the helper input_boolean change. Below is mine.


- id: '1640018496945'
  alias: Someone rang the doorbell
  description: ''
  trigger:
  - platform: state
    entity_id: input_boolean.doorbell
    to: 'on'
  condition: []
  action:
  - service: script.turn_on
    target:
      entity_id:
      - script.someone_is_at_the_door_lights_bedroom
      - script.someone_is_at_the_door_lights_office
      - script.someone_is_at_the_door_lights_living_room_lamp
      - script.someone_is_at_the_door_lights_kitchen_leds
      - script.send_doorbell_photo
  - service: tts.google_say
    data:
      entity_id: media_player.the_home
      message: Someone is at the door!
  mode: single

In my case:

  • It sends FB message with photos from doorbell camera and 2 other cameras stating someone rang doorbell
  • Sends notification to my Android TVs using notify android TV integration
  • Blinks lights in every room, returning them to previous state
  • Announces that someone rang a doorbell via my Google Homes.

Good luck!

4 Likes

Thankyou so much for this. Finally got this working!

1 Like

Hello.
Your solution seems amazing, but for now I am missing the expertise to mess with hardware and don’t have the sonnof bridge or means to flash it.
So using what I have, I thought of a possible new solution, but I need your help:

What I have now:

  • 1 x Tuya doorbeel installed
  • 2 x Chimes paired with the Tuya Doorbell
  • NOT RELATED YET: Broadlink RM3+ Pro (with RF)
  • NOT USED: Old Ring doorbell, probably V1.0, working in HA, but with no chimes

What I am planning:

  • Replace the Tuya doorbell with the Ring one (this would leave me without the chimes)

My problem, my possible solution and what I need:

  • I can detect the button press of the Ring doorbell in HA
  • I CANNOT recieve a valid code from the Tuya dooorbell to the Broadlink (I know it’s probably not possible, not right hardware as you mentioned on other post)
  • I CANNOT send yet na RF code from Broadlink to activate the chimes because I don’t know the format they need to be programmed. In short, I need a valid code(s) (assuming most Tuya doorbells use the same format or similar) so that I can send it from Broadlink to program the chimes, and then use them with the Ring in HA.

What I am asking:

  • Could you please sem my a VALID and REAL RF code, probably in private, so I can test it with my crazy idea?

Hope it was not too confusing, and I hope you understand what I am asking. Thanks in advance!

Hey, you need the sonoff with special firmwares flashed. It’s not possible with broadlink.

You can slo do this with esphome and a CC1101 (433) (tran/re)ceiver.

My setup: ESP8266 with CC1101 and the following config.

Add custom integration to config/esphome, cc1101.h from dbuezas/esphome-cc1101 (github.com)

Make sure to wire it correctly.
RCSwitch-CC1101-Driver-Lib/WIRING ESP8266.txt at master · TMInnovations/RCSwitch-CC1101-Driver-Lib (github.com)

Note: I ordered mine from AliExpress and they had a wrong wirediagram…

And the esphome config:

sensor:
  - platform: custom
    lambda: |-
      auto my_sensor = new CC1101(
        D5, // SCK
        D6, // MISO
        D7, // MOSI
        D8, // CSN
        D1, // GDO0
        200, // bandwidth_in_khz
        433.92 // freq_in_mhz
      );
      App.register_component(my_sensor);
      return {my_sensor};
    sensors:
      id: transciver
      internal: true
remote_transmitter:
  - pin: D1 # This is GDO0
    carrier_duty_percent: 100%

remote_receiver:
  - pin: D1 # This is GDO0
      # on the esp8266 use any of D1,D2,D5,D6,D7,Rx
      # Don't use D3,D4,D8,TX, boot often fails.
      # Can't be D0 or GPIO17 b/c no interrupts
    dump:
      - raw
binary_sensor:
  - platform: remote_receiver
    name: deurbel
    raw:
      code: [501, -1510, 1497, -509, 494, -1514, 468, -1517, 1495, -485, 1523, -484, 1525, -487, 1496, -509, 500, -1506, 499, -1484, 1502, -497, 515, -1479, 502, -1500, 1518, -496, 491, -1497, 515, -1470, 1539, -468, 514, -1523, 486, -1497, 1515, -494]

You need to adjust the code with your code!

Open the logs of the esp and press the ring button.
All raw codes will be dumped. In my case several times right after eachother…
Copy that and put in your esp config.

And done, you now have a sensor that turn on/off when the doorbell is pressed.