OUARZA
January 8, 2026, 6:51am
1
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.
OUARZA
January 8, 2026, 6:57am
2
Since I could only post one image per message, here’s what I did on the Jeedom side:
jeffcrum
(Jeff Crum)
January 9, 2026, 4:10pm
3
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
OUARZA
January 9, 2026, 4:23pm
4
Perfect, I’d like the YAML code.
jeffcrum
(Jeff Crum)
January 9, 2026, 4:24pm
5
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.
OUARZA
January 9, 2026, 5:01pm
6
Thank you so much
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
jeffcrum
(Jeff Crum)
January 9, 2026, 5:07pm
7
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.
OUARZA
January 9, 2026, 9:17pm
8
Thank you so much, it’s starting to look like something
1 Like
jeffcrum
(Jeff Crum)
January 10, 2026, 3:37pm
9
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 }}"
jeffcrum
(Jeff Crum)
January 10, 2026, 11:30pm
10
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