|
@@ -1,10 +1,9 @@
|
|
|
-use comm;
|
|
|
-use comm::Channel;
|
|
|
-use config::Config;
|
|
|
+extern crate time;
|
|
|
+
|
|
|
use std::fs::File;
|
|
|
use std::io::prelude::*;
|
|
|
use std::io;
|
|
|
-use std::thread;
|
|
|
+use super::Sensor;
|
|
|
|
|
|
struct StatFiles {
|
|
|
rx: File,
|
|
@@ -12,47 +11,59 @@ struct StatFiles {
|
|
|
}
|
|
|
|
|
|
struct Stats {
|
|
|
- rx: u32,
|
|
|
- tx: u32
|
|
|
+ rx: i64,
|
|
|
+ tx: i64
|
|
|
+}
|
|
|
+
|
|
|
+pub struct NetSpeedSensor {
|
|
|
+ files: Vec<StatFiles>,
|
|
|
+ stats: Option<Stats>,
|
|
|
+ last_time: i64
|
|
|
+}
|
|
|
+
|
|
|
+impl NetSpeedSensor {
|
|
|
+ pub fn new(devices: &Vec<&str>) -> NetSpeedSensor {
|
|
|
+ let files: Vec<StatFiles> = devices.iter()
|
|
|
+ .flat_map(|dev| open_stats(&dev).ok())
|
|
|
+ .collect();
|
|
|
+
|
|
|
+ NetSpeedSensor {
|
|
|
+ files: files,
|
|
|
+ stats: None,
|
|
|
+ last_time: 0
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-pub fn netspeed(tx: &Channel, config: &Config) {
|
|
|
- let devices = parse_config(config);
|
|
|
- let mut files : Vec<StatFiles> = devices.iter()
|
|
|
- .flat_map(|dev| open_stats(&dev).ok())
|
|
|
- .collect();
|
|
|
+impl Sensor for NetSpeedSensor {
|
|
|
+ fn status(&mut self) -> String {
|
|
|
+ let curr_time = time::get_time().sec;
|
|
|
|
|
|
- let mut prev_stats : Option<Stats> = None;
|
|
|
- loop {
|
|
|
- let stats = files
|
|
|
+ let stats = self.files
|
|
|
.iter_mut()
|
|
|
.flat_map(|file| read_stats(file).ok())
|
|
|
.fold(Stats { rx: 0, tx: 0 }, |acc, elem| Stats {
|
|
|
rx: acc.rx + elem.rx,
|
|
|
tx: acc.tx + elem.tx
|
|
|
});
|
|
|
- let output = match prev_stats {
|
|
|
+
|
|
|
+ let output = match self.stats.as_ref() {
|
|
|
Some(pstats) => {
|
|
|
- let rx = format_bytes(stats.rx - pstats.rx);
|
|
|
- let tx = format_bytes(stats.tx - pstats.tx);
|
|
|
- format!("{}↓ {}↑", rx, tx)
|
|
|
+ let rx = (stats.rx - pstats.rx) / (curr_time - self.last_time);
|
|
|
+ let tx = (stats.tx - pstats.tx) / (curr_time - self.last_time);
|
|
|
+ format!("{}↓ {}↑", format_bytes(rx), format_bytes(tx))
|
|
|
},
|
|
|
None => "?".to_string()
|
|
|
};
|
|
|
- prev_stats = Some(stats);
|
|
|
- comm::send(tx, "netspeed", &output);
|
|
|
- thread::sleep_ms(1000);
|
|
|
- }
|
|
|
-}
|
|
|
|
|
|
-fn parse_config(cfg: &Config) -> Vec<&str> {
|
|
|
- let val = cfg.lookup("netspeed.devices").unwrap();
|
|
|
- let arr = val.as_slice().unwrap();
|
|
|
- let arr: Vec<&str> = arr.iter().flat_map(|elem| elem.as_str()).collect();
|
|
|
- arr
|
|
|
+ self.last_time = curr_time;
|
|
|
+ self.stats = Some(stats);
|
|
|
+
|
|
|
+ output
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-fn format_bytes(bytes: u32) -> String {
|
|
|
+fn format_bytes(bytes: i64) -> String {
|
|
|
let kib = bytes >> 10;
|
|
|
if kib > 1024 {
|
|
|
format!("{:.*} M", 1, (kib as f32) / 1024.0)
|
|
@@ -79,10 +90,10 @@ fn read_stats(files: &mut StatFiles) -> Result<Stats, io::Error> {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
-fn read_bytes(f: &mut File) -> u32 {
|
|
|
+fn read_bytes(f: &mut File) -> i64 {
|
|
|
let mut s = String::new();
|
|
|
assert!(f.read_to_string(&mut s).is_ok());
|
|
|
- let i : u32 = s.trim().parse().unwrap();
|
|
|
+ let i : i64 = s.trim().parse().unwrap();
|
|
|
assert!(f.seek(io::SeekFrom::Start(0)).is_ok());
|
|
|
i
|
|
|
}
|