Pulse length to determine state of electric gate

Hi all,

I am looking for a way to determine the length of a pulse using ESPHome, which will determine the state of a device. The device is a gate motor. It offers an output on/off circuit that does the following:

  • No pulse: The gate motor is either completely off OR gate is closed and running on battery backup
  • Short pulse: A short pulse, less than 500ms roughly about every 1 to 2 seconds, means the gate power is good and the gate is closed
  • Longer pulse: More than 500ms, roughly every second, means the gate is either opening or closing
  • On: The circuit is on, means the gate is open

I want to derive only three states from the gate; No or short pulse -> Gate Closed. Longer pulse -> Gate opening/closing, On -> Gate is open.

Seems an obvious problem to solve, but I have no idea how to do this in ESPHome. At the moment I’ve defined a binary input with an input filter of 500ms. So I get an open/close/open/close for the opening and closing cycle, or I get an open if the gate is open. It works, but its not ideal, because I would prefer to have a state that specifically represent 1) closed, 2) opening/closing and 3) open.

Sounds a bit like a duty cycle problem https://esphome.io/components/sensor/duty_cycle.html

Nickrout,

Thanks, that was a handy pointer. I’ve managed to implement that, and setting the update interval to 2 seconds seems the most accurate. I want to convert those values to 3 different states now, so I defined a template sensor. The problem is that it also has an update interval. I am having to figure out how to change the duty cycle value range to a specific state without having to rely on another 2 second update interval. My initial attempt:

sensor:
  - platform: duty_cycle
    update_interval: 2s
    pin: 
      number: 27
      inverted: yes
      mode: INPUT_PULLUP
    name: "Front Gate Status DC"
    id: front_gate_status_dc
    internal: true

  - platform: template
    name: "Front Gate Status TM"
    lambda: |-
      if (id(front_gate_status_dc).state == 0) {
        return 0;
      } else if (id(front_gate_status_dc).state < 20) {
        return 1;
      } else if (id(front_gate_status_dc).state < 60) {
        return 2;
      } else {
        return 3;
      }
    update_interval: 2s