adaptive-lighting/docs/advanced/brightness-modes.md
Bas Nijholt cbbcabdd1f
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
2026-01-12 23:39:57 +01:00

124 lines
5.7 KiB
Markdown

---
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.
![image](https://github.com/basnijholt/adaptive-lighting/assets/6897215/15143580-13cd-4ab2-a603-89f2b7830afd)
![image](https://github.com/basnijholt/adaptive-lighting/assets/6897215/f61fdac9-6d47-48c9-84ed-cbb451d5de5d)
![image](https://github.com/basnijholt/adaptive-lighting/assets/6897215/e5fc5d27-3c37-4e3d-93d1-6e7cf4b48e7c)
![image](https://github.com/basnijholt/adaptive-lighting/assets/6897215/3dcbdc42-63c4-49df-8651-d2fae53dd08d)
> 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
![cl_percent|690x131](https://community-home-assistant-assets.s3.dualstack.us-west-2.amazonaws.com/original/3X/6/5/657ff98beb65a94598edeb4bdfd939095db1a22c.PNG)
### :thermometer: Color Temperature
![cl_color_temp|690x129](https://community-home-assistant-assets.s3.dualstack.us-west-2.amazonaws.com/original/3X/5/9/59e84263cbecd8e428cb08777a0413672c48dfcd.PNG)
### :high_brightness: Brightness
![cl_brightness|690x130](https://community-home-assistant-assets.s3.dualstack.us-west-2.amazonaws.com/original/3X/5/8/58ebd994b62a8b1abfb3497a5288d923ff4e2330.PNG)
### While using `transition_until_sleep: true`
![image](https://user-images.githubusercontent.com/2219836/228949675-f9699624-8abc-466c-bb04-250ce0f495b8.png)
<!-- 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.