//! # ble-ledly
//! [](https://crates.io/crates/ble-ledly)
//! [](https://docs.rs/ble-ledly/)
//! 
//! > _Customizable_ and _extensible_ cross-platform high-level _Bluetooth Low Energy_ light controller.
//!
//! Provides **out-of-the-box** support for generic _RGB_ led strips and **BLE** lamps and light bulbs.
//! Designed to be _extensible_, allows to implement your own devices, communication protocol or
//! both (_See the readme file for more_). Supports hardware specific animations (transferrable) and
//! software non-transferrable animations.
//!
//! ## Capabilities
//!
//! Each device supports multiple capabilities available as featurs through *conditional compilation* in the _.toml_ file.
//!
//! ```toml
//! ble-ledly = {version = "0.3", features = ["all"]}
//! ```
//!
//! Each _capability_ provides a single point access to a specific device characteristic that can be manipulated through the publicly available ``set()`` method. All the methods are available through the _standard API_ `Capability::set(opts)` or through more idiomatic methods as follow.
//!
//! ```rust, ignore
//! // standard
//! Light::set(light, &protocol, &LightOption::On).await?;
//!
//! // idiomatic syntactic sugar
//! light.turn_on(&protocol).await?;
//! ```
//!
//! | Capability | Description | Implemented? |
//! |-------------|-----------------------------------------------------------------------------------------------|--------------|
//! |` Light ` | Light state (on/off) | ✅ |
//! |` Color ` | Light Color (RGB) | ✅ |
//! |` Brightness ` | Light white levels | ✅ |
//! |` HWAnimate ` | Hardware specific animations (subjected to protocol) | ✅ |
//! |` SWAnimate ` | Software animation (require continuous communication, but allows custom effect on any device) | ✅ |
//! |` Temperature` | Light temperature (K) | |
//!
//!
//! ## Animations
//!
//! ### Transferrable vs. Non-transferrable
//!
//! _Transferrable animations_ are built-in in the _target ble device_ which takes care of driving the led(s); once the command is sent, __no extra communication needed__ between the __client and ble light controller__. _Non-transferrable_ animations bypass the controller's built-in effects and allow for higher degree of customization while providing support for legacy or cheap _light controllers_ allowing to provide effects otherwise not available to the target device. As a consequence, this requires __continuous connection__ between the _controller and client_.
//!
//! ## Current support
//!
//! | Animation | Capability | Color Support | Implemented? |
//! |-------------------|------------|----------------------------------------|--------------|
//! | Pulsating | HWAnimate | Red/Green/Blue | ✅ |
//! | Breathing | SWAnimate | RGB/Any | ✅ |
//! | Rainbow Pulsating | HWAnimate | N/A | |
//! | Pulsating Bicolor | HWAnimate | Red/Green, Red/Blue, Green/Blue | |
//! | Rainbow flashing | HWAnimate | N/A | |
//! | Cross-fade | SWAnimate | RGB/Any | |
//! | Rainbow jumping | HWAnimate | N/A | |
//! | Flashing | HWAnimate | Red, Green, Blue, Yellow, Purple, Cyan | |
//!
//! ## Extensibility
//!
//! This library has been designed with _extensibility in mind_.
//!
//! - It is possible to create your own _device_ by implementing the `Device` trait and use the _built-in_ communication protocol.
//! - You can add your own __communication protocol__ by implementing the `Protocol` trait and use it to drive one of the built-in devices.
//! - Create your own `device` and `communication protocol`.
//!
//! ## Usage
//!
//! An example using built-in _device_ **LedDevice** and _GenericRGB_ communication protocol.
//! For more examples, see the [examples](https://github.com/espressoshock/ble-ledly/tree/main/examples) folder.
//!
//! ### Minimal Configuration
//!
//! ```rust, no_run
//! # use ble_ledly::capability::color::*;
//! # use ble_ledly::communication_protocol::GenericRGB;
//! # use ble_ledly::device::LedDevice;
//! # use ble_ledly::device::{CharKind, UuidKind};
//! # use ble_ledly::Controller;
//!
//! use std::error::Error;
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn Error>> {
//!
//! // Create a new Light controller with prefix
//! // Auto-filter devices that contain the prefix
//! let mut controller = Controller::<LedDevice>::new_with_prefix("QHM-").await?;
//!
//! // Connect
//! controller.connect().await?;
//!
//! // Choose your communication protocol
//! let protocol = GenericRGB::default();
//!
//! // set default write characteristic for all connected
//! // devices
//! controller.set_all_char(&CharKind::Write, &UuidKind::Uuid16(0xFFD9))?;
//!
//! // Setting first found light color to red
//! let first_light = controller.list().get(0).unwrap();
//! first_light.color(&protocol, 255, 0, 0).await?;
//!
//! Ok(())
//! }
//! ```
//!
//! ### Light controls
//!
//! ```rust, no_run
//! use ble_ledly::capability::color::*;
//! use ble_ledly::capability::light::*;
//! use ble_ledly::capability::sw_animate::*;
//! use ble_ledly::communication_protocol::GenericRGB;
//! use ble_ledly::Controller;
//! use ble_ledly::device::LedDevice;
//! use ble_ledly::device::{CharKind, UuidKind};
//!
//! use std::error::Error;
//! use std::time::Duration;
//! use tokio::time;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn Error>> {
//! // Create a new Light controller
//! let mut controller = Controller::<LedDevice>::new().await?;
//!
//! // Discover devices (scan)
//! let led_devices = controller.device_discovery().await?;
//!
//! // inspect all found devices
//! for device in led_devices.iter() {
//! println!("Found device: {}", device);
//! }
//! // filter devices
//! let lights: Vec<LedDevice> = led_devices
//! .into_iter()
//! .filter(|device| device.name.contains("QHM-"))
//! .collect();
//!
//! // Connect
//! controller.connect_with_devices(lights).await?;
//!
//! // Choose your communication protocol
//! let protocol = GenericRGB::default();
//!
//! // set the default write Characteristic
//! // for all devices. Optionally you can also
//! // set it per-device. Look the examples folder for more
//! controller.set_all_char(&CharKind::Write, &UuidKind::Uuid16(0xFFD9))?;
//!
//! // list all connected devices
//! let connected_lights = controller.list();
//! for light in connected_lights.iter_mut() {
//! println!("Connected to : {}", light.name);
//!
//! // Control the lights
//! println!("Turning light on...");
//! light.turn_on(&protocol).await?;
//!
//! // Set color
//! println!("Setting color...");
//! light.color(&protocol, 255, 0, 0).await?;
//! time::sleep(Duration::from_millis(800)).await;
//! light.color(&protocol, 0, 255, 0).await?;
//! time::sleep(Duration::from_millis(800)).await;
//! light.color(&protocol, 0, 0, 255).await?;
//! time::sleep(Duration::from_millis(800)).await;
//!
//! println!("SW Animation - Breathing effect...");
//! light
//! .breathing(
//! &GenericRGB {},
//! &ColorOption::RGB(255, 0, 0),
//! &SWAnimationRepeat::FiniteCount(2),
//! &SWAnimationSpeed::Fastest,
//! )
//! .await?;
//! light
//! .breathing(
//! &GenericRGB {},
//! &ColorOption::RGB(0, 255, 0),
//! &SWAnimationRepeat::FiniteCount(2),
//! &SWAnimationSpeed::Fastest,
//! )
//! .await?;
//! light
//! .breathing(
//! &GenericRGB {},
//! &ColorOption::RGB(0, 0, 255),
//! &SWAnimationRepeat::FiniteCount(2),
//! &SWAnimationSpeed::Fastest,
//! )
//! .await?;
//!
//! // Control the lights
//! println!("Turning light off...");
//! light.turn_off(&protocol).await?;
//! }
//!
//! Ok(())
//! }
//! ```
//! ## Contributing
//!
//! Open a PR or issue
//!
//! ## License
//!
//! MIT
pub mod capability;
pub mod communication_protocol;
pub mod controller;
pub mod device;
pub mod error;
//----------//
// Re-export//
//----------//
////////////////////////////////////
pub use self::controller::Controller;
////////////////////////////////////