Malformed script template when calling service - driving me crazy!

Hi,

I’m trying to create a script based off of a blueprint, but my changes won’t save - the validation of the script sequence failes with this message:

Message malformed: template value should be a string for dictionary value @ data['sequence'][0]['repeat']['sequence'][0]['choose'][0]['sequence'][0]['data']

I have tried all kinds of different things, but I have no idea how to resolve this issue. I really hope someone with sharp eyes can spot my (probably very simple) error!

Here’s my current config:

alias: Sunrise
fields:
  light_entity:
    description: Entity to use for sunlight effect
  sunrise_duration:
    description: How long the sunrise should take, in minutes
    default: 30
  start_brightness:
    description: Start light brightness
    default: 2
  end_brightness:
    description: End light brightness
    default: 254
variables:
  seconds: "{{float(sunrise_duration) * 60}}"
  runtime: 0
  tick_time: "{{float(seconds) / float(range_brightness)}}"
  range_brightness: "{{float(end_brightness)-float(start_brightness)}}"
  start_mired: "{{state_attr(light_entity, 'max_mireds')}}"
  end_mired: "{{[state_attr(light_entity, 'min_mireds')|int(0), min_mired|int(0)]|max}}"
sequence:
  - repeat:
      until: "{{ state_attr(light_entity, 'brightness') >= end_brightness }}"
      sequence:
        - delay: "{{tick_time}}"
        - choose:
          - alias: "Supports minreds"
            conditions: "{{state_attr(light_entity, 'min_mireds') != None}}"
            sequence:
              - service: light.turn_on
                # I expect the error to be somewhere around here, according to the error
                data:
                  brightness: >
                    {{(float(end_brightness) - (float(range_brightness) * (seconds - runtime) / float(seconds))) | int(0)}}
                  color_temp: >
                    {{(float(end_mired) + (float(start_mired) - float(end_mired)) * (seconds - runtime) / float(seconds))) | int(0)}}
                target:
                  entity_id: "{{ light_entity }}"
          default:
            - service: light.turn_on
              data:
                brightness: >
                  {{(float(end_brightness) - (float(range_brightness) * (seconds - runtime) / float(seconds))) | int(0)}}
              target:
                entity_id: "{{ light_entity }}"
        - variables:
            runtime: "{{ float(runtime) + tick_time }}"
mode: single

This appears to be solved - apparently there was one too many closing parens in the color_temp template! :frowning:

FWIW, you can simplify the templates that perform calculations with numeric attributes by removing the numerous float functions. Values for mireds and brightness are already numeric, either int or float and not string (so they don’t need conversion from string to float).

Thanks - I’ll do that to remove some of the confusing parens.

Slightly off-topic, how does one increment a counter locally in a repeat while loop?

runtime: "{{ runtime + tick_time }}" keeps setting runtime to tick_time

Maybe try using the repeat.index as a multiplier.

I find it best to avoid ‘fake math’ when dealing with time. a couple half seconds adds up overtime.

  variables:
    start: "{{ now() }}"
    runtime: "{{ (now() - start).seconds }}"
  ...
  sequence:
    ...
    variables:
      runtime: "{{ (now() - start).seconds }}"

Recently I was making a similar fake calculation adding 0.1 second increments over 30 seconds, my result always ended up around ~34 seconds in real time, which I could see in my logs. Switched it to use time exactly and the runtime dropped to exactly 30 seconds + a few micro seconds.