summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs99
1 files changed, 5 insertions, 94 deletions
diff --git a/src/main.rs b/src/main.rs
index d7dda15..19880cf 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -18,9 +18,11 @@ use std::sync::Mutex;
mod maxmin;
mod models;
mod schema;
+mod device;
use self::maxmin::*;
use self::models::*;
+use self::device::DeviceResponse;
/// Application context to be available on every request.
struct Context {
@@ -28,18 +30,6 @@ struct Context {
secret_key: Vec<u8>,
}
-/// Status of a device.
-#[derive(Serialize)]
-struct DeviceResponse {
- device_id: String,
- name: String,
- battery_level: Option<f64>,
- current_value: Option<f64>,
- water_level: Option<f64>,
- last_watered: Option<DateTime<Utc>>,
- last_updated: Option<DateTime<Utc>>,
-}
-
/// Time series of datapoints for a device.
#[derive(Serialize)]
struct DeviceData {
@@ -61,87 +51,8 @@ struct PutDataRequest {
value: f64,
battery_value: f64,
signature: String,
-}
-
-impl DeviceResponse {
- pub fn calculate_status(&mut self, data: &[Datapoint]) {
- self.last_updated = data
- .last()
- .map(|v| DateTime::<Utc>::from_utc(v.timestamp, Utc));
- self.battery_level = data.last().map(|v| v.battery_status);
-
- // Find the local extrema
- let mut values = data.iter().map(|v| v.value).collect();
- normalize(&mut values);
- smooth(&mut values, 3.0);
- derive(&mut values);
- let extrema = find_extrema(&values);
-
- // Look for a sharp drop in the value to indicate watering.
- let last_watered_index = extrema
- .iter()
- .filter_map(|x| match x {
- Extremum::Minimum(i) => {
- if values[*i] < -0.1 {
- Some(i)
- } else {
- None
- }
- }
- _ => None,
- })
- .last();
-
- self.last_watered =
- last_watered_index.map(|i| DateTime::<Utc>::from_utc(data[*i].timestamp, Utc));
-
- // How much water is left?
- let low_watermark = last_watered_index.map(|i| data[*i].value);
- let high_watermark = last_watered_index
- .and_then(|i| {
- extrema
- .iter()
- .rev()
- .filter_map(|x| match x {
- Extremum::Maximum(j) => {
- if j < i {
- Some(j)
- } else {
- None
- }
- }
- _ => None,
- })
- .next()
- })
- .map(|i| data[*i].value);
-
- self.current_value = data.last().map(|v| v.value);
- self.water_level = if let (Some(high), Some(low), Some(current)) =
- (high_watermark, low_watermark, self.current_value)
- {
- Some(
- 1.0 - (current - f64::min(low, current))
- / (f64::max(high, current) - f64::max(low, current)),
- )
- } else {
- None
- };
- }
-}
-
-impl From<Device> for DeviceResponse {
- fn from(device: Device) -> DeviceResponse {
- DeviceResponse {
- device_id: device.device_id,
- name: device.name,
- battery_level: None,
- water_level: None,
- current_value: None,
- last_watered: None,
- last_updated: None,
- }
- }
+ temperature_value: Option<f64>,
+ relative_humidity_value: Option<f64>,
}
impl DeviceData {
@@ -314,7 +225,7 @@ async fn main() -> io::Result<()> {
.app_data(ctx.clone())
.route("/data", web::get().to(get_data))
.route("/data", web::put().to(put_data))
- .service(Files::new("/", "www/").index_file("index.html"))
+ .service(Files::new("/", "./www").index_file("index.html"))
})
.bind(bind)
.unwrap()