Wake-up time at a different time each day

Hello,
I’m a beginner with HA.
This topic interests me How to create the alarm clock in HASS? - #68 by jimmyeao.
I’m trying to recreate the alarm clock I had on Jeedom.
So I did this:

square: false
type: grid
columns: 2
cards:
  - type: entities
    entities:
      - entity: input_boolean.reveil_mode
      - entity: input_boolean.reveil_lundi
        name: Lundi
      - entity: input_boolean.reveil_mardi
        name: Mardi
      - entity: input_boolean.reveil_mercredi
        name: Mercredi
      - entity: input_boolean.reveil_jeudi
        name: Jeudi
      - entity: input_boolean.reveil_vendredi
        name: Vendredi
      - entity: input_boolean.reveil_samedi
        name: Samedi
      - entity: input_boolean.reveil_dimanche
        name: Dimanche
    show_header_toggle: false
  - type: vertical-stack
    cards:
      - type: entities
        entities:
          - entity: sensor.reveil_prochain_reveil
          - entity: input_datetime.reveil_heure_lundi
          - entity: input_datetime.reveil_heure_mardi
          - entity: input_datetime.reveil_heure_mercredi
          - entity: input_datetime.reveil_heure_jeudi
          - entity: input_datetime.reveil_heure_vendredi
          - entity: input_datetime.reveil_heure_samedi
          - entity: input_datetime.reveil_heure_dimanche
        show_header_toggle: false
        state_color: false
title: Réveil

I find the “hours” section ugly, especially since, contrary to what I’ve seen, I need a different schedule. per day.

Could you help me make something a bit nicer for selecting schedules?

I thought about doing something like this [07 ↑↓] [30 ↑↓] but I can’t get it to work.

Thank you for your valuable help.

Since I could only post one image per message, here’s what I did on the Jeedom side:

Okay. This sounded like fun. So, I took a stab at it.

Back-end processing still needs built to set the next alarm helper and handle the alarm going off.

But, here is the front-end I came up with.

Tapping the Alarm button toggles the whole thing off and on. Tapping each day button toggles that day off an on. Up and down arrows for each day’s hour and minute. The minute goes in 15 minute increments. But, that could easily be changed.

1 Like

Perfect, I’d like the YAML code.

So, this uses:
custom:button-card link
custom:decluttering-card link

Setup eight input_boolean helpers:
input_boolean.alarm_clock
input_boolean.alarm_clock_monday
input_boolean.alarm_clock_tuesday
input_boolean.alarm_clock_wednesday
input_boolean.alarm_clock_thursday
input_boolean.alarm_clock_friday
input_boolean.alarm_clock_saturday
input_boolean.alarm_clock_sunday

And, eight input_datetime helpers:
input_datetime.alarm_clock - this one is Date and Time
input_datetime.alarm_clock_monday - time only
input_datetime.alarm_clock_tuesday - time only
input_datetime.alarm_clock_wednesday - time only
input_datetime.alarm_clock_thursday - time only
input_datetime.alarm_clock_friday - time only
input_datetime.alarm_clock_saturday - time only
input_datetime.alarm_clock_sunday - time only

Of course, you can name these how you want. If you only change the name of the day to match your language, the only change in the card will be the variable when calling the decluttering template. Once you have your days in there, you can resize the button with the day in it as needed.

The raw card yaml is

Summary
decluttering_templates:
  alarm_clock_day:
    card:
      type: vertical-stack
      cards:
        - type: horizontal-stack
          cards:
            - type: custom:button-card
              entity: input_boolean.alarm_clock_[[day_of_week]]
              tap_action:
                action: toggle
              state:
                - value: 'off'
                  styles:
                    name:
                      - color: red
                - value: 'on'
                  styles:
                    name:
                      - color: lime
              name: '[[day_of_week]]'
              show_state: false
              show_icon: false
              styles:
                card:
                  - width: 130px
                  - height: 50px
                  - padding: 0
                name:
                  - transform: scale(1.5)
            - type: vertical-stack
              cards:
                - type: custom:button-card
                  entity: input_datetime.alarm_clock_[[day_of_week]]
                  icon: mdi:menu-up
                  show_name: false
                  variables:
                    newhour: |
                      [[[
                        if (states[entity.entity_id].attributes.hour == 23) {
                          return 0;
                        } else {
                          return states[entity.entity_id].attributes.hour + 1;
                        }
                      ]]]
                    hour: |
                      [[[
                        if (variables.newhour < 10) {
                          return `0${variables.newhour}`;
                        } else {
                          return `${variables.newhour}`;
                        }
                      ]]]
                    minute: |
                      [[[
                        if (states[entity.entity_id].attributes.minute < 10) {
                          return `0${states[entity.entity_id].attributes.minute}`;
                        } else {
                          return `${states[entity.entity_id].attributes.minute}`;
                        }
                      ]]]
                  tap_action:
                    action: call-service
                    service: input_datetime.set_datetime
                    target:
                      entity_id: input_datetime.alarm_clock_[[day_of_week]]
                    data:
                      time: >-
                        [[[ return `${variables.hour}:${variables.minute}:00`
                        ]]]
                  styles:
                    card:
                      - width: 40px
                      - height: 20px
                      - padding: 0
                - type: custom:button-card
                  entity: input_datetime.alarm_clock_[[day_of_week]]
                  icon: mdi:menu-down
                  show_name: false
                  variables:
                    newhour: |
                      [[[
                        if (states[entity.entity_id].attributes.hour == 0) {
                          return 23;
                        } else {
                          return states[entity.entity_id].attributes.hour - 1;
                        }
                      ]]]
                    hour: |
                      [[[
                        if (variables.newhour < 10) {
                          return `0${variables.newhour}`;
                        } else {
                          return `${variables.newhour}`;
                        }
                      ]]]
                    minute: |
                      [[[
                        if (states[entity.entity_id].attributes.minute < 10) {
                          return `0${states[entity.entity_id].attributes.minute}`;
                        } else {
                          return `${states[entity.entity_id].attributes.minute}`;
                        }
                      ]]]
                  tap_action:
                    action: call-service
                    service: input_datetime.set_datetime
                    target:
                      entity_id: input_datetime.alarm_clock_[[day_of_week]]
                    data:
                      time: >-
                        [[[ return `${variables.hour}:${variables.minute}:00`
                        ]]]
                  styles:
                    card:
                      - width: 40px
                      - height: 20px
                      - padding: 0
            - type: custom:button-card
              entity: input_datetime.alarm_clock_[[day_of_week]]
              tap_action: none
              show_icon: false
              variables:
                hour: |
                  [[[
                    if (states[entity.entity_id].attributes.hour < 10) {
                      return `0${states[entity.entity_id].attributes.hour}`;
                    } else {
                      return `${states[entity.entity_id].attributes.hour}`;
                    }
                  ]]]
                minute: |
                  [[[
                    if (states[entity.entity_id].attributes.minute < 10) {
                      return `0${states[entity.entity_id].attributes.minute}`;
                    } else {
                      return `${states[entity.entity_id].attributes.minute}`;
                    }
                  ]]]
              name: '[[[ return `${variables.hour}:${variables.minute}`; ]]]'
              styles:
                card:
                  - width: 120px
                  - height: 50px
                  - padding: 0
                name:
                  - transform: scale(1.5)
            - type: vertical-stack
              cards:
                - type: custom:button-card
                  entity: input_datetime.alarm_clock_[[day_of_week]]
                  icon: mdi:menu-up
                  show_name: false
                  variables:
                    newminute: |
                      [[[
                        if (states[entity.entity_id].attributes.minute == 45) {
                          return 0;
                        } else {
                          return states[entity.entity_id].attributes.minute + 15;
                        }
                      ]]]
                    minute: |
                      [[[
                        if (variables.newminute < 10) {
                          return `0${variables.newminute}`;
                        } else {
                          return `${variables.newminute}`;
                        }
                      ]]]
                    hour: |
                      [[[
                        if (states[entity.entity_id].attributes.hour < 10) {
                          return `0${states[entity.entity_id].attributes.hour}`;
                        } else {
                          return `${states[entity.entity_id].attributes.hour}`;
                        }
                      ]]]
                  tap_action:
                    action: call-service
                    service: input_datetime.set_datetime
                    target:
                      entity_id: input_datetime.alarm_clock_[[day_of_week]]
                    data:
                      time: >-
                        [[[ return `${variables.hour}:${variables.minute}:00`
                        ]]]
                  styles:
                    card:
                      - width: 40px
                      - height: 20px
                      - padding: 0
                - type: custom:button-card
                  entity: input_datetime.alarm_clock_[[day_of_week]]
                  icon: mdi:menu-down
                  show_name: false
                  variables:
                    newminute: |
                      [[[
                        if (states[entity.entity_id].attributes.minute == 0) {
                          return 45;
                        } else {
                          return states[entity.entity_id].attributes.minute - 15;
                        }
                      ]]]
                    minute: |
                      [[[
                        if (variables.newminute < 10) {
                          return `0${variables.newminute}`;
                        } else {
                          return `${variables.newminute}`;
                        }
                      ]]]
                    hour: |
                      [[[
                        if (states[entity.entity_id].attributes.hour < 10) {
                          return `0${states[entity.entity_id].attributes.hour}`;
                        } else {
                          return `${states[entity.entity_id].attributes.hour}`;
                        }
                      ]]]
                  tap_action:
                    action: call-service
                    service: input_datetime.set_datetime
                    target:
                      entity_id: input_datetime.alarm_clock_[[day_of_week]]
                    data:
                      time: >-
                        [[[ return `${variables.hour}:${variables.minute}:00`
                        ]]]
                  styles:
                    card:
                      - width: 40px
                      - height: 20px
                      - padding: 0
views:
  - title: Alarm Clock
    icon: mdi:clock
    badges: []
    type: custom:masonry-layout
    layout:
      width: 240
    cards:
      - type: vertical-stack
        cards:
          - type: horizontal-stack
            cards:
              - type: custom:button-card
                entity: input_boolean.alarm_clock
                tap_action:
                  action: toggle
                state:
                  - value: 'off'
                    styles:
                      name:
                        - color: red
                  - value: 'on'
                    styles:
                      name:
                        - color: lime
                name: Alarm
                show_state: false
                show_icon: false
                styles:
                  card:
                    - width: 130px
                    - height: 50px
                    - padding: 0
                  name:
                    - transform: scale(1.5)
              - type: custom:button-card
                entity: input_datetime.alarm_clock
                label: Next Alarm
                show_label: true
                show_icon: false
                name: |
                  [[[
                    if (helpers.formatDateYear(states[entity.entity_id].state) != '2000')
                      return `${helpers.formatDateWeekdayShort(states[entity.entity_id].state)} @ ${helpers.formatTime(states[entity.entity_id].state)}`
                    else
                      return 'None';
                  ]]]
                tap_action: none
                styles:
                  card:
                    - width: 210px
                    - height: 50px
                    - padding: 0
                  grid:
                    - grid-template-areas: '"l" "i" "n" "s"'
                    - grid-template-rows: min-content 1fr min-content min-content
                    - grid-template-columns: 1fr
          - type: custom:decluttering-card
            template: alarm_clock_day
            variables:
              - day_of_week: monday
          - type: custom:decluttering-card
            template: alarm_clock_day
            variables:
              - day_of_week: tuesday
          - type: custom:decluttering-card
            template: alarm_clock_day
            variables:
              - day_of_week: wednesday
          - type: custom:decluttering-card
            template: alarm_clock_day
            variables:
              - day_of_week: thursday
          - type: custom:decluttering-card
            template: alarm_clock_day
            variables:
              - day_of_week: friday
          - type: custom:decluttering-card
            template: alarm_clock_day
            variables:
              - day_of_week: saturday
          - type: custom:decluttering-card
            template: alarm_clock_day
            variables:
              - day_of_week: sunday

The decluttering card contains a day worth of code. It is used seven times in the dashboard with a variable for the day name.

Let me know if you have any questions.

Thank you so much :slight_smile:
What interests me is the mechanism for incrementing and decrementing the times.

We agree that this is the part:

            - type: custom:button-card
              entity: input_datetime.alarm_clock_[[day_of_week]]
              tap_action: none
              show_icon: false
              variables:
                hour: |
                  [[[
                    if (states[entity.entity_id].attributes.hour < 10) {
                      return `0${states[entity.entity_id].attributes.hour}`;
                    } else {
                      return `${states[entity.entity_id].attributes.hour}`;
                    }
                  ]]]
                minute: |
                  [[[
                    if (states[entity.entity_id].attributes.minute < 10) {
                      return `0${states[entity.entity_id].attributes.minute}`;
                    } else {
                      return `${states[entity.entity_id].attributes.minute}`;
                    }
                  ]]]
              name: '[[[ return `${variables.hour}:${variables.minute}`; ]]]'
              styles:
                card:
                  - width: 120px
                  - height: 50px
                  - padding: 0
                name:
                  - transform: scale(1.5)
            - type: vertical-stack
              cards:
                - type: custom:button-card
                  entity: input_datetime.alarm_clock_[[day_of_week]]
                  icon: mdi:menu-up
                  show_name: false
                  variables:
                    newminute: |
                      [[[
                        if (states[entity.entity_id].attributes.minute == 45) {
                          return 0;
                        } else {
                          return states[entity.entity_id].attributes.minute + 15;
                        }
                      ]]]
                    minute: |
                      [[[
                        if (variables.newminute < 10) {
                          return `0${variables.newminute}`;
                        } else {
                          return `${variables.newminute}`;
                        }
                      ]]]
                    hour: |
                      [[[
                        if (states[entity.entity_id].attributes.hour < 10) {
                          return `0${states[entity.entity_id].attributes.hour}`;
                        } else {
                          return `${states[entity.entity_id].attributes.hour}`;
                        }
                      ]]]
                  tap_action:
                    action: call-service
                    service: input_datetime.set_datetime
                    target:
                      entity_id: input_datetime.alarm_clock_[[day_of_week]]
                    data:
                      time: >-
                        [[[ return `${variables.hour}:${variables.minute}:00`
                        ]]]
                  styles:
                    card:
                      - width: 40px
                      - height: 20px
                      - padding: 0
                - type: custom:button-card
                  entity: input_datetime.alarm_clock_[[day_of_week]]
                  icon: mdi:menu-down
                  show_name: false
                  variables:
                    newminute: |
                      [[[
                        if (states[entity.entity_id].attributes.minute == 0) {
                          return 45;
                        } else {
                          return states[entity.entity_id].attributes.minute - 15;
                        }
                      ]]]
                    minute: |
                      [[[
                        if (variables.newminute < 10) {
                          return `0${variables.newminute}`;
                        } else {
                          return `${variables.newminute}`;
                        }
                      ]]]
                    hour: |
                      [[[
                        if (states[entity.entity_id].attributes.hour < 10) {
                          return `0${states[entity.entity_id].attributes.hour}`;
                        } else {
                          return `${states[entity.entity_id].attributes.hour}`;
                        }
                      ]]]
                  tap_action:
                    action: call-service
                    service: input_datetime.set_datetime
                    target:
                      entity_id: input_datetime.alarm_clock_[[day_of_week]]
                    data:
                      time: >-
                        [[[ return `${variables.hour}:${variables.minute}:00`
                        ]]]
                  styles:
                    card:
                      - width: 40px
                      - height: 20px
                      - padding: 0

You are showing the button that displays the time followed by the two buttons that increment and decrement the minutes. There are two buttons above that to increment and decrement the hours.

So, yes. That also allows the hours/minutes to roll in the case of going above or below the min/max for each part of the time.

Thank you so much, it’s starting to look like something :slight_smile:

1 Like

Okay. To finish what I started …
An automation and a script will close this.

The automation watches for changes in the weekday booleans or datetime helpers. When any of them change, it calls a script that sets the next alarm date/time.
It has a second trigger for the current date/time matching the next alarm date/time. When that happens, it calls the script above.
It also currently sends a persistent notification if the main boolean helper is on. This is what would need changed for your specific situation of what you want the alarm to do.

In the script, if all daily booleans are turned off, it sets the next alarm to 1/1/2000. A change was made in the card in the above post to show None when the year is 2000.

Automation

Summary
alias: Alarm Clock
description: ""
triggers:
  - trigger: state
    entity_id:
      - input_boolean.alarm_clock
      - input_boolean.alarm_clock_monday
      - input_datetime.alarm_clock_monday
      - input_boolean.alarm_clock_tuesday
      - input_datetime.alarm_clock_tuesday
      - input_boolean.alarm_clock_wednesday
      - input_datetime.alarm_clock_wednesday
      - input_boolean.alarm_clock_thursday
      - input_datetime.alarm_clock_thursday
      - input_boolean.alarm_clock_friday
      - input_datetime.alarm_clock_friday
      - input_boolean.alarm_clock_saturday
      - input_datetime.alarm_clock_saturday
      - input_boolean.alarm_clock_sunday
      - input_datetime.alarm_clock_sunday
    id: setnext
  - trigger: time
    at: input_datetime.alarm_clock
    id: alarm
conditions: []
actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - setnext
        sequence:
          - action: script.turn_on
            metadata: {}
            target:
              entity_id: script.alarm_clock_2
            data: {}
      - conditions:
          - condition: trigger
            id:
              - alarm
        sequence:
          - parallel:
              - action: script.turn_on
                metadata: {}
                target:
                  entity_id: script.alarm_clock_2
                data: {}
              - if:
                  - condition: state
                    entity_id: input_boolean.alarm_clock
                    state:
                      - "on"
                then:
####################################################  Here is what to change for what you want to happen  #############################################
                  - action: persistent_notification.create
                    metadata: {}
                    data:
                      message: Ding Ding Ding
                      title: Alarm Clock
mode: single

And the script

Summary
alias: Alarm Clock
description: ""
sequence:
  - variables:
      nextalarm: >
        {%- set ns=namespace(nextalarm=[]) -%} {% for day in
        ['monday','tuesday','wednesday','thursday','friday','saturday','sunday']
        -%}
          {%- set weekday = loop.index - 1 -%}
          {%- if weekday < now().weekday() -%}
            {%- set adddays = weekday - now().weekday() + 7 -%}
          {%- elif weekday == now().weekday() -%}
            {%- set adddays = weekday - now().weekday() -%}
            {%- if states('input_datetime.alarm_clock_'~day) < now().time() | string -%}
              {%- set adddays = adddays + 7 -%}
            {%- endif %}
          {%- else -%}
            {%- set adddays = weekday - now().weekday() -%}
          {%- endif %}
          {%- if states('input_boolean.alarm_clock_'~day) == 'on' and states('input_boolean.alarm_clock') == 'on' -%}
            {%- set ns.nextalarm = ns.nextalarm + [as_timestamp(now().replace(hour=state_attr('input_datetime.alarm_clock_'~day, 'hour'), minute=state_attr('input_datetime.alarm_clock_'~day, 'minute'), second=0) + timedelta(days=adddays))] -%}
          {%- endif %}
        {% endfor -%} {%- if ns.nextalarm | count > 0 -%}
          {{ ns.nextalarm | sort | first }}
        {%- else -%}
          {{ 946706400.751659 }}
        {%- endif -%}
  - action: input_datetime.set_datetime
    metadata: {}
    target:
      entity_id: input_datetime.alarm_clock
    data:
      timestamp: "{{ nextalarm }}"

And, just for fun, at midnight, if the next alarm date equals today’s date, add an alarm to an Android phone. I expect this can be done on iPhone too. But, don’t have one.

The SKIP_UI intent shuts the alarm off when dismissed instead of leaving it live for the next day. There is no way to delete alarms from an Android device from HA. Although same times will be overlaid and turned back on.

Understand this will NOT survive a reboot. If HA is down or rebooting at midnight, the alarm won’t set and you will be late! The same with the original automation. If HA is down or restarting at the alarm time, you will be late!

Replaced automation from above

Summary
alias: Alarm Clock
description: ""
triggers:
  - trigger: state
    entity_id:
      - input_boolean.alarm_clock
      - input_boolean.alarm_clock_monday
      - input_datetime.alarm_clock_monday
      - input_boolean.alarm_clock_tuesday
      - input_datetime.alarm_clock_tuesday
      - input_boolean.alarm_clock_wednesday
      - input_datetime.alarm_clock_wednesday
      - input_boolean.alarm_clock_thursday
      - input_datetime.alarm_clock_thursday
      - input_boolean.alarm_clock_friday
      - input_datetime.alarm_clock_friday
      - input_boolean.alarm_clock_saturday
      - input_datetime.alarm_clock_saturday
      - input_boolean.alarm_clock_sunday
      - input_datetime.alarm_clock_sunday
    id: set_next
  - trigger: time
    at: input_datetime.alarm_clock
    id: alarm
  - trigger: time
    at: "00:00:00"
    id: set_android_alarm
conditions: []
actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - set_next
        sequence:
          - action: script.turn_on
            metadata: {}
            target:
              entity_id: script.alarm_clock_2
            data: {}
      - conditions:
          - condition: trigger
            id:
              - alarm
        sequence:
          - parallel:
              - action: script.turn_on
                metadata: {}
                target:
                  entity_id: script.alarm_clock_2
                data: {}
              - if:
                  - condition: state
                    entity_id: input_boolean.alarm_clock
                    state:
                      - "on"
                then:
                  - action: persistent_notification.create
                    metadata: {}
                    data:
                      message: Ding Ding Ding
                      title: Alarm Clock
      - conditions:
          - condition: trigger
            id:
              - set_android_alarm
          - condition: template
            value_template: >
              {{ as_datetime(states('input_datetime.alarm_clock')).strftime('%Y-%m-%d') == as_datetime(now()).strftime('%Y-%m-%d') }}
        sequence:
          - action: notify.jeffs_phone
            data:
              message: command_activity
              data:
                intent_action: android.intent.action.SET_ALARM
                intent_extras: >-
                  {% set hour = state_attr('input_datetime.alarm_clock', 'hour')
                  %} {% set minute = state_attr('input_datetime.alarm_clock', 'minute') %}
                    android.intent.extra.alarm.HOUR:{{ hour }},android.intent.extra.alarm.MINUTES:{{ minute }},android.intent.extra.alarm.SKIP_UI:true
mode: single