Triggering an input_number to change based on multiple inputs

Hi all,

Just starting the journey and getting stuck on the best way to do things. I’m building a heating control logic into HA. I am trying to work out how to best trigger state changes to input values (Helpers) based on changes to other input values and sensors. It seems like there are many ways to crack this nut and as a result I’m struggling to discover the best way to do something simple!

Keeping it simple I have:


input_number.room1_set_temp  <-- the input set temperature for room 1
input_number.room2_set_temp  <-- the input set temperature for room 2
sensor.room1_temp <-- the actual temperature in room 1
sensor.room2_temp <-- the actual temperature in room 2
input_number.room1_demand_temp <-- the difference between the set temp and the actual temp in room 1
input_number.room2_demand_temp <-- the difference between the set temp and the actual temp in room 2
input_number.max_demand_temp <-- the maximum of the demand temps in any room
input_number.demand_tolerance <-- the tolereance for demand temperature (only set manually)
input_number.thermostatic_demand_state <-- binary, 1 if the max demand temp is above the demand tolerance, 0 otherwise

What I want to automate:
1 Trigger the calculation of the demand temperature

This should trigger whenever the input_number.room1_set_temp OR sensor.room1_temp changes.
The action should be to set input_number.room1_demand_temp to the difference between the above inputs. Same ot be copied for room 2

2: Trigger the calculation of the max demand temperature

This should trigger whenever input_number.room1_demand_temp OR input_number.room2_demand_temp changes.
The action should be to update input_number.max_demand_temp with the maxiumum of the above values.

  1. Trigger the state change of the heating demand

This should trigger whenever input_number.max_demand_temp or input_number.demand_tolerance changes.
The action should be to set the binary state of the input_number.thermostatic_demand_state to 1 if input_number.max_demand_temp > input_number.demand_tolerance or zero otherwise.

If someone could help me figure out how to do one of these, I can probably work the others out! Thanks so much.

Hi there, I think this could be done easily with thermostat and climate domain service but to help you with automation ,the first automation should look like below.

alias: Demand Temperature Set
description: ''
mode: single
trigger:
  - platform: state
    entity_id: input_number.room1_set_temp
  - platform: state
    entity_id: sensor.room1_temp
condition: []
action:
  - service: input_number.set_value
    target:
      entity_id: input_number.room1_demand_temp
    data:
      value: >-
        {{ (states('input_number.room1_set_temp') | int -
        states('sensor.room1_temp') | int) | abs }}

Here I have used a template to find the difference between the two temperatures. If you want to have both positive and negative values please remove |abs from the template

2nd automation would look like

alias: Max Demand Temperature Set
description: ''
mode: single
trigger:
  - platform: state
    entity_id: input_number.room1_demand_temp
  - platform: state
    entity_id: input_number.room2_demand_temp
condition: []
action:
  - service: input_number.set_value
    target:
      entity_id: input_number.max_demand_temp
    data:
      value: >-
        {% if states('input_number.room1_demand_temp')|int >=
        states('input_number.room2_demand_temp')|int %}    
        {{states('input_number.room1_demand_temp')|int}} {% else %}    
        {{states('input_number.room2_demand_temp')|int}} {% endif %}

Third would look like

alias: Heating demand
description: ''
mode: single
trigger:
  - platform: state
    entity_id: ' input_number.max_demand_temp'
  - platform: state
    entity_id: input_number.demand_tolerance
condition: []
action:
  - service: input_number.set_value
    target:
      entity_id: input_number.thermostatic_demand_state
    data:
      value: >-
        {% if states('input_number.max_demand_temp')|int >
        states('input_number.demand_tolerance')|int %}     1 {% else %}     0 {%
        endif %}

There could be small corrections in all these but I hope you get the idea of the templates used.
If you have any doubt regarding deploying automations, please check the below gif

1 Like

Set your triggers in the automation for ALL of the inputs you are watching. Don’t fill in any values in the triggers though, other than trigger id, give them short trigger id’s

Nothing in conditions.

In the main automation, for the action you pick choose.
Then to satisfy #1, you pick OR in the conditions. And select the first trigger id as the condition, then add a second condition within the OR block and add the second trigger id. Now in actions you can do call service for input_number.set_value and use a template to calculate the difference you want to set.

Now you want to look for the button “Add Option”, and then essentially repeat what you just did, use OR for the condition, and then add the next triggers you want to act upon.

Repeat the process.

Make sure that because this automation will be triggered, when a lot of inputs are changed, and those inputs are changed from within this automation, that the mode is NOT set to single, instead set it to either Queued or Parallel.

I would query whether or not your “binary” input_number, is supposed to be an input_number, or whether it would be better as an input_boolean - which is what binary stuff should really be.

If this explanation is not good enough, I’ll come back (or someone will) with example code.

1 Like
{{ [states('input_number.room1_demand_temp')|int,states('input_number.room2_demand_temp')|int]|max }}

Does that job.

1 Like

Amazing thank you!

One slight fly in the ointment, my thermostatic_demand_state input is actually an input_boolean.
You can’t set an input_boolean with set_value… how would I change this to work with a true/false on boolean rather than a 1/0 on a number?

action:
  - service: input_number.set_value
    target:
      entity_id: input_number.thermostatic_demand_state
    data:
      value: >-
        {% if states('input_number.max_demand_temp')|int >
        states('input_number.demand_tolerance')|int %}     1 {% else %}     0 {%
        endif %}

Thanks again…

Just read the documentation on the automation modes. Would ‘restart’ not be better for this, as I only care about the latest state?

Please change the entity_ids

alias: Heating demand
description: ''
mode: single
trigger:
  - platform: state
    entity_id: ' input_number.max_demand_temp'
  - platform: state
    entity_id: input_number.demand_tolerance
condition: []
action:
  - choose:
      - conditions:
          - condition: template
            value_template: >-
              {{states('input_number.max_demand_temp')|int >
              states('input_number.demand_tolerance')|int }}
        sequence:
          - service: input_boolean.turn_on
            target:
              entity_id: input_boolean.thermostatic_demand_state
    default:
      - service: input_boolean.turn_off
        target:
          entity_id: input_boolean.thermostatic_demand_state
1 Like

Although choose has many applications, this is a situation where a service template is adequate.

alias: Heating demand
description: ''
mode: single
trigger:
  - platform: state
    entity_id:
      - input_number.max_demand_temp
      - input_number.demand_tolerance
condition: []
action:
  - service: "input_boolean.turn_{{ 'on' if states('input_number.max_demand_temp')|int > states('input_number.demand_tolerance')|int else 'off' }}"
    target:
      entity_id: input_boolean.thermostatic_demand_state

Potentially restart would work, but I wanted to prevent any weird race conditions. Because the same automation would react to all 3 of your needs, then when need 1 is met, it sets the input number that need 2 is then triggered by, which would restart the automation, and then need 2 sets the input_boolean in need 3 which would trigger the automation again. Restart will probably be OK, but I was trying to avoid any situation where the automation had not finished it’s previous task before it was triggered again.