Skip to content

feat: add independent morning and evening color temperature plateaus - #1642

Open
Charles-HL wants to merge 4 commits into
basnijholt:mainfrom
Charles-HL:feat/color-temperature-plateau
Open

Charles-HL wants to merge 4 commits into
basnijholt:mainfrom
Charles-HL:feat/color-temperature-plateau

Conversation

@Charles-HL

@Charles-HL Charles-HL commented Oct 18, 2026 •

Copy link
Copy Markdown

Motivation

Today the color temperature follows the sun position, so it only touches max_color_temp at a single instant (solar noon). For lights where the cool value is the most useful one (for example a kitchen at 4000 K), it is not possible to stay there for a few hours without changing the temperature range or giving up smooth ramps.

What this adds

Two independent duration options, in seconds (same unit as sunrise_offset and brightness_mode_time_*), default 0:

Option Meaning
color_temp_plateau_morning Time before solar noon during which the color temperature already stays at max_color_temp
color_temp_plateau_evening Time after solar noon during which the color temperature stays at max_color_temp

Two optional local wall-clock options, which must be set together:

Option Meaning
color_temp_fixed_plateau_end Evening time until which the color temperature stays at max_color_temp
color_temp_fixed_descent_end Local time by which it has smoothly descended to min_color_temp

One optional temperature, which needs the two fixed times:

Option Meaning
color_temp_fixed_plateau_kelvin Evening temperature (between min_color_temp and max_color_temp) held for the last hour before color_temp_fixed_plateau_end, instead of max_color_temp

The fixed schedule allows, for example, keeping a kitchen at 4000 K until 21:00 and descending to 2700 K by 23:00 throughout the year. It only affects color temperature. The existing solar curve remains the default when the two fields are unset.

All options are available in YAML, the options flow, and change_switch_settings; service metadata, documentation and English translations are included.

Behavior and validation

  • The solar plateaus retain the existing noon anchor and use a continuous, monotonic curve; a zero duration keeps the original calculation unchanged.
  • The fixed evening schedule starts no earlier than solar noon, uses a cosine ease from the fixed plateau end to the descent end, and remains continuous into the normal evening/night behavior.
  • Fixed times are local wall-clock values, work across midnight and daylight-saving changes, and are constrained to an evening plateau end and a maximum 12-hour descent.
  • Incoherent pairs are rejected in the options flow, YAML, and service calls.
  • With color_temp_fixed_plateau_kelvin the daytime maximum is not capped: after it the temperature descends along the regular afternoon curve, reaches the target exactly and holds it for the last hour before the plateau end in every season (the curve is traversed faster when the regular one would be too late, e.g. in summer), then eases down to the minimum. No step anywhere; unset keeps the previous behavior. It is ignored on a day where the plateau end is less than one hour after solar noon. The target must lie between min_color_temp and max_color_temp (re-checked when they change) and needs both fixed times.
  • Brightness curves, sleep mode, and the normal behavior of all existing configurations remain unchanged.

Tests

  • Color calculation: default parity, solar-plateau shape and side independence, fixed 21:00–23:00 schedules, post-midnight schedules, daylight-saving dates, season/location variation, sunset/sunrise boundaries, sleep/RGB behavior, and brightness non-regression.
  • Evening plateau temperature: exact hold over all 365 days (DST included), solar plateau durations, early plateau ends, polar days, bounds, sleep/brightness parity.
  • Configuration: options-flow round trips and invalid fixed-time pairs.
  • Runtime settings: service changes, reset behavior, and YAML validation.

Full component suite: 814 passed. Ruff lint passes for the modified files.

Add `color_temp_plateau_morning` and `color_temp_plateau_evening` (seconds,
default 0, max 12h). They keep `max_color_temp` for that long before / after
solar noon, and compress the ramp from/to `min_color_temp` at sunrise/sunset so
the curve stays continuous and smooth. Each side is independent, only the
color temperature is affected (not brightness, sleep mode or the night), and the
default (0) is bit-for-bit identical to the previous behavior. Each plateau is
clamped to 90% of the half-day so the ramp never collapses.
@greptile-apps

greptile-apps Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no actionable issues were found.

Summary

Adds independent morning and evening periods that hold color temperature at max_color_temp.

  • Lights can hold their daytime maximum color temperature on either side of noon.

No actionable issues found. Tests were reviewed but not run.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Options["YAML, options, or service"] --> Settings["Check durations and build settings"]
  Settings --> Events["Existing sun events"]
  Events --> Original["Original sun position"]
  Events --> Plateau["Color-only position with plateau"]
  Original --> Brightness["Unchanged brightness"]
  Original --> Returned["Unchanged returned sun position"]
  Plateau --> Kelvin["Color temperature"]
  Kelvin --> RGB["RGB and other color values"]
Loading

Reviews (1) · Last reviewed commit: "docs: clarify plateau validation limits" · Reviewed by Greptile

@Charles-HL
Charles-HL force-pushed the feat/color-temperature-plateau branch from 046a4d5 to 919b4c7 Compare October 18, 2026 21:27
Add the optional color_temp_fixed_plateau_kelvin setting (between
min_color_temp and max_color_temp) for the fixed evening schedule. The
daytime maximum is kept; after it the color temperature descends along the
regular afternoon curve, reaches the target exactly and holds it for the last
hour before color_temp_fixed_plateau_end, whatever the season, then eases to
min_color_temp as before. The curve is sped up when the regular one would be
too late (summer), without any step. Unset keeps the previous behavior.

Validated in the options flow, YAML, the stored configuration and the
change_switch_settings service, with services, translations and docs.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant