Compare commits

...

10 Commits

Author SHA1 Message Date
Romulus21
aab2a634ef change valut to float 2024-09-23 09:51:15 +02:00
Romulus21
7d5a94f4bb add 3 new sensors 2024-08-24 23:19:17 +02:00
Romulus21
ca9132e9ee pass clippy 2024-08-24 15:36:32 +02:00
Romulus21
92010cc9cd add author on toml 2024-08-20 08:37:41 +02:00
Romulus21
10aa0b1818 add description 2024-08-19 22:56:26 +02:00
Romulus21
635696219c fix average duration var 2024-08-19 22:18:54 +02:00
Romulus21
af60eeb00d Merge branch 'main' of git.rodev.fr:Romain/rust_agregator 2024-08-19 22:14:27 +02:00
Romulus21
01749e299f fix average duration var 2024-08-19 22:13:50 +02:00
Romulus21
44956a2657 fix average duration var 2024-08-19 22:11:09 +02:00
Romulus21
f01ab3aa6f change avg period 2024-08-19 17:57:51 +02:00
2 changed files with 63 additions and 25 deletions

View File

@@ -1,7 +1,9 @@
[package] [package]
name = "rust_agreagator" name = "rust_agreagator"
version = "0.1.0" version = "0.1.0"
authors = ["Romulus21 <romain@delanoe.pro>"]
edition = "2021" edition = "2021"
description = "Script computing the average of values from a sensor in MySQL database."
[dependencies] [dependencies]
chrono = "0.4" chrono = "0.4"

View File

@@ -3,14 +3,14 @@ extern crate serde;
extern crate serde_derive; extern crate serde_derive;
use dotenv::dotenv; use dotenv::dotenv;
use std::env;
use mysql::*;
use mysql::prelude::*; use mysql::prelude::*;
use mysql::*;
use serde::Deserialize; use serde::Deserialize;
use std::env;
extern crate chrono; extern crate chrono;
use chrono::{Duration, Utc, NaiveDate};
use chrono::prelude::*; use chrono::prelude::*;
use chrono::{Duration, NaiveDate, Utc};
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
struct Sensor { struct Sensor {
@@ -24,7 +24,7 @@ impl Sensor {
Sensor { Sensor {
service, service,
capteur, capteur,
type_donnee type_donnee,
} }
} }
} }
@@ -58,14 +58,19 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let db_user = env::var("DB_USER").expect("DB_USER must be set"); let db_user = env::var("DB_USER").expect("DB_USER must be set");
let db_password = env::var("DB_PASSWORD").expect("DB_PASSWORD must be set"); let db_password = env::var("DB_PASSWORD").expect("DB_PASSWORD must be set");
let db_host = env::var("DB_HOST").expect("DB_HOST must be set"); let db_host = env::var("DB_HOST").expect("DB_HOST must be set");
let db_port: u16 = env::var("DB_PORT").expect("DB_PORT must be set").parse().unwrap(); let db_port: u16 = env::var("DB_PORT")
.expect("DB_PORT must be set")
.parse()
.unwrap();
let db_name = env::var("DB_NAME").expect("DB_NAME must be set"); let db_name = env::var("DB_NAME").expect("DB_NAME must be set");
let url = format!("mysql://{}:{}@{}:{}/{}", db_user, db_password, db_host, db_port, db_name); let url = format!(
"mysql://{}:{}@{}:{}/{}",
db_user, db_password, db_host, db_port, db_name
);
let pool = Pool::new(url.as_str())?; let pool = Pool::new(url.as_str())?;
let mut conn = pool.get_conn()?; let mut conn = pool.get_conn()?;
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if args.len() == 1 { if args.len() == 1 {
let date = (Utc::now() - Duration::days(7)).naive_utc().date(); let date = (Utc::now() - Duration::days(7)).naive_utc().date();
@@ -74,45 +79,75 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let date = NaiveDate::parse_from_str(&args[1], "%Y-%m-%d").unwrap(); let date = NaiveDate::parse_from_str(&args[1], "%Y-%m-%d").unwrap();
let _ = aggregate_values(&mut conn, date); let _ = aggregate_values(&mut conn, date);
} }
dbg!(args); //dbg!(args);
Ok(()) Ok(())
} }
fn aggregate_values(conn: &mut PooledConn, date: NaiveDate) -> Result<(), Box<dyn std::error::Error>> { fn aggregate_values(
conn: &mut PooledConn,
let start_time = Utc.with_ymd_and_hms(date.year(), date.month(), date.day(), 00, 00, 00).unwrap() - Duration::minutes(15); date: NaiveDate,
let end_time = start_time + Duration::days(1); ) -> Result<(), Box<dyn std::error::Error>> {
let average_duration = 15;
let sensors = [ let sensors = [
Sensor::new("maison".to_string(), "bureau".to_string(), "co2".to_string()), Sensor::new(
Sensor::new("maison".to_string(), "bureau".to_string(), "tvoc".to_string()) "maison".to_string(),
"bureau".to_string(),
"temperature".to_string(),
),
Sensor::new(
"maison".to_string(),
"bureau".to_string(),
"humidite".to_string(),
),
Sensor::new(
"maison".to_string(),
"bureau".to_string(),
"pression".to_string(),
),
Sensor::new(
"maison".to_string(),
"bureau".to_string(),
"co2".to_string(),
),
Sensor::new(
"maison".to_string(),
"bureau".to_string(),
"tvoc".to_string(),
),
]; ];
for sensor in &sensors { for sensor in &sensors {
let start_time = Utc
.with_ymd_and_hms(date.year(), date.month(), date.day(), 00, 00, 00)
.unwrap()
- (Duration::minutes(average_duration) / 2);
let end_time = start_time + Duration::days(1);
let mut current_time = start_time; let mut current_time = start_time;
while current_time <= end_time { while current_time <= end_time {
let start_time_loop = current_time.to_string(); let start_time_loop = current_time.to_string();
let end_time_loop = (current_time + Duration::minutes(29) + Duration::seconds(59)).to_string(); let end_time_loop =
(current_time + Duration::minutes(average_duration - 1) + Duration::seconds(59))
.to_string();
let query = format!("SELECT * FROM donnees WHERE service = '{}' AND capteur = '{}' AND type = '{}' AND (date_donnee BETWEEN '{}' AND '{}');", sensor.service, sensor.capteur, sensor.type_donnee, start_time_loop, end_time_loop); let query = format!("SELECT * FROM donnees WHERE service = '{}' AND capteur = '{}' AND type = '{}' AND (date_donnee BETWEEN '{}' AND '{}');", sensor.service, sensor.capteur, sensor.type_donnee, start_time_loop, end_time_loop);
let selected_rows: Vec<Row> = conn.query(query)?; let selected_rows: Vec<Row> = conn.query(query)?;
let donnees: Vec<Donnee> = selected_rows.into_iter().map(Donnee::from).collect(); let donnees: Vec<Donnee> = selected_rows.into_iter().map(Donnee::from).collect();
let mut value: i32 = 0; let mut value: f32 = 0.0;
let mut count = 0; let mut count: f32 = 0.0;
let mut ids: Vec<String> = Vec::new(); let mut ids: Vec<String> = Vec::new();
for donnee in donnees { for donnee in donnees {
value = value + donnee.donnee.parse::<i32>().unwrap(); value += donnee.donnee.parse::<f32>().unwrap();
count = count + 1; count += 1.0;
ids.push(donnee.id.to_string()); ids.push(donnee.id.to_string());
} }
if count > 1 { if count > 1.0 {
let average = value / count; let average = value / count;
let entry_date = current_time + Duration::minutes(15); let entry_date = current_time + (Duration::minutes(average_duration) / 2);
let donnee = Donnee { let donnee = Donnee {
id: 0, id: 0,
service: sensor.service.to_string(), service: sensor.service.to_string(),
@@ -124,10 +159,11 @@ fn aggregate_values(conn: &mut PooledConn, date: NaiveDate) -> Result<(), Box<dy
let _ = insert_value(conn, donnee); let _ = insert_value(conn, donnee);
let query = "DELETE FROM donnees WHERE id IN (".to_owned() + &*ids.join(", ") + ");"; let query =
"DELETE FROM donnees WHERE id IN (".to_owned() + &*ids.join(", ") + ");";
let _: Vec<Row> = conn.query(query)?; let _: Vec<Row> = conn.query(query)?;
} }
current_time = current_time + Duration::minutes(30); current_time += Duration::minutes(average_duration);
} }
} }
@@ -142,4 +178,4 @@ fn insert_value(conn: &mut PooledConn, donnee: Donnee) -> Result<(), mysql::Erro
conn.exec_drop(query, ())?; conn.exec_drop(query, ())?;
Ok(()) Ok(())
} }