Hello,
I created a template sensor that would calculate my battery bank recharge time and it works in order when conditions are “positive” meaning when the battery is charging - it will correctly calculate time needed for it to be full.
Problem comes to when battery is busy discharging (I am using it as its an off-grid type of setup) - it will display negative value.
I am struggling to configure the template sensor to show positive values only, and if result is negative perhaps show some message

Here is my sensor:

- platform: template
sensors:
battery_recharge_time:
friendly_name: "Battery Recharge Time"
unit_of_measurement: "Hr"
value_template: >-
{% set x = states('sensor.battery_remaining_capacity') | float %}
{% set y = states('sensor.battery_current') | float %}
{{(2*(x/y)) | round(0, default=0)}}

Can it be configure that if the value of the calculation {{(2*(x/y)) | round(0, default=0)}} is greater then 95, it says “Almost full” and once it reaches a 100, it says “Full”…anything else, Discharging is fine

Sure, that’s just more if cases, you just have to be careful of the order you put them in (the first test that resolves true will be the state). Also if you don’t want to graph the time you can get round the unit problem like this:

- platform: template
sensors:
battery_recharge_time:
friendly_name: "Battery Recharge Time"
value_template: >-
{% set x = states('sensor.battery_remaining_capacity') | float %}
{% set y = states('sensor.battery_current') | float %}
{% set z = (2*(x/y)) | round(0, default=0) %}
{% if z = 100 %}
Full
{% elif z > 95 %}
Almost full
{% elif z >= 0 %}
{{ z }} Hr
{% else %}
Discharging
{% endif %}

- platform: template
sensors:
battery_recharge_time:
friendly_name: "Battery Recharge Time"
value_template: >-
{% set x = states('sensor.battery_remaining_capacity') | float %}
{% set y = states('sensor.battery_current') | float %}
{% set z = (2*(x/y)) | round(0, default=0) %}
{% if z == 100 %}
Full
{% elif z > 95 %}
Almost full
{% elif z >= 0 %}
{{ z }} Hr
{% else %}
Discharging
{% endif %}

Again, Tom, thank you so very much…I am learning so much because of you

and one more question…after testing, this will never show the 100 value because z > 95 is Almost full so it will display that even when the state is 100.
How would I make it “if >95 but <100” in one statement?

As tom stated in his earlier reply, the order of the if tests is important. The first test (reading from top to bottom) that resolves true will be the state.

Oh, ok. Didn’t know that it works in that direction…that is good to know (like network firewall rules - top to bottom order)
Ok, great…I’ll test all today then

Thanks so much!
Need to read more about jinja2…I just started using templating

when sensor.battery_current comes down to 0A cause battery is now full - the template sensor becomes unavailable (because one can’t divide with 0).
How would I put a default result of this sensor to be always 1, or do I need to create another template sensor for that variable in order to allow it to be +x, -y, but not allow it to be 0?

Also, when I calculated a bit better (and turned on my brain :)), my results are Ah, so I had to adjust like this:

- platform: template
sensors:
battery_recharge_time:
friendly_name: "Battery Recharge Time"
value_template: >-
{% set x = states('sensor.battery_remaining_capacity') | float %}
{% set y = states('sensor.battery_current') | float %}
{% set z = (2*(x/y)) | round(0, default=0) %}
{% if z == 592 %}
Battery Full
{% elif 580 > z > 550 %}
Battery almost full (>530 %)
{% elif z >= 0 %}
{{ z }} Hr
{% else %}
Battery Discharging...
{% endif %}

My total battery capacity is 296 Ah (Full), so with the calc of 2x(296/0)= error
Therefor it must be 2x(296/1) and that is full battery (592).
Now its starting to be a bit more clear

So, main thing is not to allow sensor.battery_current to be 0

One thing to remember if you use the {% elif 580 > z > 550 %} is that you will create a a band between 581 and 591 that reports very high recharge times instead of “Battery almost full”.

You could use this little sort filter trick to set a range for your y value, so that you avoid the divide by zero error

- platform: template
sensors:
battery_recharge_time:
friendly_name: "Battery Recharge Time"
value_template: >-
{% set x = states('sensor.battery_remaining_capacity') | float %}
{% set y = ([0.1, (states('sensor.battery_current') | float), 200]|sort)[1] %}
{% set z = (2*(x/y)) | round(0, default=0) %}
{% if z > 591 %}
Battery Full
{% elif 591 > z > 550 %}
Battery almost full
{% elif z >= 0 %}
{{ z }} Hr
{% else %}
Battery Discharging...
{% endif %}

{% set x = states('sensor.battery_remaining_capacity') | float %}
{% set y = states('sensor.battery_current') | float) %}
{% if y < 0.1 %}
Battery Discharging
{% else %}
{% set z = (2*(x/y)) | round(0, default=0) %}
{% if z > 591 %}
Battery Full
{% elif 591 > z > 550 %}
Battery almost full
{% else %}
{{ z }} Hr
{% endif %}
{% endif %}

The the Z calculation isn’t performed if the battery current is negative, because we know it is discharging if the current is negative.
Does that sound right?

EDIT: Changed the y test to less than 0.1, to avoid the divide by zero when the current is exactly 0. Depending on the precision of the actual value stored in the sensor you might be able to change this to < 0.01