Opening shades with different position depending on given data and winter/summer

Hi,

I have 8 Shades, which I want to open in the morning. Depending if we have “winter” or Summer, they have different opening values. I have two scripts, that “do their job”; but IMHO look “clumsy”. So I try to change it, but with not luck.

So here is how the scripts look like: (I only show 4 shades as an example). They are named ‘cover.l1, cover.l2’ … ‘cover.l4’, ‘cover.r1’ … ‘cover.r4’

alias: WZ Rolläden 100% auf
sequence:
  - target:
      entity_id: cover.l1
    data:
      position: 100
    action: espsomfy_rts.set_shade_position
    alias: L1 100%
  - delay:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 0
## 6 deleted
  - target:
      entity_id: cover.r4
    data:
      position: 100
    action: espsomfy_rts.set_shade_position
    enabled: true
    alias: R4 100%
  - delay:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 0
icon: mdi:roller-shade
mode: single
description: ""

The other script is basically the same, but with individual cover positions for each cover (33, 35, 47, … depending on where they are located.)
Between each cover call, there is a delay, which is needed in my environment.

I am really old, and know languages like C, perl, paascal :slight_smile: (assembler on the C64, …), … In those languages I would have used a three dimensional array like

covers[winter][l1][100]
covers[winter][l2][100]
covers[winter][l3][100]
covers[winter][l4][100]
covers[winter][r1][100]
covers[winter][r2][100]
covers[winter][r3][100]
covers[winter][r4][100]
covers[summer][l1][0]
covers[summer][l2][0]
covers[summer][l3][34]
covers[summer][l4][35]
covers[summer][r1][38]
covers[summer][r2][37]
covers[summer][r3][38]
covers[summer][r4][38]

Than “program” something like

if $summertime than
  $coveropening="summer"
else
  $coveropening="winter"
fi

foreach $cover in $covers[$coveropening] do
  - target:
      entity_id: cover.$cover
    data:
      position: $covers[$coveropening][$cover]
    action: espsomfy_rts.set_shade_position
  - delay:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 0

Is there something similar, or is there a better way to do it? Reason: In the long run, I want to compute the openiung position depending on the solar azimut, but before I want to understand to handle such structured data in something like “foreach, while_do, …”. I learn best by exampley, so if yomeone has a script and would like to share it, I really would appreciate it.

thank you all for reading
Juergen

There are several ways to do it. Here’s one way:

alias: WZ Rolläden 
sequence:
  - variables:
      is_summer: "{{ now().month in [6, 7, 8, 9] }}"
  - target:
      entity_id: cover.l1
    data:
      position: "{{ iif(is_summer, 100, 0 }}"
    action: espsomfy_rts.set_shade_position
    alias: L1
  - delay: 1
## 6 deleted
  - target:
      entity_id: cover.r4
    data:
      position: "{{ iif(is_summer, 100, 35 }}"
    action: espsomfy_rts.set_shade_position
    enabled: true
    alias: R4
  - delay: 1
icon: mdi:roller-shade
mode: single

The variable is_summer uses a template to produce a boolean value. It’s true if the current month is June, July, August or September. Otherwise, it’s false. The template’s logic can be enhanced to support your exact requirements

The position option uses a template to determine which value to report. An Inline If (iif) is used to report the summer position if is_summer is true. Otherwise it reports the winter position. Once again, the template can be enhanced to support your requirements.

Reference


EDIT

Here’s another way to do it. It’s more concise because it uses a “repeat for-each” to iterate through a dictionary containing the cover entities and their respective position.

alias: WZ Rolläden 
sequence:
  - variables:
      is_summer: "{{ now().month in [6, 7, 8, 9] }}"
  - repeat:
      for_each:
        - shade: cover.l1
          posn: "{{ iif(is_summer, 100, 0 }}"
        - shade: cover.r4
          posn: "{{ iif(is_summer, 100, 35 }}"
      sequence:
        - target:
            entity_id: "{{ repeat.item.shade }}"
          data:
            position: "{{ repeat.item.posn }}"
          action: espsomfy_rts.set_shade_position
        - delay: 1

I may be older than you :smile:

I understand where you are coming from. I suggest to tackle your problem a little bit differently. Rather than thinking in terms of programming languages and code, take a look at automations.

Home Assistant gives you the possibility to use a very comprehensive UI. Start your journey by defining the triggers that you want to use to initiate the cover actions. From a programming perspective it is close to a If/Then construction, but you will quickly realize that the UI is extremely powerful in allowing you to set up very complex scenarios with a few clicks.

Triggers could be time, sunset (with offsets), external temperature - whatever you want. You can then link the trigger to conditions. Here too, the sky is the limit. If you happen to have PV panels, you could for example use the solar production as an indicator of sunlight. Combine this with date and temperature to either open the cover in winter times to take advantage of the sun, or close it in summer to keep the heat out.

I started with HA not too long ago, and have similar plans to control the individual covers based on temperature, date, azimuth and elevation.

Leave the YAML to itself and play a little bit with the UI. In the action section, aside of addressing individual entities, you can also control groups, areas, etc within one action definition without having to bother about YAML code

Enjoy!