Cover Template - Too Optimistic and always setting new state?

I have my Somfy RTS Blinds set up and working with the Cover Template solution to track the state in HA, which is working fine.

Now I am trying to make them close conditionally, if the windows are open set a pending operation flag and don’t close them (which would be acted on when the window gets closed) and close the blind if window is closed.

So I have the cover template calling a script that handles this fine, however, with the Optimistic option enabled though, as soon as you hit close, the state becomes closed even if the script doesn’t actually the close the physical blind.

I’ve tried adding a Stop action with the error flag on the script when it will not close the blind (i.e. window is open) but the cover template doesn’t seem to see that error and still changes to closed anyway.

I don’t have any position sensors for these blinds, so curious if anyone has any pointers on how to handle it?

My current thinking is that I would have to create some input_number helpers, set the value of those within the script and then use the cover value_template parameter to change the state and not use Optimistic option at all.
Means that I end up with 3 entities for each blind just to get the statefulness and seems excessive but if that will do it, that seems fine.

Thanks in advance.

Can you post your current cover template? I use cover templates quite a bit and have a pretty complex set of them for my regular curtains that are on an Add-A-Motor that has a reverse switch on it so basically it runs until the switch is hit, then it’s in reverse mode the next time you turn on the outlet. I mention that because I’ve been able to control these very dumb curtains with a high degree of accuracy (i.e., open to X percent) and have been through a lot of tweaking over the years to improve upon them. Perhaps seeing your template will help answer some questions.

I do not use optimistic mode at all, I simply timed how long each curtain takes to open and to close and bake that into my template so I know to run it for X seconds to get to Y percent (give or take).

Thanks, I wasn’t sure if the template/scripts themselves would really make sense, but can definitely post them.

Functionality wise, the script and cover configuration is doing what I want, the pending_close helpers are set and the cover moves only when I want etc.

The issue is just that once close_cover runs, it doesn’t care about any of the conditional pieces in the script and always changes state to closed.

If I have optimistic: false then it never changes state, so my assumption is that I would need to use another helper, that has it’s value set by the script and then have that in the value_template for the cover template.

Or some way for close_cover to pick up on the stop: error on the script and not change state for the cover when that happens.


covers.yaml (only showing one cover but have 6 set up):

- platform: template
  covers:
    kitchen_blind_stateful:
      friendly_name: "Kitchen Blind (Stateful)"
      device_class: shade
      optimistic: true
      open_cover:
        - service: script.blinds_open
          data:
            window: "kitchen"
            blind: "kitchen"
      close_cover:
        - service: script.blinds_close
          data:
            window: "kitchen"
            blind: "kitchen"
      stop_cover:
        - service: cover.stop_cover
          target:
            entity_id: cover.kitchen_blind

scripts.yaml

blinds_close:
  alias: Blinds - Close
  sequence:
  - if:
    - condition: template
      value_template: '{{ is_state(''binary_sensor.'' ~ window ~ ''_window_state'',  ''on'') }}'
    then:
    - service: input_boolean.turn_on
      data_template:
        entity_id: input_boolean.blind_{{ blind }}_pending_close
    - service: notify.pushover
      data_template:
        message: '{{ blind }} not closed, Window is Open'
      data:
        title: Blinds Not Closed
    - stop: Blind not closed
      error: true
    else:
    - service: cover.close_cover
      data_template:
        entity_id: cover.{{ blind }}_blind
    - if:
      - condition: template
        value_template: '{{ is_state(''input_boolean.blind_'' ~ window ~ ''_pending_close'',  ''on'') }}'
      then:
      - service: input_boolean.turn_off
        data_template:
          entity_id: input_boolean.blind_{{ blind }}_pending_close
  mode: parallel
  max: 6
blinds_open:
  alias: Blinds - Open
  sequence:
  - service: cover.open_cover
    data_template:
      entity_id: cover.{{ blind }}_blind
  - if:
    - condition: template
      value_template: input_boolean.blind_{{ blind }}_pending_close == on
    then:
    - service: input_boolean.turn_off
      data_template:
        entity_id: input_boolean.blind_{{ blind }}_pending_close
  mode: parallel
  max: 6

The logic in blinds_close is:

  • if window is open
  • then:
    • set pending_close to on and do NOT close
  • else:
    • close cover
    • if pending_close = on, then turn off

blinds_open is a bit more basic:

  • always open
  • if pending_close = on, then turn off

You don’t really need the script, you could put all of that into the template instead for the actions (one of the very reasons I like templates). The open/close state should report properly once the given command finishes it’s sequence, so I wonder if it’s more about the script not returning or not returning promptly that is causing it to not show open or closed properly. I would try putting those script sequences into a cover template just to see if that’s the case - it doesn’t hurt to try.

Same behaviour with it in the template itself (that version is below), I was trying to be clever and not need to repeat that block of code for all 6 covers by using a script, but good shout to try that way.

optimistic: true always gets the state updated, even when it hits the stop: error.
optimistic: false never changes state.


- platform: template
  covers:
    kitchen_blind_stateful:
      friendly_name: "Kitchen Blind (Stateful)"
      device_class: shade
      optimistic: true
      open_cover:
        - service: script.blinds_open
          data:
            window: "kitchen"
            blind: "kitchen"
      close_cover:
        - if:
            - condition: template
              value_template: '{{ is_state("binary_sensor.kitchen_window_state",  "on") }}'
          then:
            - service: input_boolean.turn_on
              data_template:
                entity_id: input_boolean.blind_kitchen_pending_close
            - service: notify.pushover
              data_template:
                message: "kitchen not closed, Window is Open"
              data:
                title: Blinds Not Closed
            - stop: Blind not closed
              error: true
          else:
            - service: cover.close_cover
              data_template:
                entity_id: cover.kitchen_blind
            - if:
                - condition: template
                  value_template: '{{ is_state("input_boolean.blind_kitchen_pending_close",  "on") }}'
              then:
                - service: input_boolean.turn_off
                  data_template:
                    entity_id: input_boolean.blind_kitchen_pending_close

What does the automation trace tell you? I’m betting that you might need a repeat or a delay (or both) in the script/sequence to keep checking the input_boolean.blind_kitchen_pending_close because it could be that you are just trying to check it too fast before it has a chance to toggle to “on”.

The trace (on the script) shows everything doing what I would expect and ending on the stop with error: true and not closing the blind, but the entity from the cover template still gets changed to closed.

I’m not sure how to get trace details for when the steps are in template directly though, but it has the same behaviour anyway.

The condition check for input_boolean.blind_kitchen_pending_close only comes in to play on a subsequent run, since it is in the else for the condition.
It also all works properly, gets updated and all shows fine on the trace, so I don’t think that is causing problems.

What I want is that only when the else branch runs, that is the only time the actual state of the cover entity should be updated to being closed because it it not closed when the then sequence runs.