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 (x_{1} ,y_{1} ) (x_{2} ,y_{2} ) 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

1 Like

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`

1 Like

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
```

tom_l
August 30, 2022, 10:23pm
18
That appears to be ESPHome configuration. Not Home Assistant.