Pass variable from button to IF part of script (kid's internet timer switch)

Hi. Please bear with me as I’m trying to learn how to use variables to reduce the number of seperate scripts and automations that I’m making.

I’m trying to use a single script to toggle either of kid’s internet access. I’ve got it partially working.

Right now when I hit a button on the dash that calls this script it starts a timer based on an input_number which is exposed as a slider.

Here is my dash card including the button for anyone interested:

square: false
type: grid
cards:
  - square: false
    type: grid
    cards:
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: script.lan_kids_internet_timer_script
          data:
            option: timer.lan_kid1_s_internet_timer
          target: {}
        entity: switch.kid1_s_chromebook
        show_state: true
        icon_height: 40px
        name: kid1's Internet
      - show_name: true
        show_icon: true
        type: button
        tap_action:
          action: call-service
          service: script.lan_kids_internet_timer_script
          data:
            option: timer.lan_kid2_s_internet_timer
          target: {}
        entity: switch.kid2_s_chromebook
        show_state: true
        icon_height: 40px
        name: kid2's Internet
    columns: 2
  - square: false
    type: grid
    cards:
      - type: custom:mushroom-template-card
        primary: >-
          {% set t = 'timer.lan_kid1_s_internet_timer' %}

          {% set state = states(t) %}

          {% set finish = state_attr(t, 'finishes_at') %}

          {% set remain = state_attr(t, 'remaining') %}

          {% set seconds = (as_timestamp(finish,0)-as_timestamp(now()))|int %}

          {% set left = iif(finish == None,iif(remain == None,0,as_timedelta('0
          ' ~remain).seconds),seconds) %}

          {{ left| timestamp_custom('%H:%M:%S', 0) }}
        secondary: Time Remaining
        icon: mdi:web
        tap_action:
          action: toggle
        hold_action:
          action: more-info
        icon_color: ''
        entity: timer.lan_kid1_s_internet_timer
      - type: custom:mushroom-template-card
        primary: >-
          {% set t = 'timer.lan_jkid2_s_internet_timer' %}

          {% set state = states(t) %}

          {% set finish = state_attr(t, 'finishes_at') %}

          {% set remain = state_attr(t, 'remaining') %}

          {% set seconds = (as_timestamp(finish,0)-as_timestamp(now()))|int %}

          {% set left = iif(finish == None,iif(remain == None,0,as_timedelta('0
          ' ~remain).seconds),seconds) %}

          {{ left| timestamp_custom('%H:%M:%S', 0) }}
        secondary: Time Remaining
        icon: mdi:web
        tap_action:
          action: toggle
        hold_action:
          action: more-info
        icon_color: ''
        entity: timer.lan_kid2_s_internet_timer
    columns: 2
  - type: custom:slider-entity-row
    entity: input_number.lan_kids_internet_timer_input
    slider:
      direction: left-right
      background: solid
      use_state_color: true
      use_percentage_bg_opacity: false
      show_track: false
      toggle_on_click: false
      force_square: false
    show_name: true
    show_state: true
    compact: true
    icon:
      show: true
      use_state_color: true
      tap_action:
        action: more-info
      icon: ''
    action_button:
      mode: toggle
      icon: mdi:power
      show: true
      show_spinner: true
      tap_action:
        action: toggle
    name: Timer Length
columns: 1

What’s working is to press the button to call the script which starts the timer.

alias: LAN - Kid's Internet Timer Script
sequence:
  - service: timer.start
    data:
      entity_id: "{{option}}"
      duration: "{{ states('input_number.lan_kids_internet_timer_input') | int * 60 }}"
mode: single

I’m using an automation to toggle the switch which controls each device’s internet:

alias: LAN - Turn Kid's Internet on/off
description: ""
trigger:
  - platform: state
    entity_id:
      - timer.lan_kid2_s_internet_timer
      - timer.lan_kid1_s_internet_timer
condition: []
action:
  - if:
      - condition: state
        entity_id: timer.lan_kid2_s_internet_timer
        state: active
    then:
      - service: switch.turn_on
        metadata: {}
        data: {}
        target:
          entity_id: switch.kid2_s_chromebook
    else:
      - service: switch.turn_off
        metadata: {}
        data: {}
        target:
          entity_id: switch.kid2_s_chromebook
  - if:
      - condition: state
        entity_id: timer.lan_kid1_s_internet_timer
        state: active
    then:
      - service: switch.turn_on
        metadata: {}
        data: {}
        target:
          entity_id: switch.kid1_s_chromebook
    else:
      - service: switch.turn_off
        metadata: {}
        data: {}
        target:
          entity_id: switch.kid1_s_chromebook
mode: single

That all works to get the timer started. What I’d like to do is be able to hit the button on the dash a second time to cancel the timer which will turn off the internet (make the button more like a toggle).

When I try to add an if statement to the script using the variable "{{option}}" which is from the button I get an error:


Here is the sript after including my IF statement:

alias: LAN - Kid's Internet Timer Script
sequence:
  - service: timer.start
    data:
      entity_id: "{{option}}"
      duration: "{{ states('input_number.lan_kids_internet_timer_input') | int * 60 }}"
    enabled: false
  - if:
      - condition: state
        entity_id: "{{option}}"
        state: "on"
    then:
      - service: timer.cancel
        data:
          entity_id: "{{option}}"
    else:
      - service: timer.start
        data:
          entity_id: "{{option}}"
          duration: >-
            {{ states('input_number.lan_kids_internet_timer_input') | int * 60
            }}
    enabled: true
mode: single

Is there something about the IF statement that cannot take a variable the same as the service part?

Final thought → as I finished my final review of this I think I answered my long question when I realized that the variable is being passed as a part of the service call, hence why it is available to the service call, and not the IF statement.

Do I need to set an input_text helper at the beginning of the script? I’ve gotta go help the kid’s with an outdoor project, but will test that later.

Well, that was a strike, and for the moment I’m beyond my understanding. I think I may need to use a template, but I haven’t figured that out yet.

When I tried setting the input_text and then using it in the IF statement it’s not working because it’s just returning the name, (that makes sense).

service: input_text.set_value
metadata: {}
data:
  value: "{{option}}"
target:
  entity_id: input_text.lan_kid_s_internet_name
if:
  - condition: state
    entity_id: input_text.lan_kid_s_internet_name
    state: "on"
then:
  - service: timer.cancel
    data:
      entity_id: "{{option}}"
else:
  - service: timer.start
    data:
      entity_id: "{{option}}"
      duration: "{{ states('input_number.lan_kids_internet_timer_input') | int * 60 }}"
enabled: true

If I could get the content of the input_text as the output. Is it possible to output the content of an input_text.lan_kid_s_internet_name similar to how a variable is used to output the previously stored value?

i.e. "{{input_text.lan_kid_s_internet_name}}"

(that doesnt’ work, but I’m guessing there’s a way with a template to output the state).

Thanks in advance!

The script syntax looks wrong, you should be declaring fields for the input.

Here is an example that works for me.

# Script to turn a switch on
# Template Parameters
# light
# turn_off
# off
rs_light_turn_off:
  description: "reliable light turn_off"
  fields:
    entity_id:
      description: "The light entity"
      example: "light.entity_id"
    message_id:
      description: "Message Text Destination"
      example: "input_text.rs_light_turn_off_message"
    retry_count_id:
      description: "Retry Counter"
      example: "counter.rs_light_turn_off_retry"
    failed_count_id:
      description: "Failed Counter"
      example: "counter.rs_light_turn_off_failed"
    call_count_id:
      description: "Success Counter"
      example: "counter.rs_light_turn_off_success"
    timeout_seconds:
      description: "Default timeout in seconds"
      example: "5"
  variables:
    max_retry: 3
  mode: parallel
  sequence:
    - service: counter.increment
      continue_on_error: true
      data_template:
        entity_id: "{{call_count_id}}"
    - service: input_text.set_value
      data_template:
        entity_id: "{{ message_id }}"
        value: "{{now().strftime('%H:%M:%S.%f')[:-3]}} turn_off  - start"        
1 Like


A State Condition’s options do not support templates.

Screenshot_20240331-185746~2

Change it to a Template Condition.

  - if:
      - condition: template
        value_template: "{{ is_state(option, 'on') }}"
    then:

A script supports input variables without defining fields. Fields are useful when you want to run the script from developer tools → services, it will then give you a nice UI to input all those variables.

I can see how the docs could be misinterpreted.
This statement:

To configure a script to accept variables using the UI, the variables can be added as fields in the script editor.

Could be interpreted as either

Using the UI you can configure a script to accept variables. The variables can be added as fields in the script editor.

-or-

To configure a script to so that variables can be input from the UI, the variables can be added as fields in the script editor.

The latter interpretation is the correct one.

1 Like

Thank you @PeteRage and @mekaneck for the example and explanations about the fields use. I did get tripped up with the docs on that, but had seen the variable passed with the service call in other cases so I muddled my way down that path.

In the end I was able to use the code that @123 suggested, so thank you for that!

Of note, I did have to tweak the logic on the script that caused the switch.kid1_s_chromebook to follow the timer.lan_kid1_s_internet_timer as well as the service call from my dash button. If I remember correctly I had to reverse the logic of which followed what as there was some conflict, but it’s sorted out now.

Here is the final example that worked for me with some UI tweaks on the dash card:

Script:
alias: LAN - Kid's Internet Timer Script
sequence:
  - service: switch.turn_on
    data:
      entity_id: "{{option2}}"
    enabled: true
  - if:
      - condition: template
        value_template: "{{ is_state(option2, 'on') }}"
    then:
      - service: timer.cancel
        data:
          entity_id: "{{option}}"
    else:
      - service: timer.start
        data:
          entity_id: "{{option}}"
          duration: >-
            {{ states('input_number.lan_kids_internet_timer_input') | int * 60
            }}
    enabled: true
mode: single
icon: mdi:web

Automation:
alias: LAN - Turn Kid's Internet on/off
description: ""
trigger:
  - platform: state
    entity_id:
      - timer.lan_kid2_s_internet_timer
      - timer.lan_kid1_s_internet_timer
condition: []
action:
  - if:
      - condition: state
        entity_id: timer.lan_kid2_s_internet_timer
        state: active
    then:
      - service: switch.turn_on
        metadata: {}
        data: {}
        target:
          entity_id: switch.kid2_s_chromebook
    else:
      - service: switch.turn_off
        metadata: {}
        data: {}
        target:
          entity_id: switch.kid2_s_chromebook
  - if:
      - condition: state
        entity_id: timer.lan_kid1_s_internet_timer
        state: active
    then:
      - service: switch.turn_on
        metadata: {}
        data: {}
        target:
          entity_id: switch.kid1_s_chromebook
    else:
      - service: switch.turn_off
        metadata: {}
        data: {}
        target:
          entity_id: switch.kid1_s_chromebook
mode: single
Dash Card
  • requires card-mod (added text color change with state of kids device internet switch)
square: false
type: grid
cards:
  - square: false
    type: grid
    cards:
      - type: conditional
        conditions: []
        card:
          type: custom:mushroom-template-card
          primary: |-
            {% if is_state('switch.kid1_s_chromebook', 'on') %}
              kid1's Internet is On     
            {% elif is_state('switch.kid1_s_chromebook', 'off') %}
              kid1's Internet is Off
            {% endif %}
          secondary: >-
            {% set t = 'timer.lan_kid1_s_internet_timer' %}

            {% set state = states(t) %}

            {% set finish = state_attr(t, 'finishes_at') %}

            {% set remain = state_attr(t, 'remaining') %}

            {% set seconds = (as_timestamp(finish,0)-as_timestamp(now()))|int %}

            {% set left = iif(finish == None,iif(remain ==
            None,0,as_timedelta('0 ' ~remain).seconds),seconds) %}

            {{ left| timestamp_custom('%H:%M:%S', 0) }} Remaining
          tap_action:
            action: call-service
            service: script.lan_kids_internet_timer_script
            data:
              option: timer.lan_kid1_s_internet_timer
              option2: switch.kid1_s_chromebook
            target: {}
          hold_action:
            action: more-info
          icon_color: |-
            {% if is_state('switch.kid1_s_chromebook', 'on') %}
              amber         
            {% elif is_state('switch.kid1_s_chromebook', 'off') %}

            {% endif %}
          entity: timer.lan_kid1_s_internet_timer
          card_mod:
            style:
              mushroom-state-info$: |
                .container {
                  align-items: center;
                          
                 {% if is_state('switch.kid1_s_chromebook','on') %} 
                  --primary-text-color:gold;
                 {%else%}
                  --card-primary-color:#7E7E7E;
                 {% endif %}
                           }
      - type: conditional
        conditions: []
        card:
          type: custom:mushroom-template-card
          primary: |-
            {% if is_state('switch.kid2_s_chromebook', 'on') %}
              kid2's Internet is On     
            {% elif is_state('switch.kid2_s_chromebook', 'off') %}
              kid2's Internet is Off
            {% endif %}
          secondary: >-
            {% set t = 'timer.lan_kid2_s_internet_timer' %}

            {% set state = states(t) %}

            {% set finish = state_attr(t, 'finishes_at') %}

            {% set remain = state_attr(t, 'remaining') %}

            {% set seconds = (as_timestamp(finish,0)-as_timestamp(now()))|int %}

            {% set left = iif(finish == None,iif(remain ==
            None,0,as_timedelta('0 ' ~remain).seconds),seconds) %}

            {{ left| timestamp_custom('%H:%M:%S', 0) }} Remaining
          tap_action:
            action: call-service
            service: script.lan_kids_internet_timer_script
            data:
              option: timer.lan_kid2_s_internet_timer
              option2: switch.kid2_s_chromebook
            target: {}
          hold_action:
            action: more-info
          icon_color: |-
            {% if is_state('switch.kid2_s_chromebook', 'on') %}
              amber         
            {% elif is_state('switch.kid2_s_chromebook', 'off') %}

            {% endif %}
          entity: timer.lan_kid2_s_internet_timer
          card_mod:
            style:
              mushroom-state-info$: |
                .container {
                  align-items: center;
                          
                 {% if is_state('switch.kid2_s_chromebook','on') %} 
                  --primary-text-color:gold;
                 {%else%}
                  --card-primary-color:#7E7E7E;
                 {% endif %}
                           }
    columns: 2
  - type: custom:slider-entity-row
    entity: input_number.lan_kids_internet_timer_input
    slider:
      direction: left-right
      background: solid
      use_state_color: true
      use_percentage_bg_opacity: false
      show_track: false
      toggle_on_click: false
      force_square: false
    show_name: true
    show_state: true
    compact: true
    icon:
      show: true
      use_state_color: true
      tap_action:
        action: more-info
      icon: ''
    action_button:
      mode: toggle
      icon: mdi:power
      show: true
      show_spinner: true
      tap_action:
        action: toggle
    name: Timer Length
columns: 1

image

For anyone interested, the device’s internet switch is exposed from the Unifi Network Application integration. It takes a few seconds to switch on the internet on or off, and the card will show whether it’s on or off with the text color and value. In my testing it sometimes takes a network refresh on the device end to get it to realize that it can now connect again to the WiFi. (This switch “blocks” the device on the Unifi end of things so it could work with WiFi or a hard connection).

It’s my long term plan to see if I can get the time remaining to update immediately with a template / helper, but for now you get a semi frequent update and get a live countdown by long holding the button as that takes you directly to the timer entity.

1 Like