Lumen is an intelligent adaptive brightness daemon for Linux that automatically adjusts your screen brightness based on ambient light sensors while learning from your manual adjustments over time.
🤖 Built with AI: This project was developed with assistance from Claude Sonnet 4.5 via GitHub Copilot, demonstrating the power of AI-assisted software development.
- 🔆 Automatic Brightness Control - Uses ambient light sensor data via iio-sensor-proxy
- 🧠 Adaptive Learning Algorithm - Remembers your preferences and improves over time
- 📈 Smooth Transitions - Gradual brightness changes (20 steps over 300ms)
- 🎯 Spline Interpolation - Smooth brightness curve between data points
- 💾 Persistent Learning - Saves learned preferences to disk
- 🔌 D-Bus Integration - No special permissions required (uses systemd-logind)
- 🎛️ Manual Control - Full replacement for
brightnessctlwith CLI commands - 🏗️ Clean Architecture - Well-organized code with domain/application/infrastructure layers
- ⚡ Async Runtime - Efficient resource usage with Tokio
- 🔒 Security Hardened - Systemd service with minimal permissions
# Clone and build
git clone <repository-url>
cd lumen
./install.sh
# Or manually
cargo build --release
mkdir -p ~/.local/bin
cp target/release/lumen ~/.local/bin/
cp lumen.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now lumen# Set brightness (0-100)
lumen set 50
# Get current brightness
lumen get
# Increase brightness
lumen increase # +10% (default)
lumen increase 5 # +5%
# Decrease brightness
lumen decrease # -10% (default)
lumen decrease 5 # -5%
# Auto-adjustment control
lumen auto-off # Disable auto-adjustment
lumen auto-on # Enable auto-adjustment
lumen auto-status # Check status# Run daemon (usually via systemd)
lumen daemon
# With debug logging
RUST_LOG=lumen=debug lumen daemonLumen provides a D-Bus API for integration with other applications (widgets, tray indicators, etc.):
# Get current brightness via D-Bus
gdbus call --session \
--dest org.lumen.Brightness \
--object-path /org/lumen/Brightness \
--method org.lumen.Brightness.GetBrightness
# Set brightness
gdbus call --session \
--dest org.lumen.Brightness \
--object-path /org/lumen/Brightness \
--method org.lumen.Brightness.SetBrightness 0.75
# Monitor brightness changes in real-time
dbus-monitor --session \
"type='signal',interface='org.lumen.Brightness',member='BrightnessChanged'"Available Signals:
BrightnessChanged(double)- Emitted when brightness changesAutoEnabledChanged(boolean)- Emitted when auto-adjustment is toggledLearningEnabledChanged(boolean)- Emitted when learning mode is toggled
See DBUS_API.md for complete API documentation with examples in Python, JavaScript, Rust, and Shell.
- Initial Curve - Starts with a sensible default brightness curve
- Monitoring - Watches for manual brightness adjustments
- Learning - When you manually adjust brightness, the daemon:
- Detects the difference between automatic and manual settings
- If difference > 5%, updates the brightness curve
- Finds nearby points (within 10 lux) or creates new ones
- Uses weighted averaging to blend old and new preferences
- Increases point weight (up to 5.0) for frequently adjusted levels
- Consolidation - Automatically merges close points when curve has >100 points
- Interpolation - Uses linear interpolation between learned points for smooth transitions
| Ambient Light (lux) | Screen Brightness (%) |
|---|---|
| 0 | 10% |
| 50 | 30% |
| 200 | 50% |
| 500 | 70% |
| 1000+ | 100% |
Built following Clean Architecture principles:
src/
├── domain/ # Business logic (framework-independent)
│ ├── entities.rs # BrightnessPoint, BrightnessCurve, BacklightState
│ ├── repositories.rs # Repository interfaces
│ └── services.rs # BrightnessService - core business logic
├── infrastructure/ # External integrations
│ ├── dbus.rs # iio-sensor-proxy D-Bus client
│ ├── backlight_dbus.rs # Brightness control via D-Bus (systemd-logind)
│ ├── control_dbus.rs # D-Bus API for external control
│ └── storage.rs # JSON persistence
├── application/ # Orchestration
│ ├── daemon.rs # Main daemon coordination
│ └── monitor.rs # Manual adjustment detection
└── main.rs # Entry point & CLI
- tokio (1.42) - Async runtime with full features
- async-trait - Async methods in traits
- futures - Stream processing
- async-stream - Async stream macros
- async-io (2.6) - I/O operations compatible with zbus executor
- zbus (5.1) - Modern D-Bus library for Rust
- serde (1.0) - Serialization framework
- serde_json (1.0) - JSON support
- tracing (0.1) - Structured logging
- tracing-subscriber (0.3) - Log output formatting
- anyhow (1.0) - Easy error handling
- thiserror (2.0) - Custom error types
- splines (4.3) - Spline interpolation for smooth curves
- directories (5.0) - Cross-platform config paths
- clap (4.5) - CLI argument parsing
Configuration is stored in ~/.config/lumen/brightness_curve.json:
{
"points": [
{
"lux": 0.0,
"brightness": 0.1,
"timestamp": "2025-11-27T...",
"weight": 1.0
}
],
"min_brightness": 0.05,
"max_brightness": 1.0
}Reset to defaults:
rm ~/.config/lumen/brightness_curve.json
systemctl --user restart lumen- Linux with ambient light sensor support
- iio-sensor-proxy (usually pre-installed)
- D-Bus system bus
- systemd-logind (for brightness control without root)
- Backlight device in
/sys/class/backlight/
Q: Why isn't the daemon changing brightness?
A: Check that iio-sensor-proxy is running (systemctl status iio-sensor-proxy) and lumen daemon is active (systemctl --user status lumen). Also ensure automatic adjustment is enabled (lumen auto-status).
Q: Can I temporarily disable automatic adjustment?
A: Yes, use lumen auto-off. To re-enable use lumen auto-on. This is useful when using idle brightness reduction features.
Q: Does lumen work as a replacement for brightnessctl?
A: Yes! Use lumen set, lumen get, lumen increase, lumen decrease for brightness control.
Q: Is there smooth brightness adjustment?
A: Yes! All brightness changes happen smoothly with 20 steps over 300ms.
Q: Service doesn't start automatically after system boot
A: Ensure the service is enabled: systemctl --user enable lumen.service. Check logs: journalctl --user -u lumen.service -b. The daemon has built-in retry logic for claiming the light sensor (up to 5 attempts with 1 second intervals) and automatically restarts on temporary failures. Use ./validate-startup-fix.sh to verify autostart functionality.
If lumen doesn't work after system reboot, run diagnostics:
# Check service status
systemctl --user status lumen.service
# View logs since boot
journalctl --user -u lumen.service -b
# Run validation test
./validate-startup-fix.shCommon issues:
- Sensor not ready at startup - Solved with automatic retries (see STARTUP_FIX.md)
- D-Bus session not ready - Service will automatically restart after 10 seconds
- Service not enabled - Run
systemctl --user enable lumen.service
# Temporarily enable debug mode
systemctl --user stop lumen.service
RUST_LOG=lumen=debug lumen daemon
# Or modify in ~/.config/systemd/user/lumen.service
# Environment="RUST_LOG=lumen=debug"
# Then: systemctl --user daemon-reload && systemctl --user restart lumen.service# Build and run directly
cargo build --release
RUST_LOG=lumen=debug ./target/release/lumen daemonPull requests are welcome! For major changes, please open an issue first.
MIT
- Claude Sonnet 4.5 (Anthropic) - AI assistant that helped design and implement this project
- GitHub Copilot - Development environment integration
- iio-sensor-proxy - Excellent D-Bus interface for sensors
- Rust community for amazing libraries
Lumen — это интеллектуальный демон адаптивной яркости для Linux, который автоматически регулирует яркость экрана на основе данных датчика освещённости, обучаясь на ваших ручных настройках.
🤖 Создано с помощью ИИ: Этот проект был разработан при поддержке Claude Sonnet 4.5 через GitHub Copilot, демонстрируя возможности разработки ПО с помощью искусственного интеллекта.
- 🔆 Автоматическое управление яркостью - Использует датчик освещённости через iio-sensor-proxy
- 🧠 Адаптивный алгоритм обучения - Запоминает ваши предпочтения и улучшается со временем
- 📈 Плавные переходы - Постепенное изменение яркости (20 шагов за 300мс)
- 🎯 Сплайн-интерполяция - Гладкая кривая яркости между точками данных
- 💾 Сохранение обучения - Запись предпочтений на диск
- 🔌 Интеграция с D-Bus - Не требует специальных прав (использует systemd-logind)
- 🎛️ Ручное управление - Полная замена
brightnessctlс CLI командами - 🏗️ Чистая архитектура - Хорошо организованный код со слоями domain/application/infrastructure
- ⚡ Асинхронный runtime - Эффективное использование ресурсов с Tokio
- 🔒 Усиленная безопасность - Systemd сервис с минимальными правами
# Клонировать и собрать
git clone <repository-url>
cd lumen
./install.sh
# Или вручную
cargo build --release
mkdir -p ~/.local/bin
cp target/release/lumen ~/.local/bin/
cp lumen.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now lumen# Установить яркость (0-100)
lumen set 50
# Получить текущую яркость
lumen get
# Увеличить яркость
lumen increase # +10% (по умолчанию)
lumen increase 5 # +5%
# Уменьшить яркость
lumen decrease # -10% (по умолчанию)
lumen decrease 5 # -5%
# Управление автоматической регулировкой
lumen auto-off # Отключить авто-регулировку
lumen auto-on # Включить авто-регулировку
lumen auto-status # Проверить статус# Запуск демона (обычно через systemd)
lumen daemon
# С отладочным логированием
RUST_LOG=lumen=debug lumen daemonLumen предоставляет D-Bus API для интеграции с другими приложениями (виджеты, индикаторы в трее и т.д.):
# Получить текущую яркость через D-Bus
gdbus call --session \
--dest org.lumen.Brightness \
--object-path /org/lumen/Brightness \
--method org.lumen.Brightness.GetBrightness
# Установить яркость
gdbus call --session \
--dest org.lumen.Brightness \
--object-path /org/lumen/Brightness \
--method org.lumen.Brightness.SetBrightness 0.75
# Мониторинг изменений яркости в реальном времени
dbus-monitor --session \
"type='signal',interface='org.lumen.Brightness',member='BrightnessChanged'"Доступные сигналы:
BrightnessChanged(double)- Отправляется при изменении яркостиAutoEnabledChanged(boolean)- Отправляется при переключении автоматической регулировкиLearningEnabledChanged(boolean)- Отправляется при переключении режима обучения
См. DBUS_API.md для полной документации API с примерами на Python, JavaScript, Rust и Shell.
Определение уровня освещённости:
Lumen подключается к iio-sensor-proxy через D-Bus (интерфейс net.hadess.SensorProxy) для непрерывного мониторинга уровня внешнего освещения. Датчик предоставляет показания освещённости в люксах (люмен на квадратный метр). Демон прослушивает сигнал D-Bus LightLevelChanged для получения обновлений в реальном времени при изменении освещения.
Адаптивный алгоритм:
- Начальная кривая - Стартует с разумной кривой яркости по умолчанию
- Мониторинг - Следит за ручными изменениями яркости
- Обучение - При ручной настройке яркости демон:
- Определяет разницу между автоматической и ручной настройкой
- Если разница > 5%, обновляет кривую яркости
- Находит близкие точки (в пределах 10 люкс) или создаёт новые
- Использует взвешенное усреднение для объединения старых и новых предпочтений
- Увеличивает вес точки (до 5.0) для часто настраиваемых уровней
- Консолидация - Автоматически объединяет близкие точки при >100 точках на кривой
- Интерполяция - Использует линейную интерполяцию между изученными точками для плавных переходов
| Освещённость (lux) | Яркость экрана (%) |
|---|---|
| 0 | 10% |
| 50 | 30% |
| 200 | 50% |
| 500 | 70% |
| 1000+ | 100% |
Построено по принципам Чистой Архитектуры:
src/
├── domain/ # Бизнес-логика (независимая от фреймворков)
│ ├── entities.rs # BrightnessPoint, BrightnessCurve, BacklightState
│ ├── repositories.rs # Интерфейсы репозиториев
│ └── services.rs # BrightnessService - основная бизнес-логика
├── infrastructure/ # Внешние интеграции
│ ├── dbus.rs # D-Bus клиент для iio-sensor-proxy
│ ├── backlight_dbus.rs # Управление яркостью через D-Bus (systemd-logind)
│ ├── control_dbus.rs # D-Bus API для внешнего управления
│ └── storage.rs # JSON персистентность
├── application/ # Оркестрация
│ ├── daemon.rs # Координация главного демона
│ └── monitor.rs # Обнаружение ручных настроек
└── main.rs # Точка входа и CLI
- iio-sensor-proxy - D-Bus сервис, предоставляющий доступ к данным датчика освещённости (ALS)
- Читает данные из
/sys/bus/iio/devices/iio:deviceX/ - Предоставляет показания датчика через D-Bus по адресу
net.hadess.SensorProxy - Обычно предустановлен в современных дистрибутивах Linux
- Установка на Arch:
sudo pacman -S iio-sensor-proxy - Установка на Ubuntu/Debian:
sudo apt install iio-sensor-proxy - Установка на Fedora:
sudo dnf install iio-sensor-proxy
- Читает данные из
- tokio (1.42) - Асинхронный runtime с полным набором функций
- async-trait - Асинхронные методы в трейтах
- futures - Обработка потоков
- async-stream - Макросы для асинхронных потоков
- async-io (2.6) - I/O операции, совместимые с исполнителем zbus
- zbus (5.1) - Современная библиотека D-Bus для Rust
- serde (1.0) - Фреймворк сериализации
- serde_json (1.0) - Поддержка JSON
- tracing (0.1) - Структурированное логирование
- tracing-subscriber (0.3) - Форматирование вывода логов
- anyhow (1.0) - Упрощённая обработка ошибок
- thiserror (2.0) - Пользовательские типы ошибок
- splines (4.3) - Сплайн-интерполяция для гладких кривых
- directories (5.0) - Кроссплатформенные пути конфигурации
- clap (4.5) - Парсинг аргументов CLI
Конфигурация хранится в ~/.config/lumen/brightness_curve.json:
{
"points": [
{
"lux": 0.0,
"brightness": 0.1,
"timestamp": "2025-11-27T...",
"weight": 1.0
}
],
"min_brightness": 0.05,
"max_brightness": 1.0
}Сброс к настройкам по умолчанию:
rm ~/.config/lumen/brightness_curve.json
systemctl --user restart lumen- Linux с поддержкой датчика освещённости (ALS)
- Большинство современных ноутбуков имеют IIO-датчики ALS
- Проверить наличие датчика:
ls /sys/bus/iio/devices/
- iio-sensor-proxy - Должен быть установлен и запущен
- Проверить статус:
systemctl status iio-sensor-proxy - Протестировать датчик:
gdbus introspect --system --dest net.hadess.SensorProxy --object-path /net/hadess/SensorProxy
- Проверить статус:
- Системная шина D-Bus - Для получения данных с датчика и управления яркостью
- systemd-logind - Для управления яркостью без root-прав
- Устройство подсветки в
/sys/class/backlight/- Обычно
intel_backlight,amdgpu_bl0или подобное
- Обычно
Q: Почему демон не меняет яркость?
A: Проверьте, что iio-sensor-proxy запущен (systemctl status iio-sensor-proxy) и демон lumen работает (systemctl --user status lumen). Также убедитесь, что автоматическая регулировка включена (lumen auto-status).
Q: Можно ли временно отключить автоматическую регулировку?
A: Да, используйте lumen auto-off. Для включения - lumen auto-on. Это полезно при использовании функций уменьшения яркости при простое системы.
Q: Работает ли lumen как замена brightnessctl?
A: Да! Используйте lumen set, lumen get, lumen increase, lumen decrease для управления яркостью.
Q: Есть ли плавная регулировка яркости?
A: Да! Все изменения яркости происходят плавно с 20 шагами за 300мс.
Q: Сервис не запускается автоматически при загрузке системы
A: Убедитесь, что сервис включен: systemctl --user enable lumen.service. Также проверьте логи: journalctl --user -u lumen.service -b. Демон имеет встроенную логику повторных попыток захвата датчика освещенности (до 5 попыток с интервалом 1 секунда), а также автоматически перезапускается при временных сбоях. Для проверки работоспособности автозапуска используйте ./validate-startup-fix.sh.
Если после перезагрузки системы lumen не работает, выполните диагностику:
# Проверьте статус сервиса
systemctl --user status lumen.service
# Посмотрите логи с момента загрузки
journalctl --user -u lumen.service -b
# Запустите валидационный тест
./validate-startup-fix.shТипичные проблемы:
- Датчик не готов при старте - Решено автоматическими повторными попытками (см. STARTUP_FIX.md)
- D-Bus сессия не готова - Сервис автоматически перезапустится через 10 секунд
- Сервис не включен - Выполните
systemctl --user enable lumen.service
# Временно включить отладочный режим
systemctl --user stop lumen.service
RUST_LOG=lumen=debug lumen daemon
# Или изменить в ~/.config/systemd/user/lumen.service
# Environment="RUST_LOG=lumen=debug"
# Затем: systemctl --user daemon-reload && systemctl --user restart lumen.service# Собрать и запустить напрямую
cargo build --release
RUST_LOG=lumen=debug ./target/release/lumen daemonPull request'ы приветствуются! Для больших изменений сначала откройте issue.
MIT
- Claude Sonnet 4.5 (Anthropic) - ИИ-ассистент, который помог спроектировать и реализовать этот проект
- GitHub Copilot - Интеграция с средой разработки
- iio-sensor-proxy - Отличный D-Bus интерфейс к датчикам
- Сообщество Rust за потрясающие библиотеки
- CLI интерфейс для управления яркостью (замена brightnessctl)
- D-Bus API для внешнего управления
- Управление автоматической регулировкой
- Плавная регулировка яркости
- Профили яркости (например, "работа", "дом", "ночь")
- Веб-интерфейс для визуализации кривой яркости
- Поддержка нескольких мониторов
- Экспорт/импорт настроек
- Машинное обучение для более сложных паттернов