view rust/src/sensor.rs @ 601:8c21df3711e2 rust

rigid_config more on sensors
author Matt Johnston <matt@ucc.asn.au>
date Wed, 15 Feb 2017 23:58:02 +0800
parents ca8102feaca6
children b45b8b4cf0f5
line wrap: on
line source

extern crate tokio_core;
extern crate futures;
extern crate futures_cpupool;

use std::time::Duration;
use std::io;
use std::fs::File;
use std::io::{Read,BufReader,BufRead};
use std::path::PathBuf;
use std::error::Error;

use tokio_core::reactor::Interval;
use tokio_core::reactor::Handle;
use futures::Stream;
use types::*;

use ::rigid_config;

pub trait Sensor {
    fn stream(handle: &Handle)
        -> Box<Stream<Item=Readings, Error=io::Error>>;
}

pub struct OneWireSensor {
}

impl OneWireSensor {
    fn new() -> OneWireSensor {
        OneWireSensor {
        }
    }

    fn step() -> Readings {
        let mut r = Readings::new();


        r.add("ambient", Some(31.2));
        r.add("wort_todo", Some(8.0));
        debug!("sensor step {:?}", r);
        r
    }

    fn sensor_names(&self) -> Result<Vec<String>, Box<Error>> {
        let mut path = PathBuf::from(&rigid_config.SENSOR_BASE_DIR);
        path.push("w1_master_slaves");

        let f = BufReader::new(File::open(path)?);
        let s = f.lines().collect::<Result<Vec<String>, io::Error>>()?;
        Ok(s)
    }
}

// does this need to be static?
lazy_static! {
    static ref thread_pool : futures_cpupool::CpuPool = futures_cpupool::CpuPool::new(3); // TODO: how many?
}

impl Sensor for OneWireSensor {
    fn stream(handle: &Handle)
        -> Box<Stream<Item=Readings, Error=io::Error>> {
        let mut s = OneWireSensor::new();

        let dur = Duration::new(rigid_config.SENSOR_SLEEP,0);
        Interval::new(dur, handle).unwrap()
            .and_then(|()| {
                thread_pool.spawn_fn(|| Ok(Self::step()))
            }).boxed()
    }
}

pub struct TestSensor {
}

impl TestSensor {
    pub fn new() -> Self {
        TestSensor {}
    }

    fn step(&mut self) -> Readings {
        let mut r = Readings::new();
        r.add("ambient", Some(31.2));
        r.add("wort", Some(Self::try_read("test_wort.txt").unwrap_or_else(|_| 18.0)));
        r.add("fridge", Some(Self::try_read("test_fridge.txt").unwrap_or_else(|_| 20.0)));
        r
    }

    fn try_read(filename: &str) -> Result<f32, Box<Error>> {
        let mut s = String::new();
        File::open(filename)?.read_to_string(&mut s)?;
        Ok(s.trim().parse::<f32>()?)
    }
}

impl Sensor for TestSensor {
    fn stream(handle: &Handle)
        -> Box<Stream<Item=Readings, Error=io::Error>> {
        let mut s = TestSensor::new();

        let dur = Duration::new(rigid_config.SENSOR_SLEEP,0);
        Interval::new(dur, handle).unwrap().map(move |()| {
            s.step()
        }).boxed()
    }
}