Can not get if/else automation to work

I’m trying to refrain from talking about how terrible HA automations logic is and instead just asking why my automations aren’t working. When I look at it, everything should work, but it doesn’t. When I trigger it manually it will work once but when the if conditions change it will not trigger again.
Maybe there is a person here who has understood the logic of HA better and can correct me with this

trigger:
  - platform: homeassistant
    event: start
  - platform: time_pattern
    minutes: "1"
    hours: "0"
condition:
  - condition: numeric_state
    entity_id: sensor.nordpool
    attribute: current_price
    below: input_number.secondary_heater
  - condition: numeric_state
    entity_id: sensor.ryra_tyte_d1_thermostat_current_temperature
    below: 40
action:
  - if:
      - condition: numeric_state
        entity_id: sensor.nordpool
        attribute: current_price
        below: input_number.secondary_heater
    then:
      - type: turn_on
        device_id: f1e951e4ea1e520eb38b7a6482c2
        entity_id: switch.heat
        domain: switch
    else:
      - type: turn_off
        device_id: f1e951e4ea1e520eb38b7a6482c2
        entity_id: switch.heat
        domain: switch
mode: restart

Explain your requirements so that we can confirm the automation you created actually fulfills them.

Did you mean this ?

condition:
  - condition: numeric_state
    entity_id: sensor.nordpool
    attribute: current_price
    below: input_number.secondary_heater
  - condition: numeric_state
    entity_id: sensor.ryra_tyte_d1_thermostat_current_temperature
    below: 40

Iirc, that means both conditions have to pass their threshold at the same time.

I actually don’t know what to explain, my problem is, that to get it to run should be really simple,
if nordpool price is below given price from secondary heater swich should turn on, else it should turn off
Automation should restart and trigger every minute to check the if conditions again.
Additional conditions before triggering if part, check also nordpool price and actual water temp.

yeah, that means when water temp is below 40 and nordpool is below given price it should run.
When I tested the both conditions were true

Yeah, ignore me, i was thinking of trigger thresholds, not conditions.

As per: Automation Trigger - Home Assistant

    - platform: time_pattern
      # Matches every hour at 5 minutes past whole
      minutes: 5

Yours only seems to be configured to fire every day at 00:01 (one minute past midnight that is). What you’re probably looking for is:

    - platform: time_pattern
      minutes: "*" # Every minute of any hour

Your automation’s condition doesn’t merely require that the price is below a threshold, it also requires the temperature sensor to be below a threshold.

That’s why I asked that you explain your application’s requirements.

Why?

Let the Nordpool current_price and temperature sensor serve as the triggers.

1 Like

Good, because there’s nothing wrong with the automation logic, just your understanding of it.

The way you have written it, it:

  • triggers at 00:01 every day (as per @D-side, you probably meant "/1")
  • checks that the price is low AND the temperature is low, otherwise stops
  • turns the heater on if the price is low; or off if it isn’t (which will never happen, as the condition has already precluded it)

Here’s a better way to do it, with an assumption on how you want the temperature to work. Trigger on any change to the price or the temperature (as per @123’s suggestion — in general, if you’re triggering at a regular time, you’re probably doing it wrong), no conditions required, switch on if both low price AND low temperature, otherwise off.

trigger:
  - platform: state
    entity_id: sensor.nordpool
    attribute: current_price
  - platform: state
    entity_id: sensor.ryra_tyte_d1_thermostat_current_temperature

action:
  - if:
      - condition: numeric_state
        entity_id: sensor.nordpool
        attribute: current_price
        below: input_number.secondary_heater
      - condition: numeric_state
        entity_id: sensor.ryra_tyte_d1_thermostat_current_temperature
        below: 40
    then:
      - service: switch.turn_on
        entity_id: switch.heat
    else:
      - service: switch.turn_off
        entity_id: switch.heat
alias: example 
trigger:
  - platform: state 
    entity_id: sensor.nordpool
    attribute: current_price
  - platform: state 
    entity_id: sensor.ryra_tyte_d1_thermostat_current_temperature
    to:
condition:
  - condition: numeric_state
    entity_id: sensor.nordpool
    attribute: current_price
    below: input_number.secondary_heater
  - condition: numeric_state
    entity_id: sensor.ryra_tyte_d1_thermostat_current_temperature
    below: 40
action:
  - variables:
      is_true: >
        {{ state_attr('sensor.nordpool', 'current_price') | float(0) < 
          states('input_number.secondary_heater') | float(0) }}
  - service: "switch.turn_{{ iif(is_true, 'on', 'off') }}"
    target: 
      entity_id: switch.heat
mode: single 

EDIT

The condition is problematic here because it’s designed to only allow for when the switch should be turned on but not off. That’s the flaw in the original design.

Move them to the action as shown in troon’s example.

If the price stays low, the water will boil — and if the price goes high, the condition will block it switching off, surely?

It will (block it). Hopefully the author sees that as well and comes to the same conclusion.

Nordpool changes hourly. I don’t know how to trigger exactly after full hour so I tried minute as a temporary workaround.
And of course, both thresholds were met for testing. I can play with threshold numbers regardless of actual values.
However it seems like D-side had a correct solution for my minute trigger. I imagine that when I want to trigger hourly I can use same solution

Trigger when it changes then:

trigger:
  - platform: state 
    entity_id: sensor.nordpool
    attribute: current_price

You really don’t want to do this. It’s inelegant and inefficient. Trigger when the thing you’re interested in changes.

You seem to be misunderstanding what the trigger does. My code snippet above says “start the automation when there is a change to the Nordpool current_price attribute”. It doesn’t care if that happens every day, every ten seconds or at completely random intervals: it will run as soon as a new value arrives, which is surely what you want.

As an analogy, you don’t listen to your phone every minute to see if it’s ringing: you react when it changes from not ringing to ringing.

You have an unhealthy fixation with the Time Pattern Trigger.

There’s no need to trigger the automation according to a fixed time interval. Just let the change in the Nordpool price serve as the trigger.

BTW, the example I posted above serves to highlight the problem with your original example (hint: it’s the condition).

My goal was to move from simple to more relevant. It is almost impossible to find errors if I start with every condition possible, so of course now I’m happy to see suggestions on how to improve it.

No one has requested that you do that.

My only request was that you explain what you wanted to achieve so that your automation could be reviewed to determine if it meets your requirements. Basically you wanted a switch to be turned on/off based on changes in energy pricing and temperature. The original automation’s choice of trigger and especially condition is what prevented it from turning off the switch.

Since I’m still not entirely sure how the HA logic works here, if the temperature condition is entered in the action part, does the heating turn off again when 40 threshold is reached? If so, this is undesirable behavior. My goal is to heat until the price changes again above a threshold or the temp is somewhere in the 70 range.
Also, I have a feeling that if I just use temp change as one trigger it will trigger too often! Every 0.1 change here is probably counted as a change in temperature.

OK, you didn’t specify that, hence the request for detailed requirements as the first response to your post…

Triggers are cheap: it doesn’t matter. Your sensor will probably only be reporting every minute maximum, which is what you were proposing to do with your time pattern trigger.

With your new temperature requirement, I’d write it like this, with two automations to keep each clean and simple. Some people prefer more complex logic and shorter / fewer automations, but this way is my personal preference. I’ve added an id to each (random UUID) so you can use the automation trace facility; and I have used 70°C for your upper temperature threshold. With this structure, the triggers are numeric_state and will only trigger when the value crosses the threshold — so when the temperature goes from below 40°C to above it, for example. Note that this code might try to turn off an already-off switch (if the price goes high whilst the water is cooling from 70° to 40°) — this usually doesn’t matter.

alias: "Switch on water heater"
description: >
    Turns on the water heater when the price is cheap
    AND the water is cold. Triggers on either thing becoming
    true, checks that both are true in the conditions before
    turning the heater on.

id: 9a437d80-2ca3-4551-b122-7d04330c0f91

trigger:
  - platform: numeric_state
    entity_id: sensor.nordpool
    attribute: current_price
    below: input_number.secondary_heater
  - platform: numeric_state
    entity_id: sensor.ryra_tyte_d1_thermostat_current_temperature
    below: 40

condition:
  - condition: numeric_state
    entity_id: sensor.nordpool
    attribute: current_price
    below: input_number.secondary_heater
  - condition: numeric_state
    entity_id: sensor.ryra_tyte_d1_thermostat_current_temperature
    below: 40

action:
  - service: switch.turn_on
    entity_id: switch.heat

alias: "Switch off water heater"
description: >
    Turns off the water heater when the price is expensive
    OR the water is hot. Triggers on either becoming true,
    no need for conditions.

id: d7333c99-fad1-412d-8ff0-1280ea58ea73

trigger:
  - platform: numeric_state
    entity_id: sensor.nordpool
    attribute: current_price
    above: input_number.secondary_heater
  - platform: numeric_state
    entity_id: sensor.ryra_tyte_d1_thermostat_current_temperature
    above: 70

action:
  - service: switch.turn_off
    entity_id: switch.heat

Pretty much, yes.

But as others said, if your goal is to make the state of one thing (the heater) dependent on states of others (in conditions), the most direct course is to trigger automation when any the source states change. If you’re concerned that source states may change a bit too often, causing intermittent switching, you can throttle it. That’ll likely result in less unnecessary busywork in HA. Because temperatures tend to stabilize every once in a while. Time never does.

As a more advanced alternative, since half of that automation is basically a thermostat, you can build a Generic Thermostat out of a heater switch and a temperature sensor, and turn that thermostat on or off depending on the price.

1 Like