How do I best create a loop?

Ok, so things are coming along with my small project here.
Now I have set up two relays, one as a switch, and the other as a light.
The switch will toggle the light as well, but not vice versa.
I’ve then made a small script, that after some time will turn off the relays.
But I would like for it to start flashing the light when it’s close to timing out.

The current script looks like this

script:
  - id: countdown
    then:
    - delay: 1min   #20min  # timer length
    - script.execute: flashing
    - while:
        condition:
          script.is_running: flashing
        then:
          - light.turn_off: buttonlight
          - delay: 5s
          - light.turn_on: buttonlight
          - delay: 5s
    - script.execute: flashing
    - while:
        condition:
          script.is_running: flashing
        then:
          - light.turn_off: buttonlight
          - delay: 2s
          - light.turn_on: buttonlight
          - delay: 2s
    - switch.turn_off: relay
    - light.turn_off: buttonlight
  - id: flashing
    then:
    - delay: 1min

But is that really the best way of doing it? I mean by having a while loop that runs until the other script that sets the time for the while loop is running? I couldn’t find a condition in the while itself that allowed for it to run in a specific time interval.

With respect to the light, do it the easy way… :slight_smile: Use the effects of a light and add the flash effect. Then you can just call the light.turn_on service with the flash effect and know it will be flashing.

Script isn’t a bad choice for what you are trying to do by using delay. Just have the on_turn_on: action for the relay output to start your “countdown” script.

1 Like

Hi @ronytomen
Thankyou for the help. I did the on_turn_on in the relay :slight_smile:
I looked at the effects for light, but I could find something that suited me, is I don’t see a flash effect in the list? But is that just poor documentation, or is it the stobe effect I should use somehow?

The light as I tried it:

light:
  - platform: binary
    id: buttonlight
    name: '${device_name} powerindicator'
    output: light_relay
    effects:
      - strobe:
        name: SlowFlash
        colors:
          - state: true
            duration: 3s
          - state: false
            duration: 3s
      - strobe:
        name: FastFlash
        colors:
          - state: true
            duration: 1s
          - state: false
            duration: 3s

But that doesn’t work, it says

light:
  - platform: binary
    id: buttonlight
    name: '${device_name} powerindicator'
    output: light_relay
    effects:
      - strobe:
          name: SlowFlash
          colors:
            - state: true
              duration: 3s
            - state: false
              duration: 3s
      - strobe:
          name: FastFlash
          colors:
            - state: true
              duration: 1s
            - state: false
              duration: 3s

Try fixing the indentation?

Darned, I really thought I had looked at the indentation, but the name is also an indentation level, jeez :slight_smile:
Thankyou, now I just need to figure out how to use the effects :wink:

Ok, so I got that part sorted, it sets the effect ( I can see that in the log), but it doesn’t flash the relay. This is the current version of the code:

This is the script for the countdown:

script:
  - id: countdown
    then:
    - delay: ${countdown_time}  # timer length
    - script.execute: warningperiod
    - light.turn_on:
        id: buttonlight
        effect: SlowFlash
    - delay: "${slow_flashing_time}"
    - light.turn_on:
        id: buttonlight
        effect: FastFlash
    - delay: "${fast_flashing_time}"
    - switch.turn_off: relay
    - light.turn_off: buttonlight
  - id: warningperiod
    then:
    - delay: "${slow_flashing_time}"
    - delay: "${fast_flashing_time}

I’m trying to figure out a better way to have a marking of when it’s in the ‘warning period’ than having a parallell script, I wonder if I need to use a “global” for that.

The ‘button handling’ part looks like this:

binary_sensor:
  - platform: gpio
    id: button
    internal: true
    pin:
      number: D4
      mode: INPUT_PULLUP
      inverted: true
    on_press:
      - if:
          condition:
            switch.is_on: relay
          then:
            - if:
                condition:
                    - script.is_running: warningperiod
                then:
                  - logger.log: "Countdoun resat"
                  - script.stop: countdown
                  - script.stop: warningperiod
                  - light.turn_on: buttonlight
                  - script.execute: countdown
                else:
                  - switch.turn_off: relay
          else:
            - switch.turn_on: relay
    filters:
      - delayed_off: 30ms

I want it to start over on the countdown, if the button is pressed during the warning period.

Please post the full YAML for this. :slight_smile:

1 Like

Ok ok :slight_smile:

This is the original code, it works, but is of course without the effects that we want to define :slight_smile:

substitutions:
  device_name: raclette-w-temp
  countdown_time: 116min
  slow_flashing_time: 3min
  fast_flashing_time: 1min

esphome:
  name: ${device_name}
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: !secret wifissid
  password: !secret wifipw
  reboot_timeout: 60min
  manual_ip:
    static_ip: 10.11.13.100
    gateway: 10.11.13.1
    subnet: 255.255.255.0
  fast_connect: true
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${device_name} Hotspot"
    password: !secret appw

# Enable Home Assistant API
api:
  password: !secret apipw

ota:
  password: !secret otapw

time:
  - platform: homeassistant
    id: homeassistant_time

logger:
  baud_rate: 0 #need this to free up UART pins

web_server:
  port: 80
  auth:
    username: !secret webuser
    password: !secret webpw

# Timer for auto turnoff
script:
  - id: countdown
    then:
    - delay: ${countdown_time}  # timer length
    - script.execute: slow_flashing
    - while:
        condition:
          script.is_running: slow_flashing
        then:
          - light.turn_off: buttonlight
          - delay: 3s
          - light.turn_on: buttonlight
          - delay: 3s
    - script.execute: fast_flashing
    - while:
        condition:
          script.is_running: fast_flashing
        then:
          - light.turn_off: buttonlight
          - delay: 3s
          - light.turn_on: buttonlight
          - delay: 3s
    - switch.turn_off: relay
    - light.turn_off: buttonlight
  - id: slow_flashing
    then:
    - delay: "${slow_flashing_time}"
  - id: fast_flashing
    then:
    - delay: "${slow_flashing_time}"

spi:
  miso_pin: D6
  clk_pin: D5

# Text Sensor with general information
text_sensor:
  - platform: version
    name: '${device_name} ESPHome Version'
  - platform: wifi_info
    ip_address:
      name: '${device_name} ip'
    ssid:
      name: '${device_name} ssid'

sensor:
  - platform: wifi_signal
    name: '${device_name} wifi signal'
    update_interval: 60s
    accuracy_decimals: 0
  - platform: uptime
    name: '${device_name} uptime'
    unit_of_measurement: days
    update_interval: 300s
    accuracy_decimals: 1
    filters:
      - multiply: 0.000011574
  - platform: max6675
    name: '${device_name} Temperature'
    cs_pin: D8

binary_sensor:
  - platform: gpio
    id: button
    internal: true
    pin:
      number: D4
      mode: INPUT_PULLUP
      inverted: true
    on_press:
      - if:
          condition:
            switch.is_on: relay
          then:
            - if:
                condition:
                  or:
                    - script.is_running: slow_flashing
                    - script.is_running: fast_flashing
                then:
                  - logger.log: "Countdoun resat"
                  - script.stop: countdown
                  - script.stop: slow_flashing
                  - script.stop: fast_flashing
                  - light.turn_on: buttonlight
                  - script.execute: countdown
                else:
                  - switch.turn_off: relay
          else:
            - switch.turn_on: relay
    filters:
      - delayed_off: 30ms

output:
  - platform: gpio
    pin: D1
    id: light_relay

switch:
  - platform: gpio
    pin: D2
    id: relay
    name: '${device_name} relay'
    on_turn_on:
      - light.turn_on: buttonlight
      - script.execute: countdown
    on_turn_off:
      - script.stop: countdown
      - light.turn_off: buttonlight

light:
  - platform: binary
    id: buttonlight
    name: '${device_name} powerindicator'
    output: light_relay

The new code I’ve set up is looking like this

substitutions:
  device_name: raclette-w-temp
  countdown_time: 1min
  slow_flashing_time: 1min
  fast_flashing_time: 1min

esphome:
  name: ${device_name}
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: !secret wifissid
  password: !secret wifipw
  reboot_timeout: 60min
  manual_ip:
    static_ip: 10.11.13.100
    gateway: 10.11.13.1
    subnet: 255.255.255.0
  fast_connect: true
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${device_name} Hotspot"
    password: !secret appw

# Enable Home Assistant API
api:
  password: !secret apipw

ota:
  password: !secret otapw

time:
  - platform: homeassistant
    id: homeassistant_time

logger:
  baud_rate: 0 #need this to free up UART pins

web_server:
  port: 80
  auth:
    username: !secret webuser
    password: !secret webpw

# Timer for auto turnoff
script:
  - id: countdown
    then:
    - delay: ${countdown_time}  # timer length
    - script.execute: flashingdelay
    - light.turn_on:
        id: buttonlight
        effect: SlowFlash
    - delay: "${slow_flashing_time}"
    - light.turn_on:
        id: buttonlight
        effect: FastFlash
    - delay: "${fast_flashing_time}"
    - switch.turn_off: relay
    - light.turn_off: buttonlight
  - id: flashingdelay
    then:
    - delay: "${slow_flashing_time}"
    - delay: "${slow_flashing_time}"

spi:
  miso_pin: D6
  clk_pin: D5

# Text Sensor with general information
text_sensor:
  - platform: version
    name: '${device_name} ESPHome Version'
  - platform: wifi_info
    ip_address:
      name: '${device_name} ip'
    ssid:
      name: '${device_name} ssid'

sensor:
  - platform: wifi_signal
    name: '${device_name} wifi signal'
    update_interval: 60s
    accuracy_decimals: 0
  - platform: uptime
    name: '${device_name} uptime'
    unit_of_measurement: days
    update_interval: 300s
    accuracy_decimals: 1
    filters:
      - multiply: 0.000011574
  - platform: max6675
    name: '${device_name} Temperature'
    cs_pin: D8

binary_sensor:
  - platform: gpio
    id: button
    internal: true
    pin:
      number: D4
      mode: INPUT_PULLUP
      inverted: true
    on_press:
      - if:
          condition:
            switch.is_on: relay
          then:
            - if:
                condition:
                  or:
                    - script.is_running: flashingdelay
                then:
                  - logger.log: "Countdoun resat"
                  - script.stop: countdown
                  - script.stop: flashingdelay
                  - light.turn_on: buttonlight
                  - script.execute: countdown
                else:
                  - switch.turn_off: relay
          else:
            - switch.turn_on: relay
    filters:
      - delayed_off: 30ms

output:
  - platform: gpio
    pin: D1
    id: light_relay

switch:
  - platform: gpio
    pin: D2
    id: relay
    name: '${device_name} relay'
    on_turn_on:
      - light.turn_on: buttonlight
      - script.execute: countdown
    on_turn_off:
      - script.stop: countdown
      - script.stop: flashingdelay
      - light.turn_off: buttonlight

light:
  - platform: binary
    id: buttonlight
    name: '${device_name} powerindicator'
    output: light_relay
    effects:
      - strobe:
          name: SlowFlash
          colors:
            - state: true
              duration: 3s
            - state: false
              duration: 3s
      - strobe:
          name: FastFlash
          colors:
            - state: true
              duration: 1s
            - state: false
              duration: 3s

And the log looks correct:

[22:01:40][D][binary_sensor:036]: 'button': Sending state ON
[22:01:40][D][switch:021]: 'raclette-w-temp relay' Turning ON.
[22:01:40][D][switch:045]: 'raclette-w-temp relay': Sending state ON
[22:01:40][D][light:275]: 'raclette-w-temp powerindicator' Setting:
[22:01:40][D][light:284]:   State: ON
[22:01:40][D][binary_sensor:036]: 'button': Sending state OFF
[22:01:40][D][api.connection:630]: Client 'Home Assistant 2021.6.6 (10.11.12.33)' connected successfully!
[22:01:40][D][time:040]: Synchronized time: Thu Jun 24 22:01:40 2021
[22:02:14][D][max6675:046]: 'raclette-w-temp Temperature': Got temperature=24.2°C
[22:02:14][D][sensor:117]: 'raclette-w-temp Temperature': Sending state 24.25000 °C with 1 decimals of accuracy
[22:02:21][D][sensor:117]: 'raclette-w-temp wifi signal': Sending state -82.00000 dBm with 0 decimals of accuracy
[22:02:40][D][light:275]: 'raclette-w-temp powerindicator' Setting:
[22:02:40][D][light:337]:   Effect: 'SlowFlash'
[22:03:14][D][max6675:046]: 'raclette-w-temp Temperature': Got temperature=24.2°C
[22:03:14][D][sensor:117]: 'raclette-w-temp Temperature': Sending state 24.25000 °C with 1 decimals of accuracy
[22:03:21][D][sensor:117]: 'raclette-w-temp wifi signal': Sending state -74.00000 dBm with 0 decimals of accuracy
[22:03:40][D][light:275]: 'raclette-w-temp powerindicator' Setting:
[22:03:40][D][light:337]:   Effect: 'FastFlash'
[22:03:52][D][binary_sensor:036]: 'button': Sending state ON
[22:03:52][D][main:600]: Countdoun resat
[22:03:52][D][light:275]: 'raclette-w-temp powerindicator' Setting:
[22:03:52][D][binary_sensor:036]: 'button': Sending state OFF
[22:03:58][D][binary_sensor:036]: 'button': Sending state ON
[22:03:58][D][switch:025]: 'raclette-w-temp relay' Turning OFF.
[22:03:58][D][switch:045]: 'raclette-w-temp relay': Sending state OFF
[22:03:58][D][light:275]: 'raclette-w-temp powerindicator' Setting:
[22:03:58][D][light:284]:   State: OFF
[22:03:58][D][light:337]:   Effect: 'None'
[22:03:58][D][binary_sensor:036]: 'button': Sending state OFF