Decipher garage door status - looking for ideas

Tags: #<Tag:0x00007f326c50b838>

Hi all,

I recently installed an ESP8266 using ESPHome to allow me to open my garage door remotely. To determine state I’m looking at status electronically using two GPIOs that are connected to the garage door controller board.

Part of my trouble in working through the logic is:

  1. The “Open” GPIO senses high when the door is open AND it also pulses at approx 1Hz when the door is opening.

  2. The “Closed” GPIO senses high when the door is closed AND it also pulses at approx 1Hz when the door is closing.

I’ve created a button that will toggle the OCS relay and this works nicely, as does the status when the door is closed. The trouble with the status is that when the door opens, the status goes “open/closed/open/closed…” for the duration that the door is opening. Not really ideal.

In my mind I think I need a sensor template that somehow ignores the pulsing and instead reads the final state from each GPIO to determine the actual open/closed state.

Tricky? I’m struggling to get my head around it and seek some wiser council :slight_smile:

As a follow-on, I wish to integrate with HomeKit (which I’ve done by way of a test cover already) however its only able to trigger the door at this stage as I’m unsure how to deal with status (see above).

Heres the relevant ESPhome config so far:

switch:
- platform: gpio
  id: relay
  pin:
    number: D5
    inverted: True
  restore_mode: ALWAYS_OFF
  
- platform: template
  name: "Garage Door"
  icon: "mdi:garage"
  turn_on_action:
  - switch.turn_on: relay
  - delay: 1s
  - switch.turn_off: relay
  
- platform: restart
  name: 'Garage Door REBOOT'
  
binary_sensor:
  - platform: gpio
    pin: D7
    name: "Garage Door Open"
    device_class: garage_door
    
  - platform: gpio
    pin: D8
    name: "Garage Door Closed"
    device_class: garage_door

Have a look at the delayed_on filter

Brilliant, thanks for this. I’ve added a 10s delay and it works nicely. I’d seen this but figured it was for debouncing switches and it wouldn’t like a large delay.

Now just working on a template sensor to decipher the other possibilities (ie, in a half open state, both inputs pulse OR after a power outage, the open input pulses).

1 Like

As a followup on this for future searchers, I eventually opted for using a Duty Cycle sensor and Pulse Counter sensor in ESPHome then used a value_template and icon_template to decode the various permutations of signals that my garage door opener outputs. Cover status can only be Open/Close but by using icon_template I’m able to provide some more meaningful feedback via the Lovelace UI (eg, power cut, open, closed, operating/partially open, unavailable).

For reference, the door opener is a very common unit sold in the New Zealand and Australian markets by various door companies. The brand and model are: Automatic Technology GDO-6v4 EasyRoller.

I intercepted the signals by connecting my ESP8266 to the GDO’s Aux socket giving me 5v supply and a common ground. By soldering pigtails carefully to the “high” side of open/close surface mount LEDs I’m able to sense the status of the doors operation. a 2v voltage drop across the LEDs is perfect to drive the GPIOs on the 3.3v ESP8266. Finally a relay connects across the OCS/GND pins to “press the button”.

Decoding the LEDs is made a little complex because they are lit solid, flash individually and together to represent open, opening, closed, closing, partially open and a power outage (why they bother to indicate this is beyond me!). Therefore it became a bit of an exercise to decipher into the simple status’ of open/closed that a Cover supports.

For my cover I have treated the LEDs/sensor connections as follows:

Bottom LED sensor:
Type: Duty Cycle. UoM: %
Sample: 3s
States:

  • Door closed = duty cycle of 100% (ie, sensor detects high)
  • Door partially open = bottom sensor detects pulses at 1Hz AND top sensor detects pulses at 1Hz (< 100 pulses / minute)
  • Door open = duty cycle of 0% (ie, sensor detects low) AND top sensor is on continuously (pulse counter = 0)

Top LED sensor:
Type: Pulse Counter. UoM: pulses/minute
Sample: 3s
States:

  • Door partially open = LED pulses at 1Hz (< 100 pulses / minute)
  • Power outage = sensor detects pulses at 2Hz (> 100 pulses / minute)

Note: approximations are used when comparing pulse/duty values as the sample period is 3s to keep the UI feedback responsive. In practise and testing it works very nicely.

Heres my cover config:

cover:
  - platform: template
    covers:
      garage_door:
        device_class: garage
        friendly_name: Garage Door
        value_template: >
          {% if is_state('sensor.garage_door_top', 'unavailable') and s_state('sensor.garage_door_bottom', 'unavailable') %}
            Closed
          {% elif states('sensor.garage_door_top') | int > 100 %}
            Closed
          {% elif states('sensor.garage_door_bottom') | int == 100 %}
            Closed
          {% elif states('sensor.garage_door_bottom') | int == 0 and states('sensor.garage_door_top') | int == 0 %}
            Open
          {% elif states('sensor.garage_door_closed') | int < 100 and states('sensor.garage_door_top') | int < 100 %}
            Open
          {% else %}
            Closed
          {% endif %}
        open_cover:
          service: switch.turn_on
          data:
            entity_id: switch.garage_door
        close_cover:
          service: switch.turn_on
          data:
            entity_id: switch.garage_door
        icon_template: >-
          {% if is_state('sensor.garage_door_top', 'unavailable') and s_state('sensor.garage_door_bottom', 'unavailable') %}
            mdi:help-box
          {% elif states('sensor.garage_door_top') | int > 100 %}
            mdi:power-plug-off
          {% elif states('sensor.garage_door_bottom') | int == 100 %}
            mdi:garage
          {% elif states('sensor.garage_door_bottom') | int == 0 and states('sensor.garage_door_top') | int == 0 %}
            mdi:garage-open
          {% elif states('sensor.garage_door_bottom') | int < 100 and states('sensor.garage_door_top') | int < 100 %}
            mdi:garage-alert
          {% else %}
            mdi:garage
          {% endif %}

I’m pretty chuffed at how this turned out. My wife is happy and now pushing me to detect her driving up the road so the door opens automatically. If I can manage this then its likely my home automation plans will take off at pace! :slight_smile: