ESPHome gate remote

Our house has a remote-operated gate that opens to allow cars to park in the lot, every apartment has their own remote. I can’t get everyones permission to hack the physical gate, so I modified my own remote to allow me remote operation.

Considerations i had:

  • allow disconnecting it to take it with me as needed and use as normal
  • physical button to operate when in home (wife-approval factor)
  • expose to Google, for voice command inside car
  • bonus: add beep sound when command is triggered

Step 1 - modify the remote controller

Solder some dupont wires to the remotes button

So it can be connected and disconnected easily, and doesn’t look too bad. Wire appearance can be improved so they aren’t dangling… Connect the cover back and it looks like this:

Step 2 - create your device

Add a dry contact relay (I used SONOFF RE5V1C) , a piezo buzzer, a push-button and box it up nicely.

Step 3 - flash it with ESPHome

  • switch to toggle inching
  • number for inching timer
  • virtual door/gate/cover device for the GPIO switch
substitutions:
  friendly_name: 'Gate'
  device_name: 're5v1c'  
  device_host: 'gate'  
  device_description: 'SONOFF RE5V1C – 5V inching/selflock relay. Dry contact output. Power Supply: 5V DC. Max Current: 10A'
  project_base: 'SONOFF'
  project_name: 'RE5V1C'
  project_version: 'IM171018005'
  chip: 'ESP8285N08'

esphome:
  name: $device_host
  comment: $device_description  
  friendly_name: ${friendly_name}  
  platform: esp8266
  board: esp8285
  esp8266_restore_from_flash: true
  project:
    name: ${project_base}.${project_name}
    version: $project_version    

packages:
  device_base: !include common/device.base.yaml  

api:
  id: ${device_name}_api
  services:  
    - service: inching_time
      variables:
        inching_time: float
      then:
      - lambda: |-        
          auto call = id(${device_name}_inching_time).make_call();
          call.set_value(inching_time);
          call.perform();        
    - service: inching_toggle
      variables:
        state: bool
      then:
      - if:        
          condition:
            - lambda: 'return state == false;'
          then:
            - switch.turn_off: ${device_name}_inching
          else:
            - switch.turn_on: ${device_name}_inching
    - service: rtttl_play
      variables:
        song_str: string
      then:
        - output.turn_on: ${device_name}_rtttl_out
        - rtttl.play:
            rtttl: !lambda "return song_str;"
        - output.turn_off: ${device_name}_rtttl_out

output:
  - id: ${device_name}_led_out
    platform: gpio
    pin:
      number: 13
      inverted: True

  - id: ${device_name}_rtttl_out
    platform: esp8266_pwm
    frequency: 40000 Hz    
    pin: 
      number: 4

rtttl:
  output: ${device_name}_rtttl_out

light:
  - platform: status_led
    name: Status led
    id: ${device_name}_status_led
    pin: 
      number: 13
      inverted: true    
    entity_category: diagnostic
    icon: mdi:led-outline
    disabled_by_default: true
    internal: true

  - platform: binary
    name: Led
    id: ${device_name}_led
    icon: mdi:led-outline  
    entity_category: diagnostic
    disabled_by_default: true    
    output: ${device_name}_led_out
    restore_mode: ALWAYS_OFF

number:
  - platform: template
    id: ${device_name}_inching_time
    name: Inching time
    icon: mdi:timer-stop-outline
    entity_category: config
    unit_of_measurement: s
    mode: auto
    optimistic: true
    restore_value: true
    min_value: 0.5
    max_value: 10
    step: 0.5
    initial_value: 1

button: 
  - platform: template
    name: Relay
    id: ${device_name}_relay_button
    icon: mdi:electric-switch
    on_press: 
      switch.toggle: ${device_name}_relay

switch:
  - platform: template
    name: Inching
    id: ${device_name}_inching
    icon: mdi:pipe
    entity_category: config
    restore_state: true
    restore_mode: RESTORE_DEFAULT_ON
    optimistic: true
    turn_on_action:
      - rtttl.play: 'inching:d=2,o=7,b=500:32b#,32b#,32c,16p,32c,16p,32c'
      - light.turn_on: ${device_name}_led
    turn_off_action:
      - rtttl.play: 'inching:d=2,o=7,b=200:32e,32d,32c'
      - light.turn_off: ${device_name}_led
  - platform: gpio
    name: Relay
    id: ${device_name}_relay
    icon: mdi:electric-switch
    device_class: outlet
    entity_category: diagnostic
    pin: 
      number: 12
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - lambda: |-
          id(${device_name}_relay).set_icon("mdi:electric-switch");
      - rtttl.play: 'open:d=2,o=7,b=500:32d,32d#,32e,8p,32e,32d,32e' 
      - if:
          condition:
            switch.is_off: ${device_name}_inching
          then:
            - logger.log: "Keep"
          else:
            - delay: !lambda "return id(${device_name}_inching_time).state * 1000;" # milliseconds
            - switch.turn_off: ${device_name}_relay
    on_turn_off:
      - if:
          condition:
            switch.is_off: ${device_name}_inching
          then:
            - rtttl.play: 'close:d=2,o=7,b=500:32c,32c#,32b#,16p,32b#,32c,32c#'

cover:
  - platform: template
    name: ${friendly_name}
    id: ${device_name}
    device_class: gate
    lambda: |-
      if (id(${device_name}_relay).state) {
        return COVER_OPEN;
      } else {
        return COVER_CLOSED;
      }
    open_action:
      - switch.turn_on: ${device_name}_relay
    close_action:
      - if:
          condition:
            switch.is_off: ${device_name}_relay
          then:
            - switch.turn_on: ${device_name}_relay
          else:
            - switch.turn_off: ${device_name}_relay      
    stop_action:
      - if:
          condition:
            switch.is_off: ${device_name}_relay
          then:
            - switch.turn_on: ${device_name}_relay
          else:
            - switch.toggle: ${device_name}_relay      

binary_sensor:
  - platform: gpio
    pin:
      number: 3
      inverted: true
    name: External Button
    id: ${device_name}_button_external
    internal: true
    on_press: 
      - switch.toggle: ${device_name}_relay

  - platform: gpio
    pin:
      number: 0
      mode: INPUT_PULLUP
      inverted: True
    name: Button
    id: ${device_name}_button
    device_class: garage_door
    entity_category: diagnostic    
    on_press: 
      - switch.turn_on: ${device_name}_relay      
    on_release:
      - switch.turn_off: ${device_name}_relay            
    filters:
      - delayed_off: 100ms                

Step 4 - enjoy a nice and functional project

Disconnect the duponts quickly and easily to take the controller with you if needed.

Step 5 - expose to Google Home / Assistant for voice control

Hi Veli!

This is exactly what I need :slight_smile: Been trying to do this with nodemcu boards etc… but this seems like a clean and simple setup! I am dedicated to copy :wink:

Couple of questions if you do not mind and apologies in advance for my lack of expertise!

  • Could you perhaps share more pictures of the wiring, especially the connection between the sonoff, remote and other stuff that is going on in that box :slight_smile:
    - ESPhome; when you say flash it… what software are you using to do so? Would be great if you could link to a tutorial somewhere?
    - How does it connect to HA?

Thanks in advance!

Edited some stuff out which I figured out in the mean time :slight_smile:

For my own setup; I have a nodemcu available which I have now added to HA with the following code:

esphome:
  name: esphome-web-1d5e2e
  friendly_name: Gate Opener

esp8266:
  board: nodemcuv2

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key REDACTED

ota:


wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-1D5E2E"
    password: "Jv624x2Xat3F"

captive_portal:

# Add Switch to pin 25   
switch:
  - platform: gpio
    pin: D0
    id: relay
    name: "Gate Remote"
    icon: "mdi:gate"
    on_turn_on:
    - delay: 500ms
    - switch.turn_off: relay```

Having trouble now getting it all wired-up and powered…

Any suggestions?

I’m also using RE5V1C for garage opening but flashed with Tasmota. I plan to reflash it with ESPHome. Can you share your device.base.yaml (sensitive info covered or replaced with garbage)?

1 Like

It’s a tight fit inside the box :grinning_face_with_smiling_eyes: but nothing special, used all the available GPIOs on the RE5V1C.

Not sure these pictures help as I dont want to dismantle the whole thing, hope you get it working :slight_smile:

For power I split open an USB cable and soldered directly onto the RE5V1C power pins.

closeup

Got it working in the meantime :smiley:

In the end I forwent the physical button as I didn’t necessarily needed one. Used a nodemcu board!

Great project and thanks!

1 Like