ble_ledly/lib.rs
1//! # ble-ledly
2//! [](https://crates.io/crates/ble-ledly)
3//! [](https://docs.rs/ble-ledly/)
4//! 
5//! > _Customizable_ and _extensible_ cross-platform high-level _Bluetooth Low Energy_ light controller.
6//!
7//! Provides **out-of-the-box** support for generic _RGB_ led strips and **BLE** lamps and light bulbs.
8//! Designed to be _extensible_, allows to implement your own devices, communication protocol or
9//! both (_See the readme file for more_). Supports hardware specific animations (transferrable) and
10//! software non-transferrable animations.
11//!
12//! ## Capabilities
13//!
14//! Each device supports multiple capabilities available as featurs through *conditional compilation* in the _.toml_ file.
15//!
16//! ```toml
17//! ble-ledly = {version = "0.3", features = ["all"]}
18//! ```
19//!
20//! 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.
21//!
22//! ```rust, ignore
23//! // standard
24//! Light::set(light, &protocol, &LightOption::On).await?;
25//!
26//! // idiomatic syntactic sugar
27//! light.turn_on(&protocol).await?;
28//! ```
29//!
30//! | Capability | Description | Implemented? |
31//! |-------------|-----------------------------------------------------------------------------------------------|--------------|
32//! |` Light ` | Light state (on/off) | ✅ |
33//! |` Color ` | Light Color (RGB) | ✅ |
34//! |` Brightness ` | Light white levels | ✅ |
35//! |` HWAnimate ` | Hardware specific animations (subjected to protocol) | ✅ |
36//! |` SWAnimate ` | Software animation (require continuous communication, but allows custom effect on any device) | ✅ |
37//! |` Temperature` | Light temperature (K) | |
38//!
39//!
40//! ## Animations
41//!
42//! ### Transferrable vs. Non-transferrable
43//!
44//! _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_.
45//!
46//! ## Current support
47//!
48//! | Animation | Capability | Color Support | Implemented? |
49//! |-------------------|------------|----------------------------------------|--------------|
50//! | Pulsating | HWAnimate | Red/Green/Blue | ✅ |
51//! | Breathing | SWAnimate | RGB/Any | ✅ |
52//! | Rainbow Pulsating | HWAnimate | N/A | |
53//! | Pulsating Bicolor | HWAnimate | Red/Green, Red/Blue, Green/Blue | |
54//! | Rainbow flashing | HWAnimate | N/A | |
55//! | Cross-fade | SWAnimate | RGB/Any | |
56//! | Rainbow jumping | HWAnimate | N/A | |
57//! | Flashing | HWAnimate | Red, Green, Blue, Yellow, Purple, Cyan | |
58//!
59//! ## Extensibility
60//!
61//! This library has been designed with _extensibility in mind_.
62//!
63//! - It is possible to create your own _device_ by implementing the `Device` trait and use the _built-in_ communication protocol.
64//! - You can add your own __communication protocol__ by implementing the `Protocol` trait and use it to drive one of the built-in devices.
65//! - Create your own `device` and `communication protocol`.
66//!
67//! ## Usage
68//!
69//! An example using built-in _device_ **LedDevice** and _GenericRGB_ communication protocol.
70//! For more examples, see the [examples](https://github.com/espressoshock/ble-ledly/tree/main/examples) folder.
71//!
72//! ### Minimal Configuration
73//!
74//! ```rust, no_run
75//! # use ble_ledly::capability::color::*;
76//! # use ble_ledly::communication_protocol::GenericRGB;
77//! # use ble_ledly::device::LedDevice;
78//! # use ble_ledly::device::{CharKind, UuidKind};
79//! # use ble_ledly::Controller;
80//!
81//! use std::error::Error;
82//! #[tokio::main]
83//! async fn main() -> Result<(), Box<dyn Error>> {
84//!
85//! // Create a new Light controller with prefix
86//! // Auto-filter devices that contain the prefix
87//! let mut controller = Controller::<LedDevice>::new_with_prefix("QHM-").await?;
88//!
89//! // Connect
90//! controller.connect().await?;
91//!
92//! // Choose your communication protocol
93//! let protocol = GenericRGB::default();
94//!
95//! // set default write characteristic for all connected
96//! // devices
97//! controller.set_all_char(&CharKind::Write, &UuidKind::Uuid16(0xFFD9))?;
98//!
99//! // Setting first found light color to red
100//! let first_light = controller.list().get(0).unwrap();
101//! first_light.color(&protocol, 255, 0, 0).await?;
102//!
103//! Ok(())
104//! }
105//! ```
106//!
107//! ### Light controls
108//!
109//! ```rust, no_run
110//! use ble_ledly::capability::color::*;
111//! use ble_ledly::capability::light::*;
112//! use ble_ledly::capability::sw_animate::*;
113//! use ble_ledly::communication_protocol::GenericRGB;
114//! use ble_ledly::Controller;
115//! use ble_ledly::device::LedDevice;
116//! use ble_ledly::device::{CharKind, UuidKind};
117//!
118//! use std::error::Error;
119//! use std::time::Duration;
120//! use tokio::time;
121//!
122//! #[tokio::main]
123//! async fn main() -> Result<(), Box<dyn Error>> {
124//! // Create a new Light controller
125//! let mut controller = Controller::<LedDevice>::new().await?;
126//!
127//! // Discover devices (scan)
128//! let led_devices = controller.device_discovery().await?;
129//!
130//! // inspect all found devices
131//! for device in led_devices.iter() {
132//! println!("Found device: {}", device);
133//! }
134//! // filter devices
135//! let lights: Vec<LedDevice> = led_devices
136//! .into_iter()
137//! .filter(|device| device.name.contains("QHM-"))
138//! .collect();
139//!
140//! // Connect
141//! controller.connect_with_devices(lights).await?;
142//!
143//! // Choose your communication protocol
144//! let protocol = GenericRGB::default();
145//!
146//! // set the default write Characteristic
147//! // for all devices. Optionally you can also
148//! // set it per-device. Look the examples folder for more
149//! controller.set_all_char(&CharKind::Write, &UuidKind::Uuid16(0xFFD9))?;
150//!
151//! // list all connected devices
152//! let connected_lights = controller.list();
153//! for light in connected_lights.iter_mut() {
154//! println!("Connected to : {}", light.name);
155//!
156//! // Control the lights
157//! println!("Turning light on...");
158//! light.turn_on(&protocol).await?;
159//!
160//! // Set color
161//! println!("Setting color...");
162//! light.color(&protocol, 255, 0, 0).await?;
163//! time::sleep(Duration::from_millis(800)).await;
164//! light.color(&protocol, 0, 255, 0).await?;
165//! time::sleep(Duration::from_millis(800)).await;
166//! light.color(&protocol, 0, 0, 255).await?;
167//! time::sleep(Duration::from_millis(800)).await;
168//!
169//! println!("SW Animation - Breathing effect...");
170//! light
171//! .breathing(
172//! &GenericRGB {},
173//! &ColorOption::RGB(255, 0, 0),
174//! &SWAnimationRepeat::FiniteCount(2),
175//! &SWAnimationSpeed::Fastest,
176//! )
177//! .await?;
178//! light
179//! .breathing(
180//! &GenericRGB {},
181//! &ColorOption::RGB(0, 255, 0),
182//! &SWAnimationRepeat::FiniteCount(2),
183//! &SWAnimationSpeed::Fastest,
184//! )
185//! .await?;
186//! light
187//! .breathing(
188//! &GenericRGB {},
189//! &ColorOption::RGB(0, 0, 255),
190//! &SWAnimationRepeat::FiniteCount(2),
191//! &SWAnimationSpeed::Fastest,
192//! )
193//! .await?;
194//!
195//! // Control the lights
196//! println!("Turning light off...");
197//! light.turn_off(&protocol).await?;
198//! }
199//!
200//! Ok(())
201//! }
202//! ```
203//! ## Contributing
204//!
205//! Open a PR or issue
206//!
207//! ## License
208//!
209//! MIT
210pub mod capability;
211pub mod communication_protocol;
212pub mod controller;
213pub mod device;
214pub mod error;
215
216//----------//
217// Re-export//
218//----------//
219////////////////////////////////////
220pub use self::controller::Controller;
221////////////////////////////////////