Weekly programming for opening shutters

Hi, I need to set up an automation that manages the opening and closing of two shutters, with a weekly programming considering the working days from Monday to Saturday with a specific opening and closing time different from public holidays, I’m going to list the days and times:
from Monday to Saturday opening at 7.30am 40%; 7:45 60%; 8:00 90%; 10:00 100%; Closing with the possibility of choosing sunset or at 8.00pm every day even on holidays;
on Sundays and all public holidays of the calendar opening at 9:00 60%; 10:00 am 90%; 11:00 am 100%.
I had created an automation that worked but only on weekdays, I subsequently modified it, creating problems and I was no longer able to go back, this is the code I have, I thank in advance anyone who wants to give me a hand.

- id: '2'
  alias: Programma Tapparelle
  trigger:
  - platform: time
    at: 07:30:00
    variables:
      level: 40
      day: '{{ now().isoweekday() == 7 or now().is_holiday() }}'
  - platform: time
    at: 07:45:00
    variables:
      level: 60
      day: '{{ now().isoweekday() == 7 or now().is_holiday() }}'
  - platform: time
    at: '10:00:00'
    variables:
      level: 90
      day: '{{ now().isoweekday() == 7 or now().is_holiday() }}'
  - platform: time
    at: '20:00:00'
    variables:
      level: '{{ 20 if now().isoweekday() == 7 else 20 }}'
      day: '{{ now().isoweekday() == 7 or now().is_holiday() }}'
  - platform: time
    at: '10:00:00'
    variables:
      level: 60
      day: '{{ now().isoweekday() == 7 or now().is_holiday() }}'
  - platform: time
    at: '11:00:00'
    variables:
      level: 90
      day: '{{ now().isoweekday() == 7 or now().is_holiday() }}'
  condition:
  - condition: template
    value_template: '{{ now().isoweekday() == 7 or now().is_holiday() }}'
  - condition: state
    entity_id: input_boolean.programma_tapparelle
    state: 'on'
  action:
  - service: cover.set_cover_position
    target:
      entity_id:
      - cover.sonoff_cam_lett
      - cover.sonoff_cam_giu
    data:
      position: '{{ level }}'

In the automation I had inserted a boolean input to create a switch that allowed me to quickly deactivate the programming on holidays.

I don’t think now().is_holiday() is a valid method in HA’s Jinja implementation. You can access the python holiday module by setting up an instance of either the Holiday calendar or the Workday sensor integration.

My suggestion would be to use the Workday sensor.

You did not describe how you plan to do the “choosing sunset or at 8.00pm every day”… so I added both as triggers and left it at that.

trigger:
  - id: open
    platform: time
    at:
      - '07:30:00'
      - '07:45:00'
      - '08:00:00'
      - '09:00:00'
      - '10:00:00'
      - '11:00:00'
  - id: close
    platform: time
    at:
      - '20:00:00'
    variables:
      closing_choice: "{{ DETERMINE WHEN TO CLOSE AT 8PM }}"
  - id: close
    platform: sun
    event: sunset
    variables:
      closing_choice: "{{ DETERMINE WHEN TO CLOSE AT SUNSET }}"
condition:
  - condition: state
    entity_id: input_boolean.programma_tapparelle
    state: 'on'
  - alias: Test if is opening OR correct closing choice
    condition: template
    value_template: "{{ trigger.id == 'open' or closing_choice }}"
  - condition: template
    value_template: "{{ time in type.keys() }}"
action:
  - service: cover.set_cover_position
    target:
      entity_id:
        - cover.sonoff_cam_lett
        - cover.sonoff_cam_giu
    data:
      position: "{{ type.get(time) }}"
variables:
  time: "{{ '20:00' if trigger.id == 'close' else (trigger.now).strftime('%H:%M') }}"
  weekday:
    "07:30": 40
    "07:45": 60
    "08:00": 90
    "10:00": 100
    "20:00": 20
  holiday:
    "09:00": 60
    "10:00": 90
    "11:00": 100
    "20:00": 20
  type: "{{ weekday if is_state('binary_sensor.workday', 'on') else holiday }}"

Didgeridrew thank you for answering me, but for closing the shutters I forgot to indicate 8:00 pm instead of sunset

I tried the automation today but, unfortunately, I found that it didn’t close at 8pm, let’s see how it behaves tomorrow morning

- id: '2'
  alias: Programma Tapparelle
  trigger:
    - id: open
      platform: time
      at:
        - '07:30:00'
        - '07:45:00'
        - '08:00:00'
        - '09:00:00'
        - '10:00:00'
        - '11:00:00'
    - id: close
      platform: time
      at:
        - '20:00:00'
  condition:
    - condition: state
      entity_id: input_boolean.programma_tapparelle
      state: 'on'
    - alias: Test if is opening OR correct closing choice
      condition: template
      value_template: "{{ trigger.id == 'open' or closing_choice }}"
    - condition: template
      value_template: "{{ time in type.keys() }}"
  action:
    - service: cover.set_cover_position
      target:
        entity_id:
          - cover.sonoff_cam_lett
          - cover.sonoff_cam_giu
      data:
        position: "{{ type.get(time) }}"
  variables:
    time: "{{ '20:00' if trigger.id == 'close' else (trigger.now).strftime('%H:%M') }}"
    weekday:
      "07:30": 40
      "07:45": 60
      "08:00": 90
      "10:00": 100
      "20:00": 20
    holiday:
      "09:00": 60
      "10:00": 90
      "11:00": 100
      "20:00": 20
    type: "{{ weekday if is_state('binary_sensor.workday', 'on') else holiday }}"

There are fancy schedule integrations, but you can do it with the built in ones. I would create two schedule helpers, one for normal days and one for holidays. You can set them in yaml, but I would go for the helper section in the GUI. Those allow you to visually set open/close times. Then, when either schedule helper changes state, check if it is a holiday or not to see if you actually react on that respective helper.

I got this error in the log:

2024-01-22 20:00:00.257 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: ‘closing_choice’ is undefined when rendering ‘{{ trigger.id == ‘open’ or closing_choice }}’

That’s because you deleted/never defined the variable… If you have decided you don’t need to be able to choose between two closing options, you can completely remove the condition:

    - alias: Test if is opening OR correct closing choice
      condition: template
      value_template: "{{ trigger.id == 'open' or closing_choice }}"

I eliminated the condition completely, but it seems to only work for some times, for example this morning 7:30, 7:45, 8:00 didn’t work, but at 9:00, 10:00, and 11:00 it did

Let’s see tonight at 8pm if they close

That points to an issue with the logic for the type variable. Did you set up a Workday sensor? Does its entity ID match what is in the variable definition, i.e. binary_sensor.workday?

yes I had configured a workday, the default one for home assistant, now I have deleted it, so it should work?

If I also want to consider vacation days as holidays, what should I do?

Not unless you changed the automation to compensate. If you made changes, you need to share the automation configuration as it currently is… otherwise any answer anyone gives you is based off incorrect data. What method are you now using to distinguish between workdays and holidays?

Same question as above… If you aren’t going to use a Workday sensor, how are you planning on distinguishing between workdays and holidays? You can’t add dates to something that doesn’t exist.

automation is always this, I haven’t changed anything

- id: '2'
  alias: Programma Tapparelle
  trigger:
    - id: open
      platform: time
      at:
        - '07:30:00'
        - '07:45:00'
        - '08:00:00'
        - '09:00:00'
        - '10:00:00'
        - '11:00:00'
    - id: close
      platform: time
      at:
        - '20:00:00'
  condition:
    - condition: state
      entity_id: input_boolean.programma_tapparelle
      state: 'on'
    - condition: template
      value_template: "{{ time in type.keys() }}"
  action:
    - service: cover.set_cover_position
      target:
        entity_id:
          - cover.sonoff_cam_lett
          - cover.sonoff_cam_giu
      data:
        position: "{{ type.get(time) }}"
  variables:
    time: "{{ '20:00' if trigger.id == 'close' else (trigger.now).strftime('%H:%M') }}"
    weekday:
      "07:30": 40
      "07:45": 60
      "08:00": 90
      "10:00": 100
      "20:00": 20
    holiday:
      "09:00": 60
      "10:00": 90
      "11:00": 100
      "20:00": 20
    type: "{{ weekday if is_state('binary_sensor.workday', 'on') else holiday }}"

I just deleted “workday” from Settings/Devices and Services

ok I reset binary_sensor.workday_sensor

Make sure to update the automation to match that entity ID.

This looks a lot like my hot water manager with times and targets. Mine is all adjustable via the front end:

then the automation:

- alias: Hot water - tank target manager

  description: >-
    This automation updates the value of the tank target based on the values in the
    schedule. The action sets the target to that slot's target value.
    Slots at midnight are considered unset and are ignored.

    Needs input_datetime.wxhwy_time and input_number.wxhwy_tgt where x is d for
    week and e for weekend; y is the slot number.

  id: 0ac52ecb-3e29-4474-b64b-9261ee9dce4e

  trigger:
    - platform: time
      at: 
        - input_datetime.wdhw1_time
        - input_datetime.wdhw2_time
        - input_datetime.wdhw3_time
        - input_datetime.wdhw4_time
        - input_datetime.wdhw5_time
        - input_datetime.wehw1_time
        - input_datetime.wehw2_time
        - input_datetime.wehw3_time
        - input_datetime.wehw4_time
        - input_datetime.wehw5_time
      variables:
        ed: "{{ ('e','d')[bool(states('binary_sensor.workday_sensor'))] }}"
  
  condition: 
    - "{{ states('sensor.time') != '00:00' }}"
    - "{{ trigger.entity_id[16] == ed }}"
  
  action:
    - service: input_number.set_value
      data:
        entity_id: input_number.tank_target
        value: "{{ states('input_number' ~ trigger.entity_id[14:21] ~ 'tgt') }}"

ok yes the automation works, but if I want to enter vacation days what should I do?

There are multiple options:

  1. Add custom holiday dates or date ranges in the Workday sensor integration. This option requires no modification of the automation, but dates/ranges have to be entered manually and there is no built-in way to automate adding annual or recurring events.
  2. Use a Calendar. This will require modifying the automation to query the calendar. You could also query the calendar with a template binary sensor and use that in a state condition in the automation.
  3. Add the dates to the automation manually. There are multiple ways to do this via templates shown in this thread.