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?
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]) }}"