The Pick Me Up

We live in an apartment building with two entry gates. To be let in you need to push a button on each gate, which calls our in-apartment telephone. We pick it up and push a button to let someone in. We have to do this twice, for both gates. This has now been automated, thanks to Home Assistant and ESPHome.

I have created a 3D-printed wall attachment, which holds two servos and a microphone. It’s all connected to an ESP32 and it works like this:

  • The phone rings when someone pushes the button outside. The microphone detects this ringtone
  • The pick-up-servo lifts the receiver.
  • The other servo pushes the “open door”- button

It then lets go of the button and hangs up the receiver - and moves out of the way so you can also pick up the phone manually if you want to. I have an input boolean I can activate, which turns automatic answering on or off. Normally I have set it to just send an actionable notification to my phone when the phone rings, with an option to open the gate from there.

Video here:
https://www.youtube.com/watch?v=eGmKvuyp2_s

STLs here:
https://www.thingiverse.com/thing:4691370

ESPHome config:

  name: esp_door_opener
  platform: ESP32
  board: esp-wrover-kit

wifi:
  ssid: "YOURSSID"
  password: "YOURPASSWORD"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp Door Opener Fallback Hotspot"
    password: "PSWD"

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:
  services:
    - service: control_lift_servo
      variables:
        level: float
      then:
        - servo.write:
            id: lift_servo
            level: !lambda 'return level / 100.0;'
    - service: control_button_servo
      variables:
        level: float
      then:
        - servo.write:
            id: button_servo
            level: !lambda 'return level / 100.0;'
            
    - service: detach_lift_servo
      then:
        - servo.detach:
            id: lift_servo
    - service: detach_button_servo
      then:
        - servo.detach:
            id: button_servo

ota:

output:
  - platform: ledc
    id: lift_servo_pin
    pin: 27
    frequency: 50 Hz
  - platform: ledc
    id: button_servo_pin
    pin: 25
    frequency: 50 Hz
    
servo:
  - id: lift_servo
    output: lift_servo_pin
  - id: button_servo
    output: button_servo_pin

binary_sensor:
  - platform: gpio
    pin: 32
    name: "Door Opener Microphone"
    device_class: sound
    filters:
      - invert:

I made a script to control the movements, and it is horrifyingly ugly, due to the fact that I don’t know how to make the servo slow down in other way than this. Any help here would be greatly appreciated!

open_door:
  alias: Lift reciever and push button
  sequence:
    - service: homeassistant.turn_on
      data:
        entity_id: script.raise_handle
    - delay:
        seconds: 3
    - service: homeassistant.turn_on
      data:
        entity_id: script.push_button
    - delay:
        seconds: 5
    - service: homeassistant.turn_on
      data:
        entity_id: script.lower_handle
    - delay:
        seconds: 5
    - service: esphome.esp_door_opener_detach_button_servo
    - service: esphome.esp_door_opener_detach_lift_servo

push_button:
  alias: Push Door Opener Button
  sequence:
    - service: esphome.esp_door_opener_control_button_servo
      data:
        level: 90
    - delay:
        seconds: 5
    - service: esphome.esp_door_opener_control_button_servo
      data:
        level: 0

raise_handle:
  alias: Raise Handle
  sequence:
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 100
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 99
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 98
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 97
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 96
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 95
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 94
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 93
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 92
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 91
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 90
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 89
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 88
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 87
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 86
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 85
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 84
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 83
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 82
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 81
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 80
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 79
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 78
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 77
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 76
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 75
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 74
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 73
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 72
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 71
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 70
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 69
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 68
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 67
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 66
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 65
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 64
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 63
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 62
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 61
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 60
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 59
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 58
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 57
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 56
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 55
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 54
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 53
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 52
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 51
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 50
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 49
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 48
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 47
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 46
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 45
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 44
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 43
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 42
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 41
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 40
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 39
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 38
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 37
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 36
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 35
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 34
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 33
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 32
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 31
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 30
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 29
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 28
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 27
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 26
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 25
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 24
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 23
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 22
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 21
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 20
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 19
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 18
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 17
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 16
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 15
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 14
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 13
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 12
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 11
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 10
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 9
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 8
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 7
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 6
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 5
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 4
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 3
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 2
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 1
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: 0
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -1
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -2
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -3
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -4
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -5
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -6
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -7
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -8
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -9
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -10
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -11
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -12
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -13
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -14
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -15
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -16
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -17
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -18
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -19
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -20
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -21
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -22
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -23
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -24
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -25
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -26
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -27
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -28
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -29
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -30
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -31
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -32
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -33
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -34
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -35
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -36
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -37
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -38
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -39
    - delay:
        milliseconds: 15
    - service: esphome.esp_door_opener_control_lift_servo
      data:
        level: -40
    - delay:
        milliseconds: 15


lower_handle:
# just reverse of the raise handle script

Here is the automation:

# Door opener ##

- alias: Enable ringing boolean
  trigger:
    - platform: state
      entity_id: binary_sensor.door_opener_microphone
      to: 'on'
  condition:
    condition: state
    entity_id: input_boolean.ringtone_detected
    state: 'off'
  action:
    - service: homeassistant.turn_on
      entity_id: input_boolean.ringtone_detected

- alias: Disable ringing boolean
  trigger:
    - platform: state
      entity_id: input_boolean.ringtone_detected
      to: 'on'
  action:
    - delay:
        seconds: 15
    - service: homeassistant.turn_off
      entity_id: input_boolean.ringtone_detected

- alias: Door opener manual
  trigger:
    - platform: state
      entity_id: input_boolean.ringtone_detected
      to: 'on'
  condition:
    condition: state
    entity_id: input_boolean.auto_open_door
    state: 'off'
  action:
    - service: notify.mobile_app_my_mobil
      data:
        message: Someone is at the door downstairs
        data:
          actions:
            - action: OPEN_DOOR
              title: "Open the door"
          ttl: 0
          priority: high

- alias: Door opener automatic
  trigger:
    - platform: state
      entity_id: input_boolean.ringtone_detected
      to: 'on'
  condition:
    condition: state
    entity_id: input_boolean.auto_open_door
    state: 'on'
  action:
    - service: notify.mobile_app_my_mobil
      data:
        message: Someone is at the door downstairs, opening door automatically
        data:
          ttl: 0
          priority: high
    - service: homeassistant.turn_on
      entity_id: script.open_door


- alias: Open the downstairs door
  trigger:
    platform: event
    event_type: mobile_app_notification_action
    event_data:
      action: OPEN_DOOR
  action:
    - service: homeassistant.turn_on
      entity_id: script.open_door

Finally, the input booleans:

ringtone_detected:
  name: Door opener is ringing
  initial: off
  icon: mdi:phone-in-talk

auto_open_door:
  name: Open the door automatically when the bell rings
  initial: off
  icon: mdi:door-open

7 Likes

Cool!

I also had a similar system for the intercom, which looks to be the same, in my old apartment, where I also utilized servos😄 The GitHub repo for the project. Fun to see someone doing the same!

That looks very similar to our intercom! The difference may be that we can not push the “open door”-button unless the receiver is lifted up first, so we ended up needing two servos. Yours look good!

1 Like

Awesome use of technology to bypass the security that your apartment building has in place to help keep out those who might do you or your neighbors harm. If something happens to one of your neighbors as a result of your device, I wonder how much they will ask for in the lawsuit.

1 Like

Yikes! Yup, that could be a concern. I’m still the one letting people in or not though, just from my phone.

As long as you have that notification running. It’s the other side of that “Normally I have…” that I was speaking about. :slight_smile:

Very cool. Personally I would implement it a bit differently so that you’re not streaming commands from HA to the ESP with every command. You can import the bookend into your esphome confit and then use them to trigger scripts or automations that run locally on the device. But if the commands aren’t overloading the api then it might be ok. Only possible downside is if comms are lost mid command you might be stuck in an unknown state.

1 Like

Really cool, wish I had a 3D printer.

I did a similar thing electrically without servos.