use crate::{
core::WeatherReadingSource,
rtl_433::{BaseReading, FiveInOneReading},
};
use metrum::Temp;
use std::{
io::{BufRead, BufReader, Result},
process::{Command, Stdio},
};
pub fn rtl_433_source() -> impl Iterator<Item = Result<String>> {
let stdout = Command::new("sh")
.arg("-c")
.arg("rtl_433 -C customary -F json -M time:iso:tz")
.stdout(Stdio::piped())
.spawn()
.expect("COuld not spawn rtl_433 process")
.stdout
.expect("Could not capture standard output.");
BufReader::new(stdout).lines()
}
pub struct RTL433Reader {}
impl RTL433Reader {
pub fn read() -> impl Iterator<Item = WeatherReadingSource> {
let source = rtl_433_source();
Self::read_from(source)
}
pub fn read_from<T: Iterator<Item = Result<String>>>(
source: T,
) -> impl Iterator<Item = WeatherReadingSource> {
source.filter_map(|line| line.ok()).filter_map(|line| {
if let Ok(reading) = BaseReading::from_string(&line) {
if reading.model == "Acurite-5n1" {
if let Ok(data) = FiveInOneReading::from_string(&line) {
if data.sequence_num == 0 {
let mut weather_reading = WeatherReadingSource::new();
weather_reading.device_id = Some(data.id);
weather_reading.time = data.time;
weather_reading.rain = data.rain_in;
weather_reading.wind_speed = Some(data.wind_avg_mi_h);
weather_reading.out_temp = if let Some(temp) = data.temperature_f {
Some(Temp::from_f(temp))
} else {
None
};
weather_reading.out_humid = data.humidity;
weather_reading.wind_dir = data.wind_dir_deg;
return Some(weather_reading);
}
}
}
}
None
})
}
}