Writing a script from scratch: where to put the code and how to turn on/off switches

Hello everyone,

I’m new to HA and trying to get my head around how to write a script, that is triggered by an automation, performs some calculations and decision and then steers my sprinklers. I know I could probably compose the script via the UI, but I think it would be much leaner to write it like below. This is the scenario:

  1. I have an automation that listens to a change of a drop down and calls a script passing the selected value to the script.
  2. in the script I want to calculate delays based on the passed value
  3. and then switch on sprinklers
  4. wait for the calculated delay and
  5. switch them off
  6. send a notification about how long the watering lasted

This is my code so far (selection Information passed by the automation to the script):

{% set durter=700 %}
{% set durs1=620 %}
{% set durs2=420 %}
{% set durbm=1240 %}

{% if selection=="Off" %}
Sprinkler are off
{% else %}
## calculate sprinkler on time for each section
{% set giesentr = ((selection | float * durter) | int | timestamp_custom('00:%M:%S')) %}
{% set giesens1 = (selection | float * durs1) | int | timestamp_custom('00:%M:%S') %}
{% set giesens2 = (selection | float * durs2) | int | timestamp_custom('00:%M:%S') %}
{% set giesenbm = (selection | float * durbm) | int | timestamp_custom('00:%M:%S') %}
{% set gesamtdur = ( giesentr + giesens1 + giesens2 + giesenbm | int timestamp_custom('00:%M:%S') %}

##steer the time on for each sprinkler based on the selection
Turn on: switch.sprinkler_terasse
  delay: {{ giesentr }}
  Turn of: switch.sprinkler_terasse
Turn on: switch.sprinkler_seite1
  delay: {{ giesens1 }}
  Turn off: switch.sprinkler_seite1
Turn on: switch.sprinkler_seite2 
  delay: {{ giesens2 }}
  Turn off: switch.sprinkler_seite2
Turn on: switch.sprinkler_baum
  delay: {{ giesenbm }}
  Turn off: switch.sprinkler_baum
{% endif %}

send notification
  data:
    message: Everything took "{{ gesamtdur }}" minutes
    title: Watering completed

So my questions are:

  1. where withing the script yaml should I put this code?
  2. How to I turn switches of/of
  3. How to I initiate delays?

thx everyone for the help

I would strongly advise you to write a few scripts in the UI first, then you can look to see what the yaml looks like and your questions will be answered… :grinning_face_with_smiling_eyes:

Here’s an example, though:

dehumidifiers_off:
  alias: Dehumidifiers off
  sequence:
  - condition: state
    entity_id: input_boolean.leave_dehumidifiers_on
    state: 'off'
  - service: switch.turn_off
    data: {}
    target:
      entity_id:
      - switch.tasmota_14
      - switch.tasmota_1
  - delay:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
  - service: switch.turn_on
    data: {}
    target:
      entity_id:
      - switch.tasmota_14
      - switch.tasmota_1
  mode: single
  icon: mdi:air-humidifier-off

The dehumidifiers are not smart. They have to be switched on manually. This script turns them off by turning off the power with the smart sockets they are plugged into. It then turns the sockets on again five seconds later. Typically it would be launched from an automation, such as the one that is triggered when I leave the house.

Yes, my house is quite damp. :roll_eyes:

What you have written is not a Home Assistant script. I agree with @Stiltjack, you should probably start with the UI script editor so you get the correct structure and syntax. It is very easy to set up a “skeleton” of your script in the UI editor, then switch to editing in YAML to incorporate your variable fields and templates.

Hello @Stiltjack, hello @Didgeridrew,

thank you both for the answers. I’ll try to set up the skeleton and then fill in the variables. Let’s see, how far I get :smiley:

Cheers,
Zavjah

Hello @Didgeridrew /@Stiltjack ,

here we go, this is the main part:

alias: BewaesserungSteuerung
sequence:
  - if:
      - condition: template
        value_template: "{{ selection }} = \"Off\""
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id:
            - switch.sprinkler_terasse
            - switch.sprinkler_seite1
            - switch.sprinkler_seite2
            - switch.sprinkler_baum
    else:
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.sprinkler_terasse
      - delay: >
          {% set durter=10 %}
          {% set sel = {{selection }} %}
          {{ ((sel | float * durter) | int | timestamp_custom('00:%M:%S')) }}
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.sprinkler_terasse
mode: single
icon: mdi:sprinkler-variant

selection is the parameter that is passed through to the script by triggering automation. First I check, if Off was selected and turn of the sprinkler.

If not, I start switching the sprinkler on and calculate the delay based on the selection and a variable for the specific sprinkler. And this is where I get the error, that the “Message is malformated…”

How must I write the code for the calculation of the delay?

thx and cheers,
Zavjah

There is no need to use | timestamp_custom('00:%M:%S') , delay accepts seconds as a integer as a valid input. How long are these delays? It usually isn’t a good idea to use delays more than a couple minutes… for prolonged waits or delays it is better to set timers or calendar events.

You are getting the error message because you are attempting to have templates inside templates and perform comparisons outside of templates… The following is a cleaned up version of what you posted, however, without addressing the long delay issue, I would not recommend using it if you need it to be reliable.

alias: BewaesserungSteuerung
fields:
  selection:
    name: Selection
    description: ""
sequence:
  - if:
      - condition: template
        value_template: "{{ selection  == 'Off' }}"
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id:
            - switch.sprinkler_terasse
            - switch.sprinkler_seite1
            - switch.sprinkler_seite2
            - switch.sprinkler_baum
    else:
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.sprinkler_terasse
      - delay: >
          {% set durter=10 %}
          {{ (selection | float * durter) | int }}
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.sprinkler_terasse
mode: single
icon: mdi:sprinkler-variant

Hello @Didgeridrew,

thank you so much for the hints. I’ve chenged eevrything like you suggested using timers and also added a variables section. It work’s like charm :smiley:

This is the final script:

alias: BewaesserungSteuerung
description: "Turn on the sprinkler one after another dependent on selected duration"
fields:
  selection:
    name: Selection
    description: ""
variables:
  durter: 700
  durs1: 620
  durs2: 420
  durbm: 1240
sequence:
  - if:
      - condition: template
        value_template: "{{ selection  == 'Off' }}"
    then:
      - service: switch.turn_off
        data: {}
        target:
          entity_id:
            - switch.sprinkler_terasse
            - switch.sprinkler_seite1
            - switch.sprinkler_seite2
            - switch.sprinkler_baum
    else:
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.sprinkler_terasse
      - service: timer.start
        data:
          duration: |
            {{ (selection | float * durter) | int }}
        target:
          entity_id: timer.timer_sprinkler
      - wait_for_trigger:
          - platform: event
            event_type: timer.finished
            event_data:
              entity_id: timer.timer_sprinkler
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.sprinkler_terasse
      - delay: "00:00:02"
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.sprinkler_seite1
      - service: timer.start
        data:
          duration: |
            {{ (selection | float * durs1) | int }}
        target:
          entity_id: timer.timer_sprinkler
      - wait_for_trigger:
          - platform: event
            event_type: timer.finished
            event_data:
              entity_id: timer.timer_sprinkler
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.sprinkler_seite1
      - delay: "00:00:02"
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.sprinkler_seite2
      - service: timer.start
        data:
          duration: |
            {{ (selection | float * durs2) | int }}
        target:
          entity_id: timer.timer_sprinkler
      - wait_for_trigger:
          - platform: event
            event_type: timer.finished
            event_data:
              entity_id: timer.timer_sprinkler
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.sprinkler_seite2
      - delay: "00:00:02"
      - service: switch.turn_on
        data: {}
        target:
          entity_id: switch.sprinkler_baum
      - service: timer.start
        data:
          duration: |
            {{ (selection | float * durbm) | int }}
        target:
          entity_id: timer.timer_sprinkler
      - wait_for_trigger:
          - platform: event
            event_type: timer.finished
            event_data:
              entity_id: timer.timer_sprinkler
      - service: switch.turn_off
        data: {}
        target:
          entity_id: switch.sprinkler_baum
      - service: input_select.select_option
        data:
          option: "Off"
        target:
          entity_id: input_select.bewasserung_zeitwahl
mode: single
icon: mdi:sprinkler-variant