Prevent blind from closing when window is open

Hi all. Very recently I started with Home Assistant with the intention of getting into home automation and doing some automation at home.

At the moment I have installed a Shelly 2.5 relay to control the blind as well as an Aqara contact sensor in the same window. Both devices work perfectly.

The sensor entity is binary_sensor.room2_window_contactand the Shelly is cover.room2_blind.

Since the blind cannot be lowered while the window is open, I have read in the forum that the best solution would be to use a ā€œTemplate Coverā€. The problem is that I canā€™t get it to work with the following code:

- platform: template
  covers:
    room2_blind_limited:
      device_class: blind
      friendly_name: "Center room blind "
      value_template: "{{is_state('sensor.room2_blind_limited', 'open')}}"
      open_cover:
        service: cover.open_cover
        data:
          entity_id: cover.room2_blind
      close_cover: >-
          {% if is_state('binary_sensor.room2_window_contact', 'close') %}
            service: cover.close_cover
            data:
              entity_id: cover.room2_blind
          {% else %}
            service: cover.stop
            data:
              entity_id: cover.room2_blind
          {% endif %}
      stop_cover:
        service: cover.stop_cover
        data:
          entity_id: cover.room2_blind

I suspect the value_template value is wrong.

Any help is welcome. Thanks!

A template always returns a string, as of now (will change in 0.115 as far as I read) you canā€™t template a dictionary. In addition Iā€™m not sure if you can even use a template in the close_cover section.

You could make a script that checks if the window is open and only closes when the window is not open. Then call this script in the close_cover section.

Binary sensor states are always off or on no matter how they are displayed in the frontend, soā€¦

{% if is_state('binary_sensor.room2_window_contact', 'off') %}

Interesting. I need to read the beta release notes again. I missed that.

Given my limited knowledge, I have decided to tackle the problem starting from scratch.
The first step is to create a template that exactly copies the operation of the cover entity.
The following code works perfectly except that the bar to manage the blind in percentage does not work.

- platform: template
  covers:
    copia_persiana_guillem:
      device_class: shade
      friendly_name: ā€œCopia Persiana Guillemā€
      position_template: ā€œ{{ state_attr(ā€˜cover.persiana_guillemā€™, ā€˜current_positionā€™) }}ā€
      open_cover:
        service: cover.open_cover
        data:
          entity_id: cover.persiana_guillem
      close_cover:
        service: cover.close_cover
        data:
          entity_id: cover.persiana_guillem
      stop_cover:
        service: cover.stop_cover
        data:
          entity_id: cover.persiana_guillem

Here is the cover copy with the nonfuncional position bar:

Note: I have also renamed the entities: cover.room2_blind -> cover.persiana_guillem

Any idea to make the position bar funcional?

Dont use fancy quotes:

ā€œ ā€ and ā€˜ ā€™

Should be:

" " and ' '

Replace them all.

Iā€™m surprised the configuration check did not pick it up and prevent you from restarting.

I donā€™t know what happened with copy&paste, but in the original file quotes are as yours:

" " and ā€™ '.

In the developer tools states menu what is the state of the cover.persiana_guillem attribute cover_position?

The attribute is current_position and Itā€™s 100 when fully open and 0 when fully closed.
I have checked this attribute in various positions in both, cover.persiana_guillem and cover.copia_persiana_guillem and the value is alway the same.

Is there any other way to ā€˜cloneā€™ an entity without using a template?

Finally, after reading Template Cover documentation again, I have realized that I had not taken into account set_position service.
Finally, it works as I wanted to:

- platform: template
  covers:
    copia_persiana_guillem:
      device_class: shade
      friendly_name: "Copia Persiana Guillem"
      position_template: "{{ state_attr('cover.persiana_guillem', 'current_position') }}"
      open_cover:
        service: cover.open_cover
        data:
          entity_id: cover.persiana_guillem
      close_cover:
        service: script.close_cover_if_closed
      stop_cover:
        service: cover.stop_cover
        data:
          entity_id: cover.persiana_guillem
      set_cover_position:
        service: script.set_position_if_closed
        data:
          position: "{{position}}"

And these are the scripts where the status of the window sensor is taken into account:

close_cover_if_closed:
  alias: Close_cover_only_if_wind_closed_script
  sequence:
  - condition: state
    entity_id: binary_sensor.sensor_ventana_guillem_contact
    state: 'off'
  - service: cover.close_cover
    data:
      entity_id: cover.persiana_guillem
  
set_position_if_closed:
  alias: Set_position_only_if_wind_closed_script
  sequence:
  - condition: state
    entity_id: binary_sensor.sensor_ventana_guillem_contact
    state: 'off'
  - service: cover.set_cover_position
    data:
      entity_id: cover.persiana_guillem
      position: "{{position}}"

I hope it can be useful to someone.

Thank you for your code. It helped tremendously in building my own template cover.
I went ahead and modified it even further so that:

  1. It contains the correct state at all times
  2. It is marked as unavailable when the window is open
  3. It can be stopped at any time
  4. It can be modified in Dashboard (thanks to unique_id).
  5. No external scripts are needed (everything is inside the template)

Hopefully this is useful for someone:

- platform: template
  covers:
    original_cover_sensor_secured:
      device_class: shade
      unique_id: original_cover_sensor_secured
      position_template: "{{ state_attr('cover.original_cover_sensor', 'current_position') }}"
      open_cover:
        - condition: state
          entity_id: binary_sensor.your_window_contact_sensor_contact
          state: "off" #window closed
        - service: cover.open_cover
          data:
            entity_id: cover.original_cover_sensor
      close_cover:
        - condition: state
          entity_id: binary_sensor.your_window_contact_sensor_contact
          state: "off" #window closed
        - service: cover.close_cover
          data:
            entity_id: cover.original_cover_sensor
      set_cover_position:
        - condition: state
          entity_id: binary_sensor.your_window_contact_sensor_contact
          state: "off" #window closed
        - service: cover.set_cover_position
          data:
            entity_id: cover.original_cover_sensor
            position: "{{position}}"
      stop_cover:
        service: cover.stop_cover
        data:
          entity_id: cover.original_cover_sensor
      value_template: "{{states('cover.original_cover_sensor')}}"
      # Make cover unavailable if window is open
      availability_template: "{{ is_state('binary_sensor.your_window_contact_sensor_contact', 'off') }}"
5 Likes

Thanks for the code! It looks promising in the Template Editor, although I had to change "{{position}}" to "{{ state_attr('cover.original_cover_sensor', 'current_position')}}". Even though what I wrote is true to the extend that it gets rid of an error in the Template editor, it disables the function to set a target position of the blind. So @ntds code was perfectly fine, sorry!

But right now Iā€™m still stuck, because I cant find out where to implement this templateā€¦could anyone give a hint?
I looked at the Home-Assistant Documentation relating to States, Templates and so on, but nothing there worked. I added the code from @ntds to my configuration.yaml (with a cover: in the line above it), but nothing happens. No errors either but nothing us showing up anywhere and the coverā€™s behaviour doesnā€™t change whether the window is open or not.

If it matters: Iā€™m running Home-Assistant CORE on a Raspberry Pi.

EDIT:
Ok, I figured it out. My problem was the indentation I thinkā€¦

I did the following steps:

  1. copy the code below to your configuration.yaml
  2. replace <original_cover> with your blind cover ID and <window_sensor> with your blinds sensor ID (both can be found under Developer Tools > STATES and search for either cover or window sensor keywords within the first column)
  3. under Developer Tools > YAML do a reload of ā€œALL YAML CONFIGURATIONā€ and then use the red ā€œRESTARTā€ button in the ā€œCheck and Restartā€ section above.
  4. now you should be able to find the entity under Developer Tools > STATES by searching for ā€œsecuredā€ (while youā€™re at it copy the whole device ID, it should be ā€œoriginal_cover_sensor_securedā€)
  5. to make use of the entity create a new card in a dashboard using the new device ID
cover:
  - platform: template
    covers:
      original_cover_sensor_secured:
        device_class: shade
        unique_id: original_cover_sensor_secured
        position_template: "{{ state_attr('cover.<original_cover>', 'current_position') }}"
        open_cover:
          - condition: state
            entity_id: binary_sensor.<window_sensor>
            state: "off" #window closed
          - service: cover.open_cover
            data:
              entity_id: cover.<original_cover>
        close_cover:
          - condition: state
            entity_id: binary_sensor.<window_sensor>
            state: "off" #window closed
          - service: cover.close_cover
            data:
              entity_id: cover.<original_cover>
        set_cover_position:
          - condition: state
            entity_id: binary_sensor.<window_sensor>
            state: "off" #window closed
          - service: cover.set_cover_position
            data:
              entity_id: cover.<original_cover>
              position: "{{position}}"
        stop_cover:
          service: cover.stop_cover
          data:
            entity_id: cover.<original_cover>
        value_template: "{{states('cover.<original_cover>')}}"
        # Make cover unavailable if window is open
        availability_template: "{{ is_state('binary_sensor.<window_sensor>', 'off') }}"
2 Likes

I have my code in a separate file called covers.yaml in the folder ā€˜custom_entitiesā€™. In there, I have the exact code above.

To get the configuration file to be able to work with this covers file, I add this to configuration.yaml:
cover: !include custom_entities/covers.yaml

Hopefully this helps.

3 Likes

Thank you! You have helped me a lot. If you ever turn this into a bluprint, please let me know.