ESPhome - Fast LED (ws2812b) Percentage effect

Hellow friends
Thanks for hearing my problem, please give me the solution for the LED Effect

First: I´m very new to HA, and I have no experience in programming. But I like to think I´m slowly improving. Anyways, please keep any answers as simple as possible.

I want LED indication for my water level in the tank. my wifi is not really good with HA, she wants to check the water level. so I want to WS2812b led to show the water level.

WS2812b LED is connected with D1 mini (through ESPhome )

Here is the program in D1 Mini
ESPHome

esphome:
  name: hall_led_notification
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: "xxxxx"
  password: "xxxxx"
  manual_ip:
    static_ip: 192.168.1.9
    gateway: 192.168.1.1
    subnet: 255.255.255.0
    dns1: 192.168.1.1
    dns2: 192.168.1.1

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Hall Led Notifications "
    password: "b122PIdkhceR"

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:
  password: "xxxxx"

ota:
  password: "xxxxx"

sensor:
  - platform: wifi_signal
    name: "WiFi Signal Hall LED Notification"
    update_interval: 60s
    id: esp32s_buzzer_wifi
    
light:
  - platform: fastled_clockless
    chipset: WS2812b
    pin: D4
    num_leds: 115
    rgb_order: GRB
    name: "Hall LED Notification"
    effects:
      # Use default parameters:
      - addressable_rainbow:
      - addressable_scan:
      - addressable_twinkle:
      - addressable_random_twinkle:

Here is how I converted my ultrasonic Sensor value to a percentage using Template

HA Template

Sensor:
  - platform: template
    sensors:
      percentage:
        friendly_name: "water_level_in_percentage"
        unit_of_measurement: '%'
        value_template: >
          {{"{:.1f}".format((0 - states('sensor.sensor.ultrasonic_sensor')|float) / -1.5) }} 

I want WS2812b led to show the water level by this value “water_level_in_percentage”

1 Like

Oh, I have been working quite a lot on the idea of using addressable led strips to show information. Like sensor values and timer/count downs. I will write about it somewhere in the forum later.

Let me give you some hints. You need a few things in your ESPhome config.

A home assistant sensor with the entity_id of your template sensor in HA. Something like (change the entity_id to the correct one):

sensor:
  - platform: homeassistant
    id: "id_water_percentage_from_ha"
    entity_id: sensor.water_level_in_percentage

An additional effect for your LED light as an addressable lambda effect:

    effects:
      - addressable_lambda:
          name: "Water level"
          lambda: |-
           const int leds_to_use=it.size();  // you can change that if you don't want all the leds to be used

            float water_percentage = id(id_water_percentage_from_ha).state;
            if (isnan(water_percentage)) {
              water_percentage = 0;
            }
            // number of leds that are drawn with full brightness
            int full_leds = int(leds_to_use*water_percentage/100.0);
            // set those leds to the current_color of the light
            it.range(0, full_leds) = current_color;

            // if full_leds is not the last led, render a remaining fraction of a led dimmed
            if (full_leds < leds_to_use) {
              it[full_leds] = current_color*((leds_to_use*water_percentage/100.0-full_leds)*255);
            }

            // set the remaing leds to black
            if (full_leds+1 < leds_to_use) {
              it.range(full_leds+1, leds_to_use) = ESPColor::BLACK; // change the color to something else if you want
            }

I hope the percentage value from HA goes from 0 to 100. If it goes from 0 to 1 remove the devide by 100.

You have to enable the “Water Level” effect in home assistant and select a color in Home Assistant to make it show the sensor value in that color. Every other effect (including None) should work as before.

I didn’t not test it. Please report if it works.

4 Likes

wow… first of all, thank you for your time.
I came into one problem

In configuration.yaml

sensor:
  - platform: homeassistant
    id: "id_water_percentage_from_ha"
    entity_id: sensor.percentage

when I check the configuration.
it is giving invalid

Configuration invalid

Platform error sensor.homeassistant - No module named ‘homeassistant.components.homeassistant.sensor’

sorry bro I don’t know how to solve this.

The sensor goes inside your esphome yaml file. It allows the your esphome device to have a copy of the sensor value from home assistant inside of it.

1 Like

Working really great bro … perfect

another one help :
By seeing the LED visually I came across one problem . LED are placed in hidden place we cant c the led directly. we can only c the light. In that, if it is 80 % or 100 % we can c all the led is on or not …
Total LED: 115
So I want first[1st] led and last[115th] led to on always on in red color and other LED (2nd to last -1[114th] led to show the percentage level )so that we can C it is 100% or 80 %

I am not 100% if I understand you correct.

But I think you could just use the ESPhome light partition platform to split your light strip into three. One with the first led, one with the last led and the middle is for the percentage that just uses exactly the same code as before.

It will show up as three lights in Home Assistant. So you can control the color of the first and last led using that and also the color of the middle range.

Btw: If you want to test how it looks with different percentages: You can add an input_number helper in the Home Assistant UI with value from 0 to 100 and connect that instead of the water level sensor in the ESPHome yaml. You then have a slider in the ui to set the percentage.

I also think, you should try to understand the lambda function. It just a few formulas to calculate what leds to switch on. That will allow you to do so much more. Maybe change the light depending on the sensor value? (90 to 100% green, 40 to 90 percent yellow and 0 to to 40% red for example). Or what every you can image. :slight_smile:

Like this:

light:
  - platform: fastled_clockless
    chipset: WS2812b
    pin: D4
    num_leds: 115
    rgb_order: GRB
    id: full_led_strip
  - platform: partition
    name: "Hall LED Notification Start"
    segments:
      - id: full_led_strip
        from: 0
        to: 0
  - platform: partition
    name: "Hall LED Notification End"
    segments:
      - id: full_led_strip
        from: 114
        to: 114
  - platform: partition
    name: "Hall LED Notification Percentage"
    segments:
      - id: full_led_strip
        from: 1
        to: 113
    effects:
      # Use default parameters:
      - addressable_rainbow:
      - addressable_scan:
      - addressable_twinkle:
      - addressable_random_twinkle:
      - addressable_lambda:
          name: "Water level"
          lambda: |-
           const int leds_to_use=it.size();  // you can change that if you don't want all the leds to be used

            float water_percentage = id(id_water_percentage_from_ha).state;
            if (isnan(water_percentage)) {
              water_percentage = 0;
            }
            // number of leds that are drawn with full brightness
            int full_leds = int(leds_to_use*water_percentage/100.0);
            // set those leds to the current_color of the light
            it.range(0, full_leds) = current_color;

            // if full_leds is not the last led, render a remaining fraction of a led dimmed
            if (full_leds < leds_to_use) {
              it[full_leds] = current_color*((leds_to_use*water_percentage/100.0-full_leds)*255);
            }

            // set the remaing leds to black
            if (full_leds+1 < leds_to_use) {
              it.range(full_leds+1, leds_to_use) = ESPColor::BLACK; // change the color to something else if you want
            }
4 Likes

thanks, brother it’s working very nice … I make one led stripe to show 2 water tank levels by using your help thanks. let me share the working LED photo

1 Like

Nice :slight_smile:

So you split your light strip into 5 partitions?

yes :slight_smile: it is working great … thanks for everything

I’m really interested to learn this type of thing.

when are u going to start your forum? In that please explain every step and every different method, that we can try with ESP home LED
On the web, I cont find anything related to these. after creating the forum please share the link to this page also. so that everyone can follow you over there.

Another one Help …

everything working properly … the only problem is WS2812b LED is flickering some time.
This is my present wiring Diagram

Do I need to any resister Like this

Or do u have some other way …?

2 Likes

I am not planing to start a new forum, just to post a some details about my project here in this community.

There a lots of possible reasons for flickering with WS281x LEDs. I don’t know which of those is the issue:

  • 3.3V vs 5V: But you are already using a level shifter.
  • Not fast enough level shifter: From your diagram I assume that you are using a level shifter mainly build for I2C. WS281x is quite fast/high bandwith protocol. It is generally advised not to use a I2C level shifter. You can try another level shifter or even without a level shifter at all if your data wire is short. In a lot of cases it works fine without a level shifter.
  • Long data line: If you have a long wire from your ESP (or level shifter) to the first LED the signal quality will be lower and that can cause flickering.
  • Poor power source quality: If your power supply delivers too low (or high) or unstable voltage (for example not enough amps), that can cause flickering.
  • An issue I had: For testing I used juper wires and a bread board for connections. It mostly worked but I had flickering. Depending an the bread board and the jumper cables it can sometimes make some not 100% stable connections that mostly work but not always. Check all your connections and if possible use soldered connections or for example Wago style connectors.
  • The ESP8266/ESP32 software: There are some reports with flickering caused by interrupts or something with ESPhome and other firmwares. (take a look in the ESPHome issues on Github.). I, with similar software as you, do not have that problem. But I am also using an ESP32. Most reports say it mostly happens when you transfer data over Wifi at the same time. A simple way to test if it this problem: Flash the software WLED on your esp8266 and see what happens. It the issue is resolved with WLED it is some kind of software problem. Then you either use WLED (there is an HA integration but stuff like you are doing here is more complicated) or further investigte the issue.
  • The missing resistor: I don’t think the missing resistor is the issue. But: It can not harm to test it.
1 Like

Hey, I know it’s quite a while ago since the last reply, but I’m currently working on an indicator light on my 3D printer (because I have an orange pi the octoprint plugins won’t work and I had a D1 mini lying around anyway).

I asked myself what the function of this block should do, because in my testings (with a humidity sensor) there was a solid consistent color for the LEDs which are on and the rest was off.
From my poor programming skills I can imagine this block should result in a gradient (dk if hue or brightness).
Was there maybe a change in the code (like ESPColor → Color) that had stopped this function or was this newer working, because the picture seems to also have a static color?
Nevertheless I would like to know how to code this addressable_lambda so that the LEDs which are on will do a wave-like effect (single color with oscillating brightness from start to end, a little bit like a windows vista+ progress bar). Hopefully my explanation is understandable and maybe someone can help me. - thanks