Help with a custom thermostat template logic and variable scopes

Hi All,

This is my first use of a template like this within home assistant so please forgive me if i’ve overlooked anything massively wrong

I have some new TRV’s and was to look at writing a bit of logic for the valve to make them a little more smart but sadly i’m failing misserably

Below is my test automation

alias: Update TRV Position
description: ""
trigger:
  - platform: state
    entity_id:
      - climate.shellytrv_2c1165dacc5b
    attribute: current_temperature
  - platform: state
    entity_id:
      - climate.shellytrv_2c1165dacc5b
    attribute: temperature
condition:
  - condition: template
    value_template: "{% set currenttemp = float( trigger.to_state.attributes.current_temperature ) %}\n{% set settemp = float( trigger.to_state.attributes.temperature ) %}\n{% set difference = ( settemp - currenttemp ) | round(2) %}\n{% set currentposition = states(\"number.\" + trigger.entity_id.split('.')[1] + \"_valve_position\") | round(0, 'ceil') | int %}\n\n{% if difference > 0.5 %}\n\t{% set fraction = ( difference / 3 ) * 100 %}\n\t{% set valveposition = ( fraction / 10) | round(0, 'ceil') * 10 | int %}\n\t{% if valveposition >= 100 %}\n\t\t{% set valveposition = 100 | int %}\n\t{% endif %}\n\t{% if valveposition < 30 %}\n\t\t{% set valveposition = 30 | int %}\n\t{% endif %}\n{% else %}\n\t{% if difference > 0 %}\n\t\t{% set valveposition = 30 | int %}\n\t\t{{ valveposition }}\n\t{% endif %}\n\t{% if difference <= 0 %}\n\t\t{% set valveposition = 0 | int %}\n\t{% endif %}\n{% endif %}\n\n{{ dict(valveposition, **valveposition) }}\n\n{% if valveposition != currentposition %}\n    {{true}}\n{% else %}\n    {{false}}\n{% endif %}"
action:
  - service: notify.mobile_app_jamie_oneplus_3t
    data:
      message: Valve position set to "{{valveposition}}" for "{{trigger.entity_id}}"
mode: single

And so its easier to read, here is the template condition

{% set currenttemp = float( trigger.to_state.attributes.current_temperature ) %}
{% set settemp = float( trigger.to_state.attributes.temperature ) %}
{% set difference = ( settemp - currenttemp ) | round(2) %}
{% set currentposition = states("number." + trigger.entity_id.split('.')[1] + "_valve_position") | round(0, 'ceil') | int %}

{% if difference > 0.5 %}
	{% set fraction = ( difference / 3 ) * 100 %}
	{% set valveposition = ( fraction / 10) | round(0, 'ceil') * 10 | int %}
	{% if valveposition >= 100 %}
		{% set valveposition = 100 | int %}
	{% endif %}
	{% if valveposition < 30 %}
		{% set valveposition = 30 | int %}
	{% endif %}
{% else %}
	{% if difference > 0 %}
		{% set valveposition = 30 | int %}
		{{ valveposition }}
	{% endif %}
	{% if difference <= 0 %}
		{% set valveposition = 0 | int %}
	{% endif %}
{% endif %}

{{ dict(valveposition, **valveposition) }}

{% if valveposition != currentposition %}
    {{true}}
{% else %}
    {{false}}
{% endif %}

In short, the main variables are as follows:
climate.shellytrv_2c1165dacc5b = Main climate element
number.shellytrv_2c1165dacc5b_valve_position = Valve position

The basic idea is to get the current and set temperature, figure out if its below/over temperature and so some logic

If its under temperature, then run some basic logic using 3 degrees as the “100%” valve position mark and opening the valve s would be relevant proportional to the temperature difference. 30% is the coded minimum valve position before it turns off and it only runs in 10 degree increments to save battery

All of the calculations seem to work as i want but i have no way of using the variables set within this condition to then perform the action. Primarily i want the condition to validate as true, then allow me to use the “valveposition” to send the new position as needed in the actions but

I’m aware about global scope on the variables but is there any way to get that variable usable in the actions?

I’m likely going around this the completely wrong way so any help would be amazing as this is my first time looking at something at this level

Regards,
Jamie

Ok, i think i have figured this out although with some changes needed on my side (due to swapping entity, not related) it is a little more awkward

So, i have changed this now so instead of a condition, it is now an action directly for define variables
The variables command looks like this with a hard coded entity

variables:
  settemp: "{{ states('input_number.shellytrv_2c1165dacc5b_set_temperature', rounded=True) | float }}"
  currenttemp: "{{ states('sensor.temperature_humidity_sensor_a938_temperature', rounded=True) | float }}"
  currentposition: >-
    {{ states('number.shellytrv_2c1165dacc5b_valve_position', rounded=True) |
    round(0, 'ceil') | int }}
  difference: "{{ ( settemp - currenttemp ) | round(2) }}"
  calculatedposition: "{{ ( ( ( difference / 3 ) * 100 ) / 10) | round(0, 'ceil') * 10 | int }}"
  calculatedpositionusable: |-
    {% if difference > 0.5 %}
      {% if calculatedposition >= 100 %}
        {{ 100 }}
      {% elif currentposition < 30 %}
        {{ 30 }}
      {% else %}
        {{ calculatedposition }}
      {% endif %}
    {% elif difference > 0 %}
      {{ 30 }}
    {% elif difference <= 0 %}
      {{ 0 }}
    {% else %}
      {{ calculatedposition }}
    {% endif %}

I had completely missed that i could put a full set of logic into the set variable command! There may still be better ways of doing this so let me know if i’m still far off