Help with the template sensor

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)}}

Please help

Try this:

- 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 %}
         {% if y > 0 %}
           {{(2*(x/y)) | round(0, default=0)}}
         {% else %}
           Discharging
         {% endif %}

Thats it!
Works fine :), thank you very much Tom

One additional question, is it possible to remove the Hr unit of measurement and display only “Discharging” as now it shows “Discharging Hr”?

No, changing the unit is not possible. Maybe -- Hr would look better?

Its ok, I’ll live with this…Discharging sounds better in my opinion…
Maybe I can just call the actual sensor “Battery Recharge Time (Hr)”

Thanks so much Tom!!!

I entered the world of templating recently so still busy digging in the dark :smiley: , but people like you make it so much better! :pray:

Hello again, I do have one more question :slight_smile:

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

Hope I’m making sense :worried:

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 %}

Sensor became unavailable

I got

TemplateSyntaxError: expected token 'end of statement block', got '='

:thinking:

It should be

{% if z == 100 %}

Got it! :slight_smile:
It was missing one additional = sign…

This one works

- 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 :slight_smile:

we replied at the same time :slight_smile:

yes, that is correct :+1:

1 Like

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.

It’s not necessary, but you can use:

{% elif 100 > z > 95 %}

Oh, ok. Didn’t know that it works in that direction…that is good to know :slight_smile: (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

Battery was sitting on 99% State of charge which means that it was almost full but this is the result i got :frowning:

and I have found a bug in the calculation

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 %}

Thanks, I’ve put it in and will try :slight_smile:

Also, getting good with debugging → {% set y = = ([0.1, (stat … just had to remove that one and then config check passed :slight_smile:
:smiley:

Its just now coming right :frowning:

Battery was on 90% and battery current -9A as it was busy discharging…
But I got “Battery Full” on the template sensor :weary:

ccc

Basically, any negative result should say “Battery discharging” but I don’t think its getting negative results…

I would have tried something like this:

{% 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