ble_ledly/
lib.rs

1//! # ble-ledly
2//! [![Crates.io](https://img.shields.io/badge/crates.io-v0.2.0-orange)](https://crates.io/crates/ble-ledly)
3//! [![Docs](https://img.shields.io/badge/docs-passing-brightgreen)](https://docs.rs/ble-ledly/)
4//! ![MIT](https://img.shields.io/github/license/espressoshock/ble-ledly)
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////////////////////////////////////