فهرست منبع

Factor out Sensor trait

This also now allows us to have multiple temperature sensors
Thomas Dy 10 سال پیش
والد
کامیت
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 }
+}