use chrono::Local; use hinoirisetr::{apply_settings, compute_settings}; use std::sync::{ atomic::{AtomicBool, Ordering}, Arc, }; use std::time::Duration; use tokio::{ io::{AsyncBufReadExt, BufReader}, net::UnixListener, sync::Notify, time::sleep, }; const SOCKET_PATH: &str = "/tmp/hinoirisetr.sock"; async fn socket_server(disabled: Arc, notify: Arc) { let _ = std::fs::remove_file(SOCKET_PATH); let listener = UnixListener::bind(SOCKET_PATH).expect("Failed to bind socket"); loop { let (stream, _) = listener.accept().await.unwrap(); let mut lines = BufReader::new(stream).lines(); if let Ok(Some(line)) = lines.next_line().await { match line.trim() { "disable" => { disabled.store(true, Ordering::SeqCst); notify.notify_one(); } "enable" => { disabled.store(false, Ordering::SeqCst); notify.notify_one(); } "toggle" => { let now = !disabled.load(Ordering::SeqCst); disabled.store(now, Ordering::SeqCst); notify.notify_one(); } "status" => { // compute current temp/gamma let now = Local::now(); let (cur_temp, cur_gamma) = compute_settings(now); println!( "dimming is {} — temp: {}K, gamma: {}%", if disabled.load(Ordering::SeqCst) { "disabled" } else { "enabled" }, cur_temp, cur_gamma ); } _ => eprintln!("unknown command: {}", line.trim()), } } } } #[tokio::main] async fn main() { let disabled = Arc::new(AtomicBool::new(false)); let notify = Arc::new(Notify::new()); // Spawn control socket server { let disabled = Arc::clone(&disabled); let notify = Arc::clone(¬ify); tokio::spawn(async move { socket_server(disabled, notify).await; }); } loop { if disabled.load(Ordering::SeqCst) { apply_settings(hinoirisetr::TEMP_DAY, hinoirisetr::GAMMA_DAY); } else { let now = Local::now(); let (temp, gamma) = compute_settings(now); apply_settings(temp, gamma); } tokio::select! { _ = sleep(Duration::from_secs(300)) => {}, _ = notify.notified() => {}, } } }