Nareshkumar Rao
7 months ago
11 changed files with 117 additions and 6 deletions
|
@ -0,0 +1,70 @@ |
|||||
|
use chrono::Utc; |
||||
|
use serde::{Deserialize, Serialize}; |
||||
|
|
||||
|
use crate::error::GenericResult; |
||||
|
|
||||
|
#[derive(Serialize, Deserialize)] |
||||
|
pub struct WateringRecord { |
||||
|
pub time: i64, |
||||
|
pub amount: u64, |
||||
|
} |
||||
|
|
||||
|
impl WateringRecord { |
||||
|
pub fn new(amount: u64) -> WateringRecord { |
||||
|
WateringRecord { |
||||
|
time: Utc::now().timestamp(), |
||||
|
amount, |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#[derive(Default)] |
||||
|
pub struct History { |
||||
|
pub watering_records: Vec<WateringRecord>, |
||||
|
} |
||||
|
|
||||
|
const FILE_PATH: &str = "./growpi.history.csv"; |
||||
|
|
||||
|
impl History { |
||||
|
pub fn save(&self) -> GenericResult<()> { |
||||
|
let mut writer = csv::WriterBuilder::new() |
||||
|
.has_headers(true) |
||||
|
.from_path(FILE_PATH)?; |
||||
|
for record in &self.watering_records { |
||||
|
writer.serialize(record)?; |
||||
|
} |
||||
|
writer.flush()?; |
||||
|
Ok(()) |
||||
|
} |
||||
|
|
||||
|
pub fn load() -> GenericResult<History> { |
||||
|
let mut history = csv::ReaderBuilder::new() |
||||
|
.has_headers(true) |
||||
|
.from_path(FILE_PATH)?; |
||||
|
let mut result = Vec::new(); |
||||
|
for record in history.deserialize() { |
||||
|
result.push(record?); |
||||
|
} |
||||
|
Ok(History { |
||||
|
watering_records: result, |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#[cfg(test)] |
||||
|
mod tests { |
||||
|
|
||||
|
use chrono::Local; |
||||
|
|
||||
|
use super::*; |
||||
|
|
||||
|
#[test] |
||||
|
fn test_write_default() { |
||||
|
let mut history = History::default(); |
||||
|
history.watering_records.push(WateringRecord { |
||||
|
time: Local::now().timestamp(), |
||||
|
amount: 456, |
||||
|
}); |
||||
|
history.save().unwrap(); |
||||
|
} |
||||
|
} |
@ -1,14 +1,20 @@ |
|||||
use std::sync::{Arc, Mutex}; |
use std::sync::{Arc, Mutex}; |
||||
|
|
||||
use crate::{config::Configuration, error::GenericResult, io}; |
|
||||
|
use crate::{config::Configuration, error::GenericResult, history::History, io}; |
||||
|
|
||||
pub type ProgramStateShared = Arc<Mutex<ProgramState>>; |
pub type ProgramStateShared = Arc<Mutex<ProgramState>>; |
||||
pub struct ProgramState { |
pub struct ProgramState { |
||||
pub config: Configuration, |
pub config: Configuration, |
||||
pub relay: io::Relay, |
pub relay: io::Relay, |
||||
|
pub history: History, |
||||
} |
} |
||||
|
|
||||
pub fn init_state(config: Configuration) -> GenericResult<ProgramStateShared> { |
pub fn init_state(config: Configuration) -> GenericResult<ProgramStateShared> { |
||||
let relay = io::Relay::new(&config)?; |
let relay = io::Relay::new(&config)?; |
||||
Ok(Arc::new(Mutex::new(ProgramState { config, relay }))) |
|
||||
|
let history = History::load()?; |
||||
|
Ok(Arc::new(Mutex::new(ProgramState { |
||||
|
config, |
||||
|
relay, |
||||
|
history, |
||||
|
}))) |
||||
} |
} |
||||
|
Loading…
Reference in new issue