How to limit cover position when door open?

Hi there,
I’m trying to create a cover template that makes sure my curtain can only be closed halfway (up to my balcony door), when my balcony door is opened.

I’ve got this to work for the close_cover, but can’t figure out what to code for set_cover_position. It needs to limit every given position below 50 to 50 and allow positions of 50 or above when the contact sensor is ‘on’. When the contact sensor is ‘off’ it needs to allow any position (as would be standard). I do not know how to code this though and anything I try to do with set_cover_position also makes the close_cover malfunction, since it uses that service.
In addition, the position and state of the curtain are not shown correctly.

This is what I have got so far:

cover:
- platform: template
  covers:
    zb_motor_woonkamer_vitrage_rechts_custom:
      device_class: curtain
      friendly_name: "Woonkamer Vitrage Rechts Custom"
      position_template: "{{ state_attr('cover.zb_motor_woonkamer_vitrage_rechts', 'current_position') }}"
      open_cover:
        service: cover.open_cover
        data:
          entity_id: cover.zb_motor_woonkamer_vitrage_rechts
      close_cover:
        service: cover.set_cover_position
        data:
          entity_id: cover.zb_motor_woonkamer_vitrage_rechts
          position: >
            {% if is_state('binary_sensor.zb_motion_no1_contact', 'on') %}
              50
            {% else %}
              0
            {% endif %}
      #set_cover_position:
      #  service: cover.set_cover_position
      #  data:
      #    entity_id: cover.zb_motor_woonkamer_vitrage_rechts
      #    position: {{position}}
      stop_cover:
        service: cover.stop_cover
        data:
          entity_id: cover.zb_motor_woonkamer_vitrage_rechts

set_cover_position is in comments on purpose for now.

Any help would be much appreciated.

Anyone any ideas?

{{ position if 50 <= position else 50 }}

or

{{ position if position >= 50 else 50 }}

same thing, just preference on what makes sense to you

Thank you very much!

Last thing I’m trying to fix is to make the curtain show as ‘closed’ at 50% when the door is open, but show the curtain as ‘closed’ at 0% when the door is closed.

I have got this to work (see code below following ‘value_template’), but it only works if I disable position_template, which of course disables the shown position of the curtain, which I do want to see…
How can I these work together?

    zb_motor_woonkamer_gordijn_rechts_custom:
      device_class: curtain
      friendly_name: "Woonkamer Gordijn Rechts Custom"
      #position_template: "{{ state_attr('cover.zb_motor_woonkamer_gordijn_rechts', 'current_position') }}"
      open_cover:
        service: cover.open_cover
        data:
          entity_id: cover.zb_motor_woonkamer_gordijn_rechts
      close_cover:
        service: cover.set_cover_position
        data:
          entity_id: cover.zb_motor_woonkamer_gordijn_rechts
          position: >
            {% if is_state('binary_sensor.zb_motion_no1_contact', 'on') %}
              50
            {% else %}
              0
            {% endif %}
      set_cover_position:
        service: cover.set_cover_position
        data:
          entity_id: cover.zb_motor_woonkamer_gordijn_rechts
          position: >
            {% if is_state('binary_sensor.zb_motion_no1_contact', 'on') %}
              {{ position if position >= 50 else 50 }}
            {% else %}
              {{position}}
            {% endif %}
      stop_cover:
        service: cover.stop_cover
        data:
          entity_id: cover.zb_motor_woonkamer_gordijn_rechts
      value_template: >
        {% if is_state('binary_sensor.zb_motion_no1_contact', 'on') %}
          {% if is_state_attr('cover.zb_motor_woonkamer_gordijn_rechts', 'current_position', 50) %}
            closed
          {% else %}
            open
          {% endif %}
        {% else %}
          {{states('cover.zb_motor_woonkamer_gordijn_rechts')}}
        {% endif %}

I think value_template cannot actually be used in combination with position_template in this way if I read the docs correct, but unsure how to achieve what I want any other way…

position_template: >
  {% set pos = state_attr('cover.zb_motor_woonkamer_gordijn_rechts', 'current_position') %}
  {{ 0 if pos <= 50 else (pos - 50) * 2 }}

Thank you for the reply Petro.

Unfortunately this crashes my entire setup and it gives the following error:

Logger: homeassistant.helpers.event
Source: helpers/template.py:546 
First occurred: 22:33:33 (1 occurrences) 
Last logged: 22:33:33

Error while processing template: Template<template=({% set pos = state_attr('cover.zb_motor_woonkamer_gordijn_rechts', 'current_position') %} {{ 0 if pos <= 50 else (pos - 50) * 2 }}) renders=2>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 544, in async_render
    render_result = _render_with_context(self.template, compiled, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 2164, in _render_with_context
    return template.render(**kwargs)
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 1301, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.10/site-packages/jinja2/environment.py", line 936, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "<template>", line 1, in top-level template code
TypeError: '<=' not supported between instances of 'NoneType' and 'int'

Here’s the code in its entirety:

    zb_motor_woonkamer_gordijn_rechts_custom:
      device_class: curtain
      friendly_name: "Woonkamer Gordijn Rechts Custom"
      position_template: >
        {% set pos = state_attr('cover.zb_motor_woonkamer_gordijn_rechts', 'current_position') %}
        {{ 0 if pos <= 50 else (pos - 50) * 2 }}
      open_cover:
        service: cover.open_cover
        data:
          entity_id: cover.zb_motor_woonkamer_gordijn_rechts
      close_cover:
        service: cover.set_cover_position
        data:
          entity_id: cover.zb_motor_woonkamer_gordijn_rechts
          position: >
            {% if is_state('binary_sensor.zb_motion_no1_contact', 'on') %}
              50
            {% else %}
              0
            {% endif %}
      set_cover_position:
        service: cover.set_cover_position
        data:
          entity_id: cover.zb_motor_woonkamer_gordijn_rechts
          position: >
            {% if is_state('binary_sensor.zb_motion_no1_contact', 'on') %}
              {{ position if position >= 50 else 50 }}
            {% else %}
              {{position}}
            {% endif %}
      stop_cover:
        service: cover.stop_cover
        data:
          entity_id: cover.zb_motor_woonkamer_gordijn_rechts

I placed it alternatively at the beginning or end of the code, but same result.

Also, wouldn’t the code you provided need to be inserted into an if else statement based on whether the door is open? Otherwise it would show the curtain as ‘closed’ at 50% when the door is closed right?

Does that enttiy actually have a current position attribute?

Yes.

try

    {% set pos = state_attr('cover.zb_motor_woonkamer_gordijn_rechts', 'current_position') %}
    {{ 0 if pos is none or pos <= 50 else (pos - 50) * 2 }}

That works!! Thanks a lot man