Need help - automation used to work but since flashing a new module, it does not

Long story short, I flashed a new ESP32 and got everything working again apart from one automation that I’m stuck with.

The full ESP home config is as follows:

esphome:
  name: study-blinds
  platform: ESP32
  board: esp32dev

  on_boot:
    then:
      - switch.turn_off: blinds_fault_light 
      
      - wait_until:
          api.connected
        
      - homeassistant.service:
          service: input_boolean.turn_off
          data:
            entity_id: input_boolean.blinds_are_closed_boolean
      - delay: 1s
      - script.execute: homeblinds
      - delay: 45s
      - script.execute: homeslats

# Enable logging
logger:


# Enable Home Assistant API
api:
  services:
    - service: blinds_position
      variables: 
        target: int
      then:
        - stepper.set_target:
            id: blinds_motor
            target: !lambda "return target;"
            
        - sensor.template.publish:
            id: blinds_position
            state: !lambda 'return target;'
            
      
    - service: slats_position
      variables: 
        target: int
      then:
        - stepper.set_target:
            id: slats_motor
            target: !lambda "return target;"
            
        - sensor.template.publish:
            id: slats_position
            state: !lambda 'return target;'      
            
    - service: blinds_speed
      variables: 
        target: int
      then:
        - stepper.set_speed:
            id: blinds_motor
            speed: !lambda "return target;"
    
    
    - service: home_slats
      then:
        - script.execute: homeslats
    
    - service: home_blinds
      then:
        - script.execute: homeblinds
    
    - service: open_slats
      then:
        - stepper.set_target:
            id: slats_motor
            target: 0
      
    - service: open_blinds
      then:
        - stepper.set_target:
            id: blinds_motor
            target: -17600
        - cover.template.publish:
            id: Study_Blind
            state: OPEN
      
cover:
  - platform: template
    name: "Study Blind"
    id: Study_Blind
    device_class: blind
    open_action:
      - stepper.set_target:
          id: slats_motor
          target: 0
      - delay: 30s
      - sensor.template.publish:
          id: slats_position
          state: !lambda return id(slats_motor).target_position;
          
      - stepper.set_target:
          id: blinds_motor
          target: -17600
      - sensor.template.publish:
          id: blinds_position
          state: !lambda return id(blinds_motor).target_position;
      - homeassistant.service:
          service: input_boolean.turn_off
          data:
            entity_id: input_boolean.blinds_are_closed_boolean
          
          
    close_action:
      - stepper.set_target:
          id: blinds_motor
          target: 0
      - delay: 45s    
      - sensor.template.publish:
          id: blinds_position
          state: !lambda return id(blinds_motor).target_position;
          
      - stepper.set_target:
          id: slats_motor
          target: -10400
      - sensor.template.publish:
          id: slats_position
          state: !lambda return id(slats_motor).target_position;
        
    stop_action:
      - stepper.set_target:
          id: blinds_motor
          target: !lambda return id(blinds_motor).current_position;
      
      - sensor.template.publish:
          id: blinds_position
          state: !lambda return id(blinds_motor).current_position;
          
      - stepper.set_target:
          id: slats_motor
          target: !lambda return id(slats_motor).current_position;         

      - sensor.template.publish:
           id: slats_position
           state: !lambda return id(slats_motor).current_position;     
            
#    optimistic: true
#    assumed_state: false

        
ota:
  password: "#########f"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Study-Blinds Fallback Hotspot"
    password: "###########"

captive_portal:

switch:
  - platform: gpio
    pin: GPIO23 
    name: Blinds_Fault
    id: blinds_fault_light
  - platform: restart
    name: "Study Blinds Restart" 
    
sensor:
  - platform: template
    name: "Study Blind Position"
    id: blinds_position  
    
  - platform: template
    name: "Study Slats Position"
    id: slats_position
 
  - platform: adc
    pin: GPIO34
    name: "Study Sun Brightness"
    id: study_sun_level
    attenuation: 11db
    update_interval: 5s  
  
binary_sensor:
  - platform: status
    name: "Study Blinds Status"    
    
  - platform: gpio
    pin:
      number: GPIO19
      mode: INPUT_PULLUP
      inverted: True
    name: "Slats Endstop"
    id: slats_endstop  
    on_press:
      then:
#         endstop hit, reset stepper position to -10400 and set target also to -10400. This will stop the motor from doing whatever it's doing
        - stepper.report_position:
            id: slats_motor
            position: -10400
        #         just in case, also set the target to 0
        - stepper.set_target:
            id: slats_motor
            target: -10400
            
        - switch.turn_off: blinds_fault_light # start of homing will turn this on.   
        
        - delay: 1s
        
        - stepper.set_target:
            id: slats_motor
            target: -10200 # back off slightly so that endstop is not in triggered state 
            
        - sensor.template.publish:
            id: slats_position
            state: !lambda return id(slats_motor).target_position;   

 
  - platform: gpio
    pin:
      number: GPIO18
      mode: INPUT_PULLUP
      inverted: True
    name: "Blinds Endstop"
    id: blinds_endstop  
    on_press:
      then:
#         endstop hit, reset stepper position to 0 and set target also to 0 - this will stop the motor from doing whatever it's doing
        - stepper.report_position:
            id: blinds_motor
            position: 0
#         just in case, also set the target to 0
        - stepper.set_target:
            id: blinds_motor
            target: 0
            
        - switch.turn_off: blinds_fault_light    
        
        - delay: 1s
        
        - stepper.set_target:
            id: blinds_motor
            target: -50 # back off slightly so that end stop is not left in triggered state
            
        - sensor.template.publish:
            id: blinds_position
            state: !lambda return id(blinds_motor).target_position;            
        
        - homeassistant.service:
            service: input_boolean.turn_on
            data:
              entity_id: input_boolean.blinds_are_closed_boolean

stepper:
  - platform: a4988
    id: blinds_motor
    step_pin: GPIO32
    dir_pin: GPIO33
    max_speed: 500 steps/s

    # Optional:
    sleep_pin:
      number: GPIO25
      inverted: True
    
    acceleration: 800
    deceleration: 800
    
  - platform: a4988
    id: slats_motor
    step_pin: GPIO27
    dir_pin: GPIO26
    max_speed: 700 steps/s

    # Optional:
    sleep_pin:
      number: GPIO14
      inverted: True
    
    acceleration: 800
    deceleration: 800    
    
script:
# add a check that the blinds end stop is triggered first.

  - id: homeslats
    then:
      - switch.turn_on: blinds_fault_light # turn on the fault light. If the end stop switch triggers, it'll turn it off. 
      
      - stepper.report_position:
          id: slats_motor
          position: 0 # set position counter to zero
      - stepper.set_target: # just to be sure
         id: slats_motor
         target: 0 
          
      - stepper.set_target:
          id: slats_motor
          target: -22000 # set to minus 22000 which is more than the maximum it travel before the end stop triggered
            # note. The "on press" action for the endstop switch will stop the motor and set its position to -10400
     
  - id: homeblinds
    then:
      - switch.turn_on: blinds_fault_light # turn on liht at start, end stop switch will turn it off if it triggers
      
      - stepper.report_position:
          id: blinds_motor
          position: 0 # set posotioncounter to zero
      - stepper.set_target: #just to be sure
          id: blinds_motor
          target: 0
    
      - stepper.set_target:
          id: blinds_motor
          target: 21000. # max from fully open to fully closed is about 19500 so switch should tigger before then
          # the "on press" action of the endstop will stop the motor and set it's position toxzero (as well as turning off the fault light).  
          
      - cover.template.publish:
          id: Study_Blind
          state: CLOSED    

The automation in question is this:

alias: "Rotate Study Blinds Slats "
description: >-
  This will rotate the study blind slats with the sun relative to the window but
  only during daylight hours, the blinds are closed and not in a fault
  condition.
trigger:
  - platform: state
    entity_id: sensor.slat_pos
condition:
  - condition: sun
    after: sunrise
    after_offset: "00:05:00"
  - condition: sun
    before: sunset
    before_offset: "-00:05:00"
  - type: is_on
    condition: device
    device_id: 4c52cc10fd000ad2af5aa397c7efd055
    entity_id: binary_sensor.study_blinds_slats_endstop
    domain: binary_sensor
  - condition: state
    entity_id: input_boolean.blinds_are_closed_boolean
    state: "on"
action:
  - service: esphome.study_blinds_slats_position
    data_template:
      target: "{{ trigger.to_state.state | int }}"
mode: single

When I run it, then check the trace, the error message is this:

Executed: 13 March 2023 at 12:26:51
Error: Error rendering data template: UndefinedError: 'dict object' has no attribute 'to_state'

and the offending piece of code is this:

service: esphome.study_blinds_slats_position
data_template:
  target: '{{ trigger.to_state.state | int }}'

What is driving me nuts is that this all worked flawlessly and has been doing so for a couple of years or so. The problem has occurred since I flashed a new device with the same code. i had a lot of problems with entity names being changed so whether this has anything to do with it, I’m not sure. Also, I put this all together couple of years ago mostly from code that I scraped from various sources, and can’t remember how or why it works.

I’d really appreciate any help.

TIA

data these days, not data_template.

Try and listen for events while this sensor changes state:

This is even more nuts. I have another similar automation which uses the exact same action and which works perfectly.

So this works:

alias: Move Slats
description: ""
trigger:
  - platform: state
    entity_id: input_number.slats_position
condition: []
action:
  - service: esphome.study_blinds_slats_position
    data_template:
      target: "{{ trigger.to_state.state | int }}"
mode: single

But this throws the error detailed above

alias: "Rotate Study Blinds Slats "
description: >-
  This will rotate the study blind slats with the sun relative to the window but
  only during daylight hours, the blinds are closed and not in a fault
  condition.
trigger:
  - platform: state
    entity_id:
      - sensor.slat_pos
condition:
  - condition: sun
    after: sunrise
    after_offset: "00:05:00"
  - condition: sun
    before: sunset
    before_offset: "-00:05:00"
  - type: is_on
    condition: device
    device_id: 4c52cc10fd000ad2af5aa397c7efd055
    entity_id: binary_sensor.study_blinds_slats_endstop
    domain: binary_sensor
  - condition: state
    entity_id: input_boolean.blinds_are_closed_boolean
    state: "on"
action:
  - service: esphome.study_blinds_slats_position
    data_template:
      target: "{{ trigger.to_state.state | int }}"
mode: single

The code for the action is identical in both automations. Assuming that the conditions are all valid (which they seem to be according to the trace, then the only difference I can see is the trigger. But it’s a valid entity and one which I monitor in the dashboard. I can see the state change in the dashboard so why am I getting this error about " no attribute to_state" ?

I think I’ve solved this myself. The reason the automation was failing was because I missed one of the entity name changes that occurred when I flashed a new device. This entity was one of the conditions for the automation. So I fixed that but I think that testing the automation by hitting “run” causes the error that I was then seeing. Because the trigger for the automation should be an entity state change and that’s what the template evaluates. If I hit “run” then there won’t have been a state change so trigger to_state.state can’t be evaluated. At least that’s what I think is happening…