Эх сурвалжийг харах

Factor out Sensor trait

This also now allows us to have multiple temperature sensors
Thomas Dy 9 жил өмнө
parent
commit
8f7c606e5f
1 өөрчлөгдсөн 72 нэмэгдсэн , 28 устгасан
  1. 72 28
      src/sensors.rs

+ 72 - 28
src/sensors.rs

@@ -4,46 +4,90 @@ use comm;
 use comm::Channel;
 use config::Config;
 use std::fs::File;
+use std::io::SeekFrom;
 use std::io::prelude::*;
 use std::thread;
 
-pub fn sensors(tx: &Channel, _config: &Config) {
-    loop {
-        let right = vec![
-            temp(),
-            time_utc(),
-            datetime()
-        ];
+trait Sensor {
+    fn status(&mut self) -> String;
+}
 
-        comm::send(tx, "sensors", &reduce(right));
-        thread::sleep_ms(1000);
+struct TempSensor {
+    file: File
+}
+
+impl TempSensor {
+    fn new(zone: &str) -> TempSensor {
+        let path = format!("/sys/class/thermal/{}/temp", zone);
+        TempSensor {
+            file: File::open(path).unwrap()
+        }
     }
 }
 
-fn reduce(arr: Vec<String>) -> String {
-    let result = arr.into_iter()
-        .fold("".to_string(), |acc, elem| format!("{} | {}", acc, elem));
-    if result.len() > 0 { result[3..].to_string() } else { result }
+impl Sensor for TempSensor {
+    fn status(&mut self) -> String {
+        let mut s = String::new();
+        self.file.read_to_string(&mut s).ok().expect("Could not read temperature stats");
+        let i : Option<u32> = s.trim().parse().ok();
+        self.file.seek(SeekFrom::Start(0)).ok().expect("Could not reread temperature");
+
+        match i {
+            Some(i) => format!("{}°C", i/1000),
+            None => "?°C".to_string(),
+        }
+    }
 }
 
-fn temp() -> String {
-    let path = "/sys/class/thermal/thermal_zone0/temp";
-    let mut f = File::open(path).unwrap();
-    let mut s = String::new();
-    assert!(f.read_to_string(&mut s).is_ok());
-    let i : u32 = s.trim().parse().unwrap();
-    format!("{}°C", i/1000)
+struct TimeSensor {
+    format: String,
+    is_utc: bool
 }
 
-fn datetime() -> String {
-    let now = time::now();
-    let localtime = time::strftime("%Y-%m-%d %H:%M", &now);
-    localtime.unwrap()
+impl TimeSensor {
+    fn new(format: &str, is_utc: bool) -> TimeSensor {
+        TimeSensor {
+            format: format.to_string(),
+            is_utc: is_utc
+        }
+    }
 }
 
-fn time_utc() -> String {
-    let now = time::now_utc();
-    let utctime = time::strftime("%H:%M", &now);
-    format!("UTC {}", utctime.unwrap())
+impl Sensor for TimeSensor {
+    fn status(&mut self) -> String {
+        let now =
+            if self.is_utc {
+                time::now_utc()
+            }
+            else {
+                time::now()
+            };
+
+
+        let time = time::strftime(&self.format, &now);
+        time.unwrap()
+    }
+}
+
+pub fn sensors(tx: &Channel, _config: &Config) {
+    let mut sensors: Vec<Box<Sensor>> = vec![
+        Box::new(TempSensor::new("thermal_zone0")),
+        Box::new(TimeSensor::new("%Y-%m-%d %H:%M", false)),
+        Box::new(TimeSensor::new("UTC %H:%M", true))
+    ];
+
+    loop {
+        let status = sensors.iter_mut()
+            .map(|sensor| sensor.status())
+            .collect::<Vec<String>>();
+
+        comm::send(tx, "sensors", &reduce(status));
+        thread::sleep_ms(1000);
+    }
 }
 
+fn reduce(arr: Vec<String>) -> String {
+    let result = arr.into_iter()
+        .fold("".to_string(), |acc, elem| format!("{} | {}", acc, elem));
+    if result.len() > 0 { result[3..].to_string() } else { result }
+}