Weekday Morning/Evening Schedule

This is a daily schedule card that I’m using to turn my heating on and off, although it could be used to schedule anything. It isn’t a very elegant solution to a problem but it works and I’ve seen other community members wanting a weekday scheduler, so I thought I’d post this project and welcome any suggestions for improvement. I did have some great suggestions from @petro and @finity, from a different thread, but this is working so I decided to post. In fact @petro has made some new suggestions while I’m writing this, so an updated version could be on the cards (excuse the pun!). I’ll update any code once I’ve successfully implemented it. Hopefully this is of use to some members.
Here’s a screenshot of the lovelace card: -


This is a picture entity card and the background-picture is a table that I made in PowerPoint (10cm x 16cm) and then saved as a png. In order to customise the colour, you’d need to make your own, or I probably could have selected a transparent background but the headers and weekdays are part of the background image, so would need to be redone to change the colour. The coloured circles are, once again, just circles made in PowerPoint (0.5cm x 0.5cm). Those images are saved in the normal ‘www folder’ in config.
Here’s the lovelace code: -

elements:
  - entity: input_datetime.mon_on_morning
    style:
      color: white
      font-size: 10px
      left: 39.5%
      top: 16%
    type: state-label
  - entity: input_datetime.mon_off_morning
    style:
      color: white
      font-size: 10px
      left: 52.5%
      top: 16%
    type: state-label
  - entity: input_datetime.mon_on_evening
    style:
      color: white
      font-size: 10px
      left: 80%
      top: 16%
    type: state-label
  - entity: input_datetime.mon_off_evening
    style:
      color: white
      font-size: 10px
      left: 93%
      top: 16%
    type: state-label
  - entity: input_datetime.tue_on_morning
    style:
      color: white
      font-size: 10px
      left: 39.5%
      top: 29%
    type: state-label
  - entity: input_datetime.tue_off_morning
    style:
      color: white
      font-size: 10px
      left: 52.5%
      top: 29%
    type: state-label
  - entity: input_datetime.tue_on_evening
    style:
      color: white
      font-size: 10px
      left: 80%
      top: 29%
    type: state-label
  - entity: input_datetime.tue_off_evening
    style:
      color: white
      font-size: 10px
      left: 93%
      top: 29%
    type: state-label
  - entity: input_datetime.wed_on_morning
    style:
      color: white
      font-size: 10px
      left: 39.5%
      top: 42%
    type: state-label
  - entity: input_datetime.wed_off_morning
    style:
      color: white
      font-size: 10px
      left: 52.5%
      top: 42%
    type: state-label
  - entity: input_datetime.wed_on_evening
    style:
      color: white
      font-size: 10px
      left: 80%
      top: 42%
    type: state-label
  - entity: input_datetime.wed_off_evening
    style:
      color: white
      font-size: 10px
      left: 93%
      top: 42%
    type: state-label
  - entity: input_datetime.thur_on_morning
    style:
      color: white
      font-size: 10px
      left: 39.5%
      top: 55%
    type: state-label
  - entity: input_datetime.thur_off_morning
    style:
      color: white
      font-size: 10px
      left: 52.5%
      top: 55%
    type: state-label
  - entity: input_datetime.thur_on_evening
    style:
      color: white
      font-size: 10px
      left: 80%
      top: 55%
    type: state-label
  - entity: input_datetime.thur_off_evening
    style:
      color: white
      font-size: 10px
      left: 93%
      top: 55%
    type: state-label
  - entity: input_datetime.fri_on_morning
    style:
      color: white
      font-size: 10px
      left: 39.5%
      top: 68%
    type: state-label
  - entity: input_datetime.fri_off_morning
    style:
      color: white
      font-size: 10px
      left: 52.5%
      top: 68%
    type: state-label
  - entity: input_datetime.fri_on_evening
    style:
      color: white
      font-size: 10px
      left: 80%
      top: 68%
    type: state-label
  - entity: input_datetime.fri_off_evening
    style:
      color: white
      font-size: 10px
      left: 93%
      top: 68%
    type: state-label
  - entity: input_datetime.sat_on_morning
    style:
      color: white
      font-size: 10px
      left: 39.5%
      top: 81%
    type: state-label
  - entity: input_datetime.sat_off_morning
    style:
      color: white
      font-size: 10px
      left: 52.5%
      top: 81%
    type: state-label
  - entity: input_datetime.sat_on_evening
    style:
      color: white
      font-size: 10px
      left: 80%
      top: 81%
    type: state-label
  - entity: input_datetime.sat_off_evening
    style:
      color: white
      font-size: 10px
      left: 93%
      top: 81%
    type: state-label
  - entity: input_datetime.sun_on_morning
    style:
      color: white
      font-size: 10px
      left: 39.5%
      top: 94%
    type: state-label
  - entity: input_datetime.sun_off_morning
    style:
      color: white
      font-size: 10px
      left: 52.5%
      top: 94%
    type: state-label
  - entity: input_datetime.sun_on_evening
    style:
      color: white
      font-size: 10px
      left: 80%
      top: 94%
    type: state-label
  - entity: input_datetime.sun_off_evening
    style:
      color: white
      font-size: 10px
      left: 93%
      top: 94%
    type: state-label
  - entity: input_boolean.timer_mon_morning
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 22.7%
      top: 10%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_tue_morning
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 22.7%
      top: 23%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_wed_morning
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 22.7%
      top: 36%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_thur_morning
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 22.7%
      top: 49%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_fri_morning
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 22.7%
      top: 62%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_sat_morning
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 22.7%
      top: 75%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_sun_morning
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 22.7%
      top: 88%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_mon_evening
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 63.5%
      top: 10%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_tue_evening
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 63.5%
      top: 23%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_wed_evening
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 63.5%
      top: 36%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_thur_evening
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 63.5%
      top: 49%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_fri_evening
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 63.5%
      top: 62%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_sat_evening
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 63.5%
      top: 75%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
  - entity: input_boolean.timer_sun_evening
    state_image:
      'off': /local/TimerOff.png
      'on': /local/TimerOn.png
    style:
      left: 63.5%
      top: 88%
      transform: scale(0.6)
    tap_action:
      action: toggle
    type: image
image: /local/Schedule.png
type: picture-elements

Here’s the different input_datetime’s: -

mon_on_morning:
  name: Mon on morning
  has_time: true

mon_off_morning:
  name: Mon off morning
  has_time: true

mon_on_evening:
  name: Mon on evening
  has_time: true

mon_off_evening:
  name: Mon off evening
  has_time: true

tue_on_morning:
  name: Tue on morning
  has_time: true

tue_off_morning:
  name: Tue off morning
  has_time: true

tue_on_evening:
  name: Tue on evening
  has_time: true

tue_off_evening:
  name: Tue off evening
  has_time: true

wed_on_morning:
  name: Wed on morning
  has_time: true

wed_off_morning:
  name: Wed off morning
  has_time: true

wed_on_evening:
  name: Wed on evening
  has_time: true

wed_off_evening:
  name: Wed off evening
  has_time: true

thur_on_morning:
  name: Thur on morning
  has_time: true

thur_off_morning:
  name: Thur off morning
  has_time: true

thur_on_evening:
  name: Thur on evening
  has_time: true

thur_off_evening:
  name: Thur off evening
  has_time: true

fri_on_morning:
  name: Fri on morning
  has_time: true

fri_off_morning:
  name: Fri off morning
  has_time: true

fri_on_evening:
  name: Fri on evening
  has_time: true

fri_off_evening:
  name: Fri off evening
  has_time: true

sat_on_morning:
  name: Sat on morning
  has_time: true

sat_off_morning:
  name: Sat off morning
  has_time: true

sat_on_evening:
  name: Sat on evening
  has_time: true

sat_off_evening:
  name: Sat off evening
  has_time: true

sun_on_morning:
  name: Sun on morning
  has_time: true

sun_off_morning:
  name: Sun off morning
  has_time: true

sun_on_evening:
  name: Sun on evening
  has_time: true

sun_off_evening:
  name: Sun off evening
  has_time: true

These are the input_booleans for selecting if the timer comes on in the morning or evening: -

timer_mon_morning:

timer_mon_evening:

timer_tue_morning:

timer_tue_evening:

timer_wed_morning:

timer_wed_evening:

timer_thur_morning:

timer_thur_evening:

timer_fri_morning:

timer_fri_evening:

timer_sat_morning:

timer_sat_evening:

timer_sun_morning:

timer_sun_evening:

And here’s the automation: -

##########################
## Schedule Automations ##
##########################
## Monday ##
- id: mon_on_morning
  alias: Mon On Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.mon_on_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_mon_morning
    state: 'on'
  - condition: time
    weekday:
    - mon
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: mon_off_morning
  alias: Mon Off Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.mon_off_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_mon_morning
    state: 'on'
  - condition: time
    weekday:
    - mon
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
- id: mon_on_evening
  alias: Mon On Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.mon_on_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_mon_evening
    state: 'on'
  - condition: time
    weekday:
    - mon
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: mon_off_evening
  alias: Mon Off Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.mon_off_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: time
    weekday:
    - mon
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
## Tuesday ##
- id: tue_on_morning
  alias: Tue On Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.tue_on_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_tue_morning
    state: 'on'
  - condition: time
    weekday:
    - tue
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: tue_off_morning
  alias: Tue Off Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.tue_off_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_tue_morning
    state: 'on'
  - condition: time
    weekday:
    - tue
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
- id: tue_on_evening
  alias: Tue On Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.tue_on_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_tue_evening
    state: 'on'
  - condition: time
    weekday:
    - tue
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: tue_off_evening
  alias: Tue Off Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.tue_off_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: time
    weekday:
    - tue
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
## Wednesday ##
- id: wed_on_morning
  alias: Wed On Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.wed_on_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_wed_morning
    state: 'on'
  - condition: time
    weekday:
    - wed
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: wed_off_morning
  alias: Wed Off Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.wed_off_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_wed_morning
    state: 'on'
  - condition: time
    weekday:
    - wed
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
- id: wed_on_evening
  alias: Wed On Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.wed_on_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_wed_evening
    state: 'on'
  - condition: time
    weekday:
    - wed
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: wed_off_evening
  alias: Wed Off Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.wed_off_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: time
    weekday:
    - wed
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
## Thursday ##
- id: thur_on_morning
  alias: Thur On Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.thur_on_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_thur_morning
    state: 'on'
  - condition: time
    weekday:
    - thu
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: thur_off_morning
  alias: Thur Off Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.thur_off_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_thur_morning
    state: 'on'
  - condition: time
    weekday:
    - thu
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
- id: thur_on_evening
  alias: Thur On Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.thur_on_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_thur_evening
    state: 'on'
  - condition: time
    weekday:
    - thu
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: thur_off_evening
  alias: Thur Off Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.thur_off_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: time
    weekday:
    - thu
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
## Friday ##
- id: fri_on_morning
  alias: Fri On Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.fri_on_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_fri_morning
    state: 'on'
  - condition: time
    weekday:
    - fri
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: fri_off_morning
  alias: Fri Off Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.fri_off_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_fri_morning
    state: 'on'
  - condition: time
    weekday:
    - fri
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
- id: fri_on_evening
  alias: Fri On Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.fri_on_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_fri_evening
    state: 'on'
  - condition: time
    weekday:
    - fri
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: fri_off_evening
  alias: Fri Off Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.fri_off_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: time
    weekday:
    - fri
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
## Saturday ##
- id: sat_on_morning
  alias: Sat On Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.sat_on_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_sat_morning
    state: 'on'
  - condition: time
    weekday:
    - sat
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: sat_off_morning
  alias: Sat Off Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.sat_off_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_sat_morning
    state: 'on'
  - condition: time
    weekday:
    - sat
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
- id: sat_on_evening
  alias: Sat On Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.sat_on_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_sat_evening
    state: 'on'
  - condition: time
    weekday:
    - sat
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: sat_off_evening
  alias: Sat Off Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.sat_off_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: time
    weekday:
    - sat
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
## Sunday ##
- id: sun_on_morning
  alias: Sun On Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.sun_on_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_sun_morning
    state: 'on'
  - condition: time
    weekday:
    - sun
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: sun_off_morning
  alias: Sun Off Morning
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.sun_off_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_sun_morning
    state: 'on'
  - condition: time
    weekday:
    - sun
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch
- id: sun_on_evening
  alias: Sun On Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.sun_on_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: state
    entity_id: input_boolean.timer_sun_evening
    state: 'on'
  - condition: time
    weekday:
    - sun
  action:
  - service: input_boolean.turn_on
    entity_id: input_boolean.heating_switch
- id: sun_off_evening
  alias: Sun Off Evening
  initial_state: 'true'
  trigger:
  - platform: template
    value_template: "{{ states('sensor.time') == (state_attr('input_datetime.sun_off_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}"
  condition:
  - condition: time
    weekday:
    - sun
  action:
  - service: input_boolean.turn_off
    entity_id: input_boolean.heating_switch

Obviously you’d just change the action to suit your needs. It could be switching lights on/off

2 Likes

Did you take a look at this post? I simplified it for you…

Takes it from 28 automations down to 2 sensors and 1 automation.

4 Likes

This is fantastic!! Thank you for taking the time to make this MUCH more elegant and compact!!

2 Likes

Hi @petro, I implemented your code but the trigger didn’t happen when I changed the time. The logs showed that the binary_sensor part has missing/extra ‘)’ brackets, so I added some. It’s possible I’ve put them in the wrong place. Would you mind taking a look please? Here’s the code.

I’ve added ‘(’ after the ‘=’ for ‘start’, 'stop, and ‘on’. Does that seem correct?

- platform: template
  sensors:
    morning_heat:
      friendly_name: Morning Heat
      entity_id: sensor.time
      value_template: >
        {% set day = now().strftime('%a').lower() %}
        {% set time = states('sensor.time') %}
        {% set start = (state_attr('input_datetime.' ~ day ~ '_on_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set stop = (state_attr('input_datetime.' ~ day ~ '_off_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set on = (is_state('input_boolean.timer_' ~ day ~ 'morning', 'on')) %}
        {{ on and start <= time <= stop }}
    evening_heat:
      friendly_name: Evening Heat
      entity_id: sensor.time
      value_template: >
        {% set day = now().strftime('%a').lower() %}
        {% set time = states('sensor.time') %}
        {% set start = (state_attr('input_datetime.' ~ day ~ '_on_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set stop = (state_attr('input_datetime.' ~ day ~ '_off_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set on = is_state('input_boolean.timer_' ~ day ~ 'evening', 'on') %}
        {{ on and start <= time <= stop }}

Would a binary_sensor update its value as soon as a time is changed, or would you expect it to happen at midnight, when the day value changes?

the parenthesis you added aren’t doing anything. The method state_attr returns a result in which the int filter is applied. Then the timestamp is applied to the result of the state_attr w/ the int filter. All of this is normal order of operation. The only time parenthesis are needed is when you need to change the order of operation or when you want to return a tuple (which is almost never in jinja).

As it stands, the binary sensor will not update immediately when you change the datetimes. It will update on the minute because of sensor.time.

If you want the binary_sensors to change when you manipulate the datetimes and the input_booleans, you need to add them to the entity_id list. So instead of:

      entity_id: sensor.time

you’ll have

      entity_id:
        - sensor.time
        - input_datetime.mon_on_morning
        - input_datetime.mon_off_morning
        - input_boolean.timer_mon_morning
        - ETC...

It’s also possible that the template for start and end are wrong, but i doubt it. Either way, place it in the template editor and see if the result is correct.

The parenthesis I added was to close the equation, as there was an extra ‘)’ at the end of the line of code, so hass wouldn’t create the morning_heat or evening_heat binary sensors. I did wait for the time to change before checking if the automation had triggered but, thinking about it, maybe I didn’t wait more than 1 minute for the changed time to register. I like the idea of adding the individual entities, so that there’s an immediate response to the changed value. I’m out all day today, so I’ll have a check tomorrow. As always, thanks so much for looking through. This has been very educational.

great tool! Thanks

1 Like

so now it works with the reduced code?

Unfortunately, I haven’t had a chance to retry the code yet. I don’t think I’ll be able to until tomorrow. I’ll post an update as soon as I can. If you have success with it, it would be great if you let us know :+1:

I thought about it a bit, i also noticed that you’re turning on/off an input boolean. Why? Does that run automations? if so, this can be simplified even more by swapping out the input boolean in your other automationsfor the binary_sensor template. You could be suppressing triggers to those automations by using the input_boolean as the trigger in the automation. So that could also be the problem.

The input_boolean is a condition but that’s a very interesting suggestion. I could look at taking out a middle-man based on your automation. I’ll report back!

Here’s the modified code I’ve been using but it’s still not triggering: -
Binary Sensor

- platform: template
  sensors:
    morning_heat:
      friendly_name: Morning Heat
      entity_id:
        - sensor.time
        - input_datetime.mon_on_morning
        - input_datetime.mon_off_morning
        - input_datetime.mon_on_evening
        - input_datetime.mon_off_evening
        - input_datetime.tue_on_morning
        - input_datetime.tue_off_morning
        - input_datetime.tue_on_evening
        - input_datetime.tue_off_evening
        - input_datetime.wed_on_morning
        - input_datetime.wed_off_morning
        - input_datetime.wed_on_evening
        - input_datetime.wed_off_evening
        - input_datetime.thu_on_morning
        - input_datetime.thu_off_morning
        - input_datetime.thu_on_evening
        - input_datetime.thu_off_evening
        - input_datetime.fri_on_morning
        - input_datetime.fri_off_morning
        - input_datetime.fri_on_evening
        - input_datetime.fri_off_evening
        - input_datetime.sat_on_morning
        - input_datetime.sat_off_morning
        - input_datetime.sat_on_evening
        - input_datetime.sat_off_evening
        - input_datetime.sun_on_morning
        - input_datetime.sun_off_morning
        - input_datetime.sun_on_evening
        - input_datetime.sun_off_evening
        - input_boolean.timer_mon_morning
        - input_boolean.timer_mon_evening
        - input_boolean.timer_tue_morning
        - input_boolean.timer_tue_evening
        - input_boolean.timer_wed_morning
        - input_boolean.timer_wed_evening
        - input_boolean.timer_thu_morning
        - input_boolean.timer_thu_evening
        - input_boolean.timer_fri_morning
        - input_boolean.timer_fri_evening
        - input_boolean.timer_sat_morning
        - input_boolean.timer_sat_evening
        - input_boolean.timer_sun_morning
        - input_boolean.timer_sun_evening
      value_template: >
        {% set day = now().strftime('%a').lower() %}
        {% set time = states('sensor.time') %}
        {% set start = (state_attr('input_datetime.' ~ day ~ '_on_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set stop = (state_attr('input_datetime.' ~ day ~ '_off_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set on = (is_state('input_boolean.timer_' ~ day ~ 'morning', 'on')) %}
        {{ on and start <= time <= stop }}
    evening_heat:
      friendly_name: Evening Heat
      entity_id:
        - sensor.time
        - input_datetime.mon_on_morning
        - input_datetime.mon_off_morning
        - input_datetime.mon_on_evening
        - input_datetime.mon_off_evening
        - input_datetime.tue_on_morning
        - input_datetime.tue_off_morning
        - input_datetime.tue_on_evening
        - input_datetime.tue_off_evening
        - input_datetime.wed_on_morning
        - input_datetime.wed_off_morning
        - input_datetime.wed_on_evening
        - input_datetime.wed_off_evening
        - input_datetime.thu_on_morning
        - input_datetime.thu_off_morning
        - input_datetime.thu_on_evening
        - input_datetime.thu_off_evening
        - input_datetime.fri_on_morning
        - input_datetime.fri_off_morning
        - input_datetime.fri_on_evening
        - input_datetime.fri_off_evening
        - input_datetime.sat_on_morning
        - input_datetime.sat_off_morning
        - input_datetime.sat_on_evening
        - input_datetime.sat_off_evening
        - input_datetime.sun_on_morning
        - input_datetime.sun_off_morning
        - input_datetime.sun_on_evening
        - input_datetime.sun_off_evening
        - input_boolean.timer_mon_morning
        - input_boolean.timer_mon_evening
        - input_boolean.timer_tue_morning
        - input_boolean.timer_tue_evening
        - input_boolean.timer_wed_morning
        - input_boolean.timer_wed_evening
        - input_boolean.timer_thu_morning
        - input_boolean.timer_thu_evening
        - input_boolean.timer_fri_morning
        - input_boolean.timer_fri_evening
        - input_boolean.timer_sat_morning
        - input_boolean.timer_sat_evening
        - input_boolean.timer_sun_morning
        - input_boolean.timer_sun_evening
      value_template: >
        {% set day = now().strftime('%a').lower() %}
        {% set time = states('sensor.time') %}
        {% set start = (state_attr('input_datetime.' ~ day ~ '_on_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set stop = (state_attr('input_datetime.' ~ day ~ '_off_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set on = is_state('input_boolean.timer_' ~ day ~ 'evening', 'on') %}
        {{ on and start <= time <= stop }}

Here’s the automation code: -

###########################
## Scedule heating Petro ##
###########################
- id: schedule_heating
  alias: Schedule Heating
  initial_state: 'true'
  trigger:
    platform: state
    entity_id: 
      - binary_sensor.morning_heat
      - binary_sensor.evening_heat
  action:
    service_template: "input_boolean.turn_{{ trigger.to_state.state }}"
    entity_id: input_boolean.heating_switch

There must be something that’s not quite right, which is stopping it from triggering. For the time being I’m going to revert back to my original code and if I can work out how to get this refined code working I’ll update the original post.

Happy tinkering all!

Hi Klagio,
There’s WAY better scheduling tools out there now but I thought I’d post that I got Petro’s reduced code working! I like the look of this card and so I’ve stuck with it for my heating (although I use a scheduling addon for everything else) and just in case you still had it, I thought I’d post the fix (>= 0.115).

Now that the templating tools tells you what entities it’s listening to, I added the template for the binary_sensors and I could see there was an underscore missing from the input_boolean. I also happened upon a post where Petro realised that

{{ on and start <= time <= stop }}

should be

{{ on and start <= time < stop }}

Put it all together and this “Takes it from 28 automations down to 2 sensors and 1 automation.”

Binary Sensor code

- platform: template
  sensors:
    morning_heat:
      friendly_name: Morning Heat
      value_template: >
        {% set day = now().strftime('%a').lower() %}
        {% set time = states('sensor.time') %}
        {% set start = (state_attr('input_datetime.' ~ day ~ '_on_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set stop = (state_attr('input_datetime.' ~ day ~ '_off_morning', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set on = (is_state('input_boolean.timer_' ~ day ~ '_morning', 'on')) %}
        {{ on and start <= time < stop }}
    evening_heat:
      friendly_name: Evening Heat
      value_template: >
        {% set day = now().strftime('%a').lower() %}
        {% set time = states('sensor.time') %}
        {% set start = (state_attr('input_datetime.' ~ day ~ '_on_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set stop = (state_attr('input_datetime.' ~ day ~ '_off_evening', 'timestamp') | int | timestamp_custom('%H:%M', False)) %}
        {% set on = is_state('input_boolean.timer_' ~ day ~ '_evening', 'on') %}
        {{ on and start <= time < stop }}

Automation

- id: heating_schedule
  alias: Heating Scedule
  description: ''
  trigger:
  - platform: state
    entity_id: binary_sensor.morning_heat, binary_sensor.evening_heat
  condition: []
  action:
  - service: input_boolean.turn_{{ trigger.to_state.state }}
    data:
      entity_id: input_boolean.heating_switch
  mode: single

Petro, I didn’t tag you in this because it’s such an old post and you’re usually busy helping everyone but if you do get the notifications still, or stumble across this.

Thank you very much :+1: :beers: :grinning:

1 Like