sensd 0.0.7-beta

The ultimate data logger and control system
Documentation
//! A basic example of sensd implementation.
//!
//! # Description
//!
//! This example displays the use of the "ThresholdAction" subscriber. Two input devices are
//! initialized using the `DeviceLog` builder - both devices return a static float value.
//!
//! # Note
//!
//! ## █▓▒░ Global Variables
//!
//! Take note that the `Group` singleton is not a global mutable static variable as this would
//! require unsafe code.
//!
//! ## █▓▒░ Operating Frequency
//! Device polling is not multi-threaded and the frequency of the event loop is determined by a
//! static frequency `FREQUENCY`. There might be a use case where frequency needs to be modulated,
//! such as during a control cycle for more accurate control. Reduced polling time might be useful
//! in embedded scenarios requiring both power conservation and accurate control.
extern crate chrono;
extern crate sensd;
extern crate serde;

use sensd::action::{Action, actions, IOCommand, Trigger};
use sensd::errors::ErrorType;
use sensd::io::{IOKind, RawValue, Input, Device};
use sensd::storage::{Group, Persistent};

/// █▓▒░ Event Loop Operating frequency
///
/// Frequency can be set to any arbitrary value and directly controls speed of event loop.
/// Frequency shouldn't be too high since polling operations are currently blocking. No error
/// occurs if polling time exceeds frequency.
///
/// Refer to file notes about making this a mutable value
const FREQUENCY: std::time::Duration = std::time::Duration::from_secs(1);

/// █▓▒░ Load settings and setup `Group`.
///
/// # Args
/// name - Name to be converted to string
///
/// # Returns
/// Single initialized Group
fn init(name: &str) -> Group {
    let group = Group::new(name.clone());
    println!("Initialized poll group: \"{}\"", name);
    group
}

/// █▓▒░ Handle polling of all devices in `Group`
fn poll(poller: &mut Group) -> Result<(), ErrorType> {
    match poller.poll() {
        Ok(_) => match poller.save() {
            Ok(_) => println!("\n"),
            Err(t) => {
                return Err(t);
            }
        },
        _ => (),
    };
    Ok(())
}

fn main() {
    let mut poller = init("main");

    // setup ph sensor
    {
        let name = "test name";
        let id = 0;
        let kind = IOKind::PH;
        let command = IOCommand::Input(|| RawValue::Float(1.2));

        // build input device
        let mut input =
            Input::new(
                name,
                id,
                Some(kind),
            ).set_command(
                command
            ).init_log(
            ).init_publisher();

        // setup publisher/action
        input.publisher_mut().as_mut().unwrap()
            .subscribe(
                actions::Threshold::new(
                    format!("Subscriber for Input:{}", id),
                    RawValue::Float(1.0),
                    Trigger::GT,
                ).into_boxed()
            );

        poller.push_input(input);
    }
    // setup flow sensor
    {
        let name = "second sensor";
        let id = 1;
        let kind = IOKind::PH;
        let command = IOCommand::Input(|| RawValue::Float(1.2));

        // build input device
        let mut input = Input::new(
            name,
            id,
            kind,
        )
            .set_command(command)
            .init_log()
            .init_publisher();

        // setup publisher/action
        input.publisher_mut().as_mut().unwrap()
            .subscribe(
                actions::Threshold::new(
                    format!("Subscriber for Input:{}", id),
                    RawValue::Float(1.0),
                    Trigger::GT,
                ).into_boxed()
            );

        poller.push_input(input);
    }

    println!("█▓▒░ Beginning polling ░▒▓█\n");

    loop {
        poll(&mut poller).expect("Error occurred during polling");

        std::thread::sleep(FREQUENCY);
    }
}