Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions illuminanced.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ check_period_in_seconds = 1
light_steps = 10
min_backlight = 70
step_barrier = 0.1
backlight_transition = "Instant"
# backlight_transition_step_count and backlight_transition_time_seconds are used only when backlight_transition
# is set to "linear"
backlight_transition_step_count = 20
backlight_transition_time_seconds = 1
max_backlight_file = "/sys/class/backlight/intel_backlight/max_brightness"
backlight_file = "/sys/class/backlight/intel_backlight/brightness"
illuminance_file = "/sys/bus/acpi/devices/ACPI0008:00/iio:device0/in_illuminance_raw"
Expand Down
18 changes: 18 additions & 0 deletions src/brightness_transition.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#[derive(Debug)]
pub enum BrightnessTransition {
Instant,
Linear,
}

const INSTANT_STR: &str = "INSTANT";
const LINEAR_STR: &str = "LINEAR";

impl BrightnessTransition {
pub fn from_str(value: &str) -> Option<Self> {
match value.to_uppercase().as_str() {
INSTANT_STR => Some(Self::Instant),
LINEAR_STR => Some(Self::Linear),
_ => None,
}
}
}
17 changes: 17 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::brightness_transition::BrightnessTransition;
use crate::ErrorCode;
use crate::LightPoint;
use log::LevelFilter;
Expand Down Expand Up @@ -92,6 +93,22 @@ impl Config {
.unwrap_or("/sys/bus/acpi/devices/ACPI0008:00/iio:device0/in_illuminance_raw")
}

pub fn backlight_transition(&self) -> BrightnessTransition {
self.get_str("general", "backlight_transition")
.and_then(|s| BrightnessTransition::from_str(s))
.unwrap_or(BrightnessTransition::Instant)
}

pub fn backlight_transition_step_count(&self) -> u32 {
self.get_u32("general", "backlight_transition_step_count")
.unwrap_or(20)
}

pub fn backlight_transition_time_seconds(&self) -> u32 {
self.get_u32("general", "backlight_transition_time_seconds")
.unwrap_or(1)
}

pub fn light_points(&self) -> Result<Vec<LightPoint>, ErrorCode> {
if self.table.is_none() {
return Ok(self.default_ligth_points());
Expand Down
85 changes: 77 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ use simplelog::{
use std::env;
use std::fs::{File, OpenOptions};
use std::io::prelude::*;
use std::sync::mpsc::Sender;
use std::thread::sleep;
use std::time::Duration;
use syslog::Facility;

mod brightness_transition;
mod config;
mod discrete_value;
mod kalman;
Expand Down Expand Up @@ -105,6 +109,7 @@ fn main_loop(
max_brightness: u32,
mut switch_monitor: switch_monitor::SwitchMonitor,
illuminance_filename: &str,
tx: Sender<u32>,
) -> Result<(), ErrorCode> {
let mut kalman = Kalman::new(
config.kalman_q(),
Expand All @@ -118,7 +123,13 @@ fn main_loop(
config.step_barrier(),
);
debug!("k: s:{:?}", stepped_brightness);
let mut brightness_to_send = None;
loop {
if let Some(brightness) = brightness_to_send {
if tx.send(brightness).is_ok() {
brightness_to_send = None;
}
}
match read_file_to_u32(illuminance_filename) {
Some(illuminance) => {
let illuminance_k = kalman.process(illuminance as f32);
Expand All @@ -129,7 +140,9 @@ fn main_loop(
"raw {}, kalman {}, new level {} new brightness {}",
illuminance, illuminance_k, brightness, new
);
set_brightness(config, new);
if tx.send(new).is_err() {
brightness_to_send = Some(new);
}
}
}
_ => error!("Cannot read illuminance"),
Expand All @@ -140,6 +153,42 @@ fn main_loop(
}
}

fn linear_ease_set_brightness(config: &Config, value: u32) {
let old_brightness = read_file_to_u32(config.backlight_filename());
if matches!(
config.backlight_transition(),
brightness_transition::BrightnessTransition::Linear
) {
if let Some(old_brightness) = old_brightness {
let transition_step_length_ms = (config.backlight_transition_time_seconds() as f32
/ config.backlight_transition_step_count() as f32
* 1000_f32) as u64;
if value > old_brightness {
let change = (value.saturating_sub(old_brightness)) as f32
/ config.backlight_transition_step_count() as f32;
for i in 1..config.backlight_transition_step_count() {
set_brightness(
config,
old_brightness.saturating_add((change * i as f32) as u32),
);
sleep(Duration::from_millis(transition_step_length_ms));
}
} else {
let change = (old_brightness.saturating_sub(value)) as f32
/ config.backlight_transition_step_count() as f32;
for i in 1..config.backlight_transition_step_count() {
set_brightness(
config,
old_brightness.saturating_sub((change * i as f32) as u32),
);
sleep(Duration::from_millis(transition_step_length_ms));
}
}
}
}
set_brightness(config, value);
}

fn set_brightness(config: &Config, value: u32) {
if let Err(e) = write_u32_to_file(config.backlight_filename(), value) {
error!("Cannot set brightness: {}", e);
Expand Down Expand Up @@ -334,13 +383,33 @@ fn run() -> Result<(), ErrorCode> {
})?;
}

main_loop(
&config,
&light_convertor,
max_brightness,
switch_monitor,
&illuminance_filename,
)
let (tx, rx) = std::sync::mpsc::channel::<u32>();
std::thread::scope(|scope| {
scope.spawn(|| {
let rx = rx;
let config = &config;
loop {
match rx.recv() {
Ok(brightness) => {
linear_ease_set_brightness(config, brightness);
}
Err(e) => {
error!("Error on receiving channel: {}", e);
break;
}
}
}
});

main_loop(
&config,
&light_convertor,
max_brightness,
switch_monitor,
&illuminance_filename,
tx,
)
})
}

fn main() {
Expand Down