d16bd7e7f8
Signed-off-by: Thomas Klaehn <thomas.klaehn@perinet.io>
151 lines
4.2 KiB
Rust
151 lines
4.2 KiB
Rust
use std::fs;
|
|
use std::io::{Seek, Write};
|
|
use std::path::Path;
|
|
|
|
use chrono::{DateTime, Datelike, Utc};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use gps_parser;
|
|
use ina3221;
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
struct Sample {
|
|
value: f64,
|
|
unit: String,
|
|
}
|
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
struct CvsData {
|
|
lat: f64,
|
|
lon: f64,
|
|
timestamp: String,
|
|
speed: Sample,
|
|
rpm: Sample,
|
|
current: Sample,
|
|
voltage: Sample,
|
|
}
|
|
|
|
#[derive(serde::Deserialize)]
|
|
struct Opts {
|
|
log_path: String,
|
|
i2c_dev: String,
|
|
i2c_slave_address: u16,
|
|
gps_dev: String,
|
|
shunt_resistor: f64,
|
|
}
|
|
|
|
fn read_opts(path: &str) -> Opts {
|
|
let opts_str = fs::read_to_string(path).expect("Unable to read log file");
|
|
return serde_json::from_str(&opts_str).unwrap();
|
|
}
|
|
|
|
fn update_date(datetime: DateTime<Utc>, year: i32, month: u32, day: u32) -> DateTime<Utc> {
|
|
let mut res = datetime;
|
|
|
|
res = match res.with_year(year) {
|
|
Some(value) => value,
|
|
_none => datetime,
|
|
};
|
|
res = match res.with_month(month) {
|
|
Some(value) => value,
|
|
_none => datetime,
|
|
};
|
|
res = match res.with_day(day) {
|
|
Some(value) => value,
|
|
_none => datetime,
|
|
};
|
|
return res;
|
|
}
|
|
|
|
fn log_sample(log_path: &str, sample: CvsData) {
|
|
let path = Path::new(log_path);
|
|
let mut log_json: Vec<CvsData> = Vec::new();
|
|
let mut file: fs::File;
|
|
if path.exists() {
|
|
file = fs::OpenOptions::new().read(true).write(true).create(true).truncate(false).append(false).open(log_path).unwrap();
|
|
let log_str = fs::read_to_string(path).expect("Unable to read log file");
|
|
log_json = serde_json::from_str(&log_str).unwrap();
|
|
file.set_len(0).unwrap();
|
|
file.rewind().unwrap();
|
|
} else {
|
|
file = fs::File::create(log_path).expect("Unable to create file");
|
|
}
|
|
log_json.push(sample);
|
|
let j = match serde_json::to_string(&log_json) {
|
|
Ok(value) => value,
|
|
Err(error) => panic!("Unable to make JSON from struct {:?}", error),
|
|
};
|
|
file.write_all(j.as_bytes()).expect("Unable to write JSON string to file");
|
|
}
|
|
|
|
fn main() {
|
|
let opts = read_opts("/etc/cvs-monitor/config.json");
|
|
let path = Path::new(&opts.log_path);
|
|
if !path.exists() {
|
|
match fs::create_dir(&opts.log_path) {
|
|
Ok(()) => {},
|
|
Err(err) => panic!("Can't create dir \"{}\" ({})", opts.log_path, err),
|
|
};
|
|
}
|
|
let now = Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
|
|
let log_file: String = opts.log_path + &now + ".json";
|
|
|
|
let mut gps_parser = gps_parser::GpsParser::new(&opts.gps_dev);
|
|
let mut ina = ina3221::Ina3221::new(opts.i2c_slave_address, &opts.i2c_dev, opts.shunt_resistor);
|
|
|
|
|
|
loop {
|
|
let speed = Sample {
|
|
value: 0.0,
|
|
unit: "km/h".to_string(),
|
|
};
|
|
let rpm = Sample {
|
|
value: 0.0,
|
|
unit: "T/min".to_string(),
|
|
};
|
|
let current = Sample {
|
|
value: 0.0,
|
|
unit: "A".to_string(),
|
|
};
|
|
let voltage = Sample {
|
|
value: 0.0,
|
|
unit: "V".to_string(),
|
|
};
|
|
|
|
let mut sample = CvsData {
|
|
lat: 0.0,
|
|
lon: 0.0,
|
|
timestamp: Utc::now().to_rfc3339(),
|
|
speed,
|
|
rpm,
|
|
current,
|
|
voltage,
|
|
};
|
|
|
|
let gps = match gps_parser.parse_nmea() {
|
|
Ok(value) => value,
|
|
Err(_) => continue
|
|
};
|
|
sample.lat = gps.lat;
|
|
sample.lon = gps.lon;
|
|
sample.speed.value = gps.speed;
|
|
sample.rpm.value = sample.speed.value * 1000.0 / (60.0 * 2.2);
|
|
|
|
let mut tmp = gps.timestamp;
|
|
tmp = update_date(tmp, Utc::now().year(), Utc::now().month(), Utc::now().day());
|
|
sample.timestamp = tmp.to_rfc3339();
|
|
let current = match ina.current(ina3221::Channel::One) {
|
|
Ok(value) => value,
|
|
Err(_error) => 0.0,
|
|
};
|
|
sample.current.value = current;
|
|
let voltage = match ina.bus_voltage(ina3221::Channel::One) {
|
|
Ok(value) => value,
|
|
Err(_error) => 0.0,
|
|
};
|
|
sample.voltage.value = voltage;
|
|
|
|
log_sample(&log_file, sample);
|
|
}
|
|
}
|