Compare commits

...

2 Commits

Author SHA1 Message Date
hiperman
95779d9805 add alarm blueprint automation 2026-01-09 22:08:33 -05:00
hiperman
3bc8a71d67 update docs 2026-01-09 22:08:02 -05:00
3 changed files with 287 additions and 131 deletions

114
README.md
View File

@@ -1,7 +1,113 @@
# ha-sunrise-alarm
A HomeAssistant blueprint that turns your smart lights into a natural alarm clock. # HomeAssistant SunriseAlarm
**Turn your smart lights into a natural alarm clock**
---
<a href="https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https://git.jaroszew.ski/patrick/ha-sunrise-alarm/src/branch/main/sunrise-alarm.yaml"> ## Table of Contents
<img src="https://my.home-assistant.io/badges/blueprint_import.svg" alt="Open your Home Assistant instance and show the blueprint import dialog"> 1. [What it is & how it works](#what-it-is-&-how-it-works)
2. [Twostep installation](#twostep-installation)
* 2.1[sunrisesimulation](#sunrisesimulation)
* 2.2[sunrisealarm](#sunrisealarm)
3. [Configurable variables](#configurable-variables)
* 3.1`sunrisesimulation` script variables
* 3.2`sunrisealarm` automation variables
4. [Customising the experience](#customising-the-experience)
5. [Troubleshooting & FAQ](#troubleshooting-&-faq)
6. [License](#license)
---
## 1. What it is & how it works
| Component | Purpose | What it does |
|-----------|---------|--------------|
| **sunrisesimulation** (script) | The “engine” that gradually lights up (or down) your bulbs | Uses a `repeat` loop to turn the selected lights on/off and slowly increase/decrease brightness over a configurable time span. |
| **sunrisealarm** (automation) | The “scheduler” that calls the simulation at a chosen time | Triggers the script at *AlarmTime Offset* (e.g. 30min before the clock). An `input_boolean` lets you switch the alarm on/off. |
> **Why two separate blueprints?**
> The simulation can be reused in any scenario (e.g. a “morning routine” or a “sunsetin30min” routine). The alarm automation is a thin wrapper that turns that simulation into a timed alarm.
---
## 2. Installation
### 2.1sunrisesimulation
1. **Import the blueprint**
<div>
<a href="https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https://git.jaroszew.ski/patrick/ha-sunrise-alarm/raw/branch/main/sunrise-simulation.yaml">
<img src="https://my.home-assistant.io/badges/blueprint_import.svg" alt="Import sunrisesimulation">
</a> </a>
</div>
2. **Create a script from the blueprint**
* In the “Create new script” dialog, name it **`sunrise-simulation`** (you can give any name you like).
* Youll be asked for a handful of variables see section3.1 for the defaults and meaning.
* Click **Create** HomeAssistant will add a script entity called `script.sunrise-simulation` (or whatever name you gave it).
---
### 2.2sunrisealarm
1. **Import the alarm automation blueprint**
<div>
<a href="https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https://git.jaroszew.ski/patrick/ha-sunrise-alarm/raw/branch/main/sunrise-alarm.yaml">
<img src="https://my.home-assistant.io/badges/blueprint_import.svg" alt="Import sunrisealarm">
</a>
</div>
2. **Create the automation**
* Pick an `input_datetime` that represents the clock you want to use as the alarm.
* Pick an `input_boolean` that toggles the alarm on or off.
* Choose a `offset_duration`
* Choose the `sunrisesimulation` script you created in the previous step for the `alarm_script` field.
* Save you now have a readytorun alarm!
> **Tip** If you want a *sunset* alarm, simply copy the `sunrisesimulation` script (or create a new script from the blueprint if you want to define a different arc) and reverse it by setting direction with the `reversed` flag set to `true`. You'll also want to create a new automation that calls it with a negative `offset_duration`.
---
## 2.3Configurable variables
### 3.1sunrisesimulation script variables
| Variable | Type | Default | Description |
|----------|------|---------|-------------|
| `lights` | list of `entity_id`s | `["light.kitchen"]` | All bulbs that should be part of the arc. |
| `total_duration` | integer | `30` | Total time the arc takes on minutes. |
| `steps` | integer | `10` | How many brightness steps the script performs. If your light(s) do not support `transition` you should set this higher for a more gradual change (max value is 100). |
| `start_brightness` | integer | `0` | Brightness percentage at the very beginning of the arc. |
| `end_brightness` | integer | `100` | Brightness percentage at the very end of the arc. |
| `start_temp` | integer | `2000` | Color temperature (kelvin) at the very beginning of the arc. |
| `end_temp` | integer | `5000` | Color temperature (kelvin) at the very end of the arc. |
| `reversed` | boolean | `false` | If `true`, the script will run your arc in reverse (useful for easily defining sunsets). |
| `curve_type` | string | `sigmoid` | `linear`, `parabolic` (quadratic), or `sigmoid` (an S-curve). As we don't perceive light intensity linearly, `sigmoid` or `parabolic` make for a more natural curve.
### 3.2sunrisealarm automation variables
| Variable | Type | Default | Description |
|----------|------|---------|-------------|
| `alarm_time` | `input_datetime` | — | The time you want the alarm to ring (e.g. `07:00 AM`). |
| `offset_duration` | `time` | `"00:30:00"` | How many minutes after `alarm_time` the sunrise arc should start. A negative value would start **before** the alarm. |
| `alarm_enabled` | `input_boolean` | — | A switch that turns the whole alarm on/off. |
| `sunrise_script` | `script` | — | The script instance created by the `sunrisesimulation` blueprint (`script.sunrise-simulation`). |
The automation uses the following logic:
1. `AlarmTime Offset` fires the automation.
2. If `AlarmEnabled` is `on`, it calls the sunrise script.
3. If `AlarmEnabled` is `off`, nothing happens.
---
## 6. License
This repository is released under the **MIT License**.
Feel free to fork, modify, or redistribute the blueprints as long as you keep the same license.

View File

@@ -1,140 +1,49 @@
blueprint: blueprint:
name: "Simulated Sunrise Alarm" name: "Simulated Sunrise Alarm"
description: "Smoothly increase light brightness with configurable steps" description: "Smoothly increase light brightness with configurable steps"
domain: script domain: automation
input: input:
target_lights: alarm_time:
name: Target Light(s) name: Alarm Clock Time
description: Light(s) to control description: The time when you should wake up
selector: selector:
target:
entity: entity:
domain: light domain: input_datetime
reversed:
name: "Simulate sunset instead of sunrise" alarm_enabled:
description: If true, reverses the direction (simulates sunset instead of sunrise) name: Alarm Clock Enabled
description: Boolean dictating whether the alarm is on or not
selector: selector:
boolean: entity:
default: false domain: input_boolean
steps: offset_duration:
name: Number of Steps name: Offset Duration
description: How many brightness steps in the curve description: How long before/after the alarm time to trigger (use negative values for earlier times).
default: 20 default: "-00:30:00"
selector: selector:
number: duration:
min: 5
max: 100
step: 1
total_duration: alarm_script:
name: Total Duration name: Script to trigger
description: Total time to complete the brightness ramp description: Script to trigger
default: 30
selector: selector:
number: entity:
min: 1 filter:
max: 120 - domain: script
unit_of_measurement: minutes
start_brightness: triggers:
name: Starting Brightness - trigger: time
description: Initial brightness percentage (0-100) at:
default: 1 entity_id: !input alarm_time
selector: offset: !input offset_duration
number:
min: 0
max: 100
step: 1
end_brightness: conditions:
name: Ending Brightness - condition: state
description: Final brightness percentage (0-100) entity_id: !input alarm_enabled
default: 100 state: "on"
selector:
number:
min: 1
max: 100
step: 1
start_temp: mode: restart
name: Starting Color Temperature
description: Final color temperature in Kelvin
default: 2000
selector:
color_temp:
min: 2000
unit: kelvin
end_temp: actions:
name: Ending Color Temperature - action: !input alarm_script
description: Final color temperature in Kelvin
default: 5500
selector:
color_temp:
unit: kelvin
curve_type:
name: Curve Type
default: "parabolic"
description: “linear”, "parabolic" (quadratic), or “sigmoid” (an S-curve/logistic curve)
selector:
select:
options:
- "linear"
- "sigmoidal"
- "parabolic"
variables:
lights: !input target_lights
start_temp: !input start_temp
end_temp: !input end_temp
curve_type: !input curve_type
total_duration: !input total_duration
num_steps: !input steps
step_delay: "{{ (total_duration * 60 / num_steps) | round(0) }}"
start_bright: !input start_brightness
end_bright: !input end_brightness
reversed: !input reversed
# Loop through each step of the curve
sequence:
- repeat:
count: "{{ num_steps }}"
sequence:
- variables:
# Calculate current step (0 to 1 range)
x: "{{ (repeat.index - 1) / (num_steps - 1) }}"
# Reflects the curve in the y-axis if reversed is true
- choose:
- conditions:
- condition: template
value_template: "{{ reversed }}"
sequence:
- variables:
x: "{{ 1 - x }}"
- variables:
curve_func: >
{%- if curve_type == 'linear' -%}
{{ x }}
{%- elif curve_type == 'sigmoidal' -%}
{{ 1 / (1 + (2.71828 ** (-12 * (x - 0.5)))) }}
{%- elif curve_type == 'parabolic' -%}
{{ x ** 2 }}
{%- endif -%}
# Map result to brightness range and color temperature range respectively
current_brightness: "{{ (start_bright + (end_bright - start_bright) * curve_func | float) | round(0) }}"
current_color_temp: "{{ (start_temp + (end_temp - start_temp) * curve_func | float) | round(0) }}"
- service: light.turn_on
target: !input target_lights
data:
brightness_pct: "{{ current_brightness }}"
kelvin: "{{ current_color_temp }}"
transition: "{{ step_delay }}"
- delay: "{{ step_delay }}"

141
sunrise-simulation.yaml Normal file
View File

@@ -0,0 +1,141 @@
blueprint:
name: "Simulated Sunrise Alarm"
description: "Smoothly increase light brightness with configurable steps"
domain: script
input:
target_lights:
name: Target Light(s)
description: Light(s) to control
selector:
target:
entity:
domain: light
steps:
name: Number of Steps
description: How many brightness steps in the curve (use more steps if your lights do not support `transition`)
default: 10
selector:
number:
min: 5
max: 100
step: 1
total_duration:
name: Total Duration
description: Total time to complete the brightness ramp
default: 30
selector:
number:
min: 1
max: 120
unit_of_measurement: minutes
start_brightness:
name: Starting Brightness
description: Initial brightness percentage (0-100)
default: 1
selector:
number:
min: 0
max: 100
step: 1
end_brightness:
name: Ending Brightness
description: Final brightness percentage (0-100)
default: 100
selector:
number:
min: 1
max: 100
step: 1
start_temp:
name: Starting Color Temperature
description: Final color temperature in Kelvin
default: 2000
selector:
color_temp:
min: 2000
unit: kelvin
end_temp:
name: Ending Color Temperature
description: Final color temperature in Kelvin
default: 5000
selector:
color_temp:
unit: kelvin
reversed:
name: "Simulate sunset instead of sunrise"
description: If true, reverses the direction (simulates sunset instead of sunrise)
selector:
boolean:
default: false
curve_type:
name: Curve Type
default: "parabolic"
description: “linear”, "parabolic" (quadratic), or “sigmoid” (an S-curve/logistic curve)
selector:
select:
options:
- "linear"
- "sigmoidal"
- "parabolic"
variables:
lights: !input target_lights
start_temp: !input start_temp
end_temp: !input end_temp
curve_type: !input curve_type
total_duration: !input total_duration
num_steps: !input steps
step_delay: "{{ (total_duration * 60 / num_steps) | round(0) }}"
start_bright: !input start_brightness
end_bright: !input end_brightness
reversed: !input reversed
# Loop through each step of the curve
sequence:
- repeat:
count: "{{ num_steps }}"
sequence:
- variables:
# Calculate current step (0 to 1 range)
x: "{{ (repeat.index - 1) / (num_steps - 1) }}"
# Reflects the curve in the y-axis if reversed is true
- choose:
- conditions:
- condition: template
value_template: "{{ reversed }}"
sequence:
- variables:
x: "{{ 1 - x }}"
- variables:
curve_func: >
{%- if curve_type == 'linear' -%}
{{ x }}
{%- elif curve_type == 'sigmoidal' -%}
{{ 1 / (1 + (2.71828 ** (-12 * (x - 0.5)))) }}
{%- elif curve_type == 'parabolic' -%}
{{ x ** 2 }}
{%- endif -%}
# Map result to brightness range and color temperature range respectively
current_brightness: "{{ (start_bright + (end_bright - start_bright) * curve_func | float) | round(0) }}"
current_color_temp: "{{ (start_temp + (end_temp - start_temp) * curve_func | float) | round(0) }}"
- service: light.turn_on
target: !input target_lights
data:
brightness_pct: "{{ current_brightness }}"
kelvin: "{{ current_color_temp }}"
transition: "{{ step_delay }}"
- delay: "{{ step_delay }}"