Battery_level attribute from ESP

Hello everyone!
I’m learning my way into ESPhome and HA and I just found something I’d like to do.
Is there a way to make the ESP report it’s battery level so it shows up on the battery section of the config --> devices --> dashboard the same way a cellphone battery does?

I have tried the following yaml, but it didn’t seem to make any effect on the dashboard.

sensor:
  - platform: adc
    pin: VCC
    id: "battery_level"
    name: "esp.2.vcc"

Any idea?

3 Likes

I don’t think you can do it in ESPHome. It only supports binary sensor device classes.

You can customise the sensor in home assistant though.

device_class: battery

I think it has to be something related with some tricky naming convention in HA.

ESPhome has many more than just binary sensors. That yaml itself is an example of an analog sensor sending a float.

I suspect there’s gotta be something I can add to make HA render the value just like it does with my cellphone. :smirk: :smirk:

1 Like

Yes but only binary sensors support device classes in ESPHome. Sensors in ESPHome do not. Sensors in Home assistant do.

So format your battery sensor on the ESPHome device to output a % instead of a voltage. Then in home assistant customise that sensor by applying the battery device class. It has icons relating to battery state.

3 Likes

There is a provision in the ESPHome documentation, that talk to the possibly of measuring VCC. Perhaps you can try the abbreviated Yaml provide in their example. Pin used needs to be A0 only.

ESP8266 Measuring VCC

On the ESP8266 you can even measure the voltage the chip is getting. This can be useful in situations where you want to shut down the chip if the voltage is low when using a battery.

To measure the VCC voltage, set pin: to VCC and make sure nothing is connected to the A0 pin.

sensor: - platform: adc pin: VCC name: “VCC Voltage”

While that’s great for getting the battery voltage it does not answer the question:

Only adding the device class will do that.

Ok understood. It’s just strange that ESPHome can create ‘Wifi signal strength’ in HA using - platform: wifi_signal and does not for the - platform: adc Vcc value as both are usually considered as attributes. But Ok point taken.

That’s exactly right!!! Thank you @tom_l!!!
I did it on my esp_2 and it works!
image

Here is the final portion of that yaml:

  - platform: adc
    pin: VCC
    id: "VCC"
    internal: true
    
  - platform: template
    name: "esp.2.battery_level"
    unit_of_measurement: '%'
    update_interval: 5s
    lambda: |-
      return ((id(VCC).state /3.30) * 100.00);

Thank you!!!

13 Likes

Yeah, that was my thought as well, so I thought HA would just take it based on the ID or name, but nope… @tom_l was right, you have to override the class manually and make sure the value is in % and not V as I had it.

I hope this is a useful sample code for other people :slight_smile:

1 Like

I’m getting the warning message when compiling it: warning: multi-line comment [-Wcomment]. Is a way arround the error message not to show up?

Thanks

It’s just a warning, forget it. I think that this small issue will be solved with next release

ok, thanks!

Hi I have a problem whit one of my d1 mini.

On one I can monitor the battery.
On the other one I get error.

Can some one help me whit this.

This is the yaml file:

esphome:
  name: pool_thermometer
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: "xxxxxx"
  password: "xxxxxxx"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Pool Thermometer"
    password: "esdUJlWfq7B4"

dallas:
 - pin: D7
 
sensor:
 - platform: dallas
   address: 0xED01193A97197128
   name: "Poolen"
   unit_of_measurement: "°C"
   
 - platform: adc
    pin: VCC
    id: "VCC"
    internal: true
    
 - platform: template
    name: "pool_thermometer_battery"
    unit_of_measurement: '%'
    update_interval: 60s
    lambda: |-
      return ((id(VCC).state /3.30) * 100.00);

captive_portal:

# Enable logging
logger:

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

ota:
  password: "xxxxxx"

Thanks

2 Likes

You are missing the name, it’s required. The ID is optional

---
platform: template
name: Level Battery ${devicename}
#device_class: battery
unit_of_measurement: '%'
accuracy_decimals: 0
id: ${devicename}_battery
update_interval: ${update_interval}
lambda: |-
  return ((id(${devicename}_voltage).state /4.2) * 100.00);
  // todo map only 3.0V to 4.2V as 0 to 100%, and up to 5V USB as 100%

can you help me to solve last line as lambda?
why is device_class not allowed?

thanks

4 Likes

Why did you choose 3.30 as the divisor? If my inkplate uses a 3.7v 1200mAH battery, should I make mine 3.7? Thanks in advance.

What I did was the following:
Minimum Voltage in my case is 3.0
Max voltage is: 4.2

for the lambda part:

lambda: |-
  return ((id(${devicename}_voltage).state -3) /1.2 * 100.00);

In this case 3.0 V will be : 3-3= 0 /1.2 = 0 * 100= 0%
4.2-3 = 1.2/1.2 = 1 *100 = 100%

3 Likes

You can probably use the thing I just specified. :smiley:

Here my full code for measuring with A0:

sensor:
  - platform: adc
    pin: A0
    id: "LIION"
    name: "A0 Voltage x 4.2"
    update_interval: 15s
    accuracy_decimals: 3
    filters:
      - multiply: 4.2
  - platform: template
    name: "D1003_Battery_Voltage"
    unit_of_measurement: 'V'
    update_interval: 15s
    accuracy_decimals: 2
    lambda: |-
      return (id(LIION).state);
  - platform: template
    name: "D1003_Battery_Percentage"
    unit_of_measurement: '%'
    update_interval: 15s
    accuracy_decimals: 0
    lambda: |-
      return ((id(LIION).state-3) /1.2 * 100.00);
3 Likes

thank you for this!, it’s funny I was actually talking about trying to find out how to do exactly that 2hrs ago!

now i know!

thanks