Binary sensor send state if regularly change state

Hello, I need help with one automation.
In Esphome. The LED on the charging module flashes when the battery is being charged.
This signal is connected to GPIO.
In esphome:

  - platform: gpio
    pin:
      number: 23
      mode: INPUT_PULLUP
      inverted: true
    name: "${friendly_name} Charger"
    id: charger

This means that it sends an ON/OFF status change every approx. 0.5 seconds

How do I set the automation so that it sends the “Charging” status to the text sensor in this state?

So far, I managed to create a sensor with the status “on battery” and “Full battery”

YAML:

binary_sensor:
##CHARGER
  - platform: gpio
    pin: 
      number: 23
      mode: INPUT_PULLUP
      inverted: true
    name: "${friendly_name} Charger"
    id: charger

  - platform: template
    name: "Test sensor"
    lambda: |-
      if (id(charger).state) {
        return true;
      } else {
        return false;
      }
    filters:
      - delayed_on_off: 1s
    id: charger_template
    on_state:
      then:
        - if:
            condition:
              binary_sensor.is_off: charger_template
            then:
              - text_sensor.template.publish:
                  id: power_status
                  state: "On Battery"
            else:
              - text_sensor.template.publish:
                  id: power_status
                  state: "Full Battery"

text_sensor:
##CHARGER TEXT
  - platform: template
    name: "${friendly_name} Power"
    id: power_status

That means I need three states

  • on Battery (GPIO off)
  • Charger Battery (GPIO on/off 0.5s)
  • Full Battery (GPIO on)

Thanks

If you have more than two states you can’t use a binary sensor. Use a sensor instead.

(binary == “two”)

try a duty cycle sensor, i think its the cleanest option.

sensor:
  - platform: duty_cycle
    pin: 
      number: 23
      mode: INPUT_PULLUP
      inverted: true
    name: "${friendly_name} Charger"
    id: charger

text_sensor:
  - platform: template
    name: "${friendly_name} Status"
    icon: mdi:eye
    lambda: |-
      if (id(charger).state < 5) {
        return {"On Battery"};
      } else if (id(charger).state < 75)  {
        return {"Charging"};
      } else {
        return {"Full Battery"};
      }    

That’s exactly what I need :slight_smile:

I’m actually keen to know what the duty cycle changes by during the charge… if it is just a fixed 50% duty cycle or if you get some sort of indication from it

another thing you can do is make the duty cycle sensor internal, so it doesnt publish to HA and take up space in your database.
to do that you will need to remove the name: ... and replace with internal: true only in the duty_cycle sensor.

you can also play with the update_interval: of the duty cycle sensor if you want faster changes, as it defaults to 1m, this means there could be a bit of a delay when changing states.

yes, I modified both sensors slightly.
Faster update, added fourth condition (on restart)
well thank you

sensor:
##CHARGE MODUL
  - platform: duty_cycle
    pin: 
      number: 23
      mode: INPUT_PULLUP
      inverted: true
    internal: true
    id: charger
    update_interval: 3s

text_sensor:
##CHARGER TEXT
  - platform: template
    name: "${friendly_name} Power"
    icon: mdi:eye
    lambda: |-
      if (id(charger).state > 75) {
        return {"Full Battery"};
      } else if (id(charger).state < 75)  {
        return {"Charging"};
      } else if (id(charger).state < 5)  {
        return {"On Battery"};
      } else {
        return {"Loading"};
      }    
    update_interval: 5s