Compare commits
2 Commits
cd5508e81d
...
95779d9805
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95779d9805 | ||
|
|
3bc8a71d67 |
116
README.md
116
README.md
@@ -1,7 +1,113 @@
|
|||||||
# ha-sunrise-alarm
|
|
||||||
|
|
||||||
A HomeAssistant blueprint that turns your smart lights into a natural alarm clock.
|
# Home‑Assistant Sunrise Alarm
|
||||||
|
**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)
|
||||||
</a>
|
2. [Two‑step installation](#two‑step-installation)
|
||||||
|
* 2.1 [sunrise‑simulation](#sunrise‑simulation)
|
||||||
|
* 2.2 [sunrise‑alarm](#sunrise‑alarm)
|
||||||
|
3. [Configurable variables](#configurable-variables)
|
||||||
|
* 3.1 `sunrise‑simulation` script variables
|
||||||
|
* 3.2 `sunrise‑alarm` 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 |
|
||||||
|
|-----------|---------|--------------|
|
||||||
|
| **sunrise‑simulation** (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. |
|
||||||
|
| **sunrise‑alarm** (automation) | The “scheduler” that calls the simulation at a chosen time | Triggers the script at *Alarm Time – Offset* (e.g. 30 min 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 “sunset‑in‑30‑min” routine). The alarm automation is a thin wrapper that turns that simulation into a timed alarm.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Installation
|
||||||
|
|
||||||
|
### 2.1 sunrise‑simulation
|
||||||
|
|
||||||
|
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 sunrise‑simulation">
|
||||||
|
</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).
|
||||||
|
* You’ll be asked for a handful of variables – see section 3.1 for the defaults and meaning.
|
||||||
|
* Click **Create** – Home‑Assistant will add a script entity called `script.sunrise-simulation` (or whatever name you gave it).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.2 sunrise‑alarm
|
||||||
|
|
||||||
|
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 sunrise‑alarm">
|
||||||
|
</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 `sunrise‑simulation` script you created in the previous step for the `alarm_script` field.
|
||||||
|
* Save – you now have a ready‑to‑run alarm!
|
||||||
|
|
||||||
|
> **Tip** – If you want a *sunset* alarm, simply copy the `sunrise‑simulation` 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.3 Configurable variables
|
||||||
|
|
||||||
|
### 3.1 sunrise‑simulation 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.2 sunrise‑alarm 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 `sunrise‑simulation` blueprint (`script.sunrise-simulation`). |
|
||||||
|
|
||||||
|
The automation uses the following logic:
|
||||||
|
|
||||||
|
1. `Alarm Time – Offset` fires the automation.
|
||||||
|
2. If `Alarm Enabled` is `on`, it calls the sunrise script.
|
||||||
|
3. If `Alarm Enabled` 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.
|
||||||
|
|||||||
@@ -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
141
sunrise-simulation.yaml
Normal 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 }}"
|
||||||
Reference in New Issue
Block a user