|  | @@ -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 }
 | 
	
		
			
				|  |  | +}
 |