- Rust 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .forgejo/workflows | ||
| assets | ||
| debian | ||
| src | ||
| Cargo.toml | ||
| config.example.toml | ||
| luxd.service | ||
| README.md | ||
🔆 luxd
A utility that automatically adjusts monitor brightness based on ambient light sensor readings by using configurable shell commands.
How it works
- Polls a sensor value: It runs the
get_commandeveryinterval_msmilliseconds and parses the standard output as a lux reading (e.g.,cat /sys/bus/iio/devices/iio:device0/in_illuminance_raw). - Maps lux to brightness: The lux reading is converted to a target brightness value using linear interpolation based on the configured
curvereference points. - Applies hysteresis: The
set_commandonly executes if the target brightness differs from the last applied value by more thanhysteresis. This prevents rapid flickering when the sensor reading fluctuates near a transition point. - Rounds and sets: The brightness is rounded to the nearest multiple of
round(e.g.,0.01or1) before theset_commandis run, replacing{}with the calculated value.
Config
Copy config.example.toml to config.toml and edit it:
| Field | Description |
|---|---|
get_command |
Command template whose stdout is parsed as lux (required). |
set_command |
Command template; {} → brightness (required). |
interval_ms |
Polling interval. |
log_level |
Log verbosity: error, info, debug, or off. |
hysteresis |
Dead band (in brightness units). 0 disables (not recommended). |
round |
Brightness rounded to nearest multiple of this step. 0 disables. |
curve |
[[curve]] points of lux → brightness, >= 2 required. |
The config path defaults to config.toml; override with the
LUXD_CONFIG environment variable.
Ambient light sensor
A cheap DIY USB sensor can be built using a microcontroller and a light sensor. See e.g. RP2040_USBHID_Ambient-Light-Sensor.
There are also many Zigbee or Bluetooth sensors out there which report illuminance (albeit not very reliably, especially battery-powered ones). Once connected to a smart home system, they can be usually accessed via its API. Example command for Home Assistant can be found in example config.
kscreen-doctor
To use with KDE's kscreen-doctor, use this command to find out your monitor ID:
kscreen-doctor --outputs
Then use the ID (e.g. 1 or DP-3) in the set_command template:
set_command = "kscreen-doctor output.DP-3.brightness.{}"
kscreen-doctor expects brightness values in the range 0-100.
Packages
Arch Linux users can install from the AUR:
paru -S luxd
Debian/Ubuntu packages and binaries can be downloaded from the release page.
Build & run
cargo build --release
cp config.example.toml config.toml # then edit it
./target/release/luxd
Log levels
log_level = "info" # in config.toml
error— only failures (sensor reads, set commands)info— also logs each brightness change, with the lux reading on the same linedebug— also logs every lux read, computed target, and hysteresis decision
The RUST_LOG environment variable overrides log_level if set, e.g.:
RUST_LOG=debug ./target/release/luxd
Systemd service
To run as a userspace systemd service, copy the service file and adjust it:
cp luxd.service ~/.config/systemd/user/luxd.service
ExecStart=/path/to/luxd/luxd
WorkingDirectory=/path/to/luxd
Then enable and start the service:
systemctl --user enable --now luxd.service
To monitor the service logs:
journalctl --user -f -u luxd.service
AI
This project was developed with LLM assistance.
License
Licensed under GPL-3.0 or later.