Open/close direction for projector screens

I have developed my first integration, for my projector screen produced by XY Screens using the RS485 interface. I used the Cover Entity and all working fine. However there is one thing that’s counter intuitive to me.

The Cover Entity assumes the retracted screen to be the open state and the rolled down screen to be the closed state. This is how you expect it to be for rolling blinds, garage doors et such.

However for a projector screen this works in the opposite way, the screen is open when it’s rolled out and closed when retracted.

I think it would be great when an extra Device Class for the Cover Entity could be created named DEVICE_CLASS_SCREEN where the logic is opposite of the logic of the DEVICE_CLASS_SHADE Device Class.

What are your thought on this?

My thoughts: Custom device classes

You could override the state property in your integration to correct this logic. See below code from the cover entity class. Just add thisntomyour integration and amend the logic.

    @property
    @final
    def state(self) -> str | None:
        """Return the state of the cover."""
        if self.is_opening:
            self._cover_is_last_toggle_direction_open = True
            return STATE_OPENING
        if self.is_closing:
            self._cover_is_last_toggle_direction_open = False
            return STATE_CLOSING

        if (closed := self.is_closed) is None:
            return None

        return STATE_CLOSED if closed else STATE_OPEN

I understand I can have my integration return whatever state I want, however this does not solve everything. First of all the interface in HA will show you the up and down arrows in the wrong directions, second there is the open and close percentage which should also be reversed. This is quite easy to fix but still.

I think it should be good if a DEVICE_CLASS_SCREEN should be added to the Cover Entity with the described behaviour so also configurations could benefit from this, like when someone uses a shelly or other device to control a projector screen

Hi,

I have the same issue. The screen is “open” when it’s down, and “closed” when up. Opposite to standard blind covers.

I’m fine with a workaround that the Lovelace detail card is reversed (I move it up in Lovelace to move it down really), but I’m wondering if there are any plans to have a separate entity type for automated projector screens (like for covers, fans, etc.), or maybe simpler - to allow users to define if a cover is “open” when it’s up or down…

Thanks!

While you wait for such a function, you know you could always make a template cover to reverse the logic. Something like:

cover:
  - platform: template
    covers:
      my_projector_screen:
        device_class: blind
        friendly_name: "My Projector Screen"
        value_template: >
            {% set orig_state = ['open','opening','closed','closing'] %}
            {% set new_state = ['closed','closing','open','opening'] %}
            {{ new_state[orig_state.index(states('sensor.projector'))] }}
        open_cover:
          - service: cover.close_cover
            target:
              entity_id: cover.projector_screen
        close_cover:
          - service: cover.open_cover
            target:
              entity_id: cover.projector_screen
        stop_cover:
          service: cover.stop_cover
          target:
            entity_id: cover.projector_screen
1 Like

I have the same problem as @rrooggiieerr or at least a similar. So I tried your code (thank you) but as soon as I paste the value_template and reload the whole cover entity stops working…

Is it maybe because my cover doesn’t have states like opening and closing? I tried removing them from the template but got the same result.

cover:
  - platform: template
    covers:
      projector_screen:
        device_class: shutter
        friendly_name: "Projector Screen"
        value_template: >
          {% set orig_state = ['open','opening','closed','closing'] %}
          {% set new_state = ['closed','closing','open','opening'] %}
          {{ new_state[orig_state.index(states('cover.projector_screen'))] }}
        open_cover:
          - service: script.projector_screen_up
            target:
              entity_id: cover.projector_screen
        close_cover:
          - service: script.projector_screen_down
            target:
              entity_id: cover.projector_screen
        stop_cover:
          - service: script.projector_screen_stop
            target:
              entity_id: cover.projector_screen

Can you point me to whats wrong with me? :slight_smile: