Skip to content

guitaripod/circadia

Repository files navigation

Circadia

License: GPL v3 Rust KDE Plasma 6 Arch Linux

Melanopic-aware color temperature daemon for KDE Plasma Wayland.

Circadia replaces KDE's built-in Night Color with a multi-phase solar elevation profile inspired by f.lux. Instead of a single day/night transition, it continuously interpolates color temperature across five twilight phases — producing gradual shifts that track the sun's actual position. At high latitudes where twilight lasts hours, this makes a real difference.

Why

Blue light suppresses melatonin production via melanopsin-containing retinal ganglion cells (ipRGCs). These cells are most sensitive around 480nm — right in the peak emission of typical displays at 6500K. Research shows that reducing display color temperature to 1900–2700K at night cuts melanopic irradiance by 5–10x, meaningfully reducing circadian disruption.

KDE Night Color does a basic warm/cool toggle. f.lux gets this right with multi-phase solar profiles, but it's closed-source and X11-only on Linux. Circadia fills the gap: open-source, Wayland-native, research-informed defaults.

Install

git clone https://github.com/guitaripod/circadia
cd circadia
makepkg -si
systemctl --user enable --now circadia

That's it. Circadia auto-detects your location from KDE settings, generates a config, and starts managing your display temperature.

What happens on install
  1. makepkg builds a native Arch package with a 1.4MB stripped binary
  2. pacman installs the binary, systemd service, and example config
  3. The systemd user service starts circadia in the background
  4. On first run, circadia reads your coordinates from ~/.config/knighttimerc (KDE's location config) and writes ~/.config/circadia/config.toml
  5. It switches KDE Night Color to constant mode and begins controlling the temperature
  6. On shutdown (or systemctl stop), it restores your original Night Color settings

Usage

circadia              # start daemon (foreground)
circadia status       # show current state
circadia preview 2700 # override temperature
circadia reset        # clear override
Example status output
elevation:   -8.5°
phase:       Nautical twilight
temperature: 3106K
updated:     2026-03-09T19:09:35+02:00

Default Profile

Temperature is a continuous function of solar elevation, linearly interpolated between these waypoints:

Elevation Temperature Phase
≥ +6° 6500K Daylight
4500K Golden hour
-6° 3400K Civil twilight
-12° 2700K Nautical twilight
≤ -18° 1900K Night

At 60°N latitude in March, the sun takes over two hours to travel from 0° to -18° — so the transition from 4500K to 1900K happens gradually over that entire period. No abrupt shifts.

Why these specific temperatures

The waypoints target melanopic response, not just visual comfort:

  • 6500K — neutral daylight, full alertness, no filtering needed
  • 4500K — mild warm shift as the sun sets, roughly matching golden hour ambient light
  • 3400K — equivalent to warm white LED lighting, typical evening indoor light
  • 2700K — incandescent-equivalent, significant melanopic reduction (~70% less than 6500K)
  • 1900K — candlelight-equivalent, near-zero melanopic stimulation

The exact melanopic impact depends on your display's spectral power distribution (SPD), which varies by panel technology. These defaults are conservative and work well across most displays. Tune the waypoints in config if you have specific SPD data for your monitor.

Configuration

Auto-created at ~/.config/circadia/config.toml on first run.

[location]
latitude = 60.16952
longitude = 24.93545
elevation_meters = 0.0

[[profile.waypoints]]
elevation = -18.0
temperature = 1900

[[profile.waypoints]]
elevation = -12.0
temperature = 2700

[[profile.waypoints]]
elevation = -6.0
temperature = 3400

[[profile.waypoints]]
elevation = 0.0
temperature = 4500

[[profile.waypoints]]
elevation = 6.0
temperature = 6500

[daemon]
update_interval_secs = 10
Configuration reference

[location]

  • latitude / longitude — decimal degrees. Auto-detected from KDE on first run.
  • elevation_meters — altitude above sea level. Affects sunrise/sunset times slightly.

[[profile.waypoints]]

  • elevation — solar elevation angle in degrees. Negative = below horizon.
  • temperature — color temperature in Kelvin (1000–6500). Must be sorted by ascending elevation, minimum 2 waypoints.

[daemon]

  • update_interval_secs — how often to recalculate and apply temperature. Default 10s.

How It Works

Architecture

Circadia is a ~550-line Rust daemon with no async runtime and no D-Bus library.

  1. On startup, saves existing KDE Night Color settings and switches to constant mode
  2. Every 10 seconds: calculates solar elevation using the NREL SPA algorithm (±0.0003° accuracy), interpolates temperature from the waypoint profile, and writes the result to kwinrc via kwriteconfig6 --notify
  3. KWin's KConfigWatcher detects the change and applies the new temperature natively through its color management pipeline — smooth built-in transitions, no OSD popups
  4. On SIGTERM/SIGINT, restores original Night Color settings and cleans up

The preview command writes an override file to $XDG_RUNTIME_DIR/circadia.override. The daemon checks this file each cycle and uses the override value instead of the calculated temperature. reset deletes the file.

Why not use KWin's preview() API

KWin's NightLight D-Bus interface exposes a preview(temperature) method. It works, but it shows an OSD popup ("Color Temperature Preview") on every call — hardcoded in KWin's source with no way to suppress it. Calling it every 10 seconds is unusable.

Instead, circadia writes directly to kwinrc and uses --notify to trigger KWin's config watcher, which applies the temperature natively without any popup.

Uninstall

systemctl --user disable --now circadia
sudo pacman -R circadia

Night Color settings are restored to their original state when the daemon stops.

Requirements

  • KDE Plasma 6 on Wayland
  • kwriteconfig6 / kreadconfig6 (provided by kconfig, a core KDE dependency)

About

Melanopic-aware color temperature daemon for KDE Plasma Wayland

Resources

License

Stars

Watchers

Forks

Contributors

Languages