Emulating an imp/kwh LED with ESPHome

Hello all,

I have created an ESPHome node that has a CT Clamp meter reading current from my house mains, and then taking a sensor value from Home Assistant it then calculates power and energy consumption. This is working great, however I am having some issues with emulating the impulse LED function that is on most smart meters.

Essentially its an LED that flashes 1000 times per kWh and I am wanting to use the on board LED to do this. I can get it to flash for every 0.001 kWh through home assistant automation, but that just fills up my logs multiple times a minute. How can I have this happen all within the yaml code in my ESP32?

I will paste my code below and you will see my attempt to do this with the interval component, but it is not doing anything. Does anyone have any suggestions?

sensor:
  - platform: adc
    pin: A0
    id: adc_sensor
    attenuation: auto

  - platform: ct_clamp
    sensor: adc_sensor
    name: "Measured Current"
    update_interval: 1s        #You may change this value (in seconds)
    id: measured_current       #Measured in ampere (I)
    filters:
      - calibrate_linear:
        - 0 -> 0
        - 0.039 -> 4.0

  - platform: homeassistant
    name: "House RMS Voltage"
    entity_id: sensor.server_rms_voltage
    id: voltage

  - platform: template
    name: "Mains Power"
    unit_of_measurement: "kW"
    state_class: measurement
    update_interval: 1s
    accuracy_decimals: 2
    id: power_sensor
    lambda: |-
      float power = ((id(voltage).state * id(measured_current).state)/1000);
      return power;

  - platform: total_daily_energy
    name: "Total Daily Energy"
    id: consumption
    device_class: energy
    state_class: total_increasing
    accuracy_decimals: 3
    power_id: power_sensor
    unit_of_measurement: kWh

time:
  - platform: sntp
    id: my_time
    servers: 0.pool.ntp.org

output:
- platform: gpio
  id: "onboardLED"
  pin: 2
light:
- platform: binary
  output: "onboardLED"
  name: "Onboard LED"

interval:
  - interval: 10ms
    then:
      - lambda: |-
          static float previous_energy = 0.0;
          float current_energy = id(consumption).state;
          if (current_energy - previous_energy >= 0.001) {
            id(onboardLED).turn_on();
            delay(250);
            id(onboardLED).turn_off();
          }
          previous_energy = current_energy;

Managed to get a reply on reddit from the developer on reddit, but I am removing my account and posts on there as part of the API protests. I will transfer the solution onto here for other users :slight_smile:

/u/jesserockz:
Use on_value on the TDE sensor and set a static for the previous value and compare there. Don’t forget to handle when the TDE is reset to 0 at midnight

Me: I used this as my implementation:

  - platform: total_daily_energy
    name: "Total Daily Energy"
    id: consumption
    device_class: energy
    state_class: total_increasing
    accuracy_decimals: 3
    power_id: power_sensor
    unit_of_measurement: kWh
    on_value:
      then:
        - lambda: |-
            static float last_value = 0;
            if (id(consumption).state - last_value >= 0.001) {
              last_value = id(consumption).state;
              id(impLED).turn_on();
              delay(250);
              id(impLED).turn_off();
            }


output:
- platform: gpio
  id: "onboardLED"
  pin: 2
light:
- platform: binary
  output: "onboardLED"
  id: "impLED"
  name: "Onboard LED"

Me: But I cannot seem to get it to call the LED, I tried testing to see if the if statement is being triggered by outputting logs, and it does do so. I did the same with the LED and it only output to the logs when I manually switched it on via Home Assistant. I swear I must be missing something obvious here. I would really appreciate further help

/u/jesserockz
id(impLED).turn_on().perform();
Also don’t delay inside the lambda, you will break stuff. Add as on_turn_on trigger to the light and do a delay action then turn off action.

This worked great and solved my issue, thanks Jesserockz!