Template returns 0 instead of 160

Hello !

So im trying to do a minor calculation with sensors. I have put static values 8 and 3 i run a similar python code and it returns 160 as it should. I’m trying to do the exact same thing but in a template, however it returns 0. Any ideas what could it be?

      {% set battery_charge = 8 | int  %}
      {% set charging_speed = 3 | int  %}
      {% set charging_time = 0 | int %}
      {% for i in range(0, battery_charge) -%}
        {% if charging_speed > battery_charge %}
          {% set charging_time = charging_time + ((battery_charge * 60) / charging_speed) | int %}
          {% set battery_charge = 0 %}
        {% endif %}
        {% set battery_charge = battery_charge - charging_speed  | int%}
        {% set charging_time = charging_time + 60 | int %}
      {%- endfor %}
      {{ charging_time | int}}

Thank you!

Variables set within for loops in templates are local.
That means they “exist” only in the for loop and do NOT OVERWRITE values outside of it.

Meaning this:

{% set charging_time = 0 | int %}

and this:

{% set charging_time = charging_time + ((battery_charge * 60) / charging_speed) | int %}

in your code are completely different values.
Never the less you can work around this by using namespaces.
(Give me a second to type an example :wink: )

2 Likes

so here is the example:

      {% set data=namespace(battery_charge=8, charging_speed=3, charging_time=0) %}

      {% for i in range(0, data.battery_charge) -%}
        {% if data.charging_speed > data.battery_charge %}
          {% set data.charging_time = data.charging_time + ((data.battery_charge * 60) / data.charging_speed) | int %}
          {% set data.battery_charge = 0 %}
        {% endif %}
        {% set data.battery_charge = data.battery_charge - data.charging_speed  | int%}
        {% set data.charging_time = data.charging_time + 60 | int %}
      {%- endfor %}
      {{ data.charging_time | int }}

EDIT: not sure if I did a type somwhere…but I am ending up with 220 :stuck_out_tongue:

2 Likes
{% for i in range(0, ..

You define i, but you nowhere use it in the Loop …

Oh I see it makes sense now. Damn i guess creating a python script would be easier at this point :smile:

Oh wow atleast its not zero, maybe it is possible :smiley: . Appreciate it !

Yeah i dont really need i. I figured if i change the value of battery_charge the one in the loop would change as well, however thats not the case :sweat_smile:

can you just post your python script? What you’re doing doesn’t make sense.

def main():

    try:
        Battery_Size = int(input("Input Battery size: " ))
        Charging_Speed = int(input("Input charging speed: "))

        if(Battery_Size <= 0 ):
            raise ValueError
        if(Charging_Speed <= 0 ):
            raise ValueError
        
        Battery_Charge = Battery_Size
        Charging_Time = 0

        while Battery_Charge > 0:
            if(Charging_Speed > Battery_Charge):
                Charging_Time += ((Battery_Charge * 60 )/ Charging_Speed)
                Battery_Charge = 0
                break
                
            Battery_Charge = Battery_Charge - Charging_Speed
            Charging_Time += 60
    
        return Charging_Time
        

    except ValueError:
        return "error"



print(main())

Ah, you’re using a while loop. Now this is going to be a pain to implement in jinja. Jinja doesn’t allow while loops.

You should just use a python script instead. THis will create sensor.charging_time every time you run the script. You can create an auotmation to run it based on changes for each sensor change.

charge_time.py

Charging_Speed = data.get('charge_speed')
Battery_Size = data.get('battery_size')

if Charging_Speed is not None and Battery_Size is not None:    
    Battery_Charge = Battery_Size
    Charging_Time = 0

    while Battery_Charge > 0:
        if(Charging_Speed > Battery_Charge):
            Charging_Time += ((Battery_Charge * 60 )/ Charging_Speed)
            Battery_Charge = 0
            break
            
        Battery_Charge = Battery_Charge - Charging_Speed
        Charging_Time += 60
    
    hass.states.set('sensor.charging_time', str(Charging_Time), {'friendly_name':'Charging Time'})
automation:
- trigger:
  - platform: state
    entity_id: 
    - sensor.battery_size
    - sensor.charge_speed
  action:
  - service: python_script.charge_time
    data:
      charge_speed: "{{ states('sensor.charge_speed') | int }}"
      battery_size: "{{ states('sensor.battery_size') | int }}"
1 Like

Thank you, so much appreciate it!

Hi again, sorry to bother you. So I tried calling the python script in the service tab and using this data

data:
      charge_speed: "{{ states('input_number.charging_speed') | int }}"
      battery_size: "{{ states('input_number.battery_size') | int }}"

However I’m having trouble sometimes the sensor appears and sometimes it doesn’t, but when it does it’s always 0, any idea what could it be?

Also I tried to use that automation, it triggers but the sensor would not appear.

Edit: sorry nvm I figured it out, home assistant doesn’t like “+=” usage :smile: