Automation to kick off another automation

I am new here. I previously used Stringify to solve a problem. I live on a farm off the grid with a spring-fed water source. There are tanks outside that I need to heat in the winter, and my bill was $800/month, and I was able to use Stringify to cut that bill in half. But now stringify is gone, and there is no out-of-the-box solution that does what I need:

The automation needs to:
Monitor temperature for a location via WUnderground
When the temp is between 32 and 25 degrees, the smart plugs need to be on for fifteen minutes, off for 45.
When the temp is between 15 and 24 degrees, it needs to be on a half hour, off for half hour.
For 14 degrees and below, it needs to be on constantly.
At the end of these timers, the automation needs to loop back and check the temp again.

Is this possible to do with Home-Assistant?

Yes, it’s possible for one automation to trigger another.
The fastest way (i know of) to do this is with events.
Have one automation fire an event as it’s last action, and have another automation use that event as a trigger.

For example, one automation would have:

  action:
  - [put other actions here]
  - event: trigger_automation_2

And the other automation would have:

  trigger:
    platform: event
    event_type: trigger_automation_2

In that way, one automation (or script, or anything else) can trigger another automation.

you can also do

- service: automation.trigger
  data:
    entity_id: automation.whatever_the_name_is

Hi,
Silicon is usually excellent at this but I don’t understand his aim here.
I wouldn’t do it like that.
$800 a month is a hellofan incentive to get this right.
I assume that you have relay or contactor switches and so are switching them on an hourly basis? (to reduce wear and prolong life). If you had triac switches you could have them 1 min on 3 mins off (for example) this would give you a more even heat and you would not need to store 15 mins of heat to get you through the next 45. Heat loss is proportional to differential so the cooler you can keep the tanks the better.
Still, it might be worthwhile, spending some of that $400 a month on insulation and a heat sensor for each tank. Loose less and only heat to keep from freezing, rather than guessing based on weather.
So, if you are happy with the hourly schedule I’d probably go with a time pattern trigger every hour, checking the temperature and stopping if above temp (we could also trigger on temp going below 32, but that only happens once on the transition hence the time check as primary)
So, if below 32, put the heater on
Then if the temp is in this range set timer to 15, if in that range then set it to 30, if in the final set it to 59 minutes.
Then switch off
Oooooh look its a new hour - rinse and repeat
Do you need actual code, if so I’ll knock some up
Do you have entities yet or are you just speculating ?

Interesting challenge. As I understand it, there are three temperature zones governing the water heater’s operation:

Temperature Zone 1: 32-25, ON for 15 minutes, restart in 45 minutes
Temperature Zone 2: 24-15, ON for 30 minutes, restart in 30 minutes
Temperature Zone 3: 15 and less, ON

In the following example:

  1. sensor.outdoor_temperature represents the Wunderground temperature reading
  2. input_text.temperature_zone keeps track of the current temperature zone

This example uses seven automations.

The first three automations monitor the outdoor temperature. Each one monitors a separate temperature zone (1, 2, and 3). If the temperature enters within the range of a temperature zone the automation turns on the water heater and records the current temperature zone.

- alias: 'monitor temperature zone 1'
  trigger:
  - platform: numeric_state
    entity_id: sensor.outdoor_temperature
    below: 32
    above: 25
  action:
  - service: input_text.set_value
    entity_id: input_text.temperature_zone
    value: 1
  - service: switch.turn_on
    entity_id: switch.water_heater

- alias: 'monitor temperature zone 2'
  trigger:
  - platform: numeric_state
    entity_id: sensor.outdoor_temperature
    below: 24
    above: 15
  action:
  - service: input_text.set_value
    entity_id: input_text.temperature_zone
    value: 2
  - service: switch.turn_on
    entity_id: switch.water_heater

- alias: 'monitor temperature zone 3'
  trigger:
  - platform: numeric_state
    entity_id: sensor.outdoor_temperature
    below: 14
  action:
  - service: input_text.set_value
    entity_id: input_text.temperature_zone
    value: 3
  - service: switch.turn_on
    entity_id: switch.water_heater

The next two automations monitor the time the water heater is on.
The water heater is turn off if it has been on for:

  • 15 minutes AND temperature zone is 1
  • 30 minutes AND temperature zone is 2
- alias: 'heater on 15 minutes'
  trigger:
    platform: state
    entity_id: switch.water_heater
    to: 'on'
    for: '00:15:00'
  condition:
    condition: state
    entity_id: input_text.temperature_zone
    state: '1'
  action:
  - service: switch.turn_off
    entity_id: switch.water_heater

- alias: 'heater on for 30 minutes'
  trigger:
    platform: state
    entity_id: switch.water_heater
    to: 'on'
    for: '00:30:00'
  condition:
    condition: state
    entity_id: input_text.temperature_zone
    state: '2'
  action:
  - service: switch.turn_off
    entity_id: switch.water_heater

The final two automations monitor the time the water heater is off.
The heater is turned on if it has been off for:

  • 45 minutes AND temperature zone is 1
  • 30 minutes AND temperature zone is 2
- alias: 'heater off for 45 minutes'
  trigger:
    platform: state
    entity_id: switch.water_heater
    to: 'off'
    for: '00:45:00'
  condition:
    condition: state
    entity_id: input_text.temperature_zone
    state: '1'
  action:
  - service: switch.turn_on
    entity_id: switch.water_heater

- alias: 'heater off for 30 minutes'
  trigger:
    platform: state
    entity_id: switch.water_heater
    to: 'off'
    for: '00:30:00'
  condition:
    condition: state
    entity_id: input_text.temperature_zone
    state: '2'
  action:
  - service: switch.turn_on
    entity_id: switch.water_heater

Although what I’ve presented is conceptually sound (or so I believe it to be), it is untested. Use at your own risk. I suggest you experiment with something non-critical, like turning a light on/off, before letting it loose on a water heater.

Taras,
What would be wrong with something along the lines of : -

- alias: au_water_tank_heater
  trigger:
  - platform: time_pattern
    hours: 1
  - platform: numeric_state
    entity_id: sensor.outdoor_temperature
    below: 32
  condition:
  - condition: numeric_state
    entity_id: sensor.outdoor_temperature
    below: 32
  action:
  - service: switch.turn_on
    entity_id: switch.water_heater
    action:
      - delay: >
          {% if states('sensor.outdoor_temperature') | float <= 14 %}
            {% set ontme = 59 %}
          {% elif states('sensor.outdoor_temperature') | float <= 24 %}
            {% set ontme = 30 %}
          {% else %}
            {% set ontme = 15 %}
          {% endif %}
          "{{ '00:' ~ ontme ~ ':00' }}"
## to define end of template
  - service: switch.turn_off
    entity_id: switch.water_heater

All in one automation ???

And if would be easy to add temperature bands and different times.
Also what happens in your setup when the temperature is 24.5° ???

Nothing happens. The original specifications don’t indicate what should happen between 24 and 25. If the specs overlooked it then it’s easy enough to adjust the automations.

Is it complete? You mentioned something about adding temperature bands.

Assuming it is complete:
As it stands, it won’t trigger for temperature changes below 32 after it has already dipped below 32 (i.e. if it’s currently 27 and dips to 23, the numeric_state trigger will ignore it. It has to rise above 32 first then dip below it to activate the trigger again). Therefore, after the temperature has dipped below 32, and remains below 32, only the Time Pattern trigger will continue to trigger the automation. So even if the temperature drops into another temperature zone, nothing will happen until the next clock tick (up to 1 hour) of the Time Pattern trigger.

The temperature bands as per the spec are in there already.
I was suggesting (maybe implying) that greater temperature resolution would allow differing times to save energy/money towards the warmer ends.
The time pattern is there to allow it to repeat after initial temperature trigger.
We could also trigger on the 24 and 14 to ensure cover for sudden drops
If the action just runs a script then it can be cancelled and restarted for the new band on the new trigger. Further triggers added to main automation could describe when temp goes up above a threshold and reset new times, this would save more energy
So one automation and one script for all conditions though a second automation could cancel the script and turn the heater off if temp > 32

I overlooked to mention that I’m unfamiliar with the automation’s nested action. Is the first-level action executed if the second-level action is still busy counting down the delay?

For example, let’s assume the temperature just dipped below 32 and so the heater is turned on with a delay of 15 minutes. A minute later, the time_pattern triggers and … does what? Turn on the heater and abort the existing delay and replace it with a new 15 minute delay? Or is locked out while the first delay instance continues to count down?

Okay, here are the two automations (on and off) and the timer script

#### water tank heater based on WU temp
- alias: au_water_tank_heater_on
  trigger:
    - platform: time_pattern
      hours: 1
    - platform: numeric_state
      entity_id: sensor.outdoor_temperature
      below: 32
    - platform: numeric_state
      entity_id: sensor.outdoor_temperature
      below: 24
    - platform: numeric_state
      entity_id: sensor.outdoor_temperature
      below: 14
  condition:
    - condition: numeric_state
      entity_id: sensor.outdoor_temperature
      below: 32
  action:
    - service: script.sc_water_tank_timer
#### turn heater off if temp > 32
- alias: au_water_tank_heater_off
  trigger:
    - platform: numeric_state
      entity_id: sensor.outdoor_temperature
      above: 32
  action:
    - service: script.turn_off
      entity_id: script.sc_water_tank_timer
    - service: switch.turn_off
      entity_id: switch.water_heater
script:
  ## sets time delay based on temp
  sc_water_tank_timer:
    alias: Water Tank Timer
    sequence:
      - service: switch.turn_on
        entity_id: switch.water_heater
      - delay: >
          {% set wut = states('sensor.outdoor_temperature') | float %}
          {% if wut <= 14 %}
            {% set ontime = 59 %}
          {% elif wut <= 24 %}
            {% set ontime = 30 %}
          {% else %}
            {% set ontime = 15 %}
          {% endif %}
          "{{ '00:' ~ ontime ~ ':00' }}"
      - service: switch.turn_off
        entity_id: switch.water_heater

Note: the issue with the above is (as Tarras says) : -
if the temperature falls below 32, the heater comes on (scheduled for 15 mins)
if the time pattern kicks in 14mins (worst case) later it will restart the timer so the heater will be on for 29 mins (again worst case)
AND should the temperature fall to 24 (or lower) at 28 mins then the timer will start again, this time at 30 mins (so heater now on for 59 mins continuous, worst case)
AND if the temperature continues to fall and achieves 14 say 29 mins later, the timer restarts again and keeps the heater on for another 59 mins, so 118 mins continuous (again really stretching circumstances, plumetting temperatures etc. BUT we don’t care because the heater should be on pretty much constantly anyway at this point)
Regardless this is ONLY ever at the start of the cold snap and quickly becomes just time pattern controlled (except at each transition).
The BEST bit though is that you can introduce more bands quite easily (you will need to restart each time, so be aware when you change code)
So, 32 to 28 could be 7 mins an hour
28 to 24 could be 15 mins an hour
24 to 20 could be 22 mins an hour
20 to 17 could be 40 mins an hour
14 to 17 could be 59 mins an hour
Or do it in 2 degree bands - you’d have to suck it and see
Overall less time on = less money spent, so more bands would help save energy and money
My $0.02 anyway

If the temperature is currently 22 and rises to 26, which trigger will handle that change?

It won’t be below: 32 because it was already triggered when the temperature initially fell to 22. That trigger will only be reset when the temperature rises above 32 and then falls below it.

Ah, good point and I had mentioned how I was going to deal with that but forgot about it when I was constructing the post.

- alias: au_water_tank_heater_on
  trigger:
    - platform: time_pattern
      hours: 1
    - platform: numeric_state
      entity_id: sensor.outdoor_temperature
      below: 32
    - platform: numeric_state
      entity_id: sensor.outdoor_temperature
      below: 24
    - platform: numeric_state
      entity_id: sensor.outdoor_temperature
      below: 14
    - platform: numeric_state
      entity_id: sensor.outdoor_temperature
      above: 24
    - platform: numeric_state
      entity_id: sensor.outdoor_temperature
      above: 14
  condition:
    - condition: numeric_state
      entity_id: sensor.outdoor_temperature
      below: 32
  action:
    - service: script.turn_off
      entity_id: script.sc_water_tank_timer
    - service: script.sc_water_tank_timer
#### turn heater off if temp > 32
- alias: au_water_tank_heater_off
  trigger:
    - platform: numeric_state
      entity_id: sensor.outdoor_temperature
      above: 32
  action:
    - service: script.turn_off
      entity_id: script.sc_water_tank_timer
    - service: switch.turn_off
      entity_id: switch.water_heater
script:
  ## sets time delay based on temp
  sc_water_tank_timer:
    alias: Water Tank Timer
    sequence:
      - service: switch.turn_on
        entity_id: switch.water_heater
      - delay: >
          {% set wut = states('sensor.outdoor_temperature') | float %}
          {% if wut <= 14 %}
            {% set ontime = 59 %}
          {% elif wut <= 24 %}
            {% set ontime = 30 %}
          {% else %}
            {% set ontime = 15 %}
          {% endif %}
          "{{ '00:' ~ ontime ~ ':00' }}"
      - service: switch.turn_off
        entity_id: switch.water_heater

Ta Da !

A moment to discuss some ‘design meta’.

One of things I’ve tried to avoid doing is this:

trigger:
 - A
 - B
 - C
 - D
action:
 if A then
 else if B then
 else if C then
 else if D then
 else
 end if

The automation uses many triggers and employs a chain of tests to determine which one triggered it. This often means the thresholds used in the trigger have to be repeated in the action (duplication). Sometimes there’s a good reason to do it this way. For this application, I created separate automations, one for each temperature zone. Why? It’s modular, easy to maintain, and each automation is simple.

Firstly I’d like to say I appreciate this discussion as it highlights two approaches to automation and “if you can’t defend a point, how do you expect anyone to support it” (obviously the ‘you’ in this context is just anyone, including me !).
I generally agree, AND it’s worse than you state in that ALL the different triggers are in one automation AND ALL the response differentiators are repeated in the script.
But … for a newbie getting started he has ALL his relevant conditions in just two places and he only has to get his head round THIS starts it off, THIS runs the bits inbetween and THIS stops it, Configurable VALUES have to trigger in the FIRST (automation) and they act in the MIDDLE (script).
Given different ways to automate this I’d actually redo the hardware first.
If you could use triacs (or even a massively overated contactor) you’d prolong longevity and reliability. AND in so doing you’d be able to reduce the overall cycle time to say 4 mins (thermal inertia issues).
if you could put a temp sensor in the top of the tank (and insulate it) you’d just need to keep the headspace above 32 (say aim at 34) and you’d be laughing. Power saved all round (I wouldn’t mind a small slice of the $800 a month we could cut back on). End of complicated power cycles with heat only applied when actually needed and minimising the thermal inertia quotient, avoiding guessing at losses due to conduction and radiation. And at $800 per month that’s 1.85 cents/minute, lets cut the minutes. The way the OP posted you can clearly see that’s is the aim of the thread.
It’s down to the user what he does though, and I’m just giving an alternate point of view (well technically I was first :crazy_face: ). I’d like to see what Petro thinks as he deals in industrial (machine tools) but maybe he doesn’t do ‘processes’ (may have in his past though).
But ultimately it’s down to the user.
Thanks again

It’s my understanding that one cannot execute a script that’s already running. Does that behavior impact the operation of your example? For example, while it is waiting for the delay to expire, it’s called again because the temperature changed zones.

Duh !
Kicks self in head
Again, my response ‘was’ to consider that and I forgot (more haste, less speed)
Fixed it now.