Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lumen - Adaptive Brightness Daemon

English | Русский


English

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.

✨ Features

  • 🔆 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 brightnessctl with 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

🚀 Quick Start

# 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

📖 Usage

CLI Commands (brightnessctl replacement)

# 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

Daemon Mode

# Run daemon (usually via systemd)
lumen daemon

# With debug logging
RUST_LOG=lumen=debug lumen daemon

D-Bus API

Lumen 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 changes
  • AutoEnabledChanged(boolean) - Emitted when auto-adjustment is toggled
  • LearningEnabledChanged(boolean) - Emitted when learning mode is toggled

See DBUS_API.md for complete API documentation with examples in Python, JavaScript, Rust, and Shell.

🧠 How Learning Works

  1. Initial Curve - Starts with a sensible default brightness curve
  2. Monitoring - Watches for manual brightness adjustments
  3. 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
  4. Consolidation - Automatically merges close points when curve has >100 points
  5. Interpolation - Uses linear interpolation between learned points for smooth transitions

🎯 Default Brightness Curve

Ambient Light (lux) Screen Brightness (%)
0 10%
50 30%
200 50%
500 70%
1000+ 100%

🏗️ Architecture

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

📦 Dependencies

Core Runtime

  • 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

D-Bus Communication

  • zbus (5.1) - Modern D-Bus library for Rust

Serialization

  • serde (1.0) - Serialization framework
  • serde_json (1.0) - JSON support

Logging & Errors

  • tracing (0.1) - Structured logging
  • tracing-subscriber (0.3) - Log output formatting
  • anyhow (1.0) - Easy error handling
  • thiserror (2.0) - Custom error types

Mathematics

  • splines (4.3) - Spline interpolation for smooth curves

Utilities

  • directories (5.0) - Cross-platform config paths
  • clap (4.5) - CLI argument parsing

⚙️ Configuration

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

🔧 Requirements

  • 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/

💡 FAQ

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.

🔍 Troubleshooting

Service not working after reboot

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.sh

Common issues:

  1. Sensor not ready at startup - Solved with automatic retries (see STARTUP_FIX.md)
  2. D-Bus session not ready - Service will automatically restart after 10 seconds
  3. Service not enabled - Run systemctl --user enable lumen.service

Debug logging

# 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

Testing without installation

# Build and run directly
cargo build --release
RUST_LOG=lumen=debug ./target/release/lumen daemon

🤝 Contributing

Pull requests are welcome! For major changes, please open an issue first.

📝 License

MIT

🙏 Acknowledgments

  • 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

Russian

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

📖 Использование

CLI команды (замена brightnessctl)

# Установить яркость (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 daemon

D-Bus API

Lumen предоставляет 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 для получения обновлений в реальном времени при изменении освещения.

Адаптивный алгоритм:

  1. Начальная кривая - Стартует с разумной кривой яркости по умолчанию
  2. Мониторинг - Следит за ручными изменениями яркости
  3. Обучение - При ручной настройке яркости демон:
    • Определяет разницу между автоматической и ручной настройкой
    • Если разница > 5%, обновляет кривую яркости
    • Находит близкие точки (в пределах 10 люкс) или создаёт новые
    • Использует взвешенное усреднение для объединения старых и новых предпочтений
    • Увеличивает вес точки (до 5.0) для часто настраиваемых уровней
  4. Консолидация - Автоматически объединяет близкие точки при >100 точках на кривой
  5. Интерполяция - Использует линейную интерполяцию между изученными точками для плавных переходов

🎯 Кривая яркости по умолчанию

Освещённость (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

Rust крейты

Основной Runtime
  • tokio (1.42) - Асинхронный runtime с полным набором функций
  • async-trait - Асинхронные методы в трейтах
  • futures - Обработка потоков
  • async-stream - Макросы для асинхронных потоков
  • async-io (2.6) - I/O операции, совместимые с исполнителем zbus

D-Bus коммуникация

  • 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 или подобное

💡 FAQ

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.

🔍 Troubleshooting

Сервис не работает после перезагрузки

Если после перезагрузки системы lumen не работает, выполните диагностику:

# Проверьте статус сервиса
systemctl --user status lumen.service

# Посмотрите логи с момента загрузки
journalctl --user -u lumen.service -b

# Запустите валидационный тест
./validate-startup-fix.sh

Типичные проблемы:

  1. Датчик не готов при старте - Решено автоматическими повторными попытками (см. STARTUP_FIX.md)
  2. D-Bus сессия не готова - Сервис автоматически перезапустится через 10 секунд
  3. Сервис не включен - Выполните 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 daemon

🤝 Участие в разработке

Pull request'ы приветствуются! Для больших изменений сначала откройте issue.

📝 Лицензия

MIT

🙏 Благодарности

  • Claude Sonnet 4.5 (Anthropic) - ИИ-ассистент, который помог спроектировать и реализовать этот проект
  • GitHub Copilot - Интеграция с средой разработки
  • iio-sensor-proxy - Отличный D-Bus интерфейс к датчикам
  • Сообщество Rust за потрясающие библиотеки

🗺️ Дорожная карта

  • CLI интерфейс для управления яркостью (замена brightnessctl)
  • D-Bus API для внешнего управления
  • Управление автоматической регулировкой
  • Плавная регулировка яркости
  • Профили яркости (например, "работа", "дом", "ночь")
  • Веб-интерфейс для визуализации кривой яркости
  • Поддержка нескольких мониторов
  • Экспорт/импорт настроек
  • Машинное обучение для более сложных паттернов

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages