Dynamic Morning Alarm System (Home Assistant + SMS, iOS Only)

Dynamic Morning Alarm System (Home Assistant + SMS, iOS Only)

Still waking up like it’s 2005? Level up your mornings with dynamic alarms, SMS-triggered iOS Shortcuts, mood lighting, Spotify, weather briefings, and even sick-day logic. It even texts your iPhone automagically to make sure you actually get out of bed.

This documentation outlines a flexible morning alarm system built in Home Assistant, integrated with SMS notifications via ClickSend Integration to trigger alarms on an iPhone using iOS Shortcuts app. The system supports sick leave management, automated actions like opening covers, and optional weather updates using AccuWeather (AccuWeather Integration). Helper names are generalized (e.g., input_select.wake_up_time, input_boolean.sick_leave) for clarity and accessibility. Both basic and advanced configurations are provided to demonstrate flexibility.

Required Integrations and Tools

Integrations

Integration Purpose Source
ClickSend Sends SMS notifications to trigger iOS Shortcuts and deliver alarm confirmations or evening summaries. Built-in Home Assistant
Workday Sensor Restricts morning routine and evening SMS to workdays. Built-in Home Assistant
AccuWeather Provides weather data for morning notifications. Built-in Home Assistant
Spotcast (Optional) Enables Spotify playback in the morning routine. HACS (Spotcast)
  • Workday Setup: Add the Workday integration via Settings > Devices & Services > Add Integration, select “Workday,” choose your country, and set a 1-day offset to align with your schedule (Workday Sensor).
  • AccuWeather Note: While AccuWeather is used here, it’s not needed for the basic functionality. Any weather integration (e.g., OpenWeatherMap) can also work.

Lovelace Tools (HACS)

Tool Purpose Source Installation
Button Card Creates interactive time selection and sick leave toggle buttons. HACS (Button Card) Install via HACS
Card Mod (Optional) Enhances button card styling with custom CSS. HACS (Card Mod) Install via HACS
  • HACS Installation: If not installed, set up HACS following the official guide (HACS Documentation).

Components

Wake-Up Time Selector

An input_select helper, input_select.wake_up_time, allows users to select a wake-up time from predefined options (e.g., 06:00, 06:30). State changes trigger automations like sending SMS notifications (Input Select).

Sick Leave Toggle

An input_boolean helper, input_boolean.sick_leave, pauses alarm routines and notifications when enabled, ideal for sick days or holidays (Input Boolean).

SMS via ClickSend

The ClickSend integration (notify.clicksend) sends SMS messages programmatically. Configure it in configuration.yaml:

notify:
  - platform: clicksend
    name: ClickSend
    username: YOUR_CLICKSEND_USERNAME
    api_key: YOUR_CLICKSEND_API_KEY

This setup enables reliable SMS delivery to trigger iOS Shortcuts (ClickSend Integration).

iOS Shortcuts Trigger

SMS messages received on an iPhone trigger iOS Shortcuts to set native alarms based on message content, ensuring reliable alarm activation.

Lovelace Interface

Simple Configuration

A straightforward entities card provides a dropdown for wake-up time and a toggle for sick leave mode.

type: entities
title: Alarm Settings
entities:
  - entity: input_select.wake_up_time
    name: "Wake-Up Time"
  - entity: input_boolean.sick_leave
    name: "Sick Leave Mode"

Advanced Configuration

Custom button cards offer an interactive experience with time selection and a styled sick leave toggle.

Time Selection Buttons

type: horizontal-stack
cards:
  - type: custom:button-card
    entity: input_select.wake_up_time
    name: "06:00"
    tap_action:
      action: call-service
      service: input_select.select_option
      service_data:
        entity_id: input_select.wake_up_time
        option: "06:00"
    show_state: false
    styles:
      card:
        - background-color: |
            [[[ return entity.state === '06:00' ? 'rgba(70,130,180,0.8)' : 'rgba(60,60,60,0.4)'; ]]]
        - color: white
  - type: custom:button-card
    entity: input_select.wake_up_time
    name: "06:30"
    tap_action:
      action: call-service
      service: input_select.select_option
      service_data:
        entity_id: input_select.wake_up_time
        option: "06:30"
    show_state: false
    styles:
      card:
        - background-color: |
            [[[ return entity.state === '06:30' ? 'rgba(70,130,180,0.8)' : 'rgba(60,60,60,0.4)'; ]]]
        - color: white
# Add more times as needed

Sick Leave Toggle Button

type: custom:button-card
entity: input_boolean.sick_leave
name: |
  [[[ return entity.state === 'on' ? '🛌 Sick Leave Mode is ACTIVE' : 'Set Sick Leave Mode'; ]]]
label: |
  [[[ return entity.state === 'on' ? 'Morning alarm is paused' : 'Pause morning alarm'; ]]]
icon: |
  [[[ return entity.state === 'on' ? 'mdi:bed-clock' : 'mdi:bed'; ]]]
color: auto
show_state: false
show_label: true
tap_action:
  action: toggle
  confirmation:
    text: |
      [[[ if (entity.state === 'off') {
            return "🛌 Are you sure you want to pause the morning alarm?";
          } else {
            return "⚠️ You are about to turn off sick leave mode!\n\nThis will resume the morning alarm. Are you ready? 😬";
          } ]]]
hold_action:
  action: more-info
styles:
  card:
    - border-radius: 20px
    - padding: 16px
    - font-size: 16px
    - text-transform: none
    - background-color: |
        [[[ return entity.state === 'on' ? 'rgba(255, 111, 105, 0.8)' : 'var(--ha-card-background, var(--card-background-color, #1c1c1c))'; ]]]
    - color: |
        [[[ return entity.state === 'on' ? '#FFFFFF' : '#D3D3D3'; ]]]
  name:
    - font-weight: bold
    - justify-self: center
    - text-align: center
  label:
    - font-size: 13px
    - color: |
        [[[ return entity.state === 'on' ? '#E0E0E0' : '#A9A9A9'; ]]]
    - justify-self: center
    - text-align: center
  icon:
    - width: 40px
    - height: 40px
    - color: |
        [[[ return entity.state === 'on' ? '#FFFFFF' : '#4CAF50'; ]]]
  grid:
    - grid-template-areas: "\"i\" \"n\" \"l\""
    - grid-template-columns: 1fr
    - grid-template-rows: auto auto auto
extra_styles: |
  @keyframes pulse {
    0% { box-shadow: 0 0 0px rgba(255,0,0,0.4); }
    50% { box-shadow: 0 0 20px rgba(255,0,0,0.7); }
    100% { box-shadow: 0 0 0px rgba(255,0,0,0.4); }
  }
  @keyframes colorPulse {
    0% { background-color: rgba(255, 111, 105, 0.8); }
    50% { background-color: rgba(255, 60, 50, 0.9); }
    100% { background-color: rgba(255, 111, 105, 0.8); }
  }
state:
  - value: "on"
    styles:
      card:
        - animation: |
            [[[ return 'pulse 2s infinite, colorPulse 2s infinite'; ]]]


ezgif-242f6d376feb18

Automations

1. Notify Wake-Up Time via SMS

Purpose: Sends an SMS when the wake-up time is changed, confirming the new setting.

Configuration:

- id: notify_alarm_time_change
  alias: "Notify Wake-Up Time via SMS"
  trigger:
    - platform: state
      entity_id: input_select.wake_up_time
  condition:
    - condition: state
      entity_id: input_boolean.sick_leave
      state: "off"
  action:
    - service: notify.clicksend
      data:
        message: >-
          Your wake-up alarm is now set to {{ states('input_select.wake_up_time') }}. Good night! 😴
  mode: single

2. Morning Routine

Purpose: Activates the morning routine 15 minutes before the set wake-up time, performing actions like turning on lights and opening covers.

Template Trigger Explanation: The template trigger ensures precision by comparing the current time (sensor.time) with the wake-up time minus 15 minutes, allowing preparatory actions to enhance the wake-up experience.

Basic Configuration:

- id: trigger_morning_routine
  alias: "Trigger Morning Routine"
  trigger:
    - platform: template
      value_template: >
        {{ states('sensor.time') ==
           (strptime(states('input_select.wake_up_time'), '%H:%M') - timedelta(minutes=15)).strftime('%H:%M') }}
  condition:
    - condition: state
      entity_id: input_boolean.sick_leave
      state: "off"
  action:
    - service: script.start_morning_routine
  mode: single

Advanced Configuration:

- id: morning_routine
  alias: "Morning Routine"
  trigger:
    - platform: template
      value_template: >
        {{ states('sensor.time') ==
           (strptime(states('input_select.wake_up_time'), '%H:%M') - timedelta(minutes=15)).strftime('%H:%M') }}
  condition:
    - condition: time
      weekday:
        - mon
        - tue
        - wed
        - thu
        - fri
    - condition: state
      entity_id: binary_sensor.workday_sensor
      state: "on"
  action:
    - service: light.turn_on
      data:
        brightness_pct: 1
      target:
        entity_id: light.bedroom_lamp
    - delay:
        seconds: 2
    - service: light.turn_on
      data:
        transition: 900
        brightness_pct: 100
      target:
        entity_id: light.bedroom_lamp
    - delay:
        minutes: 15
    - service: cover.open_cover
      target:
        entity_id: cover.bedroom_blinds
    - service: notify.mobile_app_user
      data:
        title: Good Morning!
        message: >
          Today's outdoor temperature is {{ states('sensor.outdoor_temperature') }} °C,
          but it feels like {{ states('sensor.realfeel_temperature') }} °C.
          The time is {{ now().strftime('%H:%M') }}. Have a great day! ❤️
    - service: media_player.play_media
      data:
        media_content_id: "spotify:track:example_track_id"
        media_content_type: "music"
      target:
        entity_id: media_player.bedroom_speaker
    - delay:
        seconds: 40
    - service: media_player.turn_off
      target:
        entity_id: media_player.bedroom_speaker
    - service: scene.turn_on
      target:
        entity_id: scene.turn_off_air_conditioner
    - service: light.turn_on
      data:
        brightness_pct: 100
      target:
        entity_id: light.kitchen_breakfast_area
    - service: alarm_control_panel.disarm
      data:
        code: "8012"
      target:
        entity_id: alarm_control_panel.security_system
    - delay:
        minutes: 15
    - service: light.turn_off
      target:
        entity_id: light.bedroom_lamp
    - delay:
        minutes: 30
    - service: notify.mobile_app_user
      data:
        message: Don't forget to wear your ring 💍
    - service: light.turn_off
      target:
        entity_id: light.kitchen_breakfast_area
  mode: single

3. Evening Summary SMS

Purpose: Sends an SMS at 21:00 on workdays, detailing the next day’s alarm time or notifying if sick leave mode is active.

Basic Configuration:

- id: evening_alarm_summary
  alias: "Evening Summary SMS"
  trigger:
    - platform: time
      at: '21:00:00'
  action:
    - choose:
        - conditions:
            - condition: state
              entity_id: input_boolean.sick_leave
              state: "off"
          sequence:
            - service: notify.clicksend
              data:
                message: >-
                  Tomorrow's wake-up alarm is set to {{ states('input_select.wake_up_time') }}. Sleep well! 🌙
        default:
          - service: notify.clicksend
            data:
              message: >-
                The morning alarm is paused (sick leave). Get well soon! 🤒
  mode: single

Advanced Configuration:

- id: evening_alarm_summary
  alias: "Evening Summary SMS"
  description: Sends an SMS every evening before a workday with the next day's alarm time or a notice if sick leave mode is on.
  trigger:
    - platform: time
      at: "21:00:00"
  condition:
    - condition: time
      weekday:
        - sun
        - mon
        - tue
        - wed
        - thu
    - condition: state
      entity_id: binary_sensor.workday_sensor
      state: "on"
  action:
    - service: notify.clicksend
      data:
        message: >
          {% set time = now().hour %}
          {% set greeting = "Good " ~ ("evening" if time >= 18 else "afternoon" if time >= 12 else "morning" if time >= 5 else "night") %}
          {% if is_state('input_boolean.sick_leave', 'on') %}
            {{ greeting }}, Sick leave mode is active – morning alarm is paused. Rest well 😴
          {% else %}
            {{ greeting }}, Your morning alarm is set to {{ states('input_select.wake_up_time') }}. Sleep well ⏰
          {% endif %}
  mode: single

4. Disable Alarms on Sick Leave

Purpose: Disables alarm-related automations when sick leave mode is enabled, with an option to auto-reset.

Basic Configuration:

- id: sick_mode_on
  alias: "Disable Alarms on Sick Leave"
  trigger:
    - platform: state
      entity_id: input_boolean.sick_leave
      to: "on"
  action:
    - service: automation.turn_off
      target:
        entity_id:
          - automation.notify_alarm_time_change
          - automation.morning_routine
          - automation.evening_alarm_summary
  mode: single

Advanced Configuration:

- id: disable_morning_alarm_on_sick_leave
  alias: "Disable Morning Alarm on Sick Leave"
  description: Pauses the morning alarm and evening SMS until the next scheduled run.
  trigger:
    - platform: state
      entity_id: input_boolean.sick_leave
      to: "on"
  action:
    - service: automation.turn_off
      target:
        entity_id:
          - automation.morning_routine
          - automation.evening_alarm_summary
      data:
        stop_actions: true
    - variables:
        now_time: "{{ now() }}"
        selected: "{{ states('input_select.wake_up_time') }}"
        next_alarm: >
          {% set t = strptime(selected, '%H:%M') - timedelta(minutes=15) %}
          {% set run = now().replace(hour=t.hour, minute=t.minute, second=0) %}
          {% if now() >= run %}
            {% set run = run + timedelta(days=1) %}
          {% endif %}
          {{ run }}
        sleep_seconds: "{{ (next_alarm - now_time).total_seconds() | int }}"
    - delay:
        seconds: "{{ sleep_seconds }}"
    - service: input_boolean.turn_off
      target:
        entity_id: input_boolean.sick_leave
    - service: automation.turn_on
      target:
        entity_id:
          - automation.morning_routine
          - automation.evening_alarm_summary
  mode: restart

5. Re-enable Alarms on Sick Leave OFF

Purpose: Re-enables automations when sick leave mode is manually disabled.

Basic Configuration:

- id: sick_mode_off
  alias: "Re-enable Alarms when Recovered"
  trigger:
    - platform: state
      entity_id: input_boolean.sick_leave
      to: "off"
  action:
    - service: automation.turn_on
      target:
        entity_id:
          - automation.notify_alarm_time_change
          - automation.morning_routine
          - automation.evening_alarm_summary
  mode: single

Advanced Configuration:

- id: reenable_morning_alarm_manual
  alias: "Re-enable Morning Alarm on Manual Sick Leave Off"
  description: Re-enables morning alarm and evening SMS if sick leave is manually turned off.
  trigger:
    - platform: state
      entity_id: input_boolean.sick_leave
      to: "off"
  condition:
    - condition: template
      value_template: >
        {% set last = state_attr('automation.disable_morning_alarm_on_sick_leave', 'last_triggered') %}
        {{ last is none or (as_timestamp(now()) - as_timestamp(last)) > 5 }}
  action:
    - service: automation.turn_on
      target:
        entity_id:
          - automation.morning_routine
          - automation.evening_alarm_summary
  mode: single

Customizing the Morning Alarm

Trigger Only on Workdays

Limit the alarm to workdays using the Workday sensor, configured via Settings > Devices & Services > Add Integration > Workday, selecting your country and a 1-day offset (Workday Sensor).

condition:
  - condition: state
    entity_id: binary_sensor.workday_sensor
    state: "on"

Automate Cover Opening

Open smart blinds automatically during the morning routine.

action:
  - service: cover.open_cover
    target:
      entity_id: cover.bedroom_blinds

Send Weather Updates via SMS

Include weather forecasts using AccuWeather (AccuWeather Integration).

action:
  - service: notify.clicksend
    data:
      message: >
        Good morning! Today's weather: {{ states('weather.accuweather') }}.
        Temperature: {{ state_attr('weather.accuweather', 'temperature') }}°C.
        Your alarm is set to {{ states('input_select.wake_up_time') }}.

Why SMS Instead of Email?

Tests showed SMS, via ClickSend, is far more reliable than email, which succeeded only 3 out of 10 times due to delays or iOS bugs. SMS ensures instant delivery, critical for timely notifications (ClickSend Integration). The only downside is that this costs money, but if you only send one text a day it’s still very affordable at 0,061 USD per SMS. Prices may vary depending on region.

Why Not Other Triggers?

Using SMS to trigger iOS Shortcuts is simpler and more robust than Home Assistant triggers in the Shortcuts app. Home Assistant triggers and webhooks do not work with iOS Shortcuts directly, making SMS a practical workaround. There are limited ways to trigger Shortcuts automations, and SMS leverages the built-in “Message” trigger, responding to texts from specific senders or content. Other providers like Twilio could work similarly (Twilio Integration), it’s not something I have personally tested tho.

iOS Shortcuts & Automations

  1. First of all, create all the alarms you want to automate in the iOS Clock app.
  2. Open the Shortcuts app on your iPhone.
  3. Create a shortcut, use “Switch Alarm Setting” to adjust the time, and disable “Show When Running” for a seamless experience. Combine this with several alarms as you wish. Give it a good name and save.
  4. At the automation tab, create a new automation with a “Message” trigger, setting “From” to ClickSend’s sender ID/Phone number (Add phone number to your Contacts app), optionally “Message Contains” to your desired wake up time. You can for example set it as “06:30”, that way you can add more times in Home Assistant and just create new shortcuts and automations in the iOS Shortcuts app. Make sure to set it to run it without confirmation.
  5. Test by sending an SMS with the correct data from the automations, from Home Assistant and verifying the alarm in the Clock app. Example below:
Your alarm is set to {{ states('input_select.wake_up_time') }}.



Conclusion

This system combines Home Assistant’s automation with ClickSend’s reliable SMS and iOS Shortcuts app, offering a flexible wake-up solution. Customize it with workdays, smart devices, and weather data for an optimized experience.

Key Citations

4 Likes