Learning yaml: multi-level conditions logic question

Hey! Trying to go back from Node Red and learn some automation yaml. The automation below works and triggers a morning routine script based on motion, time of day, workday (yes/no) and if the room is already in use.

There are two paths, one for workday (turns on if time is after 05:00:00) and weekend (turns on if time is after 07:00:00).

How can I optimize this logic and reduce the line of code using more advanced conditions (AND/OR)? The output sequence is the same for both paths. So I’m guessing some form of first level condition checking for the time and workday logic, and then another lower level condition check for the rest? I’m pretty stuck here how this should be spliced in yaml.

Any help on this is most welcome!

- alias: 'Trigger morning light in kitchen'
  trigger:
    platform: state
    entity_id: binary_sensor.kok_rorelse
  action:
    - choose:
      # Normal working day
      - conditions:
        - condition: state
          entity_id: binary_sensor.kok_rorelse
          state: 'on'
        - condition: time
          after: '05:00:00'
          before: '09:00:00'
        - condition: state
          entity_id: 'binary_sensor.workday_sensor'
          state: 'on'
        - condition: state
          entity_id: light.room_kok
          state: 'off'
        sequence:
          - service: script.turn_on
            entity_id: script.turn_on_morning_kitchen_mode
      # Weekend/Holiday
      - conditions:
        - condition: state
          entity_id: binary_sensor.kok_rorelse
          state: 'on'
        - condition: time
          after: '07:00:00'
          before: '09:00:00'
        - condition: state
          entity_id: 'binary_sensor.workday_sensor'
          state: 'off'
        - condition: state
          entity_id: light.room_kok
          state: 'off'
        sequence:
          - service: script.turn_on
            entity_id: script.turn_on_morning_kitchen_mode

Unless I’m missing something, the only difference is that the time range is different for weekdays, so duplicating the other conditions seems unnecessary.

Also, both require the sensor to be on, so why not use that as the trigger instead of triggering on all state changes?

So just at first glance you could reduce it to this…

- alias: 'Trigger morning light in kitchen'
  trigger:
    platform: state
    entity_id: binary_sensor.kok_rorelse
    to: 'on' 
  condition:
    condition: state
    entity_id: light.room_kok
    state: 'off' 
  action:
    - choose:
      # Normal working day
      - conditions:
        - condition: time
          after: '05:00:00'
          before: '09:00:00'
        - condition: state
          entity_id: 'binary_sensor.workday_sensor'
          state: 'on'
        sequence:
          service: script.turn_on_morning_kitchen_mode
      # Weekend/Holiday
      - conditions:
        - condition: time
          after: '07:00:00'
          before: '09:00:00'
        - condition: state
          entity_id: 'binary_sensor.workday_sensor'
          state: 'off'
        sequence:
          service: script.turn_on_morning_kitchen_mode

Although if it was me I would combine the weekday/timespan thing into a template especially as you’re firing the exact same result in the action which kinda makes the whole chooser redundant, thus reducing it to this…

- alias: 'Trigger morning light in kitchen'
  trigger:
    platform: state
    entity_id: binary_sensor.kok_rorelse
    to: 'on' 
  condition:
    - condition: state
      entity_id: light.room_kok
      state: 'off'
    - "{{ (states('binary_sensor.workday_sensor', 'on') and now().hour in [5, 6, 7, 8]) or (states('binary_sensor.workday_sensor', 'off') and now().hour in [7, 8]) }}" 
  action:
    service: script.turn_on_morning_kitchen_mode

Thanks @anon43302295 for the excellent input and your time writing it. Seems the next step for me is to learn templating!

Something is wrong with the template tho cause its firing “TypeError: call() takes 2 positional arguments but 3 were given” errors in the log. Commenting out that line runs the automation but without the workday/time logic. Any idea on what could be wrong?

1 Like

Are you on version 115?

yes 115.0.

Sorry, spotted my error, replace the template with this…

"{{ (is_state('binary_sensor.workday_sensor', 'on') and now().hour in [5, 6, 7, 8]) or (is_state('binary_sensor.workday_sensor', 'off') and now().hour in [7, 8]) }}"
1 Like

Perfect, works as intended.

1 Like