Hi all!
I have a DIY electric motorbike, which runs a custom BMS system. It pings the pack voltage via MQTT when charging to HA.
The sensor config is as follows
platform: mqtt
name: ‘3Fazer - Voltage’
state_topic: ‘ev/3fazer’
unit_of_measurement: 'V
I would like to convert this voltage to battery charge % if possible inside HA.
100% is 116.2V
0% 95.2V
The battery drain is more or less linear. Any assistance on how I can do this would be much appreciated. as always.
AllHailJ
(J Gent)
April 7, 2022, 8:09pm
2
Have you considered using a template sensor.
template:
- sensor:
- name: "battery_sensor"
unique_id: "Battery Sensor"
state: >-
{% set voltage = states('sensor.3fazer_-_voltage') | float(0) %}
{{ ((voltage - 95.2) / 0.21) | int }}
This will give you the % in a truncated integer.
Thank you so much, worked perfectly.
tom_l
April 8, 2022, 5:13am
4
You don’t need a template sensor. The MQTT sensor supports a value template.
- platform: mqtt
name: '3Fazer - Voltage'
state_topic: 'ev/3fazer'
value_template: "{{ ((value|float(0) - 95.2) / 0.21)|round(0) }}"
unit_of_measurement: '%'
Also using |int
truncates the decimal, where as |round(0)
will round to the nearest whole number.
e.g.
70.99|int = 70
70.99|round(0) = 71
1 Like
Also thanks! I did like the seperation so I can monitor voltage as well.
Updated it to use round vs int and that has correct it showing 99% vs 100% at full charge. Thanks
TheStigh
(TheStigh)
August 13, 2022, 3:32pm
6
Hi @tom_l
Possibly kind of dumb question - how did you get the value of ‘0.21’ in the example above?
I have a sensor where I measure mm, and want to find the percentage where min are 100 mm and max are 500 mm…?
tom_l
August 13, 2022, 3:53pm
7
From this data:
alexanderfitu:
100% is 116.2V
0% 95.2V
If given two points (x1 ,y1 ) (x2 ,y2 ) you can work out the equation for the line that passes through them:
y = mx + c
https://content.byui.edu/file/b8b83119-9acc-4a7b-bc84-efacf9043998/1/Math-2-11-2.html
So your two points (0%, 100mm) and (100%, 500mm) gives:
y = 0.25*x - 25
or
% full = 0.25*(x in mm) - 25
2 Likes
TheStigh
(TheStigh)
August 13, 2022, 11:22pm
9
@tom_l
I was thinking wrong;
My sensor range are 100 mm (full) to 500 mm (empty) to monitor a water tank.
In my case, when the states(sensor.water_level)
= 100, it should show 100% and opposite, when at 500 it should show 0%.
How on earth should I calculate this?
To make it worse, I wanted to put this into a gauge. It worked well until I realized it was all opposite… duh…
Are you able to help on this?
tom_l
August 13, 2022, 11:30pm
10
Exactly the same way as in the link I provided above.
%full = -0.25*(x in mm) + 125
TheStigh
(TheStigh)
August 14, 2022, 1:24am
11
alexanderfitu:
100% is 116.2V
0% 95.2V
Could you please show me how you calculated the numbers?
Sorry, advanced math ain’t my strong side, I do electronics and ESP32 stuff (using a TOF to measure the distance to the water level)
I am using slider (input_number) as the min & max can change (different tanks to monitor).
Initially I resolved it differently:
state: >-
{% set fill = states('sensor.tof_poc') | float(0) %}
{% set min = states('input_number.mm_min') | float(0) %}
{% set max = states('input_number.mm_max') | float(0) %}
{{ (((fill - min) * 100) / (max-min)) | round(0) }}
How am I going to put that advanced calculation - even the other way where 100 mm = 100% and 500 mm = 0%? And even bring into consideration the input sliders where min and max can change?
Think I’m about to give up this route and look for something else…
tom_l
August 14, 2022, 2:36am
12
I did. Watch the video in the link I posted. It’s high school maths.
You could try this instead:
You cant use templates with it but it is easy to change the points config. Which really you should not have to once it is set up.
tom_l
August 14, 2022, 3:51am
13
As a mental exercise for the points (0%, input_number.mm_min
) and (100%, input_number.mm_max
):
state: >-
{% set distance = states('sensor.tof_poc') | float(0) %}
{% set x1 = states('input_number.mm_min') | float(0) %}
{% set x2 = states('input_number.mm_max') | float(0) %}
{% set m = 100 / (x2 - x1) %}
{% set c = 100 - (m * x2) %}
{{ distance * m + c }}
this will work for any values of input_number.mm_min
and input_number.mm_max
2 Likes
TheStigh
(TheStigh)
August 14, 2022, 2:05pm
14
I actually got it with your example I’m passed 50, so I do not remember so much from math classes back in the days
Interesting part - if I changed
{% set x1 = states('input_number.mm_min') | float(0) %}
{% set x2 = states('input_number.mm_max') | float(0) %}
to
{% set x1 = states('input_number.mm_max') | float(0) %}
{% set x2 = states('input_number.mm_min') | float(0) %}
I get the reversed % where 100mm are 100% and 500 mm are 0%.
Thank you so much @tom_l
tom_l
August 14, 2022, 2:07pm
15
TheStigh:
Interesting part - if I changed
{% set x1 = states('input_number.mm_min') | float(0) %}
{% set x2 = states('input_number.mm_max') | float(0) %}
to
{% set x1 = states('input_number.mm_max') | float(0) %}
{% set x2 = states('input_number.mm_min') | float(0) %}
I get the reversed % where 100mm are 100% and 500 mm are 0%.
Um no. All you have to do is change the input number values in the frontend using the sliders.
input_number.mm_min = 100
and
input_number.mm_max = 500
or
input_number.mm_min = 500
and
input_number.mm_max = 100
Will both work the way you want them to. That was the whole point of using input numbers in the template, so you don’t have to change the template.
TheStigh
(TheStigh)
August 14, 2022, 2:12pm
16
I noticed that straight away… playing with both scenarios
Need to make sure this way of calculating stick to my brain
Thats my config. Works perfectly. 0.1m = 100%, 1.1m=0%
sensor:
- platform: ultrasonic
trigger_pin: 27
echo_pin: 26
unit_of_measurement: "%"
accuracy_decimals: 0
name: "Lenti esoviz tartaly"
update_interval: 10s
filters:
- calibrate_linear:
- 0.1 -> 100
- 1.1 -> 0
1 Like
tom_l
August 30, 2022, 10:23pm
18
That appears to be ESPHome configuration. Not Home Assistant.
ajueket
(oron_enthusiast)
November 16, 2024, 4:56pm
19
This was helpful for my setup.
Arn49
(Arn49)
February 2, 2025, 12:11pm
21
Hello All
I am a beginner and I would like to convert a volume entity (mm) into % and I do not know how to do it. Can someone come to my aid by providing me with a code to perform this task please. Thank you all