Add a color (2 colors can be now defined for a machine).
[temp2RGB.git] / src / main_loop.rs
1 use std::{
2 sync::{
3 atomic::{AtomicBool, Ordering},
4 Arc,
5 },
6 time::{self, Duration},
7 };
8
9 use crate::{consts, machine, rgb, settings, timer, winring0};
10
11 pub fn main_loop(completed: Arc<AtomicBool>) {
12 if consts::FREQ_REFRESHING_RGB > consts::FREQ_TEMP_POLLING {
13 panic!("Polling frequency must be greater or equal than RGB refresh frequency");
14 }
15
16 if consts::FREQ_TEMP_POLLING % consts::FREQ_REFRESHING_RGB != 0 {
17 panic!("Polling frequency must be a multiple of RGB refresh frequency");
18 }
19
20 winring0::init();
21
22 let sleep = timer::Sleep::new();
23
24 let file_conf_path = if cfg!(debug_assertions) {
25 String::from(consts::FILE_CONF)
26 } else {
27 String::from(
28 dirs::config_dir()
29 .unwrap()
30 .join(consts::SERVICE_NAME)
31 .join(consts::FILE_CONF)
32 .to_str()
33 .unwrap(),
34 )
35 };
36
37 let settings = settings::Settings::read(&file_conf_path).expect("Cannot load settings");
38 println!("Settings: {settings:?}");
39
40 let mut machine: Box<dyn machine::Machine> = match settings.machine_name {
41 settings::MachineName::Jiji => {
42 Box::new(machine::MachineJiji::new().expect("Unable to create MachineJiji"))
43 }
44 settings::MachineName::LyssMetal => {
45 Box::new(machine::MachineLyssMetal::new().expect("Unable to create MachineLyssMetal"))
46 }
47 };
48
49 let mut kernel = [0f32; consts::KERNEL_SIZE_SAMPLES];
50 let mut current_pos = 0usize;
51
52 let mut tick = 0i64;
53 let period = Duration::from_micros(1_000_000u64 / consts::FREQ_TEMP_POLLING as u64);
54
55 loop {
56 if completed.load(Ordering::Relaxed) {
57 break;
58 }
59
60 let time_beginning_loop = time::Instant::now();
61
62 let temp = (machine.get_cpu_tmp() + machine.get_gpu_tmp()) / 2f32;
63 kernel[current_pos] = temp;
64 current_pos = (current_pos + 1) % consts::KERNEL_SIZE_SAMPLES;
65 let mean_temp = {
66 let mut s = 0f32;
67 for t in kernel {
68 s += t;
69 }
70 s / kernel.len() as f32
71 };
72
73 let normalized_temp = num::clamp(
74 (mean_temp - settings.cold_temperature)
75 / (settings.hot_temperature - settings.cold_temperature),
76 0f32,
77 1f32,
78 ); // Between 0 (cold) and 1 (hot).
79
80 let color_1 =
81 rgb::linear_interpolation(settings.cold_color_1, settings.hot_color_1, normalized_temp);
82
83 let color_2 = match (settings.cold_color_2, settings.hot_color_2) {
84 (Some(cold_color), Some(hot_color)) => Some(rgb::linear_interpolation(
85 cold_color,
86 hot_color,
87 normalized_temp,
88 )),
89 _ => None,
90 };
91
92 // println!("normalized_temp: {normalized_temp}");
93
94 if tick % (consts::FREQ_TEMP_POLLING / consts::FREQ_REFRESHING_RGB) as i64 == 0 {
95 println!("Update RGB: {color_1:?}/{color_2:?}, temp: {mean_temp}");
96 machine.set_color_1(&color_1);
97 if color_2.is_some() {
98 machine.set_color_2(&color_2.unwrap());
99 } else {
100 machine.set_color_2(&color_1);
101 }
102 }
103
104 let elapsed = time::Instant::now() - time_beginning_loop;
105 if elapsed < period {
106 let to_wait = period - elapsed;
107 sleep.wait(to_wait);
108 }
109 tick += 1;
110 }
111
112 // println!("Press any key to continue...");
113 // std::io::stdin().read_line(&mut String::new()).unwrap();
114
115 winring0::deinit();
116 }