Creating a Battery Meter from LED Strip

Hi All,

I’ve recently had a new home battery installed and I can read the value from the home assistant integration giving me a ‘sensor.battery_level’ entity.

Using an addressable WS2812 LED strip - I would like to make a battery meter - with each led showing 10% of usage. With the ultimate idea of printing a 3D case for it to go in for an easy visual check.

I’ve used addressable LED’s on ESP32’s before but I’m struggling to get my head around the code for this one.

Has anyone done this before or can give me a starter for 10 to get me going?

Thanks
Leacho

Off the top off my head- you probably only need a light and a sensor:

light:
  - platform: neopixelbus
    type: GRB
    variant: WS2812
    pin: GPIO22
    num_leds: 10
    id: my_light

sensor:
  - platform: adc # actually whatever sensor you are going to read voltage from
    pin: GPIO32
    name: "Battery Level"
    filters:
      - calibrate_linear:
          # Map 0.0 (from sensor) to 0.0 (true value)
          - 0.0 -> 0.0
          - 2.0 -> 1.0
          - 3.0 -> 2.0
          - 5.0 -> 3.0
          # etc.  In here map sensor output from 0 to 10
          # it doesn't return integers so convert it later
    on_value:
      - light.addressable_set:
          id: my_light
          range_from: 0
          range_to: !lambda "return int(x)-1;"  # led 0 is first led, led 9 is 10th led
          red: 100%
          green: 0%
          blue: 0% # whatever color you want

This is totally untested and I think the C int function works in C++ - so give it a go.

Or someone who has actually done this may chime in… :smiley:

EDIT: re-read and see the battery level is coming from HA, so you could convert it to 0-10 range there. You should get the idea though. Also - the above code won’t work if you have a sensor value of zero… Sorry.

1 Like

Thanks @zoogara - that’s a good starter for 10, but yes I do have a sensor coming from home assistant that counts down (or up) from 100-0 - so basically I’m trying to work out how to get the LED’s on depending on how much is left.

For example, if the battery is 100 - all 10 lights are on, if its 50, 5 are on, 0, then 0 are on.

Thanks again
Leacho

1 Like
    on_value_range:
      - below: 1
        then
          - light.turn_off: my_light
      - above: 1
        then
          - light.addressable_set:
              id: my_light
              range_from: 0
              range_to: !lambda "return x/10-1;"  # led 0 is first led, led 9 is 10th led
              red: 100%
              green: 0%
              blue: 0% # whatever color you want

I don’t have a spare WS2812 strip about so I can’t test, but the bare bones of what you want to do is in those 2 components. Sure you may need to manually set pixels to 0% and so forth - don’t know. Have a play.

1 Like