Hey All,
Having a bit of trouble trying to get my garage door sensor right. Have the basics working, but want it to be a bit more advanced.
Door components:
- Merlin Garage Door with Momentary Trigger input
- No access to limit switches
Project Parts:
- Wemos D1 Mini
- US-100 Ultrasonic Sensor
- Momentary Relay
What am i trying to achieve?
- Garage Door can be opened, closed or sent to a specific position
- Sensor is the US-100 Distance sensor
Where am i at?
- Door Trigger Works
- US-100 Can detect is Door is open ( < 0.1) or Closed (> 1.0)
Currently i’m a bit stuck on using Lambdas to detect if the door is Rising or Lowering. My concept is to take the current reading of the sensor, compare it to the current value. If the reading is less than store, then door is rising, if the reading is greater than, the door is lowering.
Can all my evaluations be in the one Lambda block?
How do i set some variables?
Am i going about this the right way?
Ultimately, i would also like to have a position indicator in Home Assistant. Heres my current ESP Code:
esphome:
name: garage_distance_sensor
platform: ESP8266
board: d1_mini
wifi:
ssid: "*******"
password: "*********"
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Garage Distance Sensor"
password: "YJo95f2jXJER"
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
switch:
- platform: gpio
pin: 13
id: relay
internal: true
sensor:
- platform: ultrasonic
name: "Garage Distance"
id: position
trigger_pin: GPIO12
echo_pin: GPIO14
update_interval: 2s
pulse_time: 10us
timeout: 20m
internal: true
globals:
- id: last_door-reading
type: int
restore_value: no
cover:
- platform: template
device_class: garage
name: "Garage Door"
id: template_cov
lambda: |-
if(id(position).state < 0.1) {
return COVER_OPEN;
}
else if(id(position).state > 1) {
return COVER_CLOSED;
}
else
{
return{};
}
open_action:
- switch.turn_on: relay
- delay: 0.5s
- switch.turn_off: relay
close_action:
- switch.turn_on: relay
- delay: 0.5s
- switch.turn_off: relay

Any thoughts or suggestions appreciatated.
Ok, so i have got most of this working. But, i’m still having trouble working out how to get the ‘Actual’ position of the door using the Ultrasonic sensor.
Heres the code i’ve hacked together from some different posts online. I’ll try and get some pictures of the physical setup shortly.
substitutions:
devicename: garagedoor
description: OpenGarage.io Device
friendly_name: Garage Overhead Door
auto_close_delay: "600s" # 10 minutes
buzzer_delay: "0.5s"
open_distance: "40" # fully open less than or equal in cm
closed_distance: "230" #closed is greater than 230
open_close_time: "20s" # allow 20s for motion to complete
reporting_delta: "3" # minimum 25cm change
esphome:
name: garage_distance_sensor
platform: ESP8266
board: d1_mini
wifi:
ssid: "*********"
password: "*********"
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Garage Distance Sensor"
password: "YJo95f2jXJER"
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
switch:
# The door opener contact (internal)
- platform: gpio
id: garage_button
pin: 13
restore_mode: ALWAYS_OFF
internal: true
on_turn_on:
- delay: 500ms
- switch.turn_off: garage_button
sensor:
- platform: ultrasonic
name: "${friendly_name} Distance"
id: ${devicename}_distance
trigger_pin: GPIO12
echo_pin: GPIO14
update_interval: 0.25s
unit_of_measurement: cm
accuracy_decimals: 0
pulse_time: 10us
timeout: 20m
internal: false
filters:
- filter_out: nan # filter timeouts
- multiply: 100 # from meter to cm
- median:
window_size: 5
send_every: 4
send_first_at: 3
#- sliding_window_moving_average:
# window_size: 5
# send_every: 3
# send_first_at: 3
- delta: ${reporting_delta}
globals:
- id: last_door_reading
type: float
restore_value: no
cover:
- platform: template
device_class: garage
name: "${friendly_name} Control"
id: ${devicename}_control
# set the distance so it is equal or less than $open_distance when open
lambda: !lambda |-
if (id(${devicename}_distance).state >= ${closed_distance}) {
return COVER_CLOSED;
} else {
return COVER_OPEN;
}
open_action:
- if:
condition:
lambda: "return id(${devicename}_control).position == cover::COVER_CLOSED;"
then:
- switch.turn_on: garage_button
- delay: ${open_close_time}
- script.execute: auto_close
stop_action:
- switch.turn_on: garage_button
close_action:
- if:
condition:
lambda: "return id(${devicename}_control).position == cover::COVER_OPEN;"
then:
- switch.turn_on: garage_button
# Disable any auto close pending action
- script.stop: auto_close
- delay: ${open_close_time}
script:
- id: auto_close
then:
- logger.log: "Automtically closing in ${auto_close_delay}"
- delay: ${auto_close_delay}
- logger.log: "Initiating automatic garage closing"
- cover.close: ${devicename}_control