|  | @@ -1,135 +0,0 @@
 | 
	
		
			
				|  |  | -extern crate time;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -use comm;
 | 
	
		
			
				|  |  | -use comm::Channel;
 | 
	
		
			
				|  |  | -use config::Config;
 | 
	
		
			
				|  |  | -use std::fs::File;
 | 
	
		
			
				|  |  | -use std::io::SeekFrom;
 | 
	
		
			
				|  |  | -use std::io::prelude::*;
 | 
	
		
			
				|  |  | -use std::thread;
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -trait Sensor {
 | 
	
		
			
				|  |  | -    fn status(&mut self) -> String;
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -struct BatterySensor {
 | 
	
		
			
				|  |  | -    charge_now: File,
 | 
	
		
			
				|  |  | -    charge_full: File
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -impl BatterySensor {
 | 
	
		
			
				|  |  | -    fn new(supply: &str) -> BatterySensor {
 | 
	
		
			
				|  |  | -        let path = format!("/sys/class/power_supply/{}", supply);
 | 
	
		
			
				|  |  | -        BatterySensor {
 | 
	
		
			
				|  |  | -            charge_now: File::open(format!("{}/{}", path, "charge_now")).unwrap(),
 | 
	
		
			
				|  |  | -            charge_full: File::open(format!("{}/{}", path, "charge_full")).unwrap()
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -impl Sensor for BatterySensor {
 | 
	
		
			
				|  |  | -    fn status(&mut self) -> String {
 | 
	
		
			
				|  |  | -        let mut s = String::new();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        self.charge_now.read_to_string(&mut s).ok().expect("Could not read current charge");
 | 
	
		
			
				|  |  | -        let charge_now : u32 = s.trim().parse().ok().expect("Could not parse charge");
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        s.clear();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        self.charge_full.read_to_string(&mut s).ok().expect("Could not read current charge");
 | 
	
		
			
				|  |  | -        let charge_full : u32 = s.trim().parse().ok().expect("Could not parse charge");
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        self.charge_now.seek(SeekFrom::Start(0)).ok();
 | 
	
		
			
				|  |  | -        self.charge_full.seek(SeekFrom::Start(0)).ok();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        format!("{}%", charge_now / (charge_full / 100))
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -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()
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -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(),
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -struct TimeSensor {
 | 
	
		
			
				|  |  | -    format: String,
 | 
	
		
			
				|  |  | -    is_utc: bool
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -impl TimeSensor {
 | 
	
		
			
				|  |  | -    fn new(format: &str, is_utc: bool) -> TimeSensor {
 | 
	
		
			
				|  |  | -        TimeSensor {
 | 
	
		
			
				|  |  | -            format: format.to_string(),
 | 
	
		
			
				|  |  | -            is_utc: is_utc
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -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 zone = config.lookup("sensors.thermal_zone").unwrap();
 | 
	
		
			
				|  |  | -    let zone = zone.as_str().unwrap();
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    let mut sensors: Vec<Box<Sensor>> = vec![
 | 
	
		
			
				|  |  | -        Box::new(TempSensor::new(zone)),
 | 
	
		
			
				|  |  | -        Box::new(TimeSensor::new("UTC %H:%M", true)),
 | 
	
		
			
				|  |  | -        Box::new(TimeSensor::new("%Y-%m-%d %H:%M", false))
 | 
	
		
			
				|  |  | -    ];
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    let bat = config.lookup("sensors.battery");
 | 
	
		
			
				|  |  | -    let bat = bat.map(|bat| bat.as_str().unwrap());
 | 
	
		
			
				|  |  | -    bat.map(|bat| sensors.insert(0, Box::new(BatterySensor::new(bat))));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    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 }
 | 
	
		
			
				|  |  | -}
 |