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:
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.
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
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
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
OUARZA
January 20, 2026, 8:51pm
11
Hello,
I think it’s ugly.
I can’t seem to make anything nice.
I agree. I thought what I came up with looks better. Just my unbiased (LOL) opinion.
Can you come up with something that is a mix of the two? Or, explain what you would like it to look like different from the two.
We got some smart folks here that can help!
I started by chasing the pic in your second post. But, decided I liked where mine went better. Just saying.
OUARZA
January 20, 2026, 9:22pm
13
Thanks, I’m looking for something very minimalist, without red/green colors… Something like what I showed, but smaller (smartphone display) and simple.
You can certainly change what I did to have toggles instead. It will take some digging to make the buttons look like toggles.
Not sure how skinny your phone is, but my screenshot above was on my phone.
tom_l
January 20, 2026, 10:46pm
15
Maybe try putting all the day’s entities in the same row using this card:
Show multiple entity states and attributes on entity rows in Home Assistant's Lovelace UI
Here’s a mock-up I threw together with some of my entities:
You have to click on the time to edit it.
entities:
- entity: switch.zone_1
name: Monday
type: custom:multiple-entity-row
toggle: true
state_color: true
entities:
- entity: input_datetime.blinds_weekday_open_time
name: Time
- entity: switch.zone_2
name: Tuesaday
type: custom:multiple-entity-row
toggle: true
state_color: true
entities:
- entity: input_datetime.blinds_weekday_open_time
name: Time
- entity: switch.zone_3
name: Tuesaday
type: custom:multiple-entity-row
toggle: true
state_color: true
entities:
- entity: input_datetime.blinds_weekday_open_time
name: Time
title: Alarm
type: entities
show_header_toggle: true
1 Like
Are multiple Tuesadays a southern hemisphere thing?
2 Likes
tom_l
January 21, 2026, 12:24am
17
Yes. Yes they are. Especially after a sleepless night out aurora watching.
3 Likes
petro
(Petro)
January 21, 2026, 12:43pm
18
Here I am thinking it was Tuesday
Nick4
(Nick)
January 21, 2026, 1:20pm
19
A simple solution: set your alarm on a mobile device and use that as a reference in HA.
That way you can have 2 alarms, in case one fails, and a very easy way to set it up, no matter what time you have to get up.
This is at least how it’s done here without having to use a dashboard.
1 Like
OUARZA
January 21, 2026, 8:21pm
20
And there you go, thank you very much for your advice, I used multiple-entity-row.
type: vertical-stack
cards:
- type: horizontal-stack
cards:
- type: entities
entities:
- entity: input_boolean.reveil_mode
type: custom:multiple-entity-row
toggle: true
icon: false
name: Mode
card_mod:
style: |
ha-card {
height: 70px !important;
display: flex;
align-items: center;
padding: 0 px !important;
}
.card-content {
width: 100%;
}
- type: custom:button-card
entity: sensor.reveil_prochain_reveil
icon: mdi:alarm
name: Prochain réveil
show_state: true
layout: vertical
styles:
card:
- padding: 8px
- font-size: 12px
- height: 70px
name:
- font-size: 13px
state:
- font-size: 14px
- color: var(--secondary-text-color)
- type: entities
entities:
- entity: input_boolean.reveil_lundi
type: custom:multiple-entity-row
toggle: true
name: Lundi
state_color: true
entities:
- entity: input_datetime.reveil_heure_lundi
name: false
- entity: input_boolean.reveil_mardi
type: custom:multiple-entity-row
toggle: true
name: Mardi
state_color: true
entities:
- entity: input_datetime.reveil_heure_mardi
name: false
- entity: input_boolean.reveil_mercredi
type: custom:multiple-entity-row
toggle: true
state_color: true
name: Mercredi
entities:
- entity: input_datetime.reveil_heure_mercredi
name: false
- entity: input_boolean.reveil_jeudi
type: custom:multiple-entity-row
toggle: true
name: Jeudi
state_color: true
entities:
- entity: input_datetime.reveil_heure_jeudi
name: false
- entity: input_boolean.reveil_vendredi
type: custom:multiple-entity-row
toggle: true
name: Vendredi
state_color: true
entities:
- entity: input_datetime.reveil_heure_vendredi
name: false
- entity: input_boolean.reveil_samedi
type: custom:multiple-entity-row
toggle: true
name: Samedi
state_color: true
entities:
- entity: input_datetime.reveil_heure_samedi
name: false
- entity: input_boolean.reveil_dimanche
type: custom:multiple-entity-row
toggle: true
name: Dimanche
state_color: true
entities:
- entity: input_datetime.reveil_heure_dimanche
name: false
show_header_toggle: false
title: Réveil