mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-10 13:54:04 +02:00
Add documentation site with Zensical framework (#1385)
* Add documentation site with Zensical framework
Create comprehensive documentation site for adaptive-lighting.nijho.lt:
- Add zensical.toml configuration with Material theme (amber/orange)
- Create docs_gen.py module for extracting README sections via markers
- Add section markers to README.md for content reuse
- Create documentation pages:
- index.md: Home with features overview
- getting-started.md: Installation and quick setup
- configuration.md: Auto-generated config options table
- services.md: Auto-generated service documentation
- automation-examples.md: Real-world automation recipes
- troubleshooting.md: Common issues and solutions
- see-also.md: External resources and links
- advanced/brightness-modes.md: Brightness mode deep dive
- advanced/manual-control.md: Manual control system docs
- advanced/sleep-mode.md: Sleep mode configuration
- Add GitHub Actions workflow for building and deploying to Pages
- Add custom CSS with sun-themed styling
- Add CNAME for custom domain
Uses markdown-code-runner to auto-generate content from code schemas
and extract README sections for single-source documentation.
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Remove duplicated content from docs, make pages thin wrappers
- troubleshooting.md: Remove manually written "Additional Tips" section
- automation-examples.md: Remove duplicate "Additional Examples" section
- configuration.md: Remove duplicate "Option Categories" tables
- sleep-mode.md: Simplify to reference main config, remove duplicate examples
- docs_gen.py: Remove unused get_troubleshooting() and get_sleep_mode_intro()
This reduces duplication risk by keeping README as single source of truth.
Docs pages now primarily pull content via markdown-code-runner.
* [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
* Integrate webapp (simulator) into docs workflow
- Merge deploy-webapp.yml into docs.yml workflow
- Build simulator and place at /simulator/ subdirectory
- Update docs links to use relative paths to simulator
- Remove separate deploy-webapp.yml to avoid conflicts
The combined workflow now:
1. Builds docs with zensical
2. Builds webapp with shinylive
3. Copies webapp to site/simulator/
4. Deploys everything to GitHub Pages
Simulator will be at adaptive-lighting.nijho.lt/simulator/
* Fix pre-commit and CI issues
- Add site_name to zensical.toml (required by MkDocs)
- Fix RET504 in docs_gen.py (unnecessary assignment before return)
- Remove docs/run_markdown_code_runner.py (lint issues, not needed for CI)
* Fix _docs_helpers.py import error in CI
- Add try/except for relative vs absolute imports in _docs_helpers.py
- Remove silent error handling in docs workflow (fail on error)
The relative import fails when markdown-code-runner executes the code
directly via sys.path.insert. The fallback to absolute import fixes this.
* Temporarily enable deployment from feature branch
* Add tabulate dependency for pandas to_markdown()
* Fix theme configuration for proper light/dark mode
- Restructure zensical.toml to match working agent-cli config
- Add three-way palette toggle (system/light/dark)
- Use proper [project.theme] structure
- Simplify extra.css to not override theme colors
- Add Inter font for text, JetBrains Mono for code
* Add Plausible analytics and fix homepage navigation
- Add custom analytics override for plausible.nijho.lt tracking
- Remove hide:navigation from index.md to show menu on homepage
* Remove temporary feature branch deployment settings
Revert to main-only deployment for docs workflow before merging.
* Revert "Remove temporary feature branch deployment settings"
This reverts commit c568694837.
* Add markdown-gfm-admonition for GitHub-style admonitions
The zensical build was failing silently because gfm_admonition extension
was not installed. Add the dependency to pyproject.toml and docs workflow.
* Use uv sync for documentation dependencies
Switch from manual pip installs to uv sync with pyproject.toml for cleaner
dependency management and reproducible builds.
* Fix markdown rendering inside details blocks
Enable md_in_html extension and add markdown="1" attribute to <details>
tags so markdown content inside them is properly rendered.
* Remove emojis from manually written documentation
Keep emojis in auto-generated content from README, but remove from
manually maintained docs in favor of clean text and Material icons.
* Enable attr_list extension for button styling
* Improve pyproject.toml and use GitHub-style admonitions
- Add accurate project metadata (version, authors, classifiers, URLs)
- Organize dependency groups: docs, dev, test
- Add tool configs for ruff, mypy, pytest
- Convert MkDocs-style admonitions (!!! tip) to GitHub-style (> [!TIP])
- Use docs group in CI workflow
* Add homeassistant and ulid-transform as runtime dependencies
Remove speculative test dependencies since tests run inside HA core.
* Simplify docs_gen.py - remove wrapper functions
Use readme_section() directly in docs instead of 10 one-liner wrappers.
Changed default strip_heading to True since that's the common case.
* Populate empty OUTPUT sections with markdown-code-runner
* Add markdown-code-runner workflow for auto-updating docs
- Add docs/run_markdown_code_runner.py script to process all docs
- Add GitHub workflow to run on push/PR and auto-commit changes
* Exclude README.md from markdown-code-runner workflow
README.md contains code blocks that import from
homeassistant.components.adaptive_lighting, which only exists
when running inside Home Assistant core, not in a regular venv.
* Update auto-generated docs
* Use editable install for markdown-code-runner workflow
- Add setuptools.packages.find config pointing to custom_components
- Remove sys.path.insert manipulation from all docs files
- Update imports to use adaptive_lighting.* package paths
- Install package with `uv pip install -e .` in workflow
- Remove deprecated license classifier (PEP 639)
* Consolidate markdown-code-runner into single workflow
- Remove separate markdown-code-runner.yml workflow
- Update update-readme.yml to handle all markdown files (docs + README)
- Rename workflow to "Update auto-generated content"
- Update README imports to use adaptive_lighting package path
* Rename workflow to markdown-code-runner
* Remove accidentally committed files
* Remove redundant markdown-code-runner from docs workflow
* Fix: use uv pip install instead of uv add in CI
* Add webapp deps (astral, shinylive) to docs group
* Remove unused install_dependencies action
* Update to latest action versions (uv@v5, upload-pages-artifact@v4)
* Remove try/except import fallback in _docs_helpers.py
* Restore install_dependencies action (used by pytest)
* Simplify docs workflow: run on all pushes/PRs
* Simplify mcr workflow paths; revert install_dependencies to main
* Remove redundant cp+sed for webapp (file already in repo)
* Fix mcr push: pull --rebase before push
* Fix mcr: checkout PR branch instead of detached HEAD
* Update auto-generated content
* Switch from setuptools to hatch build system
Replace [tool.setuptools.packages.find] with [tool.hatch.build.targets.wheel]
for hatchling compatibility.
* Update auto-generated content
* Move homeassistant deps to docs group
This is a HA custom component, not a pip package. The homeassistant
dependency is only needed for docs building, not as a project dependency.
* Update auto-generated content
* Remove PyPI-only metadata from pyproject.toml
* Remove arbitrary version constraints from dependency groups
* Update auto-generated content
* Remove unused troubleshooting section markers from README
* Remove temporary feature branch settings from docs workflow
* Use GitHub admonition syntax for warning in change_switch_settings section
* Update auto-generated content
This commit is contained in:
parent
e0f812d406
commit
cbbcabdd1f
23 changed files with 7816 additions and 145 deletions
63
.github/workflows/deploy-webapp.yml
vendored
63
.github/workflows/deploy-webapp.yml
vendored
|
|
@ -1,63 +0,0 @@
|
|||
# Simple workflow for deploying WebAssembly app to GitHub Pages
|
||||
name: Deploy WebAssembly app to Pages
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Single deploy job since we're just deploying
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Set Up Python
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.14.2
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
pip install -r webapp/requirements.txt
|
||||
pip install shinylive
|
||||
|
||||
- name: Build the WebAssembly app
|
||||
run: |
|
||||
set -ex
|
||||
cp custom_components/adaptive_lighting/color_and_brightness.py webapp/color_and_brightness.py
|
||||
sed -i 's/homeassistant.util.color/homeassistant_util_color/g' "webapp/color_and_brightness.py"
|
||||
shinylive export webapp site
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
with:
|
||||
# Upload the 'site' directory, where your app has been built
|
||||
path: "site"
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
64
.github/workflows/docs.yml
vendored
Normal file
64
.github/workflows/docs.yml
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
name: Documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
|
||||
- name: Install dependencies
|
||||
run: uv sync --group docs
|
||||
|
||||
- name: Build documentation
|
||||
run: uv run zensical build
|
||||
|
||||
- name: Build webapp (simulator)
|
||||
run: uv run shinylive export webapp webapp-site
|
||||
|
||||
- name: Integrate webapp into docs
|
||||
run: |
|
||||
# Copy webapp into docs site at /simulator/
|
||||
mkdir -p site/simulator
|
||||
cp -r webapp-site/* site/simulator/
|
||||
echo "Webapp integrated at site/simulator/"
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
with:
|
||||
path: ./site
|
||||
|
||||
deploy:
|
||||
if: github.ref == 'refs/heads/main' && github.event_name != 'pull_request'
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
|
|
@ -1,33 +1,34 @@
|
|||
name: Update README.md, strings.json, and services.yaml
|
||||
name: markdown-code-runner
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- "README.md"
|
||||
- "custom_components/adaptive_lighting/const.py"
|
||||
- ".github/workflows/update-readme.yml"
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
update_readme:
|
||||
markdown-code-runner:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ github.head_ref }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install Home Assistant
|
||||
uses: ./.github/workflows/install_dependencies
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.13"
|
||||
|
||||
- name: Install markdown-code-runner and README code dependencies
|
||||
run: |
|
||||
uv pip install markdown-code-runner==2.1.0 pandas tabulate
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
|
||||
- name: Run markdown-code-runner
|
||||
run: uv run markdown-code-runner --verbose README.md
|
||||
run: |
|
||||
uv sync --group docs
|
||||
uv pip install -e .
|
||||
uv run python docs/run_markdown_code_runner.py
|
||||
|
||||
- name: Run update services.yaml
|
||||
run: uv run python .github/update-services.py
|
||||
|
|
@ -35,23 +36,22 @@ jobs:
|
|||
- name: Run update strings.json
|
||||
run: uv run python .github/update-strings.py
|
||||
|
||||
- name: Commit updated README.md, strings.json, and services.yaml
|
||||
- name: Commit updated files
|
||||
id: commit
|
||||
run: |
|
||||
git add -u .
|
||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
if git diff --quiet && git diff --staged --quiet; then
|
||||
echo "No changes in README.md, strings.json, and services.yaml, skipping commit."
|
||||
echo "No changes, skipping commit."
|
||||
echo "commit_status=skipped" >> $GITHUB_ENV
|
||||
else
|
||||
git commit -m "Update README.md, strings.json, and services.yaml"
|
||||
git commit -m "Update auto-generated content"
|
||||
echo "commit_status=committed" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Push changes
|
||||
if: env.commit_status == 'committed'
|
||||
uses: ad-m/github-push-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ github.head_ref }}
|
||||
run: |
|
||||
git pull --rebase
|
||||
git push
|
||||
146
README.md
146
README.md
|
|
@ -24,6 +24,7 @@ https://github.com/basnijholt/adaptive-lighting/assets/6897215/68908f7d-fbf1-499
|
|||
|
||||
[[ToC](#books-table-of-contents)]
|
||||
|
||||
<!-- SECTION:features:START -->
|
||||
## :bulb: Features
|
||||
|
||||
When initially turning on a light that is controlled by Adaptive Lighting, the `light.turn_on` service call is intercepted, and the light's brightness and color are automatically adjusted based on the sun's position.
|
||||
|
|
@ -35,7 +36,9 @@ Adaptive Lighting provides four switches (using "living_room" as an example comp
|
|||
- `switch.adaptive_lighting_sleep_mode_living_room`: Activate "sleep mode" 😴 and set custom sleep_brightness and sleep_color_temp.
|
||||
- `switch.adaptive_lighting_adapt_brightness_living_room`: Enable or disable brightness adaptation 🔆 for supported lights.
|
||||
- `switch.adaptive_lighting_adapt_color_living_room`: Enable or disable color adaptation 🌈 for supported lights.
|
||||
<!-- SECTION:features:END -->
|
||||
|
||||
<!-- SECTION:manual-control:START -->
|
||||
### :control_knobs: Regain Manual Control
|
||||
|
||||
Adaptive Lighting is designed to automatically detect when you or another source (e.g., automation) manually changes light settings 🕹️.
|
||||
|
|
@ -46,6 +49,7 @@ Additionally, enabling `detect_non_ha_changes` allows Adaptive Lighting to detec
|
|||
The `adaptive_lighting.manual_control` event is fired when a light is marked as "manually controlled," allowing for integration with automations 🤖.
|
||||
|
||||
> ⚠️ **_Caution: Some lights might falsely indicate an 'on' state, which could result in lights turning on unexpectedly. Disable `detect_non_ha_changes` if you encounter such issues._**
|
||||
<!-- SECTION:manual-control:END -->
|
||||
|
||||
## :books: Table of Contents
|
||||
|
||||
|
|
@ -99,56 +103,57 @@ All of the configuration options are listed below, along with their default valu
|
|||
The YAML and frontend configuration methods support all of the options listed below.
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from homeassistant.components.adaptive_lighting import _docs_helpers -->
|
||||
<!-- print(_docs_helpers.generate_config_markdown_table()) -->
|
||||
<!-- from adaptive_lighting._docs_helpers import generate_config_markdown_table -->
|
||||
<!-- print(generate_config_markdown_table()) -->
|
||||
<!-- CODE:END -->
|
||||
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
| Variable name | Description | Default | Type |
|
||||
|:-------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------|:----------------------------------------|
|
||||
| `lights` | List of light entity_ids to be controlled (may be empty). 🌟 | `[]` | list of `entity_id`s |
|
||||
| `interval` | Frequency to adapt the lights, in seconds. 🔄 | `90` | `int > 0` |
|
||||
| `transition` | Duration of transition when lights change, in seconds. 🕑 | `45` | `float` 0-6553 |
|
||||
| `initial_transition` | Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️ | `1` | `float` 0-6553 |
|
||||
| `min_brightness` | Minimum brightness percentage. 💡 | `1` | `int` 1-100 |
|
||||
| `max_brightness` | Maximum brightness percentage. 💡 | `100` | `int` 1-100 |
|
||||
| `min_color_temp` | Warmest color temperature in Kelvin. 🔥 | `2000` | `int` 1000-10000 |
|
||||
| `max_color_temp` | Coldest color temperature in Kelvin. ❄️ | `5500` | `int` 1000-10000 |
|
||||
| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | `False` | `bool` |
|
||||
| `sleep_brightness` | Brightness percentage of lights in sleep mode. 😴 | `1` | `int` 1-100 |
|
||||
| `sleep_rgb_or_color_temp` | Use either `"rgb_color"` or `"color_temp"` in sleep mode. 🌙 | `color_temp` | one of `['color_temp', 'rgb_color']` |
|
||||
| `sleep_color_temp` | Color temperature in sleep mode (used when `sleep_rgb_or_color_temp` is `color_temp`) in Kelvin. 😴 | `1000` | `int` 1000-10000 |
|
||||
| `sleep_rgb_color` | RGB color in sleep mode (used when `sleep_rgb_or_color_temp` is "rgb_color"). 🌈 | `[255, 56, 0]` | RGB color |
|
||||
| `sleep_transition` | Duration of transition when "sleep mode" is toggled in seconds. 😴 | `1` | `float` 0-6553 |
|
||||
| `transition_until_sleep` | When enabled, Adaptive Lighting will treat sleep settings as the minimum, transitioning to these values after sunset. 🌙 | `False` | `bool` |
|
||||
| `sunrise_time` | Set a fixed time (HH:MM:SS) for sunrise. 🌅 | `None` | `str` |
|
||||
| `min_sunrise_time` | Set the earliest virtual sunrise time (HH:MM:SS), allowing for later sunrises. 🌅 | `None` | `str` |
|
||||
| `max_sunrise_time` | Set the latest virtual sunrise time (HH:MM:SS), allowing for earlier sunrises. 🌅 | `None` | `str` |
|
||||
| `sunrise_offset` | Adjust sunrise time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
|
||||
| `sunset_time` | Set a fixed time (HH:MM:SS) for sunset. 🌇 | `None` | `str` |
|
||||
| `min_sunset_time` | Set the earliest virtual sunset time (HH:MM:SS), allowing for later sunsets. 🌇 | `None` | `str` |
|
||||
| `max_sunset_time` | Set the latest virtual sunset time (HH:MM:SS), allowing for earlier sunsets. 🌇 | `None` | `str` |
|
||||
| `sunset_offset` | Adjust sunset time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
|
||||
| `brightness_mode` | Brightness mode to use. Possible values are `default`, `linear`, and `tanh` (uses `brightness_mode_time_dark` and `brightness_mode_time_light`). 📈 | `default` | one of `['default', 'linear', 'tanh']` |
|
||||
| Variable name | Description | Default | Type |
|
||||
|:-------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------|:----------------------------------------|
|
||||
| `lights` | List of light entity_ids to be controlled (may be empty). 🌟 | `[]` | list of `entity_id`s |
|
||||
| `interval` | Frequency to adapt the lights, in seconds. 🔄 | `90` | `int > 0` |
|
||||
| `transition` | Duration of transition when lights change, in seconds. 🕑 | `45` | `float` 0-6553 |
|
||||
| `initial_transition` | Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️ | `1` | `float` 0-6553 |
|
||||
| `min_brightness` | Minimum brightness percentage. 💡 | `1` | `int` 1-100 |
|
||||
| `max_brightness` | Maximum brightness percentage. 💡 | `100` | `int` 1-100 |
|
||||
| `min_color_temp` | Warmest color temperature in Kelvin. 🔥 | `2000` | `int` 1000-10000 |
|
||||
| `max_color_temp` | Coldest color temperature in Kelvin. ❄️ | `5500` | `int` 1000-10000 |
|
||||
| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | `False` | `bool` |
|
||||
| `sleep_brightness` | Brightness percentage of lights in sleep mode. 😴 | `1` | `int` 1-100 |
|
||||
| `sleep_rgb_or_color_temp` | Use either `"rgb_color"` or `"color_temp"` in sleep mode. 🌙 | `color_temp` | one of `['color_temp', 'rgb_color']` |
|
||||
| `sleep_color_temp` | Color temperature in sleep mode (used when `sleep_rgb_or_color_temp` is `color_temp`) in Kelvin. 😴 | `1000` | `int` 1000-10000 |
|
||||
| `sleep_rgb_color` | RGB color in sleep mode (used when `sleep_rgb_or_color_temp` is "rgb_color"). 🌈 | `[255, 56, 0]` | RGB color |
|
||||
| `sleep_transition` | Duration of transition when "sleep mode" is toggled in seconds. 😴 | `1` | `float` 0-6553 |
|
||||
| `transition_until_sleep` | When enabled, Adaptive Lighting will treat sleep settings as the minimum, transitioning to these values after sunset. 🌙 | `False` | `bool` |
|
||||
| `sunrise_time` | Set a fixed time (HH:MM:SS) for sunrise. 🌅 | `None` | `str` |
|
||||
| `min_sunrise_time` | Set the earliest virtual sunrise time (HH:MM:SS), allowing for later sunrises. 🌅 | `None` | `str` |
|
||||
| `max_sunrise_time` | Set the latest virtual sunrise time (HH:MM:SS), allowing for earlier sunrises. 🌅 | `None` | `str` |
|
||||
| `sunrise_offset` | Adjust sunrise time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
|
||||
| `sunset_time` | Set a fixed time (HH:MM:SS) for sunset. 🌇 | `None` | `str` |
|
||||
| `min_sunset_time` | Set the earliest virtual sunset time (HH:MM:SS), allowing for later sunsets. 🌇 | `None` | `str` |
|
||||
| `max_sunset_time` | Set the latest virtual sunset time (HH:MM:SS), allowing for earlier sunsets. 🌇 | `None` | `str` |
|
||||
| `sunset_offset` | Adjust sunset time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
|
||||
| `brightness_mode` | Brightness mode to use. Possible values are `default`, `linear`, and `tanh` (uses `brightness_mode_time_dark` and `brightness_mode_time_light`). 📈 | `default` | one of `['default', 'linear', 'tanh']` |
|
||||
| `brightness_mode_time_dark` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness before/after sunrise/sunset. 📈📉 | `900` | `int` |
|
||||
| `brightness_mode_time_light` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness after/before sunrise/sunset. 📈📉. | `3600` | `int` |
|
||||
| `take_over_control` | Pause adaptation of individual lights and hand over (manual) control to other sources that issue `light.turn_on` calls for lights that are on. 🔒 | `True` | `bool` |
|
||||
| `take_over_control_mode` | The adaptation pausing mode when other sources change brightness and/or color of lights. `pause_all` always pauses both brightness and color adaptation. `pause_changed` pauses the adaptation of only the changed attributes and continues adapting unchanged attributes, e.g., continues color adaptation when only brightness was changed. | `pause_all` | one of `['pause_all', 'pause_changed']` |
|
||||
| `detect_non_ha_changes` | Detects and halts adaptations for non-`light.turn_on` state changes. Needs `take_over_control` enabled. 🕵️ Caution: ⚠️ Some lights might falsely indicate an 'on' state, which could result in lights turning on unexpectedly. Note that this calls `homeassistant.update_entity` every `interval`! Disable this feature if you encounter such issues. | `False` | `bool` |
|
||||
| `autoreset_control_seconds` | Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️ | `0` | `int` 0-31536000 |
|
||||
| `only_once` | Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄 | `False` | `bool` |
|
||||
| `take_over_control` | Pause adaptation of individual lights and hand over (manual) control to other sources that issue `light.turn_on` calls for lights that are on. 🔒 | `True` | `bool` |
|
||||
| `take_over_control_mode` | The adaptation pausing mode when other sources change brightness and/or color of lights. `pause_all` always pauses both brightness and color adaptation. `pause_changed` pauses the adaptation of only the changed attributes and continues adapting unchanged attributes, e.g., continues color adaptation when only brightness was changed. | `pause_all` | one of `['pause_all', 'pause_changed']` |
|
||||
| `detect_non_ha_changes` | Detects and halts adaptations for non-`light.turn_on` state changes. Needs `take_over_control` enabled. 🕵️ Caution: ⚠️ Some lights might falsely indicate an 'on' state, which could result in lights turning on unexpectedly. Note that this calls `homeassistant.update_entity` every `interval`! Disable this feature if you encounter such issues. | `False` | `bool` |
|
||||
| `autoreset_control_seconds` | Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️ | `0` | `int` 0-31536000 |
|
||||
| `only_once` | Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄 | `False` | `bool` |
|
||||
| `adapt_only_on_bare_turn_on` | When turning lights on initially. If set to `true`, AL adapts only if `light.turn_on` is invoked without specifying color or brightness. ❌🌈 This e.g., prevents adaptation when activating a scene and marks the light as manually controlled. If `false`, AL adapts regardless of the presence of color or brightness in the initial `service_data`. Needs `take_over_control` enabled. 🕵️ | `False` | `bool` |
|
||||
| `separate_turn_on_commands` | Use separate `light.turn_on` calls for color and brightness, needed for some light types. 🔀 | `False` | `bool` |
|
||||
| `send_split_delay` | Delay (ms) between `separate_turn_on_commands` for lights that don't support simultaneous brightness and color setting. ⏲️ | `0` | `int` 0-10000 |
|
||||
| `adapt_delay` | Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️ | `0` | `float > 0` |
|
||||
| `skip_redundant_commands` | Skip sending adaptation commands whose target state already equals the light's known state. Minimizes network traffic and improves the adaptation responsivity in some situations. 📉Disable if physical light states get out of sync with HA's recorded state. | `False` | `bool` |
|
||||
| `intercept` | Intercept and adapt `light.turn_on` calls to enabling instantaneous color and brightness adaptation. 🏎️ Disable for lights that do not support `light.turn_on` with color and brightness. | `True` | `bool` |
|
||||
| `multi_light_intercept` | Intercept and adapt `light.turn_on` calls that target multiple lights. ➗⚠️ This might result in splitting up a single `light.turn_on` call into multiple calls, e.g., when lights are in different switches. Requires `intercept` to be enabled. | `True` | `bool` |
|
||||
| `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` |
|
||||
| `separate_turn_on_commands` | Use separate `light.turn_on` calls for color and brightness, needed for some light types. 🔀 | `False` | `bool` |
|
||||
| `send_split_delay` | Delay (ms) between `separate_turn_on_commands` for lights that don't support simultaneous brightness and color setting. ⏲️ | `0` | `int` 0-10000 |
|
||||
| `adapt_delay` | Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️ | `0` | `float > 0` |
|
||||
| `skip_redundant_commands` | Skip sending adaptation commands whose target state already equals the light's known state. Minimizes network traffic and improves the adaptation responsivity in some situations. 📉Disable if physical light states get out of sync with HA's recorded state. | `False` | `bool` |
|
||||
| `intercept` | Intercept and adapt `light.turn_on` calls to enabling instantaneous color and brightness adaptation. 🏎️ Disable for lights that do not support `light.turn_on` with color and brightness. | `True` | `bool` |
|
||||
| `multi_light_intercept` | Intercept and adapt `light.turn_on` calls that target multiple lights. ➗⚠️ This might result in splitting up a single `light.turn_on` call into multiple calls, e.g., when lights are in different switches. Requires `intercept` to be enabled. | `True` | `bool` |
|
||||
| `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` |
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
<!-- SECTION:config-example-full:START -->
|
||||
Full example:
|
||||
|
||||
```yaml
|
||||
|
|
@ -175,6 +180,7 @@ adaptive_lighting:
|
|||
only_once: false
|
||||
|
||||
```
|
||||
<!-- SECTION:config-example-full:END -->
|
||||
|
||||
### :hammer_and_wrench: Services
|
||||
|
||||
|
|
@ -183,21 +189,21 @@ adaptive_lighting:
|
|||
`adaptive_lighting.apply` applies Adaptive Lighting settings to lights on demand.
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from homeassistant.components.adaptive_lighting import _docs_helpers -->
|
||||
<!-- print(_docs_helpers.generate_apply_markdown_table()) -->
|
||||
<!-- from adaptive_lighting._docs_helpers import generate_apply_markdown_table -->
|
||||
<!-- print(generate_apply_markdown_table()) -->
|
||||
<!-- CODE:END -->
|
||||
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
| Service data attribute | Description | Required | Type |
|
||||
|:-------------------------|:-------------------------------------------------------------------------------------|:-----------|:---------------------|
|
||||
| `entity_id` | The `entity_id` of the switch with the settings to apply. 📝 | ✅ | list of `entity_id`s |
|
||||
| `lights` | A light (or list of lights) to apply the settings to. 💡 | ❌ | list of `entity_id`s |
|
||||
| `transition` | Duration of transition when lights change, in seconds. 🕑 | ❌ | `float` 0-6553 |
|
||||
| `adapt_brightness` | Whether to adapt the brightness of the light. 🌞 | ❌ | bool |
|
||||
| `adapt_color` | Whether to adapt the color on supporting lights. 🌈 | ❌ | bool |
|
||||
| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | ❌ | bool |
|
||||
| `turn_on_lights` | Whether to turn on lights that are currently off. 🔆 | ❌ | bool |
|
||||
| Service data attribute | Description | Required | Type |
|
||||
|:-------------------------|:--------------------------------------------------------------------------------------|:-----------|:---------------------|
|
||||
| `entity_id` | The `entity_id` of the switch with the settings to apply. 📝 | ✅ | list of `entity_id`s |
|
||||
| `lights` | A light (or list of lights) to apply the settings to. 💡 | ❌ | list of `entity_id`s |
|
||||
| `transition` | Duration of transition when lights change, in seconds. 🕑 | ❌ | `float` 0-6553 |
|
||||
| `adapt_brightness` | Whether to adapt the brightness of the light. 🌞 | ❌ | bool |
|
||||
| `adapt_color` | Whether to adapt the color on supporting lights. 🌈 | ❌ | bool |
|
||||
| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | ❌ | bool |
|
||||
| `turn_on_lights` | Whether to turn on lights that are currently off. 🔆 | ❌ | bool |
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
#### `adaptive_lighting.set_manual_control`
|
||||
|
|
@ -205,24 +211,27 @@ adaptive_lighting:
|
|||
`adaptive_lighting.set_manual_control` can mark (or unmark) whether a light is "manually controlled", meaning that when a light has `manual_control`, the light is not adapted.
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from homeassistant.components.adaptive_lighting import _docs_helpers -->
|
||||
<!-- print(_docs_helpers.generate_set_manual_control_markdown_table()) -->
|
||||
<!-- from adaptive_lighting._docs_helpers import generate_set_manual_control_markdown_table -->
|
||||
<!-- print(generate_set_manual_control_markdown_table()) -->
|
||||
<!-- CODE:END -->
|
||||
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
| Service data attribute | Description | Required | Type |
|
||||
|:-------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------|:-----------------------------------------|
|
||||
| `entity_id` | The `entity_id` of the switch in which to (un)mark the light as being `manually controlled`. 📝 | ✅ | list of `entity_id`s |
|
||||
| `lights` | entity_id(s) of lights, if not specified, all lights in the switch are selected. 💡 | ❌ | list of `entity_id`s |
|
||||
| `manual_control` | Whether to add ("true") or remove ("false") all adapted attributes of the light from the "manual_control" list, or the name of an attribute for selective addition. 🔒 | ❌ | bool or one of `['brightness', 'color']` |
|
||||
| Service data attribute | Description | Required | Type |
|
||||
|:-------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------|:-----------------------------------------|
|
||||
| `entity_id` | The `entity_id` of the switch in which to (un)mark the light as being `manually controlled`. 📝 | ✅ | list of `entity_id`s |
|
||||
| `lights` | entity_id(s) of lights, if not specified, all lights in the switch are selected. 💡 | ❌ | list of `entity_id`s |
|
||||
| `manual_control` | Whether to add ("true") or remove ("false") all adapted attributes of the light from the "manual_control" list, or the name of an attribute for selective addition. 🔒 | ❌ | bool or one of `['brightness', 'color']` |
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
<!-- SECTION:change-switch-settings:START -->
|
||||
#### `adaptive_lighting.change_switch_settings`
|
||||
|
||||
`adaptive_lighting.change_switch_settings` (new in 1.7.0) Change any of the above configuration options of Adaptive Lighting (such as `sunrise_time` or `prefer_rgb_color`) with a service call directly from your script/automation.
|
||||
|
||||
> ⚠️ **_Note: These settings will **not** be written to your config and will be reset on restart of Home Assistant! You can see the current settings in the `switch.adaptive_lighting_XXX` attributes if `include_config_in_attributes` is enabled._**
|
||||
> [!WARNING]
|
||||
> These settings will **not** be written to your config and will be reset on restart of Home Assistant! You can see the current settings in the `switch.adaptive_lighting_XXX` attributes if `include_config_in_attributes` is enabled.
|
||||
|
||||
| Service data attribute | Required | Description |
|
||||
| --------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
|
|
@ -237,10 +246,12 @@ The following keys are disallowed:
|
|||
| `lights` | You may call `adaptive_lighting.apply` with your lights or create a new config instead. |
|
||||
| `name` | You can rename your switch's display name in Home Assistant's UI. |
|
||||
| `interval` | The interval is used only once when the config loads. A config change and restart are required. |
|
||||
<!-- SECTION:change-switch-settings:END -->
|
||||
|
||||
<!-- SECTION:automation-examples:START -->
|
||||
## :robot: Automation examples
|
||||
|
||||
<details>
|
||||
<details markdown="1">
|
||||
<summary>Reset the <code>manual_control</code> status of a light after an hour.</summary>
|
||||
|
||||
```yaml
|
||||
|
|
@ -265,7 +276,7 @@ The following keys are disallowed:
|
|||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<details markdown="1">
|
||||
<summary>Toggle multiple Adaptive Lighting switches to "sleep mode" using an <code>input_boolean.sleep_mode</code>.</summary>
|
||||
|
||||
```yaml
|
||||
|
|
@ -336,6 +347,7 @@ iphone_carly_wakeup:
|
|||
```
|
||||
|
||||
</details>
|
||||
<!-- SECTION:automation-examples:END -->
|
||||
|
||||
## Additional Information
|
||||
|
||||
|
|
@ -345,6 +357,7 @@ Adaptive Lighting was initially inspired by @claytonjn's [hass-circadian\_lighti
|
|||
|
||||
## :sos: Troubleshooting
|
||||
|
||||
<!-- SECTION:troubleshooting-intro:START -->
|
||||
Encountering issues? Enable debug logging in your `configuration.yaml`:
|
||||
|
||||
```yaml
|
||||
|
|
@ -355,7 +368,9 @@ logger:
|
|||
```
|
||||
|
||||
After the issue occurs, create a new issue report with the log (`/config/home-assistant.log`).
|
||||
<!-- SECTION:troubleshooting-intro:END -->
|
||||
|
||||
<!-- SECTION:common-problems:START -->
|
||||
### :exclamation: Common Problems & Solutions
|
||||
|
||||
#### :bulb: Lights Not Responding or Turning On by Themselves
|
||||
|
|
@ -413,7 +428,9 @@ These lights are known to exhibit disadvantageous behaviour due to firmware bugs
|
|||
- Ikea Tradfri bulbs/drivers (and related Ikea smart light products)
|
||||
- Unsupported simultaneous transition of brightness and color: When receiving such a command, they switch the brightness instantly and only transition the color. To get smooth transitions of both brightness and color, enable `separate_turn_on_commands`.
|
||||
- Unresponsiveness during color transitions: No other commands are processed during an ongoing color transition, e.g., turn-off commands are ignored and lights stay on despite being reported as off to Home Assistant. The default config with long transitions thus results in long periods of unresponsiveness. To work around this, disable transitions by setting `transition` to `0`, and increase the adaptation frequency by setting `interval` to a short time, e.g., `15` seconds, to retain the impression of smooth continuous adaptations. Keeping the `initial_transition` is recommended for a smooth fade-in (lights are usually not turned off momentarily after being turned on, in which case a short period of unresponsiveness is tolerable).
|
||||
<!-- SECTION:common-problems:END -->
|
||||
|
||||
<!-- SECTION:graphs:START -->
|
||||
## :bar_chart: Graphs!
|
||||
These graphs were generated using the values calculated by the Adaptive Lighting sensor/switch(es).
|
||||
|
||||
|
|
@ -428,10 +445,12 @@ These graphs were generated using the values calculated by the Adaptive Lighting
|
|||
|
||||
### While using `transition_until_sleep: true`
|
||||

|
||||
<!-- SECTION:graphs:END -->
|
||||
|
||||
<!-- SECTION:brightness-modes:START -->
|
||||
### Custom brightness ramps using `brightness_mode` with `"linear"` and `"tanh"`
|
||||
|
||||
<details>
|
||||
<details markdown="1">
|
||||
<summary>Enhance your control over brightness transitions during sunrise and sunset with <code>brightness_mode</code> (click here to learn more 🧠).</summary>
|
||||
|
||||
With Adaptive Lighting, you can set a `brightness_mode` to specify how the brightness changes during sunrise and sunset. The `brightness_mode` can be set to `"default"` ([as illustrated in other graphs above](#high_brightness-brightness)), `"linear"`, or `"tanh"`. If you choose to deviate from the `"default"` mode, you can adjust `brightness_mode_time_dark` and `brightness_mode_time_light` to further customize the lighting transitions.
|
||||
|
|
@ -454,12 +473,15 @@ Notice the values of `brightness_mode_time_light` and `brightness_mode_time_dark
|
|||

|
||||
|
||||
> Check out the interactive webapp on https://basnijholt.github.io/adaptive-lighting/ to play with the parameters and see how the brightness changes!
|
||||
<!-- SECTION:brightness-modes:END -->
|
||||
|
||||
<!-- SECTION:see-also:START -->
|
||||
## :eyes: See also
|
||||
|
||||
- [*Sleep better with Adaptive Lighting in Home Assistant*](https://wartner.io/sleep-better-with-adaptive-lightning-in-home-assistant/) by Florian Wartner on 2023-02-23 (blog post 📜)
|
||||
- [*Automatic smart light brightness and color based on the sun*](https://www.youtube.com/watch?v=Rg3zI1Oyk3c) by Home Automation Guy on 2022-08-31 (YouTube video 📺)
|
||||
- [*Adaptive Lighting Blew My Mind in Home Assistant - How to set it up*](https://www.youtube.com/watch?v=c1cnccmgl3k) by Smart Home Junkie on 2022-06-26 (YouTube video 📺)
|
||||
<!-- SECTION:see-also:END -->
|
||||
|
||||
## :busts_in_silhouette: Contributors
|
||||
|
||||
|
|
|
|||
84
custom_components/adaptive_lighting/docs_gen.py
Normal file
84
custom_components/adaptive_lighting/docs_gen.py
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
"""Documentation generation utilities for Adaptive Lighting.
|
||||
|
||||
Provides functions to extract sections from README.md and transform
|
||||
content for the documentation site. Used by markdown-code-runner
|
||||
to generate documentation pages from README content.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
# Path to README relative to this module
|
||||
_MODULE_DIR = Path(__file__).parent
|
||||
README_PATH = _MODULE_DIR.parent.parent / "README.md"
|
||||
|
||||
|
||||
def readme_section(section_name: str, *, strip_heading: bool = True) -> str:
|
||||
"""Extract a marked section from README.md.
|
||||
|
||||
Sections are marked with HTML comments:
|
||||
<!-- SECTION:section_name:START -->
|
||||
content
|
||||
<!-- SECTION:section_name:END -->
|
||||
|
||||
Args:
|
||||
section_name: The name of the section to extract
|
||||
strip_heading: If True, remove the first heading from the section
|
||||
|
||||
Returns:
|
||||
The content between the section markers
|
||||
|
||||
Raises:
|
||||
ValueError: If the section is not found in README.md
|
||||
|
||||
"""
|
||||
content = README_PATH.read_text()
|
||||
|
||||
start_marker = f"<!-- SECTION:{section_name}:START -->"
|
||||
end_marker = f"<!-- SECTION:{section_name}:END -->"
|
||||
|
||||
start_idx = content.find(start_marker)
|
||||
if start_idx == -1:
|
||||
msg = f"Section '{section_name}' not found in README.md"
|
||||
raise ValueError(msg)
|
||||
|
||||
end_idx = content.find(end_marker, start_idx)
|
||||
if end_idx == -1:
|
||||
msg = f"End marker for section '{section_name}' not found"
|
||||
raise ValueError(msg)
|
||||
|
||||
section = content[start_idx + len(start_marker) : end_idx].strip()
|
||||
|
||||
if strip_heading:
|
||||
# Remove first heading (# or ## or ###)
|
||||
section = re.sub(r"^#{1,3}\s+[^\n]+\n+", "", section, count=1)
|
||||
|
||||
return _transform_readme_links(section)
|
||||
|
||||
|
||||
def _transform_readme_links(content: str) -> str:
|
||||
"""Transform README internal links to docs site links."""
|
||||
# Map README anchors to doc pages
|
||||
link_map = {
|
||||
"#gear-configuration": "configuration.md",
|
||||
"#memo-options": "configuration.md#all-options",
|
||||
"#hammer_and_wrench-services": "services.md",
|
||||
"#adaptive_lightingapply": "services.md#adaptive_lightingapply",
|
||||
"#adaptive_lightingset_manual_control": "services.md#adaptive_lightingset_manual_control",
|
||||
"#adaptive_lightingchange_switch_settings": "services.md#adaptive_lightingchange_switch_settings",
|
||||
"#robot-automation-examples": "automation-examples.md",
|
||||
"#sos-troubleshooting": "troubleshooting.md",
|
||||
"#exclamation-common-problems--solutions": "troubleshooting.md#common-problems-solutions",
|
||||
"#bar_chart-graphs": "advanced/brightness-modes.md#graphs",
|
||||
"#bulb-features": "index.md#features",
|
||||
"#control_knobs-regain-manual-control": "advanced/manual-control.md",
|
||||
"#eyes-see-also": "see-also.md",
|
||||
}
|
||||
|
||||
for old_link, new_link in link_map.items():
|
||||
content = content.replace(f"]({old_link})", f"]({new_link})")
|
||||
|
||||
# Remove ToC link pattern [[ToC](#...)]
|
||||
return re.sub(r"\[\[ToC\]\([^)]+\)\]", "", content)
|
||||
1
docs/CNAME
Normal file
1
docs/CNAME
Normal file
|
|
@ -0,0 +1 @@
|
|||
adaptive-lighting.nijho.lt
|
||||
124
docs/advanced/brightness-modes.md
Normal file
124
docs/advanced/brightness-modes.md
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
---
|
||||
icon: lucide/trending-up
|
||||
---
|
||||
|
||||
# Brightness Modes
|
||||
|
||||
Enhance your control over brightness transitions during sunrise and sunset with the `brightness_mode` option.
|
||||
|
||||
## Available Modes
|
||||
|
||||
Adaptive Lighting supports three brightness modes:
|
||||
|
||||
| Mode | Description |
|
||||
|------|-------------|
|
||||
| `default` | Standard behavior based on sun position |
|
||||
| `linear` | Linear ramp between min/max brightness |
|
||||
| `tanh` | Smooth S-curve using hyperbolic tangent |
|
||||
|
||||
## Detailed Explanation
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting.docs_gen import readme_section -->
|
||||
<!-- print(readme_section("brightness-modes")) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
<details markdown="1">
|
||||
<summary>Enhance your control over brightness transitions during sunrise and sunset with <code>brightness_mode</code> (click here to learn more 🧠).</summary>
|
||||
|
||||
With Adaptive Lighting, you can set a `brightness_mode` to specify how the brightness changes during sunrise and sunset. The `brightness_mode` can be set to `"default"` ([as illustrated in other graphs above](#high_brightness-brightness)), `"linear"`, or `"tanh"`. If you choose to deviate from the `"default"` mode, you can adjust `brightness_mode_time_dark` and `brightness_mode_time_light` to further customize the lighting transitions.
|
||||
|
||||
When `brightness_mode` is set to `"linear"`:
|
||||
|
||||
- During **_sunset_**, the brightness begins to gradually decrease from `max_brightness` starting at `time=sunset_time - brightness_mode_time_light`, until it reaches `min_brightness` at `time=sunset_time + brightness_mode_time_dark`.
|
||||
- During **_sunrise_**, the brightness begins to gradually increase from `min_brightness` starting at `time=sunrise_time - brightness_mode_time_dark`, until it reaches `max_brightness` at `time=sunrise_time + brightness_mode_time_light`.
|
||||
|
||||
When `brightness_mode` is set to `"tanh"`, it uses the smooth transition of a [hyperbolic tangent function](https://mathworld.wolfram.com/HyperbolicTangent.html):
|
||||
|
||||
- During **_sunset_**, the brightness starts to decrease from 95% of `max_brightness` starting at `time=sunset_time - brightness_mode_time_light`, until it reaches 5% of `min_brightness` at `time=sunset_time + brightness_mode_time_dark`.
|
||||
- During **_sunrise_**, the brightness starts to increase from 5% of `min_brightness` starting at `time=sunrise_time - brightness_mode_time_dark`, until it reaches 95% of `max_brightness` at `time=sunrise_time + brightness_mode_time_light`.
|
||||
</details>
|
||||
|
||||
Notice the values of `brightness_mode_time_light` and `brightness_mode_time_dark` in the text box.
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
> Check out the interactive webapp on https://basnijholt.github.io/adaptive-lighting/ to play with the parameters and see how the brightness changes!
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
## Configuration Parameters
|
||||
|
||||
When using `linear` or `tanh` modes, you can fine-tune the transition with these parameters:
|
||||
|
||||
| Parameter | Default | Description |
|
||||
|-----------|---------|-------------|
|
||||
| `brightness_mode_time_dark` | 900 (15 min) | Duration to ramp brightness before/after sunrise/sunset |
|
||||
| `brightness_mode_time_light` | 3600 (1 hour) | Duration to ramp brightness after/before sunrise/sunset |
|
||||
|
||||
## Example Configurations
|
||||
|
||||
### Quick Transition (Linear)
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "Quick transitions"
|
||||
lights:
|
||||
- light.living_room
|
||||
brightness_mode: linear
|
||||
brightness_mode_time_dark: 600 # 10 minutes
|
||||
brightness_mode_time_light: 1800 # 30 minutes
|
||||
```
|
||||
|
||||
### Smooth Transition (Tanh)
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "Smooth transitions"
|
||||
lights:
|
||||
- light.bedroom
|
||||
brightness_mode: tanh
|
||||
brightness_mode_time_dark: 1200 # 20 minutes
|
||||
brightness_mode_time_light: 3600 # 1 hour
|
||||
```
|
||||
|
||||
## Graphs
|
||||
|
||||
These graphs show how brightness changes throughout the day based on calculated values:
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting.docs_gen import readme_section -->
|
||||
<!-- print(readme_section("graphs")) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
These graphs were generated using the values calculated by the Adaptive Lighting sensor/switch(es).
|
||||
|
||||
### :sunny: Sun Position
|
||||

|
||||
|
||||
### :thermometer: Color Temperature
|
||||

|
||||
|
||||
### :high_brightness: Brightness
|
||||

|
||||
|
||||
### While using `transition_until_sleep: true`
|
||||

|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
## Interactive Simulator
|
||||
|
||||
The best way to understand brightness modes is to experiment with the interactive simulator:
|
||||
|
||||
<div style="text-align: center; margin: 2rem 0;">
|
||||
<a href="../simulator/" class="simulator-link">
|
||||
Try the Simulator
|
||||
</a>
|
||||
</div>
|
||||
|
||||
Adjust the `brightness_mode`, `brightness_mode_time_dark`, and `brightness_mode_time_light` parameters to see how they affect the brightness curve in real-time.
|
||||
162
docs/advanced/manual-control.md
Normal file
162
docs/advanced/manual-control.md
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
---
|
||||
icon: lucide/hand
|
||||
---
|
||||
|
||||
# Manual Control
|
||||
|
||||
Adaptive Lighting is designed to work seamlessly with manual adjustments, detecting when you or another source changes light settings and pausing adaptation accordingly.
|
||||
|
||||
## How It Works
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting.docs_gen import readme_section -->
|
||||
<!-- print(readme_section("manual-control")) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
Adaptive Lighting is designed to automatically detect when you or another source (e.g., automation) manually changes light settings 🕹️.
|
||||
When this occurs, the affected light is marked as "manually controlled," and Adaptive Lighting will not make further adjustments until the light is turned off and back on or reset using the `adaptive_lighting.set_manual_control` service call.
|
||||
This feature is available when `take_over_control` is enabled.
|
||||
|
||||
Additionally, enabling `detect_non_ha_changes` allows Adaptive Lighting to detect all state changes, including those made outside of Home Assistant, by comparing the light's state to its previously used settings.
|
||||
The `adaptive_lighting.manual_control` event is fired when a light is marked as "manually controlled," allowing for integration with automations 🤖.
|
||||
|
||||
> ⚠️ **_Caution: Some lights might falsely indicate an 'on' state, which could result in lights turning on unexpectedly. Disable `detect_non_ha_changes` if you encounter such issues._**
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### take_over_control
|
||||
|
||||
When enabled (default: `true`), Adaptive Lighting detects `light.turn_on` service calls that specify brightness or color values. If such a call is detected for a light that's already on, that light is marked as "manually controlled".
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "With manual control detection"
|
||||
lights:
|
||||
- light.living_room
|
||||
take_over_control: true # default
|
||||
```
|
||||
|
||||
### take_over_control_mode
|
||||
|
||||
Controls how adaptation pauses when manual changes are detected:
|
||||
|
||||
| Mode | Behavior |
|
||||
|------|----------|
|
||||
| `pause_all` | Pause both brightness and color adaptation (default) |
|
||||
| `pause_changed` | Only pause adaptation of the changed attribute |
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "Selective pause"
|
||||
lights:
|
||||
- light.living_room
|
||||
take_over_control: true
|
||||
take_over_control_mode: pause_changed # Only pause changed attributes
|
||||
```
|
||||
|
||||
### detect_non_ha_changes
|
||||
|
||||
When enabled, Adaptive Lighting detects state changes made outside of Home Assistant by comparing the light's current state to its previously applied settings.
|
||||
|
||||
> [!WARNING]
|
||||
> **Use with caution.** Some lights may falsely report an "on" state, which could result in lights turning on unexpectedly. Disable this option if you encounter such issues.
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "Detect external changes"
|
||||
lights:
|
||||
- light.living_room
|
||||
take_over_control: true
|
||||
detect_non_ha_changes: true
|
||||
```
|
||||
|
||||
### autoreset_control_seconds
|
||||
|
||||
Automatically resets the manual control flag after a specified number of seconds. Set to `0` to disable (default).
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "Auto-reset after 2 hours"
|
||||
lights:
|
||||
- light.living_room
|
||||
take_over_control: true
|
||||
autoreset_control_seconds: 7200 # 2 hours
|
||||
```
|
||||
|
||||
### adapt_only_on_bare_turn_on
|
||||
|
||||
When enabled, Adaptive Lighting only adapts lights when `light.turn_on` is called without specifying brightness or color. This is useful when you want scenes to work without interference.
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "Respect scenes"
|
||||
lights:
|
||||
- light.living_room
|
||||
take_over_control: true
|
||||
adapt_only_on_bare_turn_on: true
|
||||
```
|
||||
|
||||
## Checking Manual Control Status
|
||||
|
||||
You can see which lights are marked as manually controlled by checking the switch attributes:
|
||||
|
||||
1. Go to **Developer Tools** → **States**
|
||||
2. Find your Adaptive Lighting switch (e.g., `switch.adaptive_lighting_living_room`)
|
||||
3. Look at the `manual_control` attribute - it lists all manually controlled lights
|
||||
|
||||
## Resetting Manual Control
|
||||
|
||||
### Via Service Call
|
||||
|
||||
```yaml
|
||||
service: adaptive_lighting.set_manual_control
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_living_room
|
||||
lights:
|
||||
- light.floor_lamp
|
||||
manual_control: false # Resume adaptation
|
||||
```
|
||||
|
||||
### By Turning Light Off and On
|
||||
|
||||
Simply turning a light off and then back on will reset its manual control status.
|
||||
|
||||
### Via Automation
|
||||
|
||||
See [Automation Examples](../automation-examples.md) for automation recipes that automatically reset manual control.
|
||||
|
||||
## Events
|
||||
|
||||
When a light is marked as manually controlled, Adaptive Lighting fires an event:
|
||||
|
||||
**Event type:** `adaptive_lighting.manual_control`
|
||||
|
||||
**Event data:**
|
||||
```yaml
|
||||
entity_id: light.living_room
|
||||
switch: switch.adaptive_lighting_living_room
|
||||
```
|
||||
|
||||
You can use this event to trigger automations:
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
- alias: "Notify on manual control"
|
||||
trigger:
|
||||
platform: event
|
||||
event_type: adaptive_lighting.manual_control
|
||||
action:
|
||||
- service: notify.mobile_app
|
||||
data:
|
||||
message: "{{ trigger.event.data.entity_id }} was manually adjusted"
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Use Zigbee groups** when controlling multiple bulbs together - this ensures consistent manual control detection
|
||||
2. **Set reasonable autoreset times** if you want lights to eventually resume adaptation
|
||||
3. **Use `pause_changed` mode** if you only adjust brightness or color individually
|
||||
4. **Disable `detect_non_ha_changes`** if you experience unexpected light turn-ons
|
||||
43
docs/advanced/sleep-mode.md
Normal file
43
docs/advanced/sleep-mode.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
icon: lucide/moon
|
||||
---
|
||||
|
||||
# Sleep Mode
|
||||
|
||||
Sleep mode is a special operating mode that sets your lights to minimal brightness and very warm color, perfect for winding down at night without disrupting your circadian rhythm.
|
||||
|
||||
## Activating Sleep Mode
|
||||
|
||||
Each Adaptive Lighting configuration creates a sleep mode switch:
|
||||
|
||||
```
|
||||
switch.adaptive_lighting_sleep_mode_<name>
|
||||
```
|
||||
|
||||
Turn it on to activate sleep mode:
|
||||
|
||||
```yaml
|
||||
service: switch.turn_on
|
||||
target:
|
||||
entity_id: switch.adaptive_lighting_sleep_mode_living_room
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
|
||||
Sleep mode is configured through the main Adaptive Lighting configuration. See the [Configuration](../configuration.md) page for the full options table. The sleep-related options are:
|
||||
|
||||
| Option | Default | Description |
|
||||
|--------|---------|-------------|
|
||||
| `sleep_brightness` | 1 | Brightness percentage in sleep mode |
|
||||
| `sleep_rgb_or_color_temp` | `color_temp` | Use `rgb_color` or `color_temp` in sleep mode |
|
||||
| `sleep_color_temp` | 1000 | Color temperature in Kelvin for sleep mode |
|
||||
| `sleep_rgb_color` | `[255, 56, 0]` | RGB color for sleep mode |
|
||||
| `sleep_transition` | 1 | Transition duration in seconds |
|
||||
| `transition_until_sleep` | false | Gradually transition to sleep settings after sunset |
|
||||
|
||||
## Automation Examples
|
||||
|
||||
See [Automation Examples](../automation-examples.md) for sleep mode automation recipes, including:
|
||||
|
||||
- Toggle sleep mode using an `input_boolean`
|
||||
- Set sunrise/sunset based on alarm time
|
||||
BIN
docs/assets/logo.png
Normal file
BIN
docs/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
46
docs/assets/stylesheets/extra.css
Normal file
46
docs/assets/stylesheets/extra.css
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/* Adaptive Lighting Documentation Custom Styles */
|
||||
|
||||
/* Hero section on index page */
|
||||
.md-content__inner > h1:first-child {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* Logo in header - make it slightly larger */
|
||||
.md-header__button.md-logo img {
|
||||
height: 1.8rem;
|
||||
}
|
||||
|
||||
/* Simulator link button styling */
|
||||
.simulator-link {
|
||||
display: inline-block;
|
||||
padding: 0.75rem 1.5rem;
|
||||
background: linear-gradient(135deg, var(--md-primary-fg-color), var(--md-accent-fg-color));
|
||||
color: white !important;
|
||||
text-decoration: none;
|
||||
border-radius: 2rem;
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.simulator-link:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Code block improvements */
|
||||
.highlight code {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
/* Table improvements */
|
||||
.md-typeset table:not([class]) {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.md-typeset table:not([class]) th {
|
||||
font-weight: 700;
|
||||
}
|
||||
115
docs/automation-examples.md
Normal file
115
docs/automation-examples.md
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
---
|
||||
icon: lucide/bot
|
||||
---
|
||||
|
||||
# Automation Examples
|
||||
|
||||
Real-world automation examples showing how to integrate Adaptive Lighting with your Home Assistant setup.
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting.docs_gen import readme_section -->
|
||||
<!-- print(readme_section("automation-examples")) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
<details markdown="1">
|
||||
<summary>Reset the <code>manual_control</code> status of a light after an hour.</summary>
|
||||
|
||||
```yaml
|
||||
- alias: "Adaptive lighting: reset manual_control after 1 hour"
|
||||
mode: parallel
|
||||
trigger:
|
||||
platform: event
|
||||
event_type: adaptive_lighting.manual_control
|
||||
variables:
|
||||
light: "{{ trigger.event.data.entity_id }}"
|
||||
switch: "{{ trigger.event.data.switch }}"
|
||||
action:
|
||||
- delay: "01:00:00"
|
||||
- condition: template
|
||||
value_template: "{{ light in state_attr(switch, 'manual_control') }}"
|
||||
- service: adaptive_lighting.set_manual_control
|
||||
data:
|
||||
entity_id: "{{ switch }}"
|
||||
lights: "{{ light }}"
|
||||
manual_control: false
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Toggle multiple Adaptive Lighting switches to "sleep mode" using an <code>input_boolean.sleep_mode</code>.</summary>
|
||||
|
||||
```yaml
|
||||
- alias: "Adaptive lighting: toggle 'sleep mode'"
|
||||
trigger:
|
||||
- platform: state
|
||||
entity_id: input_boolean.sleep_mode
|
||||
- platform: homeassistant
|
||||
event: start # in case the states aren't properly restored
|
||||
variables:
|
||||
sleep_mode: "{{ states('input_boolean.sleep_mode') }}"
|
||||
action:
|
||||
service: "switch.turn_{{ sleep_mode }}"
|
||||
entity_id:
|
||||
- switch.adaptive_lighting_sleep_mode_living_room
|
||||
- switch.adaptive_lighting_sleep_mode_bedroom
|
||||
```
|
||||
|
||||
Set your sunrise and sunset time based on your alarm. The below script sets sunset_time exactly 12 hours after the custom sunrise time.
|
||||
|
||||
```yaml
|
||||
iphone_carly_wakeup:
|
||||
alias: iPhone Carly Wakeup
|
||||
sequence:
|
||||
- condition: state
|
||||
entity_id: input_boolean.carly_iphone_wakeup
|
||||
state: "off"
|
||||
- service: input_datetime.set_datetime
|
||||
target:
|
||||
entity_id: input_datetime.carly_iphone_wakeup
|
||||
data:
|
||||
time: '{{ now().strftime("%H:%M:%S") }}'
|
||||
- service: input_boolean.turn_on
|
||||
target:
|
||||
entity_id: input_boolean.carly_iphone_wakeup
|
||||
- repeat:
|
||||
count: >
|
||||
{{ (states.switch
|
||||
| map(attribute="entity_id")
|
||||
| select(">","switch.adaptive_lighting_al_")
|
||||
| select("<", "switch.adaptive_lighting_al_z")
|
||||
| join(",")
|
||||
).split(",") | length }}
|
||||
sequence:
|
||||
- service: adaptive_lighting.change_switch_settings
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_al_den_ceilingfan_lights
|
||||
sunrise_time: '{{ now().strftime("%H:%M:%S") }}'
|
||||
sunset_time: >
|
||||
{{ (as_timestamp(now()) + 12*60*60) | timestamp_custom("%H:%M:%S") }}
|
||||
- service: script.turn_on
|
||||
target:
|
||||
entity_id: script.run_wakeup_routine
|
||||
- service: input_boolean.turn_off
|
||||
target:
|
||||
entity_id:
|
||||
- input_boolean.carly_iphone_winddown
|
||||
- input_boolean.carly_iphone_bedtime
|
||||
- service: input_datetime.set_datetime
|
||||
target:
|
||||
entity_id: input_datetime.wakeup_time
|
||||
data:
|
||||
time: '{{ now().strftime("%H:%M:%S") }}'
|
||||
- service: script.adaptive_lighting_disable_sleep_mode
|
||||
mode: queued
|
||||
icon: mdi:weather-sunset
|
||||
max: 10
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
> [!TIP]
|
||||
> **Have a useful automation?** Share your automation examples by [opening an issue](https://github.com/basnijholt/adaptive-lighting/issues) or submitting a pull request to the README.
|
||||
150
docs/configuration.md
Normal file
150
docs/configuration.md
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
---
|
||||
icon: lucide/settings
|
||||
---
|
||||
|
||||
# Configuration
|
||||
|
||||
Adaptive Lighting supports configuration through both YAML and the Home Assistant UI, with identical option names in both methods.
|
||||
|
||||
## Basic Configuration
|
||||
|
||||
The minimal configuration requires only adding the integration to your `configuration.yaml`:
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
```
|
||||
|
||||
You can then configure everything through the UI at **Settings** → **Devices & Services** → **Adaptive Lighting** → **Configure**.
|
||||
|
||||
## YAML Configuration
|
||||
|
||||
For YAML configuration, you can specify lights and options directly:
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "Living Room"
|
||||
lights:
|
||||
- light.living_room_ceiling
|
||||
- light.living_room_lamp
|
||||
```
|
||||
|
||||
## All Options
|
||||
|
||||
All configuration options are listed below with their default values. These options work identically in both YAML and the UI.
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting._docs_helpers import generate_config_markdown_table -->
|
||||
<!-- print(generate_config_markdown_table()) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
| Variable name | Description | Default | Type |
|
||||
|:-------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------|:----------------------------------------|
|
||||
| `lights` | List of light entity_ids to be controlled (may be empty). 🌟 | `[]` | list of `entity_id`s |
|
||||
| `interval` | Frequency to adapt the lights, in seconds. 🔄 | `90` | `int > 0` |
|
||||
| `transition` | Duration of transition when lights change, in seconds. 🕑 | `45` | `float` 0-6553 |
|
||||
| `initial_transition` | Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️ | `1` | `float` 0-6553 |
|
||||
| `min_brightness` | Minimum brightness percentage. 💡 | `1` | `int` 1-100 |
|
||||
| `max_brightness` | Maximum brightness percentage. 💡 | `100` | `int` 1-100 |
|
||||
| `min_color_temp` | Warmest color temperature in Kelvin. 🔥 | `2000` | `int` 1000-10000 |
|
||||
| `max_color_temp` | Coldest color temperature in Kelvin. ❄️ | `5500` | `int` 1000-10000 |
|
||||
| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | `False` | `bool` |
|
||||
| `sleep_brightness` | Brightness percentage of lights in sleep mode. 😴 | `1` | `int` 1-100 |
|
||||
| `sleep_rgb_or_color_temp` | Use either `"rgb_color"` or `"color_temp"` in sleep mode. 🌙 | `color_temp` | one of `['color_temp', 'rgb_color']` |
|
||||
| `sleep_color_temp` | Color temperature in sleep mode (used when `sleep_rgb_or_color_temp` is `color_temp`) in Kelvin. 😴 | `1000` | `int` 1000-10000 |
|
||||
| `sleep_rgb_color` | RGB color in sleep mode (used when `sleep_rgb_or_color_temp` is "rgb_color"). 🌈 | `[255, 56, 0]` | RGB color |
|
||||
| `sleep_transition` | Duration of transition when "sleep mode" is toggled in seconds. 😴 | `1` | `float` 0-6553 |
|
||||
| `transition_until_sleep` | When enabled, Adaptive Lighting will treat sleep settings as the minimum, transitioning to these values after sunset. 🌙 | `False` | `bool` |
|
||||
| `sunrise_time` | Set a fixed time (HH:MM:SS) for sunrise. 🌅 | `None` | `str` |
|
||||
| `min_sunrise_time` | Set the earliest virtual sunrise time (HH:MM:SS), allowing for later sunrises. 🌅 | `None` | `str` |
|
||||
| `max_sunrise_time` | Set the latest virtual sunrise time (HH:MM:SS), allowing for earlier sunrises. 🌅 | `None` | `str` |
|
||||
| `sunrise_offset` | Adjust sunrise time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
|
||||
| `sunset_time` | Set a fixed time (HH:MM:SS) for sunset. 🌇 | `None` | `str` |
|
||||
| `min_sunset_time` | Set the earliest virtual sunset time (HH:MM:SS), allowing for later sunsets. 🌇 | `None` | `str` |
|
||||
| `max_sunset_time` | Set the latest virtual sunset time (HH:MM:SS), allowing for earlier sunsets. 🌇 | `None` | `str` |
|
||||
| `sunset_offset` | Adjust sunset time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
|
||||
| `brightness_mode` | Brightness mode to use. Possible values are `default`, `linear`, and `tanh` (uses `brightness_mode_time_dark` and `brightness_mode_time_light`). 📈 | `default` | one of `['default', 'linear', 'tanh']` |
|
||||
| `brightness_mode_time_dark` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness before/after sunrise/sunset. 📈📉 | `900` | `int` |
|
||||
| `brightness_mode_time_light` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness after/before sunrise/sunset. 📈📉. | `3600` | `int` |
|
||||
| `take_over_control` | Pause adaptation of individual lights and hand over (manual) control to other sources that issue `light.turn_on` calls for lights that are on. 🔒 | `True` | `bool` |
|
||||
| `take_over_control_mode` | The adaptation pausing mode when other sources change brightness and/or color of lights. `pause_all` always pauses both brightness and color adaptation. `pause_changed` pauses the adaptation of only the changed attributes and continues adapting unchanged attributes, e.g., continues color adaptation when only brightness was changed. | `pause_all` | one of `['pause_all', 'pause_changed']` |
|
||||
| `detect_non_ha_changes` | Detects and halts adaptations for non-`light.turn_on` state changes. Needs `take_over_control` enabled. 🕵️ Caution: ⚠️ Some lights might falsely indicate an 'on' state, which could result in lights turning on unexpectedly. Note that this calls `homeassistant.update_entity` every `interval`! Disable this feature if you encounter such issues. | `False` | `bool` |
|
||||
| `autoreset_control_seconds` | Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️ | `0` | `int` 0-31536000 |
|
||||
| `only_once` | Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄 | `False` | `bool` |
|
||||
| `adapt_only_on_bare_turn_on` | When turning lights on initially. If set to `true`, AL adapts only if `light.turn_on` is invoked without specifying color or brightness. ❌🌈 This e.g., prevents adaptation when activating a scene and marks the light as manually controlled. If `false`, AL adapts regardless of the presence of color or brightness in the initial `service_data`. Needs `take_over_control` enabled. 🕵️ | `False` | `bool` |
|
||||
| `separate_turn_on_commands` | Use separate `light.turn_on` calls for color and brightness, needed for some light types. 🔀 | `False` | `bool` |
|
||||
| `send_split_delay` | Delay (ms) between `separate_turn_on_commands` for lights that don't support simultaneous brightness and color setting. ⏲️ | `0` | `int` 0-10000 |
|
||||
| `adapt_delay` | Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️ | `0` | `float > 0` |
|
||||
| `skip_redundant_commands` | Skip sending adaptation commands whose target state already equals the light's known state. Minimizes network traffic and improves the adaptation responsivity in some situations. 📉Disable if physical light states get out of sync with HA's recorded state. | `False` | `bool` |
|
||||
| `intercept` | Intercept and adapt `light.turn_on` calls to enabling instantaneous color and brightness adaptation. 🏎️ Disable for lights that do not support `light.turn_on` with color and brightness. | `True` | `bool` |
|
||||
| `multi_light_intercept` | Intercept and adapt `light.turn_on` calls that target multiple lights. ➗⚠️ This might result in splitting up a single `light.turn_on` call into multiple calls, e.g., when lights are in different switches. Requires `intercept` to be enabled. | `True` | `bool` |
|
||||
| `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` |
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
## Full Configuration Example
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting.docs_gen import readme_section -->
|
||||
<!-- print(readme_section("config-example-full", strip_heading=False)) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
Full example:
|
||||
|
||||
```yaml
|
||||
# Example configuration.yaml entry
|
||||
adaptive_lighting:
|
||||
- name: "default"
|
||||
lights: []
|
||||
prefer_rgb_color: false
|
||||
transition: 45
|
||||
initial_transition: 1
|
||||
interval: 90
|
||||
min_brightness: 1
|
||||
max_brightness: 100
|
||||
min_color_temp: 2000
|
||||
max_color_temp: 5500
|
||||
sleep_brightness: 1
|
||||
sleep_color_temp: 1000
|
||||
sunrise_time: "08:00:00" # override the sunrise time
|
||||
sunrise_offset:
|
||||
sunset_time:
|
||||
sunset_offset: 1800 # in seconds or '00:30:00'
|
||||
take_over_control: true
|
||||
detect_non_ha_changes: false
|
||||
only_once: false
|
||||
|
||||
```
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
## Multiple Configurations
|
||||
|
||||
You can create multiple Adaptive Lighting configurations for different areas or use cases:
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "Daytime Spaces"
|
||||
lights:
|
||||
- light.living_room
|
||||
- light.kitchen
|
||||
- light.office
|
||||
min_brightness: 30
|
||||
max_brightness: 100
|
||||
|
||||
- name: "Bedroom"
|
||||
lights:
|
||||
- light.bedroom_ceiling
|
||||
- light.bedroom_lamp
|
||||
min_brightness: 5
|
||||
max_brightness: 80
|
||||
sleep_brightness: 1
|
||||
sleep_color_temp: 1000
|
||||
```
|
||||
|
||||
## Related Topics
|
||||
|
||||
- [Brightness Modes](advanced/brightness-modes.md) - Detailed explanation of brightness calculation modes
|
||||
- [Sleep Mode](advanced/sleep-mode.md) - Sleep mode configuration
|
||||
- [Manual Control](advanced/manual-control.md) - How manual control detection works
|
||||
117
docs/getting-started.md
Normal file
117
docs/getting-started.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
---
|
||||
icon: lucide/rocket
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
|
||||
This guide will help you install and configure Adaptive Lighting for the first time.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Home Assistant](https://www.home-assistant.io/) 2024.12.0 or newer
|
||||
- [HACS](https://hacs.xyz/) (Home Assistant Community Store) installed
|
||||
|
||||
## Installation
|
||||
|
||||
### Via HACS (Recommended)
|
||||
|
||||
1. Open HACS in your Home Assistant instance
|
||||
2. Click on **Integrations**
|
||||
3. Click the **+ Explore & Download Repositories** button
|
||||
4. Search for "Adaptive Lighting"
|
||||
5. Click **Download**
|
||||
6. Restart Home Assistant
|
||||
|
||||
Or use this button to open HACS directly:
|
||||
|
||||
[](https://my.home-assistant.io/redirect/hacs_repository/?owner=basnijholt&repository=adaptive-lighting&category=integration)
|
||||
|
||||
### Manual Installation
|
||||
|
||||
1. Download the latest release from [GitHub](https://github.com/basnijholt/adaptive-lighting/releases)
|
||||
2. Extract the `adaptive_lighting` folder to your `config/custom_components/` directory
|
||||
3. Restart Home Assistant
|
||||
|
||||
## Configuration
|
||||
|
||||
### Step 1: Add to configuration.yaml
|
||||
|
||||
Add the following to your `configuration.yaml`:
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> This entry is required even if you plan to configure everything through the UI.
|
||||
|
||||
### Step 2: Restart Home Assistant
|
||||
|
||||
Restart Home Assistant for the changes to take effect.
|
||||
|
||||
### Step 3: Add the Integration
|
||||
|
||||
1. Go to **Settings** → **Devices & Services**
|
||||
2. Click **+ Add Integration**
|
||||
3. Search for "Adaptive Lighting"
|
||||
4. Follow the setup wizard to select your lights
|
||||
|
||||
### Step 4: Configure Your Lights
|
||||
|
||||
You can configure Adaptive Lighting in two ways:
|
||||
|
||||
=== "Via UI"
|
||||
|
||||
1. Go to **Settings** → **Devices & Services**
|
||||
2. Find Adaptive Lighting and click **Configure**
|
||||
3. Adjust settings as needed
|
||||
|
||||
=== "Via YAML"
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "Living Room"
|
||||
lights:
|
||||
- light.living_room_ceiling
|
||||
- light.living_room_lamp
|
||||
min_brightness: 20
|
||||
max_brightness: 100
|
||||
min_color_temp: 2200
|
||||
max_color_temp: 5500
|
||||
```
|
||||
|
||||
## Basic Configuration Example
|
||||
|
||||
Here's a simple configuration to get you started:
|
||||
|
||||
```yaml
|
||||
adaptive_lighting:
|
||||
- name: "Main Lights"
|
||||
lights:
|
||||
- light.living_room
|
||||
- light.bedroom
|
||||
- light.kitchen
|
||||
transition: 30
|
||||
min_brightness: 10
|
||||
max_brightness: 100
|
||||
min_color_temp: 2000
|
||||
max_color_temp: 5500
|
||||
```
|
||||
|
||||
## Verifying Installation
|
||||
|
||||
After configuration, you should see new switches in Home Assistant:
|
||||
|
||||
- `switch.adaptive_lighting_main_lights`
|
||||
- `switch.adaptive_lighting_sleep_mode_main_lights`
|
||||
- `switch.adaptive_lighting_adapt_brightness_main_lights`
|
||||
- `switch.adaptive_lighting_adapt_color_main_lights`
|
||||
|
||||
Turn on `switch.adaptive_lighting_main_lights` to start adapting your lights!
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Configuration Reference](configuration.md) - Explore all available options
|
||||
- [Services](services.md) - Learn about service calls for automations
|
||||
- [Automation Examples](automation-examples.md) - See real-world automation recipes
|
||||
- [Troubleshooting](troubleshooting.md) - Common issues and solutions
|
||||
85
docs/index.md
Normal file
85
docs/index.md
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
---
|
||||
icon: lucide/sun
|
||||
---
|
||||
|
||||
# Adaptive Lighting
|
||||
|
||||
**Enhance Your Home's Atmosphere with Smart, Sun-Synchronized Lighting**
|
||||
|
||||
<div style="text-align: center; margin: 2rem 0;">
|
||||
<img src="assets/logo.png" alt="Adaptive Lighting Logo" width="200" />
|
||||
</div>
|
||||
|
||||
[Adaptive Lighting](https://github.com/basnijholt/adaptive-lighting) is a custom component for [Home Assistant](https://www.home-assistant.io/) that intelligently adjusts the brightness and color of your lights based on the sun's position, while still allowing for manual control.
|
||||
|
||||
<div style="text-align: center; margin: 2rem 0;">
|
||||
<a href="https://my.home-assistant.io/redirect/hacs_repository/?owner=basnijholt&repository=adaptive-lighting&category=integration" class="md-button md-button--primary">
|
||||
Install via HACS
|
||||
</a>
|
||||
<a href="simulator/" class="md-button">
|
||||
Try the Simulator
|
||||
</a>
|
||||
</div>
|
||||
|
||||
By automatically adapting the settings of your lights throughout the day, Adaptive Lighting helps maintain your natural circadian rhythm, which can lead to improved sleep, mood, and overall well-being. Experience cooler color temperatures at noon, gradually transitioning to warmer colors at sunset and sunrise.
|
||||
|
||||
## Features
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting.docs_gen import readme_section -->
|
||||
<!-- print(readme_section("features")) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
When initially turning on a light that is controlled by Adaptive Lighting, the `light.turn_on` service call is intercepted, and the light's brightness and color are automatically adjusted based on the sun's position.
|
||||
After that, the light's brightness and color are automatically adjusted at a regular interval.
|
||||
|
||||
Adaptive Lighting provides four switches (using "living_room" as an example component name):
|
||||
|
||||
- `switch.adaptive_lighting_living_room`: Turn Adaptive Lighting on or off and view current light settings through its attributes.
|
||||
- `switch.adaptive_lighting_sleep_mode_living_room`: Activate "sleep mode" 😴 and set custom sleep_brightness and sleep_color_temp.
|
||||
- `switch.adaptive_lighting_adapt_brightness_living_room`: Enable or disable brightness adaptation 🔆 for supported lights.
|
||||
- `switch.adaptive_lighting_adapt_color_living_room`: Enable or disable color adaptation 🌈 for supported lights.
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Install via HACS**: Search for "Adaptive Lighting" in the [Home Assistant Community Store](https://hacs.xyz/)
|
||||
2. **Add to configuration**: Add `adaptive_lighting:` to your `configuration.yaml`
|
||||
3. **Configure**: Go to **Settings** → **Devices & Services** → **Add Integration** → **Adaptive Lighting**
|
||||
4. **Select your lights**: Choose which lights to control and enjoy automatic adaptation!
|
||||
|
||||
```yaml
|
||||
# Minimal configuration.yaml entry
|
||||
adaptive_lighting:
|
||||
lights:
|
||||
- light.living_room
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> **Using the UI exclusively?** Even if you plan to configure everything through the UI, the `adaptive_lighting:` entry must still be present in your `configuration.yaml`.
|
||||
|
||||
[Get Started →](getting-started.md){ .md-button .md-button--primary }
|
||||
[View All Options →](configuration.md){ .md-button }
|
||||
|
||||
## How It Works
|
||||
|
||||
Adaptive Lighting provides four switches for each configuration (using "living_room" as an example):
|
||||
|
||||
| Switch | Purpose |
|
||||
|--------|---------|
|
||||
| `switch.adaptive_lighting_living_room` | Main on/off control |
|
||||
| `switch.adaptive_lighting_sleep_mode_living_room` | Activate sleep mode |
|
||||
| `switch.adaptive_lighting_adapt_brightness_living_room` | Enable/disable brightness adaptation |
|
||||
| `switch.adaptive_lighting_adapt_color_living_room` | Enable/disable color adaptation |
|
||||
|
||||
## Interactive Simulator
|
||||
|
||||
Visualize how Adaptive Lighting will work with your settings using the interactive simulator:
|
||||
|
||||
<div style="text-align: center; margin: 2rem 0;">
|
||||
<a href="simulator/" class="simulator-link">
|
||||
Try the Interactive Simulator
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<!-- Privacy-friendly analytics by Plausible -->
|
||||
<script async src="https://plausible.nijho.lt/js/pa-yNpTS2silFzWxGYjHM_Bk.js"></script>
|
||||
<script>
|
||||
window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};
|
||||
plausible.init()
|
||||
</script>
|
||||
71
docs/run_markdown_code_runner.py
Executable file
71
docs/run_markdown_code_runner.py
Executable file
|
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/env python3
|
||||
# ruff: noqa: T201, S603, S607
|
||||
"""Update all markdown files that use markdown-code-runner for auto-generation.
|
||||
|
||||
Run from repo root: uv run python docs/run_markdown_code_runner.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def find_markdown_files_with_code_blocks(docs_dir: Path) -> list[Path]:
|
||||
"""Find all markdown files containing markdown-code-runner markers."""
|
||||
files_with_code = []
|
||||
for md_file in docs_dir.rglob("*.md"):
|
||||
content = md_file.read_text()
|
||||
if "<!-- CODE:START -->" in content:
|
||||
files_with_code.append(md_file)
|
||||
return sorted(files_with_code)
|
||||
|
||||
|
||||
def run_markdown_code_runner(files: list[Path], repo_root: Path) -> bool:
|
||||
"""Run markdown-code-runner on all files. Returns True if all succeeded."""
|
||||
if not files:
|
||||
print("No files with CODE:START markers found.")
|
||||
return True
|
||||
|
||||
print(f"Found {len(files)} file(s) with auto-generated content:")
|
||||
for f in files:
|
||||
print(f" - {f.relative_to(repo_root)}")
|
||||
print()
|
||||
|
||||
all_success = True
|
||||
for file in files:
|
||||
rel_path = file.relative_to(repo_root)
|
||||
print(f"Updating {rel_path}...", end=" ", flush=True)
|
||||
result = subprocess.run(
|
||||
["markdown-code-runner", str(file)],
|
||||
check=False,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
if result.returncode == 0:
|
||||
print("✓")
|
||||
else:
|
||||
print("✗")
|
||||
print(f" Error: {result.stderr}")
|
||||
all_success = False
|
||||
|
||||
return all_success
|
||||
|
||||
|
||||
def main() -> int:
|
||||
"""Main entry point."""
|
||||
repo_root = Path(__file__).parent.parent
|
||||
|
||||
# Process docs/ files and README.md
|
||||
files = find_markdown_files_with_code_blocks(repo_root / "docs")
|
||||
readme = repo_root / "README.md"
|
||||
if readme.exists() and "<!-- CODE:START -->" in readme.read_text():
|
||||
files.append(readme)
|
||||
|
||||
success = run_markdown_code_runner(files, repo_root)
|
||||
return 0 if success else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
73
docs/see-also.md
Normal file
73
docs/see-also.md
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
icon: lucide/external-link
|
||||
---
|
||||
|
||||
# See Also
|
||||
|
||||
Resources, tutorials, and related projects for Adaptive Lighting.
|
||||
|
||||
## Tutorials & Articles
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting.docs_gen import readme_section -->
|
||||
<!-- print(readme_section("see-also")) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
- [*Sleep better with Adaptive Lighting in Home Assistant*](https://wartner.io/sleep-better-with-adaptive-lightning-in-home-assistant/) by Florian Wartner on 2023-02-23 (blog post 📜)
|
||||
- [*Automatic smart light brightness and color based on the sun*](https://www.youtube.com/watch?v=Rg3zI1Oyk3c) by Home Automation Guy on 2022-08-31 (YouTube video 📺)
|
||||
- [*Adaptive Lighting Blew My Mind in Home Assistant - How to set it up*](https://www.youtube.com/watch?v=c1cnccmgl3k) by Smart Home Junkie on 2022-06-26 (YouTube video 📺)
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
## Interactive Tools
|
||||
|
||||
### Adaptive Lighting Simulator
|
||||
|
||||
Visualize how different settings affect your lighting throughout the day:
|
||||
|
||||
<div style="text-align: center; margin: 2rem 0;">
|
||||
<a href="../simulator/" class="simulator-link">
|
||||
Open the Simulator
|
||||
</a>
|
||||
</div>
|
||||
|
||||
The simulator lets you:
|
||||
|
||||
- Adjust all configuration parameters in real-time
|
||||
- See how brightness and color temperature change throughout the day
|
||||
- Visualize the effects of different `brightness_mode` settings
|
||||
- Test sleep mode transitions
|
||||
|
||||
## Related Projects
|
||||
|
||||
### Circadian Lighting
|
||||
|
||||
Adaptive Lighting was initially inspired by [hass-circadian_lighting](https://github.com/claytonjn/hass-circadian_lighting) by @claytonjn, but has since been entirely rewritten and expanded with many new features.
|
||||
|
||||
## Official Documentation
|
||||
|
||||
- [Home Assistant Documentation (PR Preview)](https://deploy-preview-14877--home-assistant-docs.netlify.app/integrations/adaptive_lighting/)
|
||||
- [Home Assistant Community Store (HACS)](https://hacs.xyz/)
|
||||
|
||||
## Community
|
||||
|
||||
- [Home Assistant Community Forums](https://community.home-assistant.io/)
|
||||
- [Home Assistant Discord](https://discord.gg/home-assistant)
|
||||
- [Reddit r/homeassistant](https://www.reddit.com/r/homeassistant/)
|
||||
|
||||
## Contributing
|
||||
|
||||
Interested in contributing to Adaptive Lighting?
|
||||
|
||||
- [GitHub Repository](https://github.com/basnijholt/adaptive-lighting)
|
||||
- [Issue Tracker](https://github.com/basnijholt/adaptive-lighting/issues)
|
||||
- [Translation via Weblate](https://hosted.weblate.org/engage/adaptive-lighting/)
|
||||
|
||||
### Translation
|
||||
|
||||
Help translate Adaptive Lighting into your language on [Hosted Weblate](https://hosted.weblate.org/engage/adaptive-lighting/). No programming knowledge required!
|
||||
|
||||
<a href="https://hosted.weblate.org/engage/adaptive-lighting/">
|
||||
<img src="https://hosted.weblate.org/widget/adaptive-lighting/multi-auto.svg" alt="Translation status" />
|
||||
</a>
|
||||
203
docs/services.md
Normal file
203
docs/services.md
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
---
|
||||
icon: lucide/zap
|
||||
---
|
||||
|
||||
# Services
|
||||
|
||||
Adaptive Lighting provides three services for programmatic control, allowing you to integrate with automations and scripts.
|
||||
|
||||
## adaptive_lighting.apply
|
||||
|
||||
Applies the current Adaptive Lighting settings to lights on demand. Useful for forcing an immediate update or applying settings to lights that aren't in the regular adaptation cycle.
|
||||
|
||||
### Parameters
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting._docs_helpers import generate_apply_markdown_table -->
|
||||
<!-- print(generate_apply_markdown_table()) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
| Service data attribute | Description | Required | Type |
|
||||
|:-------------------------|:--------------------------------------------------------------------------------------|:-----------|:---------------------|
|
||||
| `entity_id` | The `entity_id` of the switch with the settings to apply. 📝 | ✅ | list of `entity_id`s |
|
||||
| `lights` | A light (or list of lights) to apply the settings to. 💡 | ❌ | list of `entity_id`s |
|
||||
| `transition` | Duration of transition when lights change, in seconds. 🕑 | ❌ | `float` 0-6553 |
|
||||
| `adapt_brightness` | Whether to adapt the brightness of the light. 🌞 | ❌ | bool |
|
||||
| `adapt_color` | Whether to adapt the color on supporting lights. 🌈 | ❌ | bool |
|
||||
| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | ❌ | bool |
|
||||
| `turn_on_lights` | Whether to turn on lights that are currently off. 🔆 | ❌ | bool |
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
### Example Usage
|
||||
|
||||
```yaml
|
||||
# Apply current settings to specific lights
|
||||
service: adaptive_lighting.apply
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_living_room
|
||||
lights:
|
||||
- light.floor_lamp
|
||||
- light.desk_lamp
|
||||
turn_on_lights: false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Force apply with custom transition
|
||||
service: adaptive_lighting.apply
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_bedroom
|
||||
transition: 5
|
||||
adapt_brightness: true
|
||||
adapt_color: true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## adaptive_lighting.set_manual_control
|
||||
|
||||
Marks or unmarks a light as "manually controlled". When a light is marked as manually controlled, Adaptive Lighting will not adjust it until the manual control flag is cleared.
|
||||
|
||||
### Parameters
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting._docs_helpers import generate_set_manual_control_markdown_table -->
|
||||
<!-- print(generate_set_manual_control_markdown_table()) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
| Service data attribute | Description | Required | Type |
|
||||
|:-------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------|:-----------------------------------------|
|
||||
| `entity_id` | The `entity_id` of the switch in which to (un)mark the light as being `manually controlled`. 📝 | ✅ | list of `entity_id`s |
|
||||
| `lights` | entity_id(s) of lights, if not specified, all lights in the switch are selected. 💡 | ❌ | list of `entity_id`s |
|
||||
| `manual_control` | Whether to add ("true") or remove ("false") all adapted attributes of the light from the "manual_control" list, or the name of an attribute for selective addition. 🔒 | ❌ | bool or one of `['brightness', 'color']` |
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
### Example Usage
|
||||
|
||||
```yaml
|
||||
# Remove manual control from a light (resume adaptation)
|
||||
service: adaptive_lighting.set_manual_control
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_living_room
|
||||
lights:
|
||||
- light.floor_lamp
|
||||
manual_control: false
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Mark a light as manually controlled (pause adaptation)
|
||||
service: adaptive_lighting.set_manual_control
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_living_room
|
||||
lights:
|
||||
- light.floor_lamp
|
||||
manual_control: true
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Only pause brightness adaptation, continue color adaptation
|
||||
service: adaptive_lighting.set_manual_control
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_living_room
|
||||
lights:
|
||||
- light.floor_lamp
|
||||
manual_control: brightness
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## adaptive_lighting.change_switch_settings
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting.docs_gen import readme_section -->
|
||||
<!-- print(readme_section("change-switch-settings")) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
#### `adaptive_lighting.change_switch_settings`
|
||||
|
||||
`adaptive_lighting.change_switch_settings` (new in 1.7.0) Change any of the above configuration options of Adaptive Lighting (such as `sunrise_time` or `prefer_rgb_color`) with a service call directly from your script/automation.
|
||||
|
||||
> [!WARNING]
|
||||
> These settings will **not** be written to your config and will be reset on restart of Home Assistant! You can see the current settings in the `switch.adaptive_lighting_XXX` attributes if `include_config_in_attributes` is enabled.
|
||||
|
||||
| Service data attribute | Required | Description |
|
||||
| --------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `use_defaults` | ❌ | (default: `current` for current settings) Choose from `factory`, `configuration`, or `current` to reset variables not being set with this service call. `current` leaves them as they are, `configuration` resets to initial startup values, `factory` resets to default values listed in the documentation. |
|
||||
| **all other keys** (except the ones in the table below ⚠️) | ❌ | See the table below for disallowed keys. |
|
||||
|
||||
The following keys are disallowed:
|
||||
|
||||
| **DISALLOWED** service data | Description |
|
||||
| --------------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `entity_id` | You cannot change the switch's `entity_id`, as it has already been registered. |
|
||||
| `lights` | You may call `adaptive_lighting.apply` with your lights or create a new config instead. |
|
||||
| `name` | You can rename your switch's display name in Home Assistant's UI. |
|
||||
| `interval` | The interval is used only once when the config loads. A config change and restart are required. |
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
### Example Usage
|
||||
|
||||
```yaml
|
||||
# Temporarily change color temperature range
|
||||
service: adaptive_lighting.change_switch_settings
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_living_room
|
||||
min_color_temp: 2500
|
||||
max_color_temp: 4000
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Override sunrise time for the day
|
||||
service: adaptive_lighting.change_switch_settings
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_bedroom
|
||||
sunrise_time: "07:00:00"
|
||||
use_defaults: current
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Reset to configuration defaults
|
||||
service: adaptive_lighting.change_switch_settings
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_living_room
|
||||
use_defaults: configuration
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Events
|
||||
|
||||
Adaptive Lighting also fires events that you can use in automations.
|
||||
|
||||
### adaptive_lighting.manual_control
|
||||
|
||||
Fired when a light is marked as "manually controlled" due to a detected manual change.
|
||||
|
||||
**Event Data:**
|
||||
|
||||
| Attribute | Description |
|
||||
|-----------|-------------|
|
||||
| `entity_id` | The light that was marked as manually controlled |
|
||||
| `switch` | The Adaptive Lighting switch entity |
|
||||
|
||||
### Example Automation
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
- alias: "Log manual control events"
|
||||
trigger:
|
||||
platform: event
|
||||
event_type: adaptive_lighting.manual_control
|
||||
action:
|
||||
- service: notify.mobile_app
|
||||
data:
|
||||
title: "Adaptive Lighting"
|
||||
message: "{{ trigger.event.data.entity_id }} was manually controlled"
|
||||
```
|
||||
|
||||
See [Automation Examples](automation-examples.md) for more use cases.
|
||||
106
docs/troubleshooting.md
Normal file
106
docs/troubleshooting.md
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
---
|
||||
icon: lucide/life-buoy
|
||||
---
|
||||
|
||||
# Troubleshooting
|
||||
|
||||
This guide covers common issues and their solutions when using Adaptive Lighting.
|
||||
|
||||
## Enable Debug Logging
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting.docs_gen import readme_section -->
|
||||
<!-- print(readme_section("troubleshooting-intro")) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
Encountering issues? Enable debug logging in your `configuration.yaml`:
|
||||
|
||||
```yaml
|
||||
logger:
|
||||
default: warning
|
||||
logs:
|
||||
custom_components.adaptive_lighting: debug
|
||||
```
|
||||
|
||||
After the issue occurs, create a new issue report with the log (`/config/home-assistant.log`).
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
## Common Problems & Solutions
|
||||
|
||||
<!-- CODE:START -->
|
||||
<!-- from adaptive_lighting.docs_gen import readme_section -->
|
||||
<!-- print(readme_section("common-problems")) -->
|
||||
<!-- CODE:END -->
|
||||
<!-- OUTPUT:START -->
|
||||
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
|
||||
#### :bulb: Lights Not Responding or Turning On by Themselves
|
||||
|
||||
Adaptive Lighting sends more commands to lights than a typical human user would. If your light control network is unhealthy, you may experience:
|
||||
|
||||
- Laggy manual commands (e.g., turning lights on or off).
|
||||
- Unresponsive lights.
|
||||
- Home Assistant reporting incorrect light states, causing Adaptive Lighting to inadvertently turn lights back on.
|
||||
|
||||
Most issues that appear to be caused by Adaptive Lighting are actually due to unrelated problems.
|
||||
Addressing these issues will significantly improve your Home Assistant experience.
|
||||
|
||||
In case lights are suddenly turning on by themselves, this is most likely due to the light incorrectly reporting an "on" state to Home Assistant, leading to an undesired Adaptive Lighting action.
|
||||
To prevent adapting in cases *where the state of the light is suddenly "on" and only adapt if there is an associated `light.turn_on` service call*, set `detect_non_ha_changes: false`.
|
||||
|
||||
#### :signal_strength: WiFi Networks
|
||||
|
||||
Ensure your light bulbs have a strong WiFi connection. If the signal strength is less than -70dBm, the connection may be weak and prone to dropping messages.
|
||||
|
||||
#### :spider_web: Zigbee, Z-Wave, and Other Mesh Networks
|
||||
|
||||
Mesh networks typically require powered devices to act as routers, relaying messages back to the central coordinator (the radio connected to Home Assistant).
|
||||
Philips lights usually function as routers, while Ikea, Sengled, and generic Tuya bulbs often do not.
|
||||
If devices become unresponsive or fail to respond to commands, Adaptive Lighting can exacerbate the issue.
|
||||
Use network maps (available in ZHA, zigbee2mqtt, deCONZ, and ZWaveJS UI) to evaluate your network health.
|
||||
Smart plugs can be an affordable way to add more routers to your network.
|
||||
|
||||
For most Zigbee networks, **using groups is essential for optimal performance**.
|
||||
For example, if you want to use Adaptive Lighting in a hallway with six bulbs, adding each bulb individually to the Adaptive Lighting configuration could overwhelm the network with commands.
|
||||
Instead, create a group in your Zigbee software (not a regular Home Assistant group) and add that single group to the Adaptive Lighting configuration.
|
||||
This sends a single broadcast command to adjust all bulbs, improving response times and keeping the bulbs in sync.
|
||||
|
||||
As a rule of thumb, if you always control lights together (e.g., bulbs in a ceiling fixture), they should be in a Zigbee group.
|
||||
Expose only the group (not individual bulbs) in Home Assistant Dashboards and external systems like Google Home or Apple HomeKit.
|
||||
|
||||
> :warning: **If you control lights individually, `manual_control` cannot behave correctly! If you need to control lights individually as well, use a [Home Assistant Light Group](https://www.home-assistant.io/integrations/group/).**
|
||||
|
||||
#### :rainbow: Light Colors Not Matching
|
||||
|
||||
Bulbs from different manufacturers or models may have varying color temperature specifications. For instance, if you have two Adaptive Lighting configurations—one with only Philips Hue White Ambiance bulbs and another with a mix of Philips Hue White Ambiance and Sengled bulbs—the Philips Hue bulbs may appear to have different color temperatures despite having identical settings.
|
||||
|
||||
To resolve this:
|
||||
|
||||
1. Include only bulbs of the same make and model in a single Adaptive Lighting configuration.
|
||||
2. Rearrange bulbs so that different color temperatures are not visible simultaneously.
|
||||
|
||||
#### :bulb: Bulb-Specific Issues
|
||||
|
||||
These lights are known to exhibit disadvantageous behaviour due to firmware bugs, insufficient functionality, or hardware limitations:
|
||||
|
||||
- [Sengled Z01-A19NAE26](https://www.zigbee2mqtt.io/devices/Z01-A19NAE26.html#sengled-z01-a19nae26)
|
||||
- Unexpected turn-ons: If Adaptive Lighting sends a long transition time (like the default 45 seconds), and the bulb is turned off during that time, it may turn back on after approximately 10 seconds to continue the transition command. Since the bulb is turning itself on, there will be no obvious trigger in Home Assistant or other logs indicating the cause of the light turning on. To fix this, set a much shorter `transition` time, such as 1 second.
|
||||
- Heat sensitivity: Additionally, these bulbs may perform poorly in enclosed "dome" style ceiling lights, particularly when hot. While most LEDs (even non-smart ones) state in the fine print that they do not support working in enclosed fixtures, in practice, more expensive bulbs like Philips Hue generally perform better. To resolve this issue, move the problematic bulbs to open-air fixtures.
|
||||
- Ikea Tradfri bulbs/drivers (and related Ikea smart light products)
|
||||
- Unsupported simultaneous transition of brightness and color: When receiving such a command, they switch the brightness instantly and only transition the color. To get smooth transitions of both brightness and color, enable `separate_turn_on_commands`.
|
||||
- Unresponsiveness during color transitions: No other commands are processed during an ongoing color transition, e.g., turn-off commands are ignored and lights stay on despite being reported as off to Home Assistant. The default config with long transitions thus results in long periods of unresponsiveness. To work around this, disable transitions by setting `transition` to `0`, and increase the adaptation frequency by setting `interval` to a short time, e.g., `15` seconds, to retain the impression of smooth continuous adaptations. Keeping the `initial_transition` is recommended for a smooth fade-in (lights are usually not turned off momentarily after being turned on, in which case a short period of unresponsiveness is tolerable).
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you're still having issues:
|
||||
|
||||
1. Enable debug logging and capture the relevant logs
|
||||
2. Open an issue on [GitHub](https://github.com/basnijholt/adaptive-lighting/issues)
|
||||
3. Include:
|
||||
- Your configuration (redact sensitive info)
|
||||
- Debug logs
|
||||
- Home Assistant version
|
||||
- Description of expected vs actual behavior
|
||||
66
pyproject.toml
Normal file
66
pyproject.toml
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "adaptive-lighting"
|
||||
version = "1.30.1"
|
||||
description = "Automatically adjust brightness and color of lights based on the sun position"
|
||||
readme = "README.md"
|
||||
license = "Apache-2.0"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
[dependency-groups]
|
||||
docs = [
|
||||
"astral",
|
||||
"homeassistant",
|
||||
"markdown-code-runner",
|
||||
"markdown-gfm-admonition",
|
||||
"pandas",
|
||||
"shinylive",
|
||||
"tabulate",
|
||||
"ulid-transform",
|
||||
"voluptuous",
|
||||
"zensical",
|
||||
]
|
||||
dev = [
|
||||
"mypy",
|
||||
"pre-commit",
|
||||
"ruff",
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
packages = ["custom_components/adaptive_lighting"]
|
||||
|
||||
[tool.ruff]
|
||||
target-version = "py312"
|
||||
line-length = 88
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = [
|
||||
"E", # pycodestyle errors
|
||||
"W", # pycodestyle warnings
|
||||
"F", # Pyflakes
|
||||
"I", # isort
|
||||
"UP", # pyupgrade
|
||||
"RUF", # Ruff-specific rules
|
||||
"B", # flake8-bugbear
|
||||
"C4", # flake8-comprehensions
|
||||
"SIM", # flake8-simplify
|
||||
]
|
||||
ignore = [
|
||||
"E501", # line too long (handled by formatter)
|
||||
]
|
||||
|
||||
[tool.ruff.lint.isort]
|
||||
known-first-party = ["adaptive_lighting"]
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.12"
|
||||
warn_return_any = true
|
||||
warn_unused_configs = true
|
||||
ignore_missing_imports = true
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
asyncio_mode = "auto"
|
||||
117
zensical.toml
Normal file
117
zensical.toml
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# Adaptive Lighting Documentation Site Configuration
|
||||
# Built with Zensical - https://zensical.org
|
||||
|
||||
[project]
|
||||
site_name = "Adaptive Lighting"
|
||||
site_description = "Automatically adjust brightness and color of lights based on the sun position"
|
||||
site_author = "Bas Nijholt"
|
||||
site_url = "https://adaptive-lighting.nijho.lt/"
|
||||
copyright = "Copyright © 2020-2026 Bas Nijholt"
|
||||
|
||||
repo_url = "https://github.com/basnijholt/adaptive-lighting"
|
||||
repo_name = "GitHub"
|
||||
edit_uri = "edit/main/docs"
|
||||
|
||||
nav = [
|
||||
{ "Home" = "index.md" },
|
||||
{ "Getting Started" = "getting-started.md" },
|
||||
{ "Configuration" = "configuration.md" },
|
||||
{ "Services" = "services.md" },
|
||||
{ "Automation Examples" = "automation-examples.md" },
|
||||
{ "Troubleshooting" = "troubleshooting.md" },
|
||||
{ "Advanced" = [
|
||||
{ "Brightness Modes" = "advanced/brightness-modes.md" },
|
||||
{ "Manual Control" = "advanced/manual-control.md" },
|
||||
{ "Sleep Mode" = "advanced/sleep-mode.md" },
|
||||
] },
|
||||
{ "See Also" = "see-also.md" },
|
||||
]
|
||||
|
||||
[project.theme]
|
||||
custom_dir = "docs/overrides"
|
||||
language = "en"
|
||||
logo = "assets/logo.png"
|
||||
|
||||
features = [
|
||||
"announce.dismiss",
|
||||
"content.action.edit",
|
||||
"content.action.view",
|
||||
"content.code.annotate",
|
||||
"content.code.copy",
|
||||
"content.code.select",
|
||||
"content.footnote.tooltips",
|
||||
"content.tabs.link",
|
||||
"content.tooltips",
|
||||
"navigation.footer",
|
||||
"navigation.indexes",
|
||||
"navigation.instant",
|
||||
"navigation.instant.prefetch",
|
||||
"navigation.path",
|
||||
"navigation.top",
|
||||
"navigation.tracking",
|
||||
"search.highlight",
|
||||
]
|
||||
|
||||
# Three-way toggle: system preference -> light -> dark -> system preference
|
||||
[[project.theme.palette]]
|
||||
media = "(prefers-color-scheme)"
|
||||
toggle.icon = "lucide/sun-moon"
|
||||
toggle.name = "Switch to light mode"
|
||||
|
||||
[[project.theme.palette]]
|
||||
media = "(prefers-color-scheme: light)"
|
||||
scheme = "default"
|
||||
primary = "amber"
|
||||
accent = "orange"
|
||||
toggle.icon = "lucide/sun"
|
||||
toggle.name = "Switch to dark mode"
|
||||
|
||||
[[project.theme.palette]]
|
||||
media = "(prefers-color-scheme: dark)"
|
||||
scheme = "slate"
|
||||
primary = "amber"
|
||||
accent = "orange"
|
||||
toggle.icon = "lucide/moon-star"
|
||||
toggle.name = "Switch to system preference"
|
||||
|
||||
[project.theme.font]
|
||||
text = "Inter"
|
||||
code = "JetBrains Mono"
|
||||
|
||||
[project.theme.icon]
|
||||
repo = "lucide/github"
|
||||
|
||||
[project.extra]
|
||||
generator = false
|
||||
|
||||
[[project.extra.social]]
|
||||
icon = "fontawesome/brands/github"
|
||||
link = "https://github.com/basnijholt/adaptive-lighting"
|
||||
|
||||
[[project.extra.social]]
|
||||
icon = "fontawesome/brands/discord"
|
||||
link = "https://discord.gg/home-assistant"
|
||||
|
||||
# Enable GitHub-style admonitions (> [!NOTE], > [!TIP], etc.)
|
||||
[project.markdown_extensions.gfm_admonition]
|
||||
|
||||
# Enable markdown inside HTML blocks (e.g., <details>)
|
||||
[project.markdown_extensions.md_in_html]
|
||||
|
||||
# Enable attribute lists for adding CSS classes (e.g., {.md-button})
|
||||
[project.markdown_extensions.attr_list]
|
||||
|
||||
# Enable syntax highlighting for fenced code blocks
|
||||
[project.markdown_extensions.pymdownx.highlight]
|
||||
anchor_linenums = true
|
||||
|
||||
[project.markdown_extensions.pymdownx.superfences]
|
||||
|
||||
# Enable tabs (=== "Tab Name" syntax)
|
||||
[project.markdown_extensions.pymdownx.tabbed]
|
||||
alternate_style = true
|
||||
|
||||
# Enable emoji/icon support
|
||||
[project.markdown_extensions.pymdownx.emoji]
|
||||
emoji_index = "zensical.extensions.emoji.twemoji"
|
||||
emoji_generator = "zensical.extensions.emoji.to_svg"
|
||||
Loading…
Add table
Add a link
Reference in a new issue