rust_gpiozero 0.2.0

A library inspired by gpiozero written in Rust.
Documentation
//! Input device component interfaces for devices such as `Button`
use rppal::gpio::{Gpio, InputPin, Level, Trigger};
use std::time::Duration;

/// Represents a generic GPIO input device.
#[derive(Debug)]
pub struct InputDevice {
    pin: InputPin,
    active_state: bool,
    inactive_state: bool,
}

impl InputDevice {
    /// Returns an InputDevice with the pin number given with the pin pulled to low by default
    /// `is_active` property is adjusted accordingly so that
    /// ``True`` still means active regardless of the :attr:`pull_up` setting
    /// # Arguments
    ///
    /// * `pin` - The GPIO pin which the device is attached to
    ///  
    pub fn new(pin: u8) -> InputDevice {
        match Gpio::new() {
            Err(e) => panic!("{:?}", e),
            Ok(gpio) => match gpio.get(pin) {
                Err(e) => panic!("{:?}", e),
                Ok(pin) => InputDevice {
                    pin: pin.into_input_pulldown(),
                    active_state: true,
                    inactive_state: false,
                },
            },
        }
    }
    /// Returns an InputDevice with the pin number given with the pin pulled high with an internal resistor by default
    /// `is_active` property is adjusted accordingly so that
    /// ``True`` still means active regardless of the :attr:`pull_up` setting
    /// # Arguments
    ///
    /// * `pin` - The GPIO pin which the device is attached to
    ///  
    pub fn new_with_pullup(pin: u8) -> InputDevice {
        match Gpio::new() {
            Err(e) => panic!("{:?}", e),
            Ok(gpio) => match gpio.get(pin) {
                Err(e) => panic!("{:?}", e),
                Ok(pin) => InputDevice {
                    pin: pin.into_input_pullup(),
                    active_state: false,
                    inactive_state: true,
                },
            },
        }
    }

    impl_device!();
    impl_gpio_device!();
    impl_io_device!();
}

macro_rules! impl_events_mixin {
    () => {
        /// Pause the program until the device is activated, or the timeout is reached.
        fn wait_for(&mut self, timeout:Option<f32>, active: bool){
            match timeout{
                None =>
                    if active {
                        self.pin.set_interrupt(Trigger::RisingEdge).unwrap();
                        self.pin.poll_interrupt(true, None).unwrap();
                    }else{
                        self.pin.set_interrupt(Trigger::FallingEdge).unwrap();
                        self.pin.poll_interrupt(true, None).unwrap();
                    }
                ,
                Some(n) => if active {
                        self.pin.set_interrupt(Trigger::RisingEdge).unwrap();
                        self.pin.poll_interrupt(true, Some(Duration::from_millis((n * 1000.0) as u64))).unwrap();
                    }else{
                        self.pin.set_interrupt(Trigger::FallingEdge).unwrap();
                        self.pin.poll_interrupt(true, Some(Duration::from_millis((n * 1000.0) as u64))).unwrap();
                    }
            }
        }


    }
}

/// Represents a generic input device with typical on/off behaviour.
/// Adds machinery to fire the active and inactive events for devices
/// that operate in a typical digital manner: straight forward on / off
/// states with (reasonably) clean transitions between the two.
#[derive(Debug)]
pub struct DigitalInputDevice {
    pin: InputPin,
    active_state: bool,
    inactive_state: bool,
    bounce_time: Option<f32>,
}

impl DigitalInputDevice {
    /// Returns a DigitalInputDevice with the pin number given with the pin pulled to low by default
    /// `is_active` property is adjusted accordingly so that
    /// ``True`` still means active regardless of the :attr:`pull_up` setting
    /// # Arguments
    ///
    /// * `pin` - The GPIO pin which the device is attached to
    /// # Note: BCM pins 2 and 3 are i2c SDA and SCL respectively and include a fixed, 1.8 kohms pull-up to 3.3v
    /// These pins are not suitable for use where no pullup resistor is required
    /// Source: https://pinout.xyz/pinout/pin5_gpio3
    pub fn new(pin: u8) -> DigitalInputDevice {
        match Gpio::new() {
            Err(e) => panic!("{:?}", e),
            Ok(gpio) => match gpio.get(pin) {
                Err(e) => panic!("{:?}", e),
                Ok(pin) => DigitalInputDevice {
                    pin: pin.into_input_pulldown(),
                    active_state: true,
                    inactive_state: false,
                    bounce_time: None,
                },
            },
        }
    }
    /// Returns a DigitalInputDevice with the pin number given with the pin pulled high with an internal resistor by default
    /// `is_active` property is adjusted accordingly so that
    /// ``True`` still means active regardless of the :attr:`pull_up` setting
    /// # Arguments
    ///
    /// * `pin` - The GPIO pin which the device is attached to
    ///  
    pub fn new_with_pullup(pin: u8) -> DigitalInputDevice {
        match Gpio::new() {
            Err(e) => panic!("{:?}", e),
            Ok(gpio) => match gpio.get(pin) {
                Err(e) => panic!("{:?}", e),
                Ok(pin) => DigitalInputDevice {
                    pin: pin.into_input_pullup(),
                    active_state: false,
                    inactive_state: true,
                    bounce_time: None,
                },
            },
        }
    }

    impl_device!();
    impl_gpio_device!();
    impl_io_device!();
    impl_events_mixin!();

    /// Pause the program until the device is deactivated, or the timeout is reached.
    pub fn wait_for_inactive(&mut self, timeout: Option<f32>) {
        self.wait_for(timeout, false)
    }

    /// Pause the program until the device is activated, or the timeout is reached.
    pub fn wait_for_active(&mut self, timeout: Option<f32>) {
        self.wait_for(timeout, true)
    }
}

/// Represents a simple push button or switch.
/// Connect one side of the button to a ground pin, and the other to any GPIO pin. The GPIO pin will be pulled high by default.
/// Alternatively, connect one side of the button to the 3V3 pin, and the other to any GPIO pin,
/// and then create a Button instance with Button::new_with_pulldown
pub struct Button {
    pin: InputPin,
    active_state: bool,
    inactive_state: bool,
    bounce_time: Option<f32>,
}

impl Button {
    /// Returns a Button with the pin number given and the pin pulled high with an internal resistor by default
    /// * `pin` - The GPIO pin which the device is attached to
    pub fn new(pin: u8) -> Button {
        match Gpio::new() {
            Err(e) => panic!("{:?}", e),
            Ok(gpio) => match gpio.get(pin) {
                Err(e) => panic!("{:?}", e),
                Ok(pin) => Button {
                    pin: pin.into_input_pullup(),
                    active_state: false,
                    inactive_state: true,
                    bounce_time: None,
                },
            },
        }
    }
    /// Returns a Button with the pin number given and the pin pulled down with an internal resistor by default
    /// * `pin` - The GPIO pin which the device is attached to
    pub fn new_with_pulldown(pin: u8) -> Button {
        match Gpio::new() {
            Err(e) => panic!("{:?}", e),
            Ok(gpio) => match gpio.get(pin) {
                Err(e) => panic!("{:?}", e),
                Ok(pin) => Button {
                    pin: pin.into_input_pulldown(),
                    active_state: true,
                    inactive_state: false,
                    bounce_time: None,
                },
            },
        }
    }

    impl_device!();
    impl_gpio_device!();
    impl_io_device!();
    impl_events_mixin!();

    //// Pause the program until the device is deactivated, or the timeout is reached.
    /// * `timeout` - Number of seconds to wait before proceeding. If this is None, then wait indefinitely until the device is inactive.
    pub fn wait_for_release(&mut self, timeout: Option<f32>) {
        self.wait_for(timeout, false)
    }

    /// Pause the program until the device is activated, or the timeout is reached.
    /// * `timeout` - Number of seconds to wait before proceeding. If this is None, then wait indefinitely until the device is active.
    pub fn wait_for_press(&mut self, timeout: Option<f32>) {
        self.wait_for(timeout, true)
    }
}